{
  "name": "pagination",
  "type": "registry:component",
  "files": [
    {
      "name": "pagination.component.ts",
      "content": "import { NgTemplateOutlet } from '@angular/common';\nimport {\n  booleanAttribute,\n  ChangeDetectionStrategy,\n  Component,\n  computed,\n  input,\n  model,\n  type TemplateRef,\n  ViewEncapsulation,\n} from '@angular/core';\n\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport { lucideChevronLeft, lucideChevronRight, lucideEllipsis } from '@ng-icons/lucide';\nimport type { ClassValue } from 'clsx';\n\nimport {\n  ZardButtonComponent,\n  type ZardButtonSizeVariants,\n  type ZardButtonTypeVariants,\n} from '@/shared/components/button';\nimport {\n  paginationContentVariants,\n  paginationEllipsisVariants,\n  paginationNextVariants,\n  paginationPreviousVariants,\n  paginationVariants,\n} from '@/shared/components/pagination/pagination.variants';\nimport { mergeClasses } from '@/shared/utils/merge-classes';\n\ntype PaginationItemSizeType = Exclude<ZardButtonSizeVariants, 'default' | 'xs' | 'sm' | 'lg'>;\ntype PaginationNavSizeType = Exclude<ZardButtonSizeVariants, 'icon' | 'icon-xs' | 'icon-sm' | 'icon-lg'>;\n\n@Component({\n  selector: 'ul[z-pagination-content]',\n  template: `\n    <ng-content />\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  encapsulation: ViewEncapsulation.None,\n  host: {\n    'data-slot': 'pagination-content',\n    '[class]': 'classes()',\n  },\n  exportAs: 'zPaginationContent',\n})\nexport class ZardPaginationContentComponent {\n  readonly class = input<ClassValue>('');\n\n  protected readonly classes = computed(() => mergeClasses(paginationContentVariants(), this.class()));\n}\n\n@Component({\n  selector: 'li[z-pagination-item]',\n  template: `\n    <ng-content />\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  encapsulation: ViewEncapsulation.None,\n  host: {\n    'data-slot': 'pagination-item',\n  },\n  exportAs: 'zPaginationItem',\n})\nexport class ZardPaginationItemComponent {}\n// Structural wrapper component for pagination items (<li>). No inputs required.\n\n@Component({\n  selector: 'button[z-pagination-button], a[z-pagination-button]',\n  imports: [ZardButtonComponent],\n  template: `\n    <z-button\n      [attr.data-active]=\"zActive() || null\"\n      [class]=\"class()\"\n      [zDisabled]=\"zDisabled()\"\n      [zSize]=\"zSize()\"\n      [zType]=\"zType()\"\n    >\n      <ng-content />\n    </z-button>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  encapsulation: ViewEncapsulation.None,\n  host: {\n    'data-slot': 'pagination-button',\n  },\n  exportAs: 'zPaginationButton',\n})\nexport class ZardPaginationButtonComponent {\n  readonly class = input<ClassValue>('');\n  readonly zActive = input(false, { transform: booleanAttribute });\n  readonly zDisabled = input(false, { transform: booleanAttribute });\n  readonly zSize = input<ZardButtonSizeVariants>('icon');\n\n  protected readonly zType = computed<ZardButtonTypeVariants>(() => (this.zActive() ? 'outline' : 'ghost'));\n}\n\n@Component({\n  selector: 'z-pagination-previous',\n  imports: [ZardPaginationButtonComponent, NgIcon],\n  template: `\n    <button\n      type=\"button\"\n      z-pagination-button\n      [attr.disabled]=\"zDisabled() ? '' : null\"\n      [class]=\"classes()\"\n      [zSize]=\"zSize()\"\n      [zDisabled]=\"zDisabled()\"\n    >\n      <span class=\"sr-only\">To previous page</span>\n      <ng-icon name=\"lucideChevronLeft\" aria-hidden=\"true\" />\n      <span class=\"hidden sm:block\" aria-hidden=\"true\">Previous</span>\n    </button>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  encapsulation: ViewEncapsulation.None,\n  viewProviders: [provideIcons({ lucideChevronLeft })],\n  exportAs: 'zPaginationPrevious',\n})\nexport class ZardPaginationPreviousComponent {\n  readonly class = input<ClassValue>('');\n  readonly zDisabled = input(false, { transform: booleanAttribute });\n  readonly zSize = input<PaginationNavSizeType>('default');\n\n  protected readonly classes = computed(() => mergeClasses(paginationPreviousVariants(), this.class()));\n}\n\n@Component({\n  selector: 'z-pagination-next',\n  imports: [ZardPaginationButtonComponent, NgIcon],\n  template: `\n    <button\n      type=\"button\"\n      z-pagination-button\n      [attr.disabled]=\"zDisabled() ? '' : null\"\n      [class]=\"classes()\"\n      [zDisabled]=\"zDisabled()\"\n      [zSize]=\"zSize()\"\n    >\n      <span class=\"sr-only\">To next page</span>\n      <span class=\"hidden sm:block\" aria-hidden=\"true\">Next</span>\n      <ng-icon name=\"lucideChevronRight\" aria-hidden=\"true\" />\n    </button>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  encapsulation: ViewEncapsulation.None,\n  viewProviders: [provideIcons({ lucideChevronRight })],\n  exportAs: 'zPaginationNext',\n})\nexport class ZardPaginationNextComponent {\n  readonly class = input<ClassValue>('');\n  readonly zDisabled = input(false, { transform: booleanAttribute });\n  readonly zSize = input<PaginationNavSizeType>('default');\n\n  protected readonly classes = computed(() => mergeClasses(paginationNextVariants(), this.class()));\n}\n\n@Component({\n  selector: 'z-pagination-ellipsis',\n  imports: [NgIcon],\n  template: `\n    <ng-icon name=\"lucideEllipsis\" aria-hidden=\"true\" />\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  encapsulation: ViewEncapsulation.None,\n  viewProviders: [provideIcons({ lucideEllipsis })],\n  host: {\n    '[class]': 'classes()',\n    'aria-hidden': 'true',\n  },\n  exportAs: 'zPaginationEllipsis',\n})\nexport class ZardPaginationEllipsisComponent {\n  readonly class = input<ClassValue>('');\n\n  protected readonly classes = computed(() => mergeClasses(paginationEllipsisVariants(), this.class()));\n}\n\n@Component({\n  selector: 'z-pagination',\n  imports: [\n    ZardPaginationContentComponent,\n    ZardPaginationItemComponent,\n    ZardPaginationButtonComponent,\n    ZardPaginationPreviousComponent,\n    ZardPaginationNextComponent,\n    NgTemplateOutlet,\n  ],\n  template: `\n    @if (zContent()) {\n      <ng-container *ngTemplateOutlet=\"zContent()\" />\n    } @else {\n      <ul z-pagination-content>\n        @if (!zSimple()) {\n          <li z-pagination-item>\n            @let pagePrevious = Math.max(1, clampedIndex() - 1);\n            <z-pagination-previous\n              [zSize]=\"navSize()\"\n              [zDisabled]=\"zDisabled() || clampedIndex() === 1\"\n              (click)=\"goToPage(pagePrevious)\"\n            />\n          </li>\n        }\n\n        @for (page of pages(); track page) {\n          <li z-pagination-item>\n            <button\n              z-pagination-button\n              type=\"button\"\n              class=\"focus-visible:rounded-md\"\n              [attr.aria-current]=\"page === clampedIndex() ? 'page' : null\"\n              [attr.aria-disabled]=\"zDisabled() || null\"\n              [zActive]=\"page === clampedIndex()\"\n              [zDisabled]=\"zDisabled()\"\n              [zSize]=\"zSize()\"\n              (click)=\"goToPage(page)\"\n            >\n              <span class=\"sr-only\">{{ pages().length === page ? 'To last page, page' : 'To page' }}</span>\n              {{ page }}\n            </button>\n          </li>\n        }\n\n        @if (!zSimple()) {\n          <li z-pagination-item>\n            @let pageNext = Math.min(clampedIndex() + 1, zTotal());\n            <z-pagination-next\n              [zSize]=\"navSize()\"\n              [zDisabled]=\"zDisabled() || clampedIndex() === zTotal()\"\n              (click)=\"goToPage(pageNext)\"\n            />\n          </li>\n        }\n      </ul>\n    }\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  encapsulation: ViewEncapsulation.None,\n  host: {\n    role: 'group',\n    'data-slot': 'pagination',\n    '[attr.aria-label]': 'zAriaLabel()',\n    '[class]': 'classes()',\n  },\n  exportAs: 'zPagination',\n})\nexport class ZardPaginationComponent {\n  readonly zAriaLabel = input('Pagination');\n  readonly zContent = input<TemplateRef<void> | undefined>();\n  readonly zDisabled = input(false, { transform: booleanAttribute });\n  readonly zPageIndex = model<number>(1);\n  readonly zSimple = input(false, { transform: booleanAttribute });\n  readonly zSize = input<PaginationItemSizeType>('icon');\n  readonly zTotal = input<number>(1);\n\n  readonly class = input<ClassValue>('');\n\n  readonly Math = Math;\n\n  protected readonly classes = computed(() => mergeClasses(paginationVariants(), this.class()));\n  readonly pages = computed<number[]>(() => Array.from({ length: Math.max(0, this.zTotal()) }, (_, i) => i + 1));\n  readonly navSize = computed(() => {\n    const size = this.zSize();\n    switch (size) {\n      case 'icon-xs':\n        return 'xs';\n      case 'icon-sm':\n        return 'sm';\n      case 'icon-lg':\n        return 'lg';\n      default:\n        return 'default';\n    }\n  });\n\n  readonly clampedIndex = computed(() => {\n    const total = Math.max(1, this.zTotal());\n    return Math.min(Math.max(1, this.zPageIndex()), total);\n  });\n\n  goToPage(page: number): void {\n    const max = Math.max(1, this.zTotal());\n    if (!this.zDisabled() && page >= 1 && page <= max && page !== this.zPageIndex()) {\n      this.zPageIndex.set(page);\n    }\n  }\n}\n"
    },
    {
      "name": "pagination.imports.ts",
      "content": "import {\n  ZardPaginationButtonComponent,\n  ZardPaginationComponent,\n  ZardPaginationContentComponent,\n  ZardPaginationEllipsisComponent,\n  ZardPaginationItemComponent,\n  ZardPaginationNextComponent,\n  ZardPaginationPreviousComponent,\n} from '@/shared/components/pagination/pagination.component';\n\nexport const ZardPaginationImports = [\n  ZardPaginationContentComponent,\n  ZardPaginationItemComponent,\n  ZardPaginationButtonComponent,\n  ZardPaginationPreviousComponent,\n  ZardPaginationNextComponent,\n  ZardPaginationEllipsisComponent,\n  ZardPaginationComponent,\n] as const;\n"
    },
    {
      "name": "pagination.variants.ts",
      "content": "import { cva } from 'class-variance-authority';\n\nexport const paginationContentVariants = cva('flex items-center gap-0.5');\n\nexport const paginationPreviousVariants = cva('pl-1.5!');\n\nexport const paginationNextVariants = cva('pr-1.5!');\n\nexport const paginationEllipsisVariants = cva(\n  'flex size-8 items-center justify-center [&_svg:not([class*=\"size-\"])]:size-4',\n);\n\nexport const paginationVariants = cva('mx-auto flex w-full justify-center');\n"
    },
    {
      "name": "index.ts",
      "content": "export * from '@/shared/components/pagination/pagination.component';\nexport * from '@/shared/components/pagination/pagination.imports';\nexport * from '@/shared/components/pagination/pagination.variants';\n"
    }
  ],
  "registryDependencies": [
    "button"
  ],
  "demos": [
    {
      "name": "iconsonly.ts",
      "content": "import { ChangeDetectionStrategy, Component, computed, signal } from '@angular/core';\n\nimport { ZardFieldImports } from '@/shared/components/field';\nimport { ZardPaginationImports } from '@/shared/components/pagination';\nimport { ZardSelectImports } from '@/shared/components/select';\n\n@Component({\n  selector: 'z-demo-pagination-iconsonly',\n  imports: [ZardPaginationImports, ZardFieldImports, ZardSelectImports],\n  template: `\n    <div class=\"flex w-full justify-around\">\n      <div class=\"flex w-fit gap-4\">\n        <div z-field class=\"flex-row items-center\">\n          <label z-field-label for=\"select-rows-per-page\" class=\"min-w-max\">Rows Per Page</label>\n          <z-select id=\"select-rows-per-page\" zSize=\"sm\" [(zValue)]=\"perPage\" class=\"min-w-20\">\n            <z-select-item zValue=\"10\">10</z-select-item>\n            <z-select-item zValue=\"25\">25</z-select-item>\n            <z-select-item zValue=\"50\">50</z-select-item>\n            <z-select-item zValue=\"100\">100</z-select-item>\n          </z-select>\n        </div>\n        <z-pagination [zTotal]=\"totalPages()\" [(zPageIndex)]=\"currentPage\" [zContent]=\"content\" />\n      </div>\n    </div>\n\n    <ng-template #content>\n      <ul z-pagination-content>\n        <li z-pagination-item>\n          <z-pagination-previous (click)=\"goToPrevious()\" [zDisabled]=\"currentPage() === 1\" />\n        </li>\n\n        <li z-pagination-item>\n          <z-pagination-next (click)=\"goToNext()\" [zDisabled]=\"currentPage() === totalPages()\" />\n        </li>\n      </ul>\n    </ng-template>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ZardDemoPaginationIconsOnlyComponent {\n  private totalItems = 350;\n\n  readonly currentPage = signal(1);\n  readonly perPage = signal('25');\n  readonly totalPages = computed(() => Math.ceil(this.totalItems / parseInt(this.perPage())));\n\n  goToPrevious() {\n    if (this.currentPage() > 1) {\n      this.currentPage.update(p => p - 1);\n    }\n  }\n\n  goToNext() {\n    if (this.currentPage() < this.totalPages()) {\n      this.currentPage.update(p => p + 1);\n    }\n  }\n}\n"
    },
    {
      "name": "preview.ts",
      "content": "import { ChangeDetectionStrategy, Component, signal } from '@angular/core';\n\nimport { ZardPaginationImports } from '../pagination.imports';\n\n@Component({\n  selector: 'z-demo-pagination-preview',\n  imports: [ZardPaginationImports],\n  template: `\n    <z-pagination [zTotal]=\"totalPages\" [(zPageIndex)]=\"currentPage\" [zContent]=\"content\" />\n\n    <ng-template #content>\n      <ul z-pagination-content>\n        <li z-pagination-item>\n          <z-pagination-previous (click)=\"goToPrevious()\" [zDisabled]=\"currentPage() === 1\" />\n        </li>\n\n        @for (page of pages(); track page) {\n          <li z-pagination-item>\n            <button type=\"button\" z-pagination-button [zActive]=\"page === currentPage()\" (click)=\"goToPage(page)\">\n              <span class=\"sr-only\">To page</span>\n              {{ page }}\n            </button>\n          </li>\n        }\n\n        <li z-pagination-item>\n          <z-pagination-ellipsis />\n        </li>\n\n        <li z-pagination-item>\n          <z-pagination-next (click)=\"goToNext()\" [zDisabled]=\"currentPage() === totalPages\" />\n        </li>\n      </ul>\n    </ng-template>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ZardDemoPaginationPreviewComponent {\n  readonly totalPages = 3;\n  readonly currentPage = signal(2);\n\n  readonly pages = signal<number[]>(Array.from({ length: this.totalPages }, (_, i) => i + 1));\n\n  goToPage(page: number) {\n    this.currentPage.set(page);\n  }\n\n  goToPrevious() {\n    if (this.currentPage() > 1) {\n      this.currentPage.update(p => p - 1);\n    }\n  }\n\n  goToNext() {\n    if (this.currentPage() < this.totalPages) {\n      this.currentPage.update(p => p + 1);\n    }\n  }\n}\n"
    },
    {
      "name": "simple.ts",
      "content": "import { ChangeDetectionStrategy, Component } from '@angular/core';\n\nimport { ZardPaginationImports } from '../pagination.imports';\n\n@Component({\n  selector: 'z-demo-pagination-simple',\n  imports: [ZardPaginationImports],\n  template: `\n    <z-pagination [zTotal]=\"5\" [(zPageIndex)]=\"currentPage\" zSimple />\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ZardDemoPaginationSimpleComponent {\n  protected currentPage = 2;\n}\n"
    }
  ]
}
