From ea8f2a10295a8621a9f1d5416b71f27915f58e99 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 2 Aug 2026 06:16:36 +0000 Subject: [PATCH] feat: add Pagination component Closes #11 --- AGENT.md | 1 + CHANGELOG.md | 1 + CLAUDE.md | 2 +- README.md | 1 + bin/usage-content.js | 1 + public/component-manifest.json | 100 ++++++++- public/llms.txt | 4 +- scripts/generate-manifest.js | 3 +- src/components/Pagination.stories.tsx | 238 +++++++++++++++++++++ src/components/Pagination.test.tsx | 152 ++++++++++++++ src/components/Pagination.tsx | 292 ++++++++++++++++++++++++++ src/components/index.ts | 2 + src/utils/responsive.ts | 5 + 13 files changed, 796 insertions(+), 6 deletions(-) create mode 100644 src/components/Pagination.stories.tsx create mode 100644 src/components/Pagination.test.tsx create mode 100644 src/components/Pagination.tsx diff --git a/AGENT.md b/AGENT.md index 0db2d8e..36ae89a 100644 --- a/AGENT.md +++ b/AGENT.md @@ -49,6 +49,7 @@ import "cyberui-2045/styles.css"; | `Carousel` | Image carousel. | | `Steps` | Multi-step progress indicator. | | `DropdownMenu` | Dropdown/context menu anchored to a trigger element. Arrow-key navigation, `danger` item styling, click-outside/Escape dismissal. | +| `Pagination` | Page control for lists/tables. Controlled `currentPage`/`totalPages`, compact ellipsis collapsing for large page counts, Previous/Next controls. | | `GradientText` | Text with cyberpunk gradient effects. | | `SectionTitle` | Title with decorative gradient line. | | `Timeline` | Vertical event history display. | diff --git a/CHANGELOG.md b/CHANGELOG.md index 57770a1..c879e08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- **`Pagination`** component — a cyberpunk-styled page control for list/table views with more results than fit on one page. Always controlled via `currentPage`/`onPageChange`. Defaults to `compact` ellipsis-collapsing (`siblingCount`/`boundaryCount` tunable) so large page counts collapse distant pages behind an ellipsis, keeping boundary pages and a window around the current page visible; `compact={false}` renders every page. `showPrevNext` toggles Previous/Next controls, `variant` (`primary`/`secondary`/`accent`) reuses Button/Badge's palette for the active-page highlight and hover glow, and `size` supports responsive values (new `RESPONSIVE_SIZE_MAPS.pagination` entry). Page/Previous/Next controls are native `} items={items} />\n@example // Render-prop trigger\n }\n items={items}\n/>" + "description": "The trigger that opens the menu. Pass a single React element (e.g. a\n`Button`) to have it cloned with the required `onClick`/`aria-*`\nwiring, or a render prop for full control over how those props are\napplied. If the element already has its own `onClick`/`onKeyDown`,\nthey're called first, before the dropdown's own handling runs.\n@example // Element trigger\nActions} items={items} />\n@example // Render-prop trigger\n }\n items={items}\n/>" }, { "name": "align", @@ -1593,6 +1593,102 @@ } ] }, + { + "name": "Pagination", + "category": "Navigation", + "sourceFile": "src/components/Pagination.tsx", + "displayName": "Pagination", + "description": "A cyberpunk-styled page control for list/table views with more results\nthan fit on one page. Always controlled via `currentPage`/`onPageChange`,\nwith a compact ellipsis-collapsing mode for large page counts.", + "docSummary": "Page control for lists/tables. Controlled `currentPage`/`totalPages`, compact ellipsis collapsing for large page counts, Previous/Next controls.", + "storybookPath": "components-pagination--docs", + "manifestOverride": false, + "props": [ + { + "name": "currentPage", + "type": "number", + "required": true, + "default": null, + "description": "Current active page, 1-based. Pagination is always controlled by this value." + }, + { + "name": "totalPages", + "type": "number", + "required": true, + "default": null, + "description": "Total number of pages available." + }, + { + "name": "onPageChange", + "type": "(page: number) => void", + "required": true, + "default": null, + "description": "Fired with the newly selected page number when the user clicks a page, Previous/Next, or uses Home/End." + }, + { + "name": "compact", + "type": "boolean | undefined", + "required": false, + "default": true, + "description": "Collapses distant page numbers behind an ellipsis for large page counts,\nalways keeping `boundaryCount` pages at each edge and `siblingCount`\npages around `currentPage` visible. When `false`, every page renders." + }, + { + "name": "siblingCount", + "type": "number | undefined", + "required": false, + "default": 1, + "description": "Number of page buttons shown on each side of `currentPage` when `compact` is true." + }, + { + "name": "boundaryCount", + "type": "number | undefined", + "required": false, + "default": 1, + "description": "Number of page buttons always shown at the start and end when `compact` is true." + }, + { + "name": "showPrevNext", + "type": "boolean | undefined", + "required": false, + "default": true, + "description": "Whether to render Previous/Next controls alongside the page numbers." + }, + { + "name": "variant", + "type": "\"primary\" | \"secondary\" | \"accent\" | undefined", + "required": false, + "default": "primary", + "description": "Visual style for the active page and hover glow, matching Button/Badge's variant vocabulary." + }, + { + "name": "size", + "type": "ResponsiveValue<\"sm\" | \"md\" | \"lg\"> | undefined", + "required": false, + "default": "md", + "description": "Size of each page control. Can be a static value or a responsive object." + }, + { + "name": "disabled", + "type": "boolean | undefined", + "required": false, + "default": false, + "description": "Disables every control in the group — no page can be selected." + }, + { + "name": "ariaLabel", + "type": "string | undefined", + "required": false, + "default": "Pagination", + "description": "Accessible label for the containing `