@codraoss/ui 0.9.4
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/LICENSE +625 -0
- package/README.md +15 -0
- package/dist/chunk-HCQJTSV3.js +39 -0
- package/dist/chunk-HCQJTSV3.js.map +1 -0
- package/dist/chunk-OU66JJZD.js +7 -0
- package/dist/chunk-OU66JJZD.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/chunk-TXNSYK4G.js +23 -0
- package/dist/chunk-TXNSYK4G.js.map +1 -0
- package/dist/components/motion/index.d.ts +92 -0
- package/dist/components/motion/index.js +643 -0
- package/dist/components/motion/index.js.map +1 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +241 -0
- package/dist/index.js +1144 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/ease.d.ts +3 -0
- package/dist/lib/ease.js +8 -0
- package/dist/lib/ease.js.map +1 -0
- package/dist/lib/file-tree.d.ts +16 -0
- package/dist/lib/file-tree.js +46 -0
- package/dist/lib/file-tree.js.map +1 -0
- package/dist/lib/highlight.d.ts +14 -0
- package/dist/lib/highlight.js +35 -0
- package/dist/lib/highlight.js.map +1 -0
- package/dist/lib/markdown-plugins.d.ts +6 -0
- package/dist/lib/markdown-plugins.js +11041 -0
- package/dist/lib/markdown-plugins.js.map +1 -0
- package/dist/lib/prompt-diff.d.ts +21 -0
- package/dist/lib/prompt-diff.js +95 -0
- package/dist/lib/prompt-diff.js.map +1 -0
- package/dist/lib/selection.d.ts +11 -0
- package/dist/lib/selection.js +15 -0
- package/dist/lib/selection.js.map +1 -0
- package/dist/lib/theme.d.ts +14 -0
- package/dist/lib/theme.js +78 -0
- package/dist/lib/theme.js.map +1 -0
- package/dist/lib/utils.d.ts +15 -0
- package/dist/lib/utils.js +14 -0
- package/dist/lib/utils.js.map +1 -0
- package/package.json +150 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1144 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cn
|
|
3
|
+
} from "./chunk-HCQJTSV3.js";
|
|
4
|
+
import {
|
|
5
|
+
EASE_OUT
|
|
6
|
+
} from "./chunk-OU66JJZD.js";
|
|
7
|
+
import "./chunk-PZ5AY32C.js";
|
|
8
|
+
|
|
9
|
+
// src/components/alert.tsx
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import { AlertCircle, CheckCircle2, AlertTriangle, Info } from "lucide-react";
|
|
12
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
|
+
var variants = {
|
|
14
|
+
default: {
|
|
15
|
+
bg: "var(--info-bg)",
|
|
16
|
+
border: "var(--info-border)",
|
|
17
|
+
color: "var(--info)",
|
|
18
|
+
icon: Info
|
|
19
|
+
},
|
|
20
|
+
destructive: {
|
|
21
|
+
bg: "var(--danger-bg)",
|
|
22
|
+
border: "var(--danger-border)",
|
|
23
|
+
color: "var(--danger)",
|
|
24
|
+
icon: AlertCircle
|
|
25
|
+
},
|
|
26
|
+
warning: {
|
|
27
|
+
bg: "var(--warning-bg)",
|
|
28
|
+
border: "var(--warning-border)",
|
|
29
|
+
color: "var(--warning)",
|
|
30
|
+
icon: AlertTriangle
|
|
31
|
+
},
|
|
32
|
+
success: {
|
|
33
|
+
bg: "var(--success-bg)",
|
|
34
|
+
border: "var(--success-border)",
|
|
35
|
+
color: "var(--success)",
|
|
36
|
+
icon: CheckCircle2
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var Alert = React.forwardRef(
|
|
40
|
+
({ className, variant = "default", icon: IconOverride, children, ...props }, ref) => {
|
|
41
|
+
const config = variants[variant];
|
|
42
|
+
const Icon = IconOverride || config.icon;
|
|
43
|
+
return /* @__PURE__ */ jsxs(
|
|
44
|
+
"div",
|
|
45
|
+
{
|
|
46
|
+
ref,
|
|
47
|
+
role: "alert",
|
|
48
|
+
className: cn(
|
|
49
|
+
"flex gap-3 rounded-lg border px-4 py-3 text-sm",
|
|
50
|
+
className
|
|
51
|
+
),
|
|
52
|
+
style: {
|
|
53
|
+
backgroundColor: config.bg,
|
|
54
|
+
borderColor: config.border,
|
|
55
|
+
color: config.color
|
|
56
|
+
},
|
|
57
|
+
...props,
|
|
58
|
+
children: [
|
|
59
|
+
/* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 shrink-0 mt-0.5" }),
|
|
60
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children })
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
Alert.displayName = "Alert";
|
|
67
|
+
|
|
68
|
+
// src/components/badge.tsx
|
|
69
|
+
import "react";
|
|
70
|
+
import "class-variance-authority";
|
|
71
|
+
|
|
72
|
+
// src/components/badge-variants.ts
|
|
73
|
+
import { cva } from "class-variance-authority";
|
|
74
|
+
var badgeVariants = cva(
|
|
75
|
+
"inline-flex items-center gap-1 rounded-md px-2 py-0.5 text-[11px] font-medium transition-colors",
|
|
76
|
+
{
|
|
77
|
+
variants: {
|
|
78
|
+
variant: {
|
|
79
|
+
default: "bg-primary/15 text-primary",
|
|
80
|
+
secondary: "bg-ui-fill/45 text-ui-default",
|
|
81
|
+
neutral: "bg-ui-fill/45 text-ui-default",
|
|
82
|
+
info: "bg-info/15 text-info",
|
|
83
|
+
success: "bg-success/15 text-success",
|
|
84
|
+
warning: "bg-warning/15 text-warning",
|
|
85
|
+
danger: "bg-danger/15 text-danger",
|
|
86
|
+
outline: "text-ui-default ring-1 ring-inset ring-ui-line bg-transparent"
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
defaultVariants: { variant: "default" }
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// src/components/badge.tsx
|
|
94
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
95
|
+
function Badge({ className, variant, ...props }) {
|
|
96
|
+
return /* @__PURE__ */ jsx2("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/components/button.tsx
|
|
100
|
+
import * as React3 from "react";
|
|
101
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
102
|
+
import "class-variance-authority";
|
|
103
|
+
import { Loader2 } from "lucide-react";
|
|
104
|
+
|
|
105
|
+
// src/components/button-variants.ts
|
|
106
|
+
import { cva as cva2 } from "class-variance-authority";
|
|
107
|
+
var buttonVariants = cva2(
|
|
108
|
+
"relative inline-flex select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
109
|
+
{
|
|
110
|
+
variants: {
|
|
111
|
+
variant: {
|
|
112
|
+
primary: "border border-[var(--btn-primary-border)] bg-[var(--btn-primary-surface)] text-[var(--btn-primary-fg)] hover:bg-[var(--btn-primary-hover)]",
|
|
113
|
+
secondary: "border border-ui-line bg-ui-base text-ui-default hover:bg-ui-fill/60",
|
|
114
|
+
default: "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90 active:scale-[.98]",
|
|
115
|
+
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
116
|
+
"destructive-outline": "border border-danger-border bg-danger-bg/40 text-danger shadow-sm hover:bg-destructive hover:text-destructive-foreground hover:border-destructive",
|
|
117
|
+
"warning-outline": "border border-warning-border bg-warning-bg/40 text-warning shadow-sm hover:bg-warning-bg hover:border-warning",
|
|
118
|
+
outline: "border border-zinc-200 bg-white shadow-sm hover:bg-zinc-50 hover:text-zinc-900 dark:border-white/10 dark:bg-white/[0.06] dark:hover:bg-white/[0.1] dark:hover:text-foreground",
|
|
119
|
+
ghost: "hover:bg-secondary hover:text-secondary-foreground",
|
|
120
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
121
|
+
accent: "bg-accent text-accent-foreground shadow-sm hover:bg-accent/90 active:scale-[.98]"
|
|
122
|
+
},
|
|
123
|
+
size: {
|
|
124
|
+
default: "h-9 rounded-md px-4 py-2 text-sm",
|
|
125
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
126
|
+
base: "h-9 rounded-md px-3 text-sm",
|
|
127
|
+
lg: "h-11 rounded-md px-6 text-sm",
|
|
128
|
+
xs: "h-6 rounded-md px-1.5 text-xs",
|
|
129
|
+
icon: "h-9 w-9 rounded-md"
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
defaultVariants: { variant: "default", size: "default" }
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
// src/components/button.tsx
|
|
137
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
138
|
+
var SQUARE_WIDTH = {
|
|
139
|
+
xs: "w-6 p-0",
|
|
140
|
+
sm: "w-8 p-0",
|
|
141
|
+
base: "w-9 p-0",
|
|
142
|
+
default: "w-9 p-0",
|
|
143
|
+
lg: "w-11 p-0",
|
|
144
|
+
icon: "p-0"
|
|
145
|
+
};
|
|
146
|
+
function shapeClass(shape, size) {
|
|
147
|
+
if (shape === "base") return "";
|
|
148
|
+
return cn(SQUARE_WIDTH[size ?? "default"], shape === "circle" && "rounded-full");
|
|
149
|
+
}
|
|
150
|
+
var Button = React3.forwardRef(
|
|
151
|
+
({ className, variant, size, shape = "base", asChild = false, icon, loading, children, ...props }, ref) => {
|
|
152
|
+
const classes = cn(buttonVariants({ variant, size }), shapeClass(shape, size), className);
|
|
153
|
+
return useRender({
|
|
154
|
+
render: asChild && React3.isValidElement(children) ? children : void 0,
|
|
155
|
+
defaultTagName: "button",
|
|
156
|
+
ref,
|
|
157
|
+
props: {
|
|
158
|
+
className: classes,
|
|
159
|
+
...props,
|
|
160
|
+
...asChild ? {} : {
|
|
161
|
+
disabled: props.disabled || loading,
|
|
162
|
+
children: /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
163
|
+
loading ? /* @__PURE__ */ jsx3(Loader2, { className: "size-4 animate-spin" }) : icon,
|
|
164
|
+
children
|
|
165
|
+
] })
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
Button.displayName = "Button";
|
|
172
|
+
var LinkButton = React3.forwardRef(
|
|
173
|
+
({ className, variant, size, shape = "base", icon, external, children, ...props }, ref) => /* @__PURE__ */ jsxs2(
|
|
174
|
+
"a",
|
|
175
|
+
{
|
|
176
|
+
ref,
|
|
177
|
+
className: cn(buttonVariants({ variant, size }), shapeClass(shape, size), className),
|
|
178
|
+
...external ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
179
|
+
...props,
|
|
180
|
+
children: [
|
|
181
|
+
icon,
|
|
182
|
+
children
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
);
|
|
187
|
+
LinkButton.displayName = "LinkButton";
|
|
188
|
+
|
|
189
|
+
// src/components/confirm-dialog.tsx
|
|
190
|
+
import { Dialog } from "@base-ui/react/dialog";
|
|
191
|
+
import { AlertTriangle as AlertTriangle2 } from "lucide-react";
|
|
192
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
193
|
+
function ConfirmDialog({
|
|
194
|
+
open,
|
|
195
|
+
onOpenChange,
|
|
196
|
+
title,
|
|
197
|
+
description,
|
|
198
|
+
confirmLabel = "Continue",
|
|
199
|
+
cancelLabel = "Cancel",
|
|
200
|
+
confirmVariant = "default",
|
|
201
|
+
onConfirm
|
|
202
|
+
}) {
|
|
203
|
+
return /* @__PURE__ */ jsx4(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs3(Dialog.Portal, { children: [
|
|
204
|
+
/* @__PURE__ */ jsx4(Dialog.Backdrop, { className: "fixed inset-0 z-40 bg-background/75 backdrop-blur-sm transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0" }),
|
|
205
|
+
/* @__PURE__ */ jsxs3(Dialog.Popup, { className: "fixed left-1/2 top-1/2 z-50 w-[calc(100vw-1.5rem)] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg border border-ui-line bg-card p-5 shadow-2xl transition-[opacity,transform] duration-150 data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0", children: [
|
|
206
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-start gap-3", children: [
|
|
207
|
+
/* @__PURE__ */ jsx4("span", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-[var(--warning-bg)] text-[var(--warning)]", children: /* @__PURE__ */ jsx4(AlertTriangle2, { size: 18 }) }),
|
|
208
|
+
/* @__PURE__ */ jsxs3("div", { className: "min-w-0", children: [
|
|
209
|
+
/* @__PURE__ */ jsx4(Dialog.Title, { className: "text-sm font-semibold text-foreground", children: title }),
|
|
210
|
+
/* @__PURE__ */ jsx4(Dialog.Description, { className: "mt-1 text-sm text-muted-foreground", children: description })
|
|
211
|
+
] })
|
|
212
|
+
] }),
|
|
213
|
+
/* @__PURE__ */ jsxs3("div", { className: "mt-5 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", children: [
|
|
214
|
+
/* @__PURE__ */ jsx4(Dialog.Close, { render: /* @__PURE__ */ jsx4(Button, { variant: "outline" }), children: cancelLabel }),
|
|
215
|
+
/* @__PURE__ */ jsx4(
|
|
216
|
+
Button,
|
|
217
|
+
{
|
|
218
|
+
variant: confirmVariant,
|
|
219
|
+
onClick: () => {
|
|
220
|
+
onConfirm();
|
|
221
|
+
onOpenChange(false);
|
|
222
|
+
},
|
|
223
|
+
children: confirmLabel
|
|
224
|
+
}
|
|
225
|
+
)
|
|
226
|
+
] })
|
|
227
|
+
] })
|
|
228
|
+
] }) });
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// src/components/input.tsx
|
|
232
|
+
import * as React4 from "react";
|
|
233
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
234
|
+
var SIZE_CLASS = {
|
|
235
|
+
xs: "h-6 rounded-md px-1.5 text-xs",
|
|
236
|
+
sm: "h-8 rounded-md px-2 text-xs",
|
|
237
|
+
base: "h-9 rounded-md px-3 text-sm",
|
|
238
|
+
lg: "h-10 rounded-md px-4 text-base"
|
|
239
|
+
};
|
|
240
|
+
var Input = React4.forwardRef(
|
|
241
|
+
({ className, size = "base", ...props }, ref) => /* @__PURE__ */ jsx5(
|
|
242
|
+
"input",
|
|
243
|
+
{
|
|
244
|
+
ref,
|
|
245
|
+
className: cn(
|
|
246
|
+
"w-full border border-ui-line bg-ui-base text-ui-default transition-colors placeholder:text-ui-subtle focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ui-brand/40 disabled:cursor-not-allowed disabled:opacity-50",
|
|
247
|
+
SIZE_CLASS[size],
|
|
248
|
+
className
|
|
249
|
+
),
|
|
250
|
+
...props
|
|
251
|
+
}
|
|
252
|
+
)
|
|
253
|
+
);
|
|
254
|
+
Input.displayName = "Input";
|
|
255
|
+
|
|
256
|
+
// src/components/layer-card.tsx
|
|
257
|
+
import * as React5 from "react";
|
|
258
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
259
|
+
var LayerCard = React5.forwardRef(
|
|
260
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
|
|
261
|
+
"div",
|
|
262
|
+
{
|
|
263
|
+
ref,
|
|
264
|
+
className: cn("rounded-lg border border-ui-line bg-ui-base", className),
|
|
265
|
+
...props
|
|
266
|
+
}
|
|
267
|
+
)
|
|
268
|
+
);
|
|
269
|
+
LayerCard.displayName = "LayerCard";
|
|
270
|
+
|
|
271
|
+
// src/components/select.tsx
|
|
272
|
+
import { domAnimation, LazyMotion, useReducedMotion } from "motion/react";
|
|
273
|
+
import {
|
|
274
|
+
useEffect,
|
|
275
|
+
useId,
|
|
276
|
+
useLayoutEffect,
|
|
277
|
+
useRef,
|
|
278
|
+
useState
|
|
279
|
+
} from "react";
|
|
280
|
+
import { createPortal } from "react-dom";
|
|
281
|
+
|
|
282
|
+
// src/components/select-panel.tsx
|
|
283
|
+
import { Check } from "lucide-react";
|
|
284
|
+
import { m } from "motion/react";
|
|
285
|
+
|
|
286
|
+
// src/components/select-shared.ts
|
|
287
|
+
var CHEVRON_TRANSITION = { type: "spring", duration: 0.4, bounce: 0.3 };
|
|
288
|
+
var LIST_VARIANTS = {
|
|
289
|
+
hidden: {},
|
|
290
|
+
show: { transition: { staggerChildren: 0.02, delayChildren: 0.03 } }
|
|
291
|
+
};
|
|
292
|
+
var ITEM_VARIANTS = {
|
|
293
|
+
hidden: { opacity: 0, y: -5, filter: "blur(2px)" },
|
|
294
|
+
show: { opacity: 1, y: 0, filter: "blur(0px)" }
|
|
295
|
+
};
|
|
296
|
+
var INSTANT_TRANSITION = { duration: 0 };
|
|
297
|
+
|
|
298
|
+
// src/components/select-panel.tsx
|
|
299
|
+
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
300
|
+
var REDUCED_TRANSITION = { duration: 0.12 };
|
|
301
|
+
var GAP_TRANSITION_OPEN = { type: "spring", duration: 0.44, bounce: 0.45, delay: 0.09 };
|
|
302
|
+
var GAP_TRANSITION_CLOSED = { type: "spring", duration: 0.26, bounce: 0.1 };
|
|
303
|
+
var RADIUS_TRANSITION_OPEN = { duration: 0.26, ease: EASE_OUT, delay: 0.1 };
|
|
304
|
+
var RADIUS_TRANSITION_CLOSED = { duration: 0.15, ease: EASE_OUT };
|
|
305
|
+
var OPACITY_TRANSITION_OPEN = { duration: 0.18 };
|
|
306
|
+
var OPACITY_TRANSITION_CLOSED = { duration: 0.16, delay: 0.1 };
|
|
307
|
+
var HEIGHT_TRANSITION_OPEN = { type: "spring", duration: 0.4, bounce: 0.14 };
|
|
308
|
+
var HEIGHT_TRANSITION_CLOSED = { duration: 0.24, ease: EASE_OUT, delay: 0.1 };
|
|
309
|
+
function SelectPanel({
|
|
310
|
+
panelRef,
|
|
311
|
+
innerRef,
|
|
312
|
+
optionRefs,
|
|
313
|
+
listId,
|
|
314
|
+
triggerId,
|
|
315
|
+
options,
|
|
316
|
+
value,
|
|
317
|
+
highlightedIndex,
|
|
318
|
+
open,
|
|
319
|
+
isTop,
|
|
320
|
+
reduce,
|
|
321
|
+
height,
|
|
322
|
+
rect,
|
|
323
|
+
onSelect,
|
|
324
|
+
onHighlight
|
|
325
|
+
}) {
|
|
326
|
+
const nearGap = open ? 8 : 0;
|
|
327
|
+
const nearRadius = open ? 7 : 0;
|
|
328
|
+
const gapT = open ? GAP_TRANSITION_OPEN : GAP_TRANSITION_CLOSED;
|
|
329
|
+
const radiusT = open ? RADIUS_TRANSITION_OPEN : RADIUS_TRANSITION_CLOSED;
|
|
330
|
+
return /* @__PURE__ */ jsx7(
|
|
331
|
+
m.div,
|
|
332
|
+
{
|
|
333
|
+
ref: panelRef,
|
|
334
|
+
id: listId,
|
|
335
|
+
role: "listbox",
|
|
336
|
+
"aria-labelledby": triggerId,
|
|
337
|
+
"aria-hidden": !open,
|
|
338
|
+
initial: false,
|
|
339
|
+
animate: reduce ? { opacity: open ? 1 : 0, height: open ? height : 0 } : {
|
|
340
|
+
opacity: open ? 1 : 0,
|
|
341
|
+
height: open ? height : 0,
|
|
342
|
+
// gap opens on the side facing the trigger
|
|
343
|
+
marginTop: isTop ? 0 : nearGap,
|
|
344
|
+
marginBottom: isTop ? nearGap : 0,
|
|
345
|
+
// near corners go flat->round; far corners stay rounded
|
|
346
|
+
borderTopLeftRadius: isTop ? 7 : nearRadius,
|
|
347
|
+
borderTopRightRadius: isTop ? 7 : nearRadius,
|
|
348
|
+
borderBottomLeftRadius: isTop ? nearRadius : 7,
|
|
349
|
+
borderBottomRightRadius: isTop ? nearRadius : 7
|
|
350
|
+
},
|
|
351
|
+
transition: reduce ? REDUCED_TRANSITION : {
|
|
352
|
+
opacity: open ? OPACITY_TRANSITION_OPEN : OPACITY_TRANSITION_CLOSED,
|
|
353
|
+
height: open ? HEIGHT_TRANSITION_OPEN : HEIGHT_TRANSITION_CLOSED,
|
|
354
|
+
marginTop: isTop ? INSTANT_TRANSITION : gapT,
|
|
355
|
+
marginBottom: isTop ? gapT : INSTANT_TRANSITION,
|
|
356
|
+
borderTopLeftRadius: isTop ? INSTANT_TRANSITION : radiusT,
|
|
357
|
+
borderTopRightRadius: isTop ? INSTANT_TRANSITION : radiusT,
|
|
358
|
+
borderBottomLeftRadius: isTop ? radiusT : INSTANT_TRANSITION,
|
|
359
|
+
borderBottomRightRadius: isTop ? radiusT : INSTANT_TRANSITION
|
|
360
|
+
},
|
|
361
|
+
style: {
|
|
362
|
+
position: "fixed",
|
|
363
|
+
left: rect?.left ?? 0,
|
|
364
|
+
width: rect?.width ?? 0,
|
|
365
|
+
top: isTop ? void 0 : rect?.bottom ?? 0,
|
|
366
|
+
bottom: isTop ? window.innerHeight - (rect?.top ?? 0) : void 0,
|
|
367
|
+
transformOrigin: isTop ? "bottom" : "top",
|
|
368
|
+
overflow: "hidden",
|
|
369
|
+
pointerEvents: open ? "auto" : "none"
|
|
370
|
+
},
|
|
371
|
+
className: "z-50 border border-ui-line bg-ui-base shadow-lg shadow-black/[0.04] dark:shadow-black/40",
|
|
372
|
+
children: /* @__PURE__ */ jsx7(
|
|
373
|
+
m.ul,
|
|
374
|
+
{
|
|
375
|
+
ref: innerRef,
|
|
376
|
+
variants: reduce ? void 0 : LIST_VARIANTS,
|
|
377
|
+
initial: false,
|
|
378
|
+
animate: open ? "show" : "hidden",
|
|
379
|
+
className: "max-h-[min(28rem,60vh)] overflow-y-auto p-1",
|
|
380
|
+
children: options.map((option, index) => {
|
|
381
|
+
const selected = option.value === value;
|
|
382
|
+
const highlighted = index === highlightedIndex;
|
|
383
|
+
return /* @__PURE__ */ jsx7(m.li, { variants: reduce ? void 0 : ITEM_VARIANTS, children: /* @__PURE__ */ jsxs4(
|
|
384
|
+
"button",
|
|
385
|
+
{
|
|
386
|
+
ref: (node) => {
|
|
387
|
+
optionRefs.current[index] = node;
|
|
388
|
+
},
|
|
389
|
+
id: `${listId}-option-${index}`,
|
|
390
|
+
type: "button",
|
|
391
|
+
role: "option",
|
|
392
|
+
"aria-selected": selected,
|
|
393
|
+
tabIndex: -1,
|
|
394
|
+
onMouseEnter: () => onHighlight(index),
|
|
395
|
+
onClick: () => onSelect(option.value),
|
|
396
|
+
className: cn(
|
|
397
|
+
// `whitespace-nowrap`: on the 72px "rows per page" select, the check icon ate the width and "10" wrapped to stacked digits.
|
|
398
|
+
"flex w-full items-center justify-between gap-2 whitespace-nowrap rounded-md px-2.5 py-1.5 text-left text-sm outline-none transition-colors",
|
|
399
|
+
selected ? "bg-ui-brand/10 font-medium text-ui-brand" : "text-ui-default hover:bg-ui-fill hover:text-ui-strong focus-visible:bg-ui-fill",
|
|
400
|
+
highlighted && !selected && "bg-ui-fill text-ui-strong"
|
|
401
|
+
),
|
|
402
|
+
children: [
|
|
403
|
+
/* @__PURE__ */ jsx7("span", { className: "min-w-0 truncate", children: option.label }),
|
|
404
|
+
selected ? /* @__PURE__ */ jsx7(Check, { className: "h-3.5 w-3.5 shrink-0" }) : null
|
|
405
|
+
]
|
|
406
|
+
}
|
|
407
|
+
) }, option.value);
|
|
408
|
+
})
|
|
409
|
+
}
|
|
410
|
+
)
|
|
411
|
+
}
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// src/components/select-trigger.tsx
|
|
416
|
+
import { ChevronDown } from "lucide-react";
|
|
417
|
+
import { m as m2 } from "motion/react";
|
|
418
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
419
|
+
var RADIUS_OPEN = [0, 0, 7];
|
|
420
|
+
var RADIUS_CLOSED = [7, 0, 7];
|
|
421
|
+
var RADIUS_TRANSITION_OPEN2 = { duration: 0.46, times: [0, 0.4, 1], ease: EASE_OUT };
|
|
422
|
+
var RADIUS_TRANSITION_CLOSED2 = { duration: 0.34, times: [0, 0.5, 1], ease: EASE_OUT };
|
|
423
|
+
function SelectTrigger({
|
|
424
|
+
triggerRef,
|
|
425
|
+
triggerId,
|
|
426
|
+
listId,
|
|
427
|
+
labelId,
|
|
428
|
+
activeDescendantId,
|
|
429
|
+
open,
|
|
430
|
+
isTop,
|
|
431
|
+
reduce,
|
|
432
|
+
selectedOption,
|
|
433
|
+
placeholder,
|
|
434
|
+
leadingIcon,
|
|
435
|
+
variant,
|
|
436
|
+
className,
|
|
437
|
+
style,
|
|
438
|
+
onToggle,
|
|
439
|
+
onKeyDown
|
|
440
|
+
}) {
|
|
441
|
+
const kf = open ? RADIUS_OPEN : RADIUS_CLOSED;
|
|
442
|
+
const kfT = reduce ? INSTANT_TRANSITION : open ? RADIUS_TRANSITION_OPEN2 : RADIUS_TRANSITION_CLOSED2;
|
|
443
|
+
return /* @__PURE__ */ jsxs5(
|
|
444
|
+
m2.button,
|
|
445
|
+
{
|
|
446
|
+
ref: triggerRef,
|
|
447
|
+
type: "button",
|
|
448
|
+
id: triggerId,
|
|
449
|
+
"aria-haspopup": "listbox",
|
|
450
|
+
"aria-expanded": open,
|
|
451
|
+
"aria-controls": listId,
|
|
452
|
+
"aria-labelledby": labelId ? `${labelId} ${triggerId}` : void 0,
|
|
453
|
+
"aria-activedescendant": activeDescendantId,
|
|
454
|
+
onClick: onToggle,
|
|
455
|
+
onKeyDown,
|
|
456
|
+
initial: false,
|
|
457
|
+
animate: {
|
|
458
|
+
borderTopLeftRadius: isTop ? kf : 7,
|
|
459
|
+
borderTopRightRadius: isTop ? kf : 7,
|
|
460
|
+
borderBottomLeftRadius: isTop ? 7 : kf,
|
|
461
|
+
borderBottomRightRadius: isTop ? 7 : kf
|
|
462
|
+
},
|
|
463
|
+
transition: {
|
|
464
|
+
borderTopLeftRadius: isTop ? kfT : INSTANT_TRANSITION,
|
|
465
|
+
borderTopRightRadius: isTop ? kfT : INSTANT_TRANSITION,
|
|
466
|
+
borderBottomLeftRadius: isTop ? INSTANT_TRANSITION : kfT,
|
|
467
|
+
borderBottomRightRadius: isTop ? INSTANT_TRANSITION : kfT
|
|
468
|
+
},
|
|
469
|
+
style,
|
|
470
|
+
className: cn(
|
|
471
|
+
"relative z-10 flex h-9 w-full items-center justify-between gap-2 border border-ui-line px-3 py-2 text-sm font-normal text-ui-default outline-none transition-colors",
|
|
472
|
+
variant === "page" ? "bg-ui-base" : "bg-ui-fill/50",
|
|
473
|
+
"hover:bg-ui-fill/70 focus-visible:ring-2 focus-visible:ring-ui-brand/40 focus-visible:ring-offset-1 focus-visible:ring-offset-background",
|
|
474
|
+
!selectedOption && "text-ui-subtle",
|
|
475
|
+
className
|
|
476
|
+
),
|
|
477
|
+
children: [
|
|
478
|
+
/* @__PURE__ */ jsxs5("span", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
479
|
+
leadingIcon && /* @__PURE__ */ jsx8("span", { className: "shrink-0 text-primary/70", children: leadingIcon }),
|
|
480
|
+
/* @__PURE__ */ jsx8("span", { className: "min-w-0 truncate", children: selectedOption ? selectedOption.label : placeholder })
|
|
481
|
+
] }),
|
|
482
|
+
/* @__PURE__ */ jsx8(
|
|
483
|
+
m2.span,
|
|
484
|
+
{
|
|
485
|
+
"aria-hidden": true,
|
|
486
|
+
animate: { rotate: open ? 180 : 0 },
|
|
487
|
+
transition: reduce ? INSTANT_TRANSITION : CHEVRON_TRANSITION,
|
|
488
|
+
className: "shrink-0 text-ui-subtle",
|
|
489
|
+
children: /* @__PURE__ */ jsx8(ChevronDown, { className: "h-4 w-4" })
|
|
490
|
+
}
|
|
491
|
+
)
|
|
492
|
+
]
|
|
493
|
+
}
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// src/components/select.tsx
|
|
498
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
499
|
+
function Select({
|
|
500
|
+
value,
|
|
501
|
+
onValueChange,
|
|
502
|
+
options,
|
|
503
|
+
placeholder = "Select...",
|
|
504
|
+
label,
|
|
505
|
+
className,
|
|
506
|
+
triggerClassName,
|
|
507
|
+
triggerStyle,
|
|
508
|
+
leadingIcon,
|
|
509
|
+
variant = "page"
|
|
510
|
+
}) {
|
|
511
|
+
const reduce = useReducedMotion() ?? false;
|
|
512
|
+
const baseId = useId();
|
|
513
|
+
const triggerId = `${baseId}-trigger`;
|
|
514
|
+
const listId = `${baseId}-list`;
|
|
515
|
+
const labelId = `${baseId}-label`;
|
|
516
|
+
const triggerRef = useRef(null);
|
|
517
|
+
const labelRef = useRef(null);
|
|
518
|
+
const panelRef = useRef(null);
|
|
519
|
+
const innerRef = useRef(null);
|
|
520
|
+
const [open, setOpen] = useState(false);
|
|
521
|
+
const [placement, setPlacement] = useState("bottom");
|
|
522
|
+
const [height, setHeight] = useState(0);
|
|
523
|
+
const [rect, setRect] = useState(null);
|
|
524
|
+
const [highlightedIndex, setHighlightedIndex] = useState(0);
|
|
525
|
+
const optionRefs = useRef([]);
|
|
526
|
+
const highlightSource = useRef("keyboard");
|
|
527
|
+
const selectedOption = options.find((opt) => opt.value === value);
|
|
528
|
+
useEffect(() => {
|
|
529
|
+
if (!open) return;
|
|
530
|
+
highlightSource.current = "keyboard";
|
|
531
|
+
const idx = options.findIndex((opt) => opt.value === value);
|
|
532
|
+
setHighlightedIndex(idx >= 0 ? idx : 0);
|
|
533
|
+
}, [open]);
|
|
534
|
+
useEffect(() => {
|
|
535
|
+
if (!open || highlightSource.current !== "keyboard") return;
|
|
536
|
+
optionRefs.current[highlightedIndex]?.scrollIntoView({ block: "nearest" });
|
|
537
|
+
}, [open, highlightedIndex]);
|
|
538
|
+
useEffect(() => {
|
|
539
|
+
if (!open) return;
|
|
540
|
+
const onKey = (e) => e.key === "Escape" && setOpen(false);
|
|
541
|
+
const onPointer = (e) => {
|
|
542
|
+
const target = e.target;
|
|
543
|
+
if (triggerRef.current?.contains(target)) return;
|
|
544
|
+
if (panelRef.current?.contains(target)) return;
|
|
545
|
+
if (labelRef.current?.contains(target)) return;
|
|
546
|
+
setOpen(false);
|
|
547
|
+
};
|
|
548
|
+
window.addEventListener("keydown", onKey);
|
|
549
|
+
window.addEventListener("pointerdown", onPointer);
|
|
550
|
+
return () => {
|
|
551
|
+
window.removeEventListener("keydown", onKey);
|
|
552
|
+
window.removeEventListener("pointerdown", onPointer);
|
|
553
|
+
};
|
|
554
|
+
}, [open]);
|
|
555
|
+
useLayoutEffect(() => {
|
|
556
|
+
const node = innerRef.current;
|
|
557
|
+
if (!node) return;
|
|
558
|
+
const measure = () => setHeight(node.offsetHeight);
|
|
559
|
+
measure();
|
|
560
|
+
const observer = new ResizeObserver(measure);
|
|
561
|
+
observer.observe(node);
|
|
562
|
+
return () => observer.disconnect();
|
|
563
|
+
}, []);
|
|
564
|
+
useLayoutEffect(() => {
|
|
565
|
+
if (!open) return;
|
|
566
|
+
const trigger = triggerRef.current;
|
|
567
|
+
if (!trigger) return;
|
|
568
|
+
let frame = null;
|
|
569
|
+
const update = () => {
|
|
570
|
+
frame = null;
|
|
571
|
+
const r = trigger.getBoundingClientRect();
|
|
572
|
+
setRect({ left: r.left, width: r.width, top: r.top, bottom: r.bottom });
|
|
573
|
+
const h = innerRef.current?.offsetHeight ?? 0;
|
|
574
|
+
const below = window.innerHeight - r.bottom;
|
|
575
|
+
const above = r.top;
|
|
576
|
+
setPlacement(below < h + 16 && above > below ? "top" : "bottom");
|
|
577
|
+
};
|
|
578
|
+
const scheduleUpdate = (e) => {
|
|
579
|
+
if (e && e.target instanceof Node && panelRef.current?.contains(e.target)) return;
|
|
580
|
+
if (frame !== null) return;
|
|
581
|
+
frame = requestAnimationFrame(update);
|
|
582
|
+
};
|
|
583
|
+
update();
|
|
584
|
+
window.addEventListener("scroll", scheduleUpdate, true);
|
|
585
|
+
window.addEventListener("resize", scheduleUpdate);
|
|
586
|
+
return () => {
|
|
587
|
+
if (frame !== null) cancelAnimationFrame(frame);
|
|
588
|
+
window.removeEventListener("scroll", scheduleUpdate, true);
|
|
589
|
+
window.removeEventListener("resize", scheduleUpdate);
|
|
590
|
+
};
|
|
591
|
+
}, [open]);
|
|
592
|
+
const moveHighlight = (next) => {
|
|
593
|
+
highlightSource.current = "keyboard";
|
|
594
|
+
setHighlightedIndex(Math.min(Math.max(next, 0), options.length - 1));
|
|
595
|
+
};
|
|
596
|
+
const onTriggerKeyDown = (e) => {
|
|
597
|
+
if (!open) {
|
|
598
|
+
if (e.key === "ArrowDown" || e.key === "ArrowUp" || e.key === "Enter" || e.key === " ") {
|
|
599
|
+
e.preventDefault();
|
|
600
|
+
setOpen(true);
|
|
601
|
+
}
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
if (options.length === 0) return;
|
|
605
|
+
switch (e.key) {
|
|
606
|
+
case "ArrowDown":
|
|
607
|
+
e.preventDefault();
|
|
608
|
+
moveHighlight(highlightedIndex + 1);
|
|
609
|
+
break;
|
|
610
|
+
case "ArrowUp":
|
|
611
|
+
e.preventDefault();
|
|
612
|
+
moveHighlight(highlightedIndex - 1);
|
|
613
|
+
break;
|
|
614
|
+
case "Home":
|
|
615
|
+
e.preventDefault();
|
|
616
|
+
moveHighlight(0);
|
|
617
|
+
break;
|
|
618
|
+
case "End":
|
|
619
|
+
e.preventDefault();
|
|
620
|
+
moveHighlight(options.length - 1);
|
|
621
|
+
break;
|
|
622
|
+
case "Enter":
|
|
623
|
+
case " ":
|
|
624
|
+
e.preventDefault();
|
|
625
|
+
onValueChange(options[highlightedIndex].value);
|
|
626
|
+
setOpen(false);
|
|
627
|
+
break;
|
|
628
|
+
case "Tab":
|
|
629
|
+
setOpen(false);
|
|
630
|
+
break;
|
|
631
|
+
default:
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
const selectOption = (next) => {
|
|
636
|
+
onValueChange(next);
|
|
637
|
+
setOpen(false);
|
|
638
|
+
};
|
|
639
|
+
const highlightOption = (index) => {
|
|
640
|
+
highlightSource.current = "pointer";
|
|
641
|
+
setHighlightedIndex(index);
|
|
642
|
+
};
|
|
643
|
+
const isTop = placement === "top";
|
|
644
|
+
return /* @__PURE__ */ jsx9(LazyMotion, { features: domAnimation, children: /* @__PURE__ */ jsxs6("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
645
|
+
label && /* @__PURE__ */ jsx9(
|
|
646
|
+
"label",
|
|
647
|
+
{
|
|
648
|
+
ref: labelRef,
|
|
649
|
+
id: labelId,
|
|
650
|
+
htmlFor: triggerId,
|
|
651
|
+
className: "text-[10px] font-bold uppercase tracking-wider text-ui-subtle",
|
|
652
|
+
children: label
|
|
653
|
+
}
|
|
654
|
+
),
|
|
655
|
+
/* @__PURE__ */ jsx9("div", { className: "relative", children: /* @__PURE__ */ jsx9(
|
|
656
|
+
SelectTrigger,
|
|
657
|
+
{
|
|
658
|
+
triggerRef,
|
|
659
|
+
triggerId,
|
|
660
|
+
listId,
|
|
661
|
+
labelId: label ? labelId : void 0,
|
|
662
|
+
activeDescendantId: open && options[highlightedIndex] ? `${listId}-option-${highlightedIndex}` : void 0,
|
|
663
|
+
open,
|
|
664
|
+
isTop,
|
|
665
|
+
reduce,
|
|
666
|
+
selectedOption,
|
|
667
|
+
placeholder,
|
|
668
|
+
leadingIcon,
|
|
669
|
+
variant,
|
|
670
|
+
className: triggerClassName,
|
|
671
|
+
style: triggerStyle,
|
|
672
|
+
onToggle: () => setOpen((v) => !v),
|
|
673
|
+
onKeyDown: onTriggerKeyDown
|
|
674
|
+
}
|
|
675
|
+
) }),
|
|
676
|
+
createPortal(
|
|
677
|
+
/* @__PURE__ */ jsx9(
|
|
678
|
+
SelectPanel,
|
|
679
|
+
{
|
|
680
|
+
panelRef,
|
|
681
|
+
innerRef,
|
|
682
|
+
optionRefs,
|
|
683
|
+
listId,
|
|
684
|
+
triggerId,
|
|
685
|
+
options,
|
|
686
|
+
value,
|
|
687
|
+
highlightedIndex,
|
|
688
|
+
open,
|
|
689
|
+
isTop,
|
|
690
|
+
reduce,
|
|
691
|
+
height,
|
|
692
|
+
rect,
|
|
693
|
+
onSelect: selectOption,
|
|
694
|
+
onHighlight: highlightOption
|
|
695
|
+
}
|
|
696
|
+
),
|
|
697
|
+
document.body
|
|
698
|
+
)
|
|
699
|
+
] }) });
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// src/components/switch.tsx
|
|
703
|
+
import * as React6 from "react";
|
|
704
|
+
import { Switch as BaseSwitch } from "@base-ui/react/switch";
|
|
705
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
706
|
+
var Switch = React6.forwardRef(
|
|
707
|
+
({ className, onCheckedChange, ...props }, ref) => /* @__PURE__ */ jsx10(
|
|
708
|
+
BaseSwitch.Root,
|
|
709
|
+
{
|
|
710
|
+
ref,
|
|
711
|
+
onCheckedChange: (checked) => onCheckedChange?.(checked),
|
|
712
|
+
className: cn(
|
|
713
|
+
// Squarish track + knob (Cloudflare-dashboard switch shape).
|
|
714
|
+
"relative inline-flex h-4 w-7 shrink-0 cursor-pointer items-center rounded-[5px] p-[2px] transition-colors duration-200",
|
|
715
|
+
// Dark mode: lighter zinc when off (reads against the page), deeper lime when on (knob doesn't blend).
|
|
716
|
+
"bg-ui-fill dark:bg-[oklch(40%_0_0)]",
|
|
717
|
+
"data-checked:bg-ui-brand dark:data-checked:bg-[oklch(64%_0.21_118)]",
|
|
718
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ui-brand/40 focus-visible:ring-offset-1 focus-visible:ring-offset-ui-base",
|
|
719
|
+
"data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
720
|
+
className
|
|
721
|
+
),
|
|
722
|
+
...props,
|
|
723
|
+
children: /* @__PURE__ */ jsx10(BaseSwitch.Thumb, { className: "h-3 w-3 rounded-[3px] bg-white shadow-sm transition-transform duration-200 data-checked:translate-x-3" })
|
|
724
|
+
}
|
|
725
|
+
)
|
|
726
|
+
);
|
|
727
|
+
Switch.displayName = "Switch";
|
|
728
|
+
|
|
729
|
+
// src/components/text.tsx
|
|
730
|
+
import "react";
|
|
731
|
+
import { cva as cva3 } from "class-variance-authority";
|
|
732
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
733
|
+
var textVariants = cva3("", {
|
|
734
|
+
variants: {
|
|
735
|
+
variant: {
|
|
736
|
+
body: "text-ui-default",
|
|
737
|
+
secondary: "text-ui-subtle",
|
|
738
|
+
strong: "text-ui-strong"
|
|
739
|
+
},
|
|
740
|
+
size: {
|
|
741
|
+
sm: "text-sm",
|
|
742
|
+
base: "text-base"
|
|
743
|
+
},
|
|
744
|
+
bold: {
|
|
745
|
+
true: "font-semibold",
|
|
746
|
+
false: ""
|
|
747
|
+
}
|
|
748
|
+
},
|
|
749
|
+
defaultVariants: { variant: "body", size: "base", bold: false }
|
|
750
|
+
});
|
|
751
|
+
function Text({ as: Comp = "p", variant, size, bold, className, ...props }) {
|
|
752
|
+
return /* @__PURE__ */ jsx11(Comp, { className: cn(textVariants({ variant, size, bold }), className), ...props });
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// src/components/skeleton.tsx
|
|
756
|
+
import "react";
|
|
757
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
758
|
+
var Skeleton = ({
|
|
759
|
+
width,
|
|
760
|
+
height,
|
|
761
|
+
borderRadius,
|
|
762
|
+
className = "",
|
|
763
|
+
style
|
|
764
|
+
}) => {
|
|
765
|
+
return /* @__PURE__ */ jsx12(
|
|
766
|
+
"div",
|
|
767
|
+
{
|
|
768
|
+
className: cn("skeleton", className),
|
|
769
|
+
style: {
|
|
770
|
+
width: width ?? "100%",
|
|
771
|
+
height: height ?? "1rem",
|
|
772
|
+
borderRadius: borderRadius ?? void 0,
|
|
773
|
+
...style
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
);
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
// src/components/empty-state.tsx
|
|
780
|
+
import "react";
|
|
781
|
+
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
782
|
+
function EmptyState({ icon, title, description, hints, linkAction, action, className }) {
|
|
783
|
+
return /* @__PURE__ */ jsxs7(
|
|
784
|
+
"div",
|
|
785
|
+
{
|
|
786
|
+
className: cn(
|
|
787
|
+
"flex flex-col items-center justify-center gap-4 px-8 py-16 text-center",
|
|
788
|
+
className
|
|
789
|
+
),
|
|
790
|
+
children: [
|
|
791
|
+
icon && /* @__PURE__ */ jsx13("div", { className: "flex h-14 w-14 items-center justify-center text-muted-foreground/40 [&_svg]:h-9 [&_svg]:w-9 [&_svg]:stroke-[1.35]", children: icon }),
|
|
792
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-1.5", children: [
|
|
793
|
+
/* @__PURE__ */ jsx13("h3", { className: "text-base font-semibold text-foreground", children: title }),
|
|
794
|
+
description && /* @__PURE__ */ jsx13("p", { className: "max-w-sm text-sm text-muted-foreground leading-relaxed", children: description })
|
|
795
|
+
] }),
|
|
796
|
+
hints && hints.length > 0 && /* @__PURE__ */ jsx13("ul", { className: "mt-1 flex flex-col gap-1.5 text-left", children: hints.map((hint) => /* @__PURE__ */ jsxs7("li", { className: "flex items-start gap-2.5 text-sm text-muted-foreground", children: [
|
|
797
|
+
/* @__PURE__ */ jsx13("span", { className: "mt-[7px] h-1.5 w-1.5 shrink-0 rounded-full bg-primary opacity-80" }),
|
|
798
|
+
/* @__PURE__ */ jsx13("span", { children: hint })
|
|
799
|
+
] }, hint)) }),
|
|
800
|
+
linkAction && /* @__PURE__ */ jsx13("div", { className: "mt-3", children: linkAction.href ? /* @__PURE__ */ jsx13(Button, { asChild: true, variant: "outline", size: "sm", children: /* @__PURE__ */ jsx13(
|
|
801
|
+
"a",
|
|
802
|
+
{
|
|
803
|
+
href: linkAction.href,
|
|
804
|
+
target: "_blank",
|
|
805
|
+
rel: "noopener noreferrer",
|
|
806
|
+
children: linkAction.label
|
|
807
|
+
}
|
|
808
|
+
) }) : /* @__PURE__ */ jsx13(
|
|
809
|
+
Button,
|
|
810
|
+
{
|
|
811
|
+
type: "button",
|
|
812
|
+
variant: "outline",
|
|
813
|
+
size: "sm",
|
|
814
|
+
onClick: linkAction.onClick,
|
|
815
|
+
children: linkAction.label
|
|
816
|
+
}
|
|
817
|
+
) }),
|
|
818
|
+
action && /* @__PURE__ */ jsx13(
|
|
819
|
+
Button,
|
|
820
|
+
{
|
|
821
|
+
type: "button",
|
|
822
|
+
variant: "ghost",
|
|
823
|
+
size: "sm",
|
|
824
|
+
onClick: action.onClick,
|
|
825
|
+
className: "mt-2 text-muted-foreground hover:text-foreground",
|
|
826
|
+
children: action.label
|
|
827
|
+
}
|
|
828
|
+
)
|
|
829
|
+
]
|
|
830
|
+
}
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// src/components/section-card.tsx
|
|
835
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
836
|
+
function SectionCard({
|
|
837
|
+
icon,
|
|
838
|
+
title,
|
|
839
|
+
description,
|
|
840
|
+
action,
|
|
841
|
+
children
|
|
842
|
+
}) {
|
|
843
|
+
return /* @__PURE__ */ jsxs8("section", { className: "ui-panel min-w-0 overflow-hidden", children: [
|
|
844
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between gap-4 border-b border-ui-line px-5 py-4", children: [
|
|
845
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 items-center gap-2.5", children: [
|
|
846
|
+
icon && /* @__PURE__ */ jsx14("span", { className: "shrink-0 text-ui-subtle", children: icon }),
|
|
847
|
+
/* @__PURE__ */ jsxs8("div", { className: "min-w-0", children: [
|
|
848
|
+
/* @__PURE__ */ jsx14("h2", { className: "text-[11px] font-semibold uppercase tracking-[0.14em] text-ui-default", children: title }),
|
|
849
|
+
description && /* @__PURE__ */ jsx14("p", { className: "mt-0.5 truncate text-xs text-ui-subtle", children: description })
|
|
850
|
+
] })
|
|
851
|
+
] }),
|
|
852
|
+
action && /* @__PURE__ */ jsx14("div", { className: "shrink-0", children: action })
|
|
853
|
+
] }),
|
|
854
|
+
children
|
|
855
|
+
] });
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// src/components/copy-button.tsx
|
|
859
|
+
import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
860
|
+
import { Check as Check2, Copy } from "lucide-react";
|
|
861
|
+
|
|
862
|
+
// src/lib/constants.ts
|
|
863
|
+
var UI_DURATION_TOOLTIP = 1500;
|
|
864
|
+
|
|
865
|
+
// src/components/copy-button.tsx
|
|
866
|
+
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
867
|
+
function CopyButton({
|
|
868
|
+
value,
|
|
869
|
+
label = "Copy",
|
|
870
|
+
className
|
|
871
|
+
}) {
|
|
872
|
+
const [copied, setCopied] = useState2(false);
|
|
873
|
+
const timer = useRef2(null);
|
|
874
|
+
useEffect2(() => () => {
|
|
875
|
+
if (timer.current !== null) window.clearTimeout(timer.current);
|
|
876
|
+
}, []);
|
|
877
|
+
const copy = async () => {
|
|
878
|
+
try {
|
|
879
|
+
await navigator.clipboard.writeText(value);
|
|
880
|
+
setCopied(true);
|
|
881
|
+
if (timer.current !== null) window.clearTimeout(timer.current);
|
|
882
|
+
timer.current = window.setTimeout(() => setCopied(false), UI_DURATION_TOOLTIP);
|
|
883
|
+
} catch {
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
return /* @__PURE__ */ jsxs9(
|
|
887
|
+
"button",
|
|
888
|
+
{
|
|
889
|
+
type: "button",
|
|
890
|
+
onClick: copy,
|
|
891
|
+
"aria-label": copied ? "Copied" : label,
|
|
892
|
+
className: cn(
|
|
893
|
+
"inline-flex shrink-0 items-center gap-1 rounded border border-ui-line px-1.5 py-0.5",
|
|
894
|
+
"text-[10px] font-medium transition-colors",
|
|
895
|
+
copied ? "text-emerald-500" : "text-ui-subtle hover:text-foreground",
|
|
896
|
+
className
|
|
897
|
+
),
|
|
898
|
+
children: [
|
|
899
|
+
copied ? /* @__PURE__ */ jsx15(Check2, { size: 10 }) : /* @__PURE__ */ jsx15(Copy, { size: 10 }),
|
|
900
|
+
copied ? "Copied" : label
|
|
901
|
+
]
|
|
902
|
+
}
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// src/components/bar-sparkline.tsx
|
|
907
|
+
import { useMemo } from "react";
|
|
908
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
909
|
+
function bucketize(data, bars) {
|
|
910
|
+
const out = Array(bars).fill(0);
|
|
911
|
+
if (data.length === 0) return out;
|
|
912
|
+
if (data.length >= bars) {
|
|
913
|
+
const size = data.length / bars;
|
|
914
|
+
for (let i = 0; i < bars; i++) {
|
|
915
|
+
const start = Math.floor(i * size);
|
|
916
|
+
const end = Math.floor((i + 1) * size);
|
|
917
|
+
out[i] = data.slice(start, end).reduce((sum, v) => sum + v, 0);
|
|
918
|
+
}
|
|
919
|
+
} else {
|
|
920
|
+
for (let i = 0; i < bars; i++) {
|
|
921
|
+
out[i] = data[Math.floor(i * data.length / bars)];
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
return out;
|
|
925
|
+
}
|
|
926
|
+
var BASELINE_PCT = 32;
|
|
927
|
+
function BarSparkline({ data, color, bars = 8, className }) {
|
|
928
|
+
const buckets = useMemo(() => bucketize(data, bars), [data, bars]);
|
|
929
|
+
const max = Math.max(...buckets, 1);
|
|
930
|
+
return /* @__PURE__ */ jsx16("div", { className: cn("flex h-12 items-end justify-end gap-[3px]", className), "aria-hidden": "true", children: buckets.map((value, i) => /* @__PURE__ */ jsx16(
|
|
931
|
+
"div",
|
|
932
|
+
{
|
|
933
|
+
className: "w-[5px] rounded-[2px] transition-[height] duration-500",
|
|
934
|
+
style: {
|
|
935
|
+
height: `${BASELINE_PCT + value / max * (100 - BASELINE_PCT)}%`,
|
|
936
|
+
background: `linear-gradient(to top, ${color}99, ${color})`
|
|
937
|
+
}
|
|
938
|
+
},
|
|
939
|
+
i
|
|
940
|
+
)) });
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
// src/components/github-mark.tsx
|
|
944
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
945
|
+
function GithubMark({ size = 16, className }) {
|
|
946
|
+
return /* @__PURE__ */ jsx17(
|
|
947
|
+
"svg",
|
|
948
|
+
{
|
|
949
|
+
width: size,
|
|
950
|
+
height: size,
|
|
951
|
+
viewBox: "0 0 24 24",
|
|
952
|
+
fill: "currentColor",
|
|
953
|
+
className,
|
|
954
|
+
"aria-hidden": "true",
|
|
955
|
+
children: /* @__PURE__ */ jsx17("path", { d: "M12 .5C5.65.5.5 5.65.5 12c0 5.08 3.29 9.39 7.86 10.91.58.11.79-.25.79-.55 0-.27-.01-1.17-.02-2.12-3.2.7-3.87-1.36-3.87-1.36-.52-1.33-1.28-1.68-1.28-1.68-1.04-.71.08-.7.08-.7 1.15.08 1.76 1.19 1.76 1.19 1.03 1.76 2.69 1.25 3.34.96.1-.75.4-1.25.72-1.54-2.55-.29-5.24-1.28-5.24-5.68 0-1.26.45-2.28 1.19-3.09-.12-.29-.52-1.46.11-3.05 0 0 .97-.31 3.17 1.18a11 11 0 0 1 2.89-.39c.98 0 1.97.13 2.89.39 2.2-1.49 3.16-1.18 3.16-1.18.63 1.59.24 2.76.12 3.05.74.81 1.19 1.83 1.19 3.09 0 4.41-2.69 5.38-5.25 5.67.41.35.77 1.05.77 2.12 0 1.53-.01 2.76-.01 3.14 0 .3.2.66.8.55A11.51 11.51 0 0 0 23.5 12C23.5 5.65 18.35.5 12 .5Z" })
|
|
956
|
+
}
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
// src/components/load-error.tsx
|
|
961
|
+
import { AlertTriangle as AlertTriangle3, RefreshCw } from "lucide-react";
|
|
962
|
+
import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
963
|
+
function LoadError({
|
|
964
|
+
title = "Couldn't load data",
|
|
965
|
+
detail,
|
|
966
|
+
hint = "Check your connection, then try again. If this keeps happening, the server may be unreachable.",
|
|
967
|
+
onRetry,
|
|
968
|
+
retrying,
|
|
969
|
+
className
|
|
970
|
+
}) {
|
|
971
|
+
return /* @__PURE__ */ jsx18(
|
|
972
|
+
"section",
|
|
973
|
+
{
|
|
974
|
+
role: "alert",
|
|
975
|
+
className: cn(
|
|
976
|
+
"ui-font-sans rounded-lg border border-ui-line bg-white p-3.5 dark:border-[oklch(0.27_0_0)] dark:bg-black sm:p-4",
|
|
977
|
+
className
|
|
978
|
+
),
|
|
979
|
+
children: /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between sm:gap-6", children: [
|
|
980
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 items-start gap-3", children: [
|
|
981
|
+
/* @__PURE__ */ jsx18("span", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-red-500/10 text-red-600 dark:text-red-400", children: /* @__PURE__ */ jsx18(AlertTriangle3, { size: 15, strokeWidth: 2 }) }),
|
|
982
|
+
/* @__PURE__ */ jsxs10("div", { className: "min-w-0", children: [
|
|
983
|
+
/* @__PURE__ */ jsx18("h2", { className: "text-[13px] font-medium text-ui-default", children: title }),
|
|
984
|
+
/* @__PURE__ */ jsx18("p", { className: "mt-0.5 text-xs leading-relaxed text-ui-subtle", children: hint }),
|
|
985
|
+
detail && /* @__PURE__ */ jsx18("code", { className: "ui-well ui-font-mono mt-2 inline-block max-w-full truncate rounded-[5px] px-2 py-1 text-[11px] text-ui-subtle", children: detail })
|
|
986
|
+
] })
|
|
987
|
+
] }),
|
|
988
|
+
onRetry && /* @__PURE__ */ jsx18(
|
|
989
|
+
Button,
|
|
990
|
+
{
|
|
991
|
+
variant: "secondary",
|
|
992
|
+
size: "sm",
|
|
993
|
+
onClick: onRetry,
|
|
994
|
+
disabled: retrying,
|
|
995
|
+
icon: /* @__PURE__ */ jsx18(RefreshCw, { size: 13, className: retrying ? "animate-spin" : "" }),
|
|
996
|
+
className: "w-full shrink-0 sm:w-auto",
|
|
997
|
+
children: "Retry"
|
|
998
|
+
}
|
|
999
|
+
)
|
|
1000
|
+
] })
|
|
1001
|
+
}
|
|
1002
|
+
);
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
// src/components/chart-primitives.tsx
|
|
1006
|
+
import { Children } from "react";
|
|
1007
|
+
import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1008
|
+
function CardDots() {
|
|
1009
|
+
return /* @__PURE__ */ jsx19(
|
|
1010
|
+
"div",
|
|
1011
|
+
{
|
|
1012
|
+
"aria-hidden": true,
|
|
1013
|
+
className: "pointer-events-none absolute inset-0 opacity-[0.35]",
|
|
1014
|
+
style: {
|
|
1015
|
+
backgroundImage: "radial-gradient(circle, var(--ui-line) 1px, transparent 1px)",
|
|
1016
|
+
backgroundSize: "18px 18px"
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
);
|
|
1020
|
+
}
|
|
1021
|
+
function GraphShell({
|
|
1022
|
+
title,
|
|
1023
|
+
icon,
|
|
1024
|
+
legend,
|
|
1025
|
+
children,
|
|
1026
|
+
className = ""
|
|
1027
|
+
}) {
|
|
1028
|
+
return /* @__PURE__ */ jsxs11(LayerCard, { className: cn("relative flex flex-col overflow-hidden", className), children: [
|
|
1029
|
+
/* @__PURE__ */ jsx19(CardDots, {}),
|
|
1030
|
+
/* @__PURE__ */ jsxs11("div", { className: "relative flex items-center gap-2 px-4 pt-4 sm:px-5 sm:pt-5", children: [
|
|
1031
|
+
icon && /* @__PURE__ */ jsx19("span", { className: "shrink-0 text-ui-subtle", children: icon }),
|
|
1032
|
+
/* @__PURE__ */ jsx19("h3", { className: "truncate text-[11px] font-semibold uppercase tracking-[0.14em] text-ui-default", children: title })
|
|
1033
|
+
] }),
|
|
1034
|
+
legend && /* @__PURE__ */ jsx19("div", { className: "relative flex flex-wrap items-center gap-x-4 gap-y-1.5 px-4 pt-3 sm:px-5", children: legend }),
|
|
1035
|
+
/* @__PURE__ */ jsx19("div", { className: "relative flex flex-1 flex-col", children })
|
|
1036
|
+
] });
|
|
1037
|
+
}
|
|
1038
|
+
function LegendChip({
|
|
1039
|
+
color,
|
|
1040
|
+
hatched,
|
|
1041
|
+
dashed,
|
|
1042
|
+
label
|
|
1043
|
+
}) {
|
|
1044
|
+
return /* @__PURE__ */ jsxs11("span", { className: "flex items-center gap-1.5 text-xs text-ui-subtle", children: [
|
|
1045
|
+
dashed ? /* @__PURE__ */ jsx19(
|
|
1046
|
+
"span",
|
|
1047
|
+
{
|
|
1048
|
+
className: "h-0 w-3.5 shrink-0 border-t-2 border-dashed",
|
|
1049
|
+
style: { borderColor: color }
|
|
1050
|
+
}
|
|
1051
|
+
) : /* @__PURE__ */ jsx19(
|
|
1052
|
+
"span",
|
|
1053
|
+
{
|
|
1054
|
+
className: "h-2.5 w-2.5 shrink-0 rounded-[3px]",
|
|
1055
|
+
style: hatched ? {
|
|
1056
|
+
backgroundImage: "repeating-linear-gradient(45deg, var(--ui-subtle) 0 1.5px, transparent 1.5px 3.5px)",
|
|
1057
|
+
backgroundColor: "color-mix(in oklch, var(--ui-fill) 60%, transparent)"
|
|
1058
|
+
} : { backgroundColor: color }
|
|
1059
|
+
}
|
|
1060
|
+
),
|
|
1061
|
+
label
|
|
1062
|
+
] });
|
|
1063
|
+
}
|
|
1064
|
+
function ChartDefs({ isDark }) {
|
|
1065
|
+
const hatch = isDark ? "rgba(228,228,231,0.5)" : "rgba(63,63,70,0.4)";
|
|
1066
|
+
const hatchBg = isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.04)";
|
|
1067
|
+
return /* @__PURE__ */ jsxs11("defs", { children: [
|
|
1068
|
+
/* @__PURE__ */ jsxs11("pattern", { id: "hatchGray", patternUnits: "userSpaceOnUse", width: "5", height: "5", patternTransform: "rotate(45)", children: [
|
|
1069
|
+
/* @__PURE__ */ jsx19("rect", { width: "5", height: "5", fill: hatchBg }),
|
|
1070
|
+
/* @__PURE__ */ jsx19("line", { x1: "0", y1: "0", x2: "0", y2: "5", stroke: hatch, strokeWidth: "1.4" })
|
|
1071
|
+
] }),
|
|
1072
|
+
/* @__PURE__ */ jsxs11("linearGradient", { id: "blueBar", x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
1073
|
+
/* @__PURE__ */ jsx19("stop", { offset: "0%", stopColor: "#60a5fa" }),
|
|
1074
|
+
/* @__PURE__ */ jsx19("stop", { offset: "100%", stopColor: "#2563eb" })
|
|
1075
|
+
] }),
|
|
1076
|
+
/* @__PURE__ */ jsxs11("linearGradient", { id: "amberFill", x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
1077
|
+
/* @__PURE__ */ jsx19("stop", { offset: "0%", stopColor: isDark ? "#f59e0b" : "#d97706", stopOpacity: 0.16 }),
|
|
1078
|
+
/* @__PURE__ */ jsx19("stop", { offset: "100%", stopColor: isDark ? "#f59e0b" : "#d97706", stopOpacity: 0.02 })
|
|
1079
|
+
] })
|
|
1080
|
+
] });
|
|
1081
|
+
}
|
|
1082
|
+
var METER_ROW_PX = 20;
|
|
1083
|
+
var METER_GAP_PX = 14;
|
|
1084
|
+
function MeterList({ visible, children }) {
|
|
1085
|
+
const scrolls = Children.count(children) > visible;
|
|
1086
|
+
return /* @__PURE__ */ jsx19("div", { className: "px-4 pb-5 pt-4 sm:px-5 sm:pb-6 sm:pt-5", children: /* @__PURE__ */ jsx19(
|
|
1087
|
+
"div",
|
|
1088
|
+
{
|
|
1089
|
+
className: cn("space-y-3.5", scrolls && "overflow-y-auto pr-3"),
|
|
1090
|
+
style: scrolls ? { maxHeight: visible * METER_ROW_PX + (visible - 1) * METER_GAP_PX } : void 0,
|
|
1091
|
+
children
|
|
1092
|
+
}
|
|
1093
|
+
) });
|
|
1094
|
+
}
|
|
1095
|
+
function TickMeter({
|
|
1096
|
+
label,
|
|
1097
|
+
value,
|
|
1098
|
+
max,
|
|
1099
|
+
color,
|
|
1100
|
+
valueLabel
|
|
1101
|
+
}) {
|
|
1102
|
+
const SEGMENTS = 26;
|
|
1103
|
+
const filled = value > 0 ? Math.max(1, Math.round(value / Math.max(max, 1) * SEGMENTS)) : 0;
|
|
1104
|
+
return /* @__PURE__ */ jsxs11("div", { className: "flex h-5 items-center gap-3", children: [
|
|
1105
|
+
/* @__PURE__ */ jsx19("span", { className: "w-28 shrink-0 truncate text-[13px] font-medium text-ui-default", title: label, children: label }),
|
|
1106
|
+
/* @__PURE__ */ jsx19("div", { className: "flex h-4 flex-1 items-stretch gap-[2.5px]", "aria-hidden": true, children: Array.from({ length: SEGMENTS }).map((_, i) => /* @__PURE__ */ jsx19(
|
|
1107
|
+
"span",
|
|
1108
|
+
{
|
|
1109
|
+
className: "min-w-[2px] flex-1 rounded-[1px]",
|
|
1110
|
+
style: { backgroundColor: i < filled ? color : "var(--ui-fill)" }
|
|
1111
|
+
},
|
|
1112
|
+
i
|
|
1113
|
+
)) }),
|
|
1114
|
+
/* @__PURE__ */ jsx19("span", { className: "ui-font-mono w-14 shrink-0 text-right text-xs tabular-nums text-ui-default", children: valueLabel })
|
|
1115
|
+
] });
|
|
1116
|
+
}
|
|
1117
|
+
export {
|
|
1118
|
+
Alert,
|
|
1119
|
+
Badge,
|
|
1120
|
+
BarSparkline,
|
|
1121
|
+
Button,
|
|
1122
|
+
CardDots,
|
|
1123
|
+
ChartDefs,
|
|
1124
|
+
ConfirmDialog,
|
|
1125
|
+
CopyButton,
|
|
1126
|
+
EmptyState,
|
|
1127
|
+
GithubMark,
|
|
1128
|
+
GraphShell,
|
|
1129
|
+
Input,
|
|
1130
|
+
LayerCard,
|
|
1131
|
+
LegendChip,
|
|
1132
|
+
LinkButton,
|
|
1133
|
+
LoadError,
|
|
1134
|
+
MeterList,
|
|
1135
|
+
SectionCard,
|
|
1136
|
+
Select,
|
|
1137
|
+
Skeleton,
|
|
1138
|
+
Switch,
|
|
1139
|
+
Text,
|
|
1140
|
+
TickMeter,
|
|
1141
|
+
badgeVariants,
|
|
1142
|
+
buttonVariants
|
|
1143
|
+
};
|
|
1144
|
+
//# sourceMappingURL=index.js.map
|