@dynamic-labs-sdk/droplet 1.14.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ui/accordion/accordion.stories.d.ts +19 -0
- package/dist/components/ui/accordion/accordion.stories.d.ts.map +1 -0
- package/dist/components/ui/alert/alert.d.ts +41 -0
- package/dist/components/ui/alert/alert.d.ts.map +1 -0
- package/dist/components/ui/alert/alert.stories.d.ts +26 -0
- package/dist/components/ui/alert/alert.stories.d.ts.map +1 -0
- package/dist/components/ui/alert/index.d.ts +3 -0
- package/dist/components/ui/alert/index.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog/alert-dialog.d.ts +4 -1
- package/dist/components/ui/alert-dialog/alert-dialog.d.ts.map +1 -1
- package/dist/components/ui/badge/badge.d.ts +11 -1
- package/dist/components/ui/badge/badge.d.ts.map +1 -1
- package/dist/components/ui/badge/badge.stories.d.ts +3 -3
- package/dist/components/ui/badge/badge.stories.d.ts.map +1 -1
- package/dist/components/ui/breadcrumb/breadcrumb.d.ts +73 -0
- package/dist/components/ui/breadcrumb/breadcrumb.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb/breadcrumb.stories.d.ts +19 -0
- package/dist/components/ui/breadcrumb/breadcrumb.stories.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb/index.d.ts +3 -0
- package/dist/components/ui/breadcrumb/index.d.ts.map +1 -0
- package/dist/components/ui/button/button.d.ts +7 -3
- package/dist/components/ui/button/button.d.ts.map +1 -1
- package/dist/components/ui/button/button.stories.d.ts +6 -3
- package/dist/components/ui/button/button.stories.d.ts.map +1 -1
- package/dist/components/ui/card/card.d.ts +14 -3
- package/dist/components/ui/card/card.d.ts.map +1 -1
- package/dist/components/ui/card/card.stories.d.ts +8 -2
- package/dist/components/ui/card/card.stories.d.ts.map +1 -1
- package/dist/components/ui/check-icon/check-icon.stories.d.ts +26 -0
- package/dist/components/ui/check-icon/check-icon.stories.d.ts.map +1 -0
- package/dist/components/ui/checkbox/checkbox.stories.d.ts.map +1 -1
- package/dist/components/ui/collapsible/collapsible.d.ts +1 -1
- package/dist/components/ui/collapsible/collapsible.d.ts.map +1 -1
- package/dist/components/ui/collapsible/collapsible.stories.d.ts +1 -0
- package/dist/components/ui/collapsible/collapsible.stories.d.ts.map +1 -1
- package/dist/components/ui/combobox/combobox.d.ts +49 -0
- package/dist/components/ui/combobox/combobox.d.ts.map +1 -0
- package/dist/components/ui/combobox/combobox.stories.d.ts +24 -0
- package/dist/components/ui/combobox/combobox.stories.d.ts.map +1 -0
- package/dist/components/ui/combobox/index.d.ts +3 -0
- package/dist/components/ui/combobox/index.d.ts.map +1 -0
- package/dist/components/ui/command/command.d.ts.map +1 -1
- package/dist/components/ui/command/command.stories.d.ts +31 -0
- package/dist/components/ui/command/command.stories.d.ts.map +1 -0
- package/dist/components/ui/dialog/dialog.d.ts +5 -1
- package/dist/components/ui/dialog/dialog.d.ts.map +1 -1
- package/dist/components/ui/dialog/dialog.stories.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/field/field.d.ts +60 -0
- package/dist/components/ui/field/field.d.ts.map +1 -0
- package/dist/components/ui/field/field.stories.d.ts +40 -0
- package/dist/components/ui/field/field.stories.d.ts.map +1 -0
- package/dist/components/ui/field/index.d.ts +3 -0
- package/dist/components/ui/field/index.d.ts.map +1 -0
- package/dist/components/ui/flush-card-detach/flush-card-detach.stories.d.ts.map +1 -1
- package/dist/components/ui/flush-card-stack/flush-card-stack.d.ts +57 -0
- package/dist/components/ui/flush-card-stack/flush-card-stack.d.ts.map +1 -0
- package/dist/components/ui/flush-card-stack/flush-card-stack.stories.d.ts +24 -0
- package/dist/components/ui/flush-card-stack/flush-card-stack.stories.d.ts.map +1 -0
- package/dist/components/ui/icon/icon.stories.d.ts +510 -0
- package/dist/components/ui/icon/icon.stories.d.ts.map +1 -0
- package/dist/components/ui/input/input.d.ts.map +1 -1
- package/dist/components/ui/kbd/kbd.d.ts +1 -1
- package/dist/components/ui/kbd/kbd.stories.d.ts +15 -0
- package/dist/components/ui/kbd/kbd.stories.d.ts.map +1 -0
- package/dist/components/ui/pagination/index.d.ts +3 -0
- package/dist/components/ui/pagination/index.d.ts.map +1 -0
- package/dist/components/ui/pagination/pagination.d.ts +82 -0
- package/dist/components/ui/pagination/pagination.d.ts.map +1 -0
- package/dist/components/ui/pagination/pagination.stories.d.ts +16 -0
- package/dist/components/ui/pagination/pagination.stories.d.ts.map +1 -0
- package/dist/components/ui/popover/popover.d.ts +1 -1
- package/dist/components/ui/popover/popover.d.ts.map +1 -1
- package/dist/components/ui/progress/progress.d.ts +7 -4
- package/dist/components/ui/progress/progress.d.ts.map +1 -1
- package/dist/components/ui/progress/progress.stories.d.ts +4 -1
- package/dist/components/ui/progress/progress.stories.d.ts.map +1 -1
- package/dist/components/ui/radio-group/index.d.ts +1 -1
- package/dist/components/ui/radio-group/index.d.ts.map +1 -1
- package/dist/components/ui/radio-group/radio-group.d.ts +45 -2
- package/dist/components/ui/radio-group/radio-group.d.ts.map +1 -1
- package/dist/components/ui/radio-group/radio-group.stories.d.ts +19 -0
- package/dist/components/ui/radio-group/radio-group.stories.d.ts.map +1 -1
- package/dist/components/ui/scroll-area/scroll-area.stories.d.ts +15 -0
- package/dist/components/ui/scroll-area/scroll-area.stories.d.ts.map +1 -0
- package/dist/components/ui/search-input/search-input.stories.d.ts +27 -0
- package/dist/components/ui/search-input/search-input.stories.d.ts.map +1 -0
- package/dist/components/ui/select/select.d.ts.map +1 -1
- package/dist/components/ui/skeleton/skeleton.d.ts +1 -1
- package/dist/components/ui/skeleton/skeleton.d.ts.map +1 -1
- package/dist/components/ui/skeleton/skeleton.stories.d.ts +1 -1
- package/dist/components/ui/slider/index.d.ts +3 -0
- package/dist/components/ui/slider/index.d.ts.map +1 -0
- package/dist/components/ui/slider/slider.d.ts +28 -0
- package/dist/components/ui/slider/slider.d.ts.map +1 -0
- package/dist/components/ui/slider/slider.stories.d.ts +40 -0
- package/dist/components/ui/slider/slider.stories.d.ts.map +1 -0
- package/dist/components/ui/sonner/sonner.stories.d.ts +10 -0
- package/dist/components/ui/sonner/sonner.stories.d.ts.map +1 -0
- package/dist/components/ui/spinner/spinner.d.ts +13 -2
- package/dist/components/ui/spinner/spinner.d.ts.map +1 -1
- package/dist/components/ui/spinner/spinner.stories.d.ts +1 -3
- package/dist/components/ui/spinner/spinner.stories.d.ts.map +1 -1
- package/dist/components/ui/stepper/index.d.ts +3 -0
- package/dist/components/ui/stepper/index.d.ts.map +1 -0
- package/dist/components/ui/stepper/stepper.d.ts +36 -0
- package/dist/components/ui/stepper/stepper.d.ts.map +1 -0
- package/dist/components/ui/stepper/stepper.stories.d.ts +21 -0
- package/dist/components/ui/stepper/stepper.stories.d.ts.map +1 -0
- package/dist/components/ui/switch/switch.d.ts.map +1 -1
- package/dist/components/ui/table/table.d.ts +1 -1
- package/dist/components/ui/table/table.d.ts.map +1 -1
- package/dist/components/ui/toggle-group/index.d.ts +3 -0
- package/dist/components/ui/toggle-group/index.d.ts.map +1 -0
- package/dist/components/ui/toggle-group/toggle-group.d.ts +62 -0
- package/dist/components/ui/toggle-group/toggle-group.d.ts.map +1 -0
- package/dist/components/ui/toggle-group/toggle-group.stories.d.ts +20 -0
- package/dist/components/ui/toggle-group/toggle-group.stories.d.ts.map +1 -0
- package/dist/components/ui/tray/renderTrayLayout.d.ts +37 -0
- package/dist/components/ui/tray/renderTrayLayout.d.ts.map +1 -0
- package/dist/components/ui/tray/resolveTrayLayout.d.ts +35 -0
- package/dist/components/ui/tray/resolveTrayLayout.d.ts.map +1 -0
- package/dist/components/ui/well/well-reveal.stories.d.ts +27 -0
- package/dist/components/ui/well/well-reveal.stories.d.ts.map +1 -0
- package/dist/components/ui/well/well.d.ts +2 -2
- package/dist/components/ui/well/well.d.ts.map +1 -1
- package/dist/components/ui/well/well.stories.d.ts +2 -2
- package/dist/index.cjs +1320 -306
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +18 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +1292 -312
- package/dist/index.esm.js.map +1 -1
- package/dist/migration.cjs +1 -1
- package/dist/migration.esm.js +1 -1
- package/dist/{toggle-row-B7XCm0Z-.cjs → toggle-row-BafR1dY7.cjs} +93 -12
- package/dist/toggle-row-BafR1dY7.cjs.map +1 -0
- package/dist/{toggle-row-C-B8HtY0.esm.js → toggle-row-h0h1m_hc.esm.js} +88 -13
- package/dist/toggle-row-h0h1m_hc.esm.js.map +1 -0
- package/package.json +1 -1
- package/src/styles/globals.css +68 -23
- package/dist/toggle-row-B7XCm0Z-.cjs.map +0 -1
- package/dist/toggle-row-C-B8HtY0.esm.js.map +0 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { a as Button, i as Input, n as Switch, o as buttonVariants, r as Label, s as
|
|
2
|
-
import { createContext, forwardRef, useCallback, useContext, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
1
|
+
import { a as Button, c as cn, i as Input, n as Switch, o as buttonVariants, r as Label, s as Spinner, t as ToggleRow } from "./toggle-row-h0h1m_hc.esm.js";
|
|
2
|
+
import { Children, Fragment, cloneElement, createContext, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { AnimatePresence, motion, useAnimation, useReducedMotion } from "motion/react";
|
|
4
4
|
import { HugeiconsIcon } from "@hugeicons/react";
|
|
5
|
-
import { Add01Icon, Alert01Icon, ArrowDown01Icon, ArrowRight01Icon, ArrowUp01Icon, Cancel01Icon, CheckmarkCircle02Icon, Copy01Icon, InformationCircleIcon, Search01Icon, Tick01Icon, WebhookIcon } from "@hugeicons/core-free-icons";
|
|
5
|
+
import { Add01Icon, Alert01Icon, AlertCircleIcon, ArrowDown01Icon, ArrowLeft01Icon, ArrowRight01Icon, ArrowUp01Icon, Cancel01Icon, CheckmarkCircle02Icon, Copy01Icon, InformationCircleIcon, MoreHorizontalIcon, Search01Icon, Tick01Icon, WebhookIcon } from "@hugeicons/core-free-icons";
|
|
6
6
|
import { cva } from "class-variance-authority";
|
|
7
7
|
import { Slot } from "@radix-ui/react-slot";
|
|
8
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
import * as AccordionPrimitive from "@radix-ui/react-accordion";
|
|
10
10
|
import { Content, Header, Item, Root, Trigger } from "@radix-ui/react-accordion";
|
|
11
11
|
import { Action, Cancel, Content as Content$1, Description, Overlay, Portal, Root as Root$1, Title, Trigger as Trigger$1 } from "@radix-ui/react-alert-dialog";
|
|
@@ -15,21 +15,21 @@ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
|
15
15
|
import { Command as Command$1 } from "cmdk";
|
|
16
16
|
import * as SheetPrimitive from "@radix-ui/react-dialog";
|
|
17
17
|
import { Close, Content as Content$2, Description as Description$1, Overlay as Overlay$1, Portal as Portal$1, Root as Root$2, Title as Title$1, Trigger as Trigger$2 } from "@radix-ui/react-dialog";
|
|
18
|
+
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
18
19
|
import { CheckboxItem, Content as Content$3, Group, Item as Item$1, ItemIndicator, Label as Label$1, Portal as Portal$2, RadioGroup as RadioGroup$1, RadioItem, Root as Root$3, Separator as Separator$1, Sub, SubContent, SubTrigger, Trigger as Trigger$3 } from "@radix-ui/react-dropdown-menu";
|
|
19
20
|
import { CheckIcon as CheckIcon$1, ChevronRightIcon as ChevronRightIcon$1, CircleIcon } from "lucide-react";
|
|
20
|
-
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
21
21
|
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
|
|
22
22
|
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
23
23
|
import { Content as Content$4, Group as Group$1, Icon as Icon$1, Item as Item$2, ItemIndicator as ItemIndicator$1, ItemText, Label as Label$2, Portal as Portal$3, Root as Root$4, ScrollDownButton, ScrollUpButton, Separator as Separator$2, Trigger as Trigger$4, Value, Viewport } from "@radix-ui/react-select";
|
|
24
24
|
import { Root as Root$5 } from "@radix-ui/react-separator";
|
|
25
25
|
import { useTheme } from "next-themes";
|
|
26
|
-
import { Toaster as Toaster$1 } from "sonner";
|
|
26
|
+
import { Toaster as Toaster$1, toast } from "sonner";
|
|
27
27
|
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
28
28
|
import { Content as Content$5, Portal as Portal$4, Provider, Root as Root$6, Trigger as Trigger$5 } from "@radix-ui/react-tooltip";
|
|
29
29
|
import Link from "next/link";
|
|
30
30
|
|
|
31
31
|
//#region src/components/unsaved-changes-bar/unsaved-changes-bar.tsx
|
|
32
|
-
const spring$
|
|
32
|
+
const spring$4 = {
|
|
33
33
|
bounce: 0,
|
|
34
34
|
duration: .35,
|
|
35
35
|
type: "spring"
|
|
@@ -67,7 +67,7 @@ const ProgressiveBlur = () => {
|
|
|
67
67
|
});
|
|
68
68
|
};
|
|
69
69
|
const popTransition = {
|
|
70
|
-
...spring$
|
|
70
|
+
...spring$4,
|
|
71
71
|
duration: .25
|
|
72
72
|
};
|
|
73
73
|
const StatusIcon = ({ state }) => {
|
|
@@ -162,11 +162,11 @@ const UnsavedChangesBar = ({ hasChanges, onSave, onReset, suppressed = false })
|
|
|
162
162
|
setBarState("unsaved");
|
|
163
163
|
} else if (!dismissTimer.current) setVisible(false);
|
|
164
164
|
}, [hasChanges]);
|
|
165
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(AnimatePresence, { children: shouldRender && /* @__PURE__ */ jsx(motion.div, {
|
|
165
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(AnimatePresence, { children: shouldRender && /* @__PURE__ */ jsx(motion.div, {
|
|
166
166
|
initial: { opacity: 0 },
|
|
167
167
|
animate: { opacity: 1 },
|
|
168
168
|
exit: { opacity: 0 },
|
|
169
|
-
transition: spring$
|
|
169
|
+
transition: spring$4,
|
|
170
170
|
children: /* @__PURE__ */ jsx(ProgressiveBlur, {})
|
|
171
171
|
}, "blur") }), /* @__PURE__ */ jsx("div", {
|
|
172
172
|
className: "fixed bottom-10 left-1/2 -translate-x-1/2 z-50",
|
|
@@ -186,7 +186,7 @@ const UnsavedChangesBar = ({ hasChanges, onSave, onReset, suppressed = false })
|
|
|
186
186
|
scale: .95,
|
|
187
187
|
y: 20
|
|
188
188
|
},
|
|
189
|
-
transition: spring$
|
|
189
|
+
transition: spring$4,
|
|
190
190
|
style: { willChange: "opacity, transform" },
|
|
191
191
|
className: "flex items-center gap-1.5 rounded-xl bg-zinc-900 dark:bg-[oklch(0.940_0.008_231)] shadow-[0_0_0_1px_rgba(0,0,0,0.08),0_8px_24px_-4px_rgba(0,0,0,0.25),0_20px_50px_-8px_rgba(0,0,0,0.20)] dark:shadow-[0_0_0_1px_rgba(0,0,0,0.08),0_8px_20px_-4px_rgba(0,0,0,0.10),0_20px_50px_-8px_rgba(0,0,0,0.08)] pl-3 pr-1.5 py-1.5",
|
|
192
192
|
children: [
|
|
@@ -298,12 +298,12 @@ const AccordionTrigger = ({ className, children, ...props }) => {
|
|
|
298
298
|
className: "flex",
|
|
299
299
|
children: /* @__PURE__ */ jsxs(AccordionPrimitive.Trigger, {
|
|
300
300
|
"data-slot": "accordion-trigger",
|
|
301
|
-
className: cn("focus-visible:ring-ring/50 flex flex-1 items-center justify-between gap-4 rounded-md px-1 py-4 text-left text-sm font-medium touch-manipulation transition-[color,background-color,opacity] duration-150 ease-out outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 cursor-pointer", className),
|
|
301
|
+
className: cn("focus-visible:ring-ring/50 flex flex-1 items-center justify-between gap-4 rounded-md px-1 py-4 text-left text-sm font-medium touch-manipulation transition-[color,background-color,opacity] duration-150 ease-out motion-reduce:transition-none outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 cursor-pointer", className),
|
|
302
302
|
...props,
|
|
303
303
|
children: [children, /* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
304
304
|
icon: ArrowRight01Icon,
|
|
305
305
|
size: 16,
|
|
306
|
-
className: "text-muted-foreground/60 pointer-events-none shrink-0 transition-transform duration-200 [*[data-state=open]>&]:rotate-90"
|
|
306
|
+
className: "text-muted-foreground/60 pointer-events-none shrink-0 transition-transform duration-200 ease-out motion-reduce:transition-none [*[data-state=open]>&]:rotate-90"
|
|
307
307
|
})]
|
|
308
308
|
})
|
|
309
309
|
});
|
|
@@ -320,6 +320,86 @@ const AccordionContent = ({ className, children, ...props }) => {
|
|
|
320
320
|
});
|
|
321
321
|
};
|
|
322
322
|
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region src/components/ui/tray/resolveTrayLayout.tsx
|
|
325
|
+
/**
|
|
326
|
+
* Resolves the droplet "tray" layout for a container (Dialog/Card/Sheet/AlertDialog).
|
|
327
|
+
*
|
|
328
|
+
* Convention (footer-priority): a container gets exactly one muted tray — the
|
|
329
|
+
* **footer** when actions are present, otherwise the **header** (e.g. Table/CodeBlock).
|
|
330
|
+
* The non-tray slots form the raised white shelf. Pass an explicit `tray` to override.
|
|
331
|
+
*
|
|
332
|
+
* Returns the partitioned pieces so each container can assemble its own shell +
|
|
333
|
+
* shelf markup with the shared `--tray-*` tokens.
|
|
334
|
+
*/
|
|
335
|
+
const resolveTrayLayout = ({ children, isHeader, isFooter, tray = "auto" }) => {
|
|
336
|
+
const elements = Children.toArray(children).filter(isValidElement);
|
|
337
|
+
const header = elements.find(isHeader);
|
|
338
|
+
const footer = elements.find(isFooter);
|
|
339
|
+
let edge;
|
|
340
|
+
if (tray === "auto") if (footer) edge = "footer";
|
|
341
|
+
else if (header) edge = "header";
|
|
342
|
+
else edge = "none";
|
|
343
|
+
else edge = tray;
|
|
344
|
+
let trayChild = void 0;
|
|
345
|
+
if (edge === "footer") trayChild = footer;
|
|
346
|
+
else if (edge === "header") trayChild = header;
|
|
347
|
+
const shelf = Children.toArray(children).filter((child) => {
|
|
348
|
+
if (!isValidElement(child)) return true;
|
|
349
|
+
if (edge === "footer" && isFooter(child)) return false;
|
|
350
|
+
if (edge === "header" && isHeader(child)) return false;
|
|
351
|
+
return true;
|
|
352
|
+
});
|
|
353
|
+
return {
|
|
354
|
+
edge,
|
|
355
|
+
shelf,
|
|
356
|
+
trayChild
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
//#endregion
|
|
361
|
+
//#region src/components/ui/tray/renderTrayLayout.tsx
|
|
362
|
+
/**
|
|
363
|
+
* Builds the shared droplet "tray" markup for a container (Dialog/Card/AlertDialog/…).
|
|
364
|
+
*
|
|
365
|
+
* Centralizes BOTH the convention (via {@link resolveTrayLayout}) and the render —
|
|
366
|
+
* the muted shell classes + the raised white shelf wrapper + the tray-slot
|
|
367
|
+
* placement — so every container (and new ones like Table/CodeBlock) shares one
|
|
368
|
+
* implementation and can't drift. Each container keeps its own root element
|
|
369
|
+
* (portal, animations, `shadow-elevated` vs `shadow-card`) and just merges
|
|
370
|
+
* `shellClassName` + renders `content`.
|
|
371
|
+
*
|
|
372
|
+
* Note: this composes the tray treatment; it does **not** make any container
|
|
373
|
+
* depend on `Card`. Containers stay independent primitives sharing a treatment.
|
|
374
|
+
*/
|
|
375
|
+
const renderTrayLayout = ({ children, isHeader, isFooter, tray = "auto", shelfClassName }) => {
|
|
376
|
+
const { edge, shelf, trayChild } = resolveTrayLayout({
|
|
377
|
+
children,
|
|
378
|
+
isFooter,
|
|
379
|
+
isHeader,
|
|
380
|
+
tray
|
|
381
|
+
});
|
|
382
|
+
if (edge === "none") return {
|
|
383
|
+
content: children,
|
|
384
|
+
edge,
|
|
385
|
+
shellClassName: "bg-card"
|
|
386
|
+
};
|
|
387
|
+
const shellClassName = cn("flex flex-col bg-[var(--tray-chrome)] px-[var(--tray-inset)]", edge === "footer" ? "pt-[var(--tray-inset)]" : "pb-[var(--tray-inset)]");
|
|
388
|
+
return {
|
|
389
|
+
content: /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
390
|
+
edge === "header" && trayChild,
|
|
391
|
+
/* @__PURE__ */ jsx("div", {
|
|
392
|
+
"data-slot": "tray-shelf",
|
|
393
|
+
className: cn("flex flex-1 flex-col overflow-hidden bg-card rounded-[var(--tray-shelf-radius)] shadow-[var(--tray-shelf-shadow)]", shelfClassName),
|
|
394
|
+
children: shelf
|
|
395
|
+
}),
|
|
396
|
+
edge === "footer" && trayChild
|
|
397
|
+
] }),
|
|
398
|
+
edge,
|
|
399
|
+
shellClassName
|
|
400
|
+
};
|
|
401
|
+
};
|
|
402
|
+
|
|
323
403
|
//#endregion
|
|
324
404
|
//#region src/components/ui/alert-dialog/alert-dialog.tsx
|
|
325
405
|
const AlertDialog = Root$1;
|
|
@@ -330,15 +410,25 @@ const AlertDialogOverlay = ({ className, ...props }) => /* @__PURE__ */ jsx(Over
|
|
|
330
410
|
className: cn("data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-[var(--overlay-md)] backdrop-blur-[2px] will-change-[opacity] duration-200 motion-reduce:animate-none", className),
|
|
331
411
|
...props
|
|
332
412
|
});
|
|
333
|
-
const AlertDialogContent = ({ className, size = "default",
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
413
|
+
const AlertDialogContent = ({ className, size = "default", tray = "auto", children, ...props }) => {
|
|
414
|
+
const { edge, shellClassName, content } = renderTrayLayout({
|
|
415
|
+
children,
|
|
416
|
+
isFooter: (el) => el.type === AlertDialogFooter,
|
|
417
|
+
isHeader: (el) => el.type === AlertDialogHeader,
|
|
418
|
+
tray
|
|
419
|
+
});
|
|
420
|
+
return /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [/* @__PURE__ */ jsx(AlertDialogOverlay, {}), /* @__PURE__ */ jsx(Content$1, {
|
|
421
|
+
"data-slot": "alert-dialog-content",
|
|
422
|
+
"data-size": size,
|
|
423
|
+
"data-tray": edge,
|
|
424
|
+
className: cn("overflow-hidden data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-98 data-[state=open]:zoom-in-95 group/alert-dialog-content fixed top-[50%] left-[50%] z-50 w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] rounded-[16px] border-0 shadow-[var(--shadow-elevated)] duration-200 data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-md will-change-[opacity,transform] motion-reduce:animate-none", shellClassName, className),
|
|
425
|
+
...props,
|
|
426
|
+
children: content
|
|
427
|
+
})] });
|
|
428
|
+
};
|
|
339
429
|
const AlertDialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
340
430
|
"data-slot": "alert-dialog-header",
|
|
341
|
-
className: cn("grid grid-rows-[auto_1fr] place-items-center gap-1.5 px-5 py-4
|
|
431
|
+
className: cn("grid grid-rows-[auto_1fr] place-items-center gap-1.5 px-5 py-4 bg-card text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]", className),
|
|
342
432
|
...props
|
|
343
433
|
});
|
|
344
434
|
const AlertDialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
@@ -348,7 +438,7 @@ const AlertDialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("div"
|
|
|
348
438
|
});
|
|
349
439
|
const AlertDialogTitle = ({ className, ...props }) => /* @__PURE__ */ jsx(Title, {
|
|
350
440
|
"data-slot": "alert-dialog-title",
|
|
351
|
-
className: cn("text-
|
|
441
|
+
className: cn("text-[17px] font-semibold text-balance sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2", className),
|
|
352
442
|
...props
|
|
353
443
|
});
|
|
354
444
|
const AlertDialogDescription = ({ className, ...props }) => /* @__PURE__ */ jsx(Description, {
|
|
@@ -356,7 +446,7 @@ const AlertDialogDescription = ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
|
356
446
|
className: cn("text-muted-foreground text-sm text-pretty", className),
|
|
357
447
|
...props
|
|
358
448
|
});
|
|
359
|
-
const AlertDialogAction = ({ className, variant = "
|
|
449
|
+
const AlertDialogAction = ({ className, variant = "destructive", size = "default", ...props }) => /* @__PURE__ */ jsx(Button, {
|
|
360
450
|
variant,
|
|
361
451
|
size,
|
|
362
452
|
asChild: true,
|
|
@@ -401,11 +491,121 @@ const AvatarFallback = ({ className, ...props }) => {
|
|
|
401
491
|
...props
|
|
402
492
|
});
|
|
403
493
|
};
|
|
494
|
+
const AvatarBadge = ({ className, ...props }) => {
|
|
495
|
+
return /* @__PURE__ */ jsx("span", {
|
|
496
|
+
"data-slot": "avatar-badge",
|
|
497
|
+
className: cn("bg-primary text-primary-foreground ring-background absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full ring-2 select-none", "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden", "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2", "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2", className),
|
|
498
|
+
...props
|
|
499
|
+
});
|
|
500
|
+
};
|
|
501
|
+
const AvatarGroup = ({ className, ...props }) => {
|
|
502
|
+
return /* @__PURE__ */ jsx("div", {
|
|
503
|
+
"data-slot": "avatar-group",
|
|
504
|
+
className: cn("*:data-[slot=avatar]:ring-background group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2", className),
|
|
505
|
+
...props
|
|
506
|
+
});
|
|
507
|
+
};
|
|
508
|
+
const AvatarGroupCount = ({ className, ...props }) => {
|
|
509
|
+
return /* @__PURE__ */ jsx("div", {
|
|
510
|
+
"data-slot": "avatar-group-count",
|
|
511
|
+
className: cn("bg-muted text-muted-foreground ring-background relative flex size-8 shrink-0 items-center justify-center rounded-full text-sm ring-2 group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3", className),
|
|
512
|
+
...props
|
|
513
|
+
});
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
//#endregion
|
|
517
|
+
//#region src/components/ui/alert/alert.tsx
|
|
518
|
+
const spring$3 = {
|
|
519
|
+
bounce: 0,
|
|
520
|
+
duration: .35,
|
|
521
|
+
type: "spring"
|
|
522
|
+
};
|
|
523
|
+
const alertVariants = cva("flex gap-3 rounded-xl border px-3.5 py-3 text-sm transition-[color,background-color,border-color] duration-150 motion-reduce:transition-none", {
|
|
524
|
+
defaultVariants: { variant: "neutral" },
|
|
525
|
+
variants: { variant: {
|
|
526
|
+
danger: "bg-[var(--danger-light)] text-[var(--text-danger)] border-[var(--border-danger)]/30",
|
|
527
|
+
info: "bg-[var(--brand-light)] text-[var(--text-link)] border-[var(--border-selected)]/30",
|
|
528
|
+
neutral: "bg-secondary text-secondary-foreground border-[var(--border-default)]",
|
|
529
|
+
success: "bg-[var(--success-light)] text-[var(--text-success)] border-[var(--border-success)]/30",
|
|
530
|
+
warning: "bg-[var(--warning-light)] text-[var(--text-warning)] border-[var(--border-warning)]/30"
|
|
531
|
+
} }
|
|
532
|
+
});
|
|
533
|
+
/** Maps each semantic variant to its Hugeicons icon. */
|
|
534
|
+
const variantIcons = {
|
|
535
|
+
danger: AlertCircleIcon,
|
|
536
|
+
info: InformationCircleIcon,
|
|
537
|
+
neutral: InformationCircleIcon,
|
|
538
|
+
success: CheckmarkCircle02Icon,
|
|
539
|
+
warning: Alert01Icon
|
|
540
|
+
};
|
|
541
|
+
/**
|
|
542
|
+
* An inline semantic callout for contextual feedback.
|
|
543
|
+
*
|
|
544
|
+
* Variants mirror the Badge semantic system: `neutral` (default) | `info` |
|
|
545
|
+
* `success` | `warning` | `danger`. Each variant carries a matching background
|
|
546
|
+
* tint, border, and leading icon drawn from the design-token set.
|
|
547
|
+
*
|
|
548
|
+
* - `danger` and `warning` use `role="alert"` (assertive); others use
|
|
549
|
+
* `role="status"` (polite) to avoid interrupting screen-reader flow.
|
|
550
|
+
* - Use `dismissible` + `onDismiss` for user-closeable callouts.
|
|
551
|
+
*
|
|
552
|
+
* @example
|
|
553
|
+
* <Alert variant="warning" title="Quota almost reached">
|
|
554
|
+
* You have used 90% of your monthly API calls.
|
|
555
|
+
* </Alert>
|
|
556
|
+
*/
|
|
557
|
+
const Alert = ({ variant = "neutral", title, children, dismissible = false, onDismiss, className, ...props }) => {
|
|
558
|
+
const [dismissed, setDismissed] = useState(false);
|
|
559
|
+
const shouldReduceMotion = useReducedMotion();
|
|
560
|
+
if (dismissed) return null;
|
|
561
|
+
const Icon$2 = variantIcons[variant];
|
|
562
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
563
|
+
role: variant === "danger" || variant === "warning" ? "alert" : "status",
|
|
564
|
+
"data-slot": "alert",
|
|
565
|
+
"data-variant": variant,
|
|
566
|
+
className: cn(alertVariants({ variant }), className),
|
|
567
|
+
...props,
|
|
568
|
+
children: [
|
|
569
|
+
/* @__PURE__ */ jsx("span", {
|
|
570
|
+
className: "shrink-0 mt-0.5 opacity-80",
|
|
571
|
+
children: /* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
572
|
+
icon: Icon$2,
|
|
573
|
+
size: 16
|
|
574
|
+
})
|
|
575
|
+
}),
|
|
576
|
+
/* @__PURE__ */ jsxs("div", {
|
|
577
|
+
className: "flex-1 min-w-0",
|
|
578
|
+
children: [title && /* @__PURE__ */ jsx("p", {
|
|
579
|
+
className: "font-medium leading-snug mb-0.5 text-pretty",
|
|
580
|
+
children: title
|
|
581
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
582
|
+
className: "leading-relaxed text-pretty",
|
|
583
|
+
children
|
|
584
|
+
})]
|
|
585
|
+
}),
|
|
586
|
+
dismissible && /* @__PURE__ */ jsx(motion.button, {
|
|
587
|
+
type: "button",
|
|
588
|
+
"aria-label": "Dismiss",
|
|
589
|
+
whileTap: shouldReduceMotion ? void 0 : { scale: .96 },
|
|
590
|
+
transition: spring$3,
|
|
591
|
+
onClick: () => {
|
|
592
|
+
setDismissed(true);
|
|
593
|
+
onDismiss?.();
|
|
594
|
+
},
|
|
595
|
+
className: "relative before:absolute before:-inset-[13px] before:content-[''] shrink-0 mt-0.5 rounded-sm p-0.5 opacity-60 hover:opacity-100 transition-[opacity] duration-150 ease-out motion-reduce:transition-none touch-manipulation cursor-pointer",
|
|
596
|
+
children: /* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
597
|
+
icon: Cancel01Icon,
|
|
598
|
+
size: 14
|
|
599
|
+
})
|
|
600
|
+
})
|
|
601
|
+
]
|
|
602
|
+
});
|
|
603
|
+
};
|
|
404
604
|
|
|
405
605
|
//#endregion
|
|
406
606
|
//#region src/components/ui/badge/badge.tsx
|
|
407
|
-
const badgeVariants = cva("inline-flex items-center justify-center rounded-[5px] border border-transparent px-1.5 py-0.5 text-xs font-medium tabular-nums w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 [&>svg]:[stroke-width:2.5] gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow,background-color] duration-150 overflow-hidden", {
|
|
408
|
-
defaultVariants: { variant: "
|
|
607
|
+
const badgeVariants = cva("inline-flex items-center justify-center rounded-[5px] border border-transparent px-1.5 py-0.5 text-xs font-medium tabular-nums w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 [&>svg]:[stroke-width:2.5] gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow,background-color] duration-150 motion-reduce:transition-none overflow-hidden", {
|
|
608
|
+
defaultVariants: { variant: "neutral" },
|
|
409
609
|
variants: { variant: {
|
|
410
610
|
brand: "bg-[var(--brand-light)] text-[var(--brand-accented)] dark:text-[oklch(0.650_0.085_256)] border-[var(--brand-default)]/20 dark:border-[oklch(0.450_0.070_256)]/30 [a&]:hover:bg-[var(--brand-light)]/80",
|
|
411
611
|
danger: "bg-[var(--danger-light)] text-[var(--text-danger)] border-[var(--border-danger)]/20 [a&]:hover:bg-[var(--danger-light)]/80",
|
|
@@ -413,11 +613,12 @@ const badgeVariants = cva("inline-flex items-center justify-center rounded-[5px]
|
|
|
413
613
|
"dashed-brand": "border-dashed border-[var(--brand-default)] text-[var(--brand-accented)] bg-transparent",
|
|
414
614
|
default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
415
615
|
destructive: "bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
416
|
-
ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
616
|
+
ghost: "hover:bg-accent hover:text-accent-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
417
617
|
"gradient-brand": "bg-gradient-to-r from-[var(--brand-default)] to-[var(--process-default)] text-white border-transparent",
|
|
418
618
|
"gradient-premium": "bg-gradient-to-r from-amber-500 to-orange-400 text-white border-transparent",
|
|
419
619
|
inactive: "bg-[var(--inactive-light)] text-muted-foreground border-[var(--border-inactive)]/40 [a&]:hover:bg-[var(--inactive-light)]/80",
|
|
420
|
-
link: "text-primary underline-offset-4 [a&]:hover:underline",
|
|
620
|
+
link: "text-primary underline-offset-4 hover:underline [a&]:hover:underline",
|
|
621
|
+
neutral: "bg-secondary text-secondary-foreground border-border [a&]:hover:bg-secondary/90",
|
|
421
622
|
outline: "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
422
623
|
process: "bg-[var(--process-light)] text-[var(--text-process)] border-[var(--border-process)]/20 [a&]:hover:bg-[var(--process-light)]/80",
|
|
423
624
|
secondary: "bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
@@ -425,7 +626,17 @@ const badgeVariants = cva("inline-flex items-center justify-center rounded-[5px]
|
|
|
425
626
|
warning: "bg-[var(--warning-light)] text-[var(--text-warning)] border-[var(--border-warning)]/20 [a&]:hover:bg-[var(--warning-light)]/80"
|
|
426
627
|
} }
|
|
427
628
|
});
|
|
428
|
-
|
|
629
|
+
/**
|
|
630
|
+
* A small status/label badge.
|
|
631
|
+
*
|
|
632
|
+
* Semantic variants (preferred): `neutral` (grey — the default), `brand`, `success`,
|
|
633
|
+
* `warning`, `danger`, `process`, `inactive`. Pick the variant by meaning.
|
|
634
|
+
*
|
|
635
|
+
* The shadcn-style variants (`default`, `secondary`, `outline`, `ghost`, `link`,
|
|
636
|
+
* `destructive`, `dashed`, `dashed-brand`, `gradient-brand`, `gradient-premium`) are
|
|
637
|
+
* kept as deprecated aliases for backwards compatibility — prefer the semantic ones.
|
|
638
|
+
*/
|
|
639
|
+
const Badge = ({ className, variant = "neutral", asChild = false, ...props }) => {
|
|
429
640
|
return /* @__PURE__ */ jsx(asChild ? Slot : "span", {
|
|
430
641
|
"data-slot": "badge",
|
|
431
642
|
"data-variant": variant,
|
|
@@ -435,35 +646,154 @@ const Badge = ({ className, variant = "default", asChild = false, ...props }) =>
|
|
|
435
646
|
};
|
|
436
647
|
|
|
437
648
|
//#endregion
|
|
438
|
-
//#region src/components/ui/
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
649
|
+
//#region src/components/ui/breadcrumb/breadcrumb.tsx
|
|
650
|
+
/**
|
|
651
|
+
* Root nav wrapper for a breadcrumb trail.
|
|
652
|
+
* Renders a semantic `<nav>` with `aria-label="breadcrumb"` so assistive
|
|
653
|
+
* technologies identify it as the site breadcrumb landmark.
|
|
654
|
+
*/
|
|
655
|
+
const Breadcrumb = ({ className, ...props }) => /* @__PURE__ */ jsx("nav", {
|
|
656
|
+
"data-slot": "breadcrumb",
|
|
657
|
+
"aria-label": "breadcrumb",
|
|
658
|
+
className: cn("", className),
|
|
442
659
|
...props
|
|
443
660
|
});
|
|
661
|
+
/**
|
|
662
|
+
* Ordered list that holds `BreadcrumbItem` children.
|
|
663
|
+
* Flex-wraps so long trails reflow gracefully on narrow viewports.
|
|
664
|
+
*/
|
|
665
|
+
const BreadcrumbList = ({ className, ...props }) => /* @__PURE__ */ jsx("ol", {
|
|
666
|
+
"data-slot": "breadcrumb-list",
|
|
667
|
+
className: cn("flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5", className),
|
|
668
|
+
...props
|
|
669
|
+
});
|
|
670
|
+
/**
|
|
671
|
+
* A single step in the breadcrumb trail.
|
|
672
|
+
* Renders as an `<li>` with inline-flex layout so icon separators stay
|
|
673
|
+
* vertically centered next to link text.
|
|
674
|
+
*/
|
|
675
|
+
const BreadcrumbItem = ({ className, ...props }) => /* @__PURE__ */ jsx("li", {
|
|
676
|
+
"data-slot": "breadcrumb-item",
|
|
677
|
+
className: cn("inline-flex items-center gap-1.5", className),
|
|
678
|
+
...props
|
|
679
|
+
});
|
|
680
|
+
/**
|
|
681
|
+
* A navigable breadcrumb step.
|
|
682
|
+
*
|
|
683
|
+
* Supports `asChild` (Radix Slot) so consumers can swap in a router `<Link>`:
|
|
684
|
+
* ```tsx
|
|
685
|
+
* <BreadcrumbLink asChild>
|
|
686
|
+
* <Link href='/settings'>Settings</Link>
|
|
687
|
+
* </BreadcrumbLink>
|
|
688
|
+
* ```
|
|
689
|
+
*
|
|
690
|
+
* Inherits `text-muted-foreground` from `BreadcrumbList` and upgrades to
|
|
691
|
+
* `text-foreground` on hover with an `ease-out` transition.
|
|
692
|
+
*/
|
|
693
|
+
const BreadcrumbLink = ({ asChild = false, className, children, ...props }) => {
|
|
694
|
+
return /* @__PURE__ */ jsx(asChild ? Slot : "a", {
|
|
695
|
+
"data-slot": "breadcrumb-link",
|
|
696
|
+
className: cn("transition-colors duration-150 ease-out hover:text-foreground motion-reduce:transition-none", className),
|
|
697
|
+
...props,
|
|
698
|
+
children
|
|
699
|
+
});
|
|
700
|
+
};
|
|
701
|
+
/**
|
|
702
|
+
* The current page indicator — the last (non-navigable) step in the trail.
|
|
703
|
+
*
|
|
704
|
+
* Renders as a `<span>` with `aria-current="page"` so screen readers announce
|
|
705
|
+
* it as the current location. Not styled as a link; uses `text-foreground` to
|
|
706
|
+
* visually distinguish it from the ancestor links.
|
|
707
|
+
*/
|
|
708
|
+
const BreadcrumbPage = ({ className, children, ...props }) => /* @__PURE__ */ jsx("span", {
|
|
709
|
+
"data-slot": "breadcrumb-page",
|
|
710
|
+
"aria-current": "page",
|
|
711
|
+
className: cn("font-normal text-foreground", className),
|
|
712
|
+
...props,
|
|
713
|
+
children
|
|
714
|
+
});
|
|
715
|
+
/**
|
|
716
|
+
* Visual divider between breadcrumb steps.
|
|
717
|
+
*
|
|
718
|
+
* Hidden from assistive technologies via `aria-hidden`.
|
|
719
|
+
* Accepts custom `children` to replace the default chevron with any icon or character.
|
|
720
|
+
*/
|
|
721
|
+
const BreadcrumbSeparator = ({ className, children, ...props }) => /* @__PURE__ */ jsx("li", {
|
|
722
|
+
"data-slot": "breadcrumb-separator",
|
|
723
|
+
"aria-hidden": "true",
|
|
724
|
+
className: cn("[&>svg]:size-3.5", className),
|
|
725
|
+
...props,
|
|
726
|
+
children: children ?? /* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
727
|
+
icon: ArrowRight01Icon,
|
|
728
|
+
size: 14,
|
|
729
|
+
className: "text-muted-foreground/60",
|
|
730
|
+
"aria-hidden": "true"
|
|
731
|
+
})
|
|
732
|
+
});
|
|
733
|
+
/**
|
|
734
|
+
* Collapsed-steps indicator for long breadcrumb trails.
|
|
735
|
+
*
|
|
736
|
+
* Renders a `MoreHorizontal` icon with a screen-reader-only "More" label.
|
|
737
|
+
* Hidden from the accessibility tree via `aria-hidden` — the surrounding
|
|
738
|
+
* visible crumbs provide sufficient context.
|
|
739
|
+
*/
|
|
740
|
+
const BreadcrumbEllipsis = ({ className, ...props }) => /* @__PURE__ */ jsxs("span", {
|
|
741
|
+
"data-slot": "breadcrumb-ellipsis",
|
|
742
|
+
"aria-hidden": "true",
|
|
743
|
+
className: cn("flex size-6 items-center justify-center", className),
|
|
744
|
+
...props,
|
|
745
|
+
children: [/* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
746
|
+
icon: MoreHorizontalIcon,
|
|
747
|
+
size: 14,
|
|
748
|
+
"aria-hidden": "true"
|
|
749
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
750
|
+
className: "sr-only",
|
|
751
|
+
children: "More"
|
|
752
|
+
})]
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
//#endregion
|
|
756
|
+
//#region src/components/ui/card/card.tsx
|
|
757
|
+
const Card = ({ className, interactive = false, selected = false, tray = "none", children, ...props }) => {
|
|
758
|
+
const { edge, shellClassName, content } = renderTrayLayout({
|
|
759
|
+
children,
|
|
760
|
+
isFooter: (el) => el.type === CardFooter,
|
|
761
|
+
isHeader: (el) => el.type === CardHeader,
|
|
762
|
+
tray
|
|
763
|
+
});
|
|
764
|
+
return /* @__PURE__ */ jsx("div", {
|
|
765
|
+
"data-slot": "card",
|
|
766
|
+
"data-selected": selected || void 0,
|
|
767
|
+
"data-tray": edge,
|
|
768
|
+
className: cn("text-card-foreground flex flex-col rounded-[16px] border-0 shadow-[var(--shadow-card)] overflow-hidden", shellClassName, interactive && "cursor-pointer transition-[box-shadow,transform] duration-150 ease-out motion-reduce:transition-none hover:shadow-[var(--shadow-elevated)] active:scale-[0.99]", selected && "shadow-[0_0_0_2px_var(--action),var(--shadow-card)]", className),
|
|
769
|
+
...props,
|
|
770
|
+
children: content
|
|
771
|
+
});
|
|
772
|
+
};
|
|
444
773
|
const CardHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
445
774
|
"data-slot": "card-header",
|
|
446
|
-
className: cn("@container/card-header
|
|
775
|
+
className: cn("@container/card-header relative flex flex-col gap-0.5 px-4 py-3.5 bg-card border-b border-[var(--border-divider)]", className),
|
|
447
776
|
...props
|
|
448
777
|
});
|
|
449
|
-
const CardTitle = ({ className, ...props }) => /* @__PURE__ */ jsx("
|
|
778
|
+
const CardTitle = ({ className, children, ...props }) => /* @__PURE__ */ jsx("h3", {
|
|
450
779
|
"data-slot": "card-title",
|
|
451
|
-
className: cn("text-
|
|
452
|
-
...props
|
|
780
|
+
className: cn("text-base leading-none font-semibold text-balance", className),
|
|
781
|
+
...props,
|
|
782
|
+
children
|
|
453
783
|
});
|
|
454
|
-
const CardDescription = ({ className, ...props }) => /* @__PURE__ */ jsx("
|
|
784
|
+
const CardDescription = ({ className, ...props }) => /* @__PURE__ */ jsx("p", {
|
|
455
785
|
"data-slot": "card-description",
|
|
456
|
-
className: cn("text-muted-foreground text-
|
|
786
|
+
className: cn("text-muted-foreground text-sm text-pretty", className),
|
|
457
787
|
...props
|
|
458
788
|
});
|
|
459
789
|
const CardContent = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
460
790
|
"data-slot": "card-content",
|
|
461
|
-
className: cn("px-
|
|
791
|
+
className: cn("flex-1 px-4 py-3 bg-card", className),
|
|
462
792
|
...props
|
|
463
793
|
});
|
|
464
794
|
const CardFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
465
795
|
"data-slot": "card-footer",
|
|
466
|
-
className: cn("flex items-center px-
|
|
796
|
+
className: cn("mt-auto flex items-center justify-end gap-2 px-4 py-3.5 border-t border-[var(--border-divider)] bg-muted", className),
|
|
467
797
|
...props
|
|
468
798
|
});
|
|
469
799
|
|
|
@@ -494,14 +824,14 @@ const CheckIcon = ({ size = 14, strokeWidth = 3, className, ...props }) => /* @_
|
|
|
494
824
|
const Checkbox = ({ className, ...props }) => {
|
|
495
825
|
return /* @__PURE__ */ jsx(CheckboxPrimitive.Root, {
|
|
496
826
|
"data-slot": "checkbox",
|
|
497
|
-
className: cn("group peer dark:bg-input/30 data-[state=checked]:bg-[var(--action)] data-[state=checked]:text-white dark:data-[state=checked]:bg-[var(--action)] data-[state=indeterminate]:bg-[var(--action)] data-[state=indeterminate]:text-white relative size-4 shrink-0 touch-manipulation rounded-[4px] border-0 shadow-[
|
|
827
|
+
className: cn("group peer dark:bg-input/30 data-[state=checked]:bg-[var(--action)] data-[state=checked]:text-white dark:data-[state=checked]:bg-[var(--action)] data-[state=indeterminate]:bg-[var(--action)] data-[state=indeterminate]:text-white relative size-4 shrink-0 touch-manipulation rounded-[4px] border-0 shadow-[var(--shadow-control)] dark:shadow-[var(--shadow-control)] hover:data-[state=unchecked]:shadow-[var(--shadow-control-hover)] dark:hover:data-[state=unchecked]:shadow-[var(--shadow-control-hover)] data-[state=checked]:shadow-[var(--shadow-control-checked)] dark:data-[state=checked]:shadow-[var(--shadow-control-checked)] data-[state=indeterminate]:shadow-[var(--shadow-control-checked)] dark:data-[state=indeterminate]:shadow-[var(--shadow-control-checked)] transition-[color,box-shadow,background-color] duration-200 ease-out motion-reduce:transition-none outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:shadow-[0_0_0_1px_var(--destructive)] disabled:cursor-not-allowed disabled:opacity-50 cursor-pointer after:absolute after:-inset-[14px] after:content-['']", className),
|
|
498
828
|
...props,
|
|
499
829
|
children: /* @__PURE__ */ jsxs(CheckboxPrimitive.Indicator, {
|
|
500
830
|
"data-slot": "checkbox-indicator",
|
|
501
831
|
className: "relative grid place-content-center text-current size-full",
|
|
502
832
|
forceMount: true,
|
|
503
833
|
children: [/* @__PURE__ */ jsx("svg", {
|
|
504
|
-
className: "size-3.5 absolute inset-0 m-auto transition-[opacity,transform,filter] duration-200 opacity-0 scale-[0.25] blur-[4px] group-data-[state=indeterminate]:opacity-100 group-data-[state=indeterminate]:scale-100 group-data-[state=indeterminate]:blur-none",
|
|
834
|
+
className: "size-3.5 absolute inset-0 m-auto transition-[opacity,transform,filter] duration-200 motion-reduce:transition-none opacity-0 scale-[0.25] blur-[4px] group-data-[state=indeterminate]:opacity-100 group-data-[state=indeterminate]:scale-100 group-data-[state=indeterminate]:blur-none",
|
|
505
835
|
viewBox: "0 0 24 24",
|
|
506
836
|
fill: "none",
|
|
507
837
|
stroke: "currentColor",
|
|
@@ -513,7 +843,7 @@ const Checkbox = ({ className, ...props }) => {
|
|
|
513
843
|
strokeWidth: 3
|
|
514
844
|
})
|
|
515
845
|
}), /* @__PURE__ */ jsx("svg", {
|
|
516
|
-
className: "size-3.5 absolute inset-0 m-auto transition-[opacity,transform,filter] duration-200 opacity-0 scale-[0.25] blur-[4px] group-data-[state=checked]:opacity-100 group-data-[state=checked]:scale-100 group-data-[state=checked]:blur-none",
|
|
846
|
+
className: "size-3.5 absolute inset-0 m-auto transition-[opacity,transform,filter] duration-200 motion-reduce:transition-none opacity-0 scale-[0.25] blur-[4px] group-data-[state=checked]:opacity-100 group-data-[state=checked]:scale-100 group-data-[state=checked]:blur-none",
|
|
517
847
|
viewBox: "0 0 24 24",
|
|
518
848
|
fill: "none",
|
|
519
849
|
stroke: "currentColor",
|
|
@@ -542,8 +872,9 @@ const CollapsibleTrigger = ({ className, ...props }) => {
|
|
|
542
872
|
...props
|
|
543
873
|
});
|
|
544
874
|
};
|
|
545
|
-
const CollapsibleContent = ({ ...props }) => /* @__PURE__ */ jsx(CollapsiblePrimitive.CollapsibleContent, {
|
|
875
|
+
const CollapsibleContent = ({ className, ...props }) => /* @__PURE__ */ jsx(CollapsiblePrimitive.CollapsibleContent, {
|
|
546
876
|
"data-slot": "collapsible-content",
|
|
877
|
+
className: cn("overflow-hidden", "data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up", "motion-reduce:animate-none", className),
|
|
547
878
|
...props
|
|
548
879
|
});
|
|
549
880
|
|
|
@@ -564,22 +895,31 @@ const DialogOverlay = ({ className, ...props }) => /* @__PURE__ */ jsx(Overlay$1
|
|
|
564
895
|
className: cn("data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-[var(--overlay-md)] backdrop-blur-[2px] will-change-[opacity] duration-200 data-[state=open]:ease-out data-[state=closed]:ease-in motion-reduce:animate-none", className),
|
|
565
896
|
...props
|
|
566
897
|
});
|
|
567
|
-
const DialogContent = ({ className, children, ...props }) =>
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
898
|
+
const DialogContent = ({ className, children, tray = "auto", ...props }) => {
|
|
899
|
+
const { edge, shellClassName, content } = renderTrayLayout({
|
|
900
|
+
children,
|
|
901
|
+
isFooter: (el) => el.type === DialogFooter,
|
|
902
|
+
isHeader: (el) => el.type === DialogHeader,
|
|
903
|
+
tray
|
|
904
|
+
});
|
|
905
|
+
return /* @__PURE__ */ jsxs(DialogPortal, {
|
|
906
|
+
"data-slot": "dialog-portal",
|
|
907
|
+
children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsx(Content$2, {
|
|
908
|
+
"data-slot": "dialog-content",
|
|
909
|
+
"data-tray": edge,
|
|
910
|
+
className: cn("overflow-hidden data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-98 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] rounded-[16px] border-0 shadow-[var(--shadow-elevated)] duration-200 data-[state=open]:ease-out data-[state=closed]:ease-in outline-none sm:max-w-md will-change-[opacity,transform] motion-reduce:animate-none", shellClassName, className),
|
|
911
|
+
...props,
|
|
912
|
+
children: content
|
|
913
|
+
})]
|
|
914
|
+
});
|
|
915
|
+
};
|
|
576
916
|
const DialogHeader = ({ className, showCloseButton = true, children, ...props }) => /* @__PURE__ */ jsxs("div", {
|
|
577
917
|
"data-slot": "dialog-header",
|
|
578
|
-
className: cn("relative flex flex-col gap-
|
|
918
|
+
className: cn("relative flex flex-col gap-0.5 px-4 py-4 border-b border-[var(--border-hairline)] bg-card sm:text-left", className),
|
|
579
919
|
...props,
|
|
580
920
|
children: [children, showCloseButton && /* @__PURE__ */ jsxs(Close, {
|
|
581
921
|
"data-slot": "dialog-close",
|
|
582
|
-
className: "absolute top-
|
|
922
|
+
className: "absolute top-1/2 right-2.5 -translate-y-1/2 inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground opacity-70 transition-[opacity,background-color] duration-150 ease-out motion-reduce:transition-none hover:opacity-100 hover:bg-accent focus-visible:ring-2 focus-visible:ring-ring/50 focus:outline-hidden cursor-pointer touch-manipulation before:absolute before:-inset-[8px] before:content-[\"\"]",
|
|
583
923
|
children: [/* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
584
924
|
icon: Cancel01Icon,
|
|
585
925
|
size: 14
|
|
@@ -591,12 +931,12 @@ const DialogHeader = ({ className, showCloseButton = true, children, ...props })
|
|
|
591
931
|
});
|
|
592
932
|
const DialogBody = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
593
933
|
"data-slot": "dialog-body",
|
|
594
|
-
className: cn("px-
|
|
934
|
+
className: cn("px-4 py-[18px] bg-card", className),
|
|
595
935
|
...props
|
|
596
936
|
});
|
|
597
937
|
const DialogFooter = ({ className, showCloseButton = false, children, ...props }) => /* @__PURE__ */ jsxs("div", {
|
|
598
938
|
"data-slot": "dialog-footer",
|
|
599
|
-
className: cn("
|
|
939
|
+
className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end px-3 py-3.5 border-t border-[var(--border-divider)] bg-muted", className),
|
|
600
940
|
...props,
|
|
601
941
|
children: [children, showCloseButton && /* @__PURE__ */ jsx(Close, {
|
|
602
942
|
asChild: true,
|
|
@@ -608,7 +948,7 @@ const DialogFooter = ({ className, showCloseButton = false, children, ...props }
|
|
|
608
948
|
});
|
|
609
949
|
const DialogTitle = ({ className, ...props }) => /* @__PURE__ */ jsx(Title$1, {
|
|
610
950
|
"data-slot": "dialog-title",
|
|
611
|
-
className: cn("text-
|
|
951
|
+
className: cn("text-[17px] leading-none font-semibold text-balance", className),
|
|
612
952
|
...props
|
|
613
953
|
});
|
|
614
954
|
const DialogDescription = ({ className, ...props }) => /* @__PURE__ */ jsx(Description$1, {
|
|
@@ -617,86 +957,6 @@ const DialogDescription = ({ className, ...props }) => /* @__PURE__ */ jsx(Descr
|
|
|
617
957
|
...props
|
|
618
958
|
});
|
|
619
959
|
|
|
620
|
-
//#endregion
|
|
621
|
-
//#region src/components/icons/animated-icon/animated-icon.tsx
|
|
622
|
-
const AnimatedIcon = forwardRef(({ children, className, onMouseEnter, onMouseLeave, size = 28, ...props }, ref) => {
|
|
623
|
-
const controls = useAnimation();
|
|
624
|
-
const isControlledRef = useRef(false);
|
|
625
|
-
useImperativeHandle(ref, () => {
|
|
626
|
-
isControlledRef.current = true;
|
|
627
|
-
return {
|
|
628
|
-
startAnimation: () => controls.start("animate"),
|
|
629
|
-
stopAnimation: () => controls.start("normal")
|
|
630
|
-
};
|
|
631
|
-
});
|
|
632
|
-
const handleMouseEnter = useCallback((e) => {
|
|
633
|
-
if (isControlledRef.current) onMouseEnter?.(e);
|
|
634
|
-
else controls.start("animate").catch(() => void 0);
|
|
635
|
-
}, [controls, onMouseEnter]);
|
|
636
|
-
const handleMouseLeave = useCallback((e) => {
|
|
637
|
-
if (isControlledRef.current) onMouseLeave?.(e);
|
|
638
|
-
else controls.start("normal").catch(() => void 0);
|
|
639
|
-
}, [controls, onMouseLeave]);
|
|
640
|
-
return /* @__PURE__ */ jsx("div", {
|
|
641
|
-
"aria-hidden": "true",
|
|
642
|
-
className: cn("inline-flex items-center justify-center", className),
|
|
643
|
-
onMouseEnter: handleMouseEnter,
|
|
644
|
-
onMouseLeave: handleMouseLeave,
|
|
645
|
-
...props,
|
|
646
|
-
children: children(controls, size)
|
|
647
|
-
});
|
|
648
|
-
});
|
|
649
|
-
AnimatedIcon.displayName = "AnimatedIcon";
|
|
650
|
-
|
|
651
|
-
//#endregion
|
|
652
|
-
//#region src/components/icons/search/search.tsx
|
|
653
|
-
const SearchIcon = forwardRef((props, ref) => /* @__PURE__ */ jsx(AnimatedIcon, {
|
|
654
|
-
ref,
|
|
655
|
-
...props,
|
|
656
|
-
children: (controls, size) => /* @__PURE__ */ jsxs(motion.svg, {
|
|
657
|
-
animate: controls,
|
|
658
|
-
fill: "none",
|
|
659
|
-
height: size,
|
|
660
|
-
stroke: "currentColor",
|
|
661
|
-
strokeLinecap: "round",
|
|
662
|
-
strokeLinejoin: "round",
|
|
663
|
-
strokeWidth: "2",
|
|
664
|
-
transition: {
|
|
665
|
-
bounce: .3,
|
|
666
|
-
duration: 1
|
|
667
|
-
},
|
|
668
|
-
variants: {
|
|
669
|
-
animate: {
|
|
670
|
-
x: [
|
|
671
|
-
0,
|
|
672
|
-
0,
|
|
673
|
-
-3,
|
|
674
|
-
0
|
|
675
|
-
],
|
|
676
|
-
y: [
|
|
677
|
-
0,
|
|
678
|
-
-4,
|
|
679
|
-
0,
|
|
680
|
-
0
|
|
681
|
-
]
|
|
682
|
-
},
|
|
683
|
-
normal: {
|
|
684
|
-
x: 0,
|
|
685
|
-
y: 0
|
|
686
|
-
}
|
|
687
|
-
},
|
|
688
|
-
viewBox: "0 0 24 24",
|
|
689
|
-
width: size,
|
|
690
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
691
|
-
children: [/* @__PURE__ */ jsx("circle", {
|
|
692
|
-
cx: "11",
|
|
693
|
-
cy: "11",
|
|
694
|
-
r: "8"
|
|
695
|
-
}), /* @__PURE__ */ jsx("path", { d: "m21 21-4.3-4.3" })]
|
|
696
|
-
})
|
|
697
|
-
}));
|
|
698
|
-
SearchIcon.displayName = "SearchIcon";
|
|
699
|
-
|
|
700
960
|
//#endregion
|
|
701
961
|
//#region src/components/ui/command/command.tsx
|
|
702
962
|
const Command = ({ className, ...props }) => /* @__PURE__ */ jsx(Command$1, {
|
|
@@ -704,23 +964,27 @@ const Command = ({ className, ...props }) => /* @__PURE__ */ jsx(Command$1, {
|
|
|
704
964
|
className: cn("bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md", className),
|
|
705
965
|
...props
|
|
706
966
|
});
|
|
707
|
-
const CommandDialog = ({ title = "Command Palette", description = "Search for a command to run...", children, className, ...props }) => /* @__PURE__ */
|
|
967
|
+
const CommandDialog = ({ title = "Command Palette", description = "Search for a command to run...", children, className, ...props }) => /* @__PURE__ */ jsx(Dialog, {
|
|
708
968
|
...props,
|
|
709
|
-
children:
|
|
710
|
-
className: "sr-only",
|
|
711
|
-
children: [/* @__PURE__ */ jsx(DialogTitle, { children: title }), /* @__PURE__ */ jsx(DialogDescription, { children: description })]
|
|
712
|
-
}), /* @__PURE__ */ jsx(DialogContent, {
|
|
969
|
+
children: /* @__PURE__ */ jsxs(DialogContent, {
|
|
713
970
|
className: cn("overflow-hidden p-0", className),
|
|
714
|
-
children: /* @__PURE__ */
|
|
971
|
+
children: [/* @__PURE__ */ jsxs(DialogHeader, {
|
|
972
|
+
className: "sr-only",
|
|
973
|
+
children: [/* @__PURE__ */ jsx(DialogTitle, { children: title }), /* @__PURE__ */ jsx(DialogDescription, { children: description })]
|
|
974
|
+
}), /* @__PURE__ */ jsx(Command, {
|
|
715
975
|
className: "[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5",
|
|
716
976
|
children
|
|
717
|
-
})
|
|
718
|
-
})
|
|
977
|
+
})]
|
|
978
|
+
})
|
|
719
979
|
});
|
|
720
980
|
const CommandInput = ({ className, ...props }) => /* @__PURE__ */ jsxs("div", {
|
|
721
981
|
"data-slot": "command-input-wrapper",
|
|
722
982
|
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
723
|
-
children: [/* @__PURE__ */ jsx(
|
|
983
|
+
children: [/* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
984
|
+
icon: Search01Icon,
|
|
985
|
+
size: 16,
|
|
986
|
+
className: "shrink-0 text-muted-foreground/70"
|
|
987
|
+
}), /* @__PURE__ */ jsx(Command$1.Input, {
|
|
724
988
|
"data-slot": "command-input",
|
|
725
989
|
className: cn("placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50", className),
|
|
726
990
|
...props
|
|
@@ -728,7 +992,7 @@ const CommandInput = ({ className, ...props }) => /* @__PURE__ */ jsxs("div", {
|
|
|
728
992
|
});
|
|
729
993
|
const CommandList = ({ className, ...props }) => /* @__PURE__ */ jsx(Command$1.List, {
|
|
730
994
|
"data-slot": "command-list",
|
|
731
|
-
className: cn("max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto", className),
|
|
995
|
+
className: cn("max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto p-1", className),
|
|
732
996
|
...props
|
|
733
997
|
});
|
|
734
998
|
const CommandEmpty = ({ ...props }) => /* @__PURE__ */ jsx(Command$1.Empty, {
|
|
@@ -738,7 +1002,7 @@ const CommandEmpty = ({ ...props }) => /* @__PURE__ */ jsx(Command$1.Empty, {
|
|
|
738
1002
|
});
|
|
739
1003
|
const CommandGroup = ({ className, ...props }) => /* @__PURE__ */ jsx(Command$1.Group, {
|
|
740
1004
|
"data-slot": "command-group",
|
|
741
|
-
className: cn("text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden
|
|
1005
|
+
className: cn("text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium", className),
|
|
742
1006
|
...props
|
|
743
1007
|
});
|
|
744
1008
|
const CommandSeparator = ({ className, ...props }) => /* @__PURE__ */ jsx(Command$1.Separator, {
|
|
@@ -757,6 +1021,95 @@ const CommandShortcut = ({ className, ...props }) => /* @__PURE__ */ jsx("span",
|
|
|
757
1021
|
...props
|
|
758
1022
|
});
|
|
759
1023
|
|
|
1024
|
+
//#endregion
|
|
1025
|
+
//#region src/components/ui/popover/popover.tsx
|
|
1026
|
+
const Popover = ({ ...props }) => /* @__PURE__ */ jsx(PopoverPrimitive.Root, {
|
|
1027
|
+
"data-slot": "popover",
|
|
1028
|
+
...props
|
|
1029
|
+
});
|
|
1030
|
+
const PopoverTrigger = ({ ...props }) => /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, {
|
|
1031
|
+
"data-slot": "popover-trigger",
|
|
1032
|
+
...props
|
|
1033
|
+
});
|
|
1034
|
+
const PopoverContent = ({ className, align = "center", sideOffset = 8, ...props }) => {
|
|
1035
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(PopoverPrimitive.Content, {
|
|
1036
|
+
"data-slot": "popover-content",
|
|
1037
|
+
align,
|
|
1038
|
+
sideOffset,
|
|
1039
|
+
className: cn("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-98 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-xl border-0 p-4 shadow-[var(--shadow-elevated)] outline-hidden will-change-[opacity,transform] motion-reduce:animate-none", className),
|
|
1040
|
+
...props
|
|
1041
|
+
}) });
|
|
1042
|
+
};
|
|
1043
|
+
const PopoverAnchor = ({ ...props }) => /* @__PURE__ */ jsx(PopoverPrimitive.Anchor, {
|
|
1044
|
+
"data-slot": "popover-anchor",
|
|
1045
|
+
...props
|
|
1046
|
+
});
|
|
1047
|
+
|
|
1048
|
+
//#endregion
|
|
1049
|
+
//#region src/components/ui/combobox/combobox.tsx
|
|
1050
|
+
/**
|
|
1051
|
+
* Searchable single-select Combobox.
|
|
1052
|
+
*
|
|
1053
|
+
* Composes `Popover`, `Button`, and `Command` from the droplet design system.
|
|
1054
|
+
* The trigger is a full-width `outline` Button with a rotating chevron that
|
|
1055
|
+
* signals open/closed state. Selecting an item closes the popover, fires
|
|
1056
|
+
* `onValueChange`, and shows a check mark next to the active selection.
|
|
1057
|
+
*
|
|
1058
|
+
* @example
|
|
1059
|
+
* ```tsx
|
|
1060
|
+
* const [chain, setChain] = useState('');
|
|
1061
|
+
* <Combobox
|
|
1062
|
+
* options={[{ value: 'eth', label: 'Ethereum' }, { value: 'sol', label: 'Solana' }]}
|
|
1063
|
+
* value={chain}
|
|
1064
|
+
* onValueChange={setChain}
|
|
1065
|
+
* placeholder="Select a chain"
|
|
1066
|
+
* />
|
|
1067
|
+
* ```
|
|
1068
|
+
*/
|
|
1069
|
+
const Combobox = ({ options, value, onValueChange, placeholder = "Select…", searchPlaceholder = "Search…", emptyText = "No results.", className, disabled = false }) => {
|
|
1070
|
+
const [open, setOpen] = useState(false);
|
|
1071
|
+
const selectedLabel = options.find((opt) => opt.value === value)?.label;
|
|
1072
|
+
const handleSelect = (selectedValue) => {
|
|
1073
|
+
onValueChange(selectedValue);
|
|
1074
|
+
setOpen(false);
|
|
1075
|
+
};
|
|
1076
|
+
return /* @__PURE__ */ jsxs(Popover, {
|
|
1077
|
+
open,
|
|
1078
|
+
onOpenChange: setOpen,
|
|
1079
|
+
children: [/* @__PURE__ */ jsx(PopoverTrigger, {
|
|
1080
|
+
asChild: true,
|
|
1081
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
1082
|
+
type: "button",
|
|
1083
|
+
"data-slot": "combobox-trigger",
|
|
1084
|
+
"aria-expanded": open,
|
|
1085
|
+
"aria-haspopup": "listbox",
|
|
1086
|
+
disabled,
|
|
1087
|
+
className: cn("flex h-8 w-full touch-manipulation items-center justify-between gap-1.5 rounded-md border-0 bg-background px-3 text-[13px] whitespace-nowrap dark:bg-input/30", "shadow-[var(--shadow-input)] hover:shadow-[var(--shadow-input-hover)]", "transition-[color,box-shadow] duration-100 ease-out motion-reduce:transition-none", "outline-none focus-visible:shadow-[0_0_0_1px_var(--ring),0_0_0_4px_var(--ring-halo)]", "cursor-pointer disabled:cursor-not-allowed disabled:opacity-50", className),
|
|
1088
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1089
|
+
className: cn("truncate", !selectedLabel && "text-muted-foreground/60"),
|
|
1090
|
+
children: selectedLabel ?? placeholder
|
|
1091
|
+
}), /* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1092
|
+
icon: ArrowDown01Icon,
|
|
1093
|
+
size: 16,
|
|
1094
|
+
className: cn("shrink-0 opacity-50 transition-transform duration-150 ease-out motion-reduce:transition-none", open && "rotate-180")
|
|
1095
|
+
})]
|
|
1096
|
+
})
|
|
1097
|
+
}), /* @__PURE__ */ jsx(PopoverContent, {
|
|
1098
|
+
className: "w-[var(--radix-popover-trigger-width)] p-0",
|
|
1099
|
+
align: "start",
|
|
1100
|
+
sideOffset: 4,
|
|
1101
|
+
children: /* @__PURE__ */ jsxs(Command, {
|
|
1102
|
+
className: "rounded-[inherit]",
|
|
1103
|
+
children: [/* @__PURE__ */ jsx(CommandInput, { placeholder: searchPlaceholder }), /* @__PURE__ */ jsxs(CommandList, { children: [/* @__PURE__ */ jsx(CommandEmpty, { children: emptyText }), options.map((opt) => /* @__PURE__ */ jsxs(CommandItem, {
|
|
1104
|
+
value: opt.value,
|
|
1105
|
+
onSelect: handleSelect,
|
|
1106
|
+
children: [/* @__PURE__ */ jsx(CheckIcon, { className: cn("shrink-0", value === opt.value ? "opacity-100" : "opacity-0") }), opt.label]
|
|
1107
|
+
}, opt.value))] })]
|
|
1108
|
+
})
|
|
1109
|
+
})]
|
|
1110
|
+
});
|
|
1111
|
+
};
|
|
1112
|
+
|
|
760
1113
|
//#endregion
|
|
761
1114
|
//#region src/components/ui/dropdown-menu/dropdown-menu.tsx
|
|
762
1115
|
const DropdownMenu = Root$3;
|
|
@@ -766,7 +1119,7 @@ const DropdownMenuSub = Sub;
|
|
|
766
1119
|
const DropdownMenuContent = forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(Portal$2, { children: /* @__PURE__ */ jsx(Content$3, {
|
|
767
1120
|
ref,
|
|
768
1121
|
sideOffset,
|
|
769
|
-
className: cn("z-50 min-w-32 overflow-hidden rounded-md bg-popover p-1 text-popover-foreground shadow-
|
|
1122
|
+
className: cn("z-50 min-w-32 overflow-hidden rounded-md bg-popover p-1 text-popover-foreground shadow-[var(--shadow-elevated)] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 motion-reduce:animate-none", className),
|
|
770
1123
|
...props
|
|
771
1124
|
}) }));
|
|
772
1125
|
DropdownMenuContent.displayName = Content$3.displayName;
|
|
@@ -783,7 +1136,7 @@ const DropdownMenuCheckboxItem = forwardRef(({ className, children, checked, ...
|
|
|
783
1136
|
...props,
|
|
784
1137
|
children: [/* @__PURE__ */ jsx("span", {
|
|
785
1138
|
className: "absolute left-2 flex size-3.5 items-center justify-center",
|
|
786
|
-
children: /* @__PURE__ */ jsx(ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon$1, { className: "size-
|
|
1139
|
+
children: /* @__PURE__ */ jsx(ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon$1, { className: "size-3.5" }) })
|
|
787
1140
|
}), children]
|
|
788
1141
|
}));
|
|
789
1142
|
DropdownMenuCheckboxItem.displayName = CheckboxItem.displayName;
|
|
@@ -800,6 +1153,7 @@ const DropdownMenuRadioItem = forwardRef(({ className, children, ...props }, ref
|
|
|
800
1153
|
DropdownMenuRadioItem.displayName = RadioItem.displayName;
|
|
801
1154
|
const DropdownMenuLabel = forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(Label$1, {
|
|
802
1155
|
ref,
|
|
1156
|
+
"data-slot": "dropdown-menu-label",
|
|
803
1157
|
className: cn("px-2 py-1.5 text-sm font-medium", inset && "pl-8", className),
|
|
804
1158
|
...props
|
|
805
1159
|
}));
|
|
@@ -811,6 +1165,7 @@ const DropdownMenuSeparator = forwardRef(({ className, ...props }, ref) => /* @_
|
|
|
811
1165
|
}));
|
|
812
1166
|
DropdownMenuSeparator.displayName = Separator$1.displayName;
|
|
813
1167
|
const DropdownMenuShortcut = ({ className, ...props }) => /* @__PURE__ */ jsx("span", {
|
|
1168
|
+
"aria-hidden": "true",
|
|
814
1169
|
className: cn("ml-auto text-xs tracking-widest text-muted-foreground", className),
|
|
815
1170
|
...props
|
|
816
1171
|
});
|
|
@@ -824,11 +1179,141 @@ const DropdownMenuSubTrigger = forwardRef(({ className, inset, children, ...prop
|
|
|
824
1179
|
DropdownMenuSubTrigger.displayName = SubTrigger.displayName;
|
|
825
1180
|
const DropdownMenuSubContent = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SubContent, {
|
|
826
1181
|
ref,
|
|
827
|
-
className: cn("z-50 min-w-32 overflow-hidden rounded-md bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", className),
|
|
1182
|
+
className: cn("z-50 min-w-32 overflow-hidden rounded-md bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 motion-reduce:animate-none", className),
|
|
828
1183
|
...props
|
|
829
1184
|
}));
|
|
830
1185
|
DropdownMenuSubContent.displayName = SubContent.displayName;
|
|
831
1186
|
|
|
1187
|
+
//#endregion
|
|
1188
|
+
//#region src/components/ui/well/well.tsx
|
|
1189
|
+
const wellVariants = cva("rounded-xl", {
|
|
1190
|
+
defaultVariants: {
|
|
1191
|
+
gap: "sm",
|
|
1192
|
+
spacing: "default",
|
|
1193
|
+
variant: "inset"
|
|
1194
|
+
},
|
|
1195
|
+
variants: {
|
|
1196
|
+
gap: {
|
|
1197
|
+
default: "space-y-4",
|
|
1198
|
+
lg: "space-y-5",
|
|
1199
|
+
none: "",
|
|
1200
|
+
sm: "space-y-3"
|
|
1201
|
+
},
|
|
1202
|
+
spacing: {
|
|
1203
|
+
default: "p-4",
|
|
1204
|
+
lg: "p-5",
|
|
1205
|
+
none: "p-0",
|
|
1206
|
+
sm: "p-3"
|
|
1207
|
+
},
|
|
1208
|
+
variant: {
|
|
1209
|
+
default: "bg-muted/50",
|
|
1210
|
+
inset: "bg-muted/50 border border-border",
|
|
1211
|
+
outline: "border border-border"
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
});
|
|
1215
|
+
const Well = ({ className, gap, spacing, variant, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
1216
|
+
"data-slot": "well",
|
|
1217
|
+
"data-spacing": spacing ?? "default",
|
|
1218
|
+
className: cn(wellVariants({
|
|
1219
|
+
gap,
|
|
1220
|
+
spacing,
|
|
1221
|
+
variant
|
|
1222
|
+
}), className),
|
|
1223
|
+
...props
|
|
1224
|
+
});
|
|
1225
|
+
const WellReveal = ({ children, className, open }) => /* @__PURE__ */ jsx("div", {
|
|
1226
|
+
className: "grid transition-[grid-template-rows] duration-[220ms] ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:transition-none",
|
|
1227
|
+
style: { gridTemplateRows: open ? "1fr" : "0fr" },
|
|
1228
|
+
"aria-hidden": !open,
|
|
1229
|
+
inert: !open,
|
|
1230
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1231
|
+
className: "overflow-hidden",
|
|
1232
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1233
|
+
className: cn("px-0.5 pb-0.5 [&>[data-slot=well]:not([data-spacing=none])]:p-[22px]", className),
|
|
1234
|
+
children
|
|
1235
|
+
})
|
|
1236
|
+
})
|
|
1237
|
+
});
|
|
1238
|
+
|
|
1239
|
+
//#endregion
|
|
1240
|
+
//#region src/components/ui/flush-card-stack/flush-card-stack.tsx
|
|
1241
|
+
const DETACH_GAP_PX = 12;
|
|
1242
|
+
/**
|
|
1243
|
+
* Declarative item marker for {@link FlushCardStack}. Renders nothing on its own;
|
|
1244
|
+
* the stack consumes its props.
|
|
1245
|
+
*/
|
|
1246
|
+
const FlushCardStackItem = (_props) => null;
|
|
1247
|
+
const isStackItem = (child) => isValidElement(child) && child.type === FlushCardStackItem;
|
|
1248
|
+
const hasReveal = (item) => Boolean(item.props.children);
|
|
1249
|
+
const detaches = (item) => hasReveal(item) && Boolean(item.props.open);
|
|
1250
|
+
/**
|
|
1251
|
+
* A vertical stack of settings cards that fuse into one block by default and
|
|
1252
|
+
* detach with a spring gap when an item's reveal is opened.
|
|
1253
|
+
*
|
|
1254
|
+
* Composed from {@link Card} + {@link WellReveal} (+ `motion`); it encapsulates
|
|
1255
|
+
* the `-mt-px` / `rounded-[16px]` / gap math so consumers pass only per-item
|
|
1256
|
+
* `open` + content:
|
|
1257
|
+
*
|
|
1258
|
+
* ```tsx
|
|
1259
|
+
* <FlushCardStack>
|
|
1260
|
+
* <FlushCardStack.Item open={emailOn} header={<ToggleRow … />}>
|
|
1261
|
+
* <Well gap='sm'>{/* checkbox rows *\/}</Well>
|
|
1262
|
+
* </FlushCardStack.Item>
|
|
1263
|
+
* <FlushCardStack.Item header={<ToggleRow … />} />
|
|
1264
|
+
* </FlushCardStack>
|
|
1265
|
+
* ```
|
|
1266
|
+
*
|
|
1267
|
+
* Rule: a seam (12px spring gap + facing edges rounding to `rounded-[16px]`)
|
|
1268
|
+
* opens between two cards when EITHER side is an open reveal item — so an open
|
|
1269
|
+
* middle item floats free on both sides, while an open first/last item produces a
|
|
1270
|
+
* single inner split. Items with no reveal, or closed reveals, always fuse.
|
|
1271
|
+
*/
|
|
1272
|
+
const FlushCardStack = ({ children, className }) => {
|
|
1273
|
+
const prefersReducedMotion = useReducedMotion();
|
|
1274
|
+
const items = Children.toArray(children).filter(isStackItem);
|
|
1275
|
+
const lastIndex = items.length - 1;
|
|
1276
|
+
const gapTransition = prefersReducedMotion ? { duration: 0 } : {
|
|
1277
|
+
bounce: 0,
|
|
1278
|
+
duration: .4,
|
|
1279
|
+
type: "spring"
|
|
1280
|
+
};
|
|
1281
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1282
|
+
"data-slot": "flush-card-stack",
|
|
1283
|
+
className,
|
|
1284
|
+
children: items.map((item, index) => {
|
|
1285
|
+
const prev = items[index - 1];
|
|
1286
|
+
const next = items[index + 1];
|
|
1287
|
+
const isFirst = index === 0;
|
|
1288
|
+
const isLast = index === lastIndex;
|
|
1289
|
+
const splitAbove = !isFirst && (detaches(item) || detaches(prev));
|
|
1290
|
+
const splitBelow = !isLast && (detaches(item) || detaches(next));
|
|
1291
|
+
const roundTop = isFirst || splitAbove;
|
|
1292
|
+
const roundBottom = isLast || splitBelow;
|
|
1293
|
+
const gapPossible = !isLast && (hasReveal(item) || hasReveal(next));
|
|
1294
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Card, {
|
|
1295
|
+
"data-detached": detaches(item) || void 0,
|
|
1296
|
+
className: cn("gap-0 py-0 transition-[border-radius] duration-300", !roundTop && "rounded-t-none -mt-px", !roundBottom && "rounded-b-none", item.props.className),
|
|
1297
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1298
|
+
className: "px-5 py-4",
|
|
1299
|
+
children: item.props.header
|
|
1300
|
+
}), hasReveal(item) && /* @__PURE__ */ jsx(WellReveal, {
|
|
1301
|
+
open: Boolean(item.props.open),
|
|
1302
|
+
children: item.props.children
|
|
1303
|
+
})]
|
|
1304
|
+
}), gapPossible && /* @__PURE__ */ jsx(motion.div, {
|
|
1305
|
+
"aria-hidden": true,
|
|
1306
|
+
"data-slot": "flush-card-gap",
|
|
1307
|
+
"data-open": splitBelow || void 0,
|
|
1308
|
+
initial: false,
|
|
1309
|
+
animate: { height: splitBelow ? DETACH_GAP_PX : 0 },
|
|
1310
|
+
transition: gapTransition
|
|
1311
|
+
})] }, item.key ?? index);
|
|
1312
|
+
})
|
|
1313
|
+
});
|
|
1314
|
+
};
|
|
1315
|
+
FlushCardStack.Item = FlushCardStackItem;
|
|
1316
|
+
|
|
832
1317
|
//#endregion
|
|
833
1318
|
//#region src/components/icon-config/icon-config.tsx
|
|
834
1319
|
const IconConfigContext = createContext({
|
|
@@ -872,6 +1357,76 @@ const Icon = (props) => {
|
|
|
872
1357
|
});
|
|
873
1358
|
};
|
|
874
1359
|
|
|
1360
|
+
//#endregion
|
|
1361
|
+
//#region src/components/ui/field/field.tsx
|
|
1362
|
+
/**
|
|
1363
|
+
* A generic labeled form-field wrapper.
|
|
1364
|
+
*
|
|
1365
|
+
* Wires a `<Label>`, an arbitrary form control, an optional description, and
|
|
1366
|
+
* an error message together with the correct `id`/`htmlFor`/`aria-describedby`
|
|
1367
|
+
* associations so callers don't have to hand-assemble these.
|
|
1368
|
+
*
|
|
1369
|
+
* When there is exactly one child element, `Field` uses `cloneElement` to
|
|
1370
|
+
* inject:
|
|
1371
|
+
* - `id` — links the label's `htmlFor` to the control
|
|
1372
|
+
* - `aria-describedby` — references the description and/or error paragraph ids
|
|
1373
|
+
* - `aria-invalid` — `true` when `error` is present
|
|
1374
|
+
*
|
|
1375
|
+
* @example
|
|
1376
|
+
* ```tsx
|
|
1377
|
+
* <Field label="Email" description="We'll never share your email." required>
|
|
1378
|
+
* <Input type="email" />
|
|
1379
|
+
* </Field>
|
|
1380
|
+
*
|
|
1381
|
+
* <Field label="Email" error="Enter a valid email address.">
|
|
1382
|
+
* <Input type="email" />
|
|
1383
|
+
* </Field>
|
|
1384
|
+
* ```
|
|
1385
|
+
*/
|
|
1386
|
+
const Field = ({ label, description, error, required, htmlFor, children, className }) => {
|
|
1387
|
+
const generatedId = useId();
|
|
1388
|
+
const controlId = htmlFor ?? generatedId;
|
|
1389
|
+
const descriptionId = `${controlId}-description`;
|
|
1390
|
+
const errorId = `${controlId}-error`;
|
|
1391
|
+
const describedByParts = [];
|
|
1392
|
+
if (description) describedByParts.push(descriptionId);
|
|
1393
|
+
if (error) describedByParts.push(errorId);
|
|
1394
|
+
const ariaDescribedBy = describedByParts.length > 0 ? describedByParts.join(" ") : void 0;
|
|
1395
|
+
const childArray = Children.toArray(children);
|
|
1396
|
+
const singleChild = childArray.length === 1 && isValidElement(childArray[0]) ? childArray[0] : null;
|
|
1397
|
+
const enrichedChild = singleChild ? cloneElement(singleChild, {
|
|
1398
|
+
"aria-describedby": singleChild.props["aria-describedby"] ?? ariaDescribedBy,
|
|
1399
|
+
id: singleChild.props.id ?? controlId,
|
|
1400
|
+
...error ? { "aria-invalid": true } : {}
|
|
1401
|
+
}) : null;
|
|
1402
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1403
|
+
className: cn("grid gap-1.5", className),
|
|
1404
|
+
children: [
|
|
1405
|
+
label && /* @__PURE__ */ jsxs(Label, {
|
|
1406
|
+
htmlFor: controlId,
|
|
1407
|
+
children: [label, required && /* @__PURE__ */ jsx("span", {
|
|
1408
|
+
"aria-hidden": true,
|
|
1409
|
+
className: "ml-0.5 text-[var(--text-danger)]",
|
|
1410
|
+
children: "*"
|
|
1411
|
+
})]
|
|
1412
|
+
}),
|
|
1413
|
+
enrichedChild ?? children,
|
|
1414
|
+
description && /* @__PURE__ */ jsx("p", {
|
|
1415
|
+
id: descriptionId,
|
|
1416
|
+
className: "text-sm text-muted-foreground",
|
|
1417
|
+
children: description
|
|
1418
|
+
}),
|
|
1419
|
+
error && /* @__PURE__ */ jsx("p", {
|
|
1420
|
+
id: errorId,
|
|
1421
|
+
role: "alert",
|
|
1422
|
+
className: "text-sm text-[var(--text-danger)]",
|
|
1423
|
+
children: error
|
|
1424
|
+
})
|
|
1425
|
+
]
|
|
1426
|
+
});
|
|
1427
|
+
};
|
|
1428
|
+
Field.displayName = "Field";
|
|
1429
|
+
|
|
875
1430
|
//#endregion
|
|
876
1431
|
//#region src/components/ui/kbd/kbd.tsx
|
|
877
1432
|
const Kbd = ({ className, ...props }) => {
|
|
@@ -882,30 +1437,6 @@ const Kbd = ({ className, ...props }) => {
|
|
|
882
1437
|
});
|
|
883
1438
|
};
|
|
884
1439
|
|
|
885
|
-
//#endregion
|
|
886
|
-
//#region src/components/ui/popover/popover.tsx
|
|
887
|
-
const Popover = ({ ...props }) => /* @__PURE__ */ jsx(PopoverPrimitive.Root, {
|
|
888
|
-
"data-slot": "popover",
|
|
889
|
-
...props
|
|
890
|
-
});
|
|
891
|
-
const PopoverTrigger = ({ ...props }) => /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, {
|
|
892
|
-
"data-slot": "popover-trigger",
|
|
893
|
-
...props
|
|
894
|
-
});
|
|
895
|
-
const PopoverContent = ({ className, align = "center", sideOffset = 4, ...props }) => {
|
|
896
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(PopoverPrimitive.Content, {
|
|
897
|
-
"data-slot": "popover-content",
|
|
898
|
-
align,
|
|
899
|
-
sideOffset,
|
|
900
|
-
className: cn("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-98 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-xl border-0 p-4 shadow-[var(--shadow-elevated)] outline-hidden will-change-[opacity,transform] motion-reduce:animate-none", className),
|
|
901
|
-
...props
|
|
902
|
-
}) });
|
|
903
|
-
};
|
|
904
|
-
const PopoverAnchor = ({ ...props }) => /* @__PURE__ */ jsx(PopoverPrimitive.Anchor, {
|
|
905
|
-
"data-slot": "popover-anchor",
|
|
906
|
-
...props
|
|
907
|
-
});
|
|
908
|
-
|
|
909
1440
|
//#endregion
|
|
910
1441
|
//#region src/components/ui/progress/progress.tsx
|
|
911
1442
|
const progressVariants = cva("h-full w-full flex-1 transition-transform duration-500 ease-out motion-reduce:transition-none", {
|
|
@@ -919,44 +1450,257 @@ const progressVariants = cva("h-full w-full flex-1 transition-transform duration
|
|
|
919
1450
|
warning: "bg-[var(--warning-default)]"
|
|
920
1451
|
} }
|
|
921
1452
|
});
|
|
922
|
-
const Progress = ({ className, indeterminate = false, value, variant, ...props }) =>
|
|
923
|
-
|
|
924
|
-
|
|
1453
|
+
const Progress = ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, className, indeterminate = false, value, variant, ...props }) => {
|
|
1454
|
+
const clamped = Math.min(100, Math.max(0, value ?? 0));
|
|
1455
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1456
|
+
"data-slot": "progress",
|
|
1457
|
+
className: cn("bg-primary/20 relative h-2 w-full overflow-hidden rounded-full", className),
|
|
1458
|
+
...props,
|
|
1459
|
+
children: [/* @__PURE__ */ jsx("progress", {
|
|
1460
|
+
"aria-label": ariaLabel ?? "Progress",
|
|
1461
|
+
"aria-labelledby": ariaLabelledBy,
|
|
1462
|
+
className: "sr-only",
|
|
1463
|
+
max: 100,
|
|
1464
|
+
value: indeterminate ? void 0 : clamped
|
|
1465
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1466
|
+
"data-slot": "progress-indicator",
|
|
1467
|
+
className: cn(progressVariants({ variant }), indeterminate && "animate-progress-indeterminate motion-reduce:animate-none"),
|
|
1468
|
+
style: indeterminate ? void 0 : { transform: `translateX(-${100 - clamped}%)` }
|
|
1469
|
+
})]
|
|
1470
|
+
});
|
|
1471
|
+
};
|
|
1472
|
+
|
|
1473
|
+
//#endregion
|
|
1474
|
+
//#region src/components/ui/radio-group/radio-group.tsx
|
|
1475
|
+
const RadioGroup = ({ className, ...props }) => {
|
|
1476
|
+
return /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, {
|
|
1477
|
+
"data-slot": "radio-group",
|
|
1478
|
+
className: cn("grid gap-3", className),
|
|
1479
|
+
...props
|
|
1480
|
+
});
|
|
1481
|
+
};
|
|
1482
|
+
const RadioGroupItem = ({ className, ...props }) => {
|
|
1483
|
+
return /* @__PURE__ */ jsx(RadioGroupPrimitive.Item, {
|
|
1484
|
+
"data-slot": "radio-group-item",
|
|
1485
|
+
className: cn("text-[var(--action)] dark:bg-input/30 relative aspect-square size-4 shrink-0 touch-manipulation rounded-full border border-[rgba(31,41,55,0.30)] dark:border-[rgba(255,255,255,0.20)] hover:data-[state=unchecked]:border-[rgba(31,41,55,0.45)] dark:hover:data-[state=unchecked]:border-[rgba(255,255,255,0.35)] data-[state=checked]:border-[var(--action)] shadow-[var(--shadow-radio)] dark:shadow-[var(--shadow-radio)] transition-[color,box-shadow,border-color] duration-100 ease-out motion-reduce:transition-none outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-[var(--destructive)] disabled:cursor-not-allowed disabled:opacity-50 cursor-pointer after:absolute after:-inset-[14px] after:content-['']", className),
|
|
1486
|
+
...props,
|
|
1487
|
+
children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, {
|
|
1488
|
+
"data-slot": "radio-group-indicator",
|
|
1489
|
+
className: "group/indicator relative flex items-center justify-center",
|
|
1490
|
+
forceMount: true,
|
|
1491
|
+
children: /* @__PURE__ */ jsx("span", { className: "bg-[var(--action)] absolute top-1/2 left-1/2 size-2 rounded-full -translate-x-1/2 -translate-y-1/2 transition-[opacity,transform] duration-150 ease-out motion-reduce:transition-none group-data-[state=unchecked]/indicator:scale-0 group-data-[state=unchecked]/indicator:opacity-0" })
|
|
1492
|
+
})
|
|
1493
|
+
});
|
|
1494
|
+
};
|
|
1495
|
+
/**
|
|
1496
|
+
* Alias for `RadioGroupItem` for use in labeled-row patterns.
|
|
1497
|
+
*
|
|
1498
|
+
* A radio is inherently part of a group — it must always live inside a
|
|
1499
|
+
* `RadioGroup`. For a standalone on/off toggle, prefer `Checkbox` or `Switch`.
|
|
1500
|
+
* `Radio` is the labeled-usage alias that signals "I'm pairing this with a
|
|
1501
|
+
* `<Label>`" rather than constructing raw item markup.
|
|
1502
|
+
*/
|
|
1503
|
+
const Radio = RadioGroupItem;
|
|
1504
|
+
/**
|
|
1505
|
+
* A convenience labeled-radio row for use inside a `RadioGroup`.
|
|
1506
|
+
*
|
|
1507
|
+
* Renders a `RadioGroupItem` paired with an associated `<Label>` (and an
|
|
1508
|
+
* optional description line) so callers don't have to wire up `id`/`htmlFor`
|
|
1509
|
+
* by hand. The `id` is stable across renders via `React.useId` unless
|
|
1510
|
+
* overridden.
|
|
1511
|
+
*
|
|
1512
|
+
* @example
|
|
1513
|
+
* ```tsx
|
|
1514
|
+
* <RadioGroup value={val} onValueChange={setVal}>
|
|
1515
|
+
* <RadioField value="a" label="Option A" description="First choice" />
|
|
1516
|
+
* <RadioField value="b" label="Option B" />
|
|
1517
|
+
* </RadioGroup>
|
|
1518
|
+
* ```
|
|
1519
|
+
*/
|
|
1520
|
+
const RadioField = ({ value, label, description, disabled, id: idProp, className }) => {
|
|
1521
|
+
const generatedId = useId();
|
|
1522
|
+
const id = idProp ?? generatedId;
|
|
1523
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1524
|
+
className: cn("flex items-start gap-3", disabled && "opacity-50", className),
|
|
1525
|
+
children: [/* @__PURE__ */ jsx(RadioGroupItem, {
|
|
1526
|
+
value,
|
|
1527
|
+
id,
|
|
1528
|
+
disabled,
|
|
1529
|
+
className: "mt-0.5"
|
|
1530
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
1531
|
+
className: "grid gap-0.5",
|
|
1532
|
+
children: [/* @__PURE__ */ jsx(Label, {
|
|
1533
|
+
htmlFor: id,
|
|
1534
|
+
className: cn("cursor-pointer transition-colors duration-100 ease-out motion-reduce:transition-none", disabled && "cursor-not-allowed"),
|
|
1535
|
+
children: label
|
|
1536
|
+
}), description && /* @__PURE__ */ jsx("p", {
|
|
1537
|
+
className: "text-sm text-muted-foreground",
|
|
1538
|
+
children: description
|
|
1539
|
+
})]
|
|
1540
|
+
})]
|
|
1541
|
+
});
|
|
1542
|
+
};
|
|
1543
|
+
|
|
1544
|
+
//#endregion
|
|
1545
|
+
//#region src/components/ui/pagination/pagination.tsx
|
|
1546
|
+
/**
|
|
1547
|
+
* Root nav wrapper for a pagination control set.
|
|
1548
|
+
* Renders a semantic `<nav>` with the ARIA `navigation` landmark.
|
|
1549
|
+
*/
|
|
1550
|
+
const Pagination = ({ className, ...props }) => /* @__PURE__ */ jsx("nav", {
|
|
1551
|
+
"data-slot": "pagination",
|
|
1552
|
+
role: "navigation",
|
|
1553
|
+
"aria-label": "pagination",
|
|
1554
|
+
className: cn("mx-auto flex w-full justify-center", className),
|
|
1555
|
+
...props
|
|
1556
|
+
});
|
|
1557
|
+
/**
|
|
1558
|
+
* Flex row that holds `PaginationItem` children.
|
|
1559
|
+
* Renders as a `<ul>` for correct list semantics inside the nav landmark.
|
|
1560
|
+
*/
|
|
1561
|
+
const PaginationContent = ({ className, ...props }) => /* @__PURE__ */ jsx("ul", {
|
|
1562
|
+
"data-slot": "pagination-content",
|
|
1563
|
+
className: cn("flex flex-row items-center gap-1", className),
|
|
1564
|
+
...props
|
|
1565
|
+
});
|
|
1566
|
+
/**
|
|
1567
|
+
* A single `<li>` slot inside `PaginationContent`.
|
|
1568
|
+
* Acts as a structural wrapper — pair with `PaginationLink`, `PaginationPrevious`, or `PaginationNext`.
|
|
1569
|
+
*/
|
|
1570
|
+
const PaginationItem = ({ className, ...props }) => /* @__PURE__ */ jsx("li", {
|
|
1571
|
+
"data-slot": "pagination-item",
|
|
1572
|
+
className: cn("", className),
|
|
1573
|
+
...props
|
|
1574
|
+
});
|
|
1575
|
+
/**
|
|
1576
|
+
* An individual page link.
|
|
1577
|
+
* Applies `buttonVariants` — `outline` when active, `ghost` when inactive — so focus rings,
|
|
1578
|
+
* `ease-out` transitions, and `motion-reduce` suppression are all inherited from Button's CVA base.
|
|
1579
|
+
*/
|
|
1580
|
+
const PaginationLink = ({ className, isActive = false, children, ...props }) => /* @__PURE__ */ jsx("a", {
|
|
1581
|
+
"data-slot": "pagination-link",
|
|
1582
|
+
"aria-current": isActive ? "page" : void 0,
|
|
1583
|
+
className: cn(buttonVariants({
|
|
1584
|
+
size: "icon-sm",
|
|
1585
|
+
variant: isActive ? "outline" : "ghost"
|
|
1586
|
+
}), className),
|
|
1587
|
+
...props,
|
|
1588
|
+
children
|
|
1589
|
+
});
|
|
1590
|
+
/**
|
|
1591
|
+
* Previous-page control.
|
|
1592
|
+
* Disabled when the consumer passes `aria-disabled="true"` or the native `disabled` attribute.
|
|
1593
|
+
* Touch target is expanded to 44 px via the pseudo-element already baked into `icon-sm`.
|
|
1594
|
+
*/
|
|
1595
|
+
const PaginationPrevious = ({ className, children, ...props }) => /* @__PURE__ */ jsxs("a", {
|
|
1596
|
+
"data-slot": "pagination-previous",
|
|
1597
|
+
"aria-label": "Go to previous page",
|
|
1598
|
+
className: cn(buttonVariants({
|
|
1599
|
+
size: "icon-sm",
|
|
1600
|
+
variant: "ghost"
|
|
1601
|
+
}), "gap-1 pl-2.5", className),
|
|
925
1602
|
...props,
|
|
926
|
-
children: [/* @__PURE__ */ jsx(
|
|
927
|
-
|
|
1603
|
+
children: [/* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1604
|
+
icon: ArrowLeft01Icon,
|
|
1605
|
+
size: 14,
|
|
1606
|
+
"aria-hidden": "true"
|
|
1607
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
928
1608
|
className: "sr-only",
|
|
929
|
-
|
|
930
|
-
value: indeterminate ? void 0 : value ?? 0
|
|
931
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
932
|
-
"data-slot": "progress-indicator",
|
|
933
|
-
className: cn(progressVariants({ variant }), indeterminate && "animate-progress-indeterminate motion-reduce:animate-none"),
|
|
934
|
-
style: indeterminate ? void 0 : { transform: `translateX(-${100 - (value ?? 0)}%)` }
|
|
1609
|
+
children: children ?? "Previous"
|
|
935
1610
|
})]
|
|
936
1611
|
});
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1612
|
+
/**
|
|
1613
|
+
* Next-page control.
|
|
1614
|
+
* Touch target is expanded to 44 px via the pseudo-element already baked into `icon-sm`.
|
|
1615
|
+
*/
|
|
1616
|
+
const PaginationNext = ({ className, children, ...props }) => /* @__PURE__ */ jsxs("a", {
|
|
1617
|
+
"data-slot": "pagination-next",
|
|
1618
|
+
"aria-label": "Go to next page",
|
|
1619
|
+
className: cn(buttonVariants({
|
|
1620
|
+
size: "icon-sm",
|
|
1621
|
+
variant: "ghost"
|
|
1622
|
+
}), "gap-1 pr-2.5", className),
|
|
1623
|
+
...props,
|
|
1624
|
+
children: [/* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1625
|
+
icon: ArrowRight01Icon,
|
|
1626
|
+
size: 14,
|
|
1627
|
+
"aria-hidden": "true"
|
|
1628
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1629
|
+
className: "sr-only",
|
|
1630
|
+
children: children ?? "Next"
|
|
1631
|
+
})]
|
|
1632
|
+
});
|
|
1633
|
+
/**
|
|
1634
|
+
* Ellipsis placeholder shown between non-contiguous page ranges.
|
|
1635
|
+
* Hidden from assistive technologies via `aria-hidden` — screen readers hear the surrounding page
|
|
1636
|
+
* numbers and can infer that pages are omitted.
|
|
1637
|
+
*/
|
|
1638
|
+
const PaginationEllipsis = ({ className, ...props }) => /* @__PURE__ */ jsxs("span", {
|
|
1639
|
+
"data-slot": "pagination-ellipsis",
|
|
1640
|
+
"aria-hidden": "true",
|
|
1641
|
+
className: cn("flex size-7 items-center justify-center text-muted-foreground", className),
|
|
1642
|
+
...props,
|
|
1643
|
+
children: [/* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1644
|
+
icon: MoreHorizontalIcon,
|
|
1645
|
+
size: 14
|
|
1646
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1647
|
+
className: "sr-only",
|
|
1648
|
+
children: "More pages"
|
|
1649
|
+
})]
|
|
1650
|
+
});
|
|
1651
|
+
/**
|
|
1652
|
+
* Pre-assembled cursor-based pagination bar.
|
|
1653
|
+
*
|
|
1654
|
+
* Renders a Previous button, an optional center label, and a Next button.
|
|
1655
|
+
* Each button is disabled automatically when there is no page in that direction.
|
|
1656
|
+
* Designed for dashboard tables and lists that use cursor/keyset pagination rather
|
|
1657
|
+
* than numbered pages — which is the dominant pattern in the Redcoast design system.
|
|
1658
|
+
*
|
|
1659
|
+
* @example
|
|
1660
|
+
* ```tsx
|
|
1661
|
+
* <CursorPagination
|
|
1662
|
+
* hasPrevious={!!cursor.before}
|
|
1663
|
+
* hasNext={!!cursor.after}
|
|
1664
|
+
* onPrevious={loadPrevious}
|
|
1665
|
+
* onNext={loadNext}
|
|
1666
|
+
* label={`${startIndex}–${endIndex} of ${total}`}
|
|
1667
|
+
* />
|
|
1668
|
+
* ```
|
|
1669
|
+
*/
|
|
1670
|
+
const CursorPagination = ({ hasPrevious, hasNext, onPrevious, onNext, label, className }) => /* @__PURE__ */ jsxs("div", {
|
|
1671
|
+
"data-slot": "cursor-pagination",
|
|
1672
|
+
className: cn("flex items-center justify-between gap-2", className),
|
|
1673
|
+
children: [
|
|
1674
|
+
/* @__PURE__ */ jsxs(Button, {
|
|
1675
|
+
variant: "ghost",
|
|
1676
|
+
size: "sm",
|
|
1677
|
+
disabled: !hasPrevious,
|
|
1678
|
+
onClick: onPrevious,
|
|
1679
|
+
"aria-label": "Go to previous page",
|
|
1680
|
+
children: [/* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1681
|
+
icon: ArrowLeft01Icon,
|
|
1682
|
+
size: 14,
|
|
1683
|
+
"aria-hidden": "true"
|
|
1684
|
+
}), "Previous"]
|
|
1685
|
+
}),
|
|
1686
|
+
label !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
1687
|
+
className: "text-sm text-muted-foreground tabular-nums",
|
|
1688
|
+
children: label
|
|
1689
|
+
}),
|
|
1690
|
+
/* @__PURE__ */ jsxs(Button, {
|
|
1691
|
+
variant: "ghost",
|
|
1692
|
+
size: "sm",
|
|
1693
|
+
disabled: !hasNext,
|
|
1694
|
+
onClick: onNext,
|
|
1695
|
+
"aria-label": "Go to next page",
|
|
1696
|
+
children: ["Next", /* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1697
|
+
icon: ArrowRight01Icon,
|
|
1698
|
+
size: 14,
|
|
1699
|
+
"aria-hidden": "true"
|
|
1700
|
+
})]
|
|
957
1701
|
})
|
|
958
|
-
|
|
959
|
-
};
|
|
1702
|
+
]
|
|
1703
|
+
});
|
|
960
1704
|
|
|
961
1705
|
//#endregion
|
|
962
1706
|
//#region src/components/ui/scroll-area/scroll-area.tsx
|
|
@@ -968,7 +1712,7 @@ const ScrollArea = ({ className, children, ...props }) => {
|
|
|
968
1712
|
children: [
|
|
969
1713
|
/* @__PURE__ */ jsx(ScrollAreaPrimitive.Viewport, {
|
|
970
1714
|
"data-slot": "scroll-area-viewport",
|
|
971
|
-
className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px]
|
|
1715
|
+
className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] motion-reduce:transition-none outline-none focus-visible:ring-[3px]",
|
|
972
1716
|
children
|
|
973
1717
|
}),
|
|
974
1718
|
/* @__PURE__ */ jsx(ScrollBar, {}),
|
|
@@ -980,7 +1724,7 @@ const ScrollBar = ({ className, orientation = "vertical", ...props }) => {
|
|
|
980
1724
|
return /* @__PURE__ */ jsx(ScrollAreaPrimitive.ScrollAreaScrollbar, {
|
|
981
1725
|
"data-slot": "scroll-area-scrollbar",
|
|
982
1726
|
orientation,
|
|
983
|
-
className: cn("flex touch-none touch-manipulation p-px transition-[background-color] select-none", orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent", orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent", className),
|
|
1727
|
+
className: cn("flex touch-none touch-manipulation p-px transition-[background-color] motion-reduce:transition-none select-none", orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent", orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent", className),
|
|
984
1728
|
...props,
|
|
985
1729
|
children: /* @__PURE__ */ jsx(ScrollAreaPrimitive.ScrollAreaThumb, {
|
|
986
1730
|
"data-slot": "scroll-area-thumb",
|
|
@@ -995,14 +1739,14 @@ const SearchInput = ({ className, placeholder = "Search...", shortcut = "⌘K",
|
|
|
995
1739
|
return /* @__PURE__ */ jsxs("button", {
|
|
996
1740
|
type: "button",
|
|
997
1741
|
"data-slot": "search-input",
|
|
998
|
-
className: cn("h-8
|
|
1742
|
+
className: cn("h-8 w-full touch-manipulation rounded-md border-0 bg-background dark:bg-input/30 shadow-[var(--shadow-input)]", "hover:shadow-[var(--shadow-input-hover)]", "transition-[color,box-shadow] duration-100 ease-out motion-reduce:transition-none", "outline-none focus-visible:shadow-[0_0_0_1px_var(--ring),0_0_0_4px_var(--ring-halo,#0072EF26)]", "flex items-center gap-2 px-2", "text-sm text-muted-foreground/60 cursor-pointer", className),
|
|
999
1743
|
onClick,
|
|
1000
1744
|
...props,
|
|
1001
1745
|
children: [
|
|
1002
1746
|
/* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1003
1747
|
icon: Search01Icon,
|
|
1004
|
-
size:
|
|
1005
|
-
className: "shrink-0 text-muted-foreground"
|
|
1748
|
+
size: 16,
|
|
1749
|
+
className: "shrink-0 text-muted-foreground/70"
|
|
1006
1750
|
}),
|
|
1007
1751
|
/* @__PURE__ */ jsx("span", {
|
|
1008
1752
|
className: "flex-1 text-left",
|
|
@@ -1030,27 +1774,27 @@ const SelectValue = ({ ...props }) => /* @__PURE__ */ jsx(Value, {
|
|
|
1030
1774
|
const SelectTrigger = ({ className, size = "default", children, ...props }) => /* @__PURE__ */ jsxs(Trigger$4, {
|
|
1031
1775
|
"data-slot": "select-trigger",
|
|
1032
1776
|
"data-size": size,
|
|
1033
|
-
className: cn("data-[placeholder]:text-muted-foreground/60 [&_svg:not([class*='text-'])]:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 flex w-fit touch-manipulation items-center justify-between gap-1.5 rounded-md border-0 bg-transparent px-3 py-2 text-[13px] whitespace-nowrap shadow-[var(--shadow-input)] hover:shadow-[var(--shadow-input-hover)] transition-[color,box-shadow] duration-100 ease-out outline-none focus-visible:shadow-[0_0_0_1px_var(--ring),
|
|
1777
|
+
className: cn("data-[placeholder]:text-muted-foreground/60 [&_svg:not([class*='text-'])]:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 flex w-fit touch-manipulation items-center justify-between gap-1.5 rounded-md border-0 bg-transparent px-3 py-2 text-[13px] whitespace-nowrap shadow-[var(--shadow-input)] hover:shadow-[var(--shadow-input-hover)] transition-[color,box-shadow] duration-100 ease-out outline-none focus-visible:shadow-[0_0_0_1px_var(--ring),0_0_0_4px_var(--ring-halo,#0072EF26)] aria-invalid:shadow-[0_0_0_1px_var(--destructive)] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:text-[13px] data-[size=sm]:px-2.5 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[state=open]:[&>svg:last-of-type]:rotate-180", className),
|
|
1034
1778
|
...props,
|
|
1035
1779
|
children: [children, /* @__PURE__ */ jsx(Icon$1, {
|
|
1036
1780
|
asChild: true,
|
|
1037
1781
|
children: /* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1038
1782
|
icon: ArrowDown01Icon,
|
|
1039
1783
|
size: 16,
|
|
1040
|
-
className: "opacity-50"
|
|
1784
|
+
className: "opacity-50 transition-transform duration-150 ease-out motion-reduce:transition-none"
|
|
1041
1785
|
})
|
|
1042
1786
|
})]
|
|
1043
1787
|
});
|
|
1044
1788
|
const SelectContent = ({ className, children, position = "popper", align = "start", ...props }) => /* @__PURE__ */ jsx(Portal$3, { children: /* @__PURE__ */ jsxs(Content$4, {
|
|
1045
1789
|
"data-slot": "select-content",
|
|
1046
|
-
className: cn("bg-popover text-popover-foreground will-change-[opacity,transform] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-xl border-0 shadow-[var(--shadow-elevated)]", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
|
|
1790
|
+
className: cn("bg-popover text-popover-foreground will-change-[opacity,transform] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 motion-reduce:animate-none relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-xl border-0 shadow-[var(--shadow-elevated)]", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
|
|
1047
1791
|
position,
|
|
1048
1792
|
align,
|
|
1049
1793
|
...props,
|
|
1050
1794
|
children: [
|
|
1051
1795
|
/* @__PURE__ */ jsx(SelectScrollUpButton, {}),
|
|
1052
1796
|
/* @__PURE__ */ jsx(Viewport, {
|
|
1053
|
-
className: cn("p-1", position === "popper" && "
|
|
1797
|
+
className: cn("p-1", position === "popper" && "w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"),
|
|
1054
1798
|
children
|
|
1055
1799
|
}),
|
|
1056
1800
|
/* @__PURE__ */ jsx(SelectScrollDownButton, {})
|
|
@@ -1063,14 +1807,14 @@ const SelectLabel = ({ className, ...props }) => /* @__PURE__ */ jsx(Label$2, {
|
|
|
1063
1807
|
});
|
|
1064
1808
|
const SelectItem = ({ className, children, ...props }) => /* @__PURE__ */ jsxs(Item$2, {
|
|
1065
1809
|
"data-slot": "select-item",
|
|
1066
|
-
className: cn("
|
|
1810
|
+
className: cn("data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[state=checked]:font-medium [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
|
|
1067
1811
|
...props,
|
|
1068
1812
|
children: [/* @__PURE__ */ jsx("span", {
|
|
1069
1813
|
"data-slot": "select-item-indicator",
|
|
1070
1814
|
className: "absolute right-2 flex size-3.5 items-center justify-center",
|
|
1071
1815
|
children: /* @__PURE__ */ jsx(ItemIndicator$1, { children: /* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1072
1816
|
icon: Tick01Icon,
|
|
1073
|
-
size:
|
|
1817
|
+
size: 14
|
|
1074
1818
|
}) })
|
|
1075
1819
|
}), /* @__PURE__ */ jsx(ItemText, { children })]
|
|
1076
1820
|
});
|
|
@@ -1085,7 +1829,8 @@ const SelectScrollUpButton = ({ className, ...props }) => /* @__PURE__ */ jsx(Sc
|
|
|
1085
1829
|
...props,
|
|
1086
1830
|
children: /* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1087
1831
|
icon: ArrowUp01Icon,
|
|
1088
|
-
size: 16
|
|
1832
|
+
size: 16,
|
|
1833
|
+
"aria-hidden": true
|
|
1089
1834
|
})
|
|
1090
1835
|
});
|
|
1091
1836
|
const SelectScrollDownButton = ({ className, ...props }) => /* @__PURE__ */ jsx(ScrollDownButton, {
|
|
@@ -1094,7 +1839,8 @@ const SelectScrollDownButton = ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
|
1094
1839
|
...props,
|
|
1095
1840
|
children: /* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1096
1841
|
icon: ArrowDown01Icon,
|
|
1097
|
-
size: 16
|
|
1842
|
+
size: 16,
|
|
1843
|
+
"aria-hidden": true
|
|
1098
1844
|
})
|
|
1099
1845
|
});
|
|
1100
1846
|
|
|
@@ -1103,7 +1849,7 @@ const SelectScrollDownButton = ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
|
1103
1849
|
const SelectableCard = ({ badge, className, description, icon, iconSize = 20, label, selected, ...props }) => /* @__PURE__ */ jsxs("button", {
|
|
1104
1850
|
"data-slot": "selectable-card",
|
|
1105
1851
|
"data-selected": selected,
|
|
1106
|
-
className: cn("group/card relative flex flex-col items-start gap-2.5 p-4 rounded-xl text-left transition-[box-shadow,background-color,scale] duration-150 touch-manipulation active:scale-[0.96] cursor-pointer w-full outline-none focus-visible:shadow-[0_0_0_1.5px_var(--action),0_0_0_4px_oklch(from_var(--action)_l_c_h_/_0.25)]", selected ? "bg-[var(--action)]/5 shadow-[0_0_0_1.5px_var(--action)]" : "shadow-[0_0_0_1px_oklch(0.278_0.03_256.85_/_0.12)] hover:shadow-[0_0_0_1px_oklch(0.278_0.03_256.85_/_0.20)]", className),
|
|
1852
|
+
className: cn("group/card relative flex flex-col items-start gap-2.5 p-4 rounded-xl text-left transition-[box-shadow,background-color,scale] duration-150 motion-reduce:transition-none touch-manipulation active:scale-[0.96] cursor-pointer w-full outline-none focus-visible:shadow-[0_0_0_1.5px_var(--action),0_0_0_4px_oklch(from_var(--action)_l_c_h_/_0.25)]", selected ? "bg-[var(--action)]/5 shadow-[0_0_0_1.5px_var(--action)]" : "shadow-[0_0_0_1px_oklch(0.278_0.03_256.85_/_0.12)] hover:shadow-[0_0_0_1px_oklch(0.278_0.03_256.85_/_0.20)]", className),
|
|
1107
1853
|
...props,
|
|
1108
1854
|
children: [
|
|
1109
1855
|
icon && /* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
@@ -1130,10 +1876,10 @@ const SelectableCard = ({ badge, className, description, icon, iconSize = 20, la
|
|
|
1130
1876
|
/* @__PURE__ */ jsx("div", {
|
|
1131
1877
|
className: "absolute top-4 right-4",
|
|
1132
1878
|
children: /* @__PURE__ */ jsx("div", {
|
|
1133
|
-
className: cn("relative size-4 shrink-0 rounded-[4px] transition-[color,box-shadow,background-color] duration-200 ease", selected ? "bg-[var(--action)] text-white shadow-[0_0_0_1px_var(--action),0px_1px_1px_0px_oklch(1_0_0_/_0.07)_inset,0px_2px_3px_0px_oklch(0.278_0.03_256.85_/_0.20),0px_1px_1px_0px_oklch(0_0_0_/_0.24)]" : "shadow-[0_0_0_1px_oklch(0.278_0.03_256.85_/_0.20),0_1px_2px_0_oklch(0_0_0_/_0.06),0_0_1px_0_oklch(0_0_0_/_0.02)] group-hover/card:shadow-[0_0_0_1px_oklch(0.278_0.03_256.85_/_0.30),0_1px_2px_0_oklch(0_0_0_/_0.06),0_0_1px_0_oklch(0_0_0_/_0.02)]"),
|
|
1879
|
+
className: cn("relative size-4 shrink-0 rounded-[4px] transition-[color,box-shadow,background-color] duration-200 ease-out motion-reduce:transition-none", selected ? "bg-[var(--action)] text-white shadow-[0_0_0_1px_var(--action),0px_1px_1px_0px_oklch(1_0_0_/_0.07)_inset,0px_2px_3px_0px_oklch(0.278_0.03_256.85_/_0.20),0px_1px_1px_0px_oklch(0_0_0_/_0.24)]" : "shadow-[0_0_0_1px_oklch(0.278_0.03_256.85_/_0.20),0_1px_2px_0_oklch(0_0_0_/_0.06),0_0_1px_0_oklch(0_0_0_/_0.02)] group-hover/card:shadow-[0_0_0_1px_oklch(0.278_0.03_256.85_/_0.30),0_1px_2px_0_oklch(0_0_0_/_0.06),0_0_1px_0_oklch(0_0_0_/_0.02)]"),
|
|
1134
1880
|
children: /* @__PURE__ */ jsx(CheckIcon, {
|
|
1135
1881
|
size: 14,
|
|
1136
|
-
className: cn("absolute inset-0 m-auto text-current transition-[opacity,transform,filter] duration-200", selected ? "opacity-100 scale-100 blur-none" : "opacity-0 scale-[0.25] blur-[4px]")
|
|
1882
|
+
className: cn("absolute inset-0 m-auto text-current transition-[opacity,transform,filter] duration-200 motion-reduce:transition-none", selected ? "opacity-100 scale-100 blur-none" : "opacity-0 scale-[0.25] blur-[4px]")
|
|
1137
1883
|
})
|
|
1138
1884
|
})
|
|
1139
1885
|
})
|
|
@@ -1151,6 +1897,41 @@ const Separator = forwardRef(({ className, orientation = "horizontal", decorativ
|
|
|
1151
1897
|
}));
|
|
1152
1898
|
Separator.displayName = Root$5.displayName;
|
|
1153
1899
|
|
|
1900
|
+
//#endregion
|
|
1901
|
+
//#region src/components/ui/slider/slider.tsx
|
|
1902
|
+
/**
|
|
1903
|
+
* Controlled range slider built on a native `<input type="range">`.
|
|
1904
|
+
*
|
|
1905
|
+
* Zero-dependency — all styling is done with Tailwind arbitrary variants so
|
|
1906
|
+
* no Radix/Headless UI install is needed. The filled portion is rendered via an
|
|
1907
|
+
* inline CSS custom property so the gradient stays in sync with the value without
|
|
1908
|
+
* any JS animation loop.
|
|
1909
|
+
*/
|
|
1910
|
+
const Slider = ({ value, onValueChange, min = 0, max = 100, step = 1, disabled = false, className }) => {
|
|
1911
|
+
const clamped = Math.min(max, Math.max(min, value));
|
|
1912
|
+
const range = max - min;
|
|
1913
|
+
const fillPercent = range === 0 ? 0 : (clamped - min) / range * 100;
|
|
1914
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1915
|
+
"data-slot": "slider",
|
|
1916
|
+
className: cn("relative flex w-full touch-manipulation items-center", className),
|
|
1917
|
+
children: /* @__PURE__ */ jsx("input", {
|
|
1918
|
+
type: "range",
|
|
1919
|
+
"data-slot": "slider-input",
|
|
1920
|
+
min,
|
|
1921
|
+
max,
|
|
1922
|
+
step,
|
|
1923
|
+
value: clamped,
|
|
1924
|
+
disabled,
|
|
1925
|
+
"aria-valuemin": min,
|
|
1926
|
+
"aria-valuemax": max,
|
|
1927
|
+
"aria-valuenow": clamped,
|
|
1928
|
+
onChange: (e) => onValueChange(Number(e.target.value)),
|
|
1929
|
+
className: cn("w-full appearance-none bg-transparent outline-none", "cursor-pointer disabled:cursor-not-allowed disabled:opacity-50", "[&::-webkit-slider-runnable-track]:h-1.5", "[&::-webkit-slider-runnable-track]:w-full", "[&::-webkit-slider-runnable-track]:rounded-full", "[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--action)_var(--slider-fill,0%),var(--bg-accented)_var(--slider-fill,0%))]", "[&::-webkit-slider-runnable-track]:transition-[background-size] [&::-webkit-slider-runnable-track]:duration-150 [&::-webkit-slider-runnable-track]:ease-out", "[&::-webkit-slider-runnable-track]:motion-reduce:transition-none", "[&::-webkit-slider-thumb]:appearance-none", "[&::-webkit-slider-thumb]:size-4", "[&::-webkit-slider-thumb]:rounded-full", "[&::-webkit-slider-thumb]:bg-background", "[&::-webkit-slider-thumb]:border", "[&::-webkit-slider-thumb]:border-[var(--action)]", "[&::-webkit-slider-thumb]:shadow-[var(--shadow-control-thumb)]", "[&::-webkit-slider-thumb]:-mt-[5px]", "[&::-webkit-slider-thumb]:transition-[box-shadow] [&::-webkit-slider-thumb]:duration-150 [&::-webkit-slider-thumb]:ease-out", "[&::-webkit-slider-thumb]:motion-reduce:transition-none", "focus-visible:[&::-webkit-slider-thumb]:shadow-[0_0_0_3px_var(--ring-halo),var(--shadow-control-thumb)]", "[&::-moz-range-track]:h-1.5", "[&::-moz-range-track]:w-full", "[&::-moz-range-track]:rounded-full", "[&::-moz-range-track]:bg-[var(--bg-accented)]", "[&::-moz-range-progress]:h-1.5", "[&::-moz-range-progress]:rounded-full", "[&::-moz-range-progress]:bg-[var(--action)]", "[&::-moz-range-thumb]:size-4", "[&::-moz-range-thumb]:rounded-full", "[&::-moz-range-thumb]:border", "[&::-moz-range-thumb]:border-[var(--action)]", "[&::-moz-range-thumb]:bg-background", "[&::-moz-range-thumb]:shadow-[var(--shadow-control-thumb)]", "[&::-moz-range-thumb]:transition-[box-shadow] [&::-moz-range-thumb]:duration-150 [&::-moz-range-thumb]:ease-out", "[&::-moz-range-thumb]:motion-reduce:transition-none", "focus-visible:[&::-moz-range-thumb]:shadow-[0_0_0_3px_var(--ring-halo),var(--shadow-control-thumb)]"),
|
|
1930
|
+
style: { "--slider-fill": `${fillPercent}%` }
|
|
1931
|
+
})
|
|
1932
|
+
});
|
|
1933
|
+
};
|
|
1934
|
+
|
|
1154
1935
|
//#endregion
|
|
1155
1936
|
//#region src/components/ui/sheet/sheet.tsx
|
|
1156
1937
|
const Sheet = ({ ...props }) => /* @__PURE__ */ jsx(SheetPrimitive.Root, {
|
|
@@ -1182,7 +1963,7 @@ const SheetContent = ({ className, children, side = "right", showCloseButton = t
|
|
|
1182
1963
|
className: cn("bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 border-0 shadow-[var(--shadow-elevated)] [animation-timing-function:cubic-bezier(0.32,0.72,0,1)] data-[state=closed]:duration-150 data-[state=open]:duration-200 will-change-[opacity,transform] motion-reduce:animate-none", side === "right" && "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 sm:max-w-sm rounded-l-xl rounded-r-md", side === "left" && "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 sm:max-w-sm rounded-r-xl rounded-l-md", side === "top" && "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto rounded-b-md", side === "bottom" && "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto rounded-t-md", className),
|
|
1183
1964
|
...props,
|
|
1184
1965
|
children: [children, showCloseButton && /* @__PURE__ */ jsxs(SheetPrimitive.Close, {
|
|
1185
|
-
className: "absolute top-3 right-3 inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground opacity-70 transition-[opacity,background-color] duration-150 ease hover:opacity-100 hover:bg-accent focus-visible:ring-2 focus-visible:ring-ring/50 focus:outline-hidden disabled:pointer-events-none cursor-pointer touch-manipulation before:absolute before:-inset-
|
|
1966
|
+
className: "absolute top-3 right-3 inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground opacity-70 transition-[opacity,background-color] duration-150 ease-out motion-reduce:transition-none hover:opacity-100 hover:bg-accent focus-visible:ring-2 focus-visible:ring-ring/50 focus:outline-hidden disabled:pointer-events-none cursor-pointer touch-manipulation before:absolute before:-inset-2 before:content-['']",
|
|
1186
1967
|
children: [/* @__PURE__ */ jsx(HugeiconsIcon, {
|
|
1187
1968
|
icon: Cancel01Icon,
|
|
1188
1969
|
size: 14
|
|
@@ -1196,14 +1977,14 @@ const SheetContent = ({ className, children, side = "right", showCloseButton = t
|
|
|
1196
1977
|
const SheetHeader = ({ className, ...props }) => {
|
|
1197
1978
|
return /* @__PURE__ */ jsx("div", {
|
|
1198
1979
|
"data-slot": "sheet-header",
|
|
1199
|
-
className: cn("flex flex-col gap-
|
|
1980
|
+
className: cn("flex flex-col gap-0.5 px-4 py-3.5 border-b border-[var(--border-divider)]", className),
|
|
1200
1981
|
...props
|
|
1201
1982
|
});
|
|
1202
1983
|
};
|
|
1203
1984
|
const SheetFooter = ({ className, ...props }) => {
|
|
1204
1985
|
return /* @__PURE__ */ jsx("div", {
|
|
1205
1986
|
"data-slot": "sheet-footer",
|
|
1206
|
-
className: cn("mt-auto flex flex-col gap-2
|
|
1987
|
+
className: cn("mt-auto flex flex-col gap-2 px-4 py-3.5 border-t border-[var(--border-divider)] bg-muted", className),
|
|
1207
1988
|
...props
|
|
1208
1989
|
});
|
|
1209
1990
|
};
|
|
@@ -1225,9 +2006,10 @@ const SheetDescription = ({ className, ...props }) => {
|
|
|
1225
2006
|
//#endregion
|
|
1226
2007
|
//#region src/components/ui/skeleton/skeleton.tsx
|
|
1227
2008
|
const Skeleton = ({ className, ...props }) => {
|
|
1228
|
-
return /* @__PURE__ */ jsx("
|
|
2009
|
+
return /* @__PURE__ */ jsx("output", {
|
|
2010
|
+
"aria-label": "Loading",
|
|
1229
2011
|
"data-slot": "skeleton",
|
|
1230
|
-
className: cn("bg-accent animate-shimmer motion-reduce:animate-none rounded-md bg-[length:200%_100%] bg-gradient-to-r from-accent via-accent/50 to-accent", className),
|
|
2012
|
+
className: cn("block bg-accent animate-shimmer motion-reduce:animate-none rounded-md bg-[length:200%_100%] bg-gradient-to-r from-accent via-accent/50 to-accent dark:via-accent/70", className),
|
|
1231
2013
|
...props
|
|
1232
2014
|
});
|
|
1233
2015
|
};
|
|
@@ -1285,27 +2067,64 @@ const Toaster = ({ ...props }) => {
|
|
|
1285
2067
|
};
|
|
1286
2068
|
|
|
1287
2069
|
//#endregion
|
|
1288
|
-
//#region src/components/ui/
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
2070
|
+
//#region src/components/ui/stepper/stepper.tsx
|
|
2071
|
+
/**
|
|
2072
|
+
* Horizontal step indicator that renders an ordered sequence of steps with
|
|
2073
|
+
* connector lines between them.
|
|
2074
|
+
*
|
|
2075
|
+
* - **COMPLETED** (index < currentStep): filled action-coloured circle + white checkmark.
|
|
2076
|
+
* - **CURRENT** (index === currentStep): action-coloured border + step number; label is font-medium.
|
|
2077
|
+
* - **UPCOMING** (index > currentStep): muted border + step number.
|
|
2078
|
+
*
|
|
2079
|
+
* Connector lines between adjacent steps are action-coloured when the segment
|
|
2080
|
+
* is completed (both endpoints are ≤ currentStep) and divider-coloured otherwise.
|
|
2081
|
+
*
|
|
2082
|
+
* @example
|
|
2083
|
+
* <Stepper steps={[{ label: 'Account' }, { label: 'Details' }, { label: 'Review' }]} currentStep={1} />
|
|
2084
|
+
*/
|
|
2085
|
+
const Stepper = ({ steps, currentStep, className, ...props }) => /* @__PURE__ */ jsx("ol", {
|
|
2086
|
+
"aria-label": "Progress",
|
|
2087
|
+
className: cn("flex w-full items-start", className),
|
|
2088
|
+
...props,
|
|
2089
|
+
children: steps.map((step, index) => {
|
|
2090
|
+
const isCompleted = index < currentStep;
|
|
2091
|
+
const isCurrent = index === currentStep;
|
|
2092
|
+
const connectorCompleted = index > 0 && index <= currentStep;
|
|
2093
|
+
return /* @__PURE__ */ jsxs("li", {
|
|
2094
|
+
className: cn("flex flex-1 items-start", index === steps.length - 1 && "flex-none"),
|
|
2095
|
+
"aria-current": isCurrent ? "step" : void 0,
|
|
2096
|
+
children: [
|
|
2097
|
+
index > 0 && /* @__PURE__ */ jsx("div", {
|
|
2098
|
+
"aria-hidden": "true",
|
|
2099
|
+
className: cn("mt-3.5 h-px flex-1 transition-colors duration-300 ease-out motion-reduce:transition-none", connectorCompleted ? "bg-[var(--action)]" : "bg-[var(--border-divider)]")
|
|
2100
|
+
}),
|
|
2101
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2102
|
+
className: "flex flex-col items-center gap-1.5",
|
|
2103
|
+
children: [
|
|
2104
|
+
/* @__PURE__ */ jsx("div", {
|
|
2105
|
+
"aria-hidden": "true",
|
|
2106
|
+
className: cn("flex size-7 shrink-0 items-center justify-center rounded-full text-xs font-semibold transition-[background-color,border-color,color] duration-300 ease-out motion-reduce:transition-none select-none", isCompleted && "bg-[var(--action)] text-white", isCurrent && "border-2 border-[var(--action)] text-[var(--action)]", !isCompleted && !isCurrent && "border border-[var(--border-default)] text-muted-foreground"),
|
|
2107
|
+
children: isCompleted ? /* @__PURE__ */ jsx(CheckIcon, {
|
|
2108
|
+
size: 13,
|
|
2109
|
+
strokeWidth: 3
|
|
2110
|
+
}) : String(index + 1)
|
|
2111
|
+
}),
|
|
2112
|
+
/* @__PURE__ */ jsx("span", {
|
|
2113
|
+
className: cn("max-w-[6rem] text-center text-xs leading-tight transition-colors duration-300 ease-out motion-reduce:transition-none", isCurrent ? "font-medium text-foreground" : "text-muted-foreground"),
|
|
2114
|
+
children: step.label
|
|
2115
|
+
}),
|
|
2116
|
+
step.description && /* @__PURE__ */ jsx("span", {
|
|
2117
|
+
className: "max-w-[6rem] text-center text-[10px] leading-tight text-muted-foreground",
|
|
2118
|
+
children: step.description
|
|
2119
|
+
})
|
|
2120
|
+
]
|
|
2121
|
+
}),
|
|
2122
|
+
index < steps.length - 1 && /* @__PURE__ */ jsx("div", {
|
|
2123
|
+
"aria-hidden": "true",
|
|
2124
|
+
className: cn("mt-3.5 h-px flex-1 transition-colors duration-300 ease-out motion-reduce:transition-none", index + 1 <= currentStep ? "bg-[var(--action)]" : "bg-[var(--border-divider)]")
|
|
2125
|
+
})
|
|
2126
|
+
]
|
|
2127
|
+
}, step.label);
|
|
1309
2128
|
})
|
|
1310
2129
|
});
|
|
1311
2130
|
|
|
@@ -1325,7 +2144,7 @@ const Table = ({ className, ...props }) => {
|
|
|
1325
2144
|
const TableHeader = ({ className, ...props }) => {
|
|
1326
2145
|
return /* @__PURE__ */ jsx("thead", {
|
|
1327
2146
|
"data-slot": "table-header",
|
|
1328
|
-
className: cn("[&_tr]:border-b [&_tr]:border-[var(--border-divider)] [&_tr]:hover:bg-transparent bg-[var(--bg-accented)]/50 sticky top-0 z-
|
|
2147
|
+
className: cn("[&_tr]:border-b [&_tr]:border-[var(--border-divider)] [&_tr]:hover:bg-transparent bg-[var(--bg-accented)]/50 sticky top-0 z-20", className),
|
|
1329
2148
|
...props
|
|
1330
2149
|
});
|
|
1331
2150
|
};
|
|
@@ -1350,10 +2169,11 @@ const TableRow = ({ className, ...props }) => {
|
|
|
1350
2169
|
...props
|
|
1351
2170
|
});
|
|
1352
2171
|
};
|
|
1353
|
-
const TableHead = ({ className, ...props }) => {
|
|
2172
|
+
const TableHead = ({ className, scope, ...props }) => {
|
|
1354
2173
|
return /* @__PURE__ */ jsx("th", {
|
|
1355
2174
|
"data-slot": "table-head",
|
|
1356
|
-
|
|
2175
|
+
scope: scope ?? "col",
|
|
2176
|
+
className: cn("text-muted-foreground h-10 px-3 text-left align-middle text-xs font-medium whitespace-nowrap tabular-nums [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", className),
|
|
1357
2177
|
...props
|
|
1358
2178
|
});
|
|
1359
2179
|
};
|
|
@@ -1401,24 +2221,155 @@ const TabsList = ({ className, variant = "default", ...props }) => {
|
|
|
1401
2221
|
const TabsTrigger = ({ className, ...props }) => {
|
|
1402
2222
|
return /* @__PURE__ */ jsx(TabsPrimitive.Trigger, {
|
|
1403
2223
|
"data-slot": "tabs-trigger",
|
|
1404
|
-
className: cn("focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap touch-manipulation transition-[color,background-color,border-color,box-shadow,opacity] duration-150 group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent", "data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 data-[state=active]:text-foreground", "after:bg-foreground after:absolute after:opacity-0 after:transition-[opacity] group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100", className),
|
|
2224
|
+
className: cn("focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap touch-manipulation transition-[color,background-color,border-color,box-shadow,opacity] duration-150 motion-reduce:transition-none group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent", "data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 data-[state=active]:text-foreground", "after:bg-foreground after:absolute after:opacity-0 after:transition-[opacity] after:motion-reduce:transition-none group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100", className),
|
|
1405
2225
|
...props
|
|
1406
2226
|
});
|
|
1407
2227
|
};
|
|
1408
2228
|
const TabsContent = ({ className, ...props }) => {
|
|
1409
2229
|
return /* @__PURE__ */ jsx(TabsPrimitive.Content, {
|
|
1410
2230
|
"data-slot": "tabs-content",
|
|
1411
|
-
className: cn("flex-1 outline-none", className),
|
|
2231
|
+
className: cn("flex-1 outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:rounded-md", className),
|
|
1412
2232
|
...props
|
|
1413
2233
|
});
|
|
1414
2234
|
};
|
|
1415
2235
|
|
|
2236
|
+
//#endregion
|
|
2237
|
+
//#region src/components/ui/toggle-group/toggle-group.tsx
|
|
2238
|
+
const ToggleGroupContext = createContext(null);
|
|
2239
|
+
const useToggleGroupContext = () => {
|
|
2240
|
+
const ctx = useContext(ToggleGroupContext);
|
|
2241
|
+
if (!ctx) throw new Error("ToggleGroupItem must be used inside a ToggleGroup");
|
|
2242
|
+
return ctx;
|
|
2243
|
+
};
|
|
2244
|
+
/**
|
|
2245
|
+
* Segmented control container that manages single or multiple selection.
|
|
2246
|
+
* Renders a rounded pill-track styled with the muted background token.
|
|
2247
|
+
* Provides context and implements roving keyboard navigation across items.
|
|
2248
|
+
*
|
|
2249
|
+
* @example
|
|
2250
|
+
* // Single selection
|
|
2251
|
+
* <ToggleGroup type="single" value={view} onValueChange={setView}>
|
|
2252
|
+
* <ToggleGroupItem value="day">Day</ToggleGroupItem>
|
|
2253
|
+
* <ToggleGroupItem value="week">Week</ToggleGroupItem>
|
|
2254
|
+
* </ToggleGroup>
|
|
2255
|
+
*
|
|
2256
|
+
* @example
|
|
2257
|
+
* // Multiple selection
|
|
2258
|
+
* <ToggleGroup type="multiple" value={formats} onValueChange={setFormats}>
|
|
2259
|
+
* <ToggleGroupItem value="bold">B</ToggleGroupItem>
|
|
2260
|
+
* <ToggleGroupItem value="italic">I</ToggleGroupItem>
|
|
2261
|
+
* </ToggleGroup>
|
|
2262
|
+
*/
|
|
2263
|
+
const ToggleGroup = ({ type, value, onValueChange, disabled = false, className, children, ...props }) => {
|
|
2264
|
+
const groupId = useId();
|
|
2265
|
+
const containerRef = useRef(null);
|
|
2266
|
+
const handleKeyDown = useCallback((e) => {
|
|
2267
|
+
const container = containerRef.current;
|
|
2268
|
+
if (!container) return;
|
|
2269
|
+
const items = Array.from(container.querySelectorAll("button[data-slot=\"toggle-group-item\"]:not([disabled])"));
|
|
2270
|
+
if (items.length === 0) return;
|
|
2271
|
+
const focused = document.activeElement;
|
|
2272
|
+
const idx = items.indexOf(focused);
|
|
2273
|
+
let next;
|
|
2274
|
+
if (e.key === "ArrowRight" || e.key === "ArrowDown") {
|
|
2275
|
+
e.preventDefault();
|
|
2276
|
+
next = (idx + 1) % items.length;
|
|
2277
|
+
} else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
|
|
2278
|
+
e.preventDefault();
|
|
2279
|
+
next = (idx - 1 + items.length) % items.length;
|
|
2280
|
+
} else if (e.key === "Home") {
|
|
2281
|
+
e.preventDefault();
|
|
2282
|
+
next = 0;
|
|
2283
|
+
} else if (e.key === "End") {
|
|
2284
|
+
e.preventDefault();
|
|
2285
|
+
next = items.length - 1;
|
|
2286
|
+
} else return;
|
|
2287
|
+
items[next]?.focus();
|
|
2288
|
+
}, []);
|
|
2289
|
+
const contextValue = useMemo(() => type === "single" ? {
|
|
2290
|
+
disabled,
|
|
2291
|
+
groupId,
|
|
2292
|
+
onValueChange,
|
|
2293
|
+
type: "single",
|
|
2294
|
+
value
|
|
2295
|
+
} : {
|
|
2296
|
+
disabled,
|
|
2297
|
+
groupId,
|
|
2298
|
+
onValueChange,
|
|
2299
|
+
type: "multiple",
|
|
2300
|
+
value
|
|
2301
|
+
}, [
|
|
2302
|
+
disabled,
|
|
2303
|
+
groupId,
|
|
2304
|
+
onValueChange,
|
|
2305
|
+
type,
|
|
2306
|
+
value
|
|
2307
|
+
]);
|
|
2308
|
+
return /* @__PURE__ */ jsx(ToggleGroupContext.Provider, {
|
|
2309
|
+
value: contextValue,
|
|
2310
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
2311
|
+
ref: containerRef,
|
|
2312
|
+
"data-slot": "toggle-group",
|
|
2313
|
+
role: type === "single" ? "radiogroup" : "toolbar",
|
|
2314
|
+
onKeyDown: handleKeyDown,
|
|
2315
|
+
className: cn("inline-flex items-center rounded-lg bg-muted p-[3px] gap-0.5", disabled && "opacity-50 pointer-events-none", className),
|
|
2316
|
+
...props,
|
|
2317
|
+
children
|
|
2318
|
+
})
|
|
2319
|
+
});
|
|
2320
|
+
};
|
|
2321
|
+
/**
|
|
2322
|
+
* An individual button within a ToggleGroup.
|
|
2323
|
+
* Reads context to determine selection state and fires the appropriate
|
|
2324
|
+
* onValueChange callback on click. Mirrors the elevated/pill styling of
|
|
2325
|
+
* the active tab trigger (bg-background + shadow) when selected.
|
|
2326
|
+
*/
|
|
2327
|
+
const ToggleGroupItem = ({ value, disabled, className, children, onClick, ...props }) => {
|
|
2328
|
+
const ctx = useToggleGroupContext();
|
|
2329
|
+
const isDisabled = disabled ?? ctx.disabled;
|
|
2330
|
+
const isActive = ctx.type === "single" ? ctx.value === value : ctx.value.includes(value);
|
|
2331
|
+
const handleClick = (e) => {
|
|
2332
|
+
if (isDisabled) return;
|
|
2333
|
+
if (ctx.type === "single") {
|
|
2334
|
+
if (ctx.value !== value) ctx.onValueChange(value);
|
|
2335
|
+
} else {
|
|
2336
|
+
const next = ctx.value.includes(value) ? ctx.value.filter((v) => v !== value) : [...ctx.value, value];
|
|
2337
|
+
ctx.onValueChange(next);
|
|
2338
|
+
}
|
|
2339
|
+
onClick?.(e);
|
|
2340
|
+
};
|
|
2341
|
+
const tabIndex = isActive ? 0 : -1;
|
|
2342
|
+
const sharedButtonProps = {
|
|
2343
|
+
className: cn("relative inline-flex h-8 flex-1 items-center justify-center gap-1.5", "rounded-md px-3 text-sm font-medium whitespace-nowrap", "cursor-pointer", "text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground", "transition-[color,background-color,box-shadow] duration-150 ease-out motion-reduce:transition-none", "data-[state=on]:bg-background data-[state=on]:text-foreground data-[state=on]:shadow-sm", "dark:data-[state=on]:bg-input/30 dark:data-[state=on]:text-foreground dark:data-[state=on]:border dark:data-[state=on]:border-input", "focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50", "disabled:pointer-events-none disabled:opacity-50", "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
|
|
2344
|
+
"data-slot": "toggle-group-item",
|
|
2345
|
+
"data-state": isActive ? "on" : "off",
|
|
2346
|
+
disabled: isDisabled,
|
|
2347
|
+
onClick: handleClick,
|
|
2348
|
+
tabIndex,
|
|
2349
|
+
type: "button"
|
|
2350
|
+
};
|
|
2351
|
+
if (ctx.type === "single") return /* @__PURE__ */ jsx("button", {
|
|
2352
|
+
...sharedButtonProps,
|
|
2353
|
+
role: "radio",
|
|
2354
|
+
"aria-checked": isActive,
|
|
2355
|
+
name: ctx.groupId,
|
|
2356
|
+
...props,
|
|
2357
|
+
children
|
|
2358
|
+
});
|
|
2359
|
+
return /* @__PURE__ */ jsx("button", {
|
|
2360
|
+
...sharedButtonProps,
|
|
2361
|
+
"aria-pressed": isActive,
|
|
2362
|
+
...props,
|
|
2363
|
+
children
|
|
2364
|
+
});
|
|
2365
|
+
};
|
|
2366
|
+
|
|
1416
2367
|
//#endregion
|
|
1417
2368
|
//#region src/components/ui/textarea/textarea.tsx
|
|
1418
2369
|
const Textarea = ({ className, ...props }) => {
|
|
1419
2370
|
return /* @__PURE__ */ jsx("textarea", {
|
|
1420
2371
|
"data-slot": "textarea",
|
|
1421
|
-
className: cn("placeholder:text-muted-foreground/60 dark:bg-input/30 flex field-sizing-content min-h-
|
|
2372
|
+
className: cn("placeholder:text-muted-foreground/60 dark:bg-input/30 flex field-sizing-content min-h-20 w-full touch-manipulation rounded-md border-0 bg-background px-3 py-2 text-base shadow-[var(--shadow-input)] transition-[color,box-shadow] duration-100 ease-out outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "hover:shadow-[var(--shadow-input-hover)]", "focus-visible:shadow-[0_0_0_1px_var(--ring),0_0_0_4px_var(--ring-halo,#0072EF26)]", "aria-invalid:shadow-[0_0_0_1px_var(--destructive),0_0_1px_0_var(--destructive)]", className),
|
|
1422
2373
|
...props
|
|
1423
2374
|
});
|
|
1424
2375
|
};
|
|
@@ -1428,65 +2379,14 @@ const Textarea = ({ className, ...props }) => {
|
|
|
1428
2379
|
const TooltipProvider = Provider;
|
|
1429
2380
|
const Tooltip = Root$6;
|
|
1430
2381
|
const TooltipTrigger = Trigger$5;
|
|
1431
|
-
const TooltipContent = forwardRef(({ className, sideOffset =
|
|
2382
|
+
const TooltipContent = forwardRef(({ className, sideOffset = 6, ...props }, ref) => /* @__PURE__ */ jsx(Portal$4, { children: /* @__PURE__ */ jsx(Content$5, {
|
|
1432
2383
|
ref,
|
|
1433
2384
|
sideOffset,
|
|
1434
|
-
className: cn("z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", className),
|
|
2385
|
+
className: cn("z-50 max-w-xs overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-balance text-primary-foreground animate-in fade-in-0 zoom-in-95 duration-150 ease-out data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:duration-100 data-[state=closed]:ease-in data-[side=bottom]:slide-in-from-top-2 data-[side=bottom]:origin-top data-[side=left]:slide-in-from-right-2 data-[side=left]:origin-right data-[side=right]:slide-in-from-left-2 data-[side=right]:origin-left data-[side=top]:slide-in-from-bottom-2 data-[side=top]:origin-bottom motion-reduce:animate-none", className),
|
|
1435
2386
|
...props
|
|
1436
2387
|
}) }));
|
|
1437
2388
|
TooltipContent.displayName = Content$5.displayName;
|
|
1438
2389
|
|
|
1439
|
-
//#endregion
|
|
1440
|
-
//#region src/components/ui/well/well.tsx
|
|
1441
|
-
const wellVariants = cva("rounded-2xl", {
|
|
1442
|
-
defaultVariants: {
|
|
1443
|
-
gap: "sm",
|
|
1444
|
-
spacing: "default",
|
|
1445
|
-
variant: "inset"
|
|
1446
|
-
},
|
|
1447
|
-
variants: {
|
|
1448
|
-
gap: {
|
|
1449
|
-
default: "space-y-4",
|
|
1450
|
-
lg: "space-y-5",
|
|
1451
|
-
none: "",
|
|
1452
|
-
sm: "space-y-3"
|
|
1453
|
-
},
|
|
1454
|
-
spacing: {
|
|
1455
|
-
default: "p-4",
|
|
1456
|
-
lg: "p-5",
|
|
1457
|
-
none: "p-0",
|
|
1458
|
-
sm: "p-3"
|
|
1459
|
-
},
|
|
1460
|
-
variant: {
|
|
1461
|
-
default: "bg-muted/50",
|
|
1462
|
-
inset: "bg-muted/50 border border-border",
|
|
1463
|
-
outline: "border border-border"
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
});
|
|
1467
|
-
const Well = ({ className, gap, spacing, variant, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
1468
|
-
"data-slot": "well",
|
|
1469
|
-
"data-spacing": spacing ?? "default",
|
|
1470
|
-
className: cn(wellVariants({
|
|
1471
|
-
gap,
|
|
1472
|
-
spacing,
|
|
1473
|
-
variant
|
|
1474
|
-
}), className),
|
|
1475
|
-
...props
|
|
1476
|
-
});
|
|
1477
|
-
const WellReveal = ({ children, className, open }) => /* @__PURE__ */ jsx("div", {
|
|
1478
|
-
className: "grid transition-[grid-template-rows] duration-[220ms] ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:transition-none",
|
|
1479
|
-
style: { gridTemplateRows: open ? "1fr" : "0fr" },
|
|
1480
|
-
"aria-hidden": !open,
|
|
1481
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
1482
|
-
className: "overflow-hidden",
|
|
1483
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
1484
|
-
className: cn("px-0.5 pb-0.5 [&>[data-slot=well]:not([data-spacing=none])]:p-[22px]", className),
|
|
1485
|
-
children
|
|
1486
|
-
})
|
|
1487
|
-
})
|
|
1488
|
-
});
|
|
1489
|
-
|
|
1490
2390
|
//#endregion
|
|
1491
2391
|
//#region src/components/asset-icon/asset-icon.tsx
|
|
1492
2392
|
const aliases = {
|
|
@@ -1697,7 +2597,7 @@ const CodeBlock = forwardRef(({ code, title, language: _language, showLineNumber
|
|
|
1697
2597
|
}),
|
|
1698
2598
|
i < lines.length - 1 && "\n"
|
|
1699
2599
|
]
|
|
1700
|
-
}, `L${i}:${line}`)) : /* @__PURE__ */ jsxs(Fragment, { children: [showTerminalPrompt && /* @__PURE__ */ jsx("span", {
|
|
2600
|
+
}, `L${i}:${line}`)) : /* @__PURE__ */ jsxs(Fragment$1, { children: [showTerminalPrompt && /* @__PURE__ */ jsx("span", {
|
|
1701
2601
|
className: cn("select-none mr-2", s.prompt),
|
|
1702
2602
|
children: "$"
|
|
1703
2603
|
}), code] }) })
|
|
@@ -2299,7 +3199,7 @@ const ToggleCard = ({ accordionKey, title, description, inputProps, allowExpand
|
|
|
2299
3199
|
"aria-hidden": true,
|
|
2300
3200
|
className: "inline-block ml-1.5 size-1.5 rounded-full bg-destructive align-middle"
|
|
2301
3201
|
})]
|
|
2302
|
-
}), Tags && Tags.length > 0 && /* @__PURE__ */ jsx(Fragment, { children: Tags.map((t) => /* @__PURE__ */ jsx("span", {
|
|
3202
|
+
}), Tags && Tags.length > 0 && /* @__PURE__ */ jsx(Fragment$1, { children: Tags.map((t) => /* @__PURE__ */ jsx("span", {
|
|
2303
3203
|
className: "leading-5",
|
|
2304
3204
|
children: t.Tag
|
|
2305
3205
|
}, t.id)) })]
|
|
@@ -2346,6 +3246,37 @@ const ToggleCard = ({ accordionKey, title, description, inputProps, allowExpand
|
|
|
2346
3246
|
});
|
|
2347
3247
|
};
|
|
2348
3248
|
|
|
3249
|
+
//#endregion
|
|
3250
|
+
//#region src/components/icons/animated-icon/animated-icon.tsx
|
|
3251
|
+
const AnimatedIcon = forwardRef(({ children, className, onMouseEnter, onMouseLeave, size = 28, ...props }, ref) => {
|
|
3252
|
+
const controls = useAnimation();
|
|
3253
|
+
const isControlledRef = useRef(false);
|
|
3254
|
+
useImperativeHandle(ref, () => {
|
|
3255
|
+
isControlledRef.current = true;
|
|
3256
|
+
return {
|
|
3257
|
+
startAnimation: () => controls.start("animate"),
|
|
3258
|
+
stopAnimation: () => controls.start("normal")
|
|
3259
|
+
};
|
|
3260
|
+
});
|
|
3261
|
+
const handleMouseEnter = useCallback((e) => {
|
|
3262
|
+
if (isControlledRef.current) onMouseEnter?.(e);
|
|
3263
|
+
else controls.start("animate").catch(() => void 0);
|
|
3264
|
+
}, [controls, onMouseEnter]);
|
|
3265
|
+
const handleMouseLeave = useCallback((e) => {
|
|
3266
|
+
if (isControlledRef.current) onMouseLeave?.(e);
|
|
3267
|
+
else controls.start("normal").catch(() => void 0);
|
|
3268
|
+
}, [controls, onMouseLeave]);
|
|
3269
|
+
return /* @__PURE__ */ jsx("div", {
|
|
3270
|
+
"aria-hidden": "true",
|
|
3271
|
+
className: cn("inline-flex items-center justify-center", className),
|
|
3272
|
+
onMouseEnter: handleMouseEnter,
|
|
3273
|
+
onMouseLeave: handleMouseLeave,
|
|
3274
|
+
...props,
|
|
3275
|
+
children: children(controls, size)
|
|
3276
|
+
});
|
|
3277
|
+
});
|
|
3278
|
+
AnimatedIcon.displayName = "AnimatedIcon";
|
|
3279
|
+
|
|
2349
3280
|
//#endregion
|
|
2350
3281
|
//#region src/components/icons/arrow-up-right/arrow-up-right.tsx
|
|
2351
3282
|
const ArrowUpRightIcon = forwardRef((props, ref) => /* @__PURE__ */ jsx(AnimatedIcon, {
|
|
@@ -3625,6 +4556,55 @@ const RefreshCWIcon = forwardRef((props, ref) => /* @__PURE__ */ jsx(AnimatedIco
|
|
|
3625
4556
|
}));
|
|
3626
4557
|
RefreshCWIcon.displayName = "RefreshCWIcon";
|
|
3627
4558
|
|
|
4559
|
+
//#endregion
|
|
4560
|
+
//#region src/components/icons/search/search.tsx
|
|
4561
|
+
const SearchIcon = forwardRef((props, ref) => /* @__PURE__ */ jsx(AnimatedIcon, {
|
|
4562
|
+
ref,
|
|
4563
|
+
...props,
|
|
4564
|
+
children: (controls, size) => /* @__PURE__ */ jsxs(motion.svg, {
|
|
4565
|
+
animate: controls,
|
|
4566
|
+
fill: "none",
|
|
4567
|
+
height: size,
|
|
4568
|
+
stroke: "currentColor",
|
|
4569
|
+
strokeLinecap: "round",
|
|
4570
|
+
strokeLinejoin: "round",
|
|
4571
|
+
strokeWidth: "2",
|
|
4572
|
+
transition: {
|
|
4573
|
+
bounce: .3,
|
|
4574
|
+
duration: 1
|
|
4575
|
+
},
|
|
4576
|
+
variants: {
|
|
4577
|
+
animate: {
|
|
4578
|
+
x: [
|
|
4579
|
+
0,
|
|
4580
|
+
0,
|
|
4581
|
+
-3,
|
|
4582
|
+
0
|
|
4583
|
+
],
|
|
4584
|
+
y: [
|
|
4585
|
+
0,
|
|
4586
|
+
-4,
|
|
4587
|
+
0,
|
|
4588
|
+
0
|
|
4589
|
+
]
|
|
4590
|
+
},
|
|
4591
|
+
normal: {
|
|
4592
|
+
x: 0,
|
|
4593
|
+
y: 0
|
|
4594
|
+
}
|
|
4595
|
+
},
|
|
4596
|
+
viewBox: "0 0 24 24",
|
|
4597
|
+
width: size,
|
|
4598
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
4599
|
+
children: [/* @__PURE__ */ jsx("circle", {
|
|
4600
|
+
cx: "11",
|
|
4601
|
+
cy: "11",
|
|
4602
|
+
r: "8"
|
|
4603
|
+
}), /* @__PURE__ */ jsx("path", { d: "m21 21-4.3-4.3" })]
|
|
4604
|
+
})
|
|
4605
|
+
}));
|
|
4606
|
+
SearchIcon.displayName = "SearchIcon";
|
|
4607
|
+
|
|
3628
4608
|
//#endregion
|
|
3629
4609
|
//#region src/components/icons/settings/settings.tsx
|
|
3630
4610
|
const SettingsIcon = forwardRef((props, ref) => /* @__PURE__ */ jsx(AnimatedIcon, {
|
|
@@ -3853,5 +4833,5 @@ const UsersIcon = forwardRef((props, ref) => /* @__PURE__ */ jsx(AnimatedIcon, {
|
|
|
3853
4833
|
UsersIcon.displayName = "UsersIcon";
|
|
3854
4834
|
|
|
3855
4835
|
//#endregion
|
|
3856
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AnimatedIcon, ArrowUpRightIcon, AskAIAction, AssetIcon, Avatar, AvatarFallback, AvatarImage, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChartBarIncreasingIcon, CheckIcon, Checkbox, ChevronDownIcon, ChevronRightIcon, ClaudeLogo, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, CopyButton, CopyCheckIcon, CopyIcon, CursorLogo, DangerZone, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DollarSignIcon, DomainList, DownloadIcon, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, FingerprintIcon, HomeIcon, Icon, IconConfigProvider, InfoBanner, Input, Kbd, KeyIcon, Label, LayoutPanelTopIcon, LinkIcon, MetricCard, MoonIcon, OpenAILogo, PageSkeleton, PanelLeftCloseIcon, PanelLeftOpenIcon, PlusIcon, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ProductPageLayout, Progress, RadioGroup, RadioGroupItem, RefreshCWIcon, ScrollArea, ScrollBar, SearchIcon, SearchInput, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SelectableCard, Separator, SettingsIcon, SettingsSection, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, ShieldCheckIcon, Skeleton, Spinner, StatCardSkeleton, StatusBadge, SunIcon, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableSkeleton, Tabs, TabsContent, TabsList, TabsTrigger, TerminalIcon, Textarea, Toaster, ToggleCard, ToggleRow, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UnsavedChangesBar, UsersIcon, VSCodeLogo, WebhooksAction, Well, WellReveal, WindsurfLogo, badgeVariants, buttonVariants, cn, useIconConfig, useUnsavedChanges, wellVariants };
|
|
4836
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AnimatedIcon, ArrowUpRightIcon, AskAIAction, AssetIcon, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChartBarIncreasingIcon, CheckIcon, Checkbox, ChevronDownIcon, ChevronRightIcon, ClaudeLogo, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, CopyButton, CopyCheckIcon, CopyIcon, CursorLogo, CursorPagination, DangerZone, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DollarSignIcon, DomainList, DownloadIcon, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, Field, FingerprintIcon, FlushCardStack, HomeIcon, Icon, IconConfigProvider, InfoBanner, Input, Kbd, KeyIcon, Label, LayoutPanelTopIcon, LinkIcon, MetricCard, MoonIcon, OpenAILogo, PageSkeleton, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PanelLeftCloseIcon, PanelLeftOpenIcon, PlusIcon, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ProductPageLayout, Progress, Radio, RadioField, RadioGroup, RadioGroupItem, RefreshCWIcon, ScrollArea, ScrollBar, SearchIcon, SearchInput, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SelectableCard, Separator, SettingsIcon, SettingsSection, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, ShieldCheckIcon, Skeleton, Slider, Spinner, StatCardSkeleton, StatusBadge, Stepper, SunIcon, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableSkeleton, Tabs, TabsContent, TabsList, TabsTrigger, TerminalIcon, Textarea, Toaster, ToggleCard, ToggleGroup, ToggleGroupItem, ToggleRow, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UnsavedChangesBar, UsersIcon, VSCodeLogo, WebhooksAction, Well, WellReveal, WindsurfLogo, badgeVariants, buttonVariants, cn, toast, useIconConfig, useUnsavedChanges, wellVariants };
|
|
3857
4837
|
//# sourceMappingURL=index.esm.js.map
|