@revealui/presentation 0.2.0 → 0.3.2

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.
Files changed (134) hide show
  1. package/README.md +146 -42
  2. package/dist/Text-BWMs9_wn.js +196 -0
  3. package/dist/Text-BWMs9_wn.js.map +1 -0
  4. package/dist/client.d.ts +3 -1
  5. package/dist/client.d.ts.map +1 -1
  6. package/dist/client.js +89 -2938
  7. package/dist/client.js.map +1 -1
  8. package/dist/components/BuiltWithRevealUI.d.ts +13 -0
  9. package/dist/components/BuiltWithRevealUI.d.ts.map +1 -0
  10. package/dist/components/Button.d.ts +3 -1
  11. package/dist/components/Button.d.ts.map +1 -1
  12. package/dist/components/Card.d.ts +18 -6
  13. package/dist/components/Card.d.ts.map +1 -1
  14. package/dist/components/Checkbox.d.ts +6 -3
  15. package/dist/components/Checkbox.d.ts.map +1 -1
  16. package/dist/components/FormLabel.d.ts +5 -1
  17. package/dist/components/FormLabel.d.ts.map +1 -1
  18. package/dist/components/Input.d.ts +4 -2
  19. package/dist/components/Input.d.ts.map +1 -1
  20. package/dist/components/Label.d.ts +7 -2
  21. package/dist/components/Label.d.ts.map +1 -1
  22. package/dist/components/Pagination.d.ts +12 -23
  23. package/dist/components/Pagination.d.ts.map +1 -1
  24. package/dist/components/Select.d.ts +36 -13
  25. package/dist/components/Select.d.ts.map +1 -1
  26. package/dist/components/Textarea.d.ts +4 -2
  27. package/dist/components/Textarea.d.ts.map +1 -1
  28. package/dist/components/accordion.d.ts.map +1 -1
  29. package/dist/components/alert.d.ts.map +1 -1
  30. package/dist/components/auth-layout.d.ts +7 -2
  31. package/dist/components/auth-layout.d.ts.map +1 -1
  32. package/dist/components/avatar-group.d.ts.map +1 -1
  33. package/dist/components/avatar.d.ts +6 -5
  34. package/dist/components/avatar.d.ts.map +1 -1
  35. package/dist/components/badge.d.ts +5 -5
  36. package/dist/components/badge.d.ts.map +1 -1
  37. package/dist/components/breadcrumb.d.ts.map +1 -1
  38. package/dist/components/button-headless.d.ts +2 -1
  39. package/dist/components/button-headless.d.ts.map +1 -1
  40. package/dist/components/callout.d.ts.map +1 -1
  41. package/dist/components/checkbox-headless.d.ts.map +1 -1
  42. package/dist/components/code-block.d.ts.map +1 -1
  43. package/dist/components/combobox.d.ts.map +1 -1
  44. package/dist/components/dialog.d.ts.map +1 -1
  45. package/dist/components/drawer.d.ts.map +1 -1
  46. package/dist/components/dropdown.d.ts.map +1 -1
  47. package/dist/components/empty-state.d.ts.map +1 -1
  48. package/dist/components/fieldset.d.ts.map +1 -1
  49. package/dist/components/form-field.d.ts +23 -0
  50. package/dist/components/form-field.d.ts.map +1 -0
  51. package/dist/components/heading.d.ts.map +1 -1
  52. package/dist/components/index.d.ts +20 -1
  53. package/dist/components/index.d.ts.map +1 -1
  54. package/dist/components/input-headless.d.ts +5 -3
  55. package/dist/components/input-headless.d.ts.map +1 -1
  56. package/dist/components/kbd.d.ts.map +1 -1
  57. package/dist/components/link.d.ts +3 -2
  58. package/dist/components/link.d.ts.map +1 -1
  59. package/dist/components/listbox.d.ts.map +1 -1
  60. package/dist/components/navbar.d.ts +5 -5
  61. package/dist/components/navbar.d.ts.map +1 -1
  62. package/dist/components/pricing-table.d.ts +23 -0
  63. package/dist/components/pricing-table.d.ts.map +1 -0
  64. package/dist/components/progress.d.ts.map +1 -1
  65. package/dist/components/radio.d.ts.map +1 -1
  66. package/dist/components/rating.d.ts.map +1 -1
  67. package/dist/components/select-headless.d.ts +5 -2
  68. package/dist/components/select-headless.d.ts.map +1 -1
  69. package/dist/components/sidebar-layout.d.ts.map +1 -1
  70. package/dist/components/sidebar.d.ts +5 -5
  71. package/dist/components/sidebar.d.ts.map +1 -1
  72. package/dist/components/skeleton.d.ts.map +1 -1
  73. package/dist/components/slider.d.ts.map +1 -1
  74. package/dist/components/stacked-layout.d.ts.map +1 -1
  75. package/dist/components/stat.d.ts.map +1 -1
  76. package/dist/components/stepper.d.ts.map +1 -1
  77. package/dist/components/switch.d.ts.map +1 -1
  78. package/dist/components/table.d.ts.map +1 -1
  79. package/dist/components/tabs.d.ts.map +1 -1
  80. package/dist/components/text.d.ts.map +1 -1
  81. package/dist/components/textarea-headless.d.ts +5 -2
  82. package/dist/components/textarea-headless.d.ts.map +1 -1
  83. package/dist/components/timeline.d.ts.map +1 -1
  84. package/dist/components/toast.d.ts.map +1 -1
  85. package/dist/components/tooltip.d.ts +7 -5
  86. package/dist/components/tooltip.d.ts.map +1 -1
  87. package/dist/hooks/index.d.ts.map +1 -1
  88. package/dist/hooks/use-click-outside.d.ts.map +1 -1
  89. package/dist/hooks/use-close-context.d.ts.map +1 -1
  90. package/dist/hooks/use-controllable-state.d.ts.map +1 -1
  91. package/dist/hooks/use-data-interactive.d.ts.map +1 -1
  92. package/dist/hooks/use-field-context.d.ts.map +1 -1
  93. package/dist/hooks/use-focus-trap.d.ts.map +1 -1
  94. package/dist/hooks/use-layout-animation.d.ts.map +1 -1
  95. package/dist/hooks/use-popover.d.ts.map +1 -1
  96. package/dist/hooks/use-roving-tabindex.d.ts.map +1 -1
  97. package/dist/hooks/use-toggle.d.ts.map +1 -1
  98. package/dist/hooks/use-transition.d.ts.map +1 -1
  99. package/dist/hooks/use-type-ahead.d.ts.map +1 -1
  100. package/dist/index.d.ts +1 -0
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +67 -85
  103. package/dist/index.js.map +1 -1
  104. package/dist/primitives/Box.d.ts +3 -1
  105. package/dist/primitives/Box.d.ts.map +1 -1
  106. package/dist/primitives/Flex.d.ts +3 -1
  107. package/dist/primitives/Flex.d.ts.map +1 -1
  108. package/dist/primitives/Grid.d.ts +3 -1
  109. package/dist/primitives/Grid.d.ts.map +1 -1
  110. package/dist/primitives/Heading.d.ts +3 -1
  111. package/dist/primitives/Heading.d.ts.map +1 -1
  112. package/dist/primitives/Slot.d.ts +3 -1
  113. package/dist/primitives/Slot.d.ts.map +1 -1
  114. package/dist/primitives/Text.d.ts +3 -1
  115. package/dist/primitives/Text.d.ts.map +1 -1
  116. package/dist/primitives/index.d.ts.map +1 -1
  117. package/dist/server.d.ts +6 -1
  118. package/dist/server.d.ts.map +1 -1
  119. package/dist/server.js +3 -32
  120. package/dist/skeleton-Bb51IWbG.js +520 -0
  121. package/dist/skeleton-Bb51IWbG.js.map +1 -0
  122. package/dist/tokens.css +265 -0
  123. package/dist/tooltip-DZGP3hO_.js +3893 -0
  124. package/dist/tooltip-DZGP3hO_.js.map +1 -0
  125. package/dist/utils/cn.d.ts.map +1 -1
  126. package/dist/utils/index.d.ts.map +1 -1
  127. package/package.json +16 -12
  128. package/dist/Box-DDhRNK02.js +0 -45
  129. package/dist/Box-DDhRNK02.js.map +0 -1
  130. package/dist/Text-BIym7IhD.js +0 -425
  131. package/dist/Text-BIym7IhD.js.map +0 -1
  132. package/dist/server.js.map +0 -1
  133. package/dist/tooltip-oH4lAnkn.js +0 -2277
  134. package/dist/tooltip-oH4lAnkn.js.map +0 -1
@@ -0,0 +1,3893 @@
1
+ import { b as clsx, i as Box, v as cn } from "./skeleton-Bb51IWbG.js";
2
+ import React, { Children, createContext, isValidElement, use, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useReducer, useRef, useState } from "react";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import { createPortal } from "react-dom";
5
+ //#region src/components/accordion.tsx
6
+ function Accordion({ className, children }) {
7
+ return /* @__PURE__ */ jsx("div", {
8
+ className: clsx("divide-y divide-zinc-200 dark:divide-zinc-700", className),
9
+ children
10
+ });
11
+ }
12
+ function AccordionItem({ title, defaultOpen = false, className, children }) {
13
+ const [open, setOpen] = useState(defaultOpen);
14
+ const id = useId();
15
+ return /* @__PURE__ */ jsxs("div", {
16
+ className,
17
+ children: [/* @__PURE__ */ jsxs("button", {
18
+ type: "button",
19
+ id: `${id}-trigger`,
20
+ "aria-expanded": open,
21
+ "aria-controls": `${id}-content`,
22
+ onClick: () => setOpen((prev) => !prev),
23
+ className: "flex w-full items-center justify-between gap-4 py-4 text-left text-sm font-medium text-zinc-950 transition-colors hover:text-zinc-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500 dark:text-white dark:hover:text-zinc-300",
24
+ children: [/* @__PURE__ */ jsx("span", { children: title }), /* @__PURE__ */ jsx("svg", {
25
+ "aria-hidden": "true",
26
+ viewBox: "0 0 16 16",
27
+ fill: "none",
28
+ className: clsx("size-4 shrink-0 text-zinc-400 transition-transform duration-200", open && "rotate-180"),
29
+ children: /* @__PURE__ */ jsx("path", {
30
+ d: "M4 6l4 4 4-4",
31
+ stroke: "currentColor",
32
+ strokeWidth: "1.5",
33
+ strokeLinecap: "round",
34
+ strokeLinejoin: "round"
35
+ })
36
+ })]
37
+ }), open && /* @__PURE__ */ jsx("section", {
38
+ id: `${id}-content`,
39
+ "aria-labelledby": `${id}-trigger`,
40
+ className: "pb-4 text-sm text-zinc-600 dark:text-zinc-400",
41
+ children
42
+ })]
43
+ });
44
+ }
45
+ //#endregion
46
+ //#region src/hooks/use-escape-key.ts
47
+ function useEscapeKey(onEscape, enabled = true) {
48
+ const callbackRef = useRef(onEscape);
49
+ callbackRef.current = onEscape;
50
+ useEffect(() => {
51
+ if (!enabled) return;
52
+ function handleKeyDown(e) {
53
+ if (e.key === "Escape") {
54
+ e.stopPropagation();
55
+ callbackRef.current();
56
+ }
57
+ }
58
+ document.addEventListener("keydown", handleKeyDown);
59
+ return () => document.removeEventListener("keydown", handleKeyDown);
60
+ }, [enabled]);
61
+ }
62
+ //#endregion
63
+ //#region src/hooks/use-focus-trap.ts
64
+ var FOCUSABLE_SELECTOR = [
65
+ "a[href]",
66
+ "button:not([disabled])",
67
+ "input:not([disabled]):not([type=\"hidden\"])",
68
+ "textarea:not([disabled])",
69
+ "select:not([disabled])",
70
+ "[tabindex]:not([tabindex=\"-1\"])"
71
+ ].join(", ");
72
+ function getFocusableElements(container) {
73
+ return Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR));
74
+ }
75
+ function useFocusTrap(containerRef, enabled = true) {
76
+ useEffect(() => {
77
+ if (!enabled) return;
78
+ const container = containerRef.current;
79
+ if (!container) return;
80
+ const previouslyFocused = document.activeElement;
81
+ const focusableElements = getFocusableElements(container);
82
+ if (focusableElements.length > 0) focusableElements[0]?.focus();
83
+ else {
84
+ container.setAttribute("tabindex", "-1");
85
+ container.focus();
86
+ }
87
+ function handleKeyDown(e) {
88
+ if (e.key !== "Tab" || !container) return;
89
+ const focusable = getFocusableElements(container);
90
+ if (focusable.length === 0) {
91
+ e.preventDefault();
92
+ return;
93
+ }
94
+ const first = focusable[0];
95
+ const last = focusable[focusable.length - 1];
96
+ if (e.shiftKey && document.activeElement === first) {
97
+ e.preventDefault();
98
+ last?.focus();
99
+ } else if (!e.shiftKey && document.activeElement === last) {
100
+ e.preventDefault();
101
+ first?.focus();
102
+ }
103
+ }
104
+ document.addEventListener("keydown", handleKeyDown, true);
105
+ return () => {
106
+ document.removeEventListener("keydown", handleKeyDown, true);
107
+ previouslyFocused?.focus();
108
+ };
109
+ }, [containerRef, enabled]);
110
+ }
111
+ //#endregion
112
+ //#region src/hooks/use-scroll-lock.ts
113
+ function useScrollLock(enabled = true) {
114
+ useEffect(() => {
115
+ if (!enabled) return;
116
+ const originalOverflow = document.body.style.overflow;
117
+ const originalPaddingRight = document.body.style.paddingRight;
118
+ const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
119
+ document.body.style.overflow = "hidden";
120
+ if (scrollbarWidth > 0) document.body.style.paddingRight = `${scrollbarWidth}px`;
121
+ return () => {
122
+ document.body.style.overflow = originalOverflow;
123
+ document.body.style.paddingRight = originalPaddingRight;
124
+ };
125
+ }, [enabled]);
126
+ }
127
+ //#endregion
128
+ //#region src/hooks/use-transition.ts
129
+ /**
130
+ * Manages CSS transition lifecycle using data attributes.
131
+ *
132
+ * Enter sequence:
133
+ * 1. Mount with `data-closed` + `data-enter` (element in hidden state)
134
+ * 2. Next frame: remove `data-closed` (CSS transition triggers)
135
+ * 3. On transitionend: remove `data-enter`
136
+ *
137
+ * Leave sequence:
138
+ * 1. Add `data-closed` + `data-leave` (CSS transition to hidden state)
139
+ * 2. On transitionend: unmount
140
+ */
141
+ function useTransition(show) {
142
+ const nodeRef = useRef(null);
143
+ const [, setTick] = useState(0);
144
+ const rerender = useCallback(() => setTick((t) => t + 1), []);
145
+ const phase = useRef(show ? "visible" : "hidden");
146
+ const prevShow = useRef(show);
147
+ const cleanupRef = useRef(null);
148
+ useEffect(() => {
149
+ cleanupRef.current?.();
150
+ cleanupRef.current = null;
151
+ if (show && !prevShow.current) {
152
+ phase.current = "enter-from";
153
+ rerender();
154
+ const frame1 = requestAnimationFrame(() => {
155
+ const frame2 = requestAnimationFrame(() => {
156
+ if (phase.current !== "enter-from") return;
157
+ phase.current = "enter-to";
158
+ rerender();
159
+ const node = nodeRef.current;
160
+ if (!node) {
161
+ phase.current = "visible";
162
+ rerender();
163
+ return;
164
+ }
165
+ let cleaned = false;
166
+ const done = () => {
167
+ if (cleaned) return;
168
+ cleaned = true;
169
+ phase.current = "visible";
170
+ rerender();
171
+ };
172
+ node.addEventListener("transitionend", done, { once: true });
173
+ const fallback = setTimeout(done, 500);
174
+ cleanupRef.current = () => {
175
+ cleaned = true;
176
+ node.removeEventListener("transitionend", done);
177
+ clearTimeout(fallback);
178
+ };
179
+ });
180
+ cleanupRef.current = () => cancelAnimationFrame(frame2);
181
+ });
182
+ cleanupRef.current = () => cancelAnimationFrame(frame1);
183
+ } else if (!show && prevShow.current) {
184
+ phase.current = "leave";
185
+ rerender();
186
+ const node = nodeRef.current;
187
+ if (!node) {
188
+ phase.current = "hidden";
189
+ rerender();
190
+ prevShow.current = show;
191
+ return;
192
+ }
193
+ let cleaned = false;
194
+ const done = () => {
195
+ if (cleaned) return;
196
+ cleaned = true;
197
+ phase.current = "hidden";
198
+ rerender();
199
+ };
200
+ node.addEventListener("transitionend", done, { once: true });
201
+ const fallback = setTimeout(done, 500);
202
+ cleanupRef.current = () => {
203
+ cleaned = true;
204
+ node.removeEventListener("transitionend", done);
205
+ clearTimeout(fallback);
206
+ };
207
+ }
208
+ prevShow.current = show;
209
+ }, [show, rerender]);
210
+ useEffect(() => {
211
+ return () => {
212
+ cleanupRef.current?.();
213
+ };
214
+ }, []);
215
+ const p = phase.current;
216
+ return {
217
+ mounted: p !== "hidden",
218
+ nodeRef,
219
+ transitionProps: {
220
+ "data-closed": p === "enter-from" || p === "leave" || p === "hidden" ? "" : void 0,
221
+ "data-enter": p === "enter-from" || p === "enter-to" ? "" : void 0,
222
+ "data-leave": p === "leave" ? "" : void 0,
223
+ "data-transition": p === "enter-from" || p === "enter-to" || p === "leave" ? "" : void 0
224
+ }
225
+ };
226
+ }
227
+ //#endregion
228
+ //#region src/hooks/use-data-interactive.ts
229
+ function useDataInteractive({ disabled = false } = {}) {
230
+ const [hover, setHover] = useState(false);
231
+ const [focus, setFocus] = useState(false);
232
+ const [active, setActive] = useState(false);
233
+ const onPointerEnter = useCallback(() => {
234
+ if (!disabled) setHover(true);
235
+ }, [disabled]);
236
+ const onPointerLeave = useCallback(() => {
237
+ setHover(false);
238
+ setActive(false);
239
+ }, []);
240
+ const onPointerDown = useCallback(() => {
241
+ if (!disabled) setActive(true);
242
+ }, [disabled]);
243
+ const onPointerUp = useCallback(() => {
244
+ setActive(false);
245
+ }, []);
246
+ const onFocus = useCallback((e) => {
247
+ if (!disabled && e.currentTarget.matches(":focus-visible")) setFocus(true);
248
+ }, [disabled]);
249
+ const onBlur = useCallback(() => {
250
+ setFocus(false);
251
+ }, []);
252
+ return {
253
+ "data-hover": hover ? "" : void 0,
254
+ "data-focus": focus ? "" : void 0,
255
+ "data-active": active ? "" : void 0,
256
+ "data-disabled": disabled ? "" : void 0,
257
+ onPointerEnter,
258
+ onPointerLeave,
259
+ onPointerDown,
260
+ onPointerUp,
261
+ onFocus,
262
+ onBlur
263
+ };
264
+ }
265
+ //#endregion
266
+ //#region src/components/link.tsx
267
+ function Link({ ref, ...props }) {
268
+ const interactiveProps = useDataInteractive();
269
+ return /* @__PURE__ */ jsx("a", {
270
+ ...props,
271
+ ...interactiveProps,
272
+ ref
273
+ });
274
+ }
275
+ //#endregion
276
+ //#region src/components/text.tsx
277
+ function Text({ className, ...props }) {
278
+ return /* @__PURE__ */ jsx("p", {
279
+ "data-slot": "text",
280
+ ...props,
281
+ className: clsx(className, "text-base/6 text-zinc-500 sm:text-sm/6 dark:text-zinc-400")
282
+ });
283
+ }
284
+ //#endregion
285
+ //#region src/components/alert.tsx
286
+ var sizes$1 = {
287
+ xs: "sm:max-w-xs",
288
+ sm: "sm:max-w-sm",
289
+ md: "sm:max-w-md",
290
+ lg: "sm:max-w-lg",
291
+ xl: "sm:max-w-xl",
292
+ "2xl": "sm:max-w-2xl",
293
+ "3xl": "sm:max-w-3xl",
294
+ "4xl": "sm:max-w-4xl",
295
+ "5xl": "sm:max-w-5xl"
296
+ };
297
+ function Alert({ size = "md", className, children, open, onClose }) {
298
+ const panelRef = useRef(null);
299
+ const titleId = useId();
300
+ const backdrop = useTransition(open);
301
+ const panel = useTransition(open);
302
+ useScrollLock(open);
303
+ useFocusTrap(panelRef, open);
304
+ useEscapeKey(onClose, open);
305
+ if (!(backdrop.mounted || panel.mounted)) return null;
306
+ return createPortal(/* @__PURE__ */ jsxs("div", {
307
+ role: "alertdialog",
308
+ "aria-modal": "true",
309
+ "aria-labelledby": titleId,
310
+ children: [backdrop.mounted && /* @__PURE__ */ jsx("button", {
311
+ type: "button",
312
+ "aria-label": "Close alert",
313
+ ref: backdrop.nodeRef,
314
+ ...backdrop.transitionProps,
315
+ onClick: onClose,
316
+ className: "fixed inset-0 flex w-screen justify-center overflow-y-auto bg-zinc-950/15 px-2 py-2 transition duration-100 focus:outline-0 data-closed:opacity-0 data-enter:ease-out data-leave:ease-in sm:px-6 sm:py-8 lg:px-8 lg:py-16 dark:bg-zinc-950/50"
317
+ }), panel.mounted && /* @__PURE__ */ jsx("div", {
318
+ className: "fixed inset-0 w-screen overflow-y-auto pt-6 sm:pt-0",
319
+ children: /* @__PURE__ */ jsx("div", {
320
+ className: "grid min-h-full grid-rows-[1fr_auto_1fr] justify-items-center p-8 sm:grid-rows-[1fr_auto_3fr] sm:p-4",
321
+ children: /* @__PURE__ */ jsx("div", {
322
+ ref: (node) => {
323
+ panelRef.current = node;
324
+ panel.nodeRef.current = node;
325
+ },
326
+ ...panel.transitionProps,
327
+ className: clsx(className, sizes$1[size], "row-start-2 w-full rounded-2xl bg-white p-8 shadow-lg ring-1 ring-zinc-950/10 sm:rounded-2xl sm:p-6 dark:bg-zinc-900 dark:ring-white/10 forced-colors:outline", "transition duration-100 will-change-transform data-closed:opacity-0 data-enter:ease-out data-closed:data-enter:scale-95 data-leave:ease-in"),
328
+ children
329
+ })
330
+ })
331
+ })]
332
+ }), document.body);
333
+ }
334
+ function AlertTitle({ className, ...props }) {
335
+ return /* @__PURE__ */ jsx("h2", {
336
+ ...props,
337
+ className: clsx(className, "text-center text-base/6 font-semibold text-balance text-zinc-950 sm:text-left sm:text-sm/6 sm:text-wrap dark:text-white")
338
+ });
339
+ }
340
+ function AlertDescription({ className, ...props }) {
341
+ return /* @__PURE__ */ jsx(Text, {
342
+ ...props,
343
+ className: clsx(className, "mt-2 text-center text-pretty sm:text-left")
344
+ });
345
+ }
346
+ function AlertBody({ className, ...props }) {
347
+ return /* @__PURE__ */ jsx("div", {
348
+ ...props,
349
+ className: clsx(className, "mt-4")
350
+ });
351
+ }
352
+ function AlertActions({ className, ...props }) {
353
+ return /* @__PURE__ */ jsx("div", {
354
+ ...props,
355
+ className: clsx(className, "mt-6 flex flex-col-reverse items-center justify-end gap-3 *:w-full sm:mt-4 sm:flex-row sm:*:w-auto")
356
+ });
357
+ }
358
+ //#endregion
359
+ //#region src/components/button-headless.tsx
360
+ var styles = {
361
+ base: [
362
+ "relative isolate inline-flex items-baseline justify-center gap-x-2 rounded-lg border text-base/6 font-semibold",
363
+ "px-[calc(--spacing(3.5)-1px)] py-[calc(--spacing(2.5)-1px)] sm:px-[calc(--spacing(3)-1px)] sm:py-[calc(--spacing(1.5)-1px)] sm:text-sm/6",
364
+ "focus:not-data-focus:outline-hidden data-focus:outline-2 data-focus:outline-offset-2 data-focus:outline-blue-500",
365
+ "data-disabled:opacity-50",
366
+ "*:data-[slot=icon]:-mx-0.5 *:data-[slot=icon]:my-0.5 *:data-[slot=icon]:size-5 *:data-[slot=icon]:shrink-0 *:data-[slot=icon]:self-center *:data-[slot=icon]:text-(--btn-icon) sm:*:data-[slot=icon]:my-1 sm:*:data-[slot=icon]:size-4 forced-colors:[--btn-icon:ButtonText] forced-colors:data-hover:[--btn-icon:ButtonText]"
367
+ ],
368
+ solid: [
369
+ "border-transparent bg-(--btn-border)",
370
+ "dark:bg-(--btn-bg)",
371
+ "before:absolute before:inset-0 before:-z-10 before:rounded-[calc(var(--radius-lg)-1px)] before:bg-(--btn-bg)",
372
+ "before:shadow-sm",
373
+ "dark:before:hidden",
374
+ "dark:border-white/5",
375
+ "after:absolute after:inset-0 after:-z-10 after:rounded-[calc(var(--radius-lg)-1px)]",
376
+ "after:shadow-[inset_0_1px_--theme(--color-white/15%)]",
377
+ "data-active:after:bg-(--btn-hover-overlay) data-hover:after:bg-(--btn-hover-overlay)",
378
+ "dark:after:-inset-px dark:after:rounded-lg",
379
+ "data-disabled:before:shadow-none data-disabled:after:shadow-none"
380
+ ],
381
+ outline: [
382
+ "border-zinc-950/10 text-zinc-950 data-active:bg-zinc-950/2.5 data-hover:bg-zinc-950/2.5",
383
+ "dark:border-white/15 dark:text-white dark:[--btn-bg:transparent] dark:data-active:bg-white/5 dark:data-hover:bg-white/5",
384
+ "[--btn-icon:var(--color-zinc-500)] data-active:[--btn-icon:var(--color-zinc-700)] data-hover:[--btn-icon:var(--color-zinc-700)] dark:data-active:[--btn-icon:var(--color-zinc-400)] dark:data-hover:[--btn-icon:var(--color-zinc-400)]"
385
+ ],
386
+ plain: [
387
+ "border-transparent text-zinc-950 data-active:bg-zinc-950/5 data-hover:bg-zinc-950/5",
388
+ "dark:text-white dark:data-active:bg-white/10 dark:data-hover:bg-white/10",
389
+ "[--btn-icon:var(--color-zinc-500)] data-active:[--btn-icon:var(--color-zinc-700)] data-hover:[--btn-icon:var(--color-zinc-700)] dark:[--btn-icon:var(--color-zinc-500)] dark:data-active:[--btn-icon:var(--color-zinc-400)] dark:data-hover:[--btn-icon:var(--color-zinc-400)]"
390
+ ],
391
+ colors: {
392
+ "dark/zinc": [
393
+ "text-white [--btn-bg:var(--color-zinc-900)] [--btn-border:var(--color-zinc-950)]/90 [--btn-hover-overlay:var(--color-white)]/10",
394
+ "dark:text-white dark:[--btn-bg:var(--color-zinc-600)] dark:[--btn-hover-overlay:var(--color-white)]/5",
395
+ "[--btn-icon:var(--color-zinc-400)] data-active:[--btn-icon:var(--color-zinc-300)] data-hover:[--btn-icon:var(--color-zinc-300)]"
396
+ ],
397
+ light: [
398
+ "text-zinc-950 [--btn-bg:white] [--btn-border:var(--color-zinc-950)]/10 [--btn-hover-overlay:var(--color-zinc-950)]/2.5 data-active:[--btn-border:var(--color-zinc-950)]/15 data-hover:[--btn-border:var(--color-zinc-950)]/15",
399
+ "dark:text-white dark:[--btn-hover-overlay:var(--color-white)]/5 dark:[--btn-bg:var(--color-zinc-800)]",
400
+ "[--btn-icon:var(--color-zinc-500)] data-active:[--btn-icon:var(--color-zinc-700)] data-hover:[--btn-icon:var(--color-zinc-700)] dark:[--btn-icon:var(--color-zinc-500)] dark:data-active:[--btn-icon:var(--color-zinc-400)] dark:data-hover:[--btn-icon:var(--color-zinc-400)]"
401
+ ],
402
+ "dark/white": [
403
+ "text-white [--btn-bg:var(--color-zinc-900)] [--btn-border:var(--color-zinc-950)]/90 [--btn-hover-overlay:var(--color-white)]/10",
404
+ "dark:text-zinc-950 dark:[--btn-bg:white] dark:[--btn-hover-overlay:var(--color-zinc-950)]/5",
405
+ "[--btn-icon:var(--color-zinc-400)] data-active:[--btn-icon:var(--color-zinc-300)] data-hover:[--btn-icon:var(--color-zinc-300)] dark:[--btn-icon:var(--color-zinc-500)] dark:data-active:[--btn-icon:var(--color-zinc-400)] dark:data-hover:[--btn-icon:var(--color-zinc-400)]"
406
+ ],
407
+ dark: [
408
+ "text-white [--btn-bg:var(--color-zinc-900)] [--btn-border:var(--color-zinc-950)]/90 [--btn-hover-overlay:var(--color-white)]/10",
409
+ "dark:[--btn-hover-overlay:var(--color-white)]/5 dark:[--btn-bg:var(--color-zinc-800)]",
410
+ "[--btn-icon:var(--color-zinc-400)] data-active:[--btn-icon:var(--color-zinc-300)] data-hover:[--btn-icon:var(--color-zinc-300)]"
411
+ ],
412
+ white: [
413
+ "text-zinc-950 [--btn-bg:white] [--btn-border:var(--color-zinc-950)]/10 [--btn-hover-overlay:var(--color-zinc-950)]/2.5 data-active:[--btn-border:var(--color-zinc-950)]/15 data-hover:[--btn-border:var(--color-zinc-950)]/15",
414
+ "dark:[--btn-hover-overlay:var(--color-zinc-950)]/5",
415
+ "[--btn-icon:var(--color-zinc-400)] data-active:[--btn-icon:var(--color-zinc-500)] data-hover:[--btn-icon:var(--color-zinc-500)]"
416
+ ],
417
+ zinc: [
418
+ "text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-zinc-600)] [--btn-border:var(--color-zinc-700)]/90",
419
+ "dark:[--btn-hover-overlay:var(--color-white)]/5",
420
+ "[--btn-icon:var(--color-zinc-400)] data-active:[--btn-icon:var(--color-zinc-300)] data-hover:[--btn-icon:var(--color-zinc-300)]"
421
+ ],
422
+ indigo: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-indigo-500)] [--btn-border:var(--color-indigo-600)]/90", "[--btn-icon:var(--color-indigo-300)] data-active:[--btn-icon:var(--color-indigo-200)] data-hover:[--btn-icon:var(--color-indigo-200)]"],
423
+ cyan: ["text-cyan-950 [--btn-bg:var(--color-cyan-300)] [--btn-border:var(--color-cyan-400)]/80 [--btn-hover-overlay:var(--color-white)]/25", "[--btn-icon:var(--color-cyan-500)]"],
424
+ red: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-red-600)] [--btn-border:var(--color-red-700)]/90", "[--btn-icon:var(--color-red-300)] data-active:[--btn-icon:var(--color-red-200)] data-hover:[--btn-icon:var(--color-red-200)]"],
425
+ orange: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-orange-500)] [--btn-border:var(--color-orange-600)]/90", "[--btn-icon:var(--color-orange-300)] data-active:[--btn-icon:var(--color-orange-200)] data-hover:[--btn-icon:var(--color-orange-200)]"],
426
+ amber: ["text-amber-950 [--btn-hover-overlay:var(--color-white)]/25 [--btn-bg:var(--color-amber-400)] [--btn-border:var(--color-amber-500)]/80", "[--btn-icon:var(--color-amber-600)]"],
427
+ yellow: ["text-yellow-950 [--btn-hover-overlay:var(--color-white)]/25 [--btn-bg:var(--color-yellow-300)] [--btn-border:var(--color-yellow-400)]/80", "[--btn-icon:var(--color-yellow-600)] data-active:[--btn-icon:var(--color-yellow-700)] data-hover:[--btn-icon:var(--color-yellow-700)]"],
428
+ lime: ["text-lime-950 [--btn-hover-overlay:var(--color-white)]/25 [--btn-bg:var(--color-lime-300)] [--btn-border:var(--color-lime-400)]/80", "[--btn-icon:var(--color-lime-600)] data-active:[--btn-icon:var(--color-lime-700)] data-hover:[--btn-icon:var(--color-lime-700)]"],
429
+ green: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-green-600)] [--btn-border:var(--color-green-700)]/90", "[--btn-icon:var(--color-white)]/60 data-active:[--btn-icon:var(--color-white)]/80 data-hover:[--btn-icon:var(--color-white)]/80"],
430
+ emerald: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-emerald-600)] [--btn-border:var(--color-emerald-700)]/90", "[--btn-icon:var(--color-white)]/60 data-active:[--btn-icon:var(--color-white)]/80 data-hover:[--btn-icon:var(--color-white)]/80"],
431
+ teal: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-teal-600)] [--btn-border:var(--color-teal-700)]/90", "[--btn-icon:var(--color-white)]/60 data-active:[--btn-icon:var(--color-white)]/80 data-hover:[--btn-icon:var(--color-white)]/80"],
432
+ sky: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-sky-500)] [--btn-border:var(--color-sky-600)]/80", "[--btn-icon:var(--color-white)]/60 data-active:[--btn-icon:var(--color-white)]/80 data-hover:[--btn-icon:var(--color-white)]/80"],
433
+ blue: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-blue-600)] [--btn-border:var(--color-blue-700)]/90", "[--btn-icon:var(--color-blue-400)] data-active:[--btn-icon:var(--color-blue-300)] data-hover:[--btn-icon:var(--color-blue-300)]"],
434
+ violet: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-violet-500)] [--btn-border:var(--color-violet-600)]/90", "[--btn-icon:var(--color-violet-300)] data-active:[--btn-icon:var(--color-violet-200)] data-hover:[--btn-icon:var(--color-violet-200)]"],
435
+ purple: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-purple-500)] [--btn-border:var(--color-purple-600)]/90", "[--btn-icon:var(--color-purple-300)] data-active:[--btn-icon:var(--color-purple-200)] data-hover:[--btn-icon:var(--color-purple-200)]"],
436
+ fuchsia: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-fuchsia-500)] [--btn-border:var(--color-fuchsia-600)]/90", "[--btn-icon:var(--color-fuchsia-300)] data-active:[--btn-icon:var(--color-fuchsia-200)] data-hover:[--btn-icon:var(--color-fuchsia-200)]"],
437
+ pink: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-pink-500)] [--btn-border:var(--color-pink-600)]/90", "[--btn-icon:var(--color-pink-300)] data-active:[--btn-icon:var(--color-pink-200)] data-hover:[--btn-icon:var(--color-pink-200)]"],
438
+ rose: ["text-white [--btn-hover-overlay:var(--color-white)]/10 [--btn-bg:var(--color-rose-500)] [--btn-border:var(--color-rose-600)]/90", "[--btn-icon:var(--color-rose-300)] data-active:[--btn-icon:var(--color-rose-200)] data-hover:[--btn-icon:var(--color-rose-200)]"]
439
+ }
440
+ };
441
+ function Button({ color, outline, plain, className, children, ref, ...props }) {
442
+ const interactiveProps = useDataInteractive({ disabled: ("disabled" in props ? props.disabled : false) ?? false });
443
+ const classes = clsx(className, styles.base, outline ? styles.outline : plain ? styles.plain : clsx(styles.solid, styles.colors[color ?? "dark/zinc"]));
444
+ return typeof props.href === "string" ? /* @__PURE__ */ jsx(Link, {
445
+ ...props,
446
+ className: classes,
447
+ ref,
448
+ children: /* @__PURE__ */ jsx(TouchTarget, { children })
449
+ }) : /* @__PURE__ */ jsx("button", {
450
+ type: "button",
451
+ ...props,
452
+ ...interactiveProps,
453
+ className: clsx(classes, "cursor-default"),
454
+ ref,
455
+ children: /* @__PURE__ */ jsx(TouchTarget, { children })
456
+ });
457
+ }
458
+ /**
459
+ * Expand the hit area to at least 44x44px on touch devices
460
+ */
461
+ function TouchTarget({ children }) {
462
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
463
+ className: "absolute top-1/2 left-1/2 size-[max(100%,2.75rem)] -translate-x-1/2 -translate-y-1/2 pointer-fine:hidden",
464
+ "aria-hidden": "true"
465
+ }), children] });
466
+ }
467
+ //#endregion
468
+ //#region src/components/avatar.tsx
469
+ function Avatar({ src = null, square = false, initials, alt = "", className, ...props }) {
470
+ const title = alt && alt.trim().length > 0 ? alt.trim() : "Avatar";
471
+ return /* @__PURE__ */ jsxs("span", {
472
+ "data-slot": "avatar",
473
+ ...props,
474
+ className: clsx(className, "inline-grid shrink-0 align-middle [--avatar-radius:20%] *:col-start-1 *:row-start-1", "outline -outline-offset-1 outline-black/10 dark:outline-white/10", square ? "rounded-(--avatar-radius) *:rounded-(--avatar-radius)" : "rounded-full *:rounded-full"),
475
+ children: [initials && /* @__PURE__ */ jsxs("svg", {
476
+ className: "size-full fill-current p-[5%] text-[48px] font-medium uppercase select-none",
477
+ viewBox: "0 0 100 100",
478
+ "aria-hidden": alt && alt.trim().length > 0 ? void 0 : "true",
479
+ children: [/* @__PURE__ */ jsx("title", { children: title }), /* @__PURE__ */ jsx("text", {
480
+ x: "50%",
481
+ y: "50%",
482
+ alignmentBaseline: "middle",
483
+ dominantBaseline: "middle",
484
+ textAnchor: "middle",
485
+ dy: ".125em",
486
+ children: initials
487
+ })]
488
+ }), src && /* @__PURE__ */ jsx("img", {
489
+ className: "size-full",
490
+ src,
491
+ alt
492
+ })]
493
+ });
494
+ }
495
+ function AvatarButton({ src, square = false, initials, alt, className, ref, ...props }) {
496
+ const interactiveProps = useDataInteractive({ disabled: ("disabled" in props ? props.disabled : false) ?? false });
497
+ const classes = clsx(className, square ? "rounded-[20%]" : "rounded-full", "relative inline-grid focus:not-data-focus:outline-hidden data-focus:outline-2 data-focus:outline-offset-2 data-focus:outline-blue-500");
498
+ return typeof props.href === "string" ? /* @__PURE__ */ jsx(Link, {
499
+ ...props,
500
+ className: classes,
501
+ ref,
502
+ children: /* @__PURE__ */ jsx(TouchTarget, { children: /* @__PURE__ */ jsx(Avatar, {
503
+ src,
504
+ square,
505
+ initials,
506
+ alt
507
+ }) })
508
+ }) : /* @__PURE__ */ jsx("button", {
509
+ type: "button",
510
+ ...props,
511
+ ...interactiveProps,
512
+ className: classes,
513
+ ref,
514
+ children: /* @__PURE__ */ jsx(TouchTarget, { children: /* @__PURE__ */ jsx(Avatar, {
515
+ src,
516
+ square,
517
+ initials,
518
+ alt
519
+ }) })
520
+ });
521
+ }
522
+ //#endregion
523
+ //#region src/components/avatar-group.tsx
524
+ function AvatarGroup({ items, max = 5, size = "md", className }) {
525
+ const sizeClasses = {
526
+ xs: "size-6",
527
+ sm: "size-8",
528
+ md: "size-10",
529
+ lg: "size-12"
530
+ };
531
+ const overlapClass = {
532
+ xs: "-ml-1.5",
533
+ sm: "-ml-2",
534
+ md: "-ml-3",
535
+ lg: "-ml-4"
536
+ };
537
+ const visible = items.slice(0, max);
538
+ const overflow = items.length - max;
539
+ return /* @__PURE__ */ jsxs("div", {
540
+ className: clsx("flex items-center", className),
541
+ children: [visible.map((item, i) => {
542
+ return /* @__PURE__ */ jsx("div", {
543
+ className: clsx("ring-2 ring-white dark:ring-zinc-900", sizeClasses[size], i > 0 && overlapClass[size], "rounded-full"),
544
+ children: /* @__PURE__ */ jsx(Avatar, {
545
+ src: item.src,
546
+ initials: item.initials,
547
+ alt: item.alt ?? "",
548
+ className: "size-full"
549
+ })
550
+ }, i);
551
+ }), overflow > 0 && /* @__PURE__ */ jsxs("div", {
552
+ className: clsx(overlapClass[size], sizeClasses[size], "flex items-center justify-center rounded-full bg-zinc-200 text-xs font-medium text-zinc-600 ring-2 ring-white dark:bg-zinc-700 dark:text-zinc-300 dark:ring-zinc-900"),
553
+ role: "img",
554
+ "aria-label": `${overflow} more`,
555
+ children: ["+", overflow]
556
+ })]
557
+ });
558
+ }
559
+ //#endregion
560
+ //#region src/components/badge.tsx
561
+ var colors$2 = {
562
+ red: "bg-red-500/15 text-red-700 group-data-hover:bg-red-500/25 dark:bg-red-500/10 dark:text-red-400 dark:group-data-hover:bg-red-500/20",
563
+ orange: "bg-orange-500/15 text-orange-700 group-data-hover:bg-orange-500/25 dark:bg-orange-500/10 dark:text-orange-400 dark:group-data-hover:bg-orange-500/20",
564
+ amber: "bg-amber-400/20 text-amber-700 group-data-hover:bg-amber-400/30 dark:bg-amber-400/10 dark:text-amber-400 dark:group-data-hover:bg-amber-400/15",
565
+ yellow: "bg-yellow-400/20 text-yellow-700 group-data-hover:bg-yellow-400/30 dark:bg-yellow-400/10 dark:text-yellow-300 dark:group-data-hover:bg-yellow-400/15",
566
+ lime: "bg-lime-400/20 text-lime-700 group-data-hover:bg-lime-400/30 dark:bg-lime-400/10 dark:text-lime-300 dark:group-data-hover:bg-lime-400/15",
567
+ green: "bg-green-500/15 text-green-700 group-data-hover:bg-green-500/25 dark:bg-green-500/10 dark:text-green-400 dark:group-data-hover:bg-green-500/20",
568
+ emerald: "bg-emerald-500/15 text-emerald-700 group-data-hover:bg-emerald-500/25 dark:bg-emerald-500/10 dark:text-emerald-400 dark:group-data-hover:bg-emerald-500/20",
569
+ teal: "bg-teal-500/15 text-teal-700 group-data-hover:bg-teal-500/25 dark:bg-teal-500/10 dark:text-teal-300 dark:group-data-hover:bg-teal-500/20",
570
+ cyan: "bg-cyan-400/20 text-cyan-700 group-data-hover:bg-cyan-400/30 dark:bg-cyan-400/10 dark:text-cyan-300 dark:group-data-hover:bg-cyan-400/15",
571
+ sky: "bg-sky-500/15 text-sky-700 group-data-hover:bg-sky-500/25 dark:bg-sky-500/10 dark:text-sky-300 dark:group-data-hover:bg-sky-500/20",
572
+ blue: "bg-blue-500/15 text-blue-700 group-data-hover:bg-blue-500/25 dark:text-blue-400 dark:group-data-hover:bg-blue-500/25",
573
+ indigo: "bg-indigo-500/15 text-indigo-700 group-data-hover:bg-indigo-500/25 dark:text-indigo-400 dark:group-data-hover:bg-indigo-500/20",
574
+ violet: "bg-violet-500/15 text-violet-700 group-data-hover:bg-violet-500/25 dark:text-violet-400 dark:group-data-hover:bg-violet-500/20",
575
+ purple: "bg-purple-500/15 text-purple-700 group-data-hover:bg-purple-500/25 dark:text-purple-400 dark:group-data-hover:bg-purple-500/20",
576
+ fuchsia: "bg-fuchsia-400/15 text-fuchsia-700 group-data-hover:bg-fuchsia-400/25 dark:bg-fuchsia-400/10 dark:text-fuchsia-400 dark:group-data-hover:bg-fuchsia-400/20",
577
+ pink: "bg-pink-400/15 text-pink-700 group-data-hover:bg-pink-400/25 dark:bg-pink-400/10 dark:text-pink-400 dark:group-data-hover:bg-pink-400/20",
578
+ rose: "bg-rose-400/15 text-rose-700 group-data-hover:bg-rose-400/25 dark:bg-rose-400/10 dark:text-rose-400 dark:group-data-hover:bg-rose-400/20",
579
+ zinc: "bg-zinc-600/10 text-zinc-700 group-data-hover:bg-zinc-600/20 dark:bg-white/5 dark:text-zinc-400 dark:group-data-hover:bg-white/10"
580
+ };
581
+ function Badge({ color = "zinc", className, ...props }) {
582
+ return /* @__PURE__ */ jsx("span", {
583
+ ...props,
584
+ className: clsx(className, "inline-flex items-center gap-x-1.5 rounded-md px-1.5 py-0.5 text-sm/5 font-medium sm:text-xs/5 forced-colors:outline", colors$2[color])
585
+ });
586
+ }
587
+ function BadgeButton({ color = "zinc", className, children, ref, ...props }) {
588
+ const interactiveProps = useDataInteractive({ disabled: ("disabled" in props ? props.disabled : false) ?? false });
589
+ const classes = clsx(className, "group relative inline-flex rounded-md focus:not-data-focus:outline-hidden data-focus:outline-2 data-focus:outline-offset-2 data-focus:outline-blue-500");
590
+ return typeof props.href === "string" ? /* @__PURE__ */ jsx(Link, {
591
+ ...props,
592
+ className: classes,
593
+ ref,
594
+ children: /* @__PURE__ */ jsx(TouchTarget, { children: /* @__PURE__ */ jsx(Badge, {
595
+ color,
596
+ children
597
+ }) })
598
+ }) : /* @__PURE__ */ jsx("button", {
599
+ type: "button",
600
+ ...props,
601
+ ...interactiveProps,
602
+ className: classes,
603
+ ref,
604
+ children: /* @__PURE__ */ jsx(TouchTarget, { children: /* @__PURE__ */ jsx(Badge, {
605
+ color,
606
+ children
607
+ }) })
608
+ });
609
+ }
610
+ //#endregion
611
+ //#region src/components/Checkbox.tsx
612
+ var CheckboxContext = React.createContext(null);
613
+ function Checkbox$1({ checked, defaultChecked, disabled, onCheckedChange, className, ref, ...props }) {
614
+ const [internalChecked, setInternalChecked] = React.useState(defaultChecked ?? false);
615
+ const handleChange = (e) => {
616
+ if (disabled) return;
617
+ const newChecked = e.target.checked;
618
+ setInternalChecked(newChecked);
619
+ onCheckedChange?.(newChecked);
620
+ };
621
+ React.useEffect(() => {
622
+ if (checked !== void 0) setInternalChecked(checked);
623
+ }, [checked]);
624
+ return /* @__PURE__ */ jsx(CheckboxContext.Provider, {
625
+ value: {
626
+ state: internalChecked,
627
+ disabled,
628
+ onCheckedChange
629
+ },
630
+ children: /* @__PURE__ */ jsx("input", {
631
+ type: "checkbox",
632
+ disabled,
633
+ checked: checked !== void 0 ? checked : internalChecked === "indeterminate" ? false : internalChecked,
634
+ ref: (el) => {
635
+ if (el) el.indeterminate = internalChecked === "indeterminate";
636
+ if (ref) if (typeof ref === "function") ref(el);
637
+ else ref.current = el;
638
+ },
639
+ onChange: handleChange,
640
+ className: cn("peer h-4 w-4 shrink-0 rounded border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground", className),
641
+ "data-state": internalChecked === "indeterminate" ? "indeterminate" : internalChecked ? "checked" : "unchecked",
642
+ ...props
643
+ })
644
+ });
645
+ }
646
+ function CheckboxIndicator({ className, ref, ...props }) {
647
+ const context = React.use(CheckboxContext);
648
+ if (!context) throw new Error("CheckboxIndicator must be used within a Checkbox");
649
+ return /* @__PURE__ */ jsxs("span", {
650
+ "data-state": context.state === "indeterminate" ? "indeterminate" : context.state ? "checked" : "unchecked",
651
+ ref,
652
+ className: cn("flex items-center justify-center text-current", className),
653
+ ...props,
654
+ children: [context.state === true && "✔", context.state === "indeterminate" && "−"]
655
+ });
656
+ }
657
+ //#endregion
658
+ //#region src/components/callout.tsx
659
+ var variantStyles = {
660
+ info: {
661
+ wrapper: "bg-blue-50 ring-blue-200 dark:bg-blue-950/30 dark:ring-blue-800",
662
+ icon: "text-blue-600 dark:text-blue-400",
663
+ iconChar: "i"
664
+ },
665
+ warning: {
666
+ wrapper: "bg-amber-50 ring-amber-200 dark:bg-amber-950/30 dark:ring-amber-800",
667
+ icon: "text-amber-600 dark:text-amber-400",
668
+ iconChar: "!"
669
+ },
670
+ error: {
671
+ wrapper: "bg-red-50 ring-red-200 dark:bg-red-950/30 dark:ring-red-800",
672
+ icon: "text-red-600 dark:text-red-400",
673
+ iconChar: "✕"
674
+ },
675
+ success: {
676
+ wrapper: "bg-green-50 ring-green-200 dark:bg-green-950/30 dark:ring-green-800",
677
+ icon: "text-green-600 dark:text-green-400",
678
+ iconChar: "✓"
679
+ },
680
+ tip: {
681
+ wrapper: "bg-violet-50 ring-violet-200 dark:bg-violet-950/30 dark:ring-violet-800",
682
+ icon: "text-violet-600 dark:text-violet-400",
683
+ iconChar: "★"
684
+ }
685
+ };
686
+ function Callout({ variant = "info", title, icon, className, children }) {
687
+ const styles = variantStyles[variant];
688
+ return /* @__PURE__ */ jsx("div", {
689
+ role: "note",
690
+ className: clsx("rounded-xl p-4 ring-1", styles.wrapper, className),
691
+ children: /* @__PURE__ */ jsxs("div", {
692
+ className: "flex gap-3",
693
+ children: [/* @__PURE__ */ jsx("span", {
694
+ className: clsx("mt-0.5 shrink-0 text-sm font-bold", styles.icon),
695
+ "aria-hidden": "true",
696
+ children: icon ?? styles.iconChar
697
+ }), /* @__PURE__ */ jsxs("div", {
698
+ className: "min-w-0 flex-1",
699
+ children: [title && /* @__PURE__ */ jsx("p", {
700
+ className: "text-sm font-semibold text-zinc-950 dark:text-white",
701
+ children: title
702
+ }), /* @__PURE__ */ jsx("div", {
703
+ className: clsx("text-sm text-zinc-700 dark:text-zinc-300", title && "mt-1"),
704
+ children
705
+ })]
706
+ })]
707
+ })
708
+ });
709
+ }
710
+ //#endregion
711
+ //#region src/hooks/use-field-context.tsx
712
+ var FieldContext = createContext(null);
713
+ function useFieldContext() {
714
+ return use(FieldContext);
715
+ }
716
+ function FieldProvider({ children, disabled = false }) {
717
+ const id = useId();
718
+ return /* @__PURE__ */ jsx(FieldContext, {
719
+ value: useMemo(() => ({
720
+ controlId: `${id}-control`,
721
+ labelId: `${id}-label`,
722
+ descriptionId: `${id}-description`,
723
+ errorId: `${id}-error`,
724
+ disabled
725
+ }), [id, disabled]),
726
+ children
727
+ });
728
+ }
729
+ /**
730
+ * Returns ARIA props for a form control that participates in a Field.
731
+ * Safe to call outside a Field — returns empty object if no context.
732
+ */
733
+ function useFieldControlProps() {
734
+ const ctx = useFieldContext();
735
+ if (!ctx) return {};
736
+ return {
737
+ id: ctx.controlId,
738
+ "aria-labelledby": ctx.labelId,
739
+ "aria-describedby": ctx.descriptionId,
740
+ "data-disabled": ctx.disabled ? "" : void 0
741
+ };
742
+ }
743
+ /**
744
+ * Returns props for a label element within a Field.
745
+ */
746
+ function useFieldLabelProps() {
747
+ const ctx = useFieldContext();
748
+ if (!ctx) return {};
749
+ return {
750
+ id: ctx.labelId,
751
+ htmlFor: ctx.controlId,
752
+ "data-disabled": ctx.disabled ? "" : void 0
753
+ };
754
+ }
755
+ /**
756
+ * Returns props for a description element within a Field.
757
+ */
758
+ function useFieldDescriptionProps() {
759
+ const ctx = useFieldContext();
760
+ if (!ctx) return {};
761
+ return {
762
+ id: ctx.descriptionId,
763
+ "data-disabled": ctx.disabled ? "" : void 0
764
+ };
765
+ }
766
+ /**
767
+ * Returns props for an error message element within a Field.
768
+ */
769
+ function useFieldErrorProps() {
770
+ const ctx = useFieldContext();
771
+ if (!ctx) return {};
772
+ return {
773
+ id: ctx.errorId,
774
+ "data-disabled": ctx.disabled ? "" : void 0
775
+ };
776
+ }
777
+ //#endregion
778
+ //#region src/hooks/use-controllable-state.ts
779
+ function useControllableState({ value: controlledValue, defaultValue, onChange }) {
780
+ const isControlled = controlledValue !== void 0;
781
+ const [internalValue, setInternalValue] = useState(defaultValue);
782
+ const value = isControlled ? controlledValue : internalValue;
783
+ const onChangeRef = useRef(onChange);
784
+ onChangeRef.current = onChange;
785
+ return [value, useCallback((next) => {
786
+ const resolvedValue = typeof next === "function" ? next(value) : next;
787
+ if (!isControlled) setInternalValue(resolvedValue);
788
+ onChangeRef.current?.(resolvedValue);
789
+ }, [isControlled, value])];
790
+ }
791
+ //#endregion
792
+ //#region src/hooks/use-toggle.ts
793
+ function useToggle({ checked: controlledChecked, defaultChecked = false, onChange, disabled = false } = {}) {
794
+ const [checked, setChecked] = useControllableState({
795
+ value: controlledChecked,
796
+ defaultValue: defaultChecked,
797
+ onChange
798
+ });
799
+ const toggle = useCallback(() => {
800
+ if (!disabled) setChecked((prev) => !prev);
801
+ }, [disabled, setChecked]);
802
+ const onClick = useCallback(() => {
803
+ toggle();
804
+ }, [toggle]);
805
+ const onKeyDown = useCallback((e) => {
806
+ if (e.key === " ") {
807
+ e.preventDefault();
808
+ toggle();
809
+ }
810
+ }, [toggle]);
811
+ return {
812
+ checked,
813
+ toggle,
814
+ toggleProps: {
815
+ "aria-checked": checked,
816
+ "data-checked": checked ? "" : void 0,
817
+ tabIndex: 0,
818
+ onClick,
819
+ onKeyDown
820
+ }
821
+ };
822
+ }
823
+ //#endregion
824
+ //#region src/components/checkbox-headless.tsx
825
+ function CheckboxGroup({ className, ...props }) {
826
+ return /* @__PURE__ */ jsx("div", {
827
+ "data-slot": "control",
828
+ ...props,
829
+ className: clsx(className, "space-y-3", "has-data-[slot=description]:space-y-6 has-data-[slot=description]:**:data-[slot=label]:font-medium")
830
+ });
831
+ }
832
+ function CheckboxField({ className, disabled, ...props }) {
833
+ return /* @__PURE__ */ jsx(FieldProvider, {
834
+ disabled,
835
+ children: /* @__PURE__ */ jsx("div", {
836
+ "data-slot": "field",
837
+ "data-disabled": disabled ? "" : void 0,
838
+ ...props,
839
+ className: clsx(className, "grid grid-cols-[1.125rem_1fr] gap-x-4 gap-y-1 sm:grid-cols-[1rem_1fr]", "*:data-[slot=control]:col-start-1 *:data-[slot=control]:row-start-1 *:data-[slot=control]:mt-0.75 sm:*:data-[slot=control]:mt-1", "*:data-[slot=label]:col-start-2 *:data-[slot=label]:row-start-1", "*:data-[slot=description]:col-start-2 *:data-[slot=description]:row-start-2", "has-data-[slot=description]:**:data-[slot=label]:font-medium")
840
+ })
841
+ });
842
+ }
843
+ var base$1 = [
844
+ "relative isolate flex size-4.5 items-center justify-center rounded-[0.3125rem] sm:size-4",
845
+ "before:absolute before:inset-0 before:-z-10 before:rounded-[calc(0.3125rem-1px)] before:bg-white before:shadow-sm",
846
+ "group-data-checked:before:bg-(--checkbox-checked-bg)",
847
+ "dark:before:hidden",
848
+ "dark:bg-white/5 dark:group-data-checked:bg-(--checkbox-checked-bg)",
849
+ "border border-zinc-950/15 group-data-checked:border-transparent group-data-hover:group-data-checked:border-transparent group-data-hover:border-zinc-950/30 group-data-checked:bg-(--checkbox-checked-border)",
850
+ "dark:border-white/15 dark:group-data-checked:border-white/5 dark:group-data-hover:group-data-checked:border-white/5 dark:group-data-hover:border-white/30",
851
+ "after:absolute after:inset-0 after:rounded-[calc(0.3125rem-1px)] after:shadow-[inset_0_1px_--theme(--color-white/15%)]",
852
+ "dark:after:-inset-px dark:after:hidden dark:after:rounded-[0.3125rem] dark:group-data-checked:after:block",
853
+ "group-data-focus:outline-2 group-data-focus:outline-offset-2 group-data-focus:outline-blue-500",
854
+ "group-data-disabled:opacity-50",
855
+ "group-data-disabled:border-zinc-950/25 group-data-disabled:bg-zinc-950/5 group-data-disabled:[--checkbox-check:var(--color-zinc-950)]/50 group-data-disabled:before:bg-transparent",
856
+ "dark:group-data-disabled:border-white/20 dark:group-data-disabled:bg-white/2.5 dark:group-data-disabled:[--checkbox-check:var(--color-white)]/50 dark:group-data-checked:group-data-disabled:after:hidden",
857
+ "forced-colors:[--checkbox-check:HighlightText] forced-colors:[--checkbox-checked-bg:Highlight] forced-colors:group-data-disabled:[--checkbox-check:Highlight]",
858
+ "dark:forced-colors:[--checkbox-check:HighlightText] dark:forced-colors:[--checkbox-checked-bg:Highlight] dark:forced-colors:group-data-disabled:[--checkbox-check:Highlight]"
859
+ ];
860
+ var colors$1 = {
861
+ "dark/zinc": ["[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-zinc-900)] [--checkbox-checked-border:var(--color-zinc-950)]/90", "dark:[--checkbox-checked-bg:var(--color-zinc-600)]"],
862
+ "dark/white": ["[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-zinc-900)] [--checkbox-checked-border:var(--color-zinc-950)]/90", "dark:[--checkbox-check:var(--color-zinc-900)] dark:[--checkbox-checked-bg:var(--color-white)] dark:[--checkbox-checked-border:var(--color-zinc-950)]/15"],
863
+ white: "[--checkbox-check:var(--color-zinc-900)] [--checkbox-checked-bg:var(--color-white)] [--checkbox-checked-border:var(--color-zinc-950)]/15",
864
+ dark: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-zinc-900)] [--checkbox-checked-border:var(--color-zinc-950)]/90",
865
+ zinc: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-zinc-600)] [--checkbox-checked-border:var(--color-zinc-700)]/90",
866
+ red: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-red-600)] [--checkbox-checked-border:var(--color-red-700)]/90",
867
+ orange: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-orange-500)] [--checkbox-checked-border:var(--color-orange-600)]/90",
868
+ amber: "[--checkbox-check:var(--color-amber-950)] [--checkbox-checked-bg:var(--color-amber-400)] [--checkbox-checked-border:var(--color-amber-500)]/80",
869
+ yellow: "[--checkbox-check:var(--color-yellow-950)] [--checkbox-checked-bg:var(--color-yellow-300)] [--checkbox-checked-border:var(--color-yellow-400)]/80",
870
+ lime: "[--checkbox-check:var(--color-lime-950)] [--checkbox-checked-bg:var(--color-lime-300)] [--checkbox-checked-border:var(--color-lime-400)]/80",
871
+ green: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-green-600)] [--checkbox-checked-border:var(--color-green-700)]/90",
872
+ emerald: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-emerald-600)] [--checkbox-checked-border:var(--color-emerald-700)]/90",
873
+ teal: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-teal-600)] [--checkbox-checked-border:var(--color-teal-700)]/90",
874
+ cyan: "[--checkbox-check:var(--color-cyan-950)] [--checkbox-checked-bg:var(--color-cyan-300)] [--checkbox-checked-border:var(--color-cyan-400)]/80",
875
+ sky: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-sky-500)] [--checkbox-checked-border:var(--color-sky-600)]/80",
876
+ blue: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-blue-600)] [--checkbox-checked-border:var(--color-blue-700)]/90",
877
+ indigo: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-indigo-500)] [--checkbox-checked-border:var(--color-indigo-600)]/90",
878
+ violet: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-violet-500)] [--checkbox-checked-border:var(--color-violet-600)]/90",
879
+ purple: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-purple-500)] [--checkbox-checked-border:var(--color-purple-600)]/90",
880
+ fuchsia: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-fuchsia-500)] [--checkbox-checked-border:var(--color-fuchsia-600)]/90",
881
+ pink: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-pink-500)] [--checkbox-checked-border:var(--color-pink-600)]/90",
882
+ rose: "[--checkbox-check:var(--color-white)] [--checkbox-checked-bg:var(--color-rose-500)] [--checkbox-checked-border:var(--color-rose-600)]/90"
883
+ };
884
+ function Checkbox({ color = "dark/zinc", className, checked: controlledChecked, defaultChecked, onChange, disabled, indeterminate, name, value, ...props }) {
885
+ const { checked, toggleProps } = useToggle({
886
+ checked: controlledChecked,
887
+ defaultChecked,
888
+ onChange,
889
+ disabled
890
+ });
891
+ const interactiveProps = useDataInteractive({ disabled });
892
+ const handleKeyDown = useCallback((e) => {
893
+ if (e.key === " ") {
894
+ e.preventDefault();
895
+ toggleProps.onKeyDown(e);
896
+ }
897
+ }, [toggleProps]);
898
+ return /* @__PURE__ */ jsxs("span", {
899
+ "data-slot": "control",
900
+ role: "checkbox",
901
+ "aria-checked": indeterminate ? "mixed" : checked,
902
+ "data-checked": checked ? "" : void 0,
903
+ "data-indeterminate": indeterminate ? "" : void 0,
904
+ "data-disabled": disabled ? "" : void 0,
905
+ tabIndex: disabled ? void 0 : 0,
906
+ onClick: disabled ? void 0 : toggleProps.onClick,
907
+ onKeyDown: disabled ? void 0 : handleKeyDown,
908
+ ...interactiveProps,
909
+ ...props,
910
+ className: clsx(className, "group inline-flex focus:outline-hidden"),
911
+ children: [name && /* @__PURE__ */ jsx("input", {
912
+ type: "hidden",
913
+ name,
914
+ value: checked ? value ?? "on" : ""
915
+ }), /* @__PURE__ */ jsx("span", {
916
+ className: clsx([base$1, colors$1[color]]),
917
+ children: /* @__PURE__ */ jsxs("svg", {
918
+ className: "size-4 stroke-(--checkbox-check) opacity-0 group-data-checked:opacity-100 sm:h-3.5 sm:w-3.5",
919
+ viewBox: "0 0 14 14",
920
+ fill: "none",
921
+ children: [
922
+ /* @__PURE__ */ jsx("title", { children: "Checkmark" }),
923
+ /* @__PURE__ */ jsx("path", {
924
+ className: "opacity-100 group-data-indeterminate:opacity-0",
925
+ d: "M3 8L6 11L11 3.5",
926
+ strokeWidth: 2,
927
+ strokeLinecap: "round",
928
+ strokeLinejoin: "round"
929
+ }),
930
+ /* @__PURE__ */ jsx("path", {
931
+ className: "opacity-0 group-data-indeterminate:opacity-100",
932
+ d: "M3 7H11",
933
+ strokeWidth: 2,
934
+ strokeLinecap: "round",
935
+ strokeLinejoin: "round"
936
+ })
937
+ ]
938
+ })
939
+ })]
940
+ });
941
+ }
942
+ //#endregion
943
+ //#region src/components/code-block.tsx
944
+ function CodeBlock({ code, language, filename, showCopy = true, className }) {
945
+ const [copied, setCopied] = useState(false);
946
+ const handleCopy = useCallback(async () => {
947
+ await navigator.clipboard.writeText(code);
948
+ setCopied(true);
949
+ setTimeout(() => setCopied(false), 2e3);
950
+ }, [code]);
951
+ return /* @__PURE__ */ jsxs("div", {
952
+ className: clsx("overflow-hidden rounded-xl bg-zinc-950 ring-1 ring-zinc-800", className),
953
+ children: [(filename || language || showCopy) && /* @__PURE__ */ jsxs("div", {
954
+ className: "flex items-center justify-between border-b border-zinc-800 px-4 py-2.5",
955
+ children: [/* @__PURE__ */ jsxs("div", {
956
+ className: "flex items-center gap-2",
957
+ children: [filename && /* @__PURE__ */ jsx("span", {
958
+ className: "text-xs text-zinc-400",
959
+ children: filename
960
+ }), language && !filename && /* @__PURE__ */ jsx("span", {
961
+ className: "rounded bg-zinc-800 px-1.5 py-0.5 text-xs text-zinc-400",
962
+ children: language
963
+ })]
964
+ }), showCopy && /* @__PURE__ */ jsx("button", {
965
+ type: "button",
966
+ onClick: () => void handleCopy(),
967
+ "aria-label": copied ? "Copied" : "Copy code",
968
+ className: "rounded px-2 py-1 text-xs text-zinc-400 transition-colors hover:bg-zinc-800 hover:text-zinc-200 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500",
969
+ children: copied ? "Copied!" : "Copy"
970
+ })]
971
+ }), /* @__PURE__ */ jsx("pre", {
972
+ className: "overflow-x-auto p-4 text-sm leading-relaxed text-zinc-300",
973
+ children: /* @__PURE__ */ jsx("code", { children: code })
974
+ })]
975
+ });
976
+ }
977
+ //#endregion
978
+ //#region src/hooks/use-click-outside.ts
979
+ function useClickOutside(refs, onClickOutside, enabled = true) {
980
+ const callbackRef = useRef(onClickOutside);
981
+ callbackRef.current = onClickOutside;
982
+ useEffect(() => {
983
+ if (!enabled) return;
984
+ function handlePointerDown(e) {
985
+ const target = e.target;
986
+ if ((Array.isArray(refs) ? refs : [refs]).every((ref) => !ref.current?.contains(target))) callbackRef.current();
987
+ }
988
+ document.addEventListener("pointerdown", handlePointerDown, true);
989
+ return () => document.removeEventListener("pointerdown", handlePointerDown, true);
990
+ }, [refs, enabled]);
991
+ }
992
+ //#endregion
993
+ //#region src/hooks/use-popover.ts
994
+ function computePosition(trigger, popover, anchor, gap, padding) {
995
+ const triggerRect = trigger.getBoundingClientRect();
996
+ const popoverRect = popover.getBoundingClientRect();
997
+ const viewportHeight = window.innerHeight;
998
+ const viewportWidth = window.innerWidth;
999
+ let top;
1000
+ let left;
1001
+ let maxHeight;
1002
+ const isTop = anchor.startsWith("top");
1003
+ const spaceBelow = viewportHeight - triggerRect.bottom - gap - padding;
1004
+ const spaceAbove = triggerRect.top - gap - padding;
1005
+ if (anchor === "selection start") {
1006
+ top = triggerRect.top;
1007
+ maxHeight = viewportHeight - top - padding;
1008
+ } else if (isTop) {
1009
+ top = triggerRect.top - popoverRect.height - gap;
1010
+ maxHeight = spaceAbove;
1011
+ if (top < padding && spaceBelow > spaceAbove) {
1012
+ top = triggerRect.bottom + gap;
1013
+ maxHeight = spaceBelow;
1014
+ }
1015
+ } else {
1016
+ top = triggerRect.bottom + gap;
1017
+ maxHeight = spaceBelow;
1018
+ if (top + popoverRect.height > viewportHeight - padding && spaceAbove > spaceBelow) {
1019
+ top = triggerRect.top - popoverRect.height - gap;
1020
+ maxHeight = spaceAbove;
1021
+ }
1022
+ }
1023
+ const isEnd = anchor.endsWith("end");
1024
+ const isStart = anchor.endsWith("start");
1025
+ if (isEnd) left = triggerRect.right - popoverRect.width;
1026
+ else if (isStart || anchor === "selection start") left = triggerRect.left;
1027
+ else left = triggerRect.left + (triggerRect.width - popoverRect.width) / 2;
1028
+ left = Math.max(padding, Math.min(left, viewportWidth - popoverRect.width - padding));
1029
+ top = Math.max(padding, top);
1030
+ return {
1031
+ top,
1032
+ left,
1033
+ maxHeight: Math.max(100, maxHeight)
1034
+ };
1035
+ }
1036
+ function usePopover({ open, anchor = "bottom", gap = 8, padding = 4 }) {
1037
+ const triggerRef = useRef(null);
1038
+ const popoverRef = useRef(null);
1039
+ const [position, setPosition] = useState({
1040
+ top: 0,
1041
+ left: 0,
1042
+ maxHeight: 300
1043
+ });
1044
+ const updatePosition = useCallback(() => {
1045
+ if (!(triggerRef.current && popoverRef.current && open)) return;
1046
+ setPosition(computePosition(triggerRef.current, popoverRef.current, anchor, gap, padding));
1047
+ }, [
1048
+ open,
1049
+ anchor,
1050
+ gap,
1051
+ padding
1052
+ ]);
1053
+ useEffect(() => {
1054
+ if (!open) return;
1055
+ requestAnimationFrame(updatePosition);
1056
+ window.addEventListener("scroll", updatePosition, true);
1057
+ window.addEventListener("resize", updatePosition);
1058
+ return () => {
1059
+ window.removeEventListener("scroll", updatePosition, true);
1060
+ window.removeEventListener("resize", updatePosition);
1061
+ };
1062
+ }, [open, updatePosition]);
1063
+ return {
1064
+ triggerRef,
1065
+ popoverRef,
1066
+ position,
1067
+ popoverProps: { style: {
1068
+ position: "fixed",
1069
+ top: position.top,
1070
+ left: position.left,
1071
+ maxHeight: position.maxHeight,
1072
+ zIndex: 50
1073
+ } }
1074
+ };
1075
+ }
1076
+ //#endregion
1077
+ //#region src/components/combobox.tsx
1078
+ var ComboboxContext = createContext(null);
1079
+ function useComboboxContext() {
1080
+ const ctx = use(ComboboxContext);
1081
+ if (!ctx) throw new Error("Combobox compound components must be used within <Combobox>");
1082
+ return ctx;
1083
+ }
1084
+ function Combobox({ options, displayValue, filter, anchor = "bottom", className, placeholder, autoFocus = false, "aria-label": ariaLabel, children, value: controlledValue, defaultValue, onChange, disabled = false, name }) {
1085
+ const [selectedValue, setSelectedValue] = useControllableState({
1086
+ value: controlledValue,
1087
+ defaultValue: defaultValue ?? null,
1088
+ onChange
1089
+ });
1090
+ const [query, setQuery] = useState("");
1091
+ const [isOpen, setIsOpen] = useState(false);
1092
+ const [activeIndex, setActiveIndex] = useState(-1);
1093
+ const inputRef = useRef(null);
1094
+ const controlRef = useRef(null);
1095
+ const listboxId = useId();
1096
+ const filteredOptions = query === "" ? options : options.filter((option) => filter ? filter(option, query) : displayValue(option)?.toLowerCase().includes(query.toLowerCase()));
1097
+ const { triggerRef, popoverRef, popoverProps } = usePopover({
1098
+ open: isOpen,
1099
+ anchor,
1100
+ gap: 8,
1101
+ padding: 16
1102
+ });
1103
+ useEffect(() => {
1104
+ if (controlRef.current) triggerRef.current = controlRef.current;
1105
+ }, [triggerRef]);
1106
+ useEffect(() => {
1107
+ if (autoFocus && !disabled) inputRef.current?.focus();
1108
+ }, [autoFocus, disabled]);
1109
+ const { mounted, nodeRef: transitionRef, transitionProps } = useTransition(isOpen);
1110
+ useClickOutside([controlRef, popoverRef], () => {
1111
+ if (isOpen) close();
1112
+ }, isOpen);
1113
+ useEscapeKey(() => {
1114
+ if (isOpen) close();
1115
+ }, isOpen);
1116
+ const open = useCallback(() => {
1117
+ if (disabled) return;
1118
+ setIsOpen(true);
1119
+ setActiveIndex(-1);
1120
+ }, [disabled]);
1121
+ const close = useCallback(() => {
1122
+ setIsOpen(false);
1123
+ setQuery("");
1124
+ setActiveIndex(-1);
1125
+ }, []);
1126
+ const select = useCallback((value) => {
1127
+ setSelectedValue(value);
1128
+ close();
1129
+ requestAnimationFrame(() => {
1130
+ inputRef.current?.focus();
1131
+ });
1132
+ }, [setSelectedValue, close]);
1133
+ const handleInputKeyDown = useCallback((e) => {
1134
+ switch (e.key) {
1135
+ case "ArrowDown":
1136
+ e.preventDefault();
1137
+ if (!isOpen) open();
1138
+ else setActiveIndex((prev) => prev < filteredOptions.length - 1 ? prev + 1 : 0);
1139
+ break;
1140
+ case "ArrowUp":
1141
+ e.preventDefault();
1142
+ if (!isOpen) open();
1143
+ else setActiveIndex((prev) => prev > 0 ? prev - 1 : filteredOptions.length - 1);
1144
+ break;
1145
+ case "Home":
1146
+ if (isOpen) {
1147
+ e.preventDefault();
1148
+ setActiveIndex(0);
1149
+ }
1150
+ break;
1151
+ case "End":
1152
+ if (isOpen) {
1153
+ e.preventDefault();
1154
+ setActiveIndex(filteredOptions.length - 1);
1155
+ }
1156
+ break;
1157
+ case "Enter":
1158
+ e.preventDefault();
1159
+ if (isOpen && activeIndex >= 0 && activeIndex < filteredOptions.length) select(filteredOptions[activeIndex]);
1160
+ break;
1161
+ case "Tab":
1162
+ if (isOpen) close();
1163
+ break;
1164
+ }
1165
+ }, [
1166
+ isOpen,
1167
+ open,
1168
+ close,
1169
+ select,
1170
+ activeIndex,
1171
+ filteredOptions
1172
+ ]);
1173
+ useEffect(() => {
1174
+ if (!isOpen || activeIndex < 0) return;
1175
+ const listbox = popoverRef.current;
1176
+ if (!listbox) return;
1177
+ const activeOption = listbox.querySelector(`[data-combobox-option-index="${activeIndex}"]`);
1178
+ if (activeOption) activeOption.scrollIntoView({ block: "nearest" });
1179
+ }, [
1180
+ activeIndex,
1181
+ isOpen,
1182
+ popoverRef
1183
+ ]);
1184
+ const contextValue = {
1185
+ selectedValue,
1186
+ activeIndex,
1187
+ filteredOptions,
1188
+ select,
1189
+ setActiveIndex
1190
+ };
1191
+ return /* @__PURE__ */ jsxs(ComboboxContext.Provider, {
1192
+ value: contextValue,
1193
+ children: [/* @__PURE__ */ jsxs("span", {
1194
+ ref: controlRef,
1195
+ "data-slot": "control",
1196
+ ...disabled ? { "data-disabled": "" } : {},
1197
+ className: clsx([
1198
+ className,
1199
+ "relative block w-full",
1200
+ "before:absolute before:inset-px before:rounded-[calc(var(--radius-lg)-1px)] before:bg-white before:shadow-sm",
1201
+ "dark:before:hidden",
1202
+ "after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:ring-transparent after:ring-inset sm:focus-within:after:ring-2 sm:focus-within:after:ring-blue-500",
1203
+ "has-data-disabled:opacity-50 has-data-disabled:before:bg-zinc-950/5 has-data-disabled:before:shadow-none",
1204
+ "has-data-invalid:before:shadow-red-500/10"
1205
+ ]),
1206
+ children: [/* @__PURE__ */ jsx("input", {
1207
+ ref: inputRef,
1208
+ "data-slot": "control",
1209
+ role: "combobox",
1210
+ "aria-label": ariaLabel,
1211
+ "aria-expanded": isOpen,
1212
+ "aria-controls": listboxId,
1213
+ "aria-activedescendant": isOpen && activeIndex >= 0 ? `${listboxId}-option-${activeIndex}` : void 0,
1214
+ "aria-autocomplete": "list",
1215
+ "aria-haspopup": "listbox",
1216
+ disabled,
1217
+ name,
1218
+ value: isOpen ? query : displayValue(selectedValue) ?? "",
1219
+ onChange: (e) => {
1220
+ setQuery(e.target.value);
1221
+ if (!isOpen) open();
1222
+ setActiveIndex(-1);
1223
+ },
1224
+ onFocus: () => {
1225
+ if (!isOpen) open();
1226
+ },
1227
+ onKeyDown: handleInputKeyDown,
1228
+ placeholder,
1229
+ ...disabled ? { "data-disabled": "" } : {},
1230
+ className: clsx([
1231
+ className,
1232
+ "relative block w-full appearance-none rounded-lg py-[calc(--spacing(2.5)-1px)] sm:py-[calc(--spacing(1.5)-1px)]",
1233
+ "pr-[calc(--spacing(10)-1px)] pl-[calc(--spacing(3.5)-1px)] sm:pr-[calc(--spacing(9)-1px)] sm:pl-[calc(--spacing(3)-1px)]",
1234
+ "text-base/6 text-zinc-950 placeholder:text-zinc-500 sm:text-sm/6 dark:text-white",
1235
+ "border border-zinc-950/10 data-hover:border-zinc-950/20 dark:border-white/10 dark:data-hover:border-white/20",
1236
+ "bg-transparent dark:bg-white/5",
1237
+ "focus:outline-hidden",
1238
+ "data-invalid:border-red-500 data-invalid:data-hover:border-red-500 dark:data-invalid:border-red-500 dark:data-invalid:data-hover:border-red-500",
1239
+ "data-disabled:border-zinc-950/20 dark:data-disabled:border-white/15 dark:data-disabled:bg-white/2.5 dark:data-hover:data-disabled:border-white/15",
1240
+ "dark:scheme-dark"
1241
+ ])
1242
+ }), /* @__PURE__ */ jsx("button", {
1243
+ type: "button",
1244
+ tabIndex: -1,
1245
+ "aria-label": "Toggle options",
1246
+ disabled,
1247
+ onClick: () => {
1248
+ if (isOpen) close();
1249
+ else {
1250
+ open();
1251
+ inputRef.current?.focus();
1252
+ }
1253
+ },
1254
+ className: "group absolute inset-y-0 right-0 flex items-center px-2",
1255
+ ...disabled ? { "data-disabled": "" } : {},
1256
+ children: /* @__PURE__ */ jsxs("svg", {
1257
+ className: "size-5 stroke-zinc-500 group-data-disabled:stroke-zinc-600 group-data-hover:stroke-zinc-700 sm:size-4 dark:stroke-zinc-400 dark:group-data-hover:stroke-zinc-300 forced-colors:stroke-[CanvasText]",
1258
+ viewBox: "0 0 16 16",
1259
+ "aria-hidden": "true",
1260
+ fill: "none",
1261
+ children: [/* @__PURE__ */ jsx("path", {
1262
+ d: "M5.75 10.75L8 13L10.25 10.75",
1263
+ strokeWidth: 1.5,
1264
+ strokeLinecap: "round",
1265
+ strokeLinejoin: "round"
1266
+ }), /* @__PURE__ */ jsx("path", {
1267
+ d: "M10.25 5.25L8 3L5.75 5.25",
1268
+ strokeWidth: 1.5,
1269
+ strokeLinecap: "round",
1270
+ strokeLinejoin: "round"
1271
+ })]
1272
+ })
1273
+ })]
1274
+ }), mounted && createPortal(/* @__PURE__ */ jsx("div", {
1275
+ ref: (node) => {
1276
+ popoverRef.current = node;
1277
+ transitionRef.current = node;
1278
+ },
1279
+ role: "listbox",
1280
+ id: listboxId,
1281
+ ...popoverProps,
1282
+ ...transitionProps,
1283
+ className: clsx("[--anchor-gap:--spacing(2)] [--anchor-padding:--spacing(4)] sm:data-[anchor~=start]:[--anchor-offset:-4px]", "isolate min-w-[calc(var(--input-width)+8px)] scroll-py-1 rounded-xl p-1 select-none empty:invisible", "outline outline-transparent focus:outline-hidden", "overflow-y-scroll overscroll-contain", "bg-white/75 backdrop-blur-xl dark:bg-zinc-800/75", "shadow-lg ring-1 ring-zinc-950/10 dark:ring-white/10 dark:ring-inset", "transition-opacity duration-100 ease-in data-closed:data-leave:opacity-0 data-transition:pointer-events-none"),
1284
+ style: {
1285
+ ...popoverProps.style,
1286
+ minWidth: controlRef.current?.offsetWidth
1287
+ },
1288
+ children: filteredOptions.map((option, index) => option == null ? null : /* @__PURE__ */ jsx(ComboboxOptionIndexProvider, {
1289
+ index,
1290
+ children: children(option)
1291
+ }, index))
1292
+ }), document.body)]
1293
+ });
1294
+ }
1295
+ var ComboboxOptionIndexContext = createContext(-1);
1296
+ function ComboboxOptionIndexProvider({ index, children }) {
1297
+ return /* @__PURE__ */ jsx(ComboboxOptionIndexContext.Provider, {
1298
+ value: index,
1299
+ children
1300
+ });
1301
+ }
1302
+ function ComboboxOption({ children, className, value, disabled = false }) {
1303
+ const { selectedValue, activeIndex, select, setActiveIndex } = useComboboxContext();
1304
+ const index = use(ComboboxOptionIndexContext);
1305
+ const isSelected = selectedValue === value;
1306
+ const isActive = activeIndex === index;
1307
+ const sharedClasses = clsx("flex min-w-0 items-center", "*:data-[slot=icon]:size-5 *:data-[slot=icon]:shrink-0 sm:*:data-[slot=icon]:size-4", "*:data-[slot=icon]:text-zinc-500 group-data-focus/option:*:data-[slot=icon]:text-white dark:*:data-[slot=icon]:text-zinc-400", "forced-colors:*:data-[slot=icon]:text-[CanvasText] forced-colors:group-data-focus/option:*:data-[slot=icon]:text-[Canvas]", "*:data-[slot=avatar]:-mx-0.5 *:data-[slot=avatar]:size-6 sm:*:data-[slot=avatar]:size-5");
1308
+ return /* @__PURE__ */ jsxs("div", {
1309
+ role: "option",
1310
+ "aria-selected": isSelected,
1311
+ "aria-disabled": disabled,
1312
+ "data-combobox-option-index": index,
1313
+ ...isActive ? { "data-focus": "" } : {},
1314
+ ...isSelected ? { "data-selected": "" } : {},
1315
+ ...disabled ? { "data-disabled": "" } : {},
1316
+ onPointerEnter: () => {
1317
+ if (!disabled) setActiveIndex(index);
1318
+ },
1319
+ onPointerLeave: () => {
1320
+ setActiveIndex(-1);
1321
+ },
1322
+ onClick: () => {
1323
+ if (!disabled) select(value);
1324
+ },
1325
+ className: clsx("group/option grid w-full cursor-default grid-cols-[1fr_--spacing(5)] items-baseline gap-x-2 rounded-lg py-2.5 pr-2 pl-3.5 sm:grid-cols-[1fr_--spacing(4)] sm:py-1.5 sm:pr-2 sm:pl-3", "text-base/6 text-zinc-950 sm:text-sm/6 dark:text-white forced-colors:text-[CanvasText]", "outline-hidden data-focus:bg-blue-500 data-focus:text-white", "forced-color-adjust-none forced-colors:data-focus:bg-[Highlight] forced-colors:data-focus:text-[HighlightText]", "data-disabled:opacity-50"),
1326
+ children: [/* @__PURE__ */ jsx("span", {
1327
+ className: clsx(className, sharedClasses),
1328
+ children
1329
+ }), /* @__PURE__ */ jsx("svg", {
1330
+ className: "relative col-start-2 hidden size-5 self-center stroke-current group-data-selected/option:inline sm:size-4",
1331
+ viewBox: "0 0 16 16",
1332
+ fill: "none",
1333
+ "aria-hidden": "true",
1334
+ children: /* @__PURE__ */ jsx("path", {
1335
+ d: "M4 8.5l3 3L12 4",
1336
+ strokeWidth: 1.5,
1337
+ strokeLinecap: "round",
1338
+ strokeLinejoin: "round"
1339
+ })
1340
+ })]
1341
+ });
1342
+ }
1343
+ function ComboboxLabel({ className, ...props }) {
1344
+ return /* @__PURE__ */ jsx("span", {
1345
+ ...props,
1346
+ className: clsx(className, "ml-2.5 truncate first:ml-0 sm:ml-2 sm:first:ml-0")
1347
+ });
1348
+ }
1349
+ function ComboboxDescription({ className, children, ...props }) {
1350
+ return /* @__PURE__ */ jsx("span", {
1351
+ ...props,
1352
+ className: clsx(className, "flex flex-1 overflow-hidden text-zinc-500 group-data-focus/option:text-white before:w-2 before:min-w-0 before:shrink dark:text-zinc-400"),
1353
+ children: /* @__PURE__ */ jsx("span", {
1354
+ className: "flex-1 truncate",
1355
+ children
1356
+ })
1357
+ });
1358
+ }
1359
+ //#endregion
1360
+ //#region src/components/description-list.tsx
1361
+ function DescriptionList({ className, ...props }) {
1362
+ return /* @__PURE__ */ jsx("dl", {
1363
+ ...props,
1364
+ className: clsx(className, "grid grid-cols-1 text-base/6 sm:grid-cols-[min(50%,--spacing(80))_auto] sm:text-sm/6")
1365
+ });
1366
+ }
1367
+ function DescriptionTerm({ className, ...props }) {
1368
+ return /* @__PURE__ */ jsx("dt", {
1369
+ ...props,
1370
+ className: clsx(className, "col-start-1 border-t border-zinc-950/5 pt-3 text-zinc-500 first:border-none sm:border-t sm:border-zinc-950/5 sm:py-3 dark:border-white/5 dark:text-zinc-400 sm:dark:border-white/5")
1371
+ });
1372
+ }
1373
+ function DescriptionDetails({ className, ...props }) {
1374
+ return /* @__PURE__ */ jsx("dd", {
1375
+ ...props,
1376
+ className: clsx(className, "pt-1 pb-3 text-zinc-950 sm:border-t sm:border-zinc-950/5 sm:py-3 sm:nth-2:border-none dark:text-white dark:sm:border-white/5")
1377
+ });
1378
+ }
1379
+ //#endregion
1380
+ //#region src/components/dialog.tsx
1381
+ var DialogContext = createContext(void 0);
1382
+ var sizes = {
1383
+ xs: "sm:max-w-xs",
1384
+ sm: "sm:max-w-sm",
1385
+ md: "sm:max-w-md",
1386
+ lg: "sm:max-w-lg",
1387
+ xl: "sm:max-w-xl",
1388
+ "2xl": "sm:max-w-2xl",
1389
+ "3xl": "sm:max-w-3xl",
1390
+ "4xl": "sm:max-w-4xl",
1391
+ "5xl": "sm:max-w-5xl"
1392
+ };
1393
+ function Dialog({ size = "lg", className, children, open, onClose }) {
1394
+ const panelRef = useRef(null);
1395
+ const titleId = useId();
1396
+ const backdrop = useTransition(open);
1397
+ const panel = useTransition(open);
1398
+ useScrollLock(open);
1399
+ useFocusTrap(panelRef, open);
1400
+ useEscapeKey(onClose, open);
1401
+ if (!(backdrop.mounted || panel.mounted)) return null;
1402
+ return createPortal(/* @__PURE__ */ jsx(DialogContext.Provider, {
1403
+ value: titleId,
1404
+ children: /* @__PURE__ */ jsxs("div", {
1405
+ role: "dialog",
1406
+ "aria-modal": "true",
1407
+ "aria-labelledby": titleId,
1408
+ children: [backdrop.mounted && /* @__PURE__ */ jsx("button", {
1409
+ type: "button",
1410
+ "aria-label": "Close dialog",
1411
+ ref: backdrop.nodeRef,
1412
+ ...backdrop.transitionProps,
1413
+ onClick: onClose,
1414
+ className: "fixed inset-0 flex w-screen justify-center overflow-y-auto bg-zinc-950/25 px-2 py-2 transition duration-100 focus:outline-0 data-closed:opacity-0 data-enter:ease-out data-leave:ease-in sm:px-6 sm:py-8 lg:px-8 lg:py-16 dark:bg-zinc-950/50"
1415
+ }), panel.mounted && /* @__PURE__ */ jsx("div", {
1416
+ className: "fixed inset-0 w-screen overflow-y-auto pt-6 sm:pt-0",
1417
+ children: /* @__PURE__ */ jsx("div", {
1418
+ className: "grid min-h-full grid-rows-[1fr_auto] justify-items-center sm:grid-rows-[1fr_auto_3fr] sm:p-4",
1419
+ children: /* @__PURE__ */ jsx("div", {
1420
+ ref: (node) => {
1421
+ panelRef.current = node;
1422
+ panel.nodeRef.current = node;
1423
+ },
1424
+ ...panel.transitionProps,
1425
+ className: clsx(className, sizes[size], "row-start-2 w-full min-w-0 rounded-t-3xl bg-white p-(--gutter) shadow-lg ring-1 ring-zinc-950/10 [--gutter:--spacing(8)] sm:mb-auto sm:rounded-2xl dark:bg-zinc-900 dark:ring-white/10 forced-colors:outline", "transition duration-100 will-change-transform data-closed:translate-y-12 data-closed:opacity-0 data-enter:ease-out data-leave:ease-in sm:data-closed:translate-y-0 sm:data-closed:data-enter:scale-95"),
1426
+ children
1427
+ })
1428
+ })
1429
+ })]
1430
+ })
1431
+ }), document.body);
1432
+ }
1433
+ function DialogTitle({ className, ...props }) {
1434
+ return /* @__PURE__ */ jsx("h2", {
1435
+ id: use(DialogContext),
1436
+ ...props,
1437
+ className: clsx(className, "text-lg/6 font-semibold text-balance text-zinc-950 sm:text-base/6 dark:text-white")
1438
+ });
1439
+ }
1440
+ function DialogDescription({ className, ...props }) {
1441
+ return /* @__PURE__ */ jsx(Text, {
1442
+ ...props,
1443
+ className: clsx(className, "mt-2 text-pretty")
1444
+ });
1445
+ }
1446
+ function DialogBody({ className, ...props }) {
1447
+ return /* @__PURE__ */ jsx("div", {
1448
+ ...props,
1449
+ className: clsx(className, "mt-6")
1450
+ });
1451
+ }
1452
+ function DialogActions({ className, ...props }) {
1453
+ return /* @__PURE__ */ jsx("div", {
1454
+ ...props,
1455
+ className: clsx(className, "mt-8 flex flex-col-reverse items-center justify-end gap-3 *:w-full sm:flex-row sm:*:w-auto")
1456
+ });
1457
+ }
1458
+ //#endregion
1459
+ //#region src/components/divider.tsx
1460
+ function Divider({ soft = false, className, ...props }) {
1461
+ return /* @__PURE__ */ jsx("hr", {
1462
+ ...props,
1463
+ className: clsx(className, "w-full border-t", soft && "border-zinc-950/5 dark:border-white/5", !soft && "border-zinc-950/10 dark:border-white/10")
1464
+ });
1465
+ }
1466
+ //#endregion
1467
+ //#region src/components/drawer.tsx
1468
+ var DrawerContext = createContext(void 0);
1469
+ var sideClasses$1 = {
1470
+ left: "inset-y-0 left-0 h-full w-full max-w-sm data-closed:-translate-x-full",
1471
+ right: "inset-y-0 right-0 h-full w-full max-w-sm data-closed:translate-x-full",
1472
+ top: "inset-x-0 top-0 w-full max-h-[50vh] data-closed:-translate-y-full",
1473
+ bottom: "inset-x-0 bottom-0 w-full max-h-[50vh] data-closed:translate-y-full"
1474
+ };
1475
+ function Drawer({ open, onClose, side = "right", className, children }) {
1476
+ const panelRef = useRef(null);
1477
+ const titleId = useId();
1478
+ const backdrop = useTransition(open);
1479
+ const panel = useTransition(open);
1480
+ useScrollLock(open);
1481
+ useFocusTrap(panelRef, open);
1482
+ useEscapeKey(onClose, open);
1483
+ const handleBackdropClick = (e) => {
1484
+ if (e.target === e.currentTarget) onClose();
1485
+ };
1486
+ if (!(backdrop.mounted || panel.mounted)) return null;
1487
+ return createPortal(/* @__PURE__ */ jsx(DrawerContext.Provider, {
1488
+ value: titleId,
1489
+ children: /* @__PURE__ */ jsxs("div", {
1490
+ role: "dialog",
1491
+ "aria-modal": "true",
1492
+ "aria-labelledby": titleId,
1493
+ children: [backdrop.mounted && /* @__PURE__ */ jsx("button", {
1494
+ type: "button",
1495
+ "aria-label": "Close drawer",
1496
+ ref: backdrop.nodeRef,
1497
+ ...backdrop.transitionProps,
1498
+ onClick: handleBackdropClick,
1499
+ className: "fixed inset-0 z-40 bg-zinc-950/25 transition duration-200 data-closed:opacity-0 data-enter:ease-out data-leave:ease-in dark:bg-zinc-950/50"
1500
+ }), panel.mounted && /* @__PURE__ */ jsx("div", {
1501
+ ref: (node) => {
1502
+ panelRef.current = node;
1503
+ panel.nodeRef.current = node;
1504
+ },
1505
+ ...panel.transitionProps,
1506
+ className: clsx("fixed z-50 overflow-y-auto bg-white shadow-xl ring-1 ring-zinc-950/10 transition duration-300 ease-in-out dark:bg-zinc-900 dark:ring-white/10", sideClasses$1[side], className),
1507
+ children
1508
+ })]
1509
+ })
1510
+ }), document.body);
1511
+ }
1512
+ function DrawerHeader({ onClose, className, children }) {
1513
+ const titleId = use(DrawerContext);
1514
+ return /* @__PURE__ */ jsxs("div", {
1515
+ className: clsx("flex items-center justify-between border-b border-zinc-200 px-6 py-4 dark:border-zinc-700", className),
1516
+ children: [/* @__PURE__ */ jsx("h2", {
1517
+ id: titleId,
1518
+ className: "text-base font-semibold text-zinc-950 dark:text-white",
1519
+ children
1520
+ }), onClose && /* @__PURE__ */ jsx("button", {
1521
+ type: "button",
1522
+ "aria-label": "Close drawer",
1523
+ onClick: onClose,
1524
+ className: "rounded-md p-1 text-zinc-400 hover:text-zinc-600 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500 dark:hover:text-zinc-200",
1525
+ children: /* @__PURE__ */ jsx("svg", {
1526
+ viewBox: "0 0 16 16",
1527
+ fill: "none",
1528
+ className: "size-4",
1529
+ "aria-hidden": "true",
1530
+ children: /* @__PURE__ */ jsx("path", {
1531
+ d: "M4 4l8 8M12 4l-8 8",
1532
+ stroke: "currentColor",
1533
+ strokeWidth: "1.5",
1534
+ strokeLinecap: "round"
1535
+ })
1536
+ })
1537
+ })]
1538
+ });
1539
+ }
1540
+ function DrawerBody({ className, ...props }) {
1541
+ return /* @__PURE__ */ jsx("div", {
1542
+ ...props,
1543
+ className: clsx("px-6 py-4", className)
1544
+ });
1545
+ }
1546
+ function DrawerFooter({ className, ...props }) {
1547
+ return /* @__PURE__ */ jsx("div", {
1548
+ ...props,
1549
+ className: clsx("flex items-center justify-end gap-3 border-t border-zinc-200 px-6 py-4 dark:border-zinc-700", className)
1550
+ });
1551
+ }
1552
+ //#endregion
1553
+ //#region src/hooks/use-roving-tabindex.ts
1554
+ function useRovingTabindex({ itemCount, initialIndex = -1, orientation = "vertical", loop = true, onActiveChange }) {
1555
+ const [activeIndex, setActiveIndexState] = useState(initialIndex);
1556
+ const itemRefs = useRef(/* @__PURE__ */ new Map());
1557
+ const onActiveChangeRef = useRef(onActiveChange);
1558
+ onActiveChangeRef.current = onActiveChange;
1559
+ const setActiveIndex = useCallback((index) => {
1560
+ setActiveIndexState(index);
1561
+ onActiveChangeRef.current?.(index);
1562
+ itemRefs.current.get(index)?.focus();
1563
+ }, []);
1564
+ const moveFocus = useCallback((direction) => {
1565
+ if (itemCount === 0) return;
1566
+ let next = activeIndex + direction;
1567
+ if (loop) {
1568
+ if (next < 0) next = itemCount - 1;
1569
+ else if (next >= itemCount) next = 0;
1570
+ } else next = Math.max(0, Math.min(itemCount - 1, next));
1571
+ if (itemRefs.current.get(next)?.hasAttribute("data-disabled")) {
1572
+ const nextNext = next + direction;
1573
+ if (nextNext >= 0 && nextNext < itemCount) {
1574
+ setActiveIndex(nextNext);
1575
+ return;
1576
+ }
1577
+ }
1578
+ setActiveIndex(next);
1579
+ }, [
1580
+ activeIndex,
1581
+ itemCount,
1582
+ loop,
1583
+ setActiveIndex
1584
+ ]);
1585
+ const onKeyDown = useCallback((e) => {
1586
+ const prevKey = orientation === "vertical" ? "ArrowUp" : "ArrowLeft";
1587
+ const nextKey = orientation === "vertical" ? "ArrowDown" : "ArrowRight";
1588
+ switch (e.key) {
1589
+ case prevKey:
1590
+ e.preventDefault();
1591
+ moveFocus(-1);
1592
+ break;
1593
+ case nextKey:
1594
+ e.preventDefault();
1595
+ moveFocus(1);
1596
+ break;
1597
+ case "Home":
1598
+ e.preventDefault();
1599
+ setActiveIndex(0);
1600
+ break;
1601
+ case "End":
1602
+ e.preventDefault();
1603
+ setActiveIndex(itemCount - 1);
1604
+ break;
1605
+ }
1606
+ }, [
1607
+ moveFocus,
1608
+ setActiveIndex,
1609
+ itemCount,
1610
+ orientation
1611
+ ]);
1612
+ const getItemProps = useCallback((index) => ({
1613
+ tabIndex: index === activeIndex ? 0 : -1,
1614
+ "data-focus": index === activeIndex ? "" : void 0,
1615
+ ref: (el) => {
1616
+ if (el) itemRefs.current.set(index, el);
1617
+ else itemRefs.current.delete(index);
1618
+ },
1619
+ onPointerEnter: () => setActiveIndex(index),
1620
+ onClick: () => setActiveIndex(index)
1621
+ }), [activeIndex, setActiveIndex]);
1622
+ return {
1623
+ activeIndex,
1624
+ setActiveIndex,
1625
+ containerProps: {
1626
+ role: orientation === "vertical" ? "listbox" : "group",
1627
+ onKeyDown
1628
+ },
1629
+ getItemProps
1630
+ };
1631
+ }
1632
+ //#endregion
1633
+ //#region src/hooks/use-type-ahead.ts
1634
+ function useTypeAhead({ getItemText, itemCount, onMatch, timeout = 350 }) {
1635
+ const searchBuffer = useRef("");
1636
+ const timeoutRef = useRef(void 0);
1637
+ return { onKeyDown: useCallback((e) => {
1638
+ if (e.key.length !== 1 || e.ctrlKey || e.metaKey || e.altKey) return;
1639
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
1640
+ searchBuffer.current += e.key.toLowerCase();
1641
+ timeoutRef.current = setTimeout(() => {
1642
+ searchBuffer.current = "";
1643
+ }, timeout);
1644
+ const query = searchBuffer.current;
1645
+ for (let i = 0; i < itemCount; i++) if (getItemText(i).toLowerCase().startsWith(query)) {
1646
+ onMatch(i);
1647
+ return;
1648
+ }
1649
+ }, [
1650
+ getItemText,
1651
+ itemCount,
1652
+ onMatch,
1653
+ timeout
1654
+ ]) };
1655
+ }
1656
+ //#endregion
1657
+ //#region src/components/dropdown.tsx
1658
+ var DropdownContext = createContext(null);
1659
+ function useDropdownContext() {
1660
+ const ctx = use(DropdownContext);
1661
+ if (!ctx) throw new Error("Dropdown compound components must be used within <Dropdown>");
1662
+ return ctx;
1663
+ }
1664
+ var DropdownItemContext = createContext(null);
1665
+ function Dropdown({ children, ...props }) {
1666
+ const [open, setOpen] = useState(false);
1667
+ const triggerRef = useRef(null);
1668
+ const close = useCallback(() => {
1669
+ setOpen(false);
1670
+ triggerRef.current?.focus();
1671
+ }, []);
1672
+ const value = useMemo(() => ({
1673
+ open,
1674
+ setOpen,
1675
+ close,
1676
+ triggerRef
1677
+ }), [open, close]);
1678
+ return /* @__PURE__ */ jsx(DropdownContext.Provider, {
1679
+ value,
1680
+ children: /* @__PURE__ */ jsx("div", {
1681
+ ...props,
1682
+ children
1683
+ })
1684
+ });
1685
+ }
1686
+ function DropdownButton({ as, className, ...props }) {
1687
+ const { open, setOpen, triggerRef } = useDropdownContext();
1688
+ const interactiveProps = useDataInteractive();
1689
+ const Component = as ?? Button;
1690
+ const handleClick = useCallback(() => {
1691
+ setOpen(!open);
1692
+ }, [open, setOpen]);
1693
+ const handleKeyDown = useCallback((e) => {
1694
+ if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
1695
+ e.preventDefault();
1696
+ setOpen(true);
1697
+ }
1698
+ }, [setOpen]);
1699
+ return /* @__PURE__ */ jsx(Component, {
1700
+ ref: triggerRef,
1701
+ ...interactiveProps,
1702
+ ...props,
1703
+ className,
1704
+ "aria-haspopup": "menu",
1705
+ "aria-expanded": open,
1706
+ onClick: handleClick,
1707
+ onKeyDown: handleKeyDown
1708
+ });
1709
+ }
1710
+ function DropdownMenu({ anchor = "bottom", className, children, ...props }) {
1711
+ const { open, close, triggerRef } = useDropdownContext();
1712
+ const { mounted, nodeRef, transitionProps } = useTransition(open);
1713
+ const popover = usePopover({
1714
+ open,
1715
+ anchor,
1716
+ gap: 8,
1717
+ padding: 4
1718
+ });
1719
+ const menuRef = useRef(null);
1720
+ const combinedRef = useCallback((el) => {
1721
+ menuRef.current = el;
1722
+ popover.popoverRef.current = el;
1723
+ nodeRef.current = el;
1724
+ }, [popover.popoverRef, nodeRef]);
1725
+ popover.triggerRef.current = triggerRef.current;
1726
+ useClickOutside([triggerRef, menuRef], close, open);
1727
+ useEscapeKey(close, open);
1728
+ const itemElements = useRef([]);
1729
+ const [itemCount, setItemCount] = useState(0);
1730
+ const register = useCallback((el) => {
1731
+ if (!itemElements.current.includes(el)) {
1732
+ itemElements.current.push(el);
1733
+ setItemCount(itemElements.current.length);
1734
+ }
1735
+ return itemElements.current.indexOf(el);
1736
+ }, []);
1737
+ const unregister = useCallback((el) => {
1738
+ const idx = itemElements.current.indexOf(el);
1739
+ if (idx !== -1) {
1740
+ itemElements.current.splice(idx, 1);
1741
+ setItemCount(itemElements.current.length);
1742
+ }
1743
+ }, []);
1744
+ const roving = useRovingTabindex({
1745
+ itemCount,
1746
+ initialIndex: -1,
1747
+ orientation: "vertical",
1748
+ loop: true
1749
+ });
1750
+ const typeAhead = useTypeAhead({
1751
+ getItemText: (index) => itemElements.current[index]?.textContent ?? "",
1752
+ itemCount,
1753
+ onMatch: (index) => roving.setActiveIndex(index)
1754
+ });
1755
+ const handleKeyDown = useCallback((e) => {
1756
+ roving.containerProps.onKeyDown(e);
1757
+ typeAhead.onKeyDown(e);
1758
+ if (e.key === "Enter" || e.key === " ") {
1759
+ e.preventDefault();
1760
+ const activeEl = itemElements.current[roving.activeIndex];
1761
+ if (activeEl) activeEl.click();
1762
+ }
1763
+ }, [roving, typeAhead]);
1764
+ const itemContextValue = useMemo(() => ({
1765
+ register,
1766
+ unregister,
1767
+ getItemProps: roving.getItemProps
1768
+ }), [
1769
+ register,
1770
+ unregister,
1771
+ roving.getItemProps
1772
+ ]);
1773
+ if (!mounted) return null;
1774
+ return createPortal(/* @__PURE__ */ jsx(DropdownItemContext.Provider, {
1775
+ value: itemContextValue,
1776
+ children: /* @__PURE__ */ jsx("div", {
1777
+ ref: combinedRef,
1778
+ ...transitionProps,
1779
+ ...props,
1780
+ role: "menu",
1781
+ "aria-orientation": "vertical",
1782
+ style: popover.popoverProps.style,
1783
+ onKeyDown: handleKeyDown,
1784
+ className: clsx(className, "[--anchor-gap:--spacing(2)] [--anchor-padding:--spacing(1)] data-[anchor~=end]:[--anchor-offset:6px] data-[anchor~=start]:[--anchor-offset:-6px] sm:data-[anchor~=end]:[--anchor-offset:4px] sm:data-[anchor~=start]:[--anchor-offset:-4px]", "isolate w-max rounded-xl p-1", "outline outline-transparent focus:outline-hidden", "overflow-y-auto", "bg-white/75 backdrop-blur-xl dark:bg-zinc-800/75", "shadow-lg ring-1 ring-zinc-950/10 dark:ring-white/10 dark:ring-inset", "supports-[grid-template-columns:subgrid]:grid supports-[grid-template-columns:subgrid]:grid-cols-[auto_1fr_1.5rem_0.5rem_auto]", "transition data-leave:duration-100 data-leave:ease-in data-closed:data-leave:opacity-0"),
1785
+ children
1786
+ })
1787
+ }), document.body);
1788
+ }
1789
+ function DropdownItem({ className, ...props }) {
1790
+ const { close } = useDropdownContext();
1791
+ const itemCtx = use(DropdownItemContext);
1792
+ const interactiveProps = useDataInteractive({ disabled: "disabled" in props ? props.disabled ?? false : false });
1793
+ const elRef = useRef(null);
1794
+ const indexRef = useRef(-1);
1795
+ const setRef = useCallback((el) => {
1796
+ if (el && itemCtx) {
1797
+ elRef.current = el;
1798
+ indexRef.current = itemCtx.register(el);
1799
+ } else if (!el && elRef.current && itemCtx) {
1800
+ itemCtx.unregister(elRef.current);
1801
+ elRef.current = null;
1802
+ indexRef.current = -1;
1803
+ }
1804
+ }, [itemCtx]);
1805
+ const rovingProps = itemCtx && indexRef.current >= 0 ? itemCtx.getItemProps(indexRef.current) : {
1806
+ tabIndex: -1,
1807
+ "data-focus": void 0,
1808
+ ref: () => {},
1809
+ onPointerEnter: () => {},
1810
+ onClick: () => {}
1811
+ };
1812
+ const propsDisabled = "disabled" in props ? props.disabled : false;
1813
+ const propsOnClick = "onClick" in props && typeof props.onClick === "function" ? props.onClick : void 0;
1814
+ const handleClick = useCallback((e) => {
1815
+ if (propsDisabled) return;
1816
+ rovingProps.onClick();
1817
+ propsOnClick?.(e);
1818
+ close();
1819
+ }, [
1820
+ close,
1821
+ propsDisabled,
1822
+ propsOnClick,
1823
+ rovingProps
1824
+ ]);
1825
+ const classes = clsx(className, "group cursor-default rounded-lg px-3.5 py-2.5 focus:outline-hidden sm:px-3 sm:py-1.5", "text-left text-base/6 text-zinc-950 sm:text-sm/6 dark:text-white forced-colors:text-[CanvasText]", "data-focus:bg-blue-500 data-focus:text-white", "data-disabled:opacity-50", "forced-color-adjust-none forced-colors:data-focus:bg-[Highlight] forced-colors:data-focus:text-[HighlightText] forced-colors:data-focus:*:data-[slot=icon]:text-[HighlightText]", "col-span-full grid grid-cols-[auto_1fr_1.5rem_0.5rem_auto] items-center supports-[grid-template-columns:subgrid]:grid-cols-subgrid", "*:data-[slot=icon]:col-start-1 *:data-[slot=icon]:row-start-1 *:data-[slot=icon]:mr-2.5 *:data-[slot=icon]:-ml-0.5 *:data-[slot=icon]:size-5 sm:*:data-[slot=icon]:mr-2 sm:*:data-[slot=icon]:size-4", "*:data-[slot=icon]:text-zinc-500 data-focus:*:data-[slot=icon]:text-white dark:*:data-[slot=icon]:text-zinc-400 dark:data-focus:*:data-[slot=icon]:text-white", "*:data-[slot=avatar]:mr-2.5 *:data-[slot=avatar]:-ml-1 *:data-[slot=avatar]:size-6 sm:*:data-[slot=avatar]:mr-2 sm:*:data-[slot=avatar]:size-5");
1826
+ if (typeof props.href === "string") {
1827
+ const { href, children, ...linkProps } = props;
1828
+ return /* @__PURE__ */ jsx(Link, {
1829
+ ref: setRef,
1830
+ role: "menuitem",
1831
+ href,
1832
+ ...linkProps,
1833
+ ...interactiveProps,
1834
+ tabIndex: rovingProps.tabIndex,
1835
+ "data-focus": rovingProps["data-focus"],
1836
+ onPointerEnter: rovingProps.onPointerEnter,
1837
+ onClick: handleClick,
1838
+ className: classes,
1839
+ children
1840
+ });
1841
+ }
1842
+ const { disabled, children, onClick: _onClick, ...buttonProps } = props;
1843
+ return /* @__PURE__ */ jsx("button", {
1844
+ ref: setRef,
1845
+ role: "menuitem",
1846
+ type: "button",
1847
+ disabled,
1848
+ ...buttonProps,
1849
+ ...interactiveProps,
1850
+ tabIndex: rovingProps.tabIndex,
1851
+ "data-focus": rovingProps["data-focus"],
1852
+ onPointerEnter: rovingProps.onPointerEnter,
1853
+ onClick: handleClick,
1854
+ className: classes,
1855
+ children
1856
+ });
1857
+ }
1858
+ function DropdownHeader({ className, ...props }) {
1859
+ return /* @__PURE__ */ jsx("div", {
1860
+ ...props,
1861
+ className: clsx(className, "col-span-5 px-3.5 pt-2.5 pb-1 sm:px-3")
1862
+ });
1863
+ }
1864
+ function DropdownSection({ className, ...props }) {
1865
+ return /* @__PURE__ */ jsx("div", {
1866
+ role: "group",
1867
+ ...props,
1868
+ className: clsx(className, "col-span-full supports-[grid-template-columns:subgrid]:grid supports-[grid-template-columns:subgrid]:grid-cols-[auto_1fr_1.5rem_0.5rem_auto]")
1869
+ });
1870
+ }
1871
+ function DropdownHeading({ className, ...props }) {
1872
+ return /* @__PURE__ */ jsx("div", {
1873
+ role: "presentation",
1874
+ ...props,
1875
+ className: clsx(className, "col-span-full grid grid-cols-[1fr_auto] gap-x-12 px-3.5 pt-2 pb-1 text-sm/5 font-medium text-zinc-500 sm:px-3 sm:text-xs/5 dark:text-zinc-400")
1876
+ });
1877
+ }
1878
+ function DropdownDivider({ className, ...props }) {
1879
+ return /* @__PURE__ */ jsx("hr", {
1880
+ ...props,
1881
+ className: clsx(className, "col-span-full mx-3.5 my-1 h-px border-0 bg-zinc-950/5 sm:mx-3 dark:bg-white/10 forced-colors:bg-[CanvasText]")
1882
+ });
1883
+ }
1884
+ function DropdownLabel({ className, ...props }) {
1885
+ return /* @__PURE__ */ jsx("div", {
1886
+ ...props,
1887
+ "data-slot": "label",
1888
+ className: clsx(className, "col-start-2 row-start-1")
1889
+ });
1890
+ }
1891
+ function DropdownDescription({ className, ...props }) {
1892
+ return /* @__PURE__ */ jsx("span", {
1893
+ "data-slot": "description",
1894
+ ...props,
1895
+ className: clsx(className, "col-span-2 col-start-2 row-start-2 text-sm/5 text-zinc-500 group-data-focus:text-white sm:text-xs/5 dark:text-zinc-400 forced-colors:group-data-focus:text-[HighlightText]")
1896
+ });
1897
+ }
1898
+ function DropdownShortcut({ keys, className, ...props }) {
1899
+ return /* @__PURE__ */ jsx("kbd", {
1900
+ ...props,
1901
+ className: clsx(className, "col-start-5 row-start-1 flex justify-self-end"),
1902
+ children: (Array.isArray(keys) ? keys : keys.split("")).map((char, index) => {
1903
+ return /* @__PURE__ */ jsx("kbd", {
1904
+ className: clsx(["min-w-[2ch] text-center font-sans text-zinc-400 capitalize group-data-focus:text-white forced-colors:group-data-focus:text-[HighlightText]", index > 0 && char.length > 1 && "pl-1"]),
1905
+ children: char
1906
+ }, `${char}-${index}`);
1907
+ })
1908
+ });
1909
+ }
1910
+ //#endregion
1911
+ //#region src/components/fieldset.tsx
1912
+ function Fieldset({ className, disabled, ...props }) {
1913
+ return /* @__PURE__ */ jsx("fieldset", {
1914
+ disabled,
1915
+ ...props,
1916
+ className: clsx(className, "*:data-[slot=text]:mt-1 [&>*+[data-slot=control]]:mt-6")
1917
+ });
1918
+ }
1919
+ function Legend({ className, ...props }) {
1920
+ return /* @__PURE__ */ jsx("legend", {
1921
+ "data-slot": "legend",
1922
+ ...props,
1923
+ className: clsx(className, "text-base/6 font-semibold text-zinc-950 data-disabled:opacity-50 sm:text-sm/6 dark:text-white")
1924
+ });
1925
+ }
1926
+ function FieldGroup({ className, ...props }) {
1927
+ return /* @__PURE__ */ jsx("div", {
1928
+ "data-slot": "control",
1929
+ ...props,
1930
+ className: clsx(className, "space-y-8")
1931
+ });
1932
+ }
1933
+ function Field({ className, disabled, ...props }) {
1934
+ return /* @__PURE__ */ jsx(FieldProvider, {
1935
+ disabled,
1936
+ children: /* @__PURE__ */ jsx("div", {
1937
+ ...props,
1938
+ "data-disabled": disabled ? "" : void 0,
1939
+ className: clsx(className, "[&>[data-slot=label]+[data-slot=control]]:mt-3", "[&>[data-slot=label]+[data-slot=description]]:mt-1", "[&>[data-slot=description]+[data-slot=control]]:mt-3", "[&>[data-slot=control]+[data-slot=description]]:mt-3", "[&>[data-slot=control]+[data-slot=error]]:mt-3", "*:data-[slot=label]:font-medium")
1940
+ })
1941
+ });
1942
+ }
1943
+ function Label({ className, ...props }) {
1944
+ const fieldLabelProps = useFieldLabelProps();
1945
+ return /* @__PURE__ */ jsx("label", {
1946
+ "data-slot": "label",
1947
+ ...fieldLabelProps,
1948
+ ...props,
1949
+ className: clsx(className, "text-base/6 text-zinc-950 select-none data-disabled:opacity-50 sm:text-sm/6 dark:text-white")
1950
+ });
1951
+ }
1952
+ function Description({ className, ...props }) {
1953
+ const fieldDescriptionProps = useFieldDescriptionProps();
1954
+ return /* @__PURE__ */ jsx("p", {
1955
+ "data-slot": "description",
1956
+ ...fieldDescriptionProps,
1957
+ ...props,
1958
+ className: clsx(className, "text-base/6 text-zinc-500 data-disabled:opacity-50 sm:text-sm/6 dark:text-zinc-400")
1959
+ });
1960
+ }
1961
+ function ErrorMessage({ className, ...props }) {
1962
+ const fieldErrorProps = useFieldErrorProps();
1963
+ return /* @__PURE__ */ jsx("p", {
1964
+ "data-slot": "error",
1965
+ ...fieldErrorProps,
1966
+ ...props,
1967
+ className: clsx(className, "text-base/6 text-red-600 data-disabled:opacity-50 sm:text-sm/6 dark:text-red-500")
1968
+ });
1969
+ }
1970
+ //#endregion
1971
+ //#region src/components/input-headless.tsx
1972
+ function InputGroup({ children }) {
1973
+ return /* @__PURE__ */ jsx("span", {
1974
+ "data-slot": "control",
1975
+ className: clsx("relative isolate block", "has-[[data-slot=icon]:first-child]:[&_input]:pl-10 has-[[data-slot=icon]:last-child]:[&_input]:pr-10 sm:has-[[data-slot=icon]:first-child]:[&_input]:pl-8 sm:has-[[data-slot=icon]:last-child]:[&_input]:pr-8", "*:data-[slot=icon]:pointer-events-none *:data-[slot=icon]:absolute *:data-[slot=icon]:top-3 *:data-[slot=icon]:z-10 *:data-[slot=icon]:size-5 sm:*:data-[slot=icon]:top-2.5 sm:*:data-[slot=icon]:size-4", "[&>[data-slot=icon]:first-child]:left-3 sm:[&>[data-slot=icon]:first-child]:left-2.5 [&>[data-slot=icon]:last-child]:right-3 sm:[&>[data-slot=icon]:last-child]:right-2.5", "*:data-[slot=icon]:text-zinc-500 dark:*:data-[slot=icon]:text-zinc-400"),
1976
+ children
1977
+ });
1978
+ }
1979
+ var dateTypes = [
1980
+ "date",
1981
+ "datetime-local",
1982
+ "month",
1983
+ "time",
1984
+ "week"
1985
+ ];
1986
+ function Input({ className, disabled, invalid, ref, ...props }) {
1987
+ const interactiveProps = useDataInteractive({ disabled });
1988
+ const fieldProps = useFieldControlProps();
1989
+ return /* @__PURE__ */ jsx("span", {
1990
+ "data-slot": "control",
1991
+ className: clsx([
1992
+ className,
1993
+ "relative block w-full",
1994
+ "before:absolute before:inset-px before:rounded-[calc(var(--radius-lg)-1px)] before:bg-white before:shadow-sm",
1995
+ "dark:before:hidden",
1996
+ "after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:ring-transparent after:ring-inset sm:focus-within:after:ring-2 sm:focus-within:after:ring-blue-500",
1997
+ "has-data-disabled:opacity-50 has-data-disabled:before:bg-zinc-950/5 has-data-disabled:before:shadow-none"
1998
+ ]),
1999
+ children: /* @__PURE__ */ jsx("input", {
2000
+ ref,
2001
+ disabled,
2002
+ ...props,
2003
+ ...interactiveProps,
2004
+ ...fieldProps,
2005
+ "data-invalid": invalid ? "" : void 0,
2006
+ "data-disabled": disabled ? "" : void 0,
2007
+ className: clsx([
2008
+ props.type && dateTypes.includes(props.type) && [
2009
+ "[&::-webkit-datetime-edit-fields-wrapper]:p-0",
2010
+ "[&::-webkit-date-and-time-value]:min-h-[1.5em]",
2011
+ "[&::-webkit-datetime-edit]:inline-flex",
2012
+ "[&::-webkit-datetime-edit]:p-0",
2013
+ "[&::-webkit-datetime-edit-year-field]:p-0",
2014
+ "[&::-webkit-datetime-edit-month-field]:p-0",
2015
+ "[&::-webkit-datetime-edit-day-field]:p-0",
2016
+ "[&::-webkit-datetime-edit-hour-field]:p-0",
2017
+ "[&::-webkit-datetime-edit-minute-field]:p-0",
2018
+ "[&::-webkit-datetime-edit-second-field]:p-0",
2019
+ "[&::-webkit-datetime-edit-millisecond-field]:p-0",
2020
+ "[&::-webkit-datetime-edit-meridiem-field]:p-0"
2021
+ ],
2022
+ "relative block w-full appearance-none rounded-lg px-[calc(--spacing(3.5)-1px)] py-[calc(--spacing(2.5)-1px)] sm:px-[calc(--spacing(3)-1px)] sm:py-[calc(--spacing(1.5)-1px)]",
2023
+ "text-base/6 text-zinc-950 placeholder:text-zinc-500 sm:text-sm/6 dark:text-white",
2024
+ "border border-zinc-950/10 data-hover:border-zinc-950/20 dark:border-white/10 dark:data-hover:border-white/20",
2025
+ "bg-transparent dark:bg-white/5",
2026
+ "focus:outline-hidden",
2027
+ "data-invalid:border-red-500 data-invalid:data-hover:border-red-500 dark:data-invalid:border-red-600 dark:data-invalid:data-hover:border-red-600",
2028
+ "data-disabled:border-zinc-950/20 dark:data-disabled:border-white/15 dark:data-disabled:bg-white/2.5 dark:data-hover:data-disabled:border-white/15",
2029
+ "dark:scheme-dark"
2030
+ ])
2031
+ })
2032
+ });
2033
+ }
2034
+ //#endregion
2035
+ //#region src/components/kbd.tsx
2036
+ function Kbd({ className, children, ...props }) {
2037
+ return /* @__PURE__ */ jsx("kbd", {
2038
+ ...props,
2039
+ className: clsx("inline-flex items-center rounded border border-zinc-300 bg-zinc-100 px-1.5 py-0.5 font-mono text-xs font-medium text-zinc-700 dark:border-zinc-600 dark:bg-zinc-800 dark:text-zinc-300", className),
2040
+ children
2041
+ });
2042
+ }
2043
+ function KbdShortcut({ keys, separator = "+", className }) {
2044
+ return /* @__PURE__ */ jsx("span", {
2045
+ className: clsx("inline-flex items-center gap-1", className),
2046
+ children: keys.map((key, i) => /* @__PURE__ */ jsxs("span", {
2047
+ className: "inline-flex items-center gap-1",
2048
+ children: [/* @__PURE__ */ jsx(Kbd, { children: key }), i < keys.length - 1 && /* @__PURE__ */ jsx("span", {
2049
+ className: "text-xs text-zinc-400",
2050
+ children: separator
2051
+ })]
2052
+ }, i))
2053
+ });
2054
+ }
2055
+ //#endregion
2056
+ //#region src/components/listbox.tsx
2057
+ var ListboxContext = createContext(null);
2058
+ function useListboxContext() {
2059
+ const ctx = use(ListboxContext);
2060
+ if (!ctx) throw new Error("Listbox compound components must be used within <Listbox>");
2061
+ return ctx;
2062
+ }
2063
+ function countOptions(children) {
2064
+ let count = 0;
2065
+ Children.forEach(children, (child) => {
2066
+ if (!isValidElement(child)) return;
2067
+ if (child.type === ListboxOption) count++;
2068
+ });
2069
+ return count;
2070
+ }
2071
+ var OptionIndexContext = createContext(-1);
2072
+ function OptionIndexProvider({ children }) {
2073
+ let index = 0;
2074
+ return /* @__PURE__ */ jsx(Fragment, { children: Children.map(children, (child) => {
2075
+ if (!isValidElement(child)) return child;
2076
+ if (child.type === ListboxOption) {
2077
+ const currentIndex = index++;
2078
+ return /* @__PURE__ */ jsx(OptionIndexContext.Provider, {
2079
+ value: currentIndex,
2080
+ children: child
2081
+ });
2082
+ }
2083
+ return child;
2084
+ }) });
2085
+ }
2086
+ function Listbox({ className, placeholder, autoFocus = false, "aria-label": ariaLabel, children: options, value: controlledValue, defaultValue, onChange, disabled = false, name }) {
2087
+ const [value, setValue] = useControllableState({
2088
+ value: controlledValue,
2089
+ defaultValue,
2090
+ onChange
2091
+ });
2092
+ const [open, setOpen] = useState(false);
2093
+ const [activeIndex, setActiveIndex] = useState(-1);
2094
+ const [optionCount, setOptionCount] = useState(0);
2095
+ const buttonId = useId();
2096
+ const listId = useId();
2097
+ const optionMapRef = useRef(/* @__PURE__ */ new Map());
2098
+ const registerOption = useCallback((index, optValue, element) => {
2099
+ optionMapRef.current.set(index, {
2100
+ value: optValue,
2101
+ element
2102
+ });
2103
+ }, []);
2104
+ const { triggerRef, popoverRef, popoverProps } = usePopover({
2105
+ open,
2106
+ anchor: "selection start",
2107
+ gap: 0,
2108
+ padding: 16
2109
+ });
2110
+ const { mounted, nodeRef, transitionProps } = useTransition(open);
2111
+ const focusTrigger = useCallback(() => {
2112
+ triggerRef.current?.focus();
2113
+ }, [triggerRef]);
2114
+ useEffect(() => {
2115
+ setOptionCount(countOptions(options));
2116
+ }, [options]);
2117
+ useEffect(() => {
2118
+ if (autoFocus && !disabled) focusTrigger();
2119
+ }, [
2120
+ autoFocus,
2121
+ disabled,
2122
+ focusTrigger
2123
+ ]);
2124
+ useClickOutside([triggerRef, popoverRef], () => setOpen(false), open);
2125
+ useEscapeKey(() => {
2126
+ setOpen(false);
2127
+ focusTrigger();
2128
+ }, open);
2129
+ const selectActiveOption = useCallback(() => {
2130
+ const entry = optionMapRef.current.get(activeIndex);
2131
+ if (entry) {
2132
+ setValue(entry.value);
2133
+ setOpen(false);
2134
+ focusTrigger();
2135
+ }
2136
+ }, [
2137
+ activeIndex,
2138
+ focusTrigger,
2139
+ setValue
2140
+ ]);
2141
+ const handleOptionsKeyDown = useCallback((e) => {
2142
+ switch (e.key) {
2143
+ case "ArrowDown":
2144
+ e.preventDefault();
2145
+ setActiveIndex((prev) => {
2146
+ const next = prev + 1;
2147
+ return next >= optionCount ? 0 : next;
2148
+ });
2149
+ break;
2150
+ case "ArrowUp":
2151
+ e.preventDefault();
2152
+ setActiveIndex((prev) => {
2153
+ const next = prev - 1;
2154
+ return next < 0 ? optionCount - 1 : next;
2155
+ });
2156
+ break;
2157
+ case "Home":
2158
+ e.preventDefault();
2159
+ setActiveIndex(0);
2160
+ break;
2161
+ case "End":
2162
+ e.preventDefault();
2163
+ setActiveIndex(optionCount - 1);
2164
+ break;
2165
+ case "Enter":
2166
+ case " ":
2167
+ e.preventDefault();
2168
+ selectActiveOption();
2169
+ break;
2170
+ }
2171
+ }, [optionCount, selectActiveOption]);
2172
+ useEffect(() => {
2173
+ if (!open || activeIndex < 0) return;
2174
+ optionMapRef.current.get(activeIndex)?.element?.scrollIntoView({ block: "nearest" });
2175
+ }, [activeIndex, open]);
2176
+ useEffect(() => {
2177
+ if (open) {
2178
+ let selectedIdx = -1;
2179
+ for (const [idx, entry] of optionMapRef.current.entries()) if (entry.value === value) {
2180
+ selectedIdx = idx;
2181
+ break;
2182
+ }
2183
+ setActiveIndex(selectedIdx >= 0 ? selectedIdx : 0);
2184
+ }
2185
+ }, [open, value]);
2186
+ useEffect(() => {
2187
+ if (mounted && popoverRef.current) popoverRef.current.focus({ preventScroll: true });
2188
+ }, [mounted, popoverRef]);
2189
+ const selectedContent = useMemo(() => {
2190
+ let matched = null;
2191
+ Children.forEach(options, (child) => {
2192
+ if (!isValidElement(child)) return;
2193
+ if (child.type === ListboxOption && child.props.value === value) matched = child.props.children;
2194
+ });
2195
+ return matched;
2196
+ }, [options, value]);
2197
+ const ctx = useMemo(() => ({
2198
+ value,
2199
+ setValue,
2200
+ open,
2201
+ setOpen,
2202
+ disabled,
2203
+ activeIndex,
2204
+ setActiveIndex,
2205
+ registerOption,
2206
+ optionCount,
2207
+ buttonId,
2208
+ listId
2209
+ }), [
2210
+ value,
2211
+ setValue,
2212
+ open,
2213
+ disabled,
2214
+ activeIndex,
2215
+ registerOption,
2216
+ optionCount,
2217
+ buttonId,
2218
+ listId
2219
+ ]);
2220
+ const handleButtonClick = useCallback(() => {
2221
+ if (!disabled) setOpen((prev) => !prev);
2222
+ }, [disabled]);
2223
+ const handleButtonKeyDown = useCallback((e) => {
2224
+ if (disabled) return;
2225
+ if (e.key === "ArrowDown" || e.key === "ArrowUp" || e.key === "Enter" || e.key === " ") {
2226
+ e.preventDefault();
2227
+ setOpen(true);
2228
+ }
2229
+ }, [disabled]);
2230
+ const selectedSharedClasses = clsx("flex min-w-0 items-center", "*:data-[slot=icon]:size-5 *:data-[slot=icon]:shrink-0 sm:*:data-[slot=icon]:size-4", "*:data-[slot=icon]:text-zinc-500 group-data-focus/option:*:data-[slot=icon]:text-white dark:*:data-[slot=icon]:text-zinc-400", "forced-colors:*:data-[slot=icon]:text-[CanvasText] forced-colors:group-data-focus/option:*:data-[slot=icon]:text-[Canvas]", "*:data-[slot=avatar]:-mx-0.5 *:data-[slot=avatar]:size-6 sm:*:data-[slot=avatar]:size-5");
2231
+ const displayContent = selectedContent != null ? /* @__PURE__ */ jsx("span", {
2232
+ className: selectedSharedClasses,
2233
+ children: selectedContent
2234
+ }) : placeholder ? /* @__PURE__ */ jsx("span", {
2235
+ className: "block truncate text-zinc-500",
2236
+ children: placeholder
2237
+ }) : null;
2238
+ return /* @__PURE__ */ jsxs(ListboxContext.Provider, {
2239
+ value: ctx,
2240
+ children: [
2241
+ name && /* @__PURE__ */ jsx("input", {
2242
+ type: "hidden",
2243
+ name,
2244
+ value: String(value ?? "")
2245
+ }),
2246
+ /* @__PURE__ */ jsxs("button", {
2247
+ ref: triggerRef,
2248
+ id: buttonId,
2249
+ type: "button",
2250
+ role: "combobox",
2251
+ "aria-expanded": open,
2252
+ "aria-haspopup": "listbox",
2253
+ "aria-controls": open ? listId : void 0,
2254
+ "aria-label": ariaLabel,
2255
+ "aria-disabled": disabled || void 0,
2256
+ "data-slot": "control",
2257
+ "data-disabled": disabled ? "" : void 0,
2258
+ "data-active": open ? "" : void 0,
2259
+ disabled,
2260
+ onClick: handleButtonClick,
2261
+ onKeyDown: handleButtonKeyDown,
2262
+ className: clsx([
2263
+ className,
2264
+ "group relative block w-full",
2265
+ "before:absolute before:inset-px before:rounded-[calc(var(--radius-lg)-1px)] before:bg-white before:shadow-sm",
2266
+ "dark:before:hidden",
2267
+ "focus:outline-hidden",
2268
+ "after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:ring-transparent after:ring-inset data-focus:after:ring-2 data-focus:after:ring-blue-500",
2269
+ "data-disabled:opacity-50 data-disabled:before:bg-zinc-950/5 data-disabled:before:shadow-none"
2270
+ ]),
2271
+ children: [/* @__PURE__ */ jsx("span", {
2272
+ className: clsx([
2273
+ "relative block w-full appearance-none rounded-lg py-[calc(--spacing(2.5)-1px)] sm:py-[calc(--spacing(1.5)-1px)]",
2274
+ "min-h-11 sm:min-h-9",
2275
+ "pr-[calc(--spacing(7)-1px)] pl-[calc(--spacing(3.5)-1px)] sm:pl-[calc(--spacing(3)-1px)]",
2276
+ "text-left text-base/6 text-zinc-950 placeholder:text-zinc-500 sm:text-sm/6 dark:text-white forced-colors:text-[CanvasText]",
2277
+ "border border-zinc-950/10 group-data-active:border-zinc-950/20 group-data-hover:border-zinc-950/20 dark:border-white/10 dark:group-data-active:border-white/20 dark:group-data-hover:border-white/20",
2278
+ "bg-transparent dark:bg-white/5",
2279
+ "group-data-invalid:border-red-500 group-data-hover:group-data-invalid:border-red-500 dark:group-data-invalid:border-red-600 dark:data-hover:group-data-invalid:border-red-600",
2280
+ "group-data-disabled:border-zinc-950/20 group-data-disabled:opacity-100 dark:group-data-disabled:border-white/15 dark:group-data-disabled:bg-white/2.5 dark:group-data-disabled:data-hover:border-white/15"
2281
+ ]),
2282
+ children: displayContent
2283
+ }), /* @__PURE__ */ jsx("span", {
2284
+ className: "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2",
2285
+ children: /* @__PURE__ */ jsxs("svg", {
2286
+ className: "size-5 stroke-zinc-500 group-data-disabled:stroke-zinc-600 sm:size-4 dark:stroke-zinc-400 forced-colors:stroke-[CanvasText]",
2287
+ viewBox: "0 0 16 16",
2288
+ "aria-hidden": "true",
2289
+ fill: "none",
2290
+ children: [/* @__PURE__ */ jsx("path", {
2291
+ d: "M5.75 10.75L8 13L10.25 10.75",
2292
+ strokeWidth: 1.5,
2293
+ strokeLinecap: "round",
2294
+ strokeLinejoin: "round"
2295
+ }), /* @__PURE__ */ jsx("path", {
2296
+ d: "M10.25 5.25L8 3L5.75 5.25",
2297
+ strokeWidth: 1.5,
2298
+ strokeLinecap: "round",
2299
+ strokeLinejoin: "round"
2300
+ })]
2301
+ })
2302
+ })]
2303
+ }),
2304
+ mounted && createPortal(/* @__PURE__ */ jsx("div", {
2305
+ ref: (node) => {
2306
+ popoverRef.current = node;
2307
+ nodeRef.current = node;
2308
+ },
2309
+ ...popoverProps,
2310
+ ...transitionProps,
2311
+ id: listId,
2312
+ role: "listbox",
2313
+ "aria-labelledby": buttonId,
2314
+ tabIndex: -1,
2315
+ onKeyDown: handleOptionsKeyDown,
2316
+ className: clsx("[--anchor-offset:-1.625rem] [--anchor-padding:--spacing(4)] sm:[--anchor-offset:-1.375rem]", "isolate w-max min-w-[calc(var(--button-width)+1.75rem)] scroll-py-1 rounded-xl p-1 select-none", "outline outline-transparent focus:outline-hidden", "overflow-y-scroll overscroll-contain", "bg-white/75 backdrop-blur-xl dark:bg-zinc-800/75", "shadow-lg ring-1 ring-zinc-950/10 dark:ring-white/10 dark:ring-inset", "transition-opacity duration-100 ease-in data-closed:data-leave:opacity-0 data-transition:pointer-events-none"),
2317
+ style: {
2318
+ ...popoverProps.style,
2319
+ minWidth: triggerRef.current ? `${triggerRef.current.getBoundingClientRect().width + 28}px` : void 0
2320
+ },
2321
+ children: /* @__PURE__ */ jsx(OptionIndexProvider, { children: options })
2322
+ }), document.body)
2323
+ ]
2324
+ });
2325
+ }
2326
+ function ListboxOption({ children, className, value: optionValue, disabled: optionDisabled = false }) {
2327
+ const ctx = useListboxContext();
2328
+ const index = use(OptionIndexContext);
2329
+ const optionRef = useRef(null);
2330
+ const isSelected = ctx.value === optionValue;
2331
+ const isFocused = ctx.activeIndex === index;
2332
+ useEffect(() => {
2333
+ ctx.registerOption(index, optionValue, optionRef.current);
2334
+ }, [
2335
+ index,
2336
+ optionValue,
2337
+ ctx.registerOption,
2338
+ ctx
2339
+ ]);
2340
+ const sharedClasses = clsx("flex min-w-0 items-center", "*:data-[slot=icon]:size-5 *:data-[slot=icon]:shrink-0 sm:*:data-[slot=icon]:size-4", "*:data-[slot=icon]:text-zinc-500 group-data-focus/option:*:data-[slot=icon]:text-white dark:*:data-[slot=icon]:text-zinc-400", "forced-colors:*:data-[slot=icon]:text-[CanvasText] forced-colors:group-data-focus/option:*:data-[slot=icon]:text-[Canvas]", "*:data-[slot=avatar]:-mx-0.5 *:data-[slot=avatar]:size-6 sm:*:data-[slot=avatar]:size-5");
2341
+ const handleClick = useCallback(() => {
2342
+ if (optionDisabled) return;
2343
+ ctx.setValue(optionValue);
2344
+ ctx.setOpen(false);
2345
+ }, [
2346
+ optionDisabled,
2347
+ ctx.setValue,
2348
+ ctx.setOpen,
2349
+ optionValue,
2350
+ ctx
2351
+ ]);
2352
+ const handlePointerEnter = useCallback(() => {
2353
+ if (!optionDisabled) ctx.setActiveIndex(index);
2354
+ }, [
2355
+ optionDisabled,
2356
+ ctx.setActiveIndex,
2357
+ index,
2358
+ ctx
2359
+ ]);
2360
+ return /* @__PURE__ */ jsxs("div", {
2361
+ ref: optionRef,
2362
+ role: "option",
2363
+ "aria-selected": isSelected,
2364
+ "aria-disabled": optionDisabled || void 0,
2365
+ "data-selected": isSelected ? "" : void 0,
2366
+ "data-focus": isFocused ? "" : void 0,
2367
+ "data-disabled": optionDisabled ? "" : void 0,
2368
+ onClick: handleClick,
2369
+ onPointerEnter: handlePointerEnter,
2370
+ tabIndex: -1,
2371
+ className: clsx("group/option grid cursor-default grid-cols-[--spacing(5)_1fr] items-baseline gap-x-2 rounded-lg py-2.5 pr-3.5 pl-2 sm:grid-cols-[--spacing(4)_1fr] sm:py-1.5 sm:pr-3 sm:pl-1.5", "text-base/6 text-zinc-950 sm:text-sm/6 dark:text-white forced-colors:text-[CanvasText]", "outline-hidden data-focus:bg-blue-500 data-focus:text-white", "forced-color-adjust-none forced-colors:data-focus:bg-[Highlight] forced-colors:data-focus:text-[HighlightText]", "data-disabled:opacity-50"),
2372
+ children: [/* @__PURE__ */ jsx("svg", {
2373
+ className: "relative hidden size-5 self-center stroke-current group-data-selected/option:inline sm:size-4",
2374
+ viewBox: "0 0 16 16",
2375
+ fill: "none",
2376
+ "aria-hidden": "true",
2377
+ children: /* @__PURE__ */ jsx("path", {
2378
+ d: "M4 8.5l3 3L12 4",
2379
+ strokeWidth: 1.5,
2380
+ strokeLinecap: "round",
2381
+ strokeLinejoin: "round"
2382
+ })
2383
+ }), /* @__PURE__ */ jsx("span", {
2384
+ className: clsx(className, sharedClasses, "col-start-2"),
2385
+ children
2386
+ })]
2387
+ });
2388
+ }
2389
+ function ListboxLabel({ className, ...props }) {
2390
+ return /* @__PURE__ */ jsx("span", {
2391
+ ...props,
2392
+ className: clsx(className, "ml-2.5 truncate first:ml-0 sm:ml-2 sm:first:ml-0")
2393
+ });
2394
+ }
2395
+ function ListboxDescription({ className, children, ...props }) {
2396
+ return /* @__PURE__ */ jsx("span", {
2397
+ ...props,
2398
+ className: clsx(className, "flex flex-1 overflow-hidden text-zinc-500 group-data-focus/option:text-white before:w-2 before:min-w-0 before:shrink dark:text-zinc-400"),
2399
+ children: /* @__PURE__ */ jsx("span", {
2400
+ className: "flex-1 truncate",
2401
+ children
2402
+ })
2403
+ });
2404
+ }
2405
+ //#endregion
2406
+ //#region src/hooks/use-layout-animation.tsx
2407
+ /**
2408
+ * Layout Animation Hook (FLIP Technique)
2409
+ *
2410
+ * Replaces motion/react's LayoutGroup + motion.span + layoutId pattern
2411
+ * with a native implementation using Web Animations API.
2412
+ *
2413
+ * The FLIP (First, Last, Invert, Play) technique:
2414
+ * 1. Record the element's position before it unmounts (First)
2415
+ * 2. Mount the new element and record its position (Last)
2416
+ * 3. Calculate the delta between positions (Invert)
2417
+ * 4. Animate from old position to new position (Play)
2418
+ *
2419
+ * @example
2420
+ * ```tsx
2421
+ * function NavSection({ children }) {
2422
+ * return <LayoutGroup>{children}</LayoutGroup>
2423
+ * }
2424
+ *
2425
+ * function NavItem({ current }) {
2426
+ * return (
2427
+ * <span>
2428
+ * {current && <LayoutIndicator layoutId="indicator" className="..." />}
2429
+ * ...
2430
+ * </span>
2431
+ * )
2432
+ * }
2433
+ * ```
2434
+ */
2435
+ var LayoutGroupContext = createContext(null);
2436
+ /**
2437
+ * Scopes layout animations to a group.
2438
+ * Elements with the same `layoutId` within a group share position data.
2439
+ */
2440
+ function LayoutGroup({ children }) {
2441
+ return /* @__PURE__ */ jsx(LayoutGroupContext, {
2442
+ value: useRef(/* @__PURE__ */ new Map()),
2443
+ children
2444
+ });
2445
+ }
2446
+ /** Spring-like easing approximation (matches motion's default layout spring) */
2447
+ var LAYOUT_EASING = "cubic-bezier(0.25, 0.8, 0.25, 1)";
2448
+ var LAYOUT_DURATION = 350;
2449
+ /**
2450
+ * Hook that implements FLIP layout animation for an element.
2451
+ *
2452
+ * When an element with the same `layoutId` unmounts from one position
2453
+ * and mounts in another, this hook animates the transition smoothly.
2454
+ *
2455
+ * @param layoutId - Shared identifier linking old and new positions
2456
+ * @returns Ref to attach to the animated element
2457
+ */
2458
+ function useLayoutAnimation(layoutId) {
2459
+ const ref = useRef(null);
2460
+ const rectsCtx = use(LayoutGroupContext);
2461
+ useLayoutEffect(() => {
2462
+ const el = ref.current;
2463
+ const rects = rectsCtx?.current;
2464
+ if (!(el && rects)) return;
2465
+ const prevRect = rects.get(layoutId);
2466
+ const currentRect = el.getBoundingClientRect();
2467
+ rects.set(layoutId, currentRect);
2468
+ if (prevRect) {
2469
+ const deltaX = prevRect.left - currentRect.left;
2470
+ const deltaY = prevRect.top - currentRect.top;
2471
+ if (Math.abs(deltaX) > .5 || Math.abs(deltaY) > .5) el.animate([{ transform: `translate(${deltaX}px, ${deltaY}px)` }, { transform: "translate(0, 0)" }], {
2472
+ duration: LAYOUT_DURATION,
2473
+ easing: LAYOUT_EASING,
2474
+ fill: "none"
2475
+ });
2476
+ }
2477
+ return () => {
2478
+ if (el) rects.set(layoutId, el.getBoundingClientRect());
2479
+ };
2480
+ });
2481
+ return ref;
2482
+ }
2483
+ /**
2484
+ * Animated indicator span that smoothly transitions between positions.
2485
+ * Drop-in replacement for `<motion.span layoutId="...">`.
2486
+ */
2487
+ function LayoutIndicator({ layoutId, ...props }) {
2488
+ return /* @__PURE__ */ jsx("span", {
2489
+ ref: useLayoutAnimation(layoutId),
2490
+ ...props
2491
+ });
2492
+ }
2493
+ //#endregion
2494
+ //#region src/components/navbar.tsx
2495
+ function Navbar({ className, ...props }) {
2496
+ return /* @__PURE__ */ jsx("nav", {
2497
+ ...props,
2498
+ className: clsx(className, "flex flex-1 items-center gap-4 py-2.5")
2499
+ });
2500
+ }
2501
+ function NavbarDivider({ className, ...props }) {
2502
+ return /* @__PURE__ */ jsx("div", {
2503
+ "aria-hidden": "true",
2504
+ ...props,
2505
+ className: clsx(className, "h-6 w-px bg-zinc-950/10 dark:bg-white/10")
2506
+ });
2507
+ }
2508
+ function NavbarSection({ className, ...props }) {
2509
+ return /* @__PURE__ */ jsx(LayoutGroup, {
2510
+ id: useId(),
2511
+ children: /* @__PURE__ */ jsx("div", {
2512
+ ...props,
2513
+ className: clsx(className, "flex items-center gap-3")
2514
+ })
2515
+ });
2516
+ }
2517
+ function NavbarSpacer({ className, ...props }) {
2518
+ return /* @__PURE__ */ jsx("div", {
2519
+ "aria-hidden": "true",
2520
+ ...props,
2521
+ className: clsx(className, "-ml-4 flex-1")
2522
+ });
2523
+ }
2524
+ function NavbarItem({ current, className, children, ref, ...props }) {
2525
+ const interactiveProps = useDataInteractive({ disabled: ("disabled" in props ? props.disabled : false) ?? false });
2526
+ const classes = clsx("relative flex min-w-0 items-center gap-3 rounded-lg p-2 text-left text-base/6 font-medium text-zinc-950 sm:text-sm/5", "*:data-[slot=icon]:size-6 *:data-[slot=icon]:shrink-0 *:data-[slot=icon]:fill-zinc-500 sm:*:data-[slot=icon]:size-5", "*:not-nth-2:last:data-[slot=icon]:ml-auto *:not-nth-2:last:data-[slot=icon]:size-5 sm:*:not-nth-2:last:data-[slot=icon]:size-4", "*:data-[slot=avatar]:-m-0.5 *:data-[slot=avatar]:size-7 *:data-[slot=avatar]:[--avatar-radius:var(--radius-md)] sm:*:data-[slot=avatar]:size-6", "data-hover:bg-zinc-950/5 data-hover:*:data-[slot=icon]:fill-zinc-950", "data-active:bg-zinc-950/5 data-active:*:data-[slot=icon]:fill-zinc-950", "dark:text-white dark:*:data-[slot=icon]:fill-zinc-400", "dark:data-hover:bg-white/5 dark:data-hover:*:data-[slot=icon]:fill-white", "dark:data-active:bg-white/5 dark:data-active:*:data-[slot=icon]:fill-white");
2527
+ return /* @__PURE__ */ jsxs("span", {
2528
+ className: clsx(className, "relative"),
2529
+ children: [current && /* @__PURE__ */ jsx(LayoutIndicator, {
2530
+ layoutId: "current-indicator",
2531
+ className: "absolute inset-x-2 -bottom-2.5 h-0.5 rounded-full bg-zinc-950 dark:bg-white"
2532
+ }), typeof props.href === "string" ? /* @__PURE__ */ jsx(Link, {
2533
+ ...props,
2534
+ className: classes,
2535
+ "data-current": current ? "true" : void 0,
2536
+ ref,
2537
+ children: /* @__PURE__ */ jsx(TouchTarget, { children })
2538
+ }) : /* @__PURE__ */ jsx("button", {
2539
+ type: "button",
2540
+ ...props,
2541
+ ...interactiveProps,
2542
+ className: clsx("cursor-default", classes),
2543
+ "data-current": current ? "true" : void 0,
2544
+ ref,
2545
+ children: /* @__PURE__ */ jsx(TouchTarget, { children })
2546
+ })]
2547
+ });
2548
+ }
2549
+ function NavbarLabel({ className, ...props }) {
2550
+ return /* @__PURE__ */ jsx("span", {
2551
+ ...props,
2552
+ className: clsx(className, "truncate")
2553
+ });
2554
+ }
2555
+ //#endregion
2556
+ //#region src/components/progress.tsx
2557
+ var trackClasses = {
2558
+ blue: "bg-blue-600 dark:bg-blue-500",
2559
+ green: "bg-green-600 dark:bg-green-500",
2560
+ red: "bg-red-600 dark:bg-red-500",
2561
+ amber: "bg-amber-500 dark:bg-amber-400",
2562
+ violet: "bg-violet-600 dark:bg-violet-500",
2563
+ zinc: "bg-zinc-600 dark:bg-zinc-400"
2564
+ };
2565
+ function Progress({ value, max = 100, color = "blue", size = "md", label, showValue = false, className }) {
2566
+ const percentage = Math.min(100, Math.max(0, value / max * 100));
2567
+ const heightClass = {
2568
+ xs: "h-1",
2569
+ sm: "h-1.5",
2570
+ md: "h-2.5",
2571
+ lg: "h-4"
2572
+ }[size];
2573
+ return /* @__PURE__ */ jsxs("div", {
2574
+ className: clsx("w-full", className),
2575
+ children: [(label || showValue) && /* @__PURE__ */ jsxs("div", {
2576
+ className: "mb-1.5 flex items-center justify-between",
2577
+ children: [label && /* @__PURE__ */ jsx("span", {
2578
+ className: "text-sm font-medium text-zinc-700 dark:text-zinc-300",
2579
+ children: label
2580
+ }), showValue && /* @__PURE__ */ jsxs("span", {
2581
+ className: "text-sm text-zinc-500 dark:text-zinc-400",
2582
+ children: [Math.round(percentage), "%"]
2583
+ })]
2584
+ }), /* @__PURE__ */ jsx("div", {
2585
+ role: "progressbar",
2586
+ "aria-valuenow": value,
2587
+ "aria-valuemin": 0,
2588
+ "aria-valuemax": max,
2589
+ "aria-label": label ?? "Progress",
2590
+ className: clsx("w-full overflow-hidden rounded-full bg-zinc-200 dark:bg-zinc-700", heightClass),
2591
+ children: /* @__PURE__ */ jsx("div", {
2592
+ className: clsx("h-full rounded-full transition-all duration-300 ease-in-out", trackClasses[color]),
2593
+ style: { width: `${percentage}%` }
2594
+ })
2595
+ })]
2596
+ });
2597
+ }
2598
+ //#endregion
2599
+ //#region src/components/radio.tsx
2600
+ var RadioGroupContext = createContext(null);
2601
+ function useRadioGroupContext() {
2602
+ const ctx = use(RadioGroupContext);
2603
+ if (!ctx) throw new Error("Radio must be used within a RadioGroup");
2604
+ return ctx;
2605
+ }
2606
+ function RadioGroup({ className, value: controlledValue, defaultValue, onChange, disabled = false, name, children, ...props }) {
2607
+ const [value, setValue] = useControllableState({
2608
+ value: controlledValue,
2609
+ defaultValue: defaultValue ?? "",
2610
+ onChange
2611
+ });
2612
+ const handleKeyDown = useCallback((e) => {
2613
+ const radios = Array.from(e.currentTarget.querySelectorAll("[role=\"radio\"]:not([data-disabled])"));
2614
+ if (radios.length === 0) return;
2615
+ const currentIndex = radios.indexOf(document.activeElement);
2616
+ let nextIndex = currentIndex;
2617
+ switch (e.key) {
2618
+ case "ArrowDown":
2619
+ case "ArrowRight":
2620
+ e.preventDefault();
2621
+ nextIndex = currentIndex + 1 >= radios.length ? 0 : currentIndex + 1;
2622
+ break;
2623
+ case "ArrowUp":
2624
+ case "ArrowLeft":
2625
+ e.preventDefault();
2626
+ nextIndex = currentIndex - 1 < 0 ? radios.length - 1 : currentIndex - 1;
2627
+ break;
2628
+ case "Home":
2629
+ e.preventDefault();
2630
+ nextIndex = 0;
2631
+ break;
2632
+ case "End":
2633
+ e.preventDefault();
2634
+ nextIndex = radios.length - 1;
2635
+ break;
2636
+ default: return;
2637
+ }
2638
+ const nextRadio = radios[nextIndex];
2639
+ if (!nextRadio) return;
2640
+ nextRadio.focus();
2641
+ const radioValue = nextRadio.getAttribute("data-value");
2642
+ if (radioValue != null) setValue(radioValue);
2643
+ }, [setValue]);
2644
+ return /* @__PURE__ */ jsx(RadioGroupContext, {
2645
+ value: {
2646
+ value,
2647
+ onChange: setValue,
2648
+ disabled,
2649
+ name
2650
+ },
2651
+ children: /* @__PURE__ */ jsx("div", {
2652
+ role: "radiogroup",
2653
+ "data-slot": "control",
2654
+ onKeyDown: handleKeyDown,
2655
+ ...props,
2656
+ className: clsx(className, "space-y-3 **:data-[slot=label]:font-normal", "has-data-[slot=description]:space-y-6 has-data-[slot=description]:**:data-[slot=label]:font-medium"),
2657
+ children
2658
+ })
2659
+ });
2660
+ }
2661
+ function RadioField({ className, disabled, ...props }) {
2662
+ return /* @__PURE__ */ jsx(FieldProvider, {
2663
+ disabled,
2664
+ children: /* @__PURE__ */ jsx("div", {
2665
+ "data-slot": "field",
2666
+ "data-disabled": disabled ? "" : void 0,
2667
+ ...props,
2668
+ className: clsx(className, "grid grid-cols-[1.125rem_1fr] gap-x-4 gap-y-1 sm:grid-cols-[1rem_1fr]", "*:data-[slot=control]:col-start-1 *:data-[slot=control]:row-start-1 *:data-[slot=control]:mt-0.75 sm:*:data-[slot=control]:mt-1", "*:data-[slot=label]:col-start-2 *:data-[slot=label]:row-start-1", "*:data-[slot=description]:col-start-2 *:data-[slot=description]:row-start-2", "has-data-[slot=description]:**:data-[slot=label]:font-medium")
2669
+ })
2670
+ });
2671
+ }
2672
+ var base = [
2673
+ "relative isolate flex size-4.75 shrink-0 rounded-full sm:size-4.25",
2674
+ "before:absolute before:inset-0 before:-z-10 before:rounded-full before:bg-white before:shadow-sm",
2675
+ "group-data-checked:before:bg-(--radio-checked-bg)",
2676
+ "dark:before:hidden",
2677
+ "dark:bg-white/5 dark:group-data-checked:bg-(--radio-checked-bg)",
2678
+ "border border-zinc-950/15 group-data-checked:border-transparent group-data-hover:group-data-checked:border-transparent group-data-hover:border-zinc-950/30 group-data-checked:bg-(--radio-checked-border)",
2679
+ "dark:border-white/15 dark:group-data-checked:border-white/5 dark:group-data-hover:group-data-checked:border-white/5 dark:group-data-hover:border-white/30",
2680
+ "after:absolute after:inset-0 after:rounded-full after:shadow-[inset_0_1px_--theme(--color-white/15%)]",
2681
+ "dark:after:-inset-px dark:after:hidden dark:after:rounded-full dark:group-data-checked:after:block",
2682
+ "[--radio-indicator:transparent] group-data-checked:[--radio-indicator:var(--radio-checked-indicator)] group-data-hover:group-data-checked:[--radio-indicator:var(--radio-checked-indicator)] group-data-hover:[--radio-indicator:var(--color-zinc-900)]/10",
2683
+ "dark:group-data-hover:group-data-checked:[--radio-indicator:var(--radio-checked-indicator)] dark:group-data-hover:[--radio-indicator:var(--color-zinc-700)]",
2684
+ "group-data-focus:outline group-data-focus:outline-2 group-data-focus:outline-offset-2 group-data-focus:outline-blue-500",
2685
+ "group-data-disabled:opacity-50",
2686
+ "group-data-disabled:border-zinc-950/25 group-data-disabled:bg-zinc-950/5 group-data-disabled:[--radio-checked-indicator:var(--color-zinc-950)]/50 group-data-disabled:before:bg-transparent",
2687
+ "dark:group-data-disabled:border-white/20 dark:group-data-disabled:bg-white/2.5 dark:group-data-disabled:[--radio-checked-indicator:var(--color-white)]/50 dark:group-data-checked:group-data-disabled:after:hidden"
2688
+ ];
2689
+ var radioColors = {
2690
+ "dark/zinc": ["[--radio-checked-bg:var(--color-zinc-900)] [--radio-checked-border:var(--color-zinc-950)]/90 [--radio-checked-indicator:var(--color-white)]", "dark:[--radio-checked-bg:var(--color-zinc-600)]"],
2691
+ "dark/white": ["[--radio-checked-bg:var(--color-zinc-900)] [--radio-checked-border:var(--color-zinc-950)]/90 [--radio-checked-indicator:var(--color-white)]", "dark:[--radio-checked-bg:var(--color-white)] dark:[--radio-checked-border:var(--color-zinc-950)]/15 dark:[--radio-checked-indicator:var(--color-zinc-900)]"],
2692
+ white: "[--radio-checked-bg:var(--color-white)] [--radio-checked-border:var(--color-zinc-950)]/15 [--radio-checked-indicator:var(--color-zinc-900)]",
2693
+ dark: "[--radio-checked-bg:var(--color-zinc-900)] [--radio-checked-border:var(--color-zinc-950)]/90 [--radio-checked-indicator:var(--color-white)]",
2694
+ zinc: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-zinc-600)] [--radio-checked-border:var(--color-zinc-700)]/90",
2695
+ red: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-red-600)] [--radio-checked-border:var(--color-red-700)]/90",
2696
+ orange: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-orange-500)] [--radio-checked-border:var(--color-orange-600)]/90",
2697
+ amber: "[--radio-checked-bg:var(--color-amber-400)] [--radio-checked-border:var(--color-amber-500)]/80 [--radio-checked-indicator:var(--color-amber-950)]",
2698
+ yellow: "[--radio-checked-bg:var(--color-yellow-300)] [--radio-checked-border:var(--color-yellow-400)]/80 [--radio-checked-indicator:var(--color-yellow-950)]",
2699
+ lime: "[--radio-checked-bg:var(--color-lime-300)] [--radio-checked-border:var(--color-lime-400)]/80 [--radio-checked-indicator:var(--color-lime-950)]",
2700
+ green: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-green-600)] [--radio-checked-border:var(--color-green-700)]/90",
2701
+ emerald: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-emerald-600)] [--radio-checked-border:var(--color-emerald-700)]/90",
2702
+ teal: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-teal-600)] [--radio-checked-border:var(--color-teal-700)]/90",
2703
+ cyan: "[--radio-checked-bg:var(--color-cyan-300)] [--radio-checked-border:var(--color-cyan-400)]/80 [--radio-checked-indicator:var(--color-cyan-950)]",
2704
+ sky: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-sky-500)] [--radio-checked-border:var(--color-sky-600)]/80",
2705
+ blue: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-blue-600)] [--radio-checked-border:var(--color-blue-700)]/90",
2706
+ indigo: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-indigo-500)] [--radio-checked-border:var(--color-indigo-600)]/90",
2707
+ violet: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-violet-500)] [--radio-checked-border:var(--color-violet-600)]/90",
2708
+ purple: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-purple-500)] [--radio-checked-border:var(--color-purple-600)]/90",
2709
+ fuchsia: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-fuchsia-500)] [--radio-checked-border:var(--color-fuchsia-600)]/90",
2710
+ pink: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-pink-500)] [--radio-checked-border:var(--color-pink-600)]/90",
2711
+ rose: "[--radio-checked-indicator:var(--color-white)] [--radio-checked-bg:var(--color-rose-500)] [--radio-checked-border:var(--color-rose-600)]/90"
2712
+ };
2713
+ function Radio({ color = "dark/zinc", className, value, disabled: localDisabled, ...props }) {
2714
+ const group = useRadioGroupContext();
2715
+ const disabled = localDisabled || group.disabled;
2716
+ const checked = group.value === value;
2717
+ const interactiveProps = useDataInteractive({ disabled });
2718
+ const handleClick = useCallback(() => {
2719
+ if (!disabled) group.onChange(value);
2720
+ }, [
2721
+ disabled,
2722
+ group,
2723
+ value
2724
+ ]);
2725
+ const handleKeyDown = useCallback((e) => {
2726
+ if ((e.key === " " || e.key === "Enter") && !disabled) {
2727
+ e.preventDefault();
2728
+ group.onChange(value);
2729
+ }
2730
+ }, [
2731
+ disabled,
2732
+ group,
2733
+ value
2734
+ ]);
2735
+ return /* @__PURE__ */ jsxs("span", {
2736
+ role: "radio",
2737
+ "data-slot": "control",
2738
+ "aria-checked": checked,
2739
+ "data-checked": checked ? "" : void 0,
2740
+ "data-disabled": disabled ? "" : void 0,
2741
+ "data-value": value,
2742
+ tabIndex: checked ? 0 : -1,
2743
+ onClick: handleClick,
2744
+ onKeyDown: handleKeyDown,
2745
+ ...interactiveProps,
2746
+ ...props,
2747
+ className: clsx(className, "group inline-flex focus:outline-hidden"),
2748
+ children: [group.name && checked && /* @__PURE__ */ jsx("input", {
2749
+ type: "hidden",
2750
+ name: group.name,
2751
+ value
2752
+ }), /* @__PURE__ */ jsx("span", {
2753
+ className: clsx([base, radioColors[color]]),
2754
+ children: /* @__PURE__ */ jsx("span", { className: clsx("size-full rounded-full border-[4.5px] border-transparent bg-(--radio-indicator) bg-clip-padding", "forced-colors:border-[Canvas] forced-colors:group-data-checked:border-[Highlight]") })
2755
+ })]
2756
+ });
2757
+ }
2758
+ //#endregion
2759
+ //#region src/components/rating.tsx
2760
+ function Rating({ value: controlledValue, defaultValue = 0, max = 5, onChange, readOnly = false, size = "md", label, className }) {
2761
+ const [internalValue, setInternalValue] = useState(defaultValue);
2762
+ const [hovered, setHovered] = useState(0);
2763
+ const id = useId();
2764
+ const value = controlledValue ?? internalValue;
2765
+ const sizeClass = {
2766
+ sm: "size-4",
2767
+ md: "size-6",
2768
+ lg: "size-8"
2769
+ }[size];
2770
+ const handleClick = useCallback((star) => {
2771
+ if (readOnly) return;
2772
+ setInternalValue(star);
2773
+ onChange?.(star);
2774
+ }, [readOnly, onChange]);
2775
+ const display = hovered > 0 ? hovered : value;
2776
+ return /* @__PURE__ */ jsxs("div", {
2777
+ className,
2778
+ children: [label && /* @__PURE__ */ jsx("span", {
2779
+ id,
2780
+ className: "sr-only",
2781
+ children: label
2782
+ }), /* @__PURE__ */ jsx("div", {
2783
+ role: readOnly ? "img" : "radiogroup",
2784
+ "aria-label": label ?? `Rating: ${value} out of ${max}`,
2785
+ "aria-labelledby": label ? id : void 0,
2786
+ className: "flex items-center gap-0.5",
2787
+ children: Array.from({ length: max }).map((_, i) => {
2788
+ const star = i + 1;
2789
+ const filled = star <= display;
2790
+ return /* @__PURE__ */ jsx("button", {
2791
+ type: "button",
2792
+ role: readOnly ? void 0 : "radio",
2793
+ "aria-checked": readOnly ? void 0 : value === star,
2794
+ "aria-label": readOnly ? void 0 : `${star} star${star !== 1 ? "s" : ""}`,
2795
+ disabled: readOnly,
2796
+ onClick: () => handleClick(star),
2797
+ onMouseEnter: () => !readOnly && setHovered(star),
2798
+ onMouseLeave: () => !readOnly && setHovered(0),
2799
+ className: clsx(sizeClass, "transition-colors", readOnly ? "cursor-default" : "cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500"),
2800
+ children: /* @__PURE__ */ jsx("svg", {
2801
+ viewBox: "0 0 20 20",
2802
+ "aria-hidden": "true",
2803
+ className: clsx("size-full", filled ? "fill-amber-400 text-amber-400" : "fill-zinc-200 text-zinc-200 dark:fill-zinc-700 dark:text-zinc-700"),
2804
+ children: /* @__PURE__ */ jsx("path", { d: "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" })
2805
+ })
2806
+ }, star);
2807
+ })
2808
+ })]
2809
+ });
2810
+ }
2811
+ //#endregion
2812
+ //#region src/components/Select.tsx
2813
+ var Check = ({ className }) => {
2814
+ return /* @__PURE__ */ jsxs("svg", {
2815
+ xmlns: "http://www.w3.org/2000/svg",
2816
+ fill: "none",
2817
+ viewBox: "0 0 24 24",
2818
+ strokeWidth: 1.5,
2819
+ stroke: "currentColor",
2820
+ className: cn("size-6", className),
2821
+ children: [/* @__PURE__ */ jsx("title", { children: "Selected" }), /* @__PURE__ */ jsx("path", {
2822
+ strokeLinecap: "round",
2823
+ strokeLinejoin: "round",
2824
+ d: "M6 12l4 4L18 8"
2825
+ })]
2826
+ });
2827
+ };
2828
+ var ChevronUp = ({ className }) => {
2829
+ return /* @__PURE__ */ jsxs("svg", {
2830
+ xmlns: "http://www.w3.org/2000/svg",
2831
+ fill: "none",
2832
+ viewBox: "0 0 24 24",
2833
+ strokeWidth: 1.5,
2834
+ stroke: "currentColor",
2835
+ className: cn("size-6", className),
2836
+ children: [/* @__PURE__ */ jsx("title", { children: "Scroll up" }), /* @__PURE__ */ jsx("path", {
2837
+ strokeLinecap: "round",
2838
+ strokeLinejoin: "round",
2839
+ d: "M19.5 15.75l-7.5-7.5-7.5 7.5"
2840
+ })]
2841
+ });
2842
+ };
2843
+ var ChevronDown = ({ className }) => {
2844
+ return /* @__PURE__ */ jsxs("svg", {
2845
+ xmlns: "http://www.w3.org/2000/svg",
2846
+ fill: "none",
2847
+ viewBox: "0 0 24 24",
2848
+ strokeWidth: 1.5,
2849
+ stroke: "currentColor",
2850
+ className: cn("size-6", className),
2851
+ children: [/* @__PURE__ */ jsx("title", { children: "Scroll down" }), /* @__PURE__ */ jsx("path", {
2852
+ strokeLinecap: "round",
2853
+ strokeLinejoin: "round",
2854
+ d: "M4.5 8.25l7.5 7.5 7.5-7.5"
2855
+ })]
2856
+ });
2857
+ };
2858
+ function Select$1({ children, className, ref, ...props }) {
2859
+ return /* @__PURE__ */ jsx(Box, {
2860
+ ref,
2861
+ className: cn(className),
2862
+ ...props,
2863
+ children
2864
+ });
2865
+ }
2866
+ Select$1.displayName = "Select";
2867
+ function SelectGroup({ children, className, ref, ...props }) {
2868
+ return /* @__PURE__ */ jsx(Box, {
2869
+ ref,
2870
+ className: cn(className),
2871
+ ...props,
2872
+ children
2873
+ });
2874
+ }
2875
+ function SelectValue({ placeholder, children, value, ref, ...props }) {
2876
+ return /* @__PURE__ */ jsx("span", {
2877
+ ref,
2878
+ ...props,
2879
+ children: children || placeholder || value
2880
+ });
2881
+ }
2882
+ function SelectTrigger({ children, className, ref, ...props }) {
2883
+ return /* @__PURE__ */ jsxs(Box, {
2884
+ className: cn("flex h-10 w-full items-center justify-between rounded border border-input bg-background px-3 py-2 text-inherit ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", className),
2885
+ ref,
2886
+ ...props,
2887
+ children: [children, /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 opacity-50" })]
2888
+ });
2889
+ }
2890
+ SelectTrigger.displayName = "SelectTrigger";
2891
+ function SelectScrollUpButton({ className, ref, ...props }) {
2892
+ return /* @__PURE__ */ jsx("button", {
2893
+ className: cn("flex cursor-default items-center justify-center py-1", className),
2894
+ ref,
2895
+ ...props,
2896
+ children: /* @__PURE__ */ jsx(ChevronUp, { className: "size-4" })
2897
+ });
2898
+ }
2899
+ function SelectScrollDownButton({ className, ref, ...props }) {
2900
+ return /* @__PURE__ */ jsx("button", {
2901
+ className: cn("flex cursor-default items-center justify-center py-1", className),
2902
+ ref,
2903
+ ...props,
2904
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4" })
2905
+ });
2906
+ }
2907
+ function SelectContent({ children, className, ref, ...props }) {
2908
+ return /* @__PURE__ */ jsxs(Box, {
2909
+ className: cn("relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded border bg-card text-popover-foreground shadow-md", className),
2910
+ ref,
2911
+ ...props,
2912
+ children: [
2913
+ /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
2914
+ /* @__PURE__ */ jsx("div", {
2915
+ className: "p-1",
2916
+ children
2917
+ }),
2918
+ /* @__PURE__ */ jsx(SelectScrollDownButton, {})
2919
+ ]
2920
+ });
2921
+ }
2922
+ SelectContent.displayName = "SelectContent";
2923
+ function SelectLabel({ className, ref, ...props }) {
2924
+ return /* @__PURE__ */ jsx("div", {
2925
+ className: cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className),
2926
+ ref,
2927
+ ...props
2928
+ });
2929
+ }
2930
+ function SelectItem({ children, className, value, ref, ...props }) {
2931
+ return /* @__PURE__ */ jsxs(Box, {
2932
+ className: cn("relative flex w-full cursor-default select-none items-center rounded py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
2933
+ "data-value": value,
2934
+ ref,
2935
+ ...props,
2936
+ children: [/* @__PURE__ */ jsx("span", {
2937
+ className: "absolute left-2 flex size-3.5 items-center justify-center",
2938
+ children: /* @__PURE__ */ jsx(Check, { className: "size-4" })
2939
+ }), /* @__PURE__ */ jsx("span", { children })]
2940
+ });
2941
+ }
2942
+ SelectItem.displayName = "SelectItem";
2943
+ function SelectSeparator({ className, ref, ...props }) {
2944
+ return /* @__PURE__ */ jsx(Box, {
2945
+ className: cn("-mx-1 my-1 h-px bg-muted", className),
2946
+ ref,
2947
+ ...props
2948
+ });
2949
+ }
2950
+ SelectSeparator.displayName = "SelectSeparator";
2951
+ //#endregion
2952
+ //#region src/components/select-headless.tsx
2953
+ function Select({ className, multiple, disabled, invalid, ref, ...props }) {
2954
+ const interactiveProps = useDataInteractive({ disabled });
2955
+ const fieldProps = useFieldControlProps();
2956
+ return /* @__PURE__ */ jsxs("span", {
2957
+ "data-slot": "control",
2958
+ className: clsx([
2959
+ className,
2960
+ "group relative block w-full",
2961
+ "before:absolute before:inset-px before:rounded-[calc(var(--radius-lg)-1px)] before:bg-white before:shadow-sm",
2962
+ "dark:before:hidden",
2963
+ "after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:ring-transparent after:ring-inset has-data-focus:after:ring-2 has-data-focus:after:ring-blue-500",
2964
+ "has-data-disabled:opacity-50 has-data-disabled:before:bg-zinc-950/5 has-data-disabled:before:shadow-none"
2965
+ ]),
2966
+ children: [/* @__PURE__ */ jsx("select", {
2967
+ ref,
2968
+ multiple,
2969
+ disabled,
2970
+ ...props,
2971
+ ...interactiveProps,
2972
+ ...fieldProps,
2973
+ "data-invalid": invalid ? "" : void 0,
2974
+ "data-disabled": disabled ? "" : void 0,
2975
+ className: clsx([
2976
+ "relative block w-full appearance-none rounded-lg py-[calc(--spacing(2.5)-1px)] sm:py-[calc(--spacing(1.5)-1px)]",
2977
+ multiple ? "px-[calc(--spacing(3.5)-1px)] sm:px-[calc(--spacing(3)-1px)]" : "pr-[calc(--spacing(10)-1px)] pl-[calc(--spacing(3.5)-1px)] sm:pr-[calc(--spacing(9)-1px)] sm:pl-[calc(--spacing(3)-1px)]",
2978
+ "[&_optgroup]:font-semibold",
2979
+ "text-base/6 text-zinc-950 placeholder:text-zinc-500 sm:text-sm/6 dark:text-white dark:*:text-white",
2980
+ "border border-zinc-950/10 data-hover:border-zinc-950/20 dark:border-white/10 dark:data-hover:border-white/20",
2981
+ "bg-transparent dark:bg-white/5 dark:*:bg-zinc-800",
2982
+ "focus:outline-hidden",
2983
+ "data-invalid:border-red-500 data-invalid:data-hover:border-red-500 dark:data-invalid:border-red-600 dark:data-invalid:data-hover:border-red-600",
2984
+ "data-disabled:border-zinc-950/20 data-disabled:opacity-100 dark:data-disabled:border-white/15 dark:data-disabled:bg-white/2.5 dark:data-hover:data-disabled:border-white/15"
2985
+ ])
2986
+ }), !multiple && /* @__PURE__ */ jsx("span", {
2987
+ className: "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2",
2988
+ children: /* @__PURE__ */ jsxs("svg", {
2989
+ className: "size-5 stroke-zinc-500 group-has-data-disabled:stroke-zinc-600 sm:size-4 dark:stroke-zinc-400 forced-colors:stroke-[CanvasText]",
2990
+ viewBox: "0 0 16 16",
2991
+ "aria-hidden": "true",
2992
+ fill: "none",
2993
+ children: [/* @__PURE__ */ jsx("path", {
2994
+ d: "M5.75 10.75L8 13L10.25 10.75",
2995
+ strokeWidth: 1.5,
2996
+ strokeLinecap: "round",
2997
+ strokeLinejoin: "round"
2998
+ }), /* @__PURE__ */ jsx("path", {
2999
+ d: "M10.25 5.25L8 3L5.75 5.25",
3000
+ strokeWidth: 1.5,
3001
+ strokeLinecap: "round",
3002
+ strokeLinejoin: "round"
3003
+ })]
3004
+ })
3005
+ })]
3006
+ });
3007
+ }
3008
+ //#endregion
3009
+ //#region src/hooks/use-close-context.ts
3010
+ var CloseContext = createContext(null);
3011
+ function useCloseContext() {
3012
+ return useContext(CloseContext);
3013
+ }
3014
+ //#endregion
3015
+ //#region src/components/sidebar.tsx
3016
+ function Sidebar({ className, ...props }) {
3017
+ return /* @__PURE__ */ jsx("nav", {
3018
+ ...props,
3019
+ className: clsx(className, "flex h-full min-h-0 flex-col")
3020
+ });
3021
+ }
3022
+ function SidebarHeader({ className, ...props }) {
3023
+ return /* @__PURE__ */ jsx("div", {
3024
+ ...props,
3025
+ className: clsx(className, "flex flex-col border-b border-zinc-950/5 p-4 dark:border-white/5 [&>[data-slot=section]+[data-slot=section]]:mt-2.5")
3026
+ });
3027
+ }
3028
+ function SidebarBody({ className, ...props }) {
3029
+ return /* @__PURE__ */ jsx("div", {
3030
+ ...props,
3031
+ className: clsx(className, "flex flex-1 flex-col overflow-y-auto p-4 [&>[data-slot=section]+[data-slot=section]]:mt-8")
3032
+ });
3033
+ }
3034
+ function SidebarFooter({ className, ...props }) {
3035
+ return /* @__PURE__ */ jsx("div", {
3036
+ ...props,
3037
+ className: clsx(className, "flex flex-col border-t border-zinc-950/5 p-4 dark:border-white/5 [&>[data-slot=section]+[data-slot=section]]:mt-2.5")
3038
+ });
3039
+ }
3040
+ function SidebarSection({ className, ...props }) {
3041
+ return /* @__PURE__ */ jsx(LayoutGroup, {
3042
+ id: useId(),
3043
+ children: /* @__PURE__ */ jsx("div", {
3044
+ ...props,
3045
+ "data-slot": "section",
3046
+ className: clsx(className, "flex flex-col gap-0.5")
3047
+ })
3048
+ });
3049
+ }
3050
+ function SidebarDivider({ className, ...props }) {
3051
+ return /* @__PURE__ */ jsx("hr", {
3052
+ ...props,
3053
+ className: clsx(className, "my-4 border-t border-zinc-950/5 lg:-mx-4 dark:border-white/5")
3054
+ });
3055
+ }
3056
+ function SidebarSpacer({ className, ...props }) {
3057
+ return /* @__PURE__ */ jsx("div", {
3058
+ "aria-hidden": "true",
3059
+ ...props,
3060
+ className: clsx(className, "mt-8 flex-1")
3061
+ });
3062
+ }
3063
+ function SidebarHeading({ className, ...props }) {
3064
+ return /* @__PURE__ */ jsx("h3", {
3065
+ ...props,
3066
+ className: clsx(className, "mb-1 px-2 text-xs/6 font-medium text-zinc-500 dark:text-zinc-400")
3067
+ });
3068
+ }
3069
+ function SidebarItem({ current, className, children, ref, ...props }) {
3070
+ const interactiveProps = useDataInteractive({ disabled: ("disabled" in props ? props.disabled : false) ?? false });
3071
+ const closeFn = useCloseContext();
3072
+ const propsOnClick = "onClick" in props ? props.onClick : void 0;
3073
+ const handleLinkClick = useCallback((e) => {
3074
+ propsOnClick?.(e);
3075
+ closeFn?.();
3076
+ }, [propsOnClick, closeFn]);
3077
+ const classes = clsx("flex w-full items-center gap-3 rounded-lg px-2 py-2.5 text-left text-base/6 font-medium text-zinc-950 sm:py-2 sm:text-sm/5", "*:data-[slot=icon]:size-6 *:data-[slot=icon]:shrink-0 *:data-[slot=icon]:fill-zinc-500 sm:*:data-[slot=icon]:size-5", "*:last:data-[slot=icon]:ml-auto *:last:data-[slot=icon]:size-5 sm:*:last:data-[slot=icon]:size-4", "*:data-[slot=avatar]:-m-0.5 *:data-[slot=avatar]:size-7 sm:*:data-[slot=avatar]:size-6", "data-hover:bg-zinc-950/5 data-hover:*:data-[slot=icon]:fill-zinc-950", "data-active:bg-zinc-950/5 data-active:*:data-[slot=icon]:fill-zinc-950", "data-current:*:data-[slot=icon]:fill-zinc-950", "dark:text-white dark:*:data-[slot=icon]:fill-zinc-400", "dark:data-hover:bg-white/5 dark:data-hover:*:data-[slot=icon]:fill-white", "dark:data-active:bg-white/5 dark:data-active:*:data-[slot=icon]:fill-white", "dark:data-current:*:data-[slot=icon]:fill-white");
3078
+ return /* @__PURE__ */ jsxs("span", {
3079
+ className: clsx(className, "relative"),
3080
+ children: [current && /* @__PURE__ */ jsx(LayoutIndicator, {
3081
+ layoutId: "current-indicator",
3082
+ className: "absolute inset-y-2 -left-4 w-0.5 rounded-full bg-zinc-950 dark:bg-white"
3083
+ }), typeof props.href === "string" ? /* @__PURE__ */ jsx(Link, {
3084
+ ...props,
3085
+ className: classes,
3086
+ "data-current": current ? "true" : void 0,
3087
+ ref,
3088
+ onClick: handleLinkClick,
3089
+ children: /* @__PURE__ */ jsx(TouchTarget, { children })
3090
+ }) : /* @__PURE__ */ jsx("button", {
3091
+ type: "button",
3092
+ ...props,
3093
+ ...interactiveProps,
3094
+ className: clsx("cursor-default", classes),
3095
+ "data-current": current ? "true" : void 0,
3096
+ ref,
3097
+ children: /* @__PURE__ */ jsx(TouchTarget, { children })
3098
+ })]
3099
+ });
3100
+ }
3101
+ function SidebarLabel({ className, ...props }) {
3102
+ return /* @__PURE__ */ jsx("span", {
3103
+ ...props,
3104
+ className: clsx(className, "truncate")
3105
+ });
3106
+ }
3107
+ //#endregion
3108
+ //#region src/components/sidebar-layout.tsx
3109
+ function OpenMenuIcon$1() {
3110
+ return /* @__PURE__ */ jsx("svg", {
3111
+ "data-slot": "icon",
3112
+ viewBox: "0 0 20 20",
3113
+ "aria-hidden": "true",
3114
+ children: /* @__PURE__ */ jsx("path", { d: "M2 6.75C2 6.33579 2.33579 6 2.75 6H17.25C17.6642 6 18 6.33579 18 6.75C18 7.16421 17.6642 7.5 17.25 7.5H2.75C2.33579 7.5 2 7.16421 2 6.75ZM2 13.25C2 12.8358 2.33579 12.5 2.75 12.5H17.25C17.6642 12.5 18 12.8358 18 13.25C18 13.6642 17.6642 14 17.25 14H2.75C2.33579 14 2 13.6642 2 13.25Z" })
3115
+ });
3116
+ }
3117
+ function CloseMenuIcon$1() {
3118
+ return /* @__PURE__ */ jsx("svg", {
3119
+ "data-slot": "icon",
3120
+ viewBox: "0 0 20 20",
3121
+ "aria-hidden": "true",
3122
+ children: /* @__PURE__ */ jsx("path", { d: "M6.28 5.22a.75.75 0 0 0-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 1 0 1.06 1.06L10 11.06l3.72 3.72a.75.75 0 1 0 1.06-1.06L11.06 10l3.72-3.72a.75.75 0 0 0-1.06-1.06L10 8.94 6.28 5.22Z" })
3123
+ });
3124
+ }
3125
+ function MobileSidebar$1({ open, close, children }) {
3126
+ const panelRef = useRef(null);
3127
+ const backdrop = useTransition(open);
3128
+ const panel = useTransition(open);
3129
+ useScrollLock(open);
3130
+ useFocusTrap(panelRef, open);
3131
+ useEscapeKey(close, open);
3132
+ if (!(backdrop.mounted || panel.mounted)) return null;
3133
+ return createPortal(/* @__PURE__ */ jsx(CloseContext.Provider, {
3134
+ value: close,
3135
+ children: /* @__PURE__ */ jsxs("div", {
3136
+ role: "dialog",
3137
+ "aria-modal": "true",
3138
+ className: "lg:hidden",
3139
+ children: [backdrop.mounted && /* @__PURE__ */ jsx("button", {
3140
+ type: "button",
3141
+ "aria-label": "Close navigation",
3142
+ ref: backdrop.nodeRef,
3143
+ ...backdrop.transitionProps,
3144
+ onClick: close,
3145
+ className: "fixed inset-0 bg-black/30 transition data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in"
3146
+ }), panel.mounted && /* @__PURE__ */ jsx("div", {
3147
+ ref: (node) => {
3148
+ panelRef.current = node;
3149
+ panel.nodeRef.current = node;
3150
+ },
3151
+ ...panel.transitionProps,
3152
+ className: "fixed inset-y-0 w-full max-w-80 p-2 transition duration-300 ease-in-out data-closed:-translate-x-full",
3153
+ children: /* @__PURE__ */ jsxs("div", {
3154
+ className: "flex h-full flex-col rounded-lg bg-white shadow-xs ring-1 ring-zinc-950/5 dark:bg-zinc-900 dark:ring-white/10",
3155
+ children: [/* @__PURE__ */ jsx("div", {
3156
+ className: "-mb-3 px-4 pt-3",
3157
+ children: /* @__PURE__ */ jsx(NavbarItem, {
3158
+ onClick: close,
3159
+ "aria-label": "Close navigation",
3160
+ children: /* @__PURE__ */ jsx(CloseMenuIcon$1, {})
3161
+ })
3162
+ }), children]
3163
+ })
3164
+ })]
3165
+ })
3166
+ }), document.body);
3167
+ }
3168
+ function SidebarLayout({ navbar, sidebar, children }) {
3169
+ const [showSidebar, setShowSidebar] = useState(false);
3170
+ return /* @__PURE__ */ jsxs("div", {
3171
+ className: "relative isolate flex min-h-svh w-full bg-white max-lg:flex-col lg:bg-zinc-100 dark:bg-zinc-900 dark:lg:bg-zinc-950",
3172
+ children: [
3173
+ /* @__PURE__ */ jsx("div", {
3174
+ className: "fixed inset-y-0 left-0 w-64 max-lg:hidden",
3175
+ children: sidebar
3176
+ }),
3177
+ /* @__PURE__ */ jsx(MobileSidebar$1, {
3178
+ open: showSidebar,
3179
+ close: () => setShowSidebar(false),
3180
+ children: sidebar
3181
+ }),
3182
+ /* @__PURE__ */ jsxs("header", {
3183
+ className: "flex items-center px-4 lg:hidden",
3184
+ children: [/* @__PURE__ */ jsx("div", {
3185
+ className: "py-2.5",
3186
+ children: /* @__PURE__ */ jsx(NavbarItem, {
3187
+ onClick: () => setShowSidebar(true),
3188
+ "aria-label": "Open navigation",
3189
+ children: /* @__PURE__ */ jsx(OpenMenuIcon$1, {})
3190
+ })
3191
+ }), /* @__PURE__ */ jsx("div", {
3192
+ className: "min-w-0 flex-1",
3193
+ children: navbar
3194
+ })]
3195
+ }),
3196
+ /* @__PURE__ */ jsx("main", {
3197
+ className: "flex flex-1 flex-col pb-2 lg:min-w-0 lg:pt-2 lg:pr-2 lg:pl-64",
3198
+ children: /* @__PURE__ */ jsx("div", {
3199
+ className: "grow p-6 lg:rounded-lg lg:bg-white lg:p-10 lg:shadow-xs lg:ring-1 lg:ring-zinc-950/5 dark:lg:bg-zinc-900 dark:lg:ring-white/10",
3200
+ children: /* @__PURE__ */ jsx("div", {
3201
+ className: "mx-auto max-w-6xl",
3202
+ children
3203
+ })
3204
+ })
3205
+ })
3206
+ ]
3207
+ });
3208
+ }
3209
+ //#endregion
3210
+ //#region src/components/slider.tsx
3211
+ function Slider({ value: controlledValue, defaultValue = 0, min = 0, max = 100, step = 1, onChange, disabled = false, label, showValue = false, className }) {
3212
+ const [internalValue, setInternalValue] = useState(defaultValue);
3213
+ const value = controlledValue ?? internalValue;
3214
+ const id = useId();
3215
+ const handleChange = useCallback((e) => {
3216
+ const next = Number(e.target.value);
3217
+ setInternalValue(next);
3218
+ onChange?.(next);
3219
+ }, [onChange]);
3220
+ const percentage = (value - min) / (max - min) * 100;
3221
+ return /* @__PURE__ */ jsxs("div", {
3222
+ className: clsx("w-full", className),
3223
+ children: [(label || showValue) && /* @__PURE__ */ jsxs("div", {
3224
+ className: "mb-2 flex items-center justify-between",
3225
+ children: [label && /* @__PURE__ */ jsx("label", {
3226
+ htmlFor: id,
3227
+ className: "text-sm font-medium text-zinc-700 dark:text-zinc-300",
3228
+ children: label
3229
+ }), showValue && /* @__PURE__ */ jsx("span", {
3230
+ className: "text-sm text-zinc-500 dark:text-zinc-400",
3231
+ children: value
3232
+ })]
3233
+ }), /* @__PURE__ */ jsx("input", {
3234
+ id,
3235
+ type: "range",
3236
+ min,
3237
+ max,
3238
+ step,
3239
+ value,
3240
+ disabled,
3241
+ onChange: handleChange,
3242
+ style: { "--slider-pct": `${percentage}%` },
3243
+ className: clsx("h-2 w-full cursor-pointer appearance-none rounded-full outline-none", "bg-zinc-200 dark:bg-zinc-700", "[&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:cursor-pointer [&::-webkit-slider-thumb]:appearance-none", "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-blue-600 [&::-webkit-slider-thumb]:shadow-sm", "[&::-webkit-slider-thumb]:ring-2 [&::-webkit-slider-thumb]:ring-white [&::-webkit-slider-thumb]:dark:ring-zinc-900", "[&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:cursor-pointer [&::-moz-range-thumb]:appearance-none", "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-none [&::-moz-range-thumb]:bg-blue-600", "focus-visible:[&::-webkit-slider-thumb]:outline-2 focus-visible:[&::-webkit-slider-thumb]:outline-offset-2 focus-visible:[&::-webkit-slider-thumb]:outline-blue-500", disabled && "cursor-not-allowed opacity-50")
3244
+ })]
3245
+ });
3246
+ }
3247
+ //#endregion
3248
+ //#region src/components/stacked-layout.tsx
3249
+ function OpenMenuIcon() {
3250
+ return /* @__PURE__ */ jsx("svg", {
3251
+ "data-slot": "icon",
3252
+ viewBox: "0 0 20 20",
3253
+ "aria-hidden": "true",
3254
+ children: /* @__PURE__ */ jsx("path", { d: "M2 6.75C2 6.33579 2.33579 6 2.75 6H17.25C17.6642 6 18 6.33579 18 6.75C18 7.16421 17.6642 7.5 17.25 7.5H2.75C2.33579 7.5 2 7.16421 2 6.75ZM2 13.25C2 12.8358 2.33579 12.5 2.75 12.5H17.25C17.6642 12.5 18 12.8358 18 13.25C18 13.6642 17.6642 14 17.25 14H2.75C2.33579 14 2 13.6642 2 13.25Z" })
3255
+ });
3256
+ }
3257
+ function CloseMenuIcon() {
3258
+ return /* @__PURE__ */ jsx("svg", {
3259
+ "data-slot": "icon",
3260
+ viewBox: "0 0 20 20",
3261
+ "aria-hidden": "true",
3262
+ children: /* @__PURE__ */ jsx("path", { d: "M6.28 5.22a.75.75 0 0 0-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 1 0 1.06 1.06L10 11.06l3.72 3.72a.75.75 0 1 0 1.06-1.06L11.06 10l3.72-3.72a.75.75 0 0 0-1.06-1.06L10 8.94 6.28 5.22Z" })
3263
+ });
3264
+ }
3265
+ function MobileSidebar({ open, close, children }) {
3266
+ const panelRef = useRef(null);
3267
+ const backdrop = useTransition(open);
3268
+ const panel = useTransition(open);
3269
+ useScrollLock(open);
3270
+ useFocusTrap(panelRef, open);
3271
+ useEscapeKey(close, open);
3272
+ if (!(backdrop.mounted || panel.mounted)) return null;
3273
+ return createPortal(/* @__PURE__ */ jsx(CloseContext.Provider, {
3274
+ value: close,
3275
+ children: /* @__PURE__ */ jsxs("div", {
3276
+ role: "dialog",
3277
+ "aria-modal": "true",
3278
+ className: "lg:hidden",
3279
+ children: [backdrop.mounted && /* @__PURE__ */ jsx("button", {
3280
+ type: "button",
3281
+ "aria-label": "Close navigation",
3282
+ ref: backdrop.nodeRef,
3283
+ ...backdrop.transitionProps,
3284
+ onClick: close,
3285
+ className: "fixed inset-0 bg-black/30 transition data-closed:opacity-0 data-enter:duration-300 data-enter:ease-out data-leave:duration-200 data-leave:ease-in"
3286
+ }), panel.mounted && /* @__PURE__ */ jsx("div", {
3287
+ ref: (node) => {
3288
+ panelRef.current = node;
3289
+ panel.nodeRef.current = node;
3290
+ },
3291
+ ...panel.transitionProps,
3292
+ className: "fixed inset-y-0 w-full max-w-80 p-2 transition duration-300 ease-in-out data-closed:-translate-x-full",
3293
+ children: /* @__PURE__ */ jsxs("div", {
3294
+ className: "flex h-full flex-col rounded-lg bg-white shadow-xs ring-1 ring-zinc-950/5 dark:bg-zinc-900 dark:ring-white/10",
3295
+ children: [/* @__PURE__ */ jsx("div", {
3296
+ className: "-mb-3 px-4 pt-3",
3297
+ children: /* @__PURE__ */ jsx(NavbarItem, {
3298
+ onClick: close,
3299
+ "aria-label": "Close navigation",
3300
+ children: /* @__PURE__ */ jsx(CloseMenuIcon, {})
3301
+ })
3302
+ }), children]
3303
+ })
3304
+ })]
3305
+ })
3306
+ }), document.body);
3307
+ }
3308
+ function StackedLayout({ navbar, sidebar, children }) {
3309
+ const [showSidebar, setShowSidebar] = useState(false);
3310
+ return /* @__PURE__ */ jsxs("div", {
3311
+ className: "relative isolate flex min-h-svh w-full flex-col bg-white lg:bg-zinc-100 dark:bg-zinc-900 dark:lg:bg-zinc-950",
3312
+ children: [
3313
+ /* @__PURE__ */ jsx(MobileSidebar, {
3314
+ open: showSidebar,
3315
+ close: () => setShowSidebar(false),
3316
+ children: sidebar
3317
+ }),
3318
+ /* @__PURE__ */ jsxs("header", {
3319
+ className: "flex items-center px-4",
3320
+ children: [/* @__PURE__ */ jsx("div", {
3321
+ className: "py-2.5 lg:hidden",
3322
+ children: /* @__PURE__ */ jsx(NavbarItem, {
3323
+ onClick: () => setShowSidebar(true),
3324
+ "aria-label": "Open navigation",
3325
+ children: /* @__PURE__ */ jsx(OpenMenuIcon, {})
3326
+ })
3327
+ }), /* @__PURE__ */ jsx("div", {
3328
+ className: "min-w-0 flex-1",
3329
+ children: navbar
3330
+ })]
3331
+ }),
3332
+ /* @__PURE__ */ jsx("main", {
3333
+ className: "flex flex-1 flex-col pb-2 lg:px-2",
3334
+ children: /* @__PURE__ */ jsx("div", {
3335
+ className: "grow p-6 lg:rounded-lg lg:bg-white lg:p-10 lg:shadow-xs lg:ring-1 lg:ring-zinc-950/5 dark:lg:bg-zinc-900 dark:lg:ring-white/10",
3336
+ children: /* @__PURE__ */ jsx("div", {
3337
+ className: "mx-auto max-w-6xl",
3338
+ children
3339
+ })
3340
+ })
3341
+ })
3342
+ ]
3343
+ });
3344
+ }
3345
+ //#endregion
3346
+ //#region src/components/stat.tsx
3347
+ function Stat({ label, value, change, trend, description, icon, className }) {
3348
+ return /* @__PURE__ */ jsxs("div", {
3349
+ className: clsx("rounded-xl bg-white p-6 ring-1 ring-zinc-950/5 dark:bg-zinc-900 dark:ring-white/10", className),
3350
+ children: [
3351
+ /* @__PURE__ */ jsxs("div", {
3352
+ className: "flex items-start justify-between",
3353
+ children: [/* @__PURE__ */ jsx("p", {
3354
+ className: "text-sm font-medium text-zinc-500 dark:text-zinc-400",
3355
+ children: label
3356
+ }), icon && /* @__PURE__ */ jsx("div", {
3357
+ className: "rounded-lg bg-zinc-100 p-2 dark:bg-zinc-800",
3358
+ children: icon
3359
+ })]
3360
+ }),
3361
+ /* @__PURE__ */ jsx("p", {
3362
+ className: "mt-2 text-3xl font-semibold tracking-tight text-zinc-950 dark:text-white",
3363
+ children: value
3364
+ }),
3365
+ (change || description) && /* @__PURE__ */ jsxs("div", {
3366
+ className: "mt-2 flex items-center gap-2",
3367
+ children: [change && trend && /* @__PURE__ */ jsxs("span", {
3368
+ className: clsx("text-sm font-medium", {
3369
+ up: "text-green-600 dark:text-green-400",
3370
+ down: "text-red-600 dark:text-red-400",
3371
+ neutral: "text-zinc-500 dark:text-zinc-400"
3372
+ }[trend]),
3373
+ children: [
3374
+ {
3375
+ up: "↑",
3376
+ down: "↓",
3377
+ neutral: "→"
3378
+ }[trend],
3379
+ " ",
3380
+ change
3381
+ ]
3382
+ }), description && /* @__PURE__ */ jsx("span", {
3383
+ className: "text-sm text-zinc-500 dark:text-zinc-400",
3384
+ children: description
3385
+ })]
3386
+ })
3387
+ ]
3388
+ });
3389
+ }
3390
+ function StatGroup({ className, children }) {
3391
+ return /* @__PURE__ */ jsx("div", {
3392
+ className: clsx("grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4", className),
3393
+ children
3394
+ });
3395
+ }
3396
+ //#endregion
3397
+ //#region src/components/stepper.tsx
3398
+ function Stepper({ steps, orientation = "horizontal", className }) {
3399
+ return orientation === "vertical" ? /* @__PURE__ */ jsx(StepperVertical, {
3400
+ steps,
3401
+ className
3402
+ }) : /* @__PURE__ */ jsx(StepperHorizontal, {
3403
+ steps,
3404
+ className
3405
+ });
3406
+ }
3407
+ function StepIcon({ status }) {
3408
+ if (status === "complete") return /* @__PURE__ */ jsx("span", {
3409
+ className: "flex size-8 items-center justify-center rounded-full bg-blue-600",
3410
+ children: /* @__PURE__ */ jsx("svg", {
3411
+ viewBox: "0 0 16 16",
3412
+ fill: "none",
3413
+ className: "size-4 text-white",
3414
+ "aria-hidden": "true",
3415
+ children: /* @__PURE__ */ jsx("path", {
3416
+ d: "M3 8l3.5 3.5L13 4",
3417
+ stroke: "currentColor",
3418
+ strokeWidth: "2",
3419
+ strokeLinecap: "round",
3420
+ strokeLinejoin: "round"
3421
+ })
3422
+ })
3423
+ });
3424
+ if (status === "current") return /* @__PURE__ */ jsx("span", {
3425
+ className: "flex size-8 items-center justify-center rounded-full border-2 border-blue-600 bg-white dark:bg-zinc-900",
3426
+ children: /* @__PURE__ */ jsx("span", { className: "size-2.5 rounded-full bg-blue-600" })
3427
+ });
3428
+ return /* @__PURE__ */ jsx("span", {
3429
+ className: "flex size-8 items-center justify-center rounded-full border-2 border-zinc-300 bg-white dark:border-zinc-600 dark:bg-zinc-900",
3430
+ children: /* @__PURE__ */ jsx("span", { className: "size-2.5 rounded-full bg-transparent" })
3431
+ });
3432
+ }
3433
+ function StepperHorizontal({ steps, className }) {
3434
+ return /* @__PURE__ */ jsx("nav", {
3435
+ "aria-label": "Progress",
3436
+ children: /* @__PURE__ */ jsx("ol", {
3437
+ className: clsx("flex items-center", className),
3438
+ children: steps.map((step, index) => {
3439
+ const isLast = index === steps.length - 1;
3440
+ return /* @__PURE__ */ jsxs("li", {
3441
+ "aria-current": step.status === "current" ? "step" : void 0,
3442
+ className: clsx("flex items-center", !isLast && "flex-1"),
3443
+ children: [/* @__PURE__ */ jsxs("div", {
3444
+ className: "flex flex-col items-center gap-1.5",
3445
+ children: [/* @__PURE__ */ jsx(StepIcon, { status: step.status }), /* @__PURE__ */ jsx("span", {
3446
+ className: clsx("text-xs font-medium", step.status === "current" ? "text-blue-600" : step.status === "complete" ? "text-zinc-950 dark:text-white" : "text-zinc-400 dark:text-zinc-500"),
3447
+ children: step.label
3448
+ })]
3449
+ }), !isLast && /* @__PURE__ */ jsx("div", {
3450
+ "aria-hidden": "true",
3451
+ className: clsx("mx-3 h-px flex-1", step.status === "complete" ? "bg-blue-600" : "bg-zinc-200 dark:bg-zinc-700")
3452
+ })]
3453
+ }, index);
3454
+ })
3455
+ })
3456
+ });
3457
+ }
3458
+ function StepperVertical({ steps, className }) {
3459
+ return /* @__PURE__ */ jsx("nav", {
3460
+ "aria-label": "Progress",
3461
+ children: /* @__PURE__ */ jsx("ol", {
3462
+ className: clsx("space-y-0", className),
3463
+ children: steps.map((step, index) => {
3464
+ const isLast = index === steps.length - 1;
3465
+ return /* @__PURE__ */ jsxs("li", {
3466
+ "aria-current": step.status === "current" ? "step" : void 0,
3467
+ className: "relative flex gap-4",
3468
+ children: [/* @__PURE__ */ jsxs("div", {
3469
+ className: "flex flex-col items-center",
3470
+ children: [/* @__PURE__ */ jsx(StepIcon, { status: step.status }), !isLast && /* @__PURE__ */ jsx("div", {
3471
+ "aria-hidden": "true",
3472
+ className: clsx("w-px flex-1", step.status === "complete" ? "bg-blue-600" : "bg-zinc-200 dark:bg-zinc-700")
3473
+ })]
3474
+ }), /* @__PURE__ */ jsxs("div", {
3475
+ className: clsx("pb-6 pt-1", isLast && "pb-0"),
3476
+ children: [/* @__PURE__ */ jsx("p", {
3477
+ className: clsx("text-sm font-medium", step.status === "current" ? "text-blue-600" : step.status === "complete" ? "text-zinc-950 dark:text-white" : "text-zinc-400 dark:text-zinc-500"),
3478
+ children: step.label
3479
+ }), step.description && /* @__PURE__ */ jsx("p", {
3480
+ className: "mt-0.5 text-sm text-zinc-500 dark:text-zinc-400",
3481
+ children: step.description
3482
+ })]
3483
+ })]
3484
+ }, index);
3485
+ })
3486
+ })
3487
+ });
3488
+ }
3489
+ //#endregion
3490
+ //#region src/components/switch.tsx
3491
+ function SwitchGroup({ className, ...props }) {
3492
+ return /* @__PURE__ */ jsx("div", {
3493
+ "data-slot": "control",
3494
+ ...props,
3495
+ className: clsx(className, "space-y-3 **:data-[slot=label]:font-normal", "has-data-[slot=description]:space-y-6 has-data-[slot=description]:**:data-[slot=label]:font-medium")
3496
+ });
3497
+ }
3498
+ function SwitchField({ className, disabled, ...props }) {
3499
+ return /* @__PURE__ */ jsx(FieldProvider, {
3500
+ disabled,
3501
+ children: /* @__PURE__ */ jsx("div", {
3502
+ "data-slot": "field",
3503
+ "data-disabled": disabled ? "" : void 0,
3504
+ ...props,
3505
+ className: clsx(className, "grid grid-cols-[1fr_auto] gap-x-8 gap-y-1 sm:grid-cols-[1fr_auto]", "*:data-[slot=control]:col-start-2 *:data-[slot=control]:self-start sm:*:data-[slot=control]:mt-0.5", "*:data-[slot=label]:col-start-1 *:data-[slot=label]:row-start-1", "*:data-[slot=description]:col-start-1 *:data-[slot=description]:row-start-2", "has-data-[slot=description]:**:data-[slot=label]:font-medium")
3506
+ })
3507
+ });
3508
+ }
3509
+ var colors = {
3510
+ "dark/zinc": ["[--switch-bg-ring:var(--color-zinc-950)]/90 [--switch-bg:var(--color-zinc-900)] dark:[--switch-bg-ring:transparent] dark:[--switch-bg:var(--color-white)]/25", "[--switch-ring:var(--color-zinc-950)]/90 [--switch-shadow:var(--color-black)]/10 [--switch:white] dark:[--switch-ring:var(--color-zinc-700)]/90"],
3511
+ "dark/white": ["[--switch-bg-ring:var(--color-zinc-950)]/90 [--switch-bg:var(--color-zinc-900)] dark:[--switch-bg-ring:transparent] dark:[--switch-bg:var(--color-white)]", "[--switch-ring:var(--color-zinc-950)]/90 [--switch-shadow:var(--color-black)]/10 [--switch:white] dark:[--switch-ring:transparent] dark:[--switch:var(--color-zinc-900)]"],
3512
+ dark: ["[--switch-bg-ring:var(--color-zinc-950)]/90 [--switch-bg:var(--color-zinc-900)] dark:[--switch-bg-ring:var(--color-white)]/15", "[--switch-ring:var(--color-zinc-950)]/90 [--switch-shadow:var(--color-black)]/10 [--switch:white]"],
3513
+ zinc: ["[--switch-bg-ring:var(--color-zinc-700)]/90 [--switch-bg:var(--color-zinc-600)] dark:[--switch-bg-ring:transparent]", "[--switch-shadow:var(--color-black)]/10 [--switch:white] [--switch-ring:var(--color-zinc-700)]/90"],
3514
+ white: ["[--switch-bg-ring:var(--color-black)]/15 [--switch-bg:white] dark:[--switch-bg-ring:transparent]", "[--switch-shadow:var(--color-black)]/10 [--switch-ring:transparent] [--switch:var(--color-zinc-950)]"],
3515
+ red: ["[--switch-bg-ring:var(--color-red-700)]/90 [--switch-bg:var(--color-red-600)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-red-700)]/90 [--switch-shadow:var(--color-red-900)]/20"],
3516
+ orange: ["[--switch-bg-ring:var(--color-orange-600)]/90 [--switch-bg:var(--color-orange-500)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-orange-600)]/90 [--switch-shadow:var(--color-orange-900)]/20"],
3517
+ amber: ["[--switch-bg-ring:var(--color-amber-500)]/80 [--switch-bg:var(--color-amber-400)] dark:[--switch-bg-ring:transparent]", "[--switch-ring:transparent] [--switch-shadow:transparent] [--switch:var(--color-amber-950)]"],
3518
+ yellow: ["[--switch-bg-ring:var(--color-yellow-400)]/80 [--switch-bg:var(--color-yellow-300)] dark:[--switch-bg-ring:transparent]", "[--switch-ring:transparent] [--switch-shadow:transparent] [--switch:var(--color-yellow-950)]"],
3519
+ lime: ["[--switch-bg-ring:var(--color-lime-400)]/80 [--switch-bg:var(--color-lime-300)] dark:[--switch-bg-ring:transparent]", "[--switch-ring:transparent] [--switch-shadow:transparent] [--switch:var(--color-lime-950)]"],
3520
+ green: ["[--switch-bg-ring:var(--color-green-700)]/90 [--switch-bg:var(--color-green-600)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-green-700)]/90 [--switch-shadow:var(--color-green-900)]/20"],
3521
+ emerald: ["[--switch-bg-ring:var(--color-emerald-600)]/90 [--switch-bg:var(--color-emerald-500)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-emerald-600)]/90 [--switch-shadow:var(--color-emerald-900)]/20"],
3522
+ teal: ["[--switch-bg-ring:var(--color-teal-700)]/90 [--switch-bg:var(--color-teal-600)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-teal-700)]/90 [--switch-shadow:var(--color-teal-900)]/20"],
3523
+ cyan: ["[--switch-bg-ring:var(--color-cyan-400)]/80 [--switch-bg:var(--color-cyan-300)] dark:[--switch-bg-ring:transparent]", "[--switch-ring:transparent] [--switch-shadow:transparent] [--switch:var(--color-cyan-950)]"],
3524
+ sky: ["[--switch-bg-ring:var(--color-sky-600)]/80 [--switch-bg:var(--color-sky-500)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-sky-600)]/80 [--switch-shadow:var(--color-sky-900)]/20"],
3525
+ blue: ["[--switch-bg-ring:var(--color-blue-700)]/90 [--switch-bg:var(--color-blue-600)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-blue-700)]/90 [--switch-shadow:var(--color-blue-900)]/20"],
3526
+ indigo: ["[--switch-bg-ring:var(--color-indigo-600)]/90 [--switch-bg:var(--color-indigo-500)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-indigo-600)]/90 [--switch-shadow:var(--color-indigo-900)]/20"],
3527
+ violet: ["[--switch-bg-ring:var(--color-violet-600)]/90 [--switch-bg:var(--color-violet-500)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-violet-600)]/90 [--switch-shadow:var(--color-violet-900)]/20"],
3528
+ purple: ["[--switch-bg-ring:var(--color-purple-600)]/90 [--switch-bg:var(--color-purple-500)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-purple-600)]/90 [--switch-shadow:var(--color-purple-900)]/20"],
3529
+ fuchsia: ["[--switch-bg-ring:var(--color-fuchsia-600)]/90 [--switch-bg:var(--color-fuchsia-500)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-fuchsia-600)]/90 [--switch-shadow:var(--color-fuchsia-900)]/20"],
3530
+ pink: ["[--switch-bg-ring:var(--color-pink-600)]/90 [--switch-bg:var(--color-pink-500)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-pink-600)]/90 [--switch-shadow:var(--color-pink-900)]/20"],
3531
+ rose: ["[--switch-bg-ring:var(--color-rose-600)]/90 [--switch-bg:var(--color-rose-500)] dark:[--switch-bg-ring:transparent]", "[--switch:white] [--switch-ring:var(--color-rose-600)]/90 [--switch-shadow:var(--color-rose-900)]/20"]
3532
+ };
3533
+ function Switch({ color = "dark/zinc", className, checked: controlledChecked, defaultChecked, onChange, disabled, name, value, ...props }) {
3534
+ const { checked, toggleProps } = useToggle({
3535
+ checked: controlledChecked,
3536
+ defaultChecked,
3537
+ onChange,
3538
+ disabled
3539
+ });
3540
+ const interactiveProps = useDataInteractive({ disabled });
3541
+ return /* @__PURE__ */ jsxs("button", {
3542
+ type: "button",
3543
+ role: "switch",
3544
+ "data-slot": "control",
3545
+ "aria-checked": checked,
3546
+ "data-checked": checked ? "" : void 0,
3547
+ "data-disabled": disabled ? "" : void 0,
3548
+ disabled,
3549
+ onClick: toggleProps.onClick,
3550
+ onKeyDown: toggleProps.onKeyDown,
3551
+ ...interactiveProps,
3552
+ ...props,
3553
+ className: clsx(className, "group relative isolate inline-flex h-6 w-10 cursor-default rounded-full p-[3px] sm:h-5 sm:w-8", "transition duration-0 ease-in-out data-changing:duration-200", "forced-colors:outline forced-colors:[--switch-bg:Highlight] dark:forced-colors:[--switch-bg:Highlight]", "bg-zinc-200 ring-1 ring-black/5 ring-inset dark:bg-white/5 dark:ring-white/15", "data-checked:bg-(--switch-bg) data-checked:ring-(--switch-bg-ring) dark:data-checked:bg-(--switch-bg) dark:data-checked:ring-(--switch-bg-ring)", "focus:not-data-focus:outline-hidden data-focus:outline-2 data-focus:outline-offset-2 data-focus:outline-blue-500", "data-hover:ring-black/15 data-hover:data-checked:ring-(--switch-bg-ring)", "dark:data-hover:ring-white/25 dark:data-hover:data-checked:ring-(--switch-bg-ring)", "data-disabled:bg-zinc-200 data-disabled:opacity-50 data-disabled:data-checked:bg-zinc-200 data-disabled:data-checked:ring-black/5", "dark:data-disabled:bg-white/15 dark:data-disabled:data-checked:bg-white/15 dark:data-disabled:data-checked:ring-white/15", colors[color]),
3554
+ children: [name && /* @__PURE__ */ jsx("input", {
3555
+ type: "hidden",
3556
+ name,
3557
+ value: checked ? value ?? "on" : ""
3558
+ }), /* @__PURE__ */ jsx("span", {
3559
+ "aria-hidden": "true",
3560
+ className: clsx("pointer-events-none relative inline-block size-4.5 rounded-full sm:size-3.5", "translate-x-0 transition duration-200 ease-in-out", "border border-transparent", "bg-white shadow-sm ring-1 ring-black/5", "group-data-checked:bg-(--switch) group-data-checked:shadow-(--switch-shadow) group-data-checked:ring-(--switch-ring)", "group-data-checked:translate-x-4 sm:group-data-checked:translate-x-3", "group-data-checked:group-data-disabled:bg-white group-data-checked:group-data-disabled:shadow-sm group-data-checked:group-data-disabled:ring-black/5")
3561
+ })]
3562
+ });
3563
+ }
3564
+ //#endregion
3565
+ //#region src/components/tabs.tsx
3566
+ var TabsContext = createContext(null);
3567
+ function useTabsContext() {
3568
+ const ctx = use(TabsContext);
3569
+ if (!ctx) throw new Error("Tabs subcomponents must be used inside <Tabs>");
3570
+ return ctx;
3571
+ }
3572
+ function Tabs({ defaultTab, value, onChange, className, children }) {
3573
+ const baseId = useId();
3574
+ const [internalTab, setInternalTab] = useState(defaultTab ?? "");
3575
+ const activeTab = value ?? internalTab;
3576
+ const setActiveTab = (id) => {
3577
+ setInternalTab(id);
3578
+ onChange?.(id);
3579
+ };
3580
+ return /* @__PURE__ */ jsx(TabsContext, {
3581
+ value: {
3582
+ activeTab,
3583
+ setActiveTab,
3584
+ baseId
3585
+ },
3586
+ children: /* @__PURE__ */ jsx("div", {
3587
+ className,
3588
+ children
3589
+ })
3590
+ });
3591
+ }
3592
+ function TabList({ className, children }) {
3593
+ const listRef = useRef(null);
3594
+ const handleKeyDown = (e) => {
3595
+ if (!listRef.current) return;
3596
+ const tabs = Array.from(listRef.current.querySelectorAll("[role=\"tab\"]"));
3597
+ const current = tabs.indexOf(document.activeElement);
3598
+ if (current === -1) return;
3599
+ let next;
3600
+ if (e.key === "ArrowRight") next = (current + 1) % tabs.length;
3601
+ else if (e.key === "ArrowLeft") next = (current - 1 + tabs.length) % tabs.length;
3602
+ else if (e.key === "Home") next = 0;
3603
+ else if (e.key === "End") next = tabs.length - 1;
3604
+ if (next !== void 0) {
3605
+ e.preventDefault();
3606
+ tabs[next]?.focus();
3607
+ tabs[next]?.click();
3608
+ }
3609
+ };
3610
+ return /* @__PURE__ */ jsx("div", {
3611
+ ref: listRef,
3612
+ role: "tablist",
3613
+ onKeyDown: handleKeyDown,
3614
+ className: clsx("flex border-b border-zinc-200 dark:border-zinc-700", className),
3615
+ children
3616
+ });
3617
+ }
3618
+ function Tab({ id, className, children }) {
3619
+ const { activeTab, setActiveTab, baseId } = useTabsContext();
3620
+ const isActive = activeTab === id;
3621
+ return /* @__PURE__ */ jsx("button", {
3622
+ type: "button",
3623
+ role: "tab",
3624
+ id: `${baseId}-tab-${id}`,
3625
+ "aria-controls": `${baseId}-panel-${id}`,
3626
+ "aria-selected": isActive,
3627
+ tabIndex: isActive ? 0 : -1,
3628
+ onClick: () => setActiveTab(id),
3629
+ className: clsx(className, "relative -mb-px border-b-2 px-4 py-2.5 text-sm font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500", isActive ? "border-blue-600 text-blue-600 dark:border-blue-400 dark:text-blue-400" : "border-transparent text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-200"),
3630
+ children
3631
+ });
3632
+ }
3633
+ function TabPanel({ id, className, children }) {
3634
+ const { activeTab, baseId } = useTabsContext();
3635
+ if (activeTab !== id) return null;
3636
+ return /* @__PURE__ */ jsx("div", {
3637
+ role: "tabpanel",
3638
+ id: `${baseId}-panel-${id}`,
3639
+ "aria-labelledby": `${baseId}-tab-${id}`,
3640
+ tabIndex: 0,
3641
+ className: clsx("focus-visible:outline-none", className),
3642
+ children
3643
+ });
3644
+ }
3645
+ //#endregion
3646
+ //#region src/components/textarea-headless.tsx
3647
+ function Textarea({ className, resizable = true, disabled, invalid, ref, ...props }) {
3648
+ const interactiveProps = useDataInteractive({ disabled });
3649
+ const fieldProps = useFieldControlProps();
3650
+ return /* @__PURE__ */ jsx("span", {
3651
+ "data-slot": "control",
3652
+ className: clsx([
3653
+ className,
3654
+ "relative block w-full",
3655
+ "before:absolute before:inset-px before:rounded-[calc(var(--radius-lg)-1px)] before:bg-white before:shadow-sm",
3656
+ "dark:before:hidden",
3657
+ "after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:ring-transparent after:ring-inset sm:focus-within:after:ring-2 sm:focus-within:after:ring-blue-500",
3658
+ "has-data-disabled:opacity-50 has-data-disabled:before:bg-zinc-950/5 has-data-disabled:before:shadow-none"
3659
+ ]),
3660
+ children: /* @__PURE__ */ jsx("textarea", {
3661
+ ref,
3662
+ disabled,
3663
+ ...props,
3664
+ ...interactiveProps,
3665
+ ...fieldProps,
3666
+ "data-invalid": invalid ? "" : void 0,
3667
+ "data-disabled": disabled ? "" : void 0,
3668
+ className: clsx([
3669
+ "relative block h-full w-full appearance-none rounded-lg px-[calc(--spacing(3.5)-1px)] py-[calc(--spacing(2.5)-1px)] sm:px-[calc(--spacing(3)-1px)] sm:py-[calc(--spacing(1.5)-1px)]",
3670
+ "text-base/6 text-zinc-950 placeholder:text-zinc-500 sm:text-sm/6 dark:text-white",
3671
+ "border border-zinc-950/10 data-hover:border-zinc-950/20 dark:border-white/10 dark:data-hover:border-white/20",
3672
+ "bg-transparent dark:bg-white/5",
3673
+ "focus:outline-hidden",
3674
+ "data-invalid:border-red-500 data-invalid:data-hover:border-red-500 dark:data-invalid:border-red-600 dark:data-invalid:data-hover:border-red-600",
3675
+ "disabled:border-zinc-950/20 dark:disabled:border-white/15 dark:disabled:bg-white/2.5 dark:data-hover:disabled:border-white/15",
3676
+ resizable ? "resize-y" : "resize-none"
3677
+ ])
3678
+ })
3679
+ });
3680
+ }
3681
+ //#endregion
3682
+ //#region src/components/timeline.tsx
3683
+ function Timeline({ className, children }) {
3684
+ return /* @__PURE__ */ jsx("ol", {
3685
+ className: clsx("relative", className),
3686
+ children
3687
+ });
3688
+ }
3689
+ function TimelineItem({ icon, date, title, description, isLast = false, className }) {
3690
+ return /* @__PURE__ */ jsxs("li", {
3691
+ className: clsx("relative flex gap-4", !isLast && "pb-8", className),
3692
+ children: [
3693
+ !isLast && /* @__PURE__ */ jsx("div", {
3694
+ "aria-hidden": "true",
3695
+ className: "absolute left-4 top-8 -bottom-0 w-px bg-zinc-200 dark:bg-zinc-700"
3696
+ }),
3697
+ /* @__PURE__ */ jsx("div", {
3698
+ className: "relative z-10 flex size-8 shrink-0 items-center justify-center rounded-full bg-white ring-1 ring-zinc-200 dark:bg-zinc-900 dark:ring-zinc-700",
3699
+ children: icon ?? /* @__PURE__ */ jsx("div", { className: "size-2 rounded-full bg-zinc-400 dark:bg-zinc-500" })
3700
+ }),
3701
+ /* @__PURE__ */ jsxs("div", {
3702
+ className: "flex-1 pt-0.5",
3703
+ children: [/* @__PURE__ */ jsxs("div", {
3704
+ className: "flex flex-wrap items-baseline justify-between gap-x-4",
3705
+ children: [/* @__PURE__ */ jsx("p", {
3706
+ className: "text-sm font-semibold text-zinc-950 dark:text-white",
3707
+ children: title
3708
+ }), date && /* @__PURE__ */ jsx("time", {
3709
+ className: "shrink-0 text-xs text-zinc-400 dark:text-zinc-500",
3710
+ children: date
3711
+ })]
3712
+ }), description && /* @__PURE__ */ jsx("p", {
3713
+ className: "mt-1 text-sm text-zinc-600 dark:text-zinc-400",
3714
+ children: description
3715
+ })]
3716
+ })
3717
+ ]
3718
+ });
3719
+ }
3720
+ //#endregion
3721
+ //#region src/components/toast.tsx
3722
+ function toastReducer(state, action) {
3723
+ switch (action.type) {
3724
+ case "ADD": return [...state, action.toast];
3725
+ case "REMOVE": return state.filter((t) => t.id !== action.id);
3726
+ }
3727
+ }
3728
+ var ToastContext = createContext(null);
3729
+ function ToastProvider({ children }) {
3730
+ const [toasts, dispatch] = useReducer(toastReducer, []);
3731
+ const addToast = useCallback((toast) => {
3732
+ const id = crypto.randomUUID();
3733
+ dispatch({
3734
+ type: "ADD",
3735
+ toast: {
3736
+ ...toast,
3737
+ id
3738
+ }
3739
+ });
3740
+ return id;
3741
+ }, []);
3742
+ const removeToast = useCallback((id) => {
3743
+ dispatch({
3744
+ type: "REMOVE",
3745
+ id
3746
+ });
3747
+ }, []);
3748
+ return /* @__PURE__ */ jsxs(ToastContext, {
3749
+ value: {
3750
+ toasts,
3751
+ addToast,
3752
+ removeToast
3753
+ },
3754
+ children: [children, typeof document !== "undefined" && createPortal(/* @__PURE__ */ jsx(ToastList, {
3755
+ toasts,
3756
+ onRemove: removeToast
3757
+ }), document.body)]
3758
+ });
3759
+ }
3760
+ function useToast() {
3761
+ const ctx = use(ToastContext);
3762
+ if (!ctx) throw new Error("useToast must be used within a ToastProvider");
3763
+ return ctx;
3764
+ }
3765
+ var variantClasses = {
3766
+ default: "bg-white dark:bg-zinc-800 ring-zinc-950/10 dark:ring-white/10",
3767
+ success: "bg-white dark:bg-zinc-800 ring-green-500/30",
3768
+ error: "bg-white dark:bg-zinc-800 ring-red-500/30",
3769
+ warning: "bg-white dark:bg-zinc-800 ring-amber-500/30",
3770
+ info: "bg-white dark:bg-zinc-800 ring-blue-500/30"
3771
+ };
3772
+ var variantIconClasses = {
3773
+ default: "hidden",
3774
+ success: "text-green-500",
3775
+ error: "text-red-500",
3776
+ warning: "text-amber-500",
3777
+ info: "text-blue-500"
3778
+ };
3779
+ var variantIcons = {
3780
+ default: "",
3781
+ success: "✓",
3782
+ error: "✕",
3783
+ warning: "!",
3784
+ info: "i"
3785
+ };
3786
+ function ToastList({ toasts, onRemove }) {
3787
+ if (toasts.length === 0) return null;
3788
+ return /* @__PURE__ */ jsx("div", {
3789
+ "aria-live": "assertive",
3790
+ className: "pointer-events-none fixed inset-0 z-50 flex flex-col items-end justify-end gap-2 p-4 sm:p-6",
3791
+ children: toasts.map((toast) => /* @__PURE__ */ jsx(ToastItem, {
3792
+ toast,
3793
+ onRemove
3794
+ }, toast.id))
3795
+ });
3796
+ }
3797
+ var EXIT_DURATION_MS = 150;
3798
+ function ToastItem({ toast, onRemove }) {
3799
+ const variant = toast.variant ?? "default";
3800
+ const [isExiting, setIsExiting] = useState(false);
3801
+ const handleRemove = useCallback(() => {
3802
+ setIsExiting(true);
3803
+ setTimeout(() => onRemove(toast.id), EXIT_DURATION_MS);
3804
+ }, [onRemove, toast.id]);
3805
+ useEffect(() => {
3806
+ const duration = toast.duration ?? 5e3;
3807
+ if (duration <= 0) return;
3808
+ const timer = setTimeout(handleRemove, duration);
3809
+ return () => clearTimeout(timer);
3810
+ }, [toast.duration, handleRemove]);
3811
+ return /* @__PURE__ */ jsxs("div", {
3812
+ role: "alert",
3813
+ className: clsx("pointer-events-auto flex w-full max-w-sm items-start gap-3 rounded-xl p-4 shadow-lg ring-1 transition-all duration-200", variantClasses[variant], isExiting ? "translate-y-2 opacity-0" : "translate-y-0 opacity-100 animate-[slide-in-from-bottom_200ms_ease-out]"),
3814
+ children: [
3815
+ variant !== "default" && /* @__PURE__ */ jsx("span", {
3816
+ className: clsx("mt-0.5 text-sm font-bold", variantIconClasses[variant]),
3817
+ children: variantIcons[variant]
3818
+ }),
3819
+ /* @__PURE__ */ jsxs("div", {
3820
+ className: "flex-1",
3821
+ children: [/* @__PURE__ */ jsx("p", {
3822
+ className: "text-sm font-semibold text-zinc-950 dark:text-white",
3823
+ children: toast.title
3824
+ }), toast.description && /* @__PURE__ */ jsx("p", {
3825
+ className: "mt-1 text-sm text-zinc-500 dark:text-zinc-400",
3826
+ children: toast.description
3827
+ })]
3828
+ }),
3829
+ /* @__PURE__ */ jsx("button", {
3830
+ type: "button",
3831
+ "aria-label": "Dismiss",
3832
+ onClick: handleRemove,
3833
+ className: "shrink-0 rounded-md text-zinc-400 hover:text-zinc-600 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500 dark:text-zinc-500 dark:hover:text-zinc-300",
3834
+ children: /* @__PURE__ */ jsx("span", {
3835
+ "aria-hidden": "true",
3836
+ children: "✕"
3837
+ })
3838
+ })
3839
+ ]
3840
+ });
3841
+ }
3842
+ //#endregion
3843
+ //#region src/components/tooltip.tsx
3844
+ var sideClasses = {
3845
+ top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
3846
+ bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
3847
+ left: "right-full top-1/2 -translate-y-1/2 mr-2",
3848
+ right: "left-full top-1/2 -translate-y-1/2 ml-2"
3849
+ };
3850
+ function Tooltip({ content, side = "top", className, delay = 200, children }) {
3851
+ const id = useId();
3852
+ const [visible, setVisible] = useState(false);
3853
+ const timeoutRef = useRef(null);
3854
+ const clear = useCallback(() => {
3855
+ if (timeoutRef.current) {
3856
+ window.clearTimeout(timeoutRef.current);
3857
+ timeoutRef.current = null;
3858
+ }
3859
+ }, []);
3860
+ const show = useCallback(() => {
3861
+ clear();
3862
+ timeoutRef.current = window.setTimeout(() => {
3863
+ setVisible(true);
3864
+ }, delay);
3865
+ }, [delay, clear]);
3866
+ const hide = useCallback(() => {
3867
+ clear();
3868
+ setVisible(false);
3869
+ }, [clear]);
3870
+ useEffect(() => {
3871
+ return clear;
3872
+ }, [clear]);
3873
+ return /* @__PURE__ */ jsxs("span", {
3874
+ className: "relative inline-flex",
3875
+ onPointerEnter: show,
3876
+ onPointerLeave: hide,
3877
+ onMouseEnter: show,
3878
+ onMouseLeave: hide,
3879
+ onFocus: show,
3880
+ onBlur: hide,
3881
+ "aria-describedby": visible ? id : void 0,
3882
+ children: [children, visible && /* @__PURE__ */ jsx("span", {
3883
+ id,
3884
+ role: "tooltip",
3885
+ className: clsx("pointer-events-none absolute z-50 w-max max-w-xs rounded-lg bg-zinc-950 px-2.5 py-1.5 text-xs text-white shadow-lg dark:bg-zinc-700", sideClasses[side], className),
3886
+ children: content
3887
+ })]
3888
+ });
3889
+ }
3890
+ //#endregion
3891
+ export { NavbarSpacer as $, CheckboxGroup as $t, CloseContext as A, Accordion as An, useRovingTabindex as At, SelectSeparator as B, DialogTitle as Bt, SidebarFooter as C, Text as Cn, DropdownHeading as Ct, SidebarLabel as D, useScrollLock as Dn, DropdownSection as Dt, SidebarItem as E, useTransition as En, DropdownMenu as Et, SelectGroup as F, Divider as Ft, RadioField as G, ComboboxDescription as Gt, SelectValue as H, DescriptionList as Ht, SelectItem as I, Dialog as It, Navbar as J, usePopover as Jt, RadioGroup as K, ComboboxLabel as Kt, SelectLabel as L, DialogActions as Lt, Select as M, DrawerBody as Mt, Select$1 as N, DrawerFooter as Nt, SidebarSection as O, useFocusTrap as On, DropdownShortcut as Ot, SelectContent as P, DrawerHeader as Pt, NavbarSection as Q, CheckboxField as Qt, SelectScrollDownButton as R, DialogBody as Rt, SidebarDivider as S, AlertTitle as Sn, DropdownHeader as St, SidebarHeading as T, useDataInteractive as Tn, DropdownLabel as Tt, Rating as U, DescriptionTerm as Ut, SelectTrigger as V, DescriptionDetails as Vt, Radio as W, Combobox as Wt, NavbarItem as X, CodeBlock as Xt, NavbarDivider as Y, useClickOutside as Yt, NavbarLabel as Z, Checkbox as Zt, StackedLayout as _, TouchTarget as _n, Legend as _t, TimelineItem as a, useFieldDescriptionProps as an, ListboxLabel as at, Sidebar as b, AlertBody as bn, DropdownDescription as bt, TabList as c, Callout as cn, KbdShortcut as ct, Switch as d, Badge as dn, Description as dt, useToggle as en, LayoutGroup as et, SwitchField as f, BadgeButton as fn, ErrorMessage as ft, StatGroup as g, Button as gn, Label as gt, Stat as h, AvatarButton as hn, Fieldset as ht, Timeline as i, useFieldControlProps as in, ListboxDescription as it, useCloseContext as j, AccordionItem as jn, Drawer as jt, SidebarSpacer as k, useEscapeKey as kn, useTypeAhead as kt, TabPanel as l, Checkbox$1 as ln, Input as lt, Stepper as m, Avatar as mn, FieldGroup as mt, ToastProvider as n, FieldProvider as nn, useLayoutAnimation as nt, Textarea as o, useFieldErrorProps as on, ListboxOption as ot, SwitchGroup as p, AvatarGroup as pn, Field as pt, Progress as q, ComboboxOption as qt, useToast as r, useFieldContext as rn, Listbox as rt, Tab as s, useFieldLabelProps as sn, Kbd as st, Tooltip as t, useControllableState as tn, LayoutIndicator as tt, Tabs as u, CheckboxIndicator as un, InputGroup as ut, Slider as v, Alert as vn, Dropdown as vt, SidebarHeader as w, Link as wn, DropdownItem as wt, SidebarBody as x, AlertDescription as xn, DropdownDivider as xt, SidebarLayout as y, AlertActions as yn, DropdownButton as yt, SelectScrollUpButton as z, DialogDescription as zt };
3892
+
3893
+ //# sourceMappingURL=tooltip-DZGP3hO_.js.map