@7onic-ui/react 0.3.9 → 0.3.10
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 +2 -2
- package/dist/chart.mjs +3 -9
- package/dist/chart.mjs.map +1 -1
- package/dist/chunk-234NAXGV.mjs +252 -0
- package/dist/chunk-234NAXGV.mjs.map +1 -0
- package/dist/chunk-53MIUPSY.mjs +13 -0
- package/dist/chunk-53MIUPSY.mjs.map +1 -0
- package/dist/chunk-BN5BEA3V.mjs +195 -0
- package/dist/chunk-BN5BEA3V.mjs.map +1 -0
- package/dist/chunk-COW3B62M.mjs +214 -0
- package/dist/chunk-COW3B62M.mjs.map +1 -0
- package/dist/chunk-CTH6SN5Y.mjs +114 -0
- package/dist/chunk-CTH6SN5Y.mjs.map +1 -0
- package/dist/chunk-D3NTQNDW.mjs +440 -0
- package/dist/chunk-D3NTQNDW.mjs.map +1 -0
- package/dist/chunk-DDRYEJBJ.mjs +164 -0
- package/dist/chunk-DDRYEJBJ.mjs.map +1 -0
- package/dist/chunk-DJAEXCRU.mjs +190 -0
- package/dist/chunk-DJAEXCRU.mjs.map +1 -0
- package/dist/chunk-DRVHHEAY.mjs +145 -0
- package/dist/chunk-DRVHHEAY.mjs.map +1 -0
- package/dist/chunk-DTLNWOTR.mjs +482 -0
- package/dist/chunk-DTLNWOTR.mjs.map +1 -0
- package/dist/chunk-DYYQOHQR.mjs +214 -0
- package/dist/chunk-DYYQOHQR.mjs.map +1 -0
- package/dist/chunk-FHUAH6AJ.mjs +93 -0
- package/dist/chunk-FHUAH6AJ.mjs.map +1 -0
- package/dist/chunk-GD4YE5AE.mjs +209 -0
- package/dist/chunk-GD4YE5AE.mjs.map +1 -0
- package/dist/chunk-GRCJ35DX.mjs +144 -0
- package/dist/chunk-GRCJ35DX.mjs.map +1 -0
- package/dist/chunk-HHX4GABH.mjs +129 -0
- package/dist/chunk-HHX4GABH.mjs.map +1 -0
- package/dist/chunk-IPCIC2BI.mjs +148 -0
- package/dist/chunk-IPCIC2BI.mjs.map +1 -0
- package/dist/chunk-IY3R2VGB.mjs +272 -0
- package/dist/chunk-IY3R2VGB.mjs.map +1 -0
- package/dist/chunk-JCJEVXER.mjs +170 -0
- package/dist/chunk-JCJEVXER.mjs.map +1 -0
- package/dist/chunk-KBPYAMGS.mjs +157 -0
- package/dist/chunk-KBPYAMGS.mjs.map +1 -0
- package/dist/chunk-LJJ6K4IU.mjs +318 -0
- package/dist/chunk-LJJ6K4IU.mjs.map +1 -0
- package/dist/chunk-MRUVGHGP.mjs +375 -0
- package/dist/chunk-MRUVGHGP.mjs.map +1 -0
- package/dist/chunk-N4K2BDGM.mjs +153 -0
- package/dist/chunk-N4K2BDGM.mjs.map +1 -0
- package/dist/chunk-NWFMJWGX.mjs +165 -0
- package/dist/chunk-NWFMJWGX.mjs.map +1 -0
- package/dist/chunk-PTAPPOKU.mjs +117 -0
- package/dist/chunk-PTAPPOKU.mjs.map +1 -0
- package/dist/chunk-PVTBM7V7.mjs +316 -0
- package/dist/chunk-PVTBM7V7.mjs.map +1 -0
- package/dist/chunk-Q5WVLK2L.mjs +77 -0
- package/dist/chunk-Q5WVLK2L.mjs.map +1 -0
- package/dist/chunk-RKSB2N5L.mjs +206 -0
- package/dist/chunk-RKSB2N5L.mjs.map +1 -0
- package/dist/chunk-S4DGVKBK.mjs +151 -0
- package/dist/chunk-S4DGVKBK.mjs.map +1 -0
- package/dist/chunk-S4T4PU7F.mjs +114 -0
- package/dist/chunk-S4T4PU7F.mjs.map +1 -0
- package/dist/chunk-SZPZOGPC.mjs +394 -0
- package/dist/chunk-SZPZOGPC.mjs.map +1 -0
- package/dist/chunk-T546XBQG.mjs +443 -0
- package/dist/chunk-T546XBQG.mjs.map +1 -0
- package/dist/chunk-UWTT5AE6.mjs +145 -0
- package/dist/chunk-UWTT5AE6.mjs.map +1 -0
- package/dist/chunk-V5UFWYFI.mjs +255 -0
- package/dist/chunk-V5UFWYFI.mjs.map +1 -0
- package/dist/chunk-VUPGBB5X.mjs +150 -0
- package/dist/chunk-VUPGBB5X.mjs.map +1 -0
- package/dist/chunk-W6YNEU53.mjs +175 -0
- package/dist/chunk-W6YNEU53.mjs.map +1 -0
- package/dist/chunk-WWSN5YME.mjs +222 -0
- package/dist/chunk-WWSN5YME.mjs.map +1 -0
- package/dist/chunk-XK52LYR4.mjs +182 -0
- package/dist/chunk-XK52LYR4.mjs.map +1 -0
- package/dist/chunk-YIAH6KHV.mjs +164 -0
- package/dist/chunk-YIAH6KHV.mjs.map +1 -0
- package/dist/chunk-Z6JWWCNL.mjs +108 -0
- package/dist/chunk-Z6JWWCNL.mjs.map +1 -0
- package/dist/chunk-ZDRUTJ4T.mjs +119 -0
- package/dist/chunk-ZDRUTJ4T.mjs.map +1 -0
- package/dist/components/accordion.mjs +19 -0
- package/dist/components/accordion.mjs.map +1 -0
- package/dist/components/alert.mjs +15 -0
- package/dist/components/alert.mjs.map +1 -0
- package/dist/components/avatar.mjs +23 -0
- package/dist/components/avatar.mjs.map +1 -0
- package/dist/components/badge.mjs +11 -0
- package/dist/components/badge.mjs.map +1 -0
- package/dist/components/breadcrumb.mjs +23 -0
- package/dist/components/breadcrumb.mjs.map +1 -0
- package/dist/components/button-group.mjs +11 -0
- package/dist/components/button-group.mjs.map +1 -0
- package/dist/components/button.mjs +12 -0
- package/dist/components/button.mjs.map +1 -0
- package/dist/components/card.mjs +25 -0
- package/dist/components/card.mjs.map +1 -0
- package/dist/components/chat-input.mjs +15 -0
- package/dist/components/chat-input.mjs.map +1 -0
- package/dist/components/chat-message.mjs +17 -0
- package/dist/components/chat-message.mjs.map +1 -0
- package/dist/components/checkbox.mjs +12 -0
- package/dist/components/checkbox.mjs.map +1 -0
- package/dist/components/divider.mjs +11 -0
- package/dist/components/divider.mjs.map +1 -0
- package/dist/components/drawer.mjs +33 -0
- package/dist/components/drawer.mjs.map +1 -0
- package/dist/components/dropdown.mjs +35 -0
- package/dist/components/dropdown.mjs.map +1 -0
- package/dist/components/field.mjs +17 -0
- package/dist/components/field.mjs.map +1 -0
- package/dist/components/icon-button.mjs +12 -0
- package/dist/components/icon-button.mjs.map +1 -0
- package/dist/components/input.mjs +12 -0
- package/dist/components/input.mjs.map +1 -0
- package/dist/components/metric-card.mjs +23 -0
- package/dist/components/metric-card.mjs.map +1 -0
- package/dist/components/modal.mjs +57 -0
- package/dist/components/modal.mjs.map +1 -0
- package/dist/components/navigation-menu.mjs +27 -0
- package/dist/components/navigation-menu.mjs.map +1 -0
- package/dist/components/pagination.mjs +33 -0
- package/dist/components/pagination.mjs.map +1 -0
- package/dist/components/popover.mjs +23 -0
- package/dist/components/popover.mjs.map +1 -0
- package/dist/components/progress.mjs +11 -0
- package/dist/components/progress.mjs.map +1 -0
- package/dist/components/quick-reply.mjs +15 -0
- package/dist/components/quick-reply.mjs.map +1 -0
- package/dist/components/radio-group.mjs +16 -0
- package/dist/components/radio-group.mjs.map +1 -0
- package/dist/components/segmented.mjs +15 -0
- package/dist/components/segmented.mjs.map +1 -0
- package/dist/components/select.mjs +23 -0
- package/dist/components/select.mjs.map +1 -0
- package/dist/components/skeleton.mjs +11 -0
- package/dist/components/skeleton.mjs.map +1 -0
- package/dist/components/slider.mjs +11 -0
- package/dist/components/slider.mjs.map +1 -0
- package/dist/components/spinner.mjs +11 -0
- package/dist/components/spinner.mjs.map +1 -0
- package/dist/components/switch.mjs +12 -0
- package/dist/components/switch.mjs.map +1 -0
- package/dist/components/table.mjs +23 -0
- package/dist/components/table.mjs.map +1 -0
- package/dist/components/tabs.mjs +19 -0
- package/dist/components/tabs.mjs.map +1 -0
- package/dist/components/textarea.mjs +12 -0
- package/dist/components/textarea.mjs.map +1 -0
- package/dist/components/toast.mjs +13 -0
- package/dist/components/toast.mjs.map +1 -0
- package/dist/components/toggle-group.mjs +15 -0
- package/dist/components/toggle-group.mjs.map +1 -0
- package/dist/components/toggle.mjs +11 -0
- package/dist/components/toggle.mjs.map +1 -0
- package/dist/components/tooltip.mjs +21 -0
- package/dist/components/tooltip.mjs.map +1 -0
- package/dist/components/typing-indicator.mjs +11 -0
- package/dist/components/typing-indicator.mjs.map +1 -0
- package/dist/index.mjs +296 -7536
- package/dist/index.mjs.map +1 -1
- package/llms.txt +23 -23
- package/package.json +4 -3
- package/dist/chart.d.mts +0 -147
- package/dist/index.d.mts +0 -1535
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
cn
|
|
4
|
+
} from "./chunk-53MIUPSY.mjs";
|
|
5
|
+
|
|
6
|
+
// src/components/ui/pagination.tsx
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import { cva } from "class-variance-authority";
|
|
9
|
+
function ChevronLeftIcon({ className }) {
|
|
10
|
+
return /* @__PURE__ */ React.createElement(
|
|
11
|
+
"svg",
|
|
12
|
+
{
|
|
13
|
+
className,
|
|
14
|
+
fill: "none",
|
|
15
|
+
viewBox: "0 0 24 24",
|
|
16
|
+
stroke: "currentColor",
|
|
17
|
+
strokeWidth: 2
|
|
18
|
+
},
|
|
19
|
+
/* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" })
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
function ChevronRightIcon({ className }) {
|
|
23
|
+
return /* @__PURE__ */ React.createElement(
|
|
24
|
+
"svg",
|
|
25
|
+
{
|
|
26
|
+
className,
|
|
27
|
+
fill: "none",
|
|
28
|
+
viewBox: "0 0 24 24",
|
|
29
|
+
stroke: "currentColor",
|
|
30
|
+
strokeWidth: 2
|
|
31
|
+
},
|
|
32
|
+
/* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" })
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
function ChevronsLeftIcon({ className }) {
|
|
36
|
+
return /* @__PURE__ */ React.createElement(
|
|
37
|
+
"svg",
|
|
38
|
+
{
|
|
39
|
+
className,
|
|
40
|
+
fill: "none",
|
|
41
|
+
viewBox: "0 0 24 24",
|
|
42
|
+
stroke: "currentColor",
|
|
43
|
+
strokeWidth: 2
|
|
44
|
+
},
|
|
45
|
+
/* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M11 17l-5-5 5-5M18 17l-5-5 5-5" })
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
function ChevronsRightIcon({ className }) {
|
|
49
|
+
return /* @__PURE__ */ React.createElement(
|
|
50
|
+
"svg",
|
|
51
|
+
{
|
|
52
|
+
className,
|
|
53
|
+
fill: "none",
|
|
54
|
+
viewBox: "0 0 24 24",
|
|
55
|
+
stroke: "currentColor",
|
|
56
|
+
strokeWidth: 2
|
|
57
|
+
},
|
|
58
|
+
/* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M13 7l5 5-5 5M6 7l5 5-5 5" })
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
function EllipsisIcon({ className }) {
|
|
62
|
+
return /* @__PURE__ */ React.createElement(
|
|
63
|
+
"svg",
|
|
64
|
+
{
|
|
65
|
+
className,
|
|
66
|
+
fill: "currentColor",
|
|
67
|
+
viewBox: "0 0 24 24"
|
|
68
|
+
},
|
|
69
|
+
/* @__PURE__ */ React.createElement("circle", { cx: "6", cy: "12", r: "1.5" }),
|
|
70
|
+
/* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
71
|
+
/* @__PURE__ */ React.createElement("circle", { cx: "18", cy: "12", r: "1.5" })
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
function range(start, end) {
|
|
75
|
+
const result = [];
|
|
76
|
+
for (let i = start; i <= end; i++) result.push(i);
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
function usePagination({
|
|
80
|
+
total,
|
|
81
|
+
siblings = 1,
|
|
82
|
+
boundaries = 1,
|
|
83
|
+
page
|
|
84
|
+
}) {
|
|
85
|
+
if (total <= 0) return [];
|
|
86
|
+
const totalPageNumbers = siblings * 2 + 3 + boundaries * 2;
|
|
87
|
+
if (totalPageNumbers >= total) {
|
|
88
|
+
return range(1, total);
|
|
89
|
+
}
|
|
90
|
+
const leftSiblingIndex = Math.max(page - siblings, boundaries + 1);
|
|
91
|
+
const rightSiblingIndex = Math.min(page + siblings, total - boundaries);
|
|
92
|
+
const showLeftDots = leftSiblingIndex > boundaries + 2;
|
|
93
|
+
const showRightDots = rightSiblingIndex < total - boundaries - 1;
|
|
94
|
+
if (!showLeftDots && showRightDots) {
|
|
95
|
+
const leftItemCount = 3 + 2 * siblings + boundaries;
|
|
96
|
+
const leftRange = range(1, leftItemCount);
|
|
97
|
+
return [...leftRange, "dots", ...range(total - boundaries + 1, total)];
|
|
98
|
+
}
|
|
99
|
+
if (showLeftDots && !showRightDots) {
|
|
100
|
+
const rightItemCount = 3 + 2 * siblings + boundaries;
|
|
101
|
+
const rightRange = range(total - rightItemCount + 1, total);
|
|
102
|
+
return [...range(1, boundaries), "dots", ...rightRange];
|
|
103
|
+
}
|
|
104
|
+
return [
|
|
105
|
+
...range(1, boundaries),
|
|
106
|
+
"dots",
|
|
107
|
+
...range(leftSiblingIndex, rightSiblingIndex),
|
|
108
|
+
"dots",
|
|
109
|
+
...range(total - boundaries + 1, total)
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
var PaginationContext = React.createContext(null);
|
|
113
|
+
function usePaginationContext() {
|
|
114
|
+
const ctx = React.useContext(PaginationContext);
|
|
115
|
+
if (!ctx) throw new Error("Pagination components must be used within <Pagination>");
|
|
116
|
+
return ctx;
|
|
117
|
+
}
|
|
118
|
+
var paginationSizeMap = {
|
|
119
|
+
xs: { item: "h-7 min-w-7 text-xs", icon: "icon-xs", gap: "gap-1" },
|
|
120
|
+
sm: { item: "h-8 min-w-8 text-sm", icon: "icon-xs", gap: "gap-1" },
|
|
121
|
+
default: { item: "h-9 min-w-9 text-md", icon: "icon-sm", gap: "gap-1" },
|
|
122
|
+
lg: { item: "h-10 min-w-10 text-md", icon: "icon-sm", gap: "gap-1.5" },
|
|
123
|
+
xl: { item: "h-12 min-w-12 text-base", icon: "icon-sm", gap: "gap-1.5" }
|
|
124
|
+
};
|
|
125
|
+
var paginationItemVariants = cva(
|
|
126
|
+
"inline-flex items-center justify-center select-none transition-colors duration-fast font-semibold focus-visible:focus-ring",
|
|
127
|
+
{
|
|
128
|
+
variants: {
|
|
129
|
+
radius: {
|
|
130
|
+
sm: "rounded-sm",
|
|
131
|
+
base: "rounded",
|
|
132
|
+
md: "rounded-md",
|
|
133
|
+
lg: "rounded-lg",
|
|
134
|
+
xl: "rounded-xl",
|
|
135
|
+
full: "rounded-full"
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
defaultVariants: {
|
|
139
|
+
radius: "md"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
var activeColorMap = {
|
|
144
|
+
default: "bg-foreground text-background",
|
|
145
|
+
primary: "bg-primary text-primary-foreground"
|
|
146
|
+
};
|
|
147
|
+
var ghostActiveColorMap = {
|
|
148
|
+
default: "bg-background-muted text-foreground font-bold",
|
|
149
|
+
primary: "bg-background-muted text-primary"
|
|
150
|
+
};
|
|
151
|
+
function getItemClasses(variant, color, isActive, disabled) {
|
|
152
|
+
if (disabled) {
|
|
153
|
+
return variant === "outline" ? "border border-border text-disabled-foreground pointer-events-none opacity-50" : "border border-transparent text-disabled-foreground pointer-events-none opacity-50";
|
|
154
|
+
}
|
|
155
|
+
if (isActive) {
|
|
156
|
+
switch (variant) {
|
|
157
|
+
case "outline":
|
|
158
|
+
return `border ${color === "default" ? "border-foreground" : "border-primary"} ${activeColorMap[color]}`;
|
|
159
|
+
case "ghost":
|
|
160
|
+
return `border border-transparent ${ghostActiveColorMap[color]}`;
|
|
161
|
+
case "default":
|
|
162
|
+
default:
|
|
163
|
+
return `border border-transparent ${activeColorMap[color]}`;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
switch (variant) {
|
|
167
|
+
case "outline":
|
|
168
|
+
return "border border-border text-text-muted hover:bg-background-muted hover:text-foreground";
|
|
169
|
+
case "ghost":
|
|
170
|
+
return "border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground";
|
|
171
|
+
case "default":
|
|
172
|
+
default:
|
|
173
|
+
return "border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground";
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
var Pagination = React.forwardRef(
|
|
177
|
+
({
|
|
178
|
+
className,
|
|
179
|
+
total = 1,
|
|
180
|
+
value,
|
|
181
|
+
defaultValue = 1,
|
|
182
|
+
onChange,
|
|
183
|
+
siblings = 1,
|
|
184
|
+
boundaries = 1,
|
|
185
|
+
size = "default",
|
|
186
|
+
variant = "default",
|
|
187
|
+
color = "default",
|
|
188
|
+
radius = "md",
|
|
189
|
+
disabled = false,
|
|
190
|
+
withControls = true,
|
|
191
|
+
withEdges = false,
|
|
192
|
+
loop = false,
|
|
193
|
+
children,
|
|
194
|
+
...props
|
|
195
|
+
}, ref) => {
|
|
196
|
+
const [internalPage, setInternalPage] = React.useState(defaultValue);
|
|
197
|
+
const isControlled = value !== void 0;
|
|
198
|
+
const page = isControlled ? value : internalPage;
|
|
199
|
+
const handlePageChange = React.useCallback((newPage) => {
|
|
200
|
+
if (disabled) return;
|
|
201
|
+
const clamped = Math.max(1, Math.min(total, newPage));
|
|
202
|
+
if (!isControlled) setInternalPage(clamped);
|
|
203
|
+
onChange?.(clamped);
|
|
204
|
+
}, [disabled, total, isControlled, onChange]);
|
|
205
|
+
const paginationRange = usePagination({ total, siblings, boundaries, page });
|
|
206
|
+
const contextValue = React.useMemo(() => ({
|
|
207
|
+
page,
|
|
208
|
+
total,
|
|
209
|
+
siblings,
|
|
210
|
+
boundaries,
|
|
211
|
+
size,
|
|
212
|
+
variant,
|
|
213
|
+
color,
|
|
214
|
+
radius,
|
|
215
|
+
disabled,
|
|
216
|
+
loop,
|
|
217
|
+
onPageChange: handlePageChange,
|
|
218
|
+
paginationRange
|
|
219
|
+
}), [page, total, siblings, boundaries, size, variant, color, radius, disabled, loop, handlePageChange, paginationRange]);
|
|
220
|
+
return /* @__PURE__ */ React.createElement(PaginationContext.Provider, { value: contextValue }, /* @__PURE__ */ React.createElement(
|
|
221
|
+
"nav",
|
|
222
|
+
{
|
|
223
|
+
ref,
|
|
224
|
+
role: "navigation",
|
|
225
|
+
"aria-label": "pagination",
|
|
226
|
+
className: cn("", className),
|
|
227
|
+
...props
|
|
228
|
+
},
|
|
229
|
+
children ?? /* @__PURE__ */ React.createElement(PaginationContent, null, withEdges && /* @__PURE__ */ React.createElement(PaginationItem, null, /* @__PURE__ */ React.createElement(PaginationFirst, null)), withControls && /* @__PURE__ */ React.createElement(PaginationItem, null, /* @__PURE__ */ React.createElement(PaginationPrevious, null)), /* @__PURE__ */ React.createElement(PaginationItems, null), withControls && /* @__PURE__ */ React.createElement(PaginationItem, null, /* @__PURE__ */ React.createElement(PaginationNext, null)), withEdges && /* @__PURE__ */ React.createElement(PaginationItem, null, /* @__PURE__ */ React.createElement(PaginationLast, null)))
|
|
230
|
+
));
|
|
231
|
+
}
|
|
232
|
+
);
|
|
233
|
+
Pagination.displayName = "Pagination";
|
|
234
|
+
var PaginationContent = React.forwardRef(
|
|
235
|
+
({ className, ...props }, ref) => {
|
|
236
|
+
const { size } = usePaginationContext();
|
|
237
|
+
const sizeClass = paginationSizeMap[size];
|
|
238
|
+
return /* @__PURE__ */ React.createElement(
|
|
239
|
+
"ul",
|
|
240
|
+
{
|
|
241
|
+
ref,
|
|
242
|
+
className: cn("flex flex-wrap items-center", sizeClass.gap, className),
|
|
243
|
+
...props
|
|
244
|
+
}
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
PaginationContent.displayName = "PaginationContent";
|
|
249
|
+
var PaginationItem = React.forwardRef(
|
|
250
|
+
({ className, ...props }, ref) => /* @__PURE__ */ React.createElement("li", { ref, className: cn("", className), ...props })
|
|
251
|
+
);
|
|
252
|
+
PaginationItem.displayName = "PaginationItem";
|
|
253
|
+
var PaginationLink = React.forwardRef(
|
|
254
|
+
({ className, page: targetPage, isActive: isActiveProp, ...props }, ref) => {
|
|
255
|
+
const ctx = usePaginationContext();
|
|
256
|
+
const isActive = isActiveProp ?? ctx.page === targetPage;
|
|
257
|
+
const sizeClass = paginationSizeMap[ctx.size];
|
|
258
|
+
return /* @__PURE__ */ React.createElement(
|
|
259
|
+
"button",
|
|
260
|
+
{
|
|
261
|
+
ref,
|
|
262
|
+
type: "button",
|
|
263
|
+
"aria-current": isActive ? "page" : void 0,
|
|
264
|
+
"aria-label": `Go to page ${targetPage}`,
|
|
265
|
+
disabled: ctx.disabled,
|
|
266
|
+
onClick: () => ctx.onPageChange(targetPage),
|
|
267
|
+
className: cn(
|
|
268
|
+
paginationItemVariants({ radius: ctx.radius }),
|
|
269
|
+
sizeClass.item,
|
|
270
|
+
getItemClasses(ctx.variant, ctx.color, isActive, ctx.disabled),
|
|
271
|
+
className
|
|
272
|
+
),
|
|
273
|
+
...props
|
|
274
|
+
},
|
|
275
|
+
targetPage
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
PaginationLink.displayName = "PaginationLink";
|
|
280
|
+
var PaginationPrevious = React.forwardRef(
|
|
281
|
+
({ className, icon, ...props }, ref) => {
|
|
282
|
+
const ctx = usePaginationContext();
|
|
283
|
+
const sizeClass = paginationSizeMap[ctx.size];
|
|
284
|
+
const isDisabled = ctx.disabled || !ctx.loop && ctx.page <= 1;
|
|
285
|
+
const handleClick = () => {
|
|
286
|
+
if (ctx.page <= 1) {
|
|
287
|
+
if (ctx.loop) ctx.onPageChange(ctx.total);
|
|
288
|
+
} else {
|
|
289
|
+
ctx.onPageChange(ctx.page - 1);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
return /* @__PURE__ */ React.createElement(
|
|
293
|
+
"button",
|
|
294
|
+
{
|
|
295
|
+
ref,
|
|
296
|
+
type: "button",
|
|
297
|
+
"aria-label": "Go to previous page",
|
|
298
|
+
disabled: isDisabled,
|
|
299
|
+
onClick: handleClick,
|
|
300
|
+
className: cn(
|
|
301
|
+
paginationItemVariants({ radius: ctx.radius }),
|
|
302
|
+
sizeClass.item,
|
|
303
|
+
getItemClasses(ctx.variant, ctx.color, false, isDisabled),
|
|
304
|
+
className
|
|
305
|
+
),
|
|
306
|
+
...props
|
|
307
|
+
},
|
|
308
|
+
icon ?? /* @__PURE__ */ React.createElement(ChevronLeftIcon, { className: sizeClass.icon })
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
);
|
|
312
|
+
PaginationPrevious.displayName = "PaginationPrevious";
|
|
313
|
+
var PaginationNext = React.forwardRef(
|
|
314
|
+
({ className, icon, ...props }, ref) => {
|
|
315
|
+
const ctx = usePaginationContext();
|
|
316
|
+
const sizeClass = paginationSizeMap[ctx.size];
|
|
317
|
+
const isDisabled = ctx.disabled || !ctx.loop && ctx.page >= ctx.total;
|
|
318
|
+
const handleClick = () => {
|
|
319
|
+
if (ctx.page >= ctx.total) {
|
|
320
|
+
if (ctx.loop) ctx.onPageChange(1);
|
|
321
|
+
} else {
|
|
322
|
+
ctx.onPageChange(ctx.page + 1);
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
return /* @__PURE__ */ React.createElement(
|
|
326
|
+
"button",
|
|
327
|
+
{
|
|
328
|
+
ref,
|
|
329
|
+
type: "button",
|
|
330
|
+
"aria-label": "Go to next page",
|
|
331
|
+
disabled: isDisabled,
|
|
332
|
+
onClick: handleClick,
|
|
333
|
+
className: cn(
|
|
334
|
+
paginationItemVariants({ radius: ctx.radius }),
|
|
335
|
+
sizeClass.item,
|
|
336
|
+
getItemClasses(ctx.variant, ctx.color, false, isDisabled),
|
|
337
|
+
className
|
|
338
|
+
),
|
|
339
|
+
...props
|
|
340
|
+
},
|
|
341
|
+
icon ?? /* @__PURE__ */ React.createElement(ChevronRightIcon, { className: sizeClass.icon })
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
);
|
|
345
|
+
PaginationNext.displayName = "PaginationNext";
|
|
346
|
+
var PaginationFirst = React.forwardRef(
|
|
347
|
+
({ className, icon, ...props }, ref) => {
|
|
348
|
+
const ctx = usePaginationContext();
|
|
349
|
+
const sizeClass = paginationSizeMap[ctx.size];
|
|
350
|
+
const isDisabled = ctx.disabled || ctx.page <= 1;
|
|
351
|
+
return /* @__PURE__ */ React.createElement(
|
|
352
|
+
"button",
|
|
353
|
+
{
|
|
354
|
+
ref,
|
|
355
|
+
type: "button",
|
|
356
|
+
"aria-label": "Go to first page",
|
|
357
|
+
disabled: isDisabled,
|
|
358
|
+
onClick: () => ctx.onPageChange(1),
|
|
359
|
+
className: cn(
|
|
360
|
+
paginationItemVariants({ radius: ctx.radius }),
|
|
361
|
+
sizeClass.item,
|
|
362
|
+
getItemClasses(ctx.variant, ctx.color, false, isDisabled),
|
|
363
|
+
className
|
|
364
|
+
),
|
|
365
|
+
...props
|
|
366
|
+
},
|
|
367
|
+
icon ?? /* @__PURE__ */ React.createElement(ChevronsLeftIcon, { className: sizeClass.icon })
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
);
|
|
371
|
+
PaginationFirst.displayName = "PaginationFirst";
|
|
372
|
+
var PaginationLast = React.forwardRef(
|
|
373
|
+
({ className, icon, ...props }, ref) => {
|
|
374
|
+
const ctx = usePaginationContext();
|
|
375
|
+
const sizeClass = paginationSizeMap[ctx.size];
|
|
376
|
+
const isDisabled = ctx.disabled || ctx.page >= ctx.total;
|
|
377
|
+
return /* @__PURE__ */ React.createElement(
|
|
378
|
+
"button",
|
|
379
|
+
{
|
|
380
|
+
ref,
|
|
381
|
+
type: "button",
|
|
382
|
+
"aria-label": "Go to last page",
|
|
383
|
+
disabled: isDisabled,
|
|
384
|
+
onClick: () => ctx.onPageChange(ctx.total),
|
|
385
|
+
className: cn(
|
|
386
|
+
paginationItemVariants({ radius: ctx.radius }),
|
|
387
|
+
sizeClass.item,
|
|
388
|
+
getItemClasses(ctx.variant, ctx.color, false, isDisabled),
|
|
389
|
+
className
|
|
390
|
+
),
|
|
391
|
+
...props
|
|
392
|
+
},
|
|
393
|
+
icon ?? /* @__PURE__ */ React.createElement(ChevronsRightIcon, { className: sizeClass.icon })
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
);
|
|
397
|
+
PaginationLast.displayName = "PaginationLast";
|
|
398
|
+
var PaginationEllipsis = React.forwardRef(
|
|
399
|
+
({ className, ...props }, ref) => {
|
|
400
|
+
const ctx = usePaginationContext();
|
|
401
|
+
const sizeClass = paginationSizeMap[ctx.size];
|
|
402
|
+
return /* @__PURE__ */ React.createElement(
|
|
403
|
+
"span",
|
|
404
|
+
{
|
|
405
|
+
ref,
|
|
406
|
+
"aria-hidden": "true",
|
|
407
|
+
className: cn(
|
|
408
|
+
"inline-flex items-center justify-center text-text-muted",
|
|
409
|
+
sizeClass.item,
|
|
410
|
+
className
|
|
411
|
+
),
|
|
412
|
+
...props
|
|
413
|
+
},
|
|
414
|
+
/* @__PURE__ */ React.createElement(EllipsisIcon, { className: sizeClass.icon }),
|
|
415
|
+
/* @__PURE__ */ React.createElement("span", { className: "sr-only" }, "More pages")
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
);
|
|
419
|
+
PaginationEllipsis.displayName = "PaginationEllipsis";
|
|
420
|
+
var PaginationItems = React.forwardRef(
|
|
421
|
+
({ className, ...props }, ref) => {
|
|
422
|
+
const ctx = usePaginationContext();
|
|
423
|
+
return /* @__PURE__ */ React.createElement("div", { ref, className: cn("contents", className), ...props }, ctx.paginationRange.map((item, index) => /* @__PURE__ */ React.createElement(PaginationItem, { key: `${item}-${index}` }, item === "dots" ? /* @__PURE__ */ React.createElement(PaginationEllipsis, null) : /* @__PURE__ */ React.createElement(PaginationLink, { page: item }))));
|
|
424
|
+
}
|
|
425
|
+
);
|
|
426
|
+
PaginationItems.displayName = "PaginationItems";
|
|
427
|
+
|
|
428
|
+
export {
|
|
429
|
+
usePagination,
|
|
430
|
+
paginationSizeMap,
|
|
431
|
+
paginationItemVariants,
|
|
432
|
+
Pagination,
|
|
433
|
+
PaginationContent,
|
|
434
|
+
PaginationItem,
|
|
435
|
+
PaginationLink,
|
|
436
|
+
PaginationPrevious,
|
|
437
|
+
PaginationNext,
|
|
438
|
+
PaginationFirst,
|
|
439
|
+
PaginationLast,
|
|
440
|
+
PaginationEllipsis,
|
|
441
|
+
PaginationItems
|
|
442
|
+
};
|
|
443
|
+
//# sourceMappingURL=chunk-T546XBQG.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/ui/pagination.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cva } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// ─── Built-in Icons ──────────────────────────────────────\n\nfunction ChevronLeftIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n )\n}\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n )\n}\n\nfunction ChevronsLeftIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11 17l-5-5 5-5M18 17l-5-5 5-5\" />\n </svg>\n )\n}\n\nfunction ChevronsRightIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M13 7l5 5-5 5M6 7l5 5-5 5\" />\n </svg>\n )\n}\n\nfunction EllipsisIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" />\n </svg>\n )\n}\n\n// ─── usePagination Hook ──────────────────────────────────\n\nexport type PaginationRange = (number | 'dots')[]\n\nexport interface UsePaginationProps {\n /** Total number of pages */\n total: number\n /** Number of siblings on each side of current page */\n siblings?: number\n /** Number of boundary pages at start/end */\n boundaries?: number\n /** Current active page (1-based) */\n page: number\n}\n\nfunction range(start: number, end: number): number[] {\n const result: number[] = []\n for (let i = start; i <= end; i++) result.push(i)\n return result\n}\n\nexport function usePagination({\n total,\n siblings = 1,\n boundaries = 1,\n page,\n}: UsePaginationProps): PaginationRange {\n if (total <= 0) return []\n\n const totalPageNumbers = siblings * 2 + 3 + boundaries * 2\n if (totalPageNumbers >= total) {\n return range(1, total)\n }\n\n const leftSiblingIndex = Math.max(page - siblings, boundaries + 1)\n const rightSiblingIndex = Math.min(page + siblings, total - boundaries)\n\n const showLeftDots = leftSiblingIndex > boundaries + 2\n const showRightDots = rightSiblingIndex < total - boundaries - 1\n\n if (!showLeftDots && showRightDots) {\n const leftItemCount = 3 + 2 * siblings + boundaries\n const leftRange = range(1, leftItemCount)\n return [...leftRange, 'dots' as const, ...range(total - boundaries + 1, total)]\n }\n\n if (showLeftDots && !showRightDots) {\n const rightItemCount = 3 + 2 * siblings + boundaries\n const rightRange = range(total - rightItemCount + 1, total)\n return [...range(1, boundaries), 'dots' as const, ...rightRange]\n }\n\n return [\n ...range(1, boundaries),\n 'dots' as const,\n ...range(leftSiblingIndex, rightSiblingIndex),\n 'dots' as const,\n ...range(total - boundaries + 1, total),\n ]\n}\n\n// ─── Context ─────────────────────────────────────────────\n\nexport type PaginationSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl'\nexport type PaginationVariant = 'default' | 'outline' | 'ghost'\nexport type PaginationColor = 'default' | 'primary'\nexport type PaginationRadius = 'sm' | 'base' | 'md' | 'lg' | 'xl' | 'full'\n\ntype PaginationContextValue = {\n page: number\n total: number\n siblings: number\n boundaries: number\n size: PaginationSize\n variant: PaginationVariant\n color: PaginationColor\n radius: PaginationRadius\n disabled: boolean\n loop: boolean\n onPageChange: (page: number) => void\n paginationRange: PaginationRange\n}\n\nconst PaginationContext = React.createContext<PaginationContextValue | null>(null)\n\nfunction usePaginationContext() {\n const ctx = React.useContext(PaginationContext)\n if (!ctx) throw new Error('Pagination components must be used within <Pagination>')\n return ctx\n}\n\n// ─── Size Map ────────────────────────────────────────────\n\nconst paginationSizeMap = {\n xs: { item: 'h-7 min-w-7 text-xs', icon: 'icon-xs', gap: 'gap-1' },\n sm: { item: 'h-8 min-w-8 text-sm', icon: 'icon-xs', gap: 'gap-1' },\n default: { item: 'h-9 min-w-9 text-md', icon: 'icon-sm', gap: 'gap-1' },\n lg: { item: 'h-10 min-w-10 text-md', icon: 'icon-sm', gap: 'gap-1.5' },\n xl: { item: 'h-12 min-w-12 text-base', icon: 'icon-sm', gap: 'gap-1.5' },\n} as const\n\n// ─── Item Variants (CVA) ─────────────────────────────────\n\nconst paginationItemVariants = cva(\n 'inline-flex items-center justify-center select-none transition-colors duration-fast font-semibold focus-visible:focus-ring',\n {\n variants: {\n radius: {\n sm: 'rounded-sm',\n base: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n full: 'rounded-full',\n },\n },\n defaultVariants: {\n radius: 'md',\n },\n }\n)\n\n// ─── Variant Style Helpers ───────────────────────────────\n\n// Active color maps\nconst activeColorMap = {\n default: 'bg-foreground text-background',\n primary: 'bg-primary text-primary-foreground',\n} as const\n\nconst ghostActiveColorMap = {\n default: 'bg-background-muted text-foreground font-bold',\n primary: 'bg-background-muted text-primary',\n} as const\n\nfunction getItemClasses(variant: PaginationVariant, color: PaginationColor, isActive: boolean, disabled: boolean) {\n if (disabled) {\n return variant === 'outline'\n ? 'border border-border text-disabled-foreground pointer-events-none opacity-50'\n : 'border border-transparent text-disabled-foreground pointer-events-none opacity-50'\n }\n if (isActive) {\n switch (variant) {\n case 'outline':\n return `border ${color === 'default' ? 'border-foreground' : 'border-primary'} ${activeColorMap[color]}`\n case 'ghost':\n return `border border-transparent ${ghostActiveColorMap[color]}`\n case 'default':\n default:\n return `border border-transparent ${activeColorMap[color]}`\n }\n }\n switch (variant) {\n case 'outline':\n return 'border border-border text-text-muted hover:bg-background-muted hover:text-foreground'\n case 'ghost':\n return 'border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground'\n case 'default':\n default:\n return 'border border-transparent text-text-muted hover:bg-background-muted hover:text-foreground'\n }\n}\n\n// ─── Pagination (Root) ───────────────────────────────────\n\nexport interface PaginationProps extends Omit<React.ComponentPropsWithoutRef<'nav'>, 'onChange'> {\n /** Total number of pages */\n total?: number\n /** Controlled active page (1-based) */\n value?: number\n /** Initial page for uncontrolled mode */\n defaultValue?: number\n /** Page change callback */\n onChange?: (page: number) => void\n /** Number of siblings on each side of current page */\n siblings?: number\n /** Number of boundary pages at start/end */\n boundaries?: number\n /** Component size */\n size?: PaginationSize\n /** Visual variant */\n variant?: PaginationVariant\n /** Active page color */\n color?: PaginationColor\n /** Border radius */\n radius?: PaginationRadius\n /** Disable all interactions */\n disabled?: boolean\n /** Show previous/next controls */\n withControls?: boolean\n /** Show first/last controls */\n withEdges?: boolean\n /** Loop from last to first and vice versa */\n loop?: boolean\n}\n\nconst Pagination = React.forwardRef<HTMLElement, PaginationProps>(\n ({\n className,\n total = 1,\n value,\n defaultValue = 1,\n onChange,\n siblings = 1,\n boundaries = 1,\n size = 'default',\n variant = 'default',\n color = 'default',\n radius = 'md',\n disabled = false,\n withControls = true,\n withEdges = false,\n loop = false,\n children,\n ...props\n }, ref) => {\n // Controlled / Uncontrolled\n const [internalPage, setInternalPage] = React.useState(defaultValue)\n const isControlled = value !== undefined\n const page = isControlled ? value : internalPage\n\n const handlePageChange = React.useCallback((newPage: number) => {\n if (disabled) return\n const clamped = Math.max(1, Math.min(total, newPage))\n if (!isControlled) setInternalPage(clamped)\n onChange?.(clamped)\n }, [disabled, total, isControlled, onChange])\n\n const paginationRange = usePagination({ total, siblings, boundaries, page })\n\n const contextValue = React.useMemo<PaginationContextValue>(() => ({\n page,\n total,\n siblings,\n boundaries,\n size,\n variant,\n color,\n radius,\n disabled,\n loop,\n onPageChange: handlePageChange,\n paginationRange,\n }), [page, total, siblings, boundaries, size, variant, color, radius, disabled, loop, handlePageChange, paginationRange])\n\n return (\n <PaginationContext.Provider value={contextValue}>\n <nav\n ref={ref}\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn('', className)}\n {...props}\n >\n {children ?? (\n <PaginationContent>\n {withEdges && <PaginationItem><PaginationFirst /></PaginationItem>}\n {withControls && <PaginationItem><PaginationPrevious /></PaginationItem>}\n <PaginationItems />\n {withControls && <PaginationItem><PaginationNext /></PaginationItem>}\n {withEdges && <PaginationItem><PaginationLast /></PaginationItem>}\n </PaginationContent>\n )}\n </nav>\n </PaginationContext.Provider>\n )\n }\n)\nPagination.displayName = 'Pagination'\n\n// ─── PaginationContent ───────────────────────────────────\n\nconst PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentPropsWithoutRef<'ul'>>(\n ({ className, ...props }, ref) => {\n const { size } = usePaginationContext()\n const sizeClass = paginationSizeMap[size]\n return (\n <ul\n ref={ref}\n className={cn('flex flex-wrap items-center', sizeClass.gap, className)}\n {...props}\n />\n )\n }\n)\nPaginationContent.displayName = 'PaginationContent'\n\n// ─── PaginationItem ──────────────────────────────────────\n\nconst PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<'li'>>(\n ({ className, ...props }, ref) => (\n <li ref={ref} className={cn('', className)} {...props} />\n )\n)\nPaginationItem.displayName = 'PaginationItem'\n\n// ─── PaginationLink ──────────────────────────────────────\n\nexport interface PaginationLinkProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Page number this link navigates to */\n page: number\n /** Whether this page is currently active (auto-detected from context if omitted) */\n isActive?: boolean\n}\n\nconst PaginationLink = React.forwardRef<HTMLButtonElement, PaginationLinkProps>(\n ({ className, page: targetPage, isActive: isActiveProp, ...props }, ref) => {\n const ctx = usePaginationContext()\n const isActive = isActiveProp ?? (ctx.page === targetPage)\n const sizeClass = paginationSizeMap[ctx.size]\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-current={isActive ? 'page' : undefined}\n aria-label={`Go to page ${targetPage}`}\n disabled={ctx.disabled}\n onClick={() => ctx.onPageChange(targetPage)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, isActive, ctx.disabled),\n className\n )}\n {...props}\n >\n {targetPage}\n </button>\n )\n }\n)\nPaginationLink.displayName = 'PaginationLink'\n\n// ─── PaginationPrevious ──────────────────────────────────\n\nexport interface PaginationPreviousProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationPrevious = React.forwardRef<HTMLButtonElement, PaginationPreviousProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || (!ctx.loop && ctx.page <= 1)\n\n const handleClick = () => {\n if (ctx.page <= 1) {\n if (ctx.loop) ctx.onPageChange(ctx.total)\n } else {\n ctx.onPageChange(ctx.page - 1)\n }\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to previous page\"\n disabled={isDisabled}\n onClick={handleClick}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronLeftIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationPrevious.displayName = 'PaginationPrevious'\n\n// ─── PaginationNext ──────────────────────────────────────\n\nexport interface PaginationNextProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationNext = React.forwardRef<HTMLButtonElement, PaginationNextProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || (!ctx.loop && ctx.page >= ctx.total)\n\n const handleClick = () => {\n if (ctx.page >= ctx.total) {\n if (ctx.loop) ctx.onPageChange(1)\n } else {\n ctx.onPageChange(ctx.page + 1)\n }\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to next page\"\n disabled={isDisabled}\n onClick={handleClick}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronRightIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationNext.displayName = 'PaginationNext'\n\n// ─── PaginationFirst ─────────────────────────────────────\n\nexport interface PaginationFirstProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationFirst = React.forwardRef<HTMLButtonElement, PaginationFirstProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || ctx.page <= 1\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to first page\"\n disabled={isDisabled}\n onClick={() => ctx.onPageChange(1)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronsLeftIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationFirst.displayName = 'PaginationFirst'\n\n// ─── PaginationLast ──────────────────────────────────────\n\nexport interface PaginationLastProps extends React.ComponentPropsWithoutRef<'button'> {\n /** Custom icon */\n icon?: React.ReactNode\n}\n\nconst PaginationLast = React.forwardRef<HTMLButtonElement, PaginationLastProps>(\n ({ className, icon, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n const isDisabled = ctx.disabled || ctx.page >= ctx.total\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Go to last page\"\n disabled={isDisabled}\n onClick={() => ctx.onPageChange(ctx.total)}\n className={cn(\n paginationItemVariants({ radius: ctx.radius }),\n sizeClass.item,\n getItemClasses(ctx.variant, ctx.color, false, isDisabled),\n className\n )}\n {...props}\n >\n {icon ?? <ChevronsRightIcon className={sizeClass.icon} />}\n </button>\n )\n }\n)\nPaginationLast.displayName = 'PaginationLast'\n\n// ─── PaginationEllipsis ──────────────────────────────────\n\nconst PaginationEllipsis = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<'span'>>(\n ({ className, ...props }, ref) => {\n const ctx = usePaginationContext()\n const sizeClass = paginationSizeMap[ctx.size]\n return (\n <span\n ref={ref}\n aria-hidden=\"true\"\n className={cn(\n 'inline-flex items-center justify-center text-text-muted',\n sizeClass.item,\n className\n )}\n {...props}\n >\n <EllipsisIcon className={sizeClass.icon} />\n <span className=\"sr-only\">More pages</span>\n </span>\n )\n }\n)\nPaginationEllipsis.displayName = 'PaginationEllipsis'\n\n// ─── PaginationItems (Convenience) ───────────────────────\n\nconst PaginationItems = React.forwardRef<HTMLDivElement, React.ComponentPropsWithoutRef<'div'>>(\n ({ className, ...props }, ref) => {\n const ctx = usePaginationContext()\n return (\n <div ref={ref} className={cn('contents', className)} {...props}>\n {ctx.paginationRange.map((item, index) => (\n <PaginationItem key={`${item}-${index}`}>\n {item === 'dots' ? (\n <PaginationEllipsis />\n ) : (\n <PaginationLink page={item} />\n )}\n </PaginationItem>\n ))}\n </div>\n )\n }\n)\nPaginationItems.displayName = 'PaginationItems'\n\n// ─── Exports ─────────────────────────────────────────────\nexport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n PaginationPrevious,\n PaginationNext,\n PaginationFirst,\n PaginationLast,\n PaginationEllipsis,\n PaginationItems,\n paginationItemVariants,\n paginationSizeMap,\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
useFieldContext
|
|
4
|
+
} from "./chunk-Z6JWWCNL.mjs";
|
|
5
|
+
import {
|
|
6
|
+
cn
|
|
7
|
+
} from "./chunk-53MIUPSY.mjs";
|
|
8
|
+
|
|
9
|
+
// src/components/ui/checkbox.tsx
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
12
|
+
import { cva } from "class-variance-authority";
|
|
13
|
+
var checkboxColorMap = {
|
|
14
|
+
default: "data-[state=checked]:bg-foreground data-[state=checked]:border-foreground data-[state=checked]:text-background data-[state=indeterminate]:bg-foreground data-[state=indeterminate]:border-foreground data-[state=indeterminate]:text-background",
|
|
15
|
+
primary: "data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=checked]:text-primary-foreground data-[state=indeterminate]:bg-primary data-[state=indeterminate]:border-primary data-[state=indeterminate]:text-primary-foreground"
|
|
16
|
+
};
|
|
17
|
+
var checkboxVariants = cva(
|
|
18
|
+
[
|
|
19
|
+
"peer relative shrink-0 border-border hover:border-border-strong transition-all duration-micro ease-out",
|
|
20
|
+
"focus-visible:focus-ring",
|
|
21
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
22
|
+
// Transparent hit area expansion via ::after
|
|
23
|
+
"after:absolute after:content-['']"
|
|
24
|
+
].join(" "),
|
|
25
|
+
{
|
|
26
|
+
variants: {
|
|
27
|
+
size: {
|
|
28
|
+
sm: "w-3.5 h-3.5 after:-inset-[5px]",
|
|
29
|
+
// 14px box → 24px click
|
|
30
|
+
default: "w-4 h-4 after:-inset-2",
|
|
31
|
+
// 16px box → 32px click
|
|
32
|
+
lg: "w-5 h-5 after:-inset-2"
|
|
33
|
+
// 20px box → 36px click
|
|
34
|
+
},
|
|
35
|
+
radius: {
|
|
36
|
+
none: "rounded-none",
|
|
37
|
+
// 0px — sharp square
|
|
38
|
+
sm: "rounded-sm",
|
|
39
|
+
// 2px — default checkbox style
|
|
40
|
+
md: "rounded"
|
|
41
|
+
// 4px — softer corners
|
|
42
|
+
},
|
|
43
|
+
weight: {
|
|
44
|
+
thin: "border",
|
|
45
|
+
// 1px
|
|
46
|
+
bold: "border-2"
|
|
47
|
+
// 2px
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
defaultVariants: {
|
|
51
|
+
size: "default",
|
|
52
|
+
radius: "sm",
|
|
53
|
+
weight: "bold"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
var checkIconSizes = {
|
|
58
|
+
sm: "w-2.5 h-2.5",
|
|
59
|
+
// 10px in 14px box
|
|
60
|
+
default: "w-3 h-3",
|
|
61
|
+
// 12px in 16px box
|
|
62
|
+
lg: "icon-xs"
|
|
63
|
+
// 14px in 20px box
|
|
64
|
+
};
|
|
65
|
+
var labelSizes = {
|
|
66
|
+
sm: "text-xs",
|
|
67
|
+
// 12px
|
|
68
|
+
default: "text-md",
|
|
69
|
+
// 14px
|
|
70
|
+
lg: "text-base"
|
|
71
|
+
// 16px
|
|
72
|
+
};
|
|
73
|
+
var gapSizes = {
|
|
74
|
+
sm: "gap-1.5",
|
|
75
|
+
default: "gap-2",
|
|
76
|
+
lg: "gap-2.5"
|
|
77
|
+
};
|
|
78
|
+
var Checkbox = React.forwardRef(({ className, size, radius, weight, color = "default", label, disabled, id, ...props }, ref) => {
|
|
79
|
+
const fieldContext = useFieldContext();
|
|
80
|
+
const resolvedSize = size || "default";
|
|
81
|
+
const resolvedDisabled = disabled ?? fieldContext?.disabled;
|
|
82
|
+
const generatedId = React.useId();
|
|
83
|
+
const checkboxId = id ?? fieldContext?.id ?? generatedId;
|
|
84
|
+
const checkbox = /* @__PURE__ */ React.createElement(
|
|
85
|
+
CheckboxPrimitive.Root,
|
|
86
|
+
{
|
|
87
|
+
ref,
|
|
88
|
+
id: checkboxId,
|
|
89
|
+
disabled: resolvedDisabled,
|
|
90
|
+
className: cn(
|
|
91
|
+
checkboxVariants({ size, radius, weight }),
|
|
92
|
+
checkboxColorMap[color],
|
|
93
|
+
className
|
|
94
|
+
),
|
|
95
|
+
...props
|
|
96
|
+
},
|
|
97
|
+
/* @__PURE__ */ React.createElement(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center animate-checkbox-enter" }, /* @__PURE__ */ React.createElement(CheckIcon, { className: checkIconSizes[resolvedSize] }))
|
|
98
|
+
);
|
|
99
|
+
if (!label) return checkbox;
|
|
100
|
+
return /* @__PURE__ */ React.createElement("div", { className: cn("group flex items-center", gapSizes[resolvedSize]) }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center" }, checkbox), /* @__PURE__ */ React.createElement(
|
|
101
|
+
"label",
|
|
102
|
+
{
|
|
103
|
+
htmlFor: checkboxId,
|
|
104
|
+
className: cn(
|
|
105
|
+
labelSizes[resolvedSize],
|
|
106
|
+
"text-text-muted cursor-pointer select-none transition-colors duration-micro",
|
|
107
|
+
"group-hover:text-foreground",
|
|
108
|
+
resolvedDisabled && "opacity-50 cursor-not-allowed"
|
|
109
|
+
)
|
|
110
|
+
},
|
|
111
|
+
label
|
|
112
|
+
));
|
|
113
|
+
});
|
|
114
|
+
Checkbox.displayName = "Checkbox";
|
|
115
|
+
function CheckIcon({ className }) {
|
|
116
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
117
|
+
"svg",
|
|
118
|
+
{
|
|
119
|
+
className: cn(className, "hidden [[data-state=checked]_&]:block"),
|
|
120
|
+
fill: "none",
|
|
121
|
+
viewBox: "0 0 24 24",
|
|
122
|
+
stroke: "currentColor",
|
|
123
|
+
strokeWidth: 3,
|
|
124
|
+
"aria-hidden": "true"
|
|
125
|
+
},
|
|
126
|
+
/* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" })
|
|
127
|
+
), /* @__PURE__ */ React.createElement(
|
|
128
|
+
"svg",
|
|
129
|
+
{
|
|
130
|
+
className: cn(className, "hidden [[data-state=indeterminate]_&]:block"),
|
|
131
|
+
fill: "none",
|
|
132
|
+
viewBox: "0 0 24 24",
|
|
133
|
+
stroke: "currentColor",
|
|
134
|
+
strokeWidth: 3,
|
|
135
|
+
"aria-hidden": "true"
|
|
136
|
+
},
|
|
137
|
+
/* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 12h14" })
|
|
138
|
+
));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export {
|
|
142
|
+
checkboxVariants,
|
|
143
|
+
Checkbox
|
|
144
|
+
};
|
|
145
|
+
//# sourceMappingURL=chunk-UWTT5AE6.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/ui/checkbox.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as CheckboxPrimitive from '@radix-ui/react-checkbox'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\nimport { useFieldContext } from './field'\n\n// Color maps for checked/indeterminate state\nconst checkboxColorMap = {\n default: 'data-[state=checked]:bg-foreground data-[state=checked]:border-foreground data-[state=checked]:text-background data-[state=indeterminate]:bg-foreground data-[state=indeterminate]:border-foreground data-[state=indeterminate]:text-background',\n primary: 'data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=checked]:text-primary-foreground data-[state=indeterminate]:bg-primary data-[state=indeterminate]:border-primary data-[state=indeterminate]:text-primary-foreground',\n} as const\n\nexport type CheckboxColor = keyof typeof checkboxColorMap\n\n// Checkbox box variants\nconst checkboxVariants = cva(\n [\n 'peer relative shrink-0 border-border hover:border-border-strong transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n // Transparent hit area expansion via ::after\n \"after:absolute after:content-['']\",\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'w-3.5 h-3.5 after:-inset-[5px]', // 14px box → 24px click\n default: 'w-4 h-4 after:-inset-2', // 16px box → 32px click\n lg: 'w-5 h-5 after:-inset-2', // 20px box → 36px click\n },\n radius: {\n none: 'rounded-none', // 0px — sharp square\n sm: 'rounded-sm', // 2px — default checkbox style\n md: 'rounded', // 4px — softer corners\n },\n weight: {\n thin: 'border', // 1px\n bold: 'border-2', // 2px\n },\n },\n defaultVariants: {\n size: 'default',\n radius: 'sm',\n weight: 'bold',\n },\n }\n)\n\n// Check icon sizes per checkbox size\nconst checkIconSizes = {\n sm: 'w-2.5 h-2.5', // 10px in 14px box\n default: 'w-3 h-3', // 12px in 16px box\n lg: 'icon-xs', // 14px in 20px box\n}\n\n// Label font sizes per checkbox size\nconst labelSizes = {\n sm: 'text-xs', // 12px\n default: 'text-md', // 14px\n lg: 'text-base', // 16px\n}\n\n// Gap between checkbox and label\nconst gapSizes = {\n sm: 'gap-1.5',\n default: 'gap-2',\n lg: 'gap-2.5',\n}\n\nexport interface CheckboxProps\n extends Omit<React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>, 'children'>,\n VariantProps<typeof checkboxVariants> {\n /** Checked state color */\n color?: CheckboxColor\n label?: string\n radius?: 'none' | 'sm' | 'md'\n}\n\nconst Checkbox = React.forwardRef<\n React.ElementRef<typeof CheckboxPrimitive.Root>,\n CheckboxProps\n>(({ className, size, radius, weight, color = 'default', label, disabled, id, ...props }, ref) => {\n const fieldContext = useFieldContext()\n const resolvedSize = size || 'default'\n const resolvedDisabled = disabled ?? fieldContext?.disabled\n const generatedId = React.useId()\n const checkboxId = id ?? fieldContext?.id ?? generatedId\n\n const checkbox = (\n <CheckboxPrimitive.Root\n ref={ref}\n id={checkboxId}\n disabled={resolvedDisabled}\n className={cn(\n checkboxVariants({ size, radius, weight }),\n checkboxColorMap[color],\n className\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator className=\"flex items-center justify-center animate-checkbox-enter\">\n <CheckIcon className={checkIconSizes[resolvedSize]} />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n )\n\n if (!label) return checkbox\n\n return (\n <div className={cn('group flex items-center', gapSizes[resolvedSize])}>\n <div className=\"flex items-center\">\n {checkbox}\n </div>\n <label\n htmlFor={checkboxId}\n className={cn(\n labelSizes[resolvedSize],\n 'text-text-muted cursor-pointer select-none transition-colors duration-micro',\n 'group-hover:text-foreground',\n resolvedDisabled && 'opacity-50 cursor-not-allowed'\n )}\n >\n {label}\n </label>\n </div>\n )\n})\nCheckbox.displayName = 'Checkbox'\n\n// Check icon — renders ✓ for checked, — for indeterminate\nfunction CheckIcon({ className }: { className?: string }) {\n return (\n <>\n {/* Check mark (shown when data-state=checked on parent Indicator) */}\n <svg\n className={cn(className, 'hidden [[data-state=checked]_&]:block')}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={3}\n aria-hidden=\"true\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n {/* Dash (shown when data-state=indeterminate on parent Indicator) */}\n <svg\n className={cn(className, 'hidden [[data-state=indeterminate]_&]:block')}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={3}\n aria-hidden=\"true\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 12h14\" />\n </svg>\n </>\n )\n}\n\nexport { Checkbox, checkboxVariants }\n"],"mappings":"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","names":[]}
|