@jbpark/ui-kit 10.0.2 → 10.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.ko.md +7 -0
- package/README.md +7 -0
- package/dist/Breadcrumb.d.mts +39 -0
- package/dist/Breadcrumb.d.mts.map +1 -0
- package/dist/Breadcrumb.mjs +103 -0
- package/dist/Breadcrumb.mjs.map +1 -0
- package/dist/Pagination.d.mts +53 -0
- package/dist/Pagination.d.mts.map +1 -0
- package/dist/Pagination.mjs +208 -0
- package/dist/Pagination.mjs.map +1 -0
- package/dist/Table.d.mts +48 -0
- package/dist/Table.d.mts.map +1 -0
- package/dist/Table.mjs +119 -0
- package/dist/Table.mjs.map +1 -0
- package/dist/components/atoms/checkbox/checkbox.mjs +2 -1
- package/dist/components/atoms/checkbox/checkbox.mjs.map +1 -1
- package/dist/components/atoms/checkbox/group.mjs +2 -1
- package/dist/components/atoms/checkbox/group.mjs.map +1 -1
- package/dist/components/atoms/color-picker.mjs +1 -1
- package/dist/components/atoms/date-picker.mjs +1 -1
- package/dist/components/atoms/float-button/back-top.mjs +1 -1
- package/dist/components/atoms/index.d.mts +2 -1
- package/dist/components/atoms/input/search.mjs +3 -1
- package/dist/components/atoms/input/search.mjs.map +1 -1
- package/dist/components/atoms/popover.mjs +1 -1
- package/dist/components/atoms/radio/group.mjs +1 -1
- package/dist/components/atoms/radio/radio.mjs +2 -1
- package/dist/components/atoms/radio/radio.mjs.map +1 -1
- package/dist/components/atoms/select-multiple.d.mts +29 -0
- package/dist/components/atoms/select-multiple.d.mts.map +1 -0
- package/dist/components/atoms/select-multiple.mjs +97 -0
- package/dist/components/atoms/select-multiple.mjs.map +1 -0
- package/dist/components/atoms/select-searchable-options.d.mts +21 -0
- package/dist/components/atoms/select-searchable-options.d.mts.map +1 -0
- package/dist/components/atoms/select-searchable-options.mjs +62 -0
- package/dist/components/atoms/select-searchable-options.mjs.map +1 -0
- package/dist/components/atoms/select-searchable.d.mts +22 -0
- package/dist/components/atoms/select-searchable.d.mts.map +1 -0
- package/dist/components/atoms/select-searchable.mjs +65 -0
- package/dist/components/atoms/select-searchable.mjs.map +1 -0
- package/dist/components/atoms/select.d.mts +8 -2
- package/dist/components/atoms/select.d.mts.map +1 -1
- package/dist/components/atoms/select.mjs +11 -1
- package/dist/components/atoms/select.mjs.map +1 -1
- package/dist/components/atoms/slider/slider.mjs +1 -1
- package/dist/components/atoms/switch.mjs +1 -1
- package/dist/components/atoms/tooltip.d.mts +21 -0
- package/dist/components/atoms/tooltip.d.mts.map +1 -0
- package/dist/components/atoms/tooltip.mjs +78 -0
- package/dist/components/atoms/tooltip.mjs.map +1 -0
- package/dist/components/atoms/typography/paragraph.mjs +1 -0
- package/dist/components/atoms/typography/paragraph.mjs.map +1 -1
- package/dist/components/atoms/typography/title.mjs +1 -0
- package/dist/components/atoms/typography/title.mjs.map +1 -1
- package/dist/components/molecules/dropdown.mjs +1 -1
- package/dist/components/molecules/index.d.mts +13 -10
- package/dist/components/molecules/marquees/marquees.mjs +1 -1
- package/dist/components/molecules/menu/menu.mjs +2 -1
- package/dist/components/molecules/menu/menu.mjs.map +1 -1
- package/dist/components/molecules/tabs.d.mts +37 -0
- package/dist/components/molecules/tabs.d.mts.map +1 -0
- package/dist/components/molecules/tabs.mjs +51 -0
- package/dist/components/molecules/tabs.mjs.map +1 -0
- package/dist/components/molecules/upload.mjs +2 -1
- package/dist/components/molecules/upload.mjs.map +1 -1
- package/dist/components/organisms/drawer.d.mts.map +1 -1
- package/dist/components/organisms/drawer.mjs +7 -2
- package/dist/components/organisms/drawer.mjs.map +1 -1
- package/dist/components/organisms/index.d.mts +6 -5
- package/dist/components/organisms/list/list.mjs +1 -1
- package/dist/components/organisms/modal.d.mts.map +1 -1
- package/dist/components/organisms/modal.mjs +7 -4
- package/dist/components/organisms/modal.mjs.map +1 -1
- package/dist/components/organisms/toast.d.mts.map +1 -1
- package/dist/components/organisms/toast.mjs +2 -1
- package/dist/components/organisms/toast.mjs.map +1 -1
- package/dist/components/templates/empty.mjs +1 -0
- package/dist/components/templates/empty.mjs.map +1 -1
- package/dist/components/templates/layout/content.mjs +1 -0
- package/dist/components/templates/layout/content.mjs.map +1 -1
- package/dist/components/templates/layout/footer.mjs +1 -0
- package/dist/components/templates/layout/footer.mjs.map +1 -1
- package/dist/components/templates/layout/header.mjs +1 -0
- package/dist/components/templates/layout/header.mjs.map +1 -1
- package/dist/components/templates/layout/layout.mjs +1 -0
- package/dist/components/templates/layout/layout.mjs.map +1 -1
- package/dist/components/templates/layout/sider.mjs +3 -1
- package/dist/components/templates/layout/sider.mjs.map +1 -1
- package/dist/components/templates/page-header.mjs +1 -0
- package/dist/components/templates/page-header.mjs.map +1 -1
- package/dist/components/templates/result.mjs +1 -0
- package/dist/components/templates/result.mjs.map +1 -1
- package/dist/core/badge.d.mts +1 -1
- package/dist/core/button.d.mts +2 -2
- package/dist/core/combobox.d.mts +7 -0
- package/dist/core/combobox.d.mts.map +1 -0
- package/dist/core/combobox.mjs +99 -0
- package/dist/core/combobox.mjs.map +1 -0
- package/dist/core/dialog.mjs.map +1 -1
- package/dist/core/drawer.mjs.map +1 -1
- package/dist/core/field.mjs +2 -4
- package/dist/core/field.mjs.map +1 -1
- package/dist/core/index.d.mts +4 -1
- package/dist/core/select.mjs +27 -22
- package/dist/core/select.mjs.map +1 -1
- package/dist/core/tabs.d.mts +9 -0
- package/dist/core/tabs.d.mts.map +1 -0
- package/dist/core/tabs.mjs +59 -0
- package/dist/core/tabs.mjs.map +1 -0
- package/dist/core/tooltip.d.mts +2 -0
- package/dist/core/tooltip.mjs +41 -0
- package/dist/core/tooltip.mjs.map +1 -0
- package/dist/index.d.mts +31 -26
- package/dist/index.mjs +7 -2
- package/dist/lib/z-layers.mjs +21 -0
- package/dist/lib/z-layers.mjs.map +1 -1
- package/dist/providers/config/dark-mode.mjs +2 -10
- package/dist/providers/config/dark-mode.mjs.map +1 -1
- package/dist/style.css +195 -16
- package/package.json +17 -2
package/README.ko.md
CHANGED
|
@@ -145,6 +145,13 @@ function App() {
|
|
|
145
145
|
해당 요소에 `isolation: isolate`를 적용해 Base UI 포털이 앱 내부의 z-index와
|
|
146
146
|
경쟁하지 않고 페이지 콘텐츠 위에 표시되도록 합니다.
|
|
147
147
|
|
|
148
|
+
반대 방향으로도 효과가 있습니다. 오버레이(Modal, Drawer, Select, Popover)와
|
|
149
|
+
페이지 흐름 안에 고정되는 요소(sticky/fixed `Layout.Header`, `FloatButton`,
|
|
150
|
+
Dropdown 메뉴)는 모두 `z-index: 1000`을 씁니다. 루트를 격리하지 않으면 이
|
|
151
|
+
요소들이 z-index가 더 낮은 앱 자체의 다이얼로그(예: shadcn의 `z-50`)를 덮습니다.
|
|
152
|
+
`data-ui-root`를 지정하면 `body`로 포털되는 앱의 오버레이가 이 요소들을 포함한
|
|
153
|
+
앱 전체를 덮습니다.
|
|
154
|
+
|
|
148
155
|
### 개별 컴포넌트 import
|
|
149
156
|
|
|
150
157
|
```tsx
|
package/README.md
CHANGED
|
@@ -145,6 +145,13 @@ Put `data-ui-root` on your application layout root. The included stylesheet
|
|
|
145
145
|
applies `isolation: isolate` there so Base UI portals render above page content
|
|
146
146
|
without competing with z-index values inside the app.
|
|
147
147
|
|
|
148
|
+
It also works in the other direction. Overlays (Modal, Drawer, Select,
|
|
149
|
+
Popover) and in-flow chrome (sticky/fixed `Layout.Header`, `FloatButton`,
|
|
150
|
+
Dropdown menus) share `z-index: 1000`. Without an isolated root, that
|
|
151
|
+
chrome paints over your own dialogs if they use a lower z-index (for example
|
|
152
|
+
shadcn's `z-50`). With `data-ui-root`, any overlay you portal to `body`
|
|
153
|
+
covers the whole app, including this chrome.
|
|
154
|
+
|
|
148
155
|
### Import Individual Components
|
|
149
156
|
|
|
150
157
|
```tsx
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/components/molecules/breadcrumb.d.ts
|
|
2
|
+
interface Item {
|
|
3
|
+
key?: React.Key;
|
|
4
|
+
title: React.ReactNode;
|
|
5
|
+
href?: string;
|
|
6
|
+
target?: React.HTMLAttributeAnchorTarget;
|
|
7
|
+
rel?: string;
|
|
8
|
+
onClick?: React.MouseEventHandler<HTMLElement>;
|
|
9
|
+
className?: string;
|
|
10
|
+
'aria-label'?: string;
|
|
11
|
+
/** Decorative icon placed before the title. */
|
|
12
|
+
icon?: React.ReactNode;
|
|
13
|
+
/** Overrides the separator after this item. */
|
|
14
|
+
separator?: React.ReactNode;
|
|
15
|
+
}
|
|
16
|
+
interface Props extends Omit<React.ComponentPropsWithoutRef<'nav'>, 'children'> {
|
|
17
|
+
items: Item[];
|
|
18
|
+
separator?: React.ReactNode;
|
|
19
|
+
/** Collapse middle items when the trail has more than this many entries. */
|
|
20
|
+
maxItems?: number;
|
|
21
|
+
itemsBeforeCollapse?: number;
|
|
22
|
+
itemsAfterCollapse?: number;
|
|
23
|
+
expandText?: string;
|
|
24
|
+
/** Render custom router links. The renderer owns aria-current for the last item. */
|
|
25
|
+
itemRender?: (item: Item, index: number, isCurrent: boolean) => React.ReactNode;
|
|
26
|
+
classNames?: {
|
|
27
|
+
list?: string;
|
|
28
|
+
item?: string;
|
|
29
|
+
link?: string;
|
|
30
|
+
current?: string;
|
|
31
|
+
separator?: string;
|
|
32
|
+
collapsed?: string;
|
|
33
|
+
popup?: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
declare const Breadcrumb: ({ items, separator, maxItems, itemsBeforeCollapse, itemsAfterCollapse, expandText, itemRender, className, classNames, dir, "aria-label": ariaLabel, ...props }: Props) => import("react").JSX.Element;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { Item, Props, Breadcrumb as default };
|
|
39
|
+
//# sourceMappingURL=Breadcrumb.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Breadcrumb.d.mts","names":[],"sources":["../src/components/molecules/breadcrumb.tsx"],"mappings":";UAUiB;EACf,MAAM,MAAM;EACZ,OAAO,MAAM;EACb;EACA,SAAS,MAAM;EACf;EACA,UAAU,MAAM,kBAAkB;EAClC;EACA;;EAEA,OAAO,MAAM;;EAEb,YAAY,MAAM;;UAGH,cAAc,KAC7B,MAAM;EAGN,OAAO;EACP,YAAY,MAAM;;EAElB;EACA;EACA;EACA;;EAEA,cACE,MAAM,MACN,eACA,uBACG,MAAM;EACX;IACE;IACA;IACA;IACA;IACA;IACA;IACA;;;cAOE,eAAc,OAAA,WAAA,UAAA,qBAAA,oBAAA,YAAA,YAAA,WAAA,YAAA,mBAAA,cAAA,SAajB,0BAAK,IAAA"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "./utils.mjs";
|
|
3
|
+
import { useConfig } from "./providers/config/context.mjs";
|
|
4
|
+
import Button from "./Button.mjs";
|
|
5
|
+
import Popover from "./components/atoms/popover.mjs";
|
|
6
|
+
import { Fragment } from "react";
|
|
7
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
//#region src/components/molecules/breadcrumb.tsx
|
|
9
|
+
const safeCount = (value, minimum) => Number.isFinite(value) ? Math.max(minimum, Math.floor(value)) : minimum;
|
|
10
|
+
const Breadcrumb = ({ items, separator = "/", maxItems = 8, itemsBeforeCollapse = 1, itemsAfterCollapse = 1, expandText = "Show path", itemRender, className, classNames, dir, "aria-label": ariaLabel, ...props }) => {
|
|
11
|
+
const { direction } = useConfig();
|
|
12
|
+
const limit = safeCount(maxItems, 3);
|
|
13
|
+
const before = Math.min(safeCount(itemsBeforeCollapse, 1), limit - 2);
|
|
14
|
+
const after = Math.min(safeCount(itemsAfterCollapse, 1), limit - before - 1);
|
|
15
|
+
const collapsed = items.length > limit && items.length - before - after > 0;
|
|
16
|
+
const visibleIndices = collapsed ? [...Array.from({ length: before }, (_, index) => index), ...Array.from({ length: after }, (_, index) => items.length - after + index)] : items.map((_, index) => index);
|
|
17
|
+
const hiddenIndices = collapsed ? Array.from({ length: items.length - before - after }, (_, index) => before + index) : [];
|
|
18
|
+
const renderItem = (index) => {
|
|
19
|
+
const item = items[index];
|
|
20
|
+
const isCurrent = index === items.length - 1;
|
|
21
|
+
if (itemRender) return itemRender(item, index, isCurrent);
|
|
22
|
+
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [item.icon != null && /* @__PURE__ */ jsx("span", {
|
|
23
|
+
"data-slot": "breadcrumb-icon",
|
|
24
|
+
"aria-hidden": "true",
|
|
25
|
+
className: "inline-flex shrink-0",
|
|
26
|
+
children: item.icon
|
|
27
|
+
}), item.title] });
|
|
28
|
+
const itemClassName = cn("inline-flex items-center gap-1.5 rounded-sm", (item.href !== void 0 || item.onClick) && "hover:text-foreground focus-visible:outline-ring focus-visible:outline-2", isCurrent ? "text-foreground font-medium" : "text-muted-foreground", (item.href !== void 0 || item.onClick) && classNames?.link, isCurrent && classNames?.current, item.className);
|
|
29
|
+
if (item.href !== void 0) return /* @__PURE__ */ jsx("a", {
|
|
30
|
+
href: item.href,
|
|
31
|
+
target: item.target,
|
|
32
|
+
rel: item.rel,
|
|
33
|
+
onClick: item.onClick,
|
|
34
|
+
"aria-label": item["aria-label"],
|
|
35
|
+
"aria-current": isCurrent ? "page" : void 0,
|
|
36
|
+
className: itemClassName,
|
|
37
|
+
children: content
|
|
38
|
+
});
|
|
39
|
+
if (item.onClick) return /* @__PURE__ */ jsx(Button, {
|
|
40
|
+
variant: "text",
|
|
41
|
+
size: "small",
|
|
42
|
+
onClick: item.onClick,
|
|
43
|
+
"aria-label": item["aria-label"],
|
|
44
|
+
"aria-current": isCurrent ? "page" : void 0,
|
|
45
|
+
className: cn("h-auto px-0 py-0 font-normal", itemClassName),
|
|
46
|
+
children: content
|
|
47
|
+
});
|
|
48
|
+
return /* @__PURE__ */ jsx("span", {
|
|
49
|
+
"aria-label": item["aria-label"],
|
|
50
|
+
"aria-current": isCurrent ? "page" : void 0,
|
|
51
|
+
className: itemClassName,
|
|
52
|
+
children: content
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
const renderSeparator = (index) => /* @__PURE__ */ jsx("li", {
|
|
56
|
+
"data-slot": "breadcrumb-separator",
|
|
57
|
+
"aria-hidden": "true",
|
|
58
|
+
className: cn("text-muted-foreground mx-2 shrink-0", classNames?.separator),
|
|
59
|
+
children: items[index]?.separator ?? separator
|
|
60
|
+
});
|
|
61
|
+
return /* @__PURE__ */ jsx("nav", {
|
|
62
|
+
...props,
|
|
63
|
+
"data-slot": "breadcrumb",
|
|
64
|
+
dir: dir ?? direction,
|
|
65
|
+
"aria-label": ariaLabel ?? "Breadcrumb",
|
|
66
|
+
className: cn("text-sm", className),
|
|
67
|
+
children: /* @__PURE__ */ jsx("ol", {
|
|
68
|
+
"data-slot": "breadcrumb-list",
|
|
69
|
+
className: cn("m-0 flex min-w-0 flex-wrap items-center p-0", classNames?.list),
|
|
70
|
+
children: visibleIndices.map((index, position) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
71
|
+
position > 0 && renderSeparator(collapsed && position === before ? index - 1 : visibleIndices[position - 1]),
|
|
72
|
+
/* @__PURE__ */ jsx("li", {
|
|
73
|
+
"data-slot": "breadcrumb-item",
|
|
74
|
+
className: cn("inline-flex min-w-0 items-center", classNames?.item),
|
|
75
|
+
children: renderItem(index)
|
|
76
|
+
}),
|
|
77
|
+
collapsed && position === before - 1 && /* @__PURE__ */ jsxs(Fragment$1, { children: [renderSeparator(index), /* @__PURE__ */ jsx("li", {
|
|
78
|
+
"data-slot": "breadcrumb-collapsed",
|
|
79
|
+
className: classNames?.collapsed,
|
|
80
|
+
children: /* @__PURE__ */ jsx(Popover, {
|
|
81
|
+
placement: "bottom",
|
|
82
|
+
className: classNames?.popup,
|
|
83
|
+
content: /* @__PURE__ */ jsx("ol", {
|
|
84
|
+
className: "m-0 grid list-none gap-1 p-0",
|
|
85
|
+
children: hiddenIndices.map((hiddenIndex) => /* @__PURE__ */ jsx("li", { children: renderItem(hiddenIndex) }, items[hiddenIndex]?.key ?? hiddenIndex))
|
|
86
|
+
}),
|
|
87
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
88
|
+
variant: "text",
|
|
89
|
+
size: "small",
|
|
90
|
+
"aria-label": expandText,
|
|
91
|
+
className: "h-auto px-1",
|
|
92
|
+
children: "…"
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
})] })
|
|
96
|
+
] }, items[index]?.key ?? index))
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
//#endregion
|
|
101
|
+
export { Breadcrumb as default };
|
|
102
|
+
|
|
103
|
+
//# sourceMappingURL=Breadcrumb.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Breadcrumb.mjs","names":[],"sources":["../src/components/molecules/breadcrumb.tsx"],"sourcesContent":["'use client';\n\nimport { Fragment } from 'react';\n\nimport { useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport Button from '../atoms/button';\nimport Popover from '../atoms/popover';\n\nexport interface Item {\n key?: React.Key;\n title: React.ReactNode;\n href?: string;\n target?: React.HTMLAttributeAnchorTarget;\n rel?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n className?: string;\n 'aria-label'?: string;\n /** Decorative icon placed before the title. */\n icon?: React.ReactNode;\n /** Overrides the separator after this item. */\n separator?: React.ReactNode;\n}\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'nav'>,\n 'children'\n> {\n items: Item[];\n separator?: React.ReactNode;\n /** Collapse middle items when the trail has more than this many entries. */\n maxItems?: number;\n itemsBeforeCollapse?: number;\n itemsAfterCollapse?: number;\n expandText?: string;\n /** Render custom router links. The renderer owns aria-current for the last item. */\n itemRender?: (\n item: Item,\n index: number,\n isCurrent: boolean,\n ) => React.ReactNode;\n classNames?: {\n list?: string;\n item?: string;\n link?: string;\n current?: string;\n separator?: string;\n collapsed?: string;\n popup?: string;\n };\n}\n\nconst safeCount = (value: number, minimum: number) =>\n Number.isFinite(value) ? Math.max(minimum, Math.floor(value)) : minimum;\n\nconst Breadcrumb = ({\n items,\n separator = '/',\n maxItems = 8,\n itemsBeforeCollapse = 1,\n itemsAfterCollapse = 1,\n expandText = 'Show path',\n itemRender,\n className,\n classNames,\n dir,\n 'aria-label': ariaLabel,\n ...props\n}: Props) => {\n const { direction } = useConfig();\n const limit = safeCount(maxItems, 3);\n const before = Math.min(safeCount(itemsBeforeCollapse, 1), limit - 2);\n const after = Math.min(safeCount(itemsAfterCollapse, 1), limit - before - 1);\n const collapsed = items.length > limit && items.length - before - after > 0;\n const visibleIndices = collapsed\n ? [\n ...Array.from({ length: before }, (_, index) => index),\n ...Array.from(\n { length: after },\n (_, index) => items.length - after + index,\n ),\n ]\n : items.map((_, index) => index);\n const hiddenIndices = collapsed\n ? Array.from(\n { length: items.length - before - after },\n (_, index) => before + index,\n )\n : [];\n\n const renderItem = (index: number) => {\n const item = items[index]!;\n const isCurrent = index === items.length - 1;\n\n if (itemRender) {\n return itemRender(item, index, isCurrent);\n }\n\n const content = (\n <>\n {item.icon != null && (\n <span\n data-slot=\"breadcrumb-icon\"\n aria-hidden=\"true\"\n className=\"inline-flex shrink-0\"\n >\n {item.icon}\n </span>\n )}\n {item.title}\n </>\n );\n const itemClassName = cn(\n 'inline-flex items-center gap-1.5 rounded-sm',\n (item.href !== undefined || item.onClick) &&\n 'hover:text-foreground focus-visible:outline-ring focus-visible:outline-2',\n isCurrent ? 'text-foreground font-medium' : 'text-muted-foreground',\n (item.href !== undefined || item.onClick) && classNames?.link,\n isCurrent && classNames?.current,\n item.className,\n //\n );\n\n if (item.href !== undefined) {\n return (\n <a\n href={item.href}\n target={item.target}\n rel={item.rel}\n onClick={item.onClick}\n aria-label={item['aria-label']}\n aria-current={isCurrent ? 'page' : undefined}\n className={itemClassName}\n >\n {content}\n </a>\n );\n }\n\n if (item.onClick) {\n return (\n <Button\n variant=\"text\"\n size=\"small\"\n onClick={item.onClick}\n aria-label={item['aria-label']}\n aria-current={isCurrent ? 'page' : undefined}\n className={cn('h-auto px-0 py-0 font-normal', itemClassName)}\n >\n {content}\n </Button>\n );\n }\n\n return (\n <span\n aria-label={item['aria-label']}\n aria-current={isCurrent ? 'page' : undefined}\n className={itemClassName}\n >\n {content}\n </span>\n );\n };\n\n const renderSeparator = (index: number) => (\n <li\n data-slot=\"breadcrumb-separator\"\n aria-hidden=\"true\"\n className={cn(\n 'text-muted-foreground mx-2 shrink-0',\n classNames?.separator,\n //\n )}\n >\n {items[index]?.separator ?? separator}\n </li>\n );\n\n return (\n <nav\n {...props}\n data-slot=\"breadcrumb\"\n dir={dir ?? direction}\n aria-label={ariaLabel ?? 'Breadcrumb'}\n className={cn(\n 'text-sm',\n className, //\n )}\n >\n <ol\n data-slot=\"breadcrumb-list\"\n className={cn(\n 'm-0 flex min-w-0 flex-wrap items-center p-0',\n classNames?.list,\n //\n )}\n >\n {visibleIndices.map((index, position) => (\n <Fragment key={items[index]?.key ?? index}>\n {position > 0 &&\n renderSeparator(\n collapsed && position === before\n ? index - 1\n : visibleIndices[position - 1]!,\n )}\n <li\n data-slot=\"breadcrumb-item\"\n className={cn(\n 'inline-flex min-w-0 items-center',\n classNames?.item, //\n )}\n >\n {renderItem(index)}\n </li>\n {collapsed && position === before - 1 && (\n <>\n {renderSeparator(index)}\n <li\n data-slot=\"breadcrumb-collapsed\"\n className={classNames?.collapsed}\n >\n <Popover\n placement=\"bottom\"\n className={classNames?.popup}\n content={\n <ol className=\"m-0 grid list-none gap-1 p-0\">\n {hiddenIndices.map(hiddenIndex => (\n <li key={items[hiddenIndex]?.key ?? hiddenIndex}>\n {renderItem(hiddenIndex)}\n </li>\n ))}\n </ol>\n }\n >\n <Button\n variant=\"text\"\n size=\"small\"\n aria-label={expandText}\n className=\"h-auto px-1\"\n >\n …\n </Button>\n </Popover>\n </li>\n </>\n )}\n </Fragment>\n ))}\n </ol>\n </nav>\n );\n};\n\nexport default Breadcrumb;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//#region src/components/molecules/pagination.d.ts
|
|
2
|
+
interface Props extends Omit<React.ComponentPropsWithoutRef<'nav'>, 'children' | 'onChange'> {
|
|
3
|
+
/** Total number of items, not pages. */
|
|
4
|
+
total: number;
|
|
5
|
+
/** Controlled number of items per page. */
|
|
6
|
+
pageSize?: number;
|
|
7
|
+
defaultPageSize?: number;
|
|
8
|
+
onPageSizeChange?: (pageSize: number) => void;
|
|
9
|
+
pageSizeOptions?: number[];
|
|
10
|
+
showSizeChanger?: boolean;
|
|
11
|
+
/** Render the total and the 1-based inclusive range of visible items. */
|
|
12
|
+
showTotal?: (total: number, range: [number, number]) => React.ReactNode;
|
|
13
|
+
showQuickJumper?: boolean;
|
|
14
|
+
/** 1-based controlled page. */
|
|
15
|
+
page?: number;
|
|
16
|
+
defaultPage?: number;
|
|
17
|
+
onChange?: (page: number) => void;
|
|
18
|
+
siblingCount?: number;
|
|
19
|
+
boundaryCount?: number;
|
|
20
|
+
showFirstLast?: boolean;
|
|
21
|
+
hideOnSinglePage?: boolean;
|
|
22
|
+
/** Render available page controls as links to these URLs. */
|
|
23
|
+
getPageHref?: (page: number) => string;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
size?: 'small' | 'middle' | 'large';
|
|
26
|
+
labels?: {
|
|
27
|
+
navigation?: string;
|
|
28
|
+
page?: (page: number) => string;
|
|
29
|
+
previous?: string;
|
|
30
|
+
next?: string;
|
|
31
|
+
first?: string;
|
|
32
|
+
last?: string;
|
|
33
|
+
pageSize?: string;
|
|
34
|
+
jump?: string;
|
|
35
|
+
go?: string;
|
|
36
|
+
};
|
|
37
|
+
classNames?: {
|
|
38
|
+
item?: string;
|
|
39
|
+
active?: string;
|
|
40
|
+
previous?: string;
|
|
41
|
+
next?: string;
|
|
42
|
+
first?: string;
|
|
43
|
+
last?: string;
|
|
44
|
+
ellipsis?: string;
|
|
45
|
+
total?: string;
|
|
46
|
+
sizeChanger?: string;
|
|
47
|
+
jumper?: string;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
declare const Pagination: ({ total, pageSize, defaultPageSize, onPageSizeChange, pageSizeOptions, showSizeChanger, showTotal, showQuickJumper, page, defaultPage, onChange, siblingCount, boundaryCount, showFirstLast, hideOnSinglePage, getPageHref, disabled, size, labels, className, classNames, "aria-label": ariaLabel, ...props }: Props) => import("react").JSX.Element | null;
|
|
51
|
+
//#endregion
|
|
52
|
+
export { Props, Pagination as default };
|
|
53
|
+
//# sourceMappingURL=Pagination.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pagination.d.mts","names":[],"sources":["../src/components/molecules/pagination.tsx"],"mappings":";UAoBiB,cAAc,KAC7B,MAAM;;EAIN;;EAEA;EACA;EACA,oBAAoB;EACpB;EACA;;EAEA,aAAa,eAAe,4BAA4B,MAAM;EAC9D;;EAEA;EACA;EACA,YAAY;EACZ;EACA;EACA;EACA;;EAEA,eAAe;EACf;EACA;EACA;IACE;IACA,QAAQ;IACR;IACA;IACA;IACA;IACA;IACA;IACA;;EAEF;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;cAkEE,eAAc,OAAA,UAAA,iBAAA,kBAAA,iBAAA,iBAAA,WAAA,iBAAA,MAAA,aAAA,UAAA,cAAA,eAAA,eAAA,kBAAA,aAAA,UAAA,MAAA,QAAA,WAAA,0BAAA,cAAA,SAwBjB,0BAAK,IAAA"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "./utils.mjs";
|
|
3
|
+
import { useConfig } from "./providers/config/context.mjs";
|
|
4
|
+
import Button from "./Button.mjs";
|
|
5
|
+
import Input from "./components/atoms/input/index.mjs";
|
|
6
|
+
import Select from "./components/atoms/select.mjs";
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from "lucide-react";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
//#region src/components/molecules/pagination.tsx
|
|
11
|
+
const clampPage = (page, pageCount) => Math.min(Math.max(1, Number.isFinite(page) ? Math.floor(page) : 1), Math.max(1, pageCount));
|
|
12
|
+
const normalizePageSize = (value) => Number.isFinite(value) && value >= 1 ? Math.floor(value) : 10;
|
|
13
|
+
const getPageItems = (page, pageCount, siblingCount, boundaryCount) => {
|
|
14
|
+
if (pageCount === 0) return [];
|
|
15
|
+
const pages = /* @__PURE__ */ new Set();
|
|
16
|
+
for (let index = 1; index <= boundaryCount && index <= pageCount; index++) {
|
|
17
|
+
pages.add(index);
|
|
18
|
+
pages.add(pageCount - index + 1);
|
|
19
|
+
}
|
|
20
|
+
for (let index = Math.max(1, page - siblingCount); index <= Math.min(pageCount, page + siblingCount); index++) pages.add(index);
|
|
21
|
+
const sorted = [...pages].sort((a, b) => a - b);
|
|
22
|
+
const items = [];
|
|
23
|
+
let previous = 0;
|
|
24
|
+
for (const current of sorted) {
|
|
25
|
+
const gap = current - previous;
|
|
26
|
+
if (gap === 2) items.push(previous + 1);
|
|
27
|
+
else if (gap > 2) items.push("start-ellipsis");
|
|
28
|
+
items.push(current);
|
|
29
|
+
previous = current;
|
|
30
|
+
}
|
|
31
|
+
const finalGap = pageCount - previous;
|
|
32
|
+
if (finalGap === 1) items.push(pageCount);
|
|
33
|
+
else if (finalGap > 1) items.push("end-ellipsis");
|
|
34
|
+
return items;
|
|
35
|
+
};
|
|
36
|
+
const Pagination = ({ total, pageSize, defaultPageSize = 10, onPageSizeChange, pageSizeOptions = [
|
|
37
|
+
10,
|
|
38
|
+
20,
|
|
39
|
+
50,
|
|
40
|
+
100
|
|
41
|
+
], showSizeChanger = false, showTotal, showQuickJumper = false, page, defaultPage = 1, onChange, siblingCount = 1, boundaryCount = 1, showFirstLast = false, hideOnSinglePage = false, getPageHref, disabled = false, size, labels, className, classNames, "aria-label": ariaLabel, ...props }) => {
|
|
42
|
+
const { componentSize, direction } = useConfig();
|
|
43
|
+
const safeTotal = Number.isFinite(total) ? Math.max(0, Math.floor(total)) : 0;
|
|
44
|
+
const [internalPageSize, setInternalPageSize] = useState(() => normalizePageSize(defaultPageSize));
|
|
45
|
+
const safePageSize = normalizePageSize(pageSize ?? internalPageSize);
|
|
46
|
+
const pageCount = Math.ceil(safeTotal / safePageSize);
|
|
47
|
+
const [jumpValue, setJumpValue] = useState("");
|
|
48
|
+
const [internal, setInternal] = useState({
|
|
49
|
+
page: clampPage(defaultPage, pageCount),
|
|
50
|
+
pageCount
|
|
51
|
+
});
|
|
52
|
+
if (page === void 0 && internal.pageCount !== pageCount) setInternal({
|
|
53
|
+
page: clampPage(internal.page, pageCount),
|
|
54
|
+
pageCount
|
|
55
|
+
});
|
|
56
|
+
const currentPage = clampPage(page ?? internal.page, pageCount);
|
|
57
|
+
const resolvedSize = size ?? componentSize ?? "middle";
|
|
58
|
+
const items = getPageItems(currentPage, pageCount, Number.isFinite(siblingCount) ? Math.max(0, Math.floor(siblingCount)) : 1, Number.isFinite(boundaryCount) ? Math.max(0, Math.floor(boundaryCount)) : 1);
|
|
59
|
+
const sizeOptions = Array.from(new Set([...pageSizeOptions, safePageSize].filter((value) => Number.isInteger(value) && value > 0))).sort((a, b) => a - b);
|
|
60
|
+
const range = safeTotal === 0 ? [0, 0] : [(currentPage - 1) * safePageSize + 1, Math.min(currentPage * safePageSize, safeTotal)];
|
|
61
|
+
const goToPage = (next) => {
|
|
62
|
+
if (disabled || pageCount === 0 || next < 1 || next > pageCount || next === currentPage) return;
|
|
63
|
+
if (page === void 0) setInternal({
|
|
64
|
+
page: next,
|
|
65
|
+
pageCount
|
|
66
|
+
});
|
|
67
|
+
onChange?.(next);
|
|
68
|
+
};
|
|
69
|
+
const changePageSize = (next) => {
|
|
70
|
+
if (disabled || next === safePageSize) return;
|
|
71
|
+
if (pageSize === void 0) setInternalPageSize(next);
|
|
72
|
+
if (page === void 0) setInternal({
|
|
73
|
+
page: 1,
|
|
74
|
+
pageCount: Math.ceil(safeTotal / next)
|
|
75
|
+
});
|
|
76
|
+
onPageSizeChange?.(next);
|
|
77
|
+
if (currentPage !== 1) onChange?.(1);
|
|
78
|
+
};
|
|
79
|
+
const jumpToPage = (event) => {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
if (!/^\d+$/.test(jumpValue.trim())) return;
|
|
82
|
+
const next = Number(jumpValue.trim());
|
|
83
|
+
if (!Number.isSafeInteger(next) || next < 1 || next > pageCount) return;
|
|
84
|
+
goToPage(next);
|
|
85
|
+
setJumpValue("");
|
|
86
|
+
};
|
|
87
|
+
const handlePageClick = (next, event) => {
|
|
88
|
+
if (getPageHref && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || event.button !== 0)) return;
|
|
89
|
+
if (getPageHref && next === currentPage) event.preventDefault();
|
|
90
|
+
goToPage(next);
|
|
91
|
+
};
|
|
92
|
+
const linkProps = (target, isDisabled) => getPageHref && !isDisabled ? {
|
|
93
|
+
render: /* @__PURE__ */ jsx("a", { href: getPageHref(target) }),
|
|
94
|
+
nativeButton: false,
|
|
95
|
+
role: "link"
|
|
96
|
+
} : {};
|
|
97
|
+
if (hideOnSinglePage && pageCount <= 1) return null;
|
|
98
|
+
return /* @__PURE__ */ jsxs("nav", {
|
|
99
|
+
...props,
|
|
100
|
+
"data-slot": "pagination",
|
|
101
|
+
"aria-label": ariaLabel ?? labels?.navigation ?? "Pagination",
|
|
102
|
+
className: cn("flex flex-wrap items-center gap-1", className),
|
|
103
|
+
children: [
|
|
104
|
+
showTotal && /* @__PURE__ */ jsx("span", {
|
|
105
|
+
"data-slot": "pagination-total",
|
|
106
|
+
className: cn("text-muted-foreground me-2 text-sm", classNames?.total),
|
|
107
|
+
children: showTotal(safeTotal, range)
|
|
108
|
+
}),
|
|
109
|
+
showFirstLast && /* @__PURE__ */ jsx(Button, {
|
|
110
|
+
...linkProps(1, disabled || pageCount === 0 || currentPage === 1),
|
|
111
|
+
icon: direction === "rtl" ? /* @__PURE__ */ jsx(ChevronsRight, {}) : /* @__PURE__ */ jsx(ChevronsLeft, {}),
|
|
112
|
+
size: resolvedSize,
|
|
113
|
+
variant: "outlined",
|
|
114
|
+
"aria-label": labels?.first ?? "First page",
|
|
115
|
+
disabled: disabled || pageCount === 0 || currentPage === 1,
|
|
116
|
+
className: cn(classNames?.item, classNames?.first),
|
|
117
|
+
onClick: (event) => handlePageClick(1, event)
|
|
118
|
+
}),
|
|
119
|
+
/* @__PURE__ */ jsx(Button, {
|
|
120
|
+
...linkProps(currentPage - 1, disabled || pageCount === 0 || currentPage === 1),
|
|
121
|
+
icon: direction === "rtl" ? /* @__PURE__ */ jsx(ChevronRight, {}) : /* @__PURE__ */ jsx(ChevronLeft, {}),
|
|
122
|
+
size: resolvedSize,
|
|
123
|
+
variant: "outlined",
|
|
124
|
+
"aria-label": labels?.previous ?? "Previous page",
|
|
125
|
+
disabled: disabled || pageCount === 0 || currentPage === 1,
|
|
126
|
+
className: cn(classNames?.item, classNames?.previous),
|
|
127
|
+
onClick: (event) => handlePageClick(currentPage - 1, event)
|
|
128
|
+
}),
|
|
129
|
+
items.map((item, index) => typeof item === "number" ? /* @__PURE__ */ jsx(Button, {
|
|
130
|
+
...linkProps(item, disabled),
|
|
131
|
+
size: resolvedSize,
|
|
132
|
+
variant: item === currentPage ? "solid" : "outlined",
|
|
133
|
+
color: item === currentPage ? "primary" : "default",
|
|
134
|
+
"aria-current": item === currentPage ? "page" : void 0,
|
|
135
|
+
"aria-label": labels?.page?.(item) ?? `Page ${item}`,
|
|
136
|
+
disabled,
|
|
137
|
+
className: cn("min-w-8", classNames?.item, item === currentPage && classNames?.active),
|
|
138
|
+
onClick: (event) => handlePageClick(item, event),
|
|
139
|
+
children: item
|
|
140
|
+
}, item) : /* @__PURE__ */ jsx("span", {
|
|
141
|
+
"aria-hidden": "true",
|
|
142
|
+
className: cn(`text-muted-foreground inline-flex min-w-6 items-center
|
|
143
|
+
justify-center`, classNames?.ellipsis),
|
|
144
|
+
children: "…"
|
|
145
|
+
}, `${item}-${index}`)),
|
|
146
|
+
/* @__PURE__ */ jsx(Button, {
|
|
147
|
+
...linkProps(currentPage + 1, disabled || pageCount === 0 || currentPage === pageCount),
|
|
148
|
+
icon: direction === "rtl" ? /* @__PURE__ */ jsx(ChevronLeft, {}) : /* @__PURE__ */ jsx(ChevronRight, {}),
|
|
149
|
+
size: resolvedSize,
|
|
150
|
+
variant: "outlined",
|
|
151
|
+
"aria-label": labels?.next ?? "Next page",
|
|
152
|
+
disabled: disabled || pageCount === 0 || currentPage === pageCount,
|
|
153
|
+
className: cn(classNames?.item, classNames?.next),
|
|
154
|
+
onClick: (event) => handlePageClick(currentPage + 1, event)
|
|
155
|
+
}),
|
|
156
|
+
showFirstLast && /* @__PURE__ */ jsx(Button, {
|
|
157
|
+
...linkProps(pageCount, disabled || pageCount === 0 || currentPage === pageCount),
|
|
158
|
+
icon: direction === "rtl" ? /* @__PURE__ */ jsx(ChevronsLeft, {}) : /* @__PURE__ */ jsx(ChevronsRight, {}),
|
|
159
|
+
size: resolvedSize,
|
|
160
|
+
variant: "outlined",
|
|
161
|
+
"aria-label": labels?.last ?? "Last page",
|
|
162
|
+
disabled: disabled || pageCount === 0 || currentPage === pageCount,
|
|
163
|
+
className: cn(classNames?.item, classNames?.last),
|
|
164
|
+
onClick: (event) => handlePageClick(pageCount, event)
|
|
165
|
+
}),
|
|
166
|
+
showSizeChanger && /* @__PURE__ */ jsx("div", {
|
|
167
|
+
"data-slot": "pagination-size-changer",
|
|
168
|
+
className: cn("ms-2 min-w-24", classNames?.sizeChanger),
|
|
169
|
+
children: /* @__PURE__ */ jsx(Select, {
|
|
170
|
+
value: String(safePageSize),
|
|
171
|
+
options: sizeOptions.map((value) => ({
|
|
172
|
+
value: String(value),
|
|
173
|
+
label: `${value} / page`
|
|
174
|
+
})),
|
|
175
|
+
onChange: (value) => changePageSize(Number(value)),
|
|
176
|
+
disabled,
|
|
177
|
+
"aria-label": labels?.pageSize ?? "Items per page"
|
|
178
|
+
})
|
|
179
|
+
}),
|
|
180
|
+
showQuickJumper && /* @__PURE__ */ jsxs("form", {
|
|
181
|
+
"data-slot": "pagination-jumper",
|
|
182
|
+
className: cn("ms-2 flex items-center gap-1", classNames?.jumper),
|
|
183
|
+
onSubmit: jumpToPage,
|
|
184
|
+
noValidate: true,
|
|
185
|
+
children: [/* @__PURE__ */ jsx(Input, {
|
|
186
|
+
type: "text",
|
|
187
|
+
inputMode: "numeric",
|
|
188
|
+
autoComplete: "off",
|
|
189
|
+
"aria-label": labels?.jump ?? "Jump to page",
|
|
190
|
+
value: jumpValue,
|
|
191
|
+
onChange: (event) => setJumpValue(event.target.value),
|
|
192
|
+
disabled: disabled || pageCount === 0,
|
|
193
|
+
className: "w-16"
|
|
194
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
195
|
+
htmlType: "submit",
|
|
196
|
+
size: resolvedSize,
|
|
197
|
+
variant: "outlined",
|
|
198
|
+
disabled: disabled || pageCount === 0,
|
|
199
|
+
children: labels?.go ?? "Go"
|
|
200
|
+
})]
|
|
201
|
+
})
|
|
202
|
+
]
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
//#endregion
|
|
206
|
+
export { Pagination as default };
|
|
207
|
+
|
|
208
|
+
//# sourceMappingURL=Pagination.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pagination.mjs","names":[],"sources":["../src/components/molecules/pagination.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\n\nimport {\n ChevronLeft,\n ChevronRight,\n ChevronsLeft,\n ChevronsRight,\n} from 'lucide-react';\n\nimport { useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport Button from '../atoms/button';\nimport Input from '../atoms/input';\nimport Select from '../atoms/select';\n\ntype PageItem = number | 'start-ellipsis' | 'end-ellipsis';\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'nav'>,\n 'children' | 'onChange'\n> {\n /** Total number of items, not pages. */\n total: number;\n /** Controlled number of items per page. */\n pageSize?: number;\n defaultPageSize?: number;\n onPageSizeChange?: (pageSize: number) => void;\n pageSizeOptions?: number[];\n showSizeChanger?: boolean;\n /** Render the total and the 1-based inclusive range of visible items. */\n showTotal?: (total: number, range: [number, number]) => React.ReactNode;\n showQuickJumper?: boolean;\n /** 1-based controlled page. */\n page?: number;\n defaultPage?: number;\n onChange?: (page: number) => void;\n siblingCount?: number;\n boundaryCount?: number;\n showFirstLast?: boolean;\n hideOnSinglePage?: boolean;\n /** Render available page controls as links to these URLs. */\n getPageHref?: (page: number) => string;\n disabled?: boolean;\n size?: 'small' | 'middle' | 'large';\n labels?: {\n navigation?: string;\n page?: (page: number) => string;\n previous?: string;\n next?: string;\n first?: string;\n last?: string;\n pageSize?: string;\n jump?: string;\n go?: string;\n };\n classNames?: {\n item?: string;\n active?: string;\n previous?: string;\n next?: string;\n first?: string;\n last?: string;\n ellipsis?: string;\n total?: string;\n sizeChanger?: string;\n jumper?: string;\n };\n}\n\nconst clampPage = (page: number, pageCount: number) =>\n Math.min(\n Math.max(1, Number.isFinite(page) ? Math.floor(page) : 1),\n Math.max(1, pageCount),\n );\n\nconst normalizePageSize = (value: number) =>\n Number.isFinite(value) && value >= 1 ? Math.floor(value) : 10;\n\nconst getPageItems = (\n page: number,\n pageCount: number,\n siblingCount: number,\n boundaryCount: number,\n): PageItem[] => {\n if (pageCount === 0) {\n return [];\n }\n\n const pages = new Set<number>();\n\n for (let index = 1; index <= boundaryCount && index <= pageCount; index++) {\n pages.add(index);\n pages.add(pageCount - index + 1);\n }\n\n for (\n let index = Math.max(1, page - siblingCount);\n index <= Math.min(pageCount, page + siblingCount);\n index++\n ) {\n pages.add(index);\n }\n\n const sorted = [...pages].sort((a, b) => a - b);\n const items: PageItem[] = [];\n let previous = 0;\n\n for (const current of sorted) {\n const gap = current - previous;\n\n if (gap === 2) {\n items.push(previous + 1);\n } else if (gap > 2) {\n items.push('start-ellipsis');\n }\n\n items.push(current);\n previous = current;\n }\n\n const finalGap = pageCount - previous;\n\n if (finalGap === 1) {\n items.push(pageCount);\n } else if (finalGap > 1) {\n items.push('end-ellipsis');\n }\n\n return items;\n};\n\nconst Pagination = ({\n total,\n pageSize,\n defaultPageSize = 10,\n onPageSizeChange,\n pageSizeOptions = [10, 20, 50, 100],\n showSizeChanger = false,\n showTotal,\n showQuickJumper = false,\n page,\n defaultPage = 1,\n onChange,\n siblingCount = 1,\n boundaryCount = 1,\n showFirstLast = false,\n hideOnSinglePage = false,\n getPageHref,\n disabled = false,\n size,\n labels,\n className,\n classNames,\n 'aria-label': ariaLabel,\n ...props\n}: Props) => {\n const { componentSize, direction } = useConfig();\n const safeTotal = Number.isFinite(total) ? Math.max(0, Math.floor(total)) : 0;\n const [internalPageSize, setInternalPageSize] = useState(() =>\n normalizePageSize(defaultPageSize),\n );\n const safePageSize = normalizePageSize(pageSize ?? internalPageSize);\n const pageCount = Math.ceil(safeTotal / safePageSize);\n const [jumpValue, setJumpValue] = useState('');\n const [internal, setInternal] = useState({\n page: clampPage(defaultPage, pageCount),\n pageCount,\n });\n\n // React retries this render with the adjusted state when the available\n // range changes. Controlled callers still own their page prop.\n if (page === undefined && internal.pageCount !== pageCount) {\n setInternal({ page: clampPage(internal.page, pageCount), pageCount });\n }\n\n const currentPage = clampPage(page ?? internal.page, pageCount);\n const resolvedSize = size ?? componentSize ?? 'middle';\n const safeSiblingCount = Number.isFinite(siblingCount)\n ? Math.max(0, Math.floor(siblingCount))\n : 1;\n const safeBoundaryCount = Number.isFinite(boundaryCount)\n ? Math.max(0, Math.floor(boundaryCount))\n : 1;\n const items = getPageItems(\n currentPage,\n pageCount,\n safeSiblingCount,\n safeBoundaryCount,\n );\n const sizeOptions = Array.from(\n new Set(\n [...pageSizeOptions, safePageSize].filter(\n value => Number.isInteger(value) && value > 0,\n ),\n ),\n ).sort((a, b) => a - b);\n const range: [number, number] =\n safeTotal === 0\n ? [0, 0]\n : [\n (currentPage - 1) * safePageSize + 1,\n Math.min(currentPage * safePageSize, safeTotal),\n ];\n\n const goToPage = (next: number) => {\n if (\n disabled ||\n pageCount === 0 ||\n next < 1 ||\n next > pageCount ||\n next === currentPage\n ) {\n return;\n }\n\n if (page === undefined) {\n setInternal({ page: next, pageCount });\n }\n\n onChange?.(next);\n };\n\n const changePageSize = (next: number) => {\n if (disabled || next === safePageSize) {\n return;\n }\n\n if (pageSize === undefined) {\n setInternalPageSize(next);\n }\n\n if (page === undefined) {\n setInternal({ page: 1, pageCount: Math.ceil(safeTotal / next) });\n }\n\n onPageSizeChange?.(next);\n\n if (currentPage !== 1) {\n onChange?.(1);\n }\n };\n\n const jumpToPage = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n if (!/^\\d+$/.test(jumpValue.trim())) {\n return;\n }\n\n const next = Number(jumpValue.trim());\n\n if (!Number.isSafeInteger(next) || next < 1 || next > pageCount) {\n return;\n }\n\n goToPage(next);\n setJumpValue('');\n };\n\n const handlePageClick = (next: number, event: React.MouseEvent) => {\n if (\n getPageHref &&\n (event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey ||\n event.button !== 0)\n ) {\n return;\n }\n\n if (getPageHref && next === currentPage) {\n event.preventDefault();\n }\n\n goToPage(next);\n };\n\n const linkProps = (target: number, isDisabled: boolean) =>\n getPageHref && !isDisabled\n ? {\n render: <a href={getPageHref(target)} />,\n nativeButton: false,\n role: 'link',\n }\n : {};\n\n if (hideOnSinglePage && pageCount <= 1) {\n return null;\n }\n\n return (\n <nav\n {...props}\n data-slot=\"pagination\"\n aria-label={ariaLabel ?? labels?.navigation ?? 'Pagination'}\n className={cn(\n 'flex flex-wrap items-center gap-1',\n className,\n //\n )}\n >\n {showTotal && (\n <span\n data-slot=\"pagination-total\"\n className={cn(\n 'text-muted-foreground me-2 text-sm',\n classNames?.total,\n //\n )}\n >\n {showTotal(safeTotal, range)}\n </span>\n )}\n {showFirstLast && (\n <Button\n {...linkProps(1, disabled || pageCount === 0 || currentPage === 1)}\n icon={direction === 'rtl' ? <ChevronsRight /> : <ChevronsLeft />}\n size={resolvedSize}\n variant=\"outlined\"\n aria-label={labels?.first ?? 'First page'}\n disabled={disabled || pageCount === 0 || currentPage === 1}\n className={cn(\n classNames?.item,\n classNames?.first,\n //\n )}\n onClick={event => handlePageClick(1, event)}\n />\n )}\n <Button\n {...linkProps(\n currentPage - 1,\n disabled || pageCount === 0 || currentPage === 1,\n )}\n icon={direction === 'rtl' ? <ChevronRight /> : <ChevronLeft />}\n size={resolvedSize}\n variant=\"outlined\"\n aria-label={labels?.previous ?? 'Previous page'}\n disabled={disabled || pageCount === 0 || currentPage === 1}\n className={cn(\n classNames?.item,\n classNames?.previous,\n //\n )}\n onClick={event => handlePageClick(currentPage - 1, event)}\n />\n {items.map((item, index) =>\n typeof item === 'number' ? (\n <Button\n key={item}\n {...linkProps(item, disabled)}\n size={resolvedSize}\n variant={item === currentPage ? 'solid' : 'outlined'}\n color={item === currentPage ? 'primary' : 'default'}\n aria-current={item === currentPage ? 'page' : undefined}\n aria-label={labels?.page?.(item) ?? `Page ${item}`}\n disabled={disabled}\n className={cn(\n 'min-w-8',\n classNames?.item,\n item === currentPage && classNames?.active,\n //\n )}\n onClick={event => handlePageClick(item, event)}\n >\n {item}\n </Button>\n ) : (\n <span\n key={`${item}-${index}`}\n aria-hidden=\"true\"\n className={cn(\n `text-muted-foreground inline-flex min-w-6 items-center\n justify-center`,\n classNames?.ellipsis,\n //\n )}\n >\n …\n </span>\n ),\n )}\n <Button\n {...linkProps(\n currentPage + 1,\n disabled || pageCount === 0 || currentPage === pageCount,\n )}\n icon={direction === 'rtl' ? <ChevronLeft /> : <ChevronRight />}\n size={resolvedSize}\n variant=\"outlined\"\n aria-label={labels?.next ?? 'Next page'}\n disabled={disabled || pageCount === 0 || currentPage === pageCount}\n className={cn(\n classNames?.item,\n classNames?.next,\n //\n )}\n onClick={event => handlePageClick(currentPage + 1, event)}\n />\n {showFirstLast && (\n <Button\n {...linkProps(\n pageCount,\n disabled || pageCount === 0 || currentPage === pageCount,\n )}\n icon={direction === 'rtl' ? <ChevronsLeft /> : <ChevronsRight />}\n size={resolvedSize}\n variant=\"outlined\"\n aria-label={labels?.last ?? 'Last page'}\n disabled={disabled || pageCount === 0 || currentPage === pageCount}\n className={cn(\n classNames?.item,\n classNames?.last,\n //\n )}\n onClick={event => handlePageClick(pageCount, event)}\n />\n )}\n {showSizeChanger && (\n <div\n data-slot=\"pagination-size-changer\"\n className={cn(\n 'ms-2 min-w-24',\n classNames?.sizeChanger,\n //\n )}\n >\n <Select\n value={String(safePageSize)}\n options={sizeOptions.map(value => ({\n value: String(value),\n label: `${value} / page`,\n }))}\n onChange={value => changePageSize(Number(value))}\n disabled={disabled}\n aria-label={labels?.pageSize ?? 'Items per page'}\n />\n </div>\n )}\n {showQuickJumper && (\n <form\n data-slot=\"pagination-jumper\"\n className={cn(\n 'ms-2 flex items-center gap-1',\n classNames?.jumper,\n //\n )}\n onSubmit={jumpToPage}\n noValidate\n >\n <Input\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"off\"\n aria-label={labels?.jump ?? 'Jump to page'}\n value={jumpValue}\n onChange={event => setJumpValue(event.target.value)}\n disabled={disabled || pageCount === 0}\n className=\"w-16\"\n />\n <Button\n htmlType=\"submit\"\n size={resolvedSize}\n variant=\"outlined\"\n disabled={disabled || pageCount === 0}\n >\n {labels?.go ?? 'Go'}\n </Button>\n </form>\n )}\n </nav>\n );\n};\n\nexport default Pagination;\n"],"mappings":"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"}
|
package/dist/Table.d.mts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Props as Props$1 } from "./Pagination.mjs";
|
|
2
|
+
//#region src/components/organisms/table.d.ts
|
|
3
|
+
type PaginationOptions = Omit<Props$1, 'total'> & ({
|
|
4
|
+
mode?: 'client';
|
|
5
|
+
total?: never;
|
|
6
|
+
} | {
|
|
7
|
+
mode: 'server';
|
|
8
|
+
total: number;
|
|
9
|
+
});
|
|
10
|
+
interface Column<T> {
|
|
11
|
+
key: React.Key;
|
|
12
|
+
title: React.ReactNode;
|
|
13
|
+
/** Field displayed when render is omitted. */
|
|
14
|
+
dataIndex?: keyof T;
|
|
15
|
+
render?: (record: T, index: number) => React.ReactNode;
|
|
16
|
+
align?: 'left' | 'center' | 'right';
|
|
17
|
+
width?: string | number;
|
|
18
|
+
className?: string;
|
|
19
|
+
headerClassName?: string;
|
|
20
|
+
}
|
|
21
|
+
interface Props<T> extends Omit<React.ComponentPropsWithoutRef<'table'>, 'children'> {
|
|
22
|
+
columns: Column<T>[];
|
|
23
|
+
data?: T[];
|
|
24
|
+
/** Use a stable key when rows may be reordered or paged. */
|
|
25
|
+
rowKey?: (record: T, index: number) => React.Key;
|
|
26
|
+
caption?: React.ReactNode;
|
|
27
|
+
loading?: boolean;
|
|
28
|
+
empty?: React.ReactNode;
|
|
29
|
+
size?: 'small' | 'middle' | 'large';
|
|
30
|
+
bordered?: boolean;
|
|
31
|
+
striped?: boolean;
|
|
32
|
+
hoverable?: boolean;
|
|
33
|
+
/** true paginates data locally; server mode expects current-page data. */
|
|
34
|
+
pagination?: boolean | PaginationOptions;
|
|
35
|
+
classNames?: {
|
|
36
|
+
container?: string;
|
|
37
|
+
header?: string;
|
|
38
|
+
body?: string;
|
|
39
|
+
row?: string;
|
|
40
|
+
cell?: string;
|
|
41
|
+
empty?: string;
|
|
42
|
+
pagination?: string;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
declare const Table: <T>({ columns, data, rowKey, loading, empty, size, bordered, striped, hoverable, pagination, caption, className, classNames, ...props }: Props<T>) => import("react").JSX.Element;
|
|
46
|
+
//#endregion
|
|
47
|
+
export { Column, PaginationOptions, Props, Table as default };
|
|
48
|
+
//# sourceMappingURL=Table.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Table.d.mts","names":[],"sources":["../src/components/organisms/table.tsx"],"mappings":";;KAaY,oBAAoB,KAAK;EAChC;EAAiB;;EAAoB;EAAgB;;UAEzC,OAAO;EACtB,KAAK,MAAM;EACX,OAAO,MAAM;;EAEb,kBAAkB;EAClB,UAAU,QAAQ,GAAG,kBAAkB,MAAM;EAC7C;EACA;EACA;EACA;;UAGe,MAAM,WAAW,KAChC,MAAM;EAGN,SAAS,OAAO;EAChB,OAAO;;EAEP,UAAU,QAAQ,GAAG,kBAAkB,MAAM;EAC7C,UAAU,MAAM;EAChB;EACA,QAAQ,MAAM;EACd;EACA;EACA;EACA;;EAEA,uBAAuB;EACvB;IACE;IACA;IACA;IACA;IACA;IACA;IACA;;;cAaE,QAAS,KAAI,SAAA,MAAA,QAAA,SAAA,OAAA,MAAA,UAAA,SAAA,WAAA,YAAA,SAAA,WAAA,eAAA,SAehB,MAAM,uBAAE,IAAA"}
|