@gridui/pagination 1.0.6 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/index.js +9 -5
- package/dist/index.js.map +2 -2
- package/dist/pagination/pagination.d.ts +6 -1
- package/docs/catalog.json +7 -3
- package/docs/reference/README.md +4 -0
- package/docs/reference/pagination.md +77 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -5,4 +5,24 @@ Core family. Public API: `Pagination`, `PaginationLabels`, `PaginationProps`.
|
|
|
5
5
|
Import components from `@gridui/pagination` and load `@gridui/pagination/styles.css` after Theme.
|
|
6
6
|
Load styles for any composed dependency used by this family. Applications own routes, labels, state persistence, and branding.
|
|
7
7
|
|
|
8
|
+
## Unknown page count
|
|
9
|
+
|
|
10
|
+
Pass `pageCount={null}` and a boolean `hasNextPage` when the server does not
|
|
11
|
+
provide a total. Pagination shows Previous, the current page, and Next. The host
|
|
12
|
+
supplies either `onPageChange` or `getPageHref`, as with a known count. Previous
|
|
13
|
+
is disabled on page 1; Next is disabled when no next page is available. No last
|
|
14
|
+
page or total is inferred. Pages must remain positive safe integers; `Infinity`
|
|
15
|
+
is rejected, and Next is disabled at `Number.MAX_SAFE_INTEGER`.
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<Pagination page={page} pageCount={null} hasNextPage={response.hasNextPage}
|
|
19
|
+
onPageChange={setPage} labels={labels} />
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
A numeric `pageCount` retains the existing bounded page window and does not take
|
|
23
|
+
`hasNextPage`. Unknown totals still use page numbers; applications own cursor
|
|
24
|
+
mapping, fetching, and history when their backend uses cursor pagination.
|
|
25
|
+
|
|
8
26
|
See [component ownership](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/docs/component-ownership.md) and [release history](https://github.com/sudo-ui/GridUI-React-Monorepo/tree/main/packages-core/pagination/.changeset/history).
|
|
27
|
+
|
|
28
|
+
[Component reference](docs/reference/README.md) contains focused API pages for each public component.
|
package/dist/index.js
CHANGED
|
@@ -59,10 +59,14 @@ import { ChevronLeft, ChevronRight, Ellipsis } from "lucide-react";
|
|
|
59
59
|
import { Fragment } from "react";
|
|
60
60
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
61
61
|
var Pagination = (props) => {
|
|
62
|
-
const { page, pageCount, labels, onPageChange, getPageHref, className, ...restProps } = props;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
const { page, pageCount, hasNextPage, labels, onPageChange, getPageHref, className, ...restProps } = props;
|
|
63
|
+
if (pageCount === null && (!Number.isSafeInteger(page) || page < 1 || typeof hasNextPage !== "boolean")) {
|
|
64
|
+
throw new RangeError("Unknown-count Pagination requires a positive safe integer page and a boolean hasNextPage.");
|
|
65
|
+
}
|
|
66
|
+
const entries = pageCount === null ? [page] : paginationRange(page, pageCount);
|
|
67
|
+
const compactEntries = pageCount === null ? entries : paginationRange(page, pageCount, true);
|
|
68
|
+
const current = pageCount === null ? page : Math.max(1, Math.min(page, pageCount));
|
|
69
|
+
const nextDisabled = pageCount === null ? !hasNextPage || current === Number.MAX_SAFE_INTEGER : pageCount === 0 || current >= pageCount;
|
|
66
70
|
const control = (target, label, children, disabled, active = false) => {
|
|
67
71
|
const shared = {
|
|
68
72
|
"aria-label": label,
|
|
@@ -154,7 +158,7 @@ var Pagination = (props) => {
|
|
|
154
158
|
className: "gridui-u-pagination--rtl:rotate-180",
|
|
155
159
|
"aria-hidden": "true"
|
|
156
160
|
}
|
|
157
|
-
),
|
|
161
|
+
), nextDisabled) })
|
|
158
162
|
]
|
|
159
163
|
}
|
|
160
164
|
)
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/pagination/range.ts", "../src/pagination/pagination.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * @author WMXPY\n * @package Pagination\n * @namespace Pagination\n * @description Range\n */\n\nexport type PaginationEntry = number | \"start-ellipsis\" | \"end-ellipsis\";\n\nexport const paginationRange = (page: number, pageCount: number, compact = false): PaginationEntry[] => {\n if (!Number.isSafeInteger(pageCount) || pageCount < 0 || !Number.isSafeInteger(page) || page < 1) {\n throw new RangeError(\"Pagination requires a positive integer page and a non-negative integer pageCount.\");\n }\n if (pageCount === 0) {\n return [];\n }\n if (pageCount <= (compact ? 5 : 7)) {\n return Array.from({ length: pageCount }, (_, index) => {\n return index + 1;\n });\n }\n const current = Math.min(page, pageCount);\n if (compact) {\n const positions = [\n ...new Set([\n 1,\n current,\n pageCount,\n ]),\n ];\n const entries: PaginationEntry[] = [];\n for (const [\n index,\n position,\n ] of positions.entries()) {\n if (index > 0 && position - positions[index - 1]! > 1) {\n entries.push(position <= current ? \"start-ellipsis\" : \"end-ellipsis\");\n }\n entries.push(position);\n }\n return entries;\n }\n const start = Math.max(2, Math.min(current - 1, pageCount - 4));\n const end = Math.min(pageCount - 1, Math.max(current + 1, 5));\n const entries: PaginationEntry[] = [1];\n if (start === 3) {\n entries.push(2);\n } else if (start > 3) {\n entries.push(\"start-ellipsis\");\n }\n for (let index = start; index <= end; index++) { entries.push(index); }\n if (end === pageCount - 2) {\n entries.push(pageCount - 1);\n } else if (end < pageCount - 2) {\n entries.push(\"end-ellipsis\");\n }\n entries.push(pageCount);\n return entries;\n};\n", "/**\n * @author WMXPY\n * @package Pagination\n * @namespace Pagination\n * @description Pagination\n */\n\nimport { type PaginationEntry, paginationRange } from \"./range\";\nimport { Button, ButtonLink } from \"@gridui/button\";\nimport { cn } from \"@gridui/style-utils\";\nimport { ChevronLeft, ChevronRight, Ellipsis } from \"lucide-react\";\nimport { type ComponentPropsWithRef, type FC, Fragment, type ReactNode } from \"react\";\n\nexport type PaginationLabels = {\n readonly navigation: string;\n readonly previous: string;\n readonly next: string;\n readonly page: (page: number) => string;\n readonly ellipsis: string;\n};\n\nexport type PaginationProps = Omit<ComponentPropsWithRef<\"nav\">, \"children\" | \"aria-label\"> & {\n readonly page: number;\n readonly pageCount: number;\n readonly
|
|
5
|
-
"mappings": ";AASO,IAAM,kBAAkB,CAAC,MAAc,WAAmB,UAAU,UAA6B;AACpG,MAAI,CAAC,OAAO,cAAc,SAAS,KAAK,YAAY,KAAK,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,GAAG;AAC9F,UAAM,IAAI,WAAW,mFAAmF;AAAA,EAC5G;AACA,MAAI,cAAc,GAAG;AACjB,WAAO,CAAC;AAAA,EACZ;AACA,MAAI,cAAc,UAAU,IAAI,IAAI;AAChC,WAAO,MAAM,KAAK,EAAE,QAAQ,UAAU,GAAG,CAAC,GAAG,UAAU;AACnD,aAAO,QAAQ;AAAA,IACnB,CAAC;AAAA,EACL;AACA,QAAM,UAAU,KAAK,IAAI,MAAM,SAAS;AACxC,MAAI,SAAS;AACT,UAAM,YAAY;AAAA,MACd,GAAG,oBAAI,IAAI;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,MACJ,CAAC;AAAA,IACL;AACA,UAAMA,WAA6B,CAAC;AACpC,eAAW;AAAA,MACP;AAAA,MACA;AAAA,IACJ,KAAK,UAAU,QAAQ,GAAG;AACtB,UAAI,QAAQ,KAAK,WAAW,UAAU,QAAQ,CAAC,IAAK,GAAG;AACnD,QAAAA,SAAQ,KAAK,YAAY,UAAU,mBAAmB,cAAc;AAAA,MACxE;AACA,MAAAA,SAAQ,KAAK,QAAQ;AAAA,IACzB;AACA,WAAOA;AAAA,EACX;AACA,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,UAAU,GAAG,YAAY,CAAC,CAAC;AAC9D,QAAM,MAAM,KAAK,IAAI,YAAY,GAAG,KAAK,IAAI,UAAU,GAAG,CAAC,CAAC;AAC5D,QAAM,UAA6B,CAAC,CAAC;AACrC,MAAI,UAAU,GAAG;AACb,YAAQ,KAAK,CAAC;AAAA,EAClB,WAAW,QAAQ,GAAG;AAClB,YAAQ,KAAK,gBAAgB;AAAA,EACjC;AACA,WAAS,QAAQ,OAAO,SAAS,KAAK,SAAS;AAAE,YAAQ,KAAK,KAAK;AAAA,EAAG;AACtE,MAAI,QAAQ,YAAY,GAAG;AACvB,YAAQ,KAAK,YAAY,CAAC;AAAA,EAC9B,WAAW,MAAM,YAAY,GAAG;AAC5B,YAAQ,KAAK,cAAc;AAAA,EAC/B;AACA,UAAQ,KAAK,SAAS;AACtB,SAAO;AACX;;;AClDA,SAAS,QAAQ,kBAAkB;AACnC,SAAS,UAAU;AACnB,SAAS,aAAa,cAAc,gBAAgB;AACpD,SAA8C,gBAAgC;
|
|
4
|
+
"sourcesContent": ["/**\n * @author WMXPY\n * @package Pagination\n * @namespace Pagination\n * @description Range\n */\n\nexport type PaginationEntry = number | \"start-ellipsis\" | \"end-ellipsis\";\n\nexport const paginationRange = (page: number, pageCount: number, compact = false): PaginationEntry[] => {\n if (!Number.isSafeInteger(pageCount) || pageCount < 0 || !Number.isSafeInteger(page) || page < 1) {\n throw new RangeError(\"Pagination requires a positive integer page and a non-negative integer pageCount.\");\n }\n if (pageCount === 0) {\n return [];\n }\n if (pageCount <= (compact ? 5 : 7)) {\n return Array.from({ length: pageCount }, (_, index) => {\n return index + 1;\n });\n }\n const current = Math.min(page, pageCount);\n if (compact) {\n const positions = [\n ...new Set([\n 1,\n current,\n pageCount,\n ]),\n ];\n const entries: PaginationEntry[] = [];\n for (const [\n index,\n position,\n ] of positions.entries()) {\n if (index > 0 && position - positions[index - 1]! > 1) {\n entries.push(position <= current ? \"start-ellipsis\" : \"end-ellipsis\");\n }\n entries.push(position);\n }\n return entries;\n }\n const start = Math.max(2, Math.min(current - 1, pageCount - 4));\n const end = Math.min(pageCount - 1, Math.max(current + 1, 5));\n const entries: PaginationEntry[] = [1];\n if (start === 3) {\n entries.push(2);\n } else if (start > 3) {\n entries.push(\"start-ellipsis\");\n }\n for (let index = start; index <= end; index++) { entries.push(index); }\n if (end === pageCount - 2) {\n entries.push(pageCount - 1);\n } else if (end < pageCount - 2) {\n entries.push(\"end-ellipsis\");\n }\n entries.push(pageCount);\n return entries;\n};\n", "/**\n * @author WMXPY\n * @package Pagination\n * @namespace Pagination\n * @description Pagination\n */\n\nimport { type PaginationEntry, paginationRange } from \"./range\";\nimport { Button, ButtonLink } from \"@gridui/button\";\nimport { cn } from \"@gridui/style-utils\";\nimport { ChevronLeft, ChevronRight, Ellipsis } from \"lucide-react\";\nimport { type ComponentPropsWithRef, type FC, Fragment, type ReactNode } from \"react\";\n\nexport type PaginationLabels = {\n readonly navigation: string;\n readonly previous: string;\n readonly next: string;\n readonly page: (page: number) => string;\n readonly ellipsis: string;\n};\n\nexport type PaginationProps = Omit<ComponentPropsWithRef<\"nav\">, \"children\" | \"aria-label\"> & {\n readonly page: number;\n readonly labels: PaginationLabels;\n} & ({\n readonly pageCount: number;\n readonly hasNextPage?: never;\n} | {\n readonly pageCount: null;\n readonly hasNextPage: boolean;\n}) & ({\n readonly onPageChange: (page: number) => void;\n readonly getPageHref?: never;\n} | {\n readonly getPageHref: (page: number) => string;\n readonly onPageChange?: never;\n});\n\nexport const Pagination: FC<PaginationProps> = (props: PaginationProps) => {\n const { page, pageCount, hasNextPage, labels, onPageChange, getPageHref, className, ...restProps } = props;\n if (pageCount === null && (!Number.isSafeInteger(page) || page < 1 || typeof hasNextPage !== \"boolean\")) {\n throw new RangeError(\"Unknown-count Pagination requires a positive safe integer page and a boolean hasNextPage.\");\n }\n const entries = pageCount === null ? [page] : paginationRange(page, pageCount);\n const compactEntries = pageCount === null ? entries : paginationRange(page, pageCount, true);\n const current = pageCount === null ? page : Math.max(1, Math.min(page, pageCount));\n const nextDisabled = pageCount === null\n ? !hasNextPage || current === Number.MAX_SAFE_INTEGER\n : pageCount === 0 || current >= pageCount;\n const control = (target: number, label: string, children: ReactNode, disabled: boolean, active = false) => {\n const shared = {\n \"aria-label\": label,\n \"aria-current\": active ? \"page\" as const : undefined,\n variant: active ? \"secondary\" as const : \"quiet\" as const,\n layout: \"icon\" as const,\n className: typeof children === \"number\" ? \"gridui-u-pagination--h-auto gridui-u-pagination--min-h-11 gridui-u-pagination--w-auto gridui-u-pagination--min-w-11 gridui-u-pagination--px-gridui-8 gridui-u-pagination--whitespace-nowrap\" : undefined,\n };\n if (getPageHref && !disabled) {\n return (<ButtonLink\n {...shared}\n href={getPageHref(target)}\n >\n {children}\n </ButtonLink>);\n }\n return (<Button\n {...shared}\n disabled={disabled}\n onClick={() => {\n if (target !== current) {\n onPageChange?.(target);\n }\n }}\n >\n {children}\n </Button>);\n };\n const renderEntry = (entry: PaginationEntry, entryClassName?: string) => {\n return (<li\n className={entryClassName}\n >\n {typeof entry === \"number\"\n ? control(entry, labels.page(entry), entry, false, entry === current)\n : (<span\n role=\"img\"\n className=\"gridui-u-pagination--inline-flex gridui-u-pagination--min-h-11 gridui-u-pagination--min-w-11 gridui-u-pagination--items-center gridui-u-pagination--justify-center gridui-u-pagination--text-muted\"\n aria-label={labels.ellipsis}\n >\n <Ellipsis\n aria-hidden=\"true\"\n />\n </span>)}\n </li>);\n };\n return (<nav\n {...restProps}\n aria-label={labels.navigation}\n className={cn(\"gridui-u-pagination--min-w-0\", className)}\n >\n <ul\n className=\"gridui-u-pagination--m-0 gridui-u-pagination--flex gridui-u-pagination--list-none gridui-u-pagination--flex-wrap gridui-u-pagination--items-center gridui-u-pagination--gap-0 gridui-u-pagination--p-0 gridui-u-pagination--md:gap-gridui-4\"\n >\n <li>\n {control(current - 1, labels.previous, (<ChevronLeft\n className=\"gridui-u-pagination--rtl:rotate-180\"\n aria-hidden=\"true\"\n />), pageCount === 0 || current === 1)}\n </li>\n {entries.map(entry => {\n return (<Fragment\n key={entry}\n >\n {entry === pageCount && compactEntries.includes(\"end-ellipsis\") && !entries.includes(\"end-ellipsis\")\n && renderEntry(\"end-ellipsis\", cn(\"gridui-u-pagination--md:hidden\"))}\n {renderEntry(entry, compactEntries.includes(entry) ? undefined : cn(\"gridui-u-pagination--hidden gridui-u-pagination--md:block\"))}\n {entry === 1 && compactEntries.includes(\"start-ellipsis\") && !entries.includes(\"start-ellipsis\")\n && renderEntry(\"start-ellipsis\", cn(\"gridui-u-pagination--md:hidden\"))}\n </Fragment>);\n })}\n <li>\n {control(current + 1, labels.next, (<ChevronRight\n className=\"gridui-u-pagination--rtl:rotate-180\"\n aria-hidden=\"true\"\n />), nextDisabled)}\n </li>\n </ul>\n </nav>);\n};\n"],
|
|
5
|
+
"mappings": ";AASO,IAAM,kBAAkB,CAAC,MAAc,WAAmB,UAAU,UAA6B;AACpG,MAAI,CAAC,OAAO,cAAc,SAAS,KAAK,YAAY,KAAK,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,GAAG;AAC9F,UAAM,IAAI,WAAW,mFAAmF;AAAA,EAC5G;AACA,MAAI,cAAc,GAAG;AACjB,WAAO,CAAC;AAAA,EACZ;AACA,MAAI,cAAc,UAAU,IAAI,IAAI;AAChC,WAAO,MAAM,KAAK,EAAE,QAAQ,UAAU,GAAG,CAAC,GAAG,UAAU;AACnD,aAAO,QAAQ;AAAA,IACnB,CAAC;AAAA,EACL;AACA,QAAM,UAAU,KAAK,IAAI,MAAM,SAAS;AACxC,MAAI,SAAS;AACT,UAAM,YAAY;AAAA,MACd,GAAG,oBAAI,IAAI;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,MACJ,CAAC;AAAA,IACL;AACA,UAAMA,WAA6B,CAAC;AACpC,eAAW;AAAA,MACP;AAAA,MACA;AAAA,IACJ,KAAK,UAAU,QAAQ,GAAG;AACtB,UAAI,QAAQ,KAAK,WAAW,UAAU,QAAQ,CAAC,IAAK,GAAG;AACnD,QAAAA,SAAQ,KAAK,YAAY,UAAU,mBAAmB,cAAc;AAAA,MACxE;AACA,MAAAA,SAAQ,KAAK,QAAQ;AAAA,IACzB;AACA,WAAOA;AAAA,EACX;AACA,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,UAAU,GAAG,YAAY,CAAC,CAAC;AAC9D,QAAM,MAAM,KAAK,IAAI,YAAY,GAAG,KAAK,IAAI,UAAU,GAAG,CAAC,CAAC;AAC5D,QAAM,UAA6B,CAAC,CAAC;AACrC,MAAI,UAAU,GAAG;AACb,YAAQ,KAAK,CAAC;AAAA,EAClB,WAAW,QAAQ,GAAG;AAClB,YAAQ,KAAK,gBAAgB;AAAA,EACjC;AACA,WAAS,QAAQ,OAAO,SAAS,KAAK,SAAS;AAAE,YAAQ,KAAK,KAAK;AAAA,EAAG;AACtE,MAAI,QAAQ,YAAY,GAAG;AACvB,YAAQ,KAAK,YAAY,CAAC;AAAA,EAC9B,WAAW,MAAM,YAAY,GAAG;AAC5B,YAAQ,KAAK,cAAc;AAAA,EAC/B;AACA,UAAQ,KAAK,SAAS;AACtB,SAAO;AACX;;;AClDA,SAAS,QAAQ,kBAAkB;AACnC,SAAS,UAAU;AACnB,SAAS,aAAa,cAAc,gBAAgB;AACpD,SAA8C,gBAAgC;AA+C1D,cAmDI,YAnDJ;AApBb,IAAM,aAAkC,CAAC,UAA2B;AACvE,QAAM,EAAE,MAAM,WAAW,aAAa,QAAQ,cAAc,aAAa,WAAW,GAAG,UAAU,IAAI;AACrG,MAAI,cAAc,SAAS,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,KAAK,OAAO,gBAAgB,YAAY;AACrG,UAAM,IAAI,WAAW,2FAA2F;AAAA,EACpH;AACA,QAAM,UAAU,cAAc,OAAO,CAAC,IAAI,IAAI,gBAAgB,MAAM,SAAS;AAC7E,QAAM,iBAAiB,cAAc,OAAO,UAAU,gBAAgB,MAAM,WAAW,IAAI;AAC3F,QAAM,UAAU,cAAc,OAAO,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,SAAS,CAAC;AACjF,QAAM,eAAe,cAAc,OAC7B,CAAC,eAAe,YAAY,OAAO,mBACnC,cAAc,KAAK,WAAW;AACpC,QAAM,UAAU,CAAC,QAAgB,OAAe,UAAqB,UAAmB,SAAS,UAAU;AACvG,UAAM,SAAS;AAAA,MACX,cAAc;AAAA,MACd,gBAAgB,SAAS,SAAkB;AAAA,MAC3C,SAAS,SAAS,cAAuB;AAAA,MACzC,QAAQ;AAAA,MACR,WAAW,OAAO,aAAa,WAAW,gMAAgM;AAAA,IAC9O;AACA,QAAI,eAAe,CAAC,UAAU;AAC1B,aAAQ;AAAA,QAAC;AAAA;AAAA,UACJ,GAAG;AAAA,UACJ,MAAM,YAAY,MAAM;AAAA,UAEvB;AAAA;AAAA,MACL;AAAA,IACJ;AACA,WAAQ;AAAA,MAAC;AAAA;AAAA,QACJ,GAAG;AAAA,QACJ;AAAA,QACA,SAAS,MAAM;AACX,cAAI,WAAW,SAAS;AACpB,2BAAe,MAAM;AAAA,UACzB;AAAA,QACJ;AAAA,QAEC;AAAA;AAAA,IACL;AAAA,EACJ;AACA,QAAM,cAAc,CAAC,OAAwB,mBAA4B;AACrE,WAAQ;AAAA,MAAC;AAAA;AAAA,QACL,WAAW;AAAA,QAEV,iBAAO,UAAU,WACZ,QAAQ,OAAO,OAAO,KAAK,KAAK,GAAG,OAAO,OAAO,UAAU,OAAO,IACjE;AAAA,UAAC;AAAA;AAAA,YACA,MAAK;AAAA,YACL,WAAU;AAAA,YACV,cAAY,OAAO;AAAA,YAEnB;AAAA,cAAC;AAAA;AAAA,gBACG,eAAY;AAAA;AAAA,YAChB;AAAA;AAAA,QACJ;AAAA;AAAA,IACR;AAAA,EACJ;AACA,SAAQ;AAAA,IAAC;AAAA;AAAA,MACJ,GAAG;AAAA,MACJ,cAAY,OAAO;AAAA,MACnB,WAAW,GAAG,gCAAgC,SAAS;AAAA,MAEvD;AAAA,QAAC;AAAA;AAAA,UACG,WAAU;AAAA,UAEV;AAAA,gCAAC,QACI,kBAAQ,UAAU,GAAG,OAAO,UAAW;AAAA,cAAC;AAAA;AAAA,gBACrC,WAAU;AAAA,gBACV,eAAY;AAAA;AAAA,YAChB,GAAK,cAAc,KAAK,YAAY,CAAC,GACzC;AAAA,YACC,QAAQ,IAAI,WAAS;AAClB,qBAAQ;AAAA,gBAAC;AAAA;AAAA,kBAGJ;AAAA,8BAAU,aAAa,eAAe,SAAS,cAAc,KAAK,CAAC,QAAQ,SAAS,cAAc,KAC5F,YAAY,gBAAgB,GAAG,gCAAgC,CAAC;AAAA,oBACtE,YAAY,OAAO,eAAe,SAAS,KAAK,IAAI,SAAY,GAAG,2DAA2D,CAAC;AAAA,oBAC/H,UAAU,KAAK,eAAe,SAAS,gBAAgB,KAAK,CAAC,QAAQ,SAAS,gBAAgB,KACxF,YAAY,kBAAkB,GAAG,gCAAgC,CAAC;AAAA;AAAA;AAAA,gBANpE;AAAA,cAOT;AAAA,YACJ,CAAC;AAAA,YACD,oBAAC,QACI,kBAAQ,UAAU,GAAG,OAAO,MAAO;AAAA,cAAC;AAAA;AAAA,gBACjC,WAAU;AAAA,gBACV,eAAY;AAAA;AAAA,YAChB,GAAK,YAAY,GACrB;AAAA;AAAA;AAAA,MACJ;AAAA;AAAA,EACJ;AACJ;",
|
|
6
6
|
"names": ["entries"]
|
|
7
7
|
}
|
|
@@ -14,9 +14,14 @@ export type PaginationLabels = {
|
|
|
14
14
|
};
|
|
15
15
|
export type PaginationProps = Omit<ComponentPropsWithRef<"nav">, "children" | "aria-label"> & {
|
|
16
16
|
readonly page: number;
|
|
17
|
-
readonly pageCount: number;
|
|
18
17
|
readonly labels: PaginationLabels;
|
|
19
18
|
} & ({
|
|
19
|
+
readonly pageCount: number;
|
|
20
|
+
readonly hasNextPage?: never;
|
|
21
|
+
} | {
|
|
22
|
+
readonly pageCount: null;
|
|
23
|
+
readonly hasNextPage: boolean;
|
|
24
|
+
}) & ({
|
|
20
25
|
readonly onPageChange: (page: number) => void;
|
|
21
26
|
readonly getPageHref?: never;
|
|
22
27
|
} | {
|
package/docs/catalog.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"name": "@gridui/pagination",
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"category": "core",
|
|
6
6
|
"description": "GridUI React pagination",
|
|
7
|
-
"usage": "
|
|
7
|
+
"usage": "Pass `pageCount={null}` and a boolean `hasNextPage` when the server does not provide a total. Pagination shows Previous, the current page, and Next. The host supplies either `onPageChange` or `getPageHref`, as with a known count. Previous is disabled on page 1; Next is disabled when no next page is available. No last page or total is inferred. Pages must remain positive safe integers; `Infinity` is rejected, and Next is disabled at `Number.MAX_SAFE_INTEGER`.",
|
|
8
8
|
"documentation": [
|
|
9
|
-
"README.md"
|
|
9
|
+
"README.md",
|
|
10
|
+
"docs/reference/README.md",
|
|
11
|
+
"docs/reference/pagination.md"
|
|
10
12
|
],
|
|
11
13
|
"exports": [
|
|
12
14
|
{
|
|
@@ -31,6 +33,8 @@
|
|
|
31
33
|
"@gridui/pagination/styles.css"
|
|
32
34
|
],
|
|
33
35
|
"examples": [
|
|
36
|
+
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/pagination/stories/getting-started.mdx",
|
|
37
|
+
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/pagination/stories/paginated-navigation.mdx",
|
|
34
38
|
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/pagination/stories/pagination.stories.tsx"
|
|
35
39
|
]
|
|
36
40
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<!-- Generated from public Props and owned stories. Run pnpm docs:storybook. -->
|
|
2
|
+
# Pagination
|
|
3
|
+
|
|
4
|
+
Navigates a collection divided into pages. Applications own the current page and the data shown for it.
|
|
5
|
+
|
|
6
|
+
Import from ``@gridui/pagination`` and load Theme before this family's stylesheet.
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
import { Pagination } from "@gridui/pagination";
|
|
10
|
+
import "@gridui/theme/styles.css";
|
|
11
|
+
import "@gridui/pagination/styles.css";
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Read the [package contract](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/pagination/README.md) for shared behavior and stylesheet dependencies.
|
|
15
|
+
|
|
16
|
+
The [working composition](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/pagination/stories/pagination.stories.tsx) demonstrates required context, state, and related components. Use View code in Storybook to inspect the actual implementation.
|
|
17
|
+
|
|
18
|
+
## API
|
|
19
|
+
|
|
20
|
+
The public Props type is the source of these signatures. Defaults below are explicit implementation defaults; story presets are separate. Native attributes remain available through the exported Props type.
|
|
21
|
+
|
|
22
|
+
### onFocus
|
|
23
|
+
|
|
24
|
+
``(event: FocusEvent<HTMLElement, Element>): void`` · Optional
|
|
25
|
+
|
|
26
|
+
Called when the corresponding interaction occurs; inspect the arguments in Actions.
|
|
27
|
+
|
|
28
|
+
### onBlur
|
|
29
|
+
|
|
30
|
+
``(event: FocusEvent<HTMLElement, Element>): void`` · Optional
|
|
31
|
+
|
|
32
|
+
Called when the corresponding interaction occurs; inspect the arguments in Actions.
|
|
33
|
+
|
|
34
|
+
### onChange
|
|
35
|
+
|
|
36
|
+
``(event: ChangeEvent<HTMLElement, Element>): void`` · Optional
|
|
37
|
+
|
|
38
|
+
Called when the corresponding interaction occurs; inspect the arguments in Actions.
|
|
39
|
+
|
|
40
|
+
### onSubmit
|
|
41
|
+
|
|
42
|
+
``(event: SubmitEvent<HTMLElement>): void`` · Optional
|
|
43
|
+
|
|
44
|
+
Called when the corresponding interaction occurs; inspect the arguments in Actions.
|
|
45
|
+
|
|
46
|
+
### onClick
|
|
47
|
+
|
|
48
|
+
``(event: MouseEvent<HTMLElement, MouseEvent>): void`` · Optional
|
|
49
|
+
|
|
50
|
+
Called when the corresponding interaction occurs; inspect the arguments in Actions.
|
|
51
|
+
|
|
52
|
+
### page
|
|
53
|
+
|
|
54
|
+
``number`` · Required
|
|
55
|
+
|
|
56
|
+
### labels
|
|
57
|
+
|
|
58
|
+
``PaginationLabels`` · Required
|
|
59
|
+
|
|
60
|
+
### pageCount
|
|
61
|
+
|
|
62
|
+
``number | null`` · Required
|
|
63
|
+
|
|
64
|
+
### hasNextPage
|
|
65
|
+
|
|
66
|
+
``boolean | undefined`` · Optional
|
|
67
|
+
|
|
68
|
+
### onPageChange
|
|
69
|
+
|
|
70
|
+
``(page: number): void`` · Optional
|
|
71
|
+
|
|
72
|
+
Called when the corresponding interaction occurs; inspect the arguments in Actions.
|
|
73
|
+
|
|
74
|
+
### getPageHref
|
|
75
|
+
|
|
76
|
+
``((page: number) => string) | undefined`` · Optional
|
|
77
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridui/pagination",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "GridUI React pagination",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"react-dom": "^19.2.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@gridui/button": "^
|
|
31
|
-
"@gridui/style-utils": "^
|
|
32
|
-
"@gridui/theme": "^2.5.
|
|
30
|
+
"@gridui/button": "^5.0.0",
|
|
31
|
+
"@gridui/style-utils": "^4.0.0",
|
|
32
|
+
"@gridui/theme": "^2.5.4",
|
|
33
33
|
"lucide-react": "1.70.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|