# Pagination

Compact page navigation with previous and next controls, windowed page numbers, optional icon-only mode, and localized labels.

Use Pagination when a feature page needs to move through a paged API result, a dense table footer, or a navigable list of routes or guides.

## Import

```ts
import { PaginationComponent } from '@edsis/component/pagination';
```

## Structure

The Angular package intentionally wraps the shadcn multi-part composition in a single standalone primitive.

```text
Pagination
├── previous button
├── page buttons and ellipsis
└── next button
```

## Basic usage

Bind `[(page)]` to a signal and keep your collection, router state, or server request outside the primitive.

```html
<Pagination
  [(page)]="currentPage"
  [total]="totalPages"
  [siblingCount]="1"
  (pageChange)="load($event)"
/>
```

## Common patterns

### Navigation data

Keep the rendered collection in sync with the pager through `computed()`.

```ts
const navigationPage = signal(1);
const pageSize = 4;

const navigationItems = [
  { title: 'Introduction', route: '/docs/introduction' },
  { title: 'Accordion', route: '/ui/shadcn/accordion' },
  { title: 'Button', route: '/ui/shadcn/button' },
  { title: 'Input', route: '/ui/shadcn/input' },
  // ...more items
];

const totalPages = Math.ceil(navigationItems.length / pageSize);
const visibleItems = computed(() => {
  const start = (navigationPage() - 1) * pageSize;
  return navigationItems.slice(start, start + pageSize);
});
```

### Icons only

Hide page numbers and visible labels when the pager sits next to a dense table or feed footer.

```html
<Pagination
  [(page)]="compactPage"
  [total]="9"
  [showPageNumbers]="false"
  previousText=""
  nextText=""
  class="mx-0 w-auto"
/>
```

### RTL and translated labels

Translate the previous and next text and provide a page formatter when locale-specific numerals should appear.

```ts
const arabicDigits = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
const toArabicNumerals = (page: number): string =>
  page
    .toString()
    .split('')
    .map((digit) => arabicDigits[Number(digit)] ?? digit)
    .join('');
```

```html
<section dir="rtl" lang="ar" class="text-right">
  <Pagination
    [(page)]="rtlPage"
    [total]="7"
    previousText="السابق"
    nextText="التالي"
    previousAriaLabel="الانتقال إلى الصفحة السابقة"
    nextAriaLabel="الانتقال إلى الصفحة التالية"
    [formatPageLabel]="toArabicNumerals"
  />
</section>
```

## API reference

| Input               | Type                       | Default                   | Description                                                            |
| ------------------- | -------------------------- | ------------------------- | ---------------------------------------------------------------------- |
| `page` (model)      | `number`                   | `1`                       | Two-way bound current page.                                            |
| `total`             | `number`                   | `1`                       | Total number of pages available.                                       |
| `siblingCount`      | `number`                   | `1`                       | Page buttons shown on either side of the active page.                  |
| `showPageNumbers`   | `boolean`                  | `true`                    | Hide numbered page buttons for compact previous and next only layouts. |
| `previousText`      | `string`                   | `'Previous'`              | Visible previous label. Set to an empty string for icon-only mode.     |
| `nextText`          | `string`                   | `'Next'`                  | Visible next label. Set to an empty string for icon-only mode.         |
| `previousAriaLabel` | `string`                   | `'Go to previous page'`   | Accessible name for the previous button.                               |
| `nextAriaLabel`     | `string`                   | `'Go to next page'`       | Accessible name for the next button.                                   |
| `formatPageLabel`   | `(page: number) => string` | `page => page.toString()` | Formats the rendered page label.                                       |
| `class`             | `string`                   | `''`                      | Extra container classes.                                               |

| Output       | Payload  | Description                                          |
| ------------ | -------- | ---------------------------------------------------- |
| `pageChange` | `number` | Emits the next page number after a user interaction. |

## Styling and theming

Pagination reuses `buttonVariants`, so the previous and next controls plus numbered page buttons inherit the same shape, focus ring, and theme tokens as the Button primitive.

Pass `class` to adjust width and alignment, for example `mx-0 w-auto` in a table footer or `justify-start` when the pager should align to the left edge of a card.

## Accessibility

- The root renders as `<nav role="navigation" aria-label="pagination">`.
- The active page is marked with `aria-current="page"`.
- Previous and next disable natively at the start and end of the available range.
- Ellipses are `aria-hidden="true"`.
- When visible text is removed for icon-only mode, keep meaningful aria labels on the previous and next buttons.

## Keyboard interactions

- Tab moves focus through the previous button, page buttons, and next button in DOM order.
- Enter and Space activate the focused button through native button semantics.

## Angular notes

- Keep the paged collection outside the component and derive the visible slice with `computed()`.
- Import `PaginationComponent` into the standalone feature component that renders the pager.
- `showPageNumbers`, `previousText`, `nextText`, and `formatPageLabel` are deliberate Angular-specific conveniences that cover the upstream icon-only and RTL guidance without exposing React-style child parts.

## Source parity

shadcn documents Pagination as several composable parts such as `PaginationLink`, `PaginationPrevious`, and `PaginationNext`. This Angular implementation intentionally collapses that structure into one primitive so route-driven and data-driven pagination can be wired quickly while still matching the upstream previous, next, ellipsis, compact, and RTL behavior.
