@puzzle-ui/ui 0.3.0 → 0.5.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 +70 -70
- package/dist/components/actions/button/button.css +5 -2
- package/dist/components/actions/button-group/button-group.css +16 -17
- package/dist/components/data-display/badge/badge.css +15 -2
- package/dist/components/data-display/badge/index.cjs +13 -2
- package/dist/components/data-display/badge/index.cjs.map +1 -1
- package/dist/components/data-display/badge/index.d.cts +7 -2
- package/dist/components/data-display/badge/index.d.ts +7 -2
- package/dist/components/data-display/badge/index.js +13 -2
- package/dist/components/data-display/badge/index.js.map +1 -1
- package/dist/components/data-display/empty-state/empty-state.css +128 -0
- package/dist/components/data-display/empty-state/empty-state.utils.cjs +6 -0
- package/dist/components/data-display/empty-state/empty-state.utils.cjs.map +1 -0
- package/dist/components/data-display/empty-state/empty-state.utils.js +6 -0
- package/dist/components/data-display/empty-state/empty-state.utils.js.map +1 -0
- package/dist/components/data-display/empty-state/index.cjs +49 -0
- package/dist/components/data-display/empty-state/index.cjs.map +1 -0
- package/dist/components/data-display/empty-state/index.d.cts +19 -0
- package/dist/components/data-display/empty-state/index.d.ts +19 -0
- package/dist/components/data-display/empty-state/index.js +44 -0
- package/dist/components/data-display/empty-state/index.js.map +1 -0
- package/dist/components/data-display/rating/index.cjs +84 -0
- package/dist/components/data-display/rating/index.cjs.map +1 -0
- package/dist/components/data-display/rating/index.d.cts +3 -0
- package/dist/components/data-display/rating/index.d.ts +3 -0
- package/dist/components/data-display/rating/index.js +84 -0
- package/dist/components/data-display/rating/index.js.map +1 -0
- package/dist/components/data-display/rating/rating.css +72 -0
- package/dist/components/data-display/rating/rating.types.d.cts +15 -0
- package/dist/components/data-display/rating/rating.types.d.ts +15 -0
- package/dist/components/data-display/rating/rating.utils.cjs +27 -0
- package/dist/components/data-display/rating/rating.utils.cjs.map +1 -0
- package/dist/components/data-display/rating/rating.utils.js +25 -0
- package/dist/components/data-display/rating/rating.utils.js.map +1 -0
- package/dist/components/editors/text-editor/editor.cjs.map +1 -1
- package/dist/components/editors/text-editor/editor.js.map +1 -1
- package/dist/components/editors/text-editor/text-document.cjs.map +1 -1
- package/dist/components/editors/text-editor/text-document.js.map +1 -1
- package/dist/components/editors/text-editor/text-parser.cjs.map +1 -1
- package/dist/components/editors/text-editor/text-parser.js.map +1 -1
- package/dist/components/editors/text-editor/text-renderer.cjs.map +1 -1
- package/dist/components/editors/text-editor/text-renderer.js.map +1 -1
- package/dist/components/forms/autocomplete/index.cjs.map +1 -1
- package/dist/components/forms/autocomplete/index.js.map +1 -1
- package/dist/components/forms/checkbox/checkbox.css +2 -10
- package/dist/components/forms/color-picker/color-picker.css +351 -0
- package/dist/components/forms/color-picker/color-picker.types.d.cts +25 -0
- package/dist/components/forms/color-picker/color-picker.types.d.ts +25 -0
- package/dist/components/forms/color-picker/color-picker.utils.cjs +116 -0
- package/dist/components/forms/color-picker/color-picker.utils.cjs.map +1 -0
- package/dist/components/forms/color-picker/color-picker.utils.js +109 -0
- package/dist/components/forms/color-picker/color-picker.utils.js.map +1 -0
- package/dist/components/forms/color-picker/index.cjs +340 -0
- package/dist/components/forms/color-picker/index.cjs.map +1 -0
- package/dist/components/forms/color-picker/index.d.cts +3 -0
- package/dist/components/forms/color-picker/index.d.ts +3 -0
- package/dist/components/forms/color-picker/index.js +340 -0
- package/dist/components/forms/color-picker/index.js.map +1 -0
- package/dist/components/forms/file-upload/file-upload.utils.cjs.map +1 -1
- package/dist/components/forms/file-upload/file-upload.utils.js.map +1 -1
- package/dist/components/forms/input/number-input.js +5 -5
- package/dist/components/forms/input/number-input.js.map +1 -1
- package/dist/components/forms/input-group/index.d.cts +3 -0
- package/dist/components/forms/input-group/index.d.ts +3 -0
- package/dist/components/forms/input-group/input-group.cjs +18 -0
- package/dist/components/forms/input-group/input-group.cjs.map +1 -0
- package/dist/components/forms/input-group/input-group.css +62 -0
- package/dist/components/forms/input-group/input-group.d.cts +7 -0
- package/dist/components/forms/input-group/input-group.d.ts +7 -0
- package/dist/components/forms/input-group/input-group.js +18 -0
- package/dist/components/forms/input-group/input-group.js.map +1 -0
- package/dist/components/forms/input-group/input-group.types.d.cts +7 -0
- package/dist/components/forms/input-group/input-group.types.d.ts +7 -0
- package/dist/components/forms/input-group/input-group.utils.cjs +5 -0
- package/dist/components/forms/input-group/input-group.utils.cjs.map +1 -0
- package/dist/components/forms/input-group/input-group.utils.js +5 -0
- package/dist/components/forms/input-group/input-group.utils.js.map +1 -0
- package/dist/components/forms/radio-group/index.d.cts +2 -1
- package/dist/components/forms/radio-group/index.d.ts +2 -1
- package/dist/components/forms/select/index.cjs.map +1 -1
- package/dist/components/forms/select/index.js.map +1 -1
- package/dist/components/forms/slider/index.cjs +1 -1
- package/dist/components/forms/slider/index.cjs.map +1 -1
- package/dist/components/forms/slider/index.js +1 -1
- package/dist/components/forms/slider/index.js.map +1 -1
- package/dist/components/forms/stepper/index.d.cts +4 -2
- package/dist/components/forms/stepper/index.d.ts +4 -2
- package/dist/components/forms/time-picker/index.cjs +108 -0
- package/dist/components/forms/time-picker/index.cjs.map +1 -0
- package/dist/components/forms/time-picker/index.d.cts +3 -0
- package/dist/components/forms/time-picker/index.d.ts +3 -0
- package/dist/components/forms/time-picker/index.js +108 -0
- package/dist/components/forms/time-picker/index.js.map +1 -0
- package/dist/components/forms/time-picker/time-picker.css +166 -0
- package/dist/components/forms/time-picker/time-picker.types.d.cts +34 -0
- package/dist/components/forms/time-picker/time-picker.types.d.ts +34 -0
- package/dist/components/forms/time-picker/time-picker.utils.cjs +25 -0
- package/dist/components/forms/time-picker/time-picker.utils.cjs.map +1 -0
- package/dist/components/forms/time-picker/time-picker.utils.js +24 -0
- package/dist/components/forms/time-picker/time-picker.utils.js.map +1 -0
- package/dist/components/forms/token-input/index.cjs +189 -0
- package/dist/components/forms/token-input/index.cjs.map +1 -0
- package/dist/components/forms/token-input/index.d.cts +3 -0
- package/dist/components/forms/token-input/index.d.ts +3 -0
- package/dist/components/forms/token-input/index.js +189 -0
- package/dist/components/forms/token-input/index.js.map +1 -0
- package/dist/components/forms/token-input/token-input.css +145 -0
- package/dist/components/forms/token-input/token-input.types.d.cts +48 -0
- package/dist/components/forms/token-input/token-input.types.d.ts +48 -0
- package/dist/components/forms/token-input/token-input.utils.cjs +30 -0
- package/dist/components/forms/token-input/token-input.utils.cjs.map +1 -0
- package/dist/components/forms/token-input/token-input.utils.js +24 -0
- package/dist/components/forms/token-input/token-input.utils.js.map +1 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.css +14 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.cjs +11 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.cjs.map +1 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.js +11 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.js.map +1 -0
- package/dist/components/layout/aspect-ratio/index.cjs +16 -0
- package/dist/components/layout/aspect-ratio/index.cjs.map +1 -0
- package/dist/components/layout/aspect-ratio/index.d.cts +11 -0
- package/dist/components/layout/aspect-ratio/index.d.ts +11 -0
- package/dist/components/layout/aspect-ratio/index.js +16 -0
- package/dist/components/layout/aspect-ratio/index.js.map +1 -0
- package/dist/components/layout/container/container.css +1 -0
- package/dist/components/layout/page-layout/page-layout.css +1 -0
- package/dist/components/layout/resizable-panels/index.cjs +1 -1
- package/dist/components/layout/resizable-panels/index.cjs.map +1 -1
- package/dist/components/layout/resizable-panels/index.js +1 -1
- package/dist/components/layout/resizable-panels/index.js.map +1 -1
- package/dist/components/layout/resizable-panels/resizable-panels.utils.cjs.map +1 -1
- package/dist/components/layout/resizable-panels/resizable-panels.utils.js.map +1 -1
- package/dist/components/layout/scroll-area/index.cjs +27 -0
- package/dist/components/layout/scroll-area/index.cjs.map +1 -0
- package/dist/components/layout/scroll-area/index.d.cts +15 -0
- package/dist/components/layout/scroll-area/index.d.ts +15 -0
- package/dist/components/layout/scroll-area/index.js +27 -0
- package/dist/components/layout/scroll-area/index.js.map +1 -0
- package/dist/components/layout/scroll-area/scroll-area.css +25 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.cjs +8 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.cjs.map +1 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.d.cts +2 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.d.ts +2 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.js +8 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.js.map +1 -0
- package/dist/components/layout/section/index.cjs +10 -4
- package/dist/components/layout/section/index.cjs.map +1 -1
- package/dist/components/layout/section/index.d.cts +1 -1
- package/dist/components/layout/section/index.d.ts +1 -1
- package/dist/components/layout/section/index.js +11 -5
- package/dist/components/layout/section/index.js.map +1 -1
- package/dist/components/layout/section/section.css +9 -3
- package/dist/components/layout/section/types.d.cts +5 -5
- package/dist/components/layout/section/types.d.ts +5 -5
- package/dist/components/layout/separator/index.cjs +18 -0
- package/dist/components/layout/separator/index.cjs.map +1 -0
- package/dist/components/layout/separator/index.d.cts +17 -0
- package/dist/components/layout/separator/index.d.ts +17 -0
- package/dist/components/layout/separator/index.js +18 -0
- package/dist/components/layout/separator/index.js.map +1 -0
- package/dist/components/layout/separator/separator.css +15 -0
- package/dist/components/layout/separator/separator.utils.cjs +11 -0
- package/dist/components/layout/separator/separator.utils.cjs.map +1 -0
- package/dist/components/layout/separator/separator.utils.d.cts +2 -0
- package/dist/components/layout/separator/separator.utils.d.ts +2 -0
- package/dist/components/layout/separator/separator.utils.js +11 -0
- package/dist/components/layout/separator/separator.utils.js.map +1 -0
- package/dist/components/layout/stack/index.cjs +18 -2
- package/dist/components/layout/stack/index.cjs.map +1 -1
- package/dist/components/layout/stack/index.d.cts +8 -6
- package/dist/components/layout/stack/index.d.ts +8 -6
- package/dist/components/layout/stack/index.js +18 -2
- package/dist/components/layout/stack/index.js.map +1 -1
- package/dist/components/layout/stack/stack.css +118 -138
- package/dist/components/navigation/accordion/index.cjs.map +1 -1
- package/dist/components/navigation/accordion/index.js.map +1 -1
- package/dist/components/navigation/carousel/index.cjs +5 -2
- package/dist/components/navigation/carousel/index.cjs.map +1 -1
- package/dist/components/navigation/carousel/index.js +5 -2
- package/dist/components/navigation/carousel/index.js.map +1 -1
- package/dist/components/navigation/pagination/index.cjs +146 -0
- package/dist/components/navigation/pagination/index.cjs.map +1 -0
- package/dist/components/navigation/pagination/index.d.cts +3 -0
- package/dist/components/navigation/pagination/index.d.ts +3 -0
- package/dist/components/navigation/pagination/index.js +146 -0
- package/dist/components/navigation/pagination/index.js.map +1 -0
- package/dist/components/navigation/pagination/pagination.css +134 -0
- package/dist/components/navigation/pagination/pagination.types.d.cts +38 -0
- package/dist/components/navigation/pagination/pagination.types.d.ts +38 -0
- package/dist/components/navigation/pagination/pagination.utils.cjs +54 -0
- package/dist/components/navigation/pagination/pagination.utils.cjs.map +1 -0
- package/dist/components/navigation/pagination/pagination.utils.js +53 -0
- package/dist/components/navigation/pagination/pagination.utils.js.map +1 -0
- package/dist/components/navigation/tabs/index.d.cts +3 -2
- package/dist/components/navigation/tabs/index.d.ts +3 -2
- package/dist/components/navigation/tree-view/index.cjs.map +1 -1
- package/dist/components/navigation/tree-view/index.js.map +1 -1
- package/dist/components/overlays/context-menu/context-menu.css +151 -0
- package/dist/components/overlays/context-menu/context-menu.types.d.cts +69 -0
- package/dist/components/overlays/context-menu/context-menu.types.d.ts +69 -0
- package/dist/components/overlays/context-menu/context-menu.utils.cjs +46 -0
- package/dist/components/overlays/context-menu/context-menu.utils.cjs.map +1 -0
- package/dist/components/overlays/context-menu/context-menu.utils.js +40 -0
- package/dist/components/overlays/context-menu/context-menu.utils.js.map +1 -0
- package/dist/components/overlays/context-menu/index.cjs +830 -0
- package/dist/components/overlays/context-menu/index.cjs.map +1 -0
- package/dist/components/overlays/context-menu/index.d.cts +42 -0
- package/dist/components/overlays/context-menu/index.d.ts +42 -0
- package/dist/components/overlays/context-menu/index.js +818 -0
- package/dist/components/overlays/context-menu/index.js.map +1 -0
- package/dist/components/overlays/dropdown-menu/dropdown-menu-content.cjs.map +1 -1
- package/dist/components/overlays/dropdown-menu/dropdown-menu-content.js.map +1 -1
- package/dist/components/overlays/dropdown-menu/dropdown-menu.utils.cjs.map +1 -1
- package/dist/components/overlays/dropdown-menu/dropdown-menu.utils.js.map +1 -1
- package/dist/components/typography/heading.cjs +6 -2
- package/dist/components/typography/heading.cjs.map +1 -1
- package/dist/components/typography/heading.d.cts +3 -2
- package/dist/components/typography/heading.d.ts +3 -2
- package/dist/components/typography/heading.js +6 -2
- package/dist/components/typography/heading.js.map +1 -1
- package/dist/components/typography/text.cjs +6 -2
- package/dist/components/typography/text.cjs.map +1 -1
- package/dist/components/typography/text.d.cts +3 -2
- package/dist/components/typography/text.d.ts +3 -2
- package/dist/components/typography/text.js +6 -2
- package/dist/components/typography/text.js.map +1 -1
- package/dist/components/utilities/preview/index.cjs +89 -21
- package/dist/components/utilities/preview/index.cjs.map +1 -1
- package/dist/components/utilities/preview/index.d.cts +6 -2
- package/dist/components/utilities/preview/index.d.ts +6 -2
- package/dist/components/utilities/preview/index.js +89 -21
- package/dist/components/utilities/preview/index.js.map +1 -1
- package/dist/components/utilities/preview/preview.css +26 -11
- package/dist/components/utilities/transition/index.d.cts +1 -1
- package/dist/components/utilities/transition/index.d.ts +1 -1
- package/dist/index.cjs +136 -97
- package/dist/index.d.cts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +12 -1
- package/package.json +7 -6
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Link } from "../link/index.js";
|
|
3
|
+
import { getPaginationItems, normalizePage } from "./pagination.utils.js";
|
|
4
|
+
import "./pagination.css";
|
|
5
|
+
import { cn } from "@puzzle-ui/core";
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
// src/components/navigation/pagination/index.tsx
|
|
9
|
+
const defaultLabels = {
|
|
10
|
+
navigation: "Pagination",
|
|
11
|
+
first: "Go to first page",
|
|
12
|
+
previous: "Go to previous page",
|
|
13
|
+
next: "Go to next page",
|
|
14
|
+
last: "Go to last page",
|
|
15
|
+
ellipsis: "More pages",
|
|
16
|
+
page: (page) => `Go to page ${page}`
|
|
17
|
+
};
|
|
18
|
+
const Pagination = ({ totalPages, page, defaultPage = 1, onPageChange, siblingCount = 1, boundaryCount = 1, showFirstLast = true, disabled = false, size = "md", labels, getPageHref, getPageAriaLabel, className, ...navProps }) => {
|
|
19
|
+
const [internalPage, setInternalPage] = useState(() => normalizePage(defaultPage, totalPages));
|
|
20
|
+
const isControlled = page !== void 0;
|
|
21
|
+
const currentPage = normalizePage(isControlled ? page : internalPage, totalPages);
|
|
22
|
+
const resolvedLabels = {
|
|
23
|
+
...defaultLabels,
|
|
24
|
+
...labels
|
|
25
|
+
};
|
|
26
|
+
const items = getPaginationItems(totalPages, currentPage, boundaryCount, siblingCount);
|
|
27
|
+
const changePage = (nextPage) => {
|
|
28
|
+
if (disabled) return;
|
|
29
|
+
const normalizedPage = normalizePage(nextPage, totalPages);
|
|
30
|
+
if (normalizedPage === 0 || normalizedPage === currentPage) return;
|
|
31
|
+
if (!isControlled) setInternalPage(normalizedPage);
|
|
32
|
+
onPageChange?.(normalizedPage);
|
|
33
|
+
};
|
|
34
|
+
const renderControl = (type, targetPage, content, ariaLabel) => {
|
|
35
|
+
const isDisabled = disabled || totalPages === 0 || targetPage < 1 || targetPage > totalPages || targetPage === currentPage;
|
|
36
|
+
const controlClass = cn("puzzle-pagination__control", "puzzle-pagination__navigation", isDisabled && "puzzle-pagination__control--disabled");
|
|
37
|
+
if (getPageHref && !isDisabled) return /* @__PURE__ */ jsx(Link, {
|
|
38
|
+
href: getPageHref(targetPage),
|
|
39
|
+
className: controlClass,
|
|
40
|
+
"aria-label": ariaLabel,
|
|
41
|
+
onClick: () => changePage(targetPage),
|
|
42
|
+
"data-pagination-action": type,
|
|
43
|
+
children: content
|
|
44
|
+
});
|
|
45
|
+
return /* @__PURE__ */ jsx("button", {
|
|
46
|
+
type: "button",
|
|
47
|
+
className: controlClass,
|
|
48
|
+
disabled: isDisabled,
|
|
49
|
+
"aria-label": ariaLabel,
|
|
50
|
+
onClick: () => changePage(targetPage),
|
|
51
|
+
"data-pagination-action": type,
|
|
52
|
+
children: content
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
return /* @__PURE__ */ jsx("nav", {
|
|
56
|
+
...navProps,
|
|
57
|
+
"aria-label": navProps["aria-label"] ?? resolvedLabels.navigation,
|
|
58
|
+
className: cn("puzzle-pagination", `puzzle-pagination--${size}`, className),
|
|
59
|
+
"data-disabled": disabled || void 0,
|
|
60
|
+
children: /* @__PURE__ */ jsxs("ul", {
|
|
61
|
+
className: "puzzle-pagination__list",
|
|
62
|
+
children: [
|
|
63
|
+
showFirstLast && /* @__PURE__ */ jsx("li", {
|
|
64
|
+
className: "puzzle-pagination__item",
|
|
65
|
+
children: renderControl("first", 1, /* @__PURE__ */ jsx("span", {
|
|
66
|
+
"aria-hidden": "true",
|
|
67
|
+
children: "«"
|
|
68
|
+
}), resolvedLabels.first)
|
|
69
|
+
}),
|
|
70
|
+
/* @__PURE__ */ jsx("li", {
|
|
71
|
+
className: "puzzle-pagination__item",
|
|
72
|
+
children: renderControl("previous", currentPage - 1, /* @__PURE__ */ jsx("span", {
|
|
73
|
+
"aria-hidden": "true",
|
|
74
|
+
children: "‹"
|
|
75
|
+
}), resolvedLabels.previous)
|
|
76
|
+
}),
|
|
77
|
+
items.map((item) => {
|
|
78
|
+
if (item.type === "ellipsis") return /* @__PURE__ */ jsx("li", {
|
|
79
|
+
className: "puzzle-pagination__item",
|
|
80
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
81
|
+
className: "puzzle-pagination__ellipsis",
|
|
82
|
+
"aria-label": resolvedLabels.ellipsis,
|
|
83
|
+
children: "…"
|
|
84
|
+
})
|
|
85
|
+
}, `ellipsis-${item.position}`);
|
|
86
|
+
const isCurrent = item.page === currentPage;
|
|
87
|
+
const ariaLabel = getPageAriaLabel?.(item.page) ?? resolvedLabels.page(item.page);
|
|
88
|
+
const pageClass = cn("puzzle-pagination__control", "puzzle-pagination__page", isCurrent && "puzzle-pagination__page--active");
|
|
89
|
+
return /* @__PURE__ */ jsx("li", {
|
|
90
|
+
className: "puzzle-pagination__item",
|
|
91
|
+
children: getPageHref ? isCurrent ? /* @__PURE__ */ jsx("span", {
|
|
92
|
+
className: pageClass,
|
|
93
|
+
"aria-label": ariaLabel,
|
|
94
|
+
"aria-current": "page",
|
|
95
|
+
"aria-disabled": disabled || void 0,
|
|
96
|
+
children: item.page
|
|
97
|
+
}) : disabled ? /* @__PURE__ */ jsx("span", {
|
|
98
|
+
className: cn(pageClass, "puzzle-pagination__control--disabled"),
|
|
99
|
+
"aria-label": ariaLabel,
|
|
100
|
+
"aria-disabled": "true",
|
|
101
|
+
children: item.page
|
|
102
|
+
}) : /* @__PURE__ */ jsx(Link, {
|
|
103
|
+
href: getPageHref(item.page),
|
|
104
|
+
className: pageClass,
|
|
105
|
+
"aria-label": ariaLabel,
|
|
106
|
+
"aria-current": void 0,
|
|
107
|
+
onClick: () => changePage(item.page),
|
|
108
|
+
children: item.page
|
|
109
|
+
}) : isCurrent ? /* @__PURE__ */ jsx("span", {
|
|
110
|
+
className: pageClass,
|
|
111
|
+
"aria-label": ariaLabel,
|
|
112
|
+
"aria-current": "page",
|
|
113
|
+
"aria-disabled": disabled || void 0,
|
|
114
|
+
children: item.page
|
|
115
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
116
|
+
type: "button",
|
|
117
|
+
className: pageClass,
|
|
118
|
+
"aria-label": ariaLabel,
|
|
119
|
+
"aria-current": isCurrent ? "page" : void 0,
|
|
120
|
+
disabled: disabled || isCurrent,
|
|
121
|
+
onClick: () => changePage(item.page),
|
|
122
|
+
children: item.page
|
|
123
|
+
})
|
|
124
|
+
}, item.page);
|
|
125
|
+
}),
|
|
126
|
+
/* @__PURE__ */ jsx("li", {
|
|
127
|
+
className: "puzzle-pagination__item",
|
|
128
|
+
children: renderControl("next", currentPage + 1, /* @__PURE__ */ jsx("span", {
|
|
129
|
+
"aria-hidden": "true",
|
|
130
|
+
children: "›"
|
|
131
|
+
}), resolvedLabels.next)
|
|
132
|
+
}),
|
|
133
|
+
showFirstLast && /* @__PURE__ */ jsx("li", {
|
|
134
|
+
className: "puzzle-pagination__item",
|
|
135
|
+
children: renderControl("last", totalPages, /* @__PURE__ */ jsx("span", {
|
|
136
|
+
"aria-hidden": "true",
|
|
137
|
+
children: "»"
|
|
138
|
+
}), resolvedLabels.last)
|
|
139
|
+
})
|
|
140
|
+
]
|
|
141
|
+
})
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
export { Pagination };
|
|
145
|
+
|
|
146
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/navigation/pagination/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { cn } from \"@puzzle-ui/core\";\nimport { Link } from \"../link\";\n\nimport type {\n PaginationItemType,\n PaginationLabels,\n PaginationProps,\n} from \"./pagination.types\";\n\nimport { getPaginationItems, normalizePage } from \"./pagination.utils\";\n\nimport \"./pagination.css\";\n\nconst defaultLabels: PaginationLabels = {\n navigation: \"Pagination\",\n first: \"Go to first page\",\n previous: \"Go to previous page\",\n next: \"Go to next page\",\n last: \"Go to last page\",\n ellipsis: \"More pages\",\n page: (page) => `Go to page ${page}`,\n};\n\nconst Pagination = ({\n totalPages,\n page,\n defaultPage = 1,\n onPageChange,\n siblingCount = 1,\n boundaryCount = 1,\n showFirstLast = true,\n disabled = false,\n size = \"md\",\n labels,\n getPageHref,\n getPageAriaLabel,\n className,\n ...navProps\n}: PaginationProps) => {\n const [internalPage, setInternalPage] = useState(() =>\n normalizePage(defaultPage, totalPages),\n );\n\n const isControlled = page !== undefined;\n const currentPage = normalizePage(\n isControlled ? page : internalPage,\n totalPages,\n );\n\n const resolvedLabels = {\n ...defaultLabels,\n ...labels,\n };\n\n const items = getPaginationItems(\n totalPages,\n currentPage,\n boundaryCount,\n siblingCount,\n );\n\n const changePage = (nextPage: number) => {\n if (disabled) return;\n\n const normalizedPage = normalizePage(nextPage, totalPages);\n\n if (normalizedPage === 0 || normalizedPage === currentPage) return;\n\n if (!isControlled) {\n setInternalPage(normalizedPage);\n }\n\n onPageChange?.(normalizedPage);\n };\n\n const renderControl = (\n type: PaginationItemType,\n targetPage: number,\n content: React.ReactNode,\n ariaLabel: string,\n ) => {\n const isDisabled =\n disabled ||\n totalPages === 0 ||\n targetPage < 1 ||\n targetPage > totalPages ||\n targetPage === currentPage;\n\n const controlClass = cn(\n \"puzzle-pagination__control\",\n \"puzzle-pagination__navigation\",\n isDisabled && \"puzzle-pagination__control--disabled\",\n );\n\n if (getPageHref && !isDisabled) {\n return (\n <Link\n href={getPageHref(targetPage)}\n className={controlClass}\n aria-label={ariaLabel}\n onClick={() => changePage(targetPage)}\n data-pagination-action={type}\n >\n {content}\n </Link>\n );\n }\n\n return (\n <button\n type=\"button\"\n className={controlClass}\n disabled={isDisabled}\n aria-label={ariaLabel}\n onClick={() => changePage(targetPage)}\n data-pagination-action={type}\n >\n {content}\n </button>\n );\n };\n\n return (\n <nav\n {...navProps}\n aria-label={navProps[\"aria-label\"] ?? resolvedLabels.navigation}\n className={cn(\n \"puzzle-pagination\",\n `puzzle-pagination--${size}`,\n className,\n )}\n data-disabled={disabled || undefined}\n >\n <ul className=\"puzzle-pagination__list\">\n {showFirstLast && (\n <li className=\"puzzle-pagination__item\">\n {renderControl(\n \"first\",\n 1,\n <span aria-hidden=\"true\">«</span>,\n resolvedLabels.first,\n )}\n </li>\n )}\n\n <li className=\"puzzle-pagination__item\">\n {renderControl(\n \"previous\",\n currentPage - 1,\n <span aria-hidden=\"true\">‹</span>,\n resolvedLabels.previous,\n )}\n </li>\n\n {items.map((item) => {\n if (item.type === \"ellipsis\") {\n return (\n <li\n key={`ellipsis-${item.position}`}\n className=\"puzzle-pagination__item\"\n >\n <span\n className=\"puzzle-pagination__ellipsis\"\n aria-label={resolvedLabels.ellipsis}\n >\n …\n </span>\n </li>\n );\n }\n\n const isCurrent = item.page === currentPage;\n const ariaLabel =\n getPageAriaLabel?.(item.page) ?? resolvedLabels.page(item.page);\n\n const pageClass = cn(\n \"puzzle-pagination__control\",\n \"puzzle-pagination__page\",\n isCurrent && \"puzzle-pagination__page--active\",\n );\n\n return (\n <li key={item.page} className=\"puzzle-pagination__item\">\n {getPageHref ? (\n isCurrent ? (\n <span\n className={pageClass}\n aria-label={ariaLabel}\n aria-current=\"page\"\n aria-disabled={disabled || undefined}\n >\n {item.page}\n </span>\n ) : disabled ? (\n <span\n className={cn(\n pageClass,\n \"puzzle-pagination__control--disabled\",\n )}\n aria-label={ariaLabel}\n aria-disabled=\"true\"\n >\n {item.page}\n </span>\n ) : (\n <Link\n href={getPageHref(item.page)}\n className={pageClass}\n aria-label={ariaLabel}\n aria-current={undefined}\n onClick={() => changePage(item.page)}\n >\n {item.page}\n </Link>\n )\n ) : isCurrent ? (\n <span\n className={pageClass}\n aria-label={ariaLabel}\n aria-current=\"page\"\n aria-disabled={disabled || undefined}\n >\n {item.page}\n </span>\n ) : (\n <button\n type=\"button\"\n className={pageClass}\n aria-label={ariaLabel}\n aria-current={isCurrent ? \"page\" : undefined}\n disabled={disabled || isCurrent}\n onClick={() => changePage(item.page)}\n >\n {item.page}\n </button>\n )}\n </li>\n );\n })}\n\n <li className=\"puzzle-pagination__item\">\n {renderControl(\n \"next\",\n currentPage + 1,\n <span aria-hidden=\"true\">›</span>,\n resolvedLabels.next,\n )}\n </li>\n\n {showFirstLast && (\n <li className=\"puzzle-pagination__item\">\n {renderControl(\n \"last\",\n totalPages,\n <span aria-hidden=\"true\">»</span>,\n resolvedLabels.last,\n )}\n </li>\n )}\n </ul>\n </nav>\n );\n};\n\nexport { Pagination, type PaginationProps };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
.puzzle-pagination {
|
|
2
|
+
--puzzle-pagination-size: 2.25rem;
|
|
3
|
+
--puzzle-pagination-gap: var(--puzzle-space-1, .25rem);
|
|
4
|
+
--puzzle-pagination-radius: var(--puzzle-radius-md, .375rem);
|
|
5
|
+
--puzzle-pagination-color: var(--puzzle-color-text, #171717);
|
|
6
|
+
--puzzle-pagination-muted: var(--puzzle-color-text-muted, #737373);
|
|
7
|
+
--puzzle-pagination-border: var(--puzzle-color-border, #e5e0d6);
|
|
8
|
+
--puzzle-pagination-active-bg: var(--puzzle-color-primary);
|
|
9
|
+
--puzzle-pagination-active-color: var(--puzzle-color-on-primary, #fff);
|
|
10
|
+
--puzzle-pagination-focus: var(--puzzle-color-ring, currentColor);
|
|
11
|
+
width: fit-content;
|
|
12
|
+
max-width: 100%;
|
|
13
|
+
color: var(--puzzle-pagination-color);
|
|
14
|
+
display: flex;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.puzzle-pagination--sm {
|
|
18
|
+
--puzzle-pagination-size: 1.875rem;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.puzzle-pagination--md {
|
|
22
|
+
--puzzle-pagination-size: 2.25rem;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.puzzle-pagination__list {
|
|
26
|
+
justify-content: center;
|
|
27
|
+
align-items: center;
|
|
28
|
+
gap: var(--puzzle-pagination-gap);
|
|
29
|
+
flex-wrap: wrap;
|
|
30
|
+
margin: 0;
|
|
31
|
+
padding: 0;
|
|
32
|
+
list-style: none;
|
|
33
|
+
display: flex;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.puzzle-pagination__item {
|
|
37
|
+
flex: none;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
align-items: center;
|
|
40
|
+
display: flex;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.puzzle-pagination__control {
|
|
44
|
+
width: var(--puzzle-pagination-size);
|
|
45
|
+
height: var(--puzzle-pagination-size);
|
|
46
|
+
border-radius: var(--puzzle-pagination-radius);
|
|
47
|
+
color: var(--puzzle-pagination-color);
|
|
48
|
+
font-family: inherit;
|
|
49
|
+
font-size: var(--puzzle-font-size-body2, .875rem);
|
|
50
|
+
font-weight: var(--puzzle-font-weight-medium, 500);
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
user-select: none;
|
|
53
|
+
touch-action: manipulation;
|
|
54
|
+
transition: background-color var(--puzzle-duration-fast, .15s) ease,
|
|
55
|
+
color var(--puzzle-duration-fast, .15s) ease,
|
|
56
|
+
border-color var(--puzzle-duration-fast, .15s) ease;
|
|
57
|
+
background: none;
|
|
58
|
+
border: 1px solid #0000;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
align-items: center;
|
|
61
|
+
padding: 0;
|
|
62
|
+
line-height: 1;
|
|
63
|
+
text-decoration: none;
|
|
64
|
+
display: inline-flex;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.puzzle-pagination__control:hover:not(:disabled):not(.puzzle-pagination__control--disabled):not(.puzzle-pagination__page--active) {
|
|
68
|
+
background: var(--puzzle-color-action-hover, #8080801a);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.puzzle-pagination__control:focus-visible {
|
|
72
|
+
outline: 2px solid var(--puzzle-pagination-focus);
|
|
73
|
+
outline-offset: 2px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.puzzle-pagination__page--active {
|
|
77
|
+
border-color: var(--puzzle-pagination-active-bg);
|
|
78
|
+
background: var(--puzzle-pagination-active-bg);
|
|
79
|
+
color: var(--puzzle-pagination-active-color);
|
|
80
|
+
cursor: default;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.puzzle-pagination__navigation {
|
|
84
|
+
border-color: var(--puzzle-pagination-border);
|
|
85
|
+
font-size: 1.25rem;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.puzzle-pagination__control:disabled, .puzzle-pagination__control--disabled {
|
|
89
|
+
color: var(--puzzle-pagination-muted);
|
|
90
|
+
cursor: not-allowed;
|
|
91
|
+
opacity: .45;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.puzzle-pagination__ellipsis {
|
|
95
|
+
width: var(--puzzle-pagination-size);
|
|
96
|
+
height: var(--puzzle-pagination-size);
|
|
97
|
+
color: var(--puzzle-pagination-muted);
|
|
98
|
+
user-select: none;
|
|
99
|
+
justify-content: center;
|
|
100
|
+
align-items: center;
|
|
101
|
+
font-size: 1rem;
|
|
102
|
+
display: inline-flex;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.puzzle-pagination[data-disabled] {
|
|
106
|
+
opacity: .65;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@media (forced-colors: active) {
|
|
110
|
+
.puzzle-pagination__control {
|
|
111
|
+
border-color: buttontext;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.puzzle-pagination__page--active {
|
|
115
|
+
color: highlighttext;
|
|
116
|
+
background: highlight;
|
|
117
|
+
border: 2px solid highlight;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.puzzle-pagination__control:focus-visible {
|
|
121
|
+
outline: 2px solid highlight;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.puzzle-pagination__control:disabled, .puzzle-pagination__control--disabled {
|
|
125
|
+
color: graytext;
|
|
126
|
+
opacity: 1;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@media (prefers-reduced-motion: reduce) {
|
|
131
|
+
.puzzle-pagination__control {
|
|
132
|
+
transition: none;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef } from "react";
|
|
2
|
+
type PaginationSize = "sm" | "md";
|
|
3
|
+
type PaginationLabels = {
|
|
4
|
+
navigation: string;
|
|
5
|
+
first: string;
|
|
6
|
+
previous: string;
|
|
7
|
+
next: string;
|
|
8
|
+
last: string;
|
|
9
|
+
ellipsis: string;
|
|
10
|
+
page: (page: number) => string;
|
|
11
|
+
};
|
|
12
|
+
type PaginationProps = Omit<ComponentPropsWithoutRef<"nav">, "children" | "onChange"> & {
|
|
13
|
+
/** Total number of available pages. */
|
|
14
|
+
totalPages: number;
|
|
15
|
+
/** Current page for controlled usage. Pages start at 1. */
|
|
16
|
+
page?: number;
|
|
17
|
+
/** Initial page for uncontrolled usage. Defaults to 1. */
|
|
18
|
+
defaultPage?: number;
|
|
19
|
+
/** Called when the selected page changes. */
|
|
20
|
+
onPageChange?: (page: number) => void;
|
|
21
|
+
/** Number of pages displayed around the current page. */
|
|
22
|
+
siblingCount?: number;
|
|
23
|
+
/** Number of pages always displayed at both boundaries. */
|
|
24
|
+
boundaryCount?: number;
|
|
25
|
+
/** Whether first and last page controls are displayed. */
|
|
26
|
+
showFirstLast?: boolean;
|
|
27
|
+
/** Whether all pagination controls are disabled. */
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
/** Visual size of the pagination controls. */
|
|
30
|
+
size?: PaginationSize;
|
|
31
|
+
/** Accessible labels for navigation controls. */
|
|
32
|
+
labels?: Partial<PaginationLabels>;
|
|
33
|
+
/** Generate a URL for a page instead of using a button. */
|
|
34
|
+
getPageHref?: (page: number) => string;
|
|
35
|
+
/** Accessible label for a specific page. */
|
|
36
|
+
getPageAriaLabel?: (page: number) => string;
|
|
37
|
+
};
|
|
38
|
+
export type { PaginationLabels, PaginationProps, PaginationSize };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef } from "react";
|
|
2
|
+
type PaginationSize = "sm" | "md";
|
|
3
|
+
type PaginationLabels = {
|
|
4
|
+
navigation: string;
|
|
5
|
+
first: string;
|
|
6
|
+
previous: string;
|
|
7
|
+
next: string;
|
|
8
|
+
last: string;
|
|
9
|
+
ellipsis: string;
|
|
10
|
+
page: (page: number) => string;
|
|
11
|
+
};
|
|
12
|
+
type PaginationProps = Omit<ComponentPropsWithoutRef<"nav">, "children" | "onChange"> & {
|
|
13
|
+
/** Total number of available pages. */
|
|
14
|
+
totalPages: number;
|
|
15
|
+
/** Current page for controlled usage. Pages start at 1. */
|
|
16
|
+
page?: number;
|
|
17
|
+
/** Initial page for uncontrolled usage. Defaults to 1. */
|
|
18
|
+
defaultPage?: number;
|
|
19
|
+
/** Called when the selected page changes. */
|
|
20
|
+
onPageChange?: (page: number) => void;
|
|
21
|
+
/** Number of pages displayed around the current page. */
|
|
22
|
+
siblingCount?: number;
|
|
23
|
+
/** Number of pages always displayed at both boundaries. */
|
|
24
|
+
boundaryCount?: number;
|
|
25
|
+
/** Whether first and last page controls are displayed. */
|
|
26
|
+
showFirstLast?: boolean;
|
|
27
|
+
/** Whether all pagination controls are disabled. */
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
/** Visual size of the pagination controls. */
|
|
30
|
+
size?: PaginationSize;
|
|
31
|
+
/** Accessible labels for navigation controls. */
|
|
32
|
+
labels?: Partial<PaginationLabels>;
|
|
33
|
+
/** Generate a URL for a page instead of using a button. */
|
|
34
|
+
getPageHref?: (page: number) => string;
|
|
35
|
+
/** Accessible label for a specific page. */
|
|
36
|
+
getPageAriaLabel?: (page: number) => string;
|
|
37
|
+
};
|
|
38
|
+
export type { PaginationLabels, PaginationProps, PaginationSize };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// src/components/navigation/pagination/pagination.utils.ts
|
|
2
|
+
const normalizeCount = (value) => Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;
|
|
3
|
+
const getPaginationItems = (totalPages, currentPage, boundaryCount = 1, siblingCount = 1) => {
|
|
4
|
+
const total = normalizeCount(totalPages);
|
|
5
|
+
const boundaries = normalizeCount(boundaryCount);
|
|
6
|
+
const siblings = normalizeCount(siblingCount);
|
|
7
|
+
if (total === 0) return [];
|
|
8
|
+
const page = Math.min(Math.max(1, normalizeCount(currentPage)), total);
|
|
9
|
+
if (total <= boundaries * 2 + siblings * 2 + 3) return Array.from({ length: total }, (_, index) => ({
|
|
10
|
+
type: "page",
|
|
11
|
+
page: index + 1
|
|
12
|
+
}));
|
|
13
|
+
const visiblePages = /* @__PURE__ */ new Set();
|
|
14
|
+
for (let index = 1; index <= Math.min(boundaries, total); index += 1) visiblePages.add(index);
|
|
15
|
+
for (let index = Math.max(1, total - boundaries + 1); index <= total; index += 1) visiblePages.add(index);
|
|
16
|
+
for (let index = Math.max(1, page - siblings); index <= Math.min(total, page + siblings); index += 1) visiblePages.add(index);
|
|
17
|
+
if (page - siblings <= boundaries + 1) visiblePages.add(boundaries + siblings + 1);
|
|
18
|
+
if (page + siblings >= total - boundaries - 1) visiblePages.add(total - boundaries - siblings);
|
|
19
|
+
const pages = [...visiblePages].sort((a, b) => a - b);
|
|
20
|
+
const items = [];
|
|
21
|
+
pages.forEach((current, index) => {
|
|
22
|
+
if (index === 0) {
|
|
23
|
+
items.push({
|
|
24
|
+
type: "page",
|
|
25
|
+
page: current
|
|
26
|
+
});
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const previous = pages[index - 1];
|
|
30
|
+
const difference = current - previous;
|
|
31
|
+
if (difference === 2) items.push({
|
|
32
|
+
type: "page",
|
|
33
|
+
page: previous + 1
|
|
34
|
+
});
|
|
35
|
+
else if (difference > 2) items.push({
|
|
36
|
+
type: "ellipsis",
|
|
37
|
+
position: index === 1 ? "start" : "end"
|
|
38
|
+
});
|
|
39
|
+
items.push({
|
|
40
|
+
type: "page",
|
|
41
|
+
page: current
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
return items;
|
|
45
|
+
};
|
|
46
|
+
const normalizePage = (page, totalPages) => {
|
|
47
|
+
const total = normalizeCount(totalPages);
|
|
48
|
+
if (total === 0) return 0;
|
|
49
|
+
return Math.min(Math.max(1, Number.isFinite(page) ? Math.floor(page) : 1), total);
|
|
50
|
+
};
|
|
51
|
+
exports.getPaginationItems = getPaginationItems;
|
|
52
|
+
exports.normalizePage = normalizePage;
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=pagination.utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.utils.cjs","names":[],"sources":["../../../../src/components/navigation/pagination/pagination.utils.ts"],"sourcesContent":["import type { PaginationItem } from \"./pagination.types\";\n\nconst normalizeCount = (value: number) =>\n Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;\n\nconst getPaginationItems = (\n totalPages: number,\n currentPage: number,\n boundaryCount = 1,\n siblingCount = 1,\n): PaginationItem[] => {\n const total = normalizeCount(totalPages);\n const boundaries = normalizeCount(boundaryCount);\n const siblings = normalizeCount(siblingCount);\n\n if (total === 0) return [];\n\n const page = Math.min(Math.max(1, normalizeCount(currentPage)), total);\n\n if (total <= boundaries * 2 + siblings * 2 + 3) {\n return Array.from({ length: total }, (_, index) => ({\n type: \"page\",\n page: index + 1,\n }));\n }\n\n const visiblePages = new Set<number>();\n\n for (let index = 1; index <= Math.min(boundaries, total); index += 1) {\n visiblePages.add(index);\n }\n\n for (\n let index = Math.max(1, total - boundaries + 1);\n index <= total;\n index += 1\n ) {\n visiblePages.add(index);\n }\n\n for (\n let index = Math.max(1, page - siblings);\n index <= Math.min(total, page + siblings);\n index += 1\n ) {\n visiblePages.add(index);\n }\n\n if (page - siblings <= boundaries + 1) {\n visiblePages.add(boundaries + siblings + 1);\n }\n\n if (page + siblings >= total - boundaries - 1) {\n visiblePages.add(total - boundaries - siblings);\n }\n\n const pages = [...visiblePages].sort((a, b) => a - b);\n const items: PaginationItem[] = [];\n\n pages.forEach((current, index) => {\n if (index === 0) {\n items.push({ type: \"page\", page: current });\n return;\n }\n\n const previous = pages[index - 1]!;\n const difference = current - previous;\n\n if (difference === 2) {\n items.push({\n type: \"page\",\n page: previous + 1,\n });\n } else if (difference > 2) {\n items.push({\n type: \"ellipsis\",\n position: index === 1 ? \"start\" : \"end\",\n });\n }\n\n items.push({\n type: \"page\",\n page: current,\n });\n });\n\n return items;\n};\n\nconst normalizePage = (page: number, totalPages: number) => {\n const total = normalizeCount(totalPages);\n\n if (total === 0) return 0;\n\n const normalized = Number.isFinite(page) ? Math.floor(page) : 1;\n\n return Math.min(Math.max(1, normalized), total);\n};\n\nexport { getPaginationItems, normalizePage };\n"],"mappings":";AAEA,MAAM,kBAAkB,UACtB,OAAO,SAAS,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,IAAI;AAE5D,MAAM,sBACJ,YACA,aACA,gBAAgB,GAChB,eAAe,MACM;CACrB,MAAM,QAAQ,eAAe,UAAU;CACvC,MAAM,aAAa,eAAe,aAAa;CAC/C,MAAM,WAAW,eAAe,YAAY;CAE5C,IAAI,UAAU,GAAG,OAAO,CAAC;CAEzB,MAAM,OAAO,KAAK,IAAI,KAAK,IAAI,GAAG,eAAe,WAAW,CAAC,GAAG,KAAK;CAErE,IAAI,SAAS,aAAa,IAAI,WAAW,IAAI,GAC3C,OAAO,MAAM,KAAK,EAAE,QAAQ,MAAM,IAAI,GAAG,WAAW;EAClD,MAAM;EACN,MAAM,QAAQ;CAChB,EAAE;CAGJ,MAAM,+BAAe,IAAI,IAAY;CAErC,KAAK,IAAI,QAAQ,GAAG,SAAS,KAAK,IAAI,YAAY,KAAK,GAAG,SAAS,GACjE,aAAa,IAAI,KAAK;CAGxB,KACE,IAAI,QAAQ,KAAK,IAAI,GAAG,QAAQ,aAAa,CAAC,GAC9C,SAAS,OACT,SAAS,GAET,aAAa,IAAI,KAAK;CAGxB,KACE,IAAI,QAAQ,KAAK,IAAI,GAAG,OAAO,QAAQ,GACvC,SAAS,KAAK,IAAI,OAAO,OAAO,QAAQ,GACxC,SAAS,GAET,aAAa,IAAI,KAAK;CAGxB,IAAI,OAAO,YAAY,aAAa,GAClC,aAAa,IAAI,aAAa,WAAW,CAAC;CAG5C,IAAI,OAAO,YAAY,QAAQ,aAAa,GAC1C,aAAa,IAAI,QAAQ,aAAa,QAAQ;CAGhD,MAAM,QAAQ,CAAC,GAAG,YAAY,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;CACpD,MAAM,QAA0B,CAAC;CAEjC,MAAM,SAAS,SAAS,UAAU;EAChC,IAAI,UAAU,GAAG;GACf,MAAM,KAAK;IAAE,MAAM;IAAQ,MAAM;GAAQ,CAAC;GAC1C;EACF;EAEA,MAAM,WAAW,MAAM,QAAQ;EAC/B,MAAM,aAAa,UAAU;EAE7B,IAAI,eAAe,GACjB,MAAM,KAAK;GACT,MAAM;GACN,MAAM,WAAW;EACnB,CAAC;OACI,IAAI,aAAa,GACtB,MAAM,KAAK;GACT,MAAM;GACN,UAAU,UAAU,IAAI,UAAU;EACpC,CAAC;EAGH,MAAM,KAAK;GACT,MAAM;GACN,MAAM;EACR,CAAC;CACH,CAAC;CAED,OAAO;AACT;AAEA,MAAM,iBAAiB,MAAc,eAAuB;CAC1D,MAAM,QAAQ,eAAe,UAAU;CAEvC,IAAI,UAAU,GAAG,OAAO;CAIxB,OAAO,KAAK,IAAI,KAAK,IAAI,GAFN,OAAO,SAAS,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,CAExB,GAAG,KAAK;AAChD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// src/components/navigation/pagination/pagination.utils.ts
|
|
2
|
+
const normalizeCount = (value) => Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;
|
|
3
|
+
const getPaginationItems = (totalPages, currentPage, boundaryCount = 1, siblingCount = 1) => {
|
|
4
|
+
const total = normalizeCount(totalPages);
|
|
5
|
+
const boundaries = normalizeCount(boundaryCount);
|
|
6
|
+
const siblings = normalizeCount(siblingCount);
|
|
7
|
+
if (total === 0) return [];
|
|
8
|
+
const page = Math.min(Math.max(1, normalizeCount(currentPage)), total);
|
|
9
|
+
if (total <= boundaries * 2 + siblings * 2 + 3) return Array.from({ length: total }, (_, index) => ({
|
|
10
|
+
type: "page",
|
|
11
|
+
page: index + 1
|
|
12
|
+
}));
|
|
13
|
+
const visiblePages = /* @__PURE__ */ new Set();
|
|
14
|
+
for (let index = 1; index <= Math.min(boundaries, total); index += 1) visiblePages.add(index);
|
|
15
|
+
for (let index = Math.max(1, total - boundaries + 1); index <= total; index += 1) visiblePages.add(index);
|
|
16
|
+
for (let index = Math.max(1, page - siblings); index <= Math.min(total, page + siblings); index += 1) visiblePages.add(index);
|
|
17
|
+
if (page - siblings <= boundaries + 1) visiblePages.add(boundaries + siblings + 1);
|
|
18
|
+
if (page + siblings >= total - boundaries - 1) visiblePages.add(total - boundaries - siblings);
|
|
19
|
+
const pages = [...visiblePages].sort((a, b) => a - b);
|
|
20
|
+
const items = [];
|
|
21
|
+
pages.forEach((current, index) => {
|
|
22
|
+
if (index === 0) {
|
|
23
|
+
items.push({
|
|
24
|
+
type: "page",
|
|
25
|
+
page: current
|
|
26
|
+
});
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const previous = pages[index - 1];
|
|
30
|
+
const difference = current - previous;
|
|
31
|
+
if (difference === 2) items.push({
|
|
32
|
+
type: "page",
|
|
33
|
+
page: previous + 1
|
|
34
|
+
});
|
|
35
|
+
else if (difference > 2) items.push({
|
|
36
|
+
type: "ellipsis",
|
|
37
|
+
position: index === 1 ? "start" : "end"
|
|
38
|
+
});
|
|
39
|
+
items.push({
|
|
40
|
+
type: "page",
|
|
41
|
+
page: current
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
return items;
|
|
45
|
+
};
|
|
46
|
+
const normalizePage = (page, totalPages) => {
|
|
47
|
+
const total = normalizeCount(totalPages);
|
|
48
|
+
if (total === 0) return 0;
|
|
49
|
+
return Math.min(Math.max(1, Number.isFinite(page) ? Math.floor(page) : 1), total);
|
|
50
|
+
};
|
|
51
|
+
export { getPaginationItems, normalizePage };
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=pagination.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.utils.js","names":[],"sources":["../../../../src/components/navigation/pagination/pagination.utils.ts"],"sourcesContent":["import type { PaginationItem } from \"./pagination.types\";\n\nconst normalizeCount = (value: number) =>\n Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;\n\nconst getPaginationItems = (\n totalPages: number,\n currentPage: number,\n boundaryCount = 1,\n siblingCount = 1,\n): PaginationItem[] => {\n const total = normalizeCount(totalPages);\n const boundaries = normalizeCount(boundaryCount);\n const siblings = normalizeCount(siblingCount);\n\n if (total === 0) return [];\n\n const page = Math.min(Math.max(1, normalizeCount(currentPage)), total);\n\n if (total <= boundaries * 2 + siblings * 2 + 3) {\n return Array.from({ length: total }, (_, index) => ({\n type: \"page\",\n page: index + 1,\n }));\n }\n\n const visiblePages = new Set<number>();\n\n for (let index = 1; index <= Math.min(boundaries, total); index += 1) {\n visiblePages.add(index);\n }\n\n for (\n let index = Math.max(1, total - boundaries + 1);\n index <= total;\n index += 1\n ) {\n visiblePages.add(index);\n }\n\n for (\n let index = Math.max(1, page - siblings);\n index <= Math.min(total, page + siblings);\n index += 1\n ) {\n visiblePages.add(index);\n }\n\n if (page - siblings <= boundaries + 1) {\n visiblePages.add(boundaries + siblings + 1);\n }\n\n if (page + siblings >= total - boundaries - 1) {\n visiblePages.add(total - boundaries - siblings);\n }\n\n const pages = [...visiblePages].sort((a, b) => a - b);\n const items: PaginationItem[] = [];\n\n pages.forEach((current, index) => {\n if (index === 0) {\n items.push({ type: \"page\", page: current });\n return;\n }\n\n const previous = pages[index - 1]!;\n const difference = current - previous;\n\n if (difference === 2) {\n items.push({\n type: \"page\",\n page: previous + 1,\n });\n } else if (difference > 2) {\n items.push({\n type: \"ellipsis\",\n position: index === 1 ? \"start\" : \"end\",\n });\n }\n\n items.push({\n type: \"page\",\n page: current,\n });\n });\n\n return items;\n};\n\nconst normalizePage = (page: number, totalPages: number) => {\n const total = normalizeCount(totalPages);\n\n if (total === 0) return 0;\n\n const normalized = Number.isFinite(page) ? Math.floor(page) : 1;\n\n return Math.min(Math.max(1, normalized), total);\n};\n\nexport { getPaginationItems, normalizePage };\n"],"mappings":";AAEA,MAAM,kBAAkB,UACtB,OAAO,SAAS,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,IAAI;AAE5D,MAAM,sBACJ,YACA,aACA,gBAAgB,GAChB,eAAe,MACM;CACrB,MAAM,QAAQ,eAAe,UAAU;CACvC,MAAM,aAAa,eAAe,aAAa;CAC/C,MAAM,WAAW,eAAe,YAAY;CAE5C,IAAI,UAAU,GAAG,OAAO,CAAC;CAEzB,MAAM,OAAO,KAAK,IAAI,KAAK,IAAI,GAAG,eAAe,WAAW,CAAC,GAAG,KAAK;CAErE,IAAI,SAAS,aAAa,IAAI,WAAW,IAAI,GAC3C,OAAO,MAAM,KAAK,EAAE,QAAQ,MAAM,IAAI,GAAG,WAAW;EAClD,MAAM;EACN,MAAM,QAAQ;CAChB,EAAE;CAGJ,MAAM,+BAAe,IAAI,IAAY;CAErC,KAAK,IAAI,QAAQ,GAAG,SAAS,KAAK,IAAI,YAAY,KAAK,GAAG,SAAS,GACjE,aAAa,IAAI,KAAK;CAGxB,KACE,IAAI,QAAQ,KAAK,IAAI,GAAG,QAAQ,aAAa,CAAC,GAC9C,SAAS,OACT,SAAS,GAET,aAAa,IAAI,KAAK;CAGxB,KACE,IAAI,QAAQ,KAAK,IAAI,GAAG,OAAO,QAAQ,GACvC,SAAS,KAAK,IAAI,OAAO,OAAO,QAAQ,GACxC,SAAS,GAET,aAAa,IAAI,KAAK;CAGxB,IAAI,OAAO,YAAY,aAAa,GAClC,aAAa,IAAI,aAAa,WAAW,CAAC;CAG5C,IAAI,OAAO,YAAY,QAAQ,aAAa,GAC1C,aAAa,IAAI,QAAQ,aAAa,QAAQ;CAGhD,MAAM,QAAQ,CAAC,GAAG,YAAY,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;CACpD,MAAM,QAA0B,CAAC;CAEjC,MAAM,SAAS,SAAS,UAAU;EAChC,IAAI,UAAU,GAAG;GACf,MAAM,KAAK;IAAE,MAAM;IAAQ,MAAM;GAAQ,CAAC;GAC1C;EACF;EAEA,MAAM,WAAW,MAAM,QAAQ;EAC/B,MAAM,aAAa,UAAU;EAE7B,IAAI,eAAe,GACjB,MAAM,KAAK;GACT,MAAM;GACN,MAAM,WAAW;EACnB,CAAC;OACI,IAAI,aAAa,GACtB,MAAM,KAAK;GACT,MAAM;GACN,UAAU,UAAU,IAAI,UAAU;EACpC,CAAC;EAGH,MAAM,KAAK;GACT,MAAM;GACN,MAAM;EACR,CAAC;CACH,CAAC;CAED,OAAO;AACT;AAEA,MAAM,iBAAiB,MAAc,eAAuB;CAC1D,MAAM,QAAQ,eAAe,UAAU;CAEvC,IAAI,UAAU,GAAG,OAAO;CAIxB,OAAO,KAAK,IAAI,KAAK,IAAI,GAFN,OAAO,SAAS,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,CAExB,GAAG,KAAK;AAChD"}
|
|
@@ -24,7 +24,8 @@ type TabsProps = Omit<ComponentPropsWithoutRef<"div">, "children" | "onChange">
|
|
|
24
24
|
children: ReactNode;
|
|
25
25
|
};
|
|
26
26
|
declare const TabsTab: ({ children }: TabsTabProps) => import("react").JSX.Element;
|
|
27
|
-
declare const
|
|
28
|
-
|
|
27
|
+
declare const TabsRoot: ({ tabBarPosition, initialActiveId, activeId, onActivate, forceMountContent, children, className, ...rootProps }: TabsProps) => import("react").JSX.Element;
|
|
28
|
+
declare const Tabs: typeof TabsRoot & {
|
|
29
|
+
Tab: typeof TabsTab;
|
|
29
30
|
};
|
|
30
31
|
export { Tabs, type TabsPosition, type TabsProps, TabsTab, type TabsTabProps };
|
|
@@ -24,7 +24,8 @@ type TabsProps = Omit<ComponentPropsWithoutRef<"div">, "children" | "onChange">
|
|
|
24
24
|
children: ReactNode;
|
|
25
25
|
};
|
|
26
26
|
declare const TabsTab: ({ children }: TabsTabProps) => import("react").JSX.Element;
|
|
27
|
-
declare const
|
|
28
|
-
|
|
27
|
+
declare const TabsRoot: ({ tabBarPosition, initialActiveId, activeId, onActivate, forceMountContent, children, className, ...rootProps }: TabsProps) => import("react").JSX.Element;
|
|
28
|
+
declare const Tabs: typeof TabsRoot & {
|
|
29
|
+
Tab: typeof TabsTab;
|
|
29
30
|
};
|
|
30
31
|
export { Tabs, type TabsPosition, type TabsProps, TabsTab, type TabsTabProps };
|