@gridui/pagination 1.0.7 → 1.1.1
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 +18 -0
- package/dist/index.js +35 -11
- package/dist/index.js.map +3 -3
- package/dist/pagination/pagination.d.ts +6 -1
- package/dist/pagination/style.d.ts +14 -0
- package/docs/catalog.json +3 -2
- package/docs/reference/pagination.md +7 -3
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -5,6 +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).
|
|
9
27
|
|
|
10
28
|
[Component reference](docs/reference/README.md) contains focused API pages for each public component.
|
package/dist/index.js
CHANGED
|
@@ -52,6 +52,26 @@ var paginationRange = (page, pageCount, compact = false) => {
|
|
|
52
52
|
return entries;
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
+
// src/pagination/style.ts
|
|
56
|
+
import { cva } from "class-variance-authority";
|
|
57
|
+
var paginationControlStyles = cva("", {
|
|
58
|
+
variants: {
|
|
59
|
+
kind: {
|
|
60
|
+
page: "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",
|
|
61
|
+
navigation: ""
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
var paginationEntryStyles = cva("", {
|
|
66
|
+
variants: {
|
|
67
|
+
visibility: {
|
|
68
|
+
all: "",
|
|
69
|
+
desktop: "gridui-u-pagination--hidden gridui-u-pagination--md:block",
|
|
70
|
+
mobile: "gridui-u-pagination--md:hidden"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
55
75
|
// src/pagination/pagination.tsx
|
|
56
76
|
import { Button, ButtonLink } from "@gridui/button";
|
|
57
77
|
import { cn } from "@gridui/style-utils";
|
|
@@ -59,17 +79,21 @@ import { ChevronLeft, ChevronRight, Ellipsis } from "lucide-react";
|
|
|
59
79
|
import { Fragment } from "react";
|
|
60
80
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
61
81
|
var Pagination = (props) => {
|
|
62
|
-
const { page, pageCount, labels, onPageChange, getPageHref, className, ...restProps } = props;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
82
|
+
const { page, pageCount, hasNextPage, labels, onPageChange, getPageHref, className, ...restProps } = props;
|
|
83
|
+
if (pageCount === null && (!Number.isSafeInteger(page) || page < 1 || typeof hasNextPage !== "boolean")) {
|
|
84
|
+
throw new RangeError("Unknown-count Pagination requires a positive safe integer page and a boolean hasNextPage.");
|
|
85
|
+
}
|
|
86
|
+
const entries = pageCount === null ? [page] : paginationRange(page, pageCount);
|
|
87
|
+
const compactEntries = pageCount === null ? entries : paginationRange(page, pageCount, true);
|
|
88
|
+
const current = pageCount === null ? page : Math.max(1, Math.min(page, pageCount));
|
|
89
|
+
const nextDisabled = pageCount === null ? !hasNextPage || current === Number.MAX_SAFE_INTEGER : pageCount === 0 || current >= pageCount;
|
|
66
90
|
const control = (target, label, children, disabled, active = false) => {
|
|
67
91
|
const shared = {
|
|
68
92
|
"aria-label": label,
|
|
69
93
|
"aria-current": active ? "page" : void 0,
|
|
70
94
|
variant: active ? "secondary" : "quiet",
|
|
71
95
|
layout: "icon",
|
|
72
|
-
className: typeof children === "number" ? "
|
|
96
|
+
className: paginationControlStyles({ kind: typeof children === "number" ? "page" : "navigation" })
|
|
73
97
|
};
|
|
74
98
|
if (getPageHref && !disabled) {
|
|
75
99
|
return /* @__PURE__ */ jsx(
|
|
@@ -95,11 +119,11 @@ var Pagination = (props) => {
|
|
|
95
119
|
}
|
|
96
120
|
);
|
|
97
121
|
};
|
|
98
|
-
const renderEntry = (entry,
|
|
122
|
+
const renderEntry = (entry, visibility = "all") => {
|
|
99
123
|
return /* @__PURE__ */ jsx(
|
|
100
124
|
"li",
|
|
101
125
|
{
|
|
102
|
-
className:
|
|
126
|
+
className: paginationEntryStyles({ visibility }) || void 0,
|
|
103
127
|
children: typeof entry === "number" ? control(entry, labels.page(entry), entry, false, entry === current) : /* @__PURE__ */ jsx(
|
|
104
128
|
"span",
|
|
105
129
|
{
|
|
@@ -140,9 +164,9 @@ var Pagination = (props) => {
|
|
|
140
164
|
Fragment,
|
|
141
165
|
{
|
|
142
166
|
children: [
|
|
143
|
-
entry === pageCount && compactEntries.includes("end-ellipsis") && !entries.includes("end-ellipsis") && renderEntry("end-ellipsis",
|
|
144
|
-
renderEntry(entry, compactEntries.includes(entry) ?
|
|
145
|
-
entry === 1 && compactEntries.includes("start-ellipsis") && !entries.includes("start-ellipsis") && renderEntry("start-ellipsis",
|
|
167
|
+
entry === pageCount && compactEntries.includes("end-ellipsis") && !entries.includes("end-ellipsis") && renderEntry("end-ellipsis", "mobile"),
|
|
168
|
+
renderEntry(entry, compactEntries.includes(entry) ? "all" : "desktop"),
|
|
169
|
+
entry === 1 && compactEntries.includes("start-ellipsis") && !entries.includes("start-ellipsis") && renderEntry("start-ellipsis", "mobile")
|
|
146
170
|
]
|
|
147
171
|
},
|
|
148
172
|
entry
|
|
@@ -154,7 +178,7 @@ var Pagination = (props) => {
|
|
|
154
178
|
className: "gridui-u-pagination--rtl:rotate-180",
|
|
155
179
|
"aria-hidden": "true"
|
|
156
180
|
}
|
|
157
|
-
),
|
|
181
|
+
), nextDisabled) })
|
|
158
182
|
]
|
|
159
183
|
}
|
|
160
184
|
)
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 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;;;
|
|
3
|
+
"sources": ["../src/pagination/range.ts", "../src/pagination/style.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 Style\n */\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nexport const paginationControlStyles = cva(\"\", {\n variants: {\n kind: {\n page: \"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\",\n navigation: \"\",\n },\n },\n});\n\nexport const paginationEntryStyles = cva(\"\", {\n variants: {\n visibility: {\n all: \"\",\n desktop: \"gridui-u-pagination--hidden gridui-u-pagination--md:block\",\n mobile: \"gridui-u-pagination--md:hidden\",\n },\n },\n});\n\nexport type PaginationEntryVisibility = NonNullable<VariantProps<typeof paginationEntryStyles>[\"visibility\"]>;\n", "/**\n * @author WMXPY\n * @package Pagination\n * @namespace Pagination\n * @description Pagination\n */\n\nimport { type PaginationEntry, paginationRange } from \"./range\";\nimport { paginationControlStyles, paginationEntryStyles, type PaginationEntryVisibility } from \"./style\";\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: paginationControlStyles({ kind: typeof children === \"number\" ? \"page\" : \"navigation\" }),\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, visibility: PaginationEntryVisibility = \"all\") => {\n return (<li\n className={paginationEntryStyles({ visibility }) || undefined}\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\", \"mobile\")}\n {renderEntry(entry, compactEntries.includes(entry) ? \"all\" : \"desktop\")}\n {entry === 1 && compactEntries.includes(\"start-ellipsis\") && !entries.includes(\"start-ellipsis\")\n && renderEntry(\"start-ellipsis\", \"mobile\")}\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": "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",
|
|
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
|
} | {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author WMXPY
|
|
3
|
+
* @package Pagination
|
|
4
|
+
* @namespace Pagination
|
|
5
|
+
* @description Style
|
|
6
|
+
*/
|
|
7
|
+
import { type VariantProps } from "class-variance-authority";
|
|
8
|
+
export declare const paginationControlStyles: (props?: ({
|
|
9
|
+
kind?: "page" | "navigation" | null | undefined;
|
|
10
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
11
|
+
export declare const paginationEntryStyles: (props?: ({
|
|
12
|
+
visibility?: "all" | "desktop" | "mobile" | null | undefined;
|
|
13
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
14
|
+
export type PaginationEntryVisibility = NonNullable<VariantProps<typeof paginationEntryStyles>["visibility"]>;
|
package/docs/catalog.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"name": "@gridui/pagination",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.1",
|
|
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
9
|
"README.md",
|
|
10
10
|
"docs/reference/README.md",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"@gridui/pagination/styles.css"
|
|
34
34
|
],
|
|
35
35
|
"examples": [
|
|
36
|
+
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/pagination/stories/getting-started.mdx",
|
|
36
37
|
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/pagination/stories/paginated-navigation.mdx",
|
|
37
38
|
"https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/packages-core/pagination/stories/pagination.stories.tsx"
|
|
38
39
|
]
|
|
@@ -53,13 +53,17 @@ Called when the corresponding interaction occurs; inspect the arguments in Actio
|
|
|
53
53
|
|
|
54
54
|
``number`` · Required
|
|
55
55
|
|
|
56
|
+
### labels
|
|
57
|
+
|
|
58
|
+
``PaginationLabels`` · Required
|
|
59
|
+
|
|
56
60
|
### pageCount
|
|
57
61
|
|
|
58
|
-
``number`` · Required
|
|
62
|
+
``number | null`` · Required
|
|
59
63
|
|
|
60
|
-
###
|
|
64
|
+
### hasNextPage
|
|
61
65
|
|
|
62
|
-
``
|
|
66
|
+
``boolean | undefined`` · Optional
|
|
63
67
|
|
|
64
68
|
### onPageChange
|
|
65
69
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridui/pagination",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "GridUI React pagination",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -27,15 +27,16 @@
|
|
|
27
27
|
"react-dom": "^19.2.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@gridui/button": "^
|
|
30
|
+
"@gridui/button": "^5.0.1",
|
|
31
31
|
"@gridui/style-utils": "^4.0.0",
|
|
32
|
-
"@gridui/theme": "^2.
|
|
33
|
-
"
|
|
32
|
+
"@gridui/theme": "^2.6.0",
|
|
33
|
+
"class-variance-authority": "0.7.1",
|
|
34
|
+
"lucide-react": "1.72.0"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@gridui-internal/configuration": "0.0.0-internal",
|
|
37
38
|
"@jest/globals": "30.5.2",
|
|
38
|
-
"@storybook/react-vite": "10.6.
|
|
39
|
+
"@storybook/react-vite": "10.6.7",
|
|
39
40
|
"@types/jest": "30.0.0",
|
|
40
41
|
"@types/node": "26.6.6",
|
|
41
42
|
"@types/react": "19.3.0",
|
|
@@ -48,7 +49,6 @@
|
|
|
48
49
|
"scripts": {
|
|
49
50
|
"build": "node ../../scripts/compilation/package.ts",
|
|
50
51
|
"compile": "tsc --project tsconfig.json",
|
|
51
|
-
"test": "jest"
|
|
52
|
-
"coverage": "jest --coverage"
|
|
52
|
+
"test": "jest"
|
|
53
53
|
}
|
|
54
54
|
}
|