type PaginationBaseProps = { /** * Total number of items in the collection (e.g., total rows in a table) * Must be >= 0. Invalid values are normalized to 0. */ totalItems: number; /** * Number of items displayed per page * Must be >= 1. Invalid values are normalized to 1. * Component calculates total pages as: Math.ceil(totalItems / pageSize) * @default 1 */ pageSize?: number; /** * Current page number (1-indexed, controlled) * Must be >= 1. Invalid values are normalized to 1. */ currentPage: number; /** * Callback when page changes via any interaction (prev/next/page number click) * @param params - Object containing page change details * @param params.page - The new page number (1-indexed) * @param params.source - How the page was changed: * - 'prev': Previous button clicked * - 'next': Next button clicked * - 'page': Page number button clicked (numbered variant only) * @param params.firstItemIndex - Index of the first item on the new page (1-indexed) * @param params.lastItemIndex - Index of the last item on the new page (1-indexed) * @param params.event - The mouse event from the button click */ onChange: ({ page, source, firstItemIndex, lastItemIndex, event, }: { page: number; source: "prev" | "next" | "page"; firstItemIndex?: number; lastItemIndex?: number; event?: React.MouseEvent; }) => void; /** * Custom label formatter * * **Compact variant**: Formats the center label showing item range (e.g., "1-10 of 100") * * **Numbered variant**: Formats mobile label only (e.g., "1/10") */ formatLabel?: (firstItemIndex?: number, lastItemIndex?: number, numOfItems?: number) => string; /** Accessible label for previous button (default: "Go to prev page") */ prevButtonAriaLabel?: string; /** Accessible label for next button (default: "Go to next page") */ nextButtonAriaLabel?: string; /** Data attribute for end-to-end testing */ "data-e2e-test-id"?: string; }; export type CompactVariantProps = PaginationBaseProps & { /** * Pagination variant * * **"compact"**: Shows prev/next icon buttons with a center label displaying item range */ variant: "compact"; /** * Label alignment * * **Note**: Only applies to **compact** variant. * * - `"center"`: Label positioned between prev/next buttons (default) * - `"left"`: Label positioned to the left of prev/next buttons * * @default "center" */ alignLabel?: "center" | "left"; }; export type NumberedVariantProps = PaginationBaseProps & { /** * Pagination variant * * **"numbered"** (default): Shows page number buttons for direct navigation with prev/next buttons * * Features: * - Clickable page numbers with ellipsis for large page counts * - Previous/Next buttons with text labels * - Mobile: displays "X/Y" format instead of page numbers */ variant?: "numbered"; /** * Show/hide text labels on Previous/Next buttons * * **Note**: Only applies to **numbered** variant. * * - `true`: Shows "Previous"/"Next" text with icons (default) * - `false`: Shows icon-only buttons for more compact display * * @default true */ showNavButtonLabels?: boolean; /** * Text label for previous button * * **Note**: Only applies to **numbered** variant when `showNavButtonLabels={true}`. * * Use for internationalization/localization. * * @default "Previous" */ prevButtonLabel?: string; /** * Text label for next button * * **Note**: Only applies to **numbered** variant when `showNavButtonLabels={true}`. * * Use for internationalization/localization. * * @default "Next" */ nextButtonLabel?: string; /** * Formatter for page button aria-label * * **Note**: Only applies to **numbered** variant. * * Use for internationalization/localization of the aria-label for page number buttons. * * @param page - The page number * @returns The formatted aria-label string * @default (page) => `Page ${page}` */ formatPageButtonAriaLabel?: (page: number) => string; }; export type PaginationProps = CompactVariantProps | NumberedVariantProps; export {};