@ship-it-ui/ui 0.0.1 → 0.0.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.
package/dist/index.js CHANGED
@@ -1,30 +1,14 @@
1
- import { clsx } from 'clsx';
2
- import { twMerge } from 'tailwind-merge';
3
- import { forwardRef, Children, isValidElement, cloneElement, useId, useRef, useState, useImperativeHandle, createContext, useMemo, useEffect, Fragment as Fragment$1, useContext, useCallback } from 'react';
4
- import { Slot } from '@radix-ui/react-slot';
5
- import { cva } from 'class-variance-authority';
6
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
- import * as RadixCheckbox from '@radix-ui/react-checkbox';
8
- import * as RadixRadio from '@radix-ui/react-radio-group';
9
- import * as RadixSelect from '@radix-ui/react-select';
10
- import * as RadixSlider from '@radix-ui/react-slider';
11
- import * as RadixSwitch from '@radix-ui/react-switch';
12
- import * as RadixAvatar from '@radix-ui/react-avatar';
13
- import * as RadixContext from '@radix-ui/react-context-menu';
14
- import * as RadixDialog from '@radix-ui/react-dialog';
15
- import * as RadixAlert from '@radix-ui/react-alert-dialog';
16
- import * as RadixMenu from '@radix-ui/react-dropdown-menu';
17
- import * as RadixHoverCard from '@radix-ui/react-hover-card';
18
- import * as RadixPopover from '@radix-ui/react-popover';
19
- import * as RadixToast from '@radix-ui/react-toast';
20
- import * as RadixTooltip from '@radix-ui/react-tooltip';
21
- import * as RadixMenubar from '@radix-ui/react-menubar';
22
- import * as RadixTabs from '@radix-ui/react-tabs';
1
+ 'use client';
23
2
 
24
3
  // src/utils/cn.ts
4
+ import { clsx } from "clsx";
5
+ import { twMerge } from "tailwind-merge";
25
6
  function cn(...inputs) {
26
7
  return twMerge(clsx(inputs));
27
8
  }
9
+
10
+ // src/hooks/useControllableState.ts
11
+ import { useCallback, useRef, useState } from "react";
28
12
  function useControllableState({
29
13
  value: controlledValue,
30
14
  defaultValue,
@@ -51,31 +35,48 @@ function useControllableState({
51
35
  );
52
36
  return [value, setValue];
53
37
  }
38
+
39
+ // src/hooks/useDisclosure.ts
40
+ import { useCallback as useCallback2, useState as useState2 } from "react";
54
41
  function useDisclosure(initial = false) {
55
- const [open, setOpen] = useState(initial);
56
- const onOpen = useCallback(() => setOpen(true), []);
57
- const onClose = useCallback(() => setOpen(false), []);
58
- const onToggle = useCallback(() => setOpen((o) => !o), []);
42
+ const [open, setOpen] = useState2(initial);
43
+ const onOpen = useCallback2(() => setOpen(true), []);
44
+ const onClose = useCallback2(() => setOpen(false), []);
45
+ const onToggle = useCallback2(() => setOpen((o) => !o), []);
59
46
  return { open, onOpen, onClose, onToggle, setOpen };
60
47
  }
48
+
49
+ // src/hooks/useEscape.ts
50
+ import { useEffect, useRef as useRef2 } from "react";
61
51
  function useEscape(handler, enabled = true) {
52
+ const handlerRef = useRef2(handler);
53
+ useEffect(() => {
54
+ handlerRef.current = handler;
55
+ }, [handler]);
62
56
  useEffect(() => {
63
57
  if (!enabled) return;
64
58
  const onKey = (e) => {
65
- if (e.key === "Escape") handler();
59
+ if (e.key === "Escape") handlerRef.current();
66
60
  };
67
- window.addEventListener("keydown", onKey);
68
- return () => window.removeEventListener("keydown", onKey);
69
- }, [handler, enabled]);
61
+ document.addEventListener("keydown", onKey);
62
+ return () => document.removeEventListener("keydown", onKey);
63
+ }, [enabled]);
70
64
  }
65
+
66
+ // src/hooks/useIsomorphicLayoutEffect.ts
67
+ import { useEffect as useEffect2, useLayoutEffect } from "react";
68
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect2;
69
+
70
+ // src/hooks/useKeyboardList.ts
71
+ import { useCallback as useCallback3, useState as useState3 } from "react";
71
72
  function useKeyboardList({
72
73
  count,
73
74
  loop = true,
74
75
  defaultCursor = 0,
75
76
  onSelect
76
77
  }) {
77
- const [cursor, setCursor] = useState(defaultCursor);
78
- const move = useCallback(
78
+ const [cursor, setCursor] = useState3(defaultCursor);
79
+ const move = useCallback3(
79
80
  (delta) => {
80
81
  if (count <= 0) return;
81
82
  setCursor((c) => {
@@ -86,7 +87,7 @@ function useKeyboardList({
86
87
  },
87
88
  [count, loop]
88
89
  );
89
- const onKeyDown = useCallback(
90
+ const onKeyDown = useCallback3(
90
91
  (event) => {
91
92
  if (count <= 0) return;
92
93
  switch (event.key) {
@@ -112,6 +113,8 @@ function useKeyboardList({
112
113
  onSelect(cursor);
113
114
  }
114
115
  break;
116
+ default:
117
+ break;
115
118
  }
116
119
  },
117
120
  [count, cursor, move, onSelect]
@@ -119,23 +122,30 @@ function useKeyboardList({
119
122
  const safeCursor = count > 0 ? Math.min(cursor, count - 1) : 0;
120
123
  return { cursor: safeCursor, setCursor, onKeyDown };
121
124
  }
125
+
126
+ // src/hooks/useOutsideClick.ts
127
+ import { useEffect as useEffect3 } from "react";
122
128
  function useOutsideClick(ref, handler, enabled = true) {
123
- useEffect(() => {
129
+ useEffect3(() => {
124
130
  if (!enabled) return;
125
131
  const onDown = (e) => {
126
132
  const el = ref.current;
127
133
  if (el && e.target instanceof Node && !el.contains(e.target)) handler();
128
134
  };
129
- document.addEventListener("mousedown", onDown);
130
- return () => document.removeEventListener("mousedown", onDown);
135
+ document.addEventListener("pointerdown", onDown);
136
+ return () => document.removeEventListener("pointerdown", onDown);
131
137
  }, [ref, handler, enabled]);
132
138
  }
139
+
140
+ // src/hooks/useTheme.ts
141
+ import { useCallback as useCallback4, useEffect as useEffect4, useState as useState4 } from "react";
133
142
  function useTheme() {
134
- const [theme, setThemeState] = useState(() => {
135
- if (typeof document === "undefined") return "dark";
136
- return document.documentElement.getAttribute("data-theme") === "light" ? "light" : "dark";
137
- });
138
- const setTheme = useCallback((next) => {
143
+ const [theme, setThemeState] = useState4("dark");
144
+ const setTheme = useCallback4((next) => {
145
+ if (typeof document === "undefined") {
146
+ setThemeState(next);
147
+ return;
148
+ }
139
149
  if (next === "light") {
140
150
  document.documentElement.setAttribute("data-theme", "light");
141
151
  } else {
@@ -143,10 +153,12 @@ function useTheme() {
143
153
  }
144
154
  setThemeState(next);
145
155
  }, []);
146
- const toggle = useCallback(() => {
156
+ const toggle = useCallback4(() => {
147
157
  setTheme(theme === "dark" ? "light" : "dark");
148
158
  }, [theme, setTheme]);
149
- useEffect(() => {
159
+ useEffect4(() => {
160
+ const initial = document.documentElement.getAttribute("data-theme");
161
+ setThemeState(initial === "light" ? "light" : "dark");
150
162
  const observer = new MutationObserver(() => {
151
163
  const attr = document.documentElement.getAttribute("data-theme");
152
164
  setThemeState(attr === "light" ? "light" : "dark");
@@ -159,6 +171,12 @@ function useTheme() {
159
171
  }, []);
160
172
  return { theme, setTheme, toggle };
161
173
  }
174
+
175
+ // src/components/Button/Button.tsx
176
+ import { Slot } from "@radix-ui/react-slot";
177
+ import { cva } from "class-variance-authority";
178
+ import { forwardRef } from "react";
179
+ import { jsx, jsxs } from "react/jsx-runtime";
162
180
  var buttonStyles = cva(
163
181
  [
164
182
  "inline-flex items-center justify-center whitespace-nowrap",
@@ -255,7 +273,12 @@ var Button = forwardRef(function Button2({
255
273
  );
256
274
  });
257
275
  Button.displayName = "Button";
258
- var iconButtonStyles = cva(
276
+
277
+ // src/components/Button/IconButton.tsx
278
+ import { cva as cva2 } from "class-variance-authority";
279
+ import { forwardRef as forwardRef2 } from "react";
280
+ import { jsx as jsx2 } from "react/jsx-runtime";
281
+ var iconButtonStyles = cva2(
259
282
  [
260
283
  "inline-grid place-items-center transition-[background,filter,color] duration-(--duration-micro)",
261
284
  "outline-none focus-visible:ring-[3px] focus-visible:ring-accent-dim",
@@ -263,11 +286,16 @@ var iconButtonStyles = cva(
263
286
  ],
264
287
  {
265
288
  variants: {
289
+ // Mirrors `Button`'s variant set, minus `link` — an underlined link
290
+ // affordance is awkward for an icon-only target, so we omit it
291
+ // intentionally. Use `<Button variant="link" icon={…} />` if you need it.
266
292
  variant: {
267
293
  primary: "bg-accent text-on-accent border border-accent hover:brightness-110",
268
294
  secondary: "bg-panel-2 text-text-muted border border-border hover:bg-[color-mix(in_oklab,var(--color-panel-2),white_4%)]",
269
295
  ghost: "bg-transparent text-text-muted border border-transparent hover:bg-panel-2 hover:text-text",
270
- outline: "bg-transparent text-text-muted border border-border-strong hover:bg-panel-2 hover:text-text"
296
+ outline: "bg-transparent text-text-muted border border-border-strong hover:bg-panel-2 hover:text-text",
297
+ destructive: "bg-err text-on-accent border border-err hover:brightness-110 active:brightness-95",
298
+ success: "bg-ok text-on-accent border border-ok hover:brightness-110 active:brightness-95"
271
299
  },
272
300
  size: {
273
301
  sm: "h-[26px] w-[26px] text-[12px] rounded-[5px]",
@@ -278,8 +306,8 @@ var iconButtonStyles = cva(
278
306
  defaultVariants: { variant: "secondary", size: "md" }
279
307
  }
280
308
  );
281
- var IconButton = forwardRef(function IconButton2({ variant, size, icon, type, className, ...props }, ref) {
282
- return /* @__PURE__ */ jsx(
309
+ var IconButton = forwardRef2(function IconButton2({ variant, size, icon, type, className, ...props }, ref) {
310
+ return /* @__PURE__ */ jsx2(
283
311
  "button",
284
312
  {
285
313
  ref,
@@ -291,9 +319,18 @@ var IconButton = forwardRef(function IconButton2({ variant, size, icon, type, cl
291
319
  );
292
320
  });
293
321
  IconButton.displayName = "IconButton";
294
- var ButtonGroup = forwardRef(function ButtonGroup2({ orientation = "horizontal", className, children, ...props }, ref) {
322
+
323
+ // src/components/Button/ButtonGroup.tsx
324
+ import {
325
+ Children,
326
+ cloneElement,
327
+ forwardRef as forwardRef3,
328
+ isValidElement
329
+ } from "react";
330
+ import { jsx as jsx3 } from "react/jsx-runtime";
331
+ var ButtonGroup = forwardRef3(function ButtonGroup2({ orientation = "horizontal", className, children, ...props }, ref) {
295
332
  const items = Children.toArray(children).filter(isValidElement);
296
- return /* @__PURE__ */ jsx(
333
+ return /* @__PURE__ */ jsx3(
297
334
  "div",
298
335
  {
299
336
  ref,
@@ -320,27 +357,42 @@ var ButtonGroup = forwardRef(function ButtonGroup2({ orientation = "horizontal",
320
357
  );
321
358
  });
322
359
  ButtonGroup.displayName = "ButtonGroup";
323
- var SplitButton = forwardRef(function SplitButton2({ variant = "primary", size = "md", onClick, onMenu, disabled, className, children, ...props }, ref) {
324
- return /* @__PURE__ */ jsxs("div", { ref, className: cn("inline-flex", className), ...props, children: [
325
- /* @__PURE__ */ jsx(
360
+
361
+ // src/components/Button/SplitButton.tsx
362
+ import { forwardRef as forwardRef4 } from "react";
363
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
364
+ var SplitButton = forwardRef4(function SplitButton2({
365
+ variant = "primary",
366
+ size = "md",
367
+ onClick,
368
+ onMenu,
369
+ disabled,
370
+ menuAriaLabel = "More actions",
371
+ className,
372
+ children,
373
+ ...props
374
+ }, ref) {
375
+ const dividerBorder = variant === "primary" || variant === "destructive" || variant === "success" ? "border-r-on-accent/20" : "border-r-border-strong";
376
+ return /* @__PURE__ */ jsxs2("div", { ref, className: cn("inline-flex", className), ...props, children: [
377
+ /* @__PURE__ */ jsx4(
326
378
  Button,
327
379
  {
328
380
  variant,
329
381
  size,
330
382
  onClick,
331
383
  disabled,
332
- className: "rounded-r-none border-r border-r-black/20",
384
+ className: cn("rounded-r-none border-r", dividerBorder),
333
385
  children
334
386
  }
335
387
  ),
336
- /* @__PURE__ */ jsx(
388
+ /* @__PURE__ */ jsx4(
337
389
  Button,
338
390
  {
339
391
  variant,
340
392
  size,
341
393
  onClick: onMenu,
342
394
  disabled,
343
- "aria-label": "More actions",
395
+ "aria-label": menuAriaLabel,
344
396
  className: "rounded-l-none px-2",
345
397
  children: "\u25BE"
346
398
  }
@@ -348,8 +400,12 @@ var SplitButton = forwardRef(function SplitButton2({ variant = "primary", size =
348
400
  ] });
349
401
  });
350
402
  SplitButton.displayName = "SplitButton";
351
- var FAB = forwardRef(function FAB2({ icon = "\u2726", type, className, style, ...props }, ref) {
352
- return /* @__PURE__ */ jsx(
403
+
404
+ // src/components/Button/FAB.tsx
405
+ import { forwardRef as forwardRef5 } from "react";
406
+ import { jsx as jsx5 } from "react/jsx-runtime";
407
+ var FAB = forwardRef5(function FAB2({ icon = "\u2726", type, className, style, ...props }, ref) {
408
+ return /* @__PURE__ */ jsx5(
353
409
  "button",
354
410
  {
355
411
  ref,
@@ -371,10 +427,15 @@ var FAB = forwardRef(function FAB2({ icon = "\u2726", type, className, style, ..
371
427
  );
372
428
  });
373
429
  FAB.displayName = "FAB";
374
- var Checkbox = forwardRef(function Checkbox2({ label, className, id: idProp, ...props }, ref) {
430
+
431
+ // src/components/Checkbox/Checkbox.tsx
432
+ import * as RadixCheckbox from "@radix-ui/react-checkbox";
433
+ import { forwardRef as forwardRef6, useId } from "react";
434
+ import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
435
+ var Checkbox = forwardRef6(function Checkbox2({ label, className, id: idProp, ...props }, ref) {
375
436
  const reactId = useId();
376
437
  const id = idProp ?? `cb-${reactId}`;
377
- return /* @__PURE__ */ jsxs(
438
+ return /* @__PURE__ */ jsxs3(
378
439
  "span",
379
440
  {
380
441
  className: cn(
@@ -383,7 +444,7 @@ var Checkbox = forwardRef(function Checkbox2({ label, className, id: idProp, ...
383
444
  className
384
445
  ),
385
446
  children: [
386
- /* @__PURE__ */ jsx(
447
+ /* @__PURE__ */ jsx6(
387
448
  RadixCheckbox.Root,
388
449
  {
389
450
  ref,
@@ -397,36 +458,45 @@ var Checkbox = forwardRef(function Checkbox2({ label, className, id: idProp, ...
397
458
  "focus-visible:ring-accent-dim outline-none focus-visible:ring-[3px]"
398
459
  ),
399
460
  ...props,
400
- children: /* @__PURE__ */ jsx(RadixCheckbox.Indicator, { className: "text-on-accent text-[11px] leading-none", children: props.checked === "indeterminate" ? "\u2212" : "\u2713" })
461
+ children: /* @__PURE__ */ jsx6(RadixCheckbox.Indicator, { className: "text-on-accent text-[11px] leading-none", children: props.checked === "indeterminate" ? "\u2212" : "\u2713" })
401
462
  }
402
463
  ),
403
- label && /* @__PURE__ */ jsx("label", { htmlFor: id, className: "cursor-pointer text-[13px]", children: label })
464
+ label && /* @__PURE__ */ jsx6("label", { htmlFor: id, className: "cursor-pointer text-[13px]", children: label })
404
465
  ]
405
466
  }
406
467
  );
407
468
  });
408
469
  Checkbox.displayName = "Checkbox";
470
+
471
+ // src/components/Field/Field.tsx
472
+ import { useId as useId2 } from "react";
473
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
409
474
  function Field({ label, hint, error, required, className, children, ...props }) {
410
- const reactId = useId();
475
+ const reactId = useId2();
411
476
  const id = `field-${reactId}`;
412
477
  const hintId = hint && !error ? `${id}-hint` : void 0;
413
478
  const errorId = error ? `${id}-error` : void 0;
414
479
  const describedBy = errorId ?? hintId;
415
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-[6px]", className), ...props, children: [
416
- label && /* @__PURE__ */ jsxs("label", { htmlFor: id, className: "text-text-muted text-[11px] font-medium", children: [
480
+ return /* @__PURE__ */ jsxs4("div", { className: cn("flex flex-col gap-[6px]", className), ...props, children: [
481
+ label && /* @__PURE__ */ jsxs4("label", { htmlFor: id, className: "text-text-muted text-[11px] font-medium", children: [
417
482
  label,
418
- required && /* @__PURE__ */ jsx("span", { className: "text-err ml-1", children: "*" })
483
+ required && /* @__PURE__ */ jsx7("span", { className: "text-err ml-1", children: "*" })
419
484
  ] }),
420
485
  children({
421
486
  id,
422
487
  "aria-describedby": describedBy,
423
488
  "aria-invalid": error ? true : void 0
424
489
  }),
425
- hint && !error && /* @__PURE__ */ jsx("div", { id: hintId, className: "text-text-dim text-[11px]", children: hint }),
426
- error && /* @__PURE__ */ jsx("div", { id: errorId, className: "text-err text-[11px]", children: error })
490
+ hint && !error && /* @__PURE__ */ jsx7("div", { id: hintId, className: "text-text-dim text-[11px]", children: hint }),
491
+ error && /* @__PURE__ */ jsx7("div", { id: errorId, className: "text-err text-[11px]", children: error })
427
492
  ] });
428
493
  }
429
- var inputWrapperStyles = cva(
494
+
495
+ // src/components/Input/Input.tsx
496
+ import { cva as cva3 } from "class-variance-authority";
497
+ import { forwardRef as forwardRef7 } from "react";
498
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
499
+ var inputWrapperStyles = cva3(
430
500
  [
431
501
  "flex items-center gap-[6px] font-sans transition-[border-color,box-shadow] duration-(--duration-micro)",
432
502
  "border focus-within:ring-[3px]",
@@ -441,22 +511,22 @@ var inputWrapperStyles = cva(
441
511
  },
442
512
  tone: {
443
513
  default: "bg-panel border-border focus-within:border-accent focus-within:ring-accent-dim",
444
- error: "bg-panel border-err focus-within:border-err focus-within:ring-[oklch(0.55_0.18_30/0.18)]"
514
+ err: "bg-panel border-err focus-within:border-err focus-within:ring-err/30"
445
515
  }
446
516
  },
447
517
  defaultVariants: { size: "md", tone: "default" }
448
518
  }
449
519
  );
450
- var Input = forwardRef(function Input2({ size, tone, icon, trailing, error, width, className, style, disabled, ...props }, ref) {
451
- const computedTone = error ? "error" : tone;
452
- return /* @__PURE__ */ jsxs(
520
+ var Input = forwardRef7(function Input2({ size, tone, icon, trailing, error, width, className, style, disabled, ...props }, ref) {
521
+ const computedTone = error ? "err" : tone;
522
+ return /* @__PURE__ */ jsxs5(
453
523
  "div",
454
524
  {
455
525
  className: cn(inputWrapperStyles({ size, tone: computedTone }), className),
456
526
  style: { width, ...style },
457
527
  children: [
458
- icon && /* @__PURE__ */ jsx("span", { className: "text-text-dim leading-none", children: icon }),
459
- /* @__PURE__ */ jsx(
528
+ icon && /* @__PURE__ */ jsx8("span", { className: "text-text-dim leading-none", children: icon }),
529
+ /* @__PURE__ */ jsx8(
460
530
  "input",
461
531
  {
462
532
  ref,
@@ -470,14 +540,26 @@ var Input = forwardRef(function Input2({ size, tone, icon, trailing, error, widt
470
540
  ...props
471
541
  }
472
542
  ),
473
- trailing && /* @__PURE__ */ jsx("span", { className: "text-text-dim text-[11px]", children: trailing })
543
+ trailing && /* @__PURE__ */ jsx8("span", { className: "text-text-dim text-[11px]", children: trailing })
474
544
  ]
475
545
  }
476
546
  );
477
547
  });
478
548
  Input.displayName = "Input";
479
- var SearchInput = forwardRef(function SearchInput2({ shortcut = "\u2318K", width = 360, className, style, placeholder = "Search\u2026", ...props }, ref) {
480
- return /* @__PURE__ */ jsxs(
549
+
550
+ // src/components/Input/SearchInput.tsx
551
+ import { forwardRef as forwardRef8 } from "react";
552
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
553
+ var SearchInput = forwardRef8(function SearchInput2({
554
+ shortcut = "\u2318K",
555
+ width = 360,
556
+ className,
557
+ style,
558
+ placeholder = "Search\u2026",
559
+ "aria-label": ariaLabel,
560
+ ...props
561
+ }, ref) {
562
+ return /* @__PURE__ */ jsxs6(
481
563
  "div",
482
564
  {
483
565
  className: cn(
@@ -489,46 +571,63 @@ var SearchInput = forwardRef(function SearchInput2({ shortcut = "\u2318K", width
489
571
  ),
490
572
  style: { width, ...style },
491
573
  children: [
492
- /* @__PURE__ */ jsx("span", { className: "text-text-dim leading-none", children: "\u2315" }),
493
- /* @__PURE__ */ jsx(
574
+ /* @__PURE__ */ jsx9("span", { className: "text-text-dim leading-none", "aria-hidden": true, children: "\u2315" }),
575
+ /* @__PURE__ */ jsx9(
494
576
  "input",
495
577
  {
496
578
  ref,
497
579
  type: "search",
498
580
  placeholder,
581
+ "aria-label": ariaLabel ?? (typeof placeholder === "string" ? placeholder : "Search"),
499
582
  className: "text-text placeholder:text-text-dim min-w-0 flex-1 border-none bg-transparent text-[13px] outline-none",
500
583
  ...props
501
584
  }
502
585
  ),
503
- shortcut && /* @__PURE__ */ jsx("kbd", { className: "text-text-dim border-border rounded-xs border px-[6px] py-[2px] font-mono text-[10px]", children: shortcut })
586
+ shortcut && /* @__PURE__ */ jsx9("kbd", { className: "text-text-dim border-border rounded-xs border px-[6px] py-[2px] font-mono text-[10px]", children: shortcut })
504
587
  ]
505
588
  }
506
589
  );
507
590
  });
508
591
  SearchInput.displayName = "SearchInput";
509
- var OTP = forwardRef(function OTP2({ length = 6, onComplete, onChange, defaultValue = "", ariaLabel = "Code", className, disabled }, ref) {
510
- const baseId = useId();
511
- const refs = useRef([]);
512
- const [values, setValues] = useState(
592
+
593
+ // src/components/OTP/OTP.tsx
594
+ import {
595
+ forwardRef as forwardRef9,
596
+ useId as useId3,
597
+ useImperativeHandle,
598
+ useRef as useRef3,
599
+ useState as useState5
600
+ } from "react";
601
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
602
+ var OTP = forwardRef9(function OTP2({ length = 6, onComplete, onChange, defaultValue = "", ariaLabel = "Code", className, disabled }, ref) {
603
+ const baseId = useId3();
604
+ const refs = useRef3([]);
605
+ const [values, setValues] = useState5(
513
606
  () => Array.from({ length }, (_, i) => defaultValue[i] ?? "")
514
607
  );
608
+ const [completedAnnouncement, setCompletedAnnouncement] = useState5("");
515
609
  useImperativeHandle(ref, () => ({
516
610
  focus: () => refs.current[0]?.focus(),
517
611
  reset: () => {
518
612
  setValues(Array(length).fill(""));
613
+ setCompletedAnnouncement("");
519
614
  refs.current[0]?.focus();
520
615
  }
521
616
  }));
522
617
  const writeAt = (i, char) => {
523
618
  if (!/^\d?$/.test(char)) return;
524
- setValues((prev) => {
525
- const next = [...prev];
526
- next[i] = char;
527
- const joined = next.join("");
528
- onChange?.(joined);
529
- if (joined.length === length && next.every((c) => c)) onComplete?.(joined);
530
- return next;
531
- });
619
+ const next = [...values];
620
+ next[i] = char;
621
+ setValues(next);
622
+ const joined = next.join("");
623
+ onChange?.(joined);
624
+ const isComplete = joined.length === length && next.every((c) => c);
625
+ if (isComplete) {
626
+ onComplete?.(joined);
627
+ setCompletedAnnouncement("Code complete");
628
+ } else {
629
+ setCompletedAnnouncement("");
630
+ }
532
631
  if (char && i < length - 1) refs.current[i + 1]?.focus();
533
632
  };
534
633
  const onKey = (i, e) => {
@@ -548,45 +647,59 @@ var OTP = forwardRef(function OTP2({ length = 6, onComplete, onChange, defaultVa
548
647
  setValues(next);
549
648
  const joined = next.join("");
550
649
  onChange?.(joined);
551
- if (joined.length === length) onComplete?.(joined);
650
+ const isComplete = joined.length === length && next.every((c) => c);
651
+ if (isComplete) {
652
+ onComplete?.(joined);
653
+ setCompletedAnnouncement("Code complete");
654
+ } else {
655
+ setCompletedAnnouncement("");
656
+ }
552
657
  refs.current[Math.min(pasted.length, length - 1)]?.focus();
553
658
  };
554
- return /* @__PURE__ */ jsx("div", { className: cn("flex gap-2", className), children: values.map((c, i) => /* @__PURE__ */ jsx(
555
- "input",
556
- {
557
- id: `${baseId}-${i}`,
558
- ref: (el) => {
559
- refs.current[i] = el;
659
+ return /* @__PURE__ */ jsxs7("div", { className: cn("flex gap-2", className), children: [
660
+ values.map((c, i) => /* @__PURE__ */ jsx10(
661
+ "input",
662
+ {
663
+ id: `${baseId}-${i}`,
664
+ ref: (el) => {
665
+ refs.current[i] = el;
666
+ },
667
+ inputMode: "numeric",
668
+ autoComplete: "one-time-code",
669
+ maxLength: 1,
670
+ value: c,
671
+ disabled,
672
+ "aria-label": `${ariaLabel} ${i + 1} of ${length}`,
673
+ onChange: (e) => writeAt(i, e.target.value),
674
+ onKeyDown: (e) => onKey(i, e),
675
+ onFocus: (e) => e.target.select(),
676
+ onPaste: i === 0 ? onPaste : void 0,
677
+ className: cn(
678
+ "text-text bg-panel h-12 w-10 rounded-md text-center font-mono text-[20px] font-medium",
679
+ "border-border border transition-[border-color,box-shadow] duration-(--duration-micro) outline-none",
680
+ "focus:border-accent focus:ring-accent-dim focus:ring-[3px]",
681
+ "disabled:cursor-not-allowed disabled:opacity-50"
682
+ )
560
683
  },
561
- inputMode: "numeric",
562
- autoComplete: "one-time-code",
563
- maxLength: 1,
564
- value: c,
565
- disabled,
566
- "aria-label": `${ariaLabel} ${i + 1} of ${length}`,
567
- onChange: (e) => writeAt(i, e.target.value),
568
- onKeyDown: (e) => onKey(i, e),
569
- onFocus: (e) => e.target.select(),
570
- onPaste: i === 0 ? onPaste : void 0,
571
- className: cn(
572
- "text-text bg-panel h-12 w-10 rounded-md text-center font-mono text-[20px] font-medium",
573
- "border-border border transition-[border-color,box-shadow] duration-(--duration-micro) outline-none",
574
- "focus:border-accent focus:ring-accent-dim focus:ring-[3px]",
575
- "disabled:cursor-not-allowed disabled:opacity-50"
576
- )
577
- },
578
- i
579
- )) });
684
+ i
685
+ )),
686
+ /* @__PURE__ */ jsx10("span", { className: "sr-only", "aria-live": "polite", "aria-atomic": "true", children: completedAnnouncement })
687
+ ] });
580
688
  });
581
689
  OTP.displayName = "OTP";
582
- var RadioGroup = forwardRef(function RadioGroup2({ className, ...props }, ref) {
583
- return /* @__PURE__ */ jsx(RadixRadio.Root, { ref, className: cn("flex flex-col gap-2", className), ...props });
690
+
691
+ // src/components/Radio/Radio.tsx
692
+ import * as RadixRadio from "@radix-ui/react-radio-group";
693
+ import { forwardRef as forwardRef10, useId as useId4 } from "react";
694
+ import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
695
+ var RadioGroup = forwardRef10(function RadioGroup2({ className, ...props }, ref) {
696
+ return /* @__PURE__ */ jsx11(RadixRadio.Root, { ref, className: cn("flex flex-col gap-2", className), ...props });
584
697
  });
585
698
  RadioGroup.displayName = "RadioGroup";
586
- var Radio = forwardRef(function Radio2({ label, className, id: idProp, ...props }, ref) {
587
- const reactId = useId();
699
+ var Radio = forwardRef10(function Radio2({ label, className, id: idProp, ...props }, ref) {
700
+ const reactId = useId4();
588
701
  const id = idProp ?? `radio-${reactId}`;
589
- return /* @__PURE__ */ jsxs(
702
+ return /* @__PURE__ */ jsxs8(
590
703
  "span",
591
704
  {
592
705
  className: cn(
@@ -595,7 +708,7 @@ var Radio = forwardRef(function Radio2({ label, className, id: idProp, ...props
595
708
  className
596
709
  ),
597
710
  children: [
598
- /* @__PURE__ */ jsx(
711
+ /* @__PURE__ */ jsx11(
599
712
  RadixRadio.Item,
600
713
  {
601
714
  ref,
@@ -608,15 +721,20 @@ var Radio = forwardRef(function Radio2({ label, className, id: idProp, ...props
608
721
  "focus-visible:ring-accent-dim outline-none focus-visible:ring-[3px]"
609
722
  ),
610
723
  ...props,
611
- children: /* @__PURE__ */ jsx(RadixRadio.Indicator, { className: "bg-accent block h-[7px] w-[7px] rounded-full" })
724
+ children: /* @__PURE__ */ jsx11(RadixRadio.Indicator, { className: "bg-accent block h-[7px] w-[7px] rounded-full" })
612
725
  }
613
726
  ),
614
- label && /* @__PURE__ */ jsx("label", { htmlFor: id, className: "cursor-pointer text-[13px]", children: label })
727
+ label && /* @__PURE__ */ jsx11("label", { htmlFor: id, className: "cursor-pointer text-[13px]", children: label })
615
728
  ]
616
729
  }
617
730
  );
618
731
  });
619
732
  Radio.displayName = "Radio";
733
+
734
+ // src/components/Select/Select.tsx
735
+ import * as RadixSelect from "@radix-ui/react-select";
736
+ import { forwardRef as forwardRef11 } from "react";
737
+ import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
620
738
  var SelectRoot = RadixSelect.Root;
621
739
  var SelectValue = RadixSelect.Value;
622
740
  var SelectGroup = RadixSelect.Group;
@@ -626,8 +744,8 @@ var triggerClasses = {
626
744
  md: "h-[34px] px-[10px] text-[13px]",
627
745
  lg: "h-10 px-3 text-[14px]"
628
746
  };
629
- var SelectTrigger = forwardRef(function SelectTrigger2({ size = "md", className, children, ...props }, ref) {
630
- return /* @__PURE__ */ jsxs(
747
+ var SelectTrigger = forwardRef11(function SelectTrigger2({ size = "md", className, children, ...props }, ref) {
748
+ return /* @__PURE__ */ jsxs9(
631
749
  RadixSelect.Trigger,
632
750
  {
633
751
  ref,
@@ -643,35 +761,35 @@ var SelectTrigger = forwardRef(function SelectTrigger2({ size = "md", className,
643
761
  ...props,
644
762
  children: [
645
763
  children,
646
- /* @__PURE__ */ jsx(RadixSelect.Icon, { className: "text-text-dim text-[11px] leading-none", children: "\u25BE" })
764
+ /* @__PURE__ */ jsx12(RadixSelect.Icon, { className: "text-text-dim text-[11px] leading-none", children: "\u25BE" })
647
765
  ]
648
766
  }
649
767
  );
650
768
  });
651
769
  SelectTrigger.displayName = "SelectTrigger";
652
- var SelectContent = forwardRef(
770
+ var SelectContent = forwardRef11(
653
771
  function SelectContent2({ className, children, position = "popper", sideOffset = 6, ...props }, ref) {
654
- return /* @__PURE__ */ jsx(RadixSelect.Portal, { children: /* @__PURE__ */ jsx(
772
+ return /* @__PURE__ */ jsx12(RadixSelect.Portal, { children: /* @__PURE__ */ jsx12(
655
773
  RadixSelect.Content,
656
774
  {
657
775
  ref,
658
776
  position,
659
777
  sideOffset,
660
778
  className: cn(
661
- "bg-panel border-border z-50 min-w-[var(--radix-select-trigger-width)] rounded-md border p-1 shadow",
779
+ "bg-panel border-border z-popover min-w-[var(--radix-select-trigger-width)] rounded-md border p-1 shadow",
662
780
  "data-[state=open]:animate-[ship-pop-in_140ms_var(--easing-out)]",
663
781
  className
664
782
  ),
665
783
  ...props,
666
- children: /* @__PURE__ */ jsx(RadixSelect.Viewport, { children })
784
+ children: /* @__PURE__ */ jsx12(RadixSelect.Viewport, { children })
667
785
  }
668
786
  ) });
669
787
  }
670
788
  );
671
789
  SelectContent.displayName = "SelectContent";
672
- var SelectItem = forwardRef(
790
+ var SelectItem = forwardRef11(
673
791
  function SelectItem2({ className, children, ...props }, ref) {
674
- return /* @__PURE__ */ jsx(
792
+ return /* @__PURE__ */ jsx12(
675
793
  RadixSelect.Item,
676
794
  {
677
795
  ref,
@@ -683,7 +801,7 @@ var SelectItem = forwardRef(
683
801
  className
684
802
  ),
685
803
  ...props,
686
- children: /* @__PURE__ */ jsx(RadixSelect.ItemText, { children })
804
+ children: /* @__PURE__ */ jsx12(RadixSelect.ItemText, { children })
687
805
  }
688
806
  );
689
807
  }
@@ -698,36 +816,52 @@ function Select({
698
816
  "aria-labelledby": ariaLabelledBy,
699
817
  ...rootProps
700
818
  }) {
701
- return /* @__PURE__ */ jsxs(RadixSelect.Root, { ...rootProps, children: [
702
- /* @__PURE__ */ jsx(
819
+ return /* @__PURE__ */ jsxs9(RadixSelect.Root, { ...rootProps, children: [
820
+ /* @__PURE__ */ jsx12(
703
821
  SelectTrigger,
704
822
  {
705
823
  size,
706
824
  className,
707
825
  "aria-label": ariaLabel,
708
826
  "aria-labelledby": ariaLabelledBy,
709
- children: /* @__PURE__ */ jsx(SelectValue, { placeholder })
827
+ children: /* @__PURE__ */ jsx12(SelectValue, { placeholder })
710
828
  }
711
829
  ),
712
- /* @__PURE__ */ jsx(SelectContent, { children: options.map((opt) => {
830
+ /* @__PURE__ */ jsx12(SelectContent, { children: options.map((opt) => {
713
831
  const value = typeof opt === "string" ? opt : opt.value;
714
832
  const label = typeof opt === "string" ? opt : opt.label;
715
- return /* @__PURE__ */ jsx(SelectItem, { value, children: label }, value);
833
+ return /* @__PURE__ */ jsx12(SelectItem, { value, children: label }, value);
716
834
  }) })
717
835
  ] });
718
836
  }
719
- var Slider = forwardRef(function Slider2({ showValue, width = 240, className, value, defaultValue, ...props }, ref) {
837
+
838
+ // src/components/Slider/Slider.tsx
839
+ import * as RadixSlider from "@radix-ui/react-slider";
840
+ import { forwardRef as forwardRef12 } from "react";
841
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
842
+ var Slider = forwardRef12(function Slider2({
843
+ showValue,
844
+ width = 240,
845
+ className,
846
+ value,
847
+ defaultValue,
848
+ thumbLabels,
849
+ "aria-label": ariaLabel,
850
+ "aria-labelledby": ariaLabelledBy,
851
+ ...props
852
+ }, ref) {
720
853
  const arrValue = Array.isArray(value) ? value : value !== void 0 ? [value] : void 0;
721
854
  const arrDefault = Array.isArray(defaultValue) ? defaultValue : defaultValue !== void 0 ? [defaultValue] : void 0;
722
855
  const display = arrValue?.[0] ?? arrDefault?.[0] ?? props.min ?? 0;
723
- return /* @__PURE__ */ jsxs(
856
+ const thumbCount = (arrValue ?? arrDefault)?.length ?? 1;
857
+ return /* @__PURE__ */ jsxs10(
724
858
  "span",
725
859
  {
726
860
  ref,
727
861
  className: cn("inline-flex items-center gap-[10px]", className),
728
862
  style: { width },
729
863
  children: [
730
- /* @__PURE__ */ jsxs(
864
+ /* @__PURE__ */ jsxs10(
731
865
  RadixSlider.Root,
732
866
  {
733
867
  value: arrValue,
@@ -735,27 +869,38 @@ var Slider = forwardRef(function Slider2({ showValue, width = 240, className, va
735
869
  className: "relative flex h-4 flex-1 touch-none items-center select-none",
736
870
  ...props,
737
871
  children: [
738
- /* @__PURE__ */ jsx(RadixSlider.Track, { className: "bg-panel-2 relative h-1 grow rounded-full", children: /* @__PURE__ */ jsx(RadixSlider.Range, { className: "bg-accent absolute h-full rounded-full" }) }),
739
- /* @__PURE__ */ jsx(
740
- RadixSlider.Thumb,
741
- {
742
- className: cn(
743
- "bg-text border-accent block h-[14px] w-[14px] rounded-full border-2 shadow",
744
- "focus-visible:ring-accent-dim outline-none focus-visible:ring-[3px]",
745
- "cursor-grab active:cursor-grabbing"
746
- ),
747
- "aria-label": "Value"
748
- }
749
- )
872
+ /* @__PURE__ */ jsx13(RadixSlider.Track, { className: "bg-panel-2 relative h-1 grow rounded-full", children: /* @__PURE__ */ jsx13(RadixSlider.Range, { className: "bg-accent absolute h-full rounded-full" }) }),
873
+ Array.from({ length: thumbCount }, (_, i) => {
874
+ const perThumb = thumbLabels?.[i];
875
+ const thumbAriaLabel = perThumb ?? (ariaLabelledBy ? void 0 : ariaLabel ?? "Value");
876
+ return /* @__PURE__ */ jsx13(
877
+ RadixSlider.Thumb,
878
+ {
879
+ className: cn(
880
+ "bg-text border-accent block h-[14px] w-[14px] rounded-full border-2 shadow",
881
+ "focus-visible:ring-accent-dim outline-none focus-visible:ring-[3px]",
882
+ "cursor-grab active:cursor-grabbing"
883
+ ),
884
+ "aria-label": thumbAriaLabel,
885
+ "aria-labelledby": perThumb ? void 0 : ariaLabelledBy
886
+ },
887
+ i
888
+ );
889
+ })
750
890
  ]
751
891
  }
752
892
  ),
753
- showValue && /* @__PURE__ */ jsx("span", { className: "text-text-muted min-w-[28px] text-right font-mono text-[11px]", children: display })
893
+ showValue && /* @__PURE__ */ jsx13("span", { className: "text-text-muted min-w-[28px] text-right font-mono text-[11px]", children: display })
754
894
  ]
755
895
  }
756
896
  );
757
897
  });
758
898
  Slider.displayName = "Slider";
899
+
900
+ // src/components/Switch/Switch.tsx
901
+ import * as RadixSwitch from "@radix-ui/react-switch";
902
+ import { forwardRef as forwardRef13, useId as useId5 } from "react";
903
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
759
904
  var trackClasses = {
760
905
  sm: "h-4 w-7",
761
906
  md: "h-5 w-9"
@@ -764,10 +909,10 @@ var thumbClasses = {
764
909
  sm: "h-3 w-3 data-[state=checked]:translate-x-3",
765
910
  md: "h-4 w-4 data-[state=checked]:translate-x-4"
766
911
  };
767
- var Switch = forwardRef(function Switch2({ label, size = "md", className, id: idProp, ...props }, ref) {
768
- const reactId = useId();
912
+ var Switch = forwardRef13(function Switch2({ label, size = "md", className, id: idProp, ...props }, ref) {
913
+ const reactId = useId5();
769
914
  const id = idProp ?? `sw-${reactId}`;
770
- return /* @__PURE__ */ jsxs(
915
+ return /* @__PURE__ */ jsxs11(
771
916
  "span",
772
917
  {
773
918
  className: cn(
@@ -776,7 +921,7 @@ var Switch = forwardRef(function Switch2({ label, size = "md", className, id: id
776
921
  className
777
922
  ),
778
923
  children: [
779
- /* @__PURE__ */ jsx(
924
+ /* @__PURE__ */ jsx14(
780
925
  RadixSwitch.Root,
781
926
  {
782
927
  ref,
@@ -789,7 +934,7 @@ var Switch = forwardRef(function Switch2({ label, size = "md", className, id: id
789
934
  trackClasses[size]
790
935
  ),
791
936
  ...props,
792
- children: /* @__PURE__ */ jsx(
937
+ children: /* @__PURE__ */ jsx14(
793
938
  RadixSwitch.Thumb,
794
939
  {
795
940
  className: cn(
@@ -801,13 +946,18 @@ var Switch = forwardRef(function Switch2({ label, size = "md", className, id: id
801
946
  )
802
947
  }
803
948
  ),
804
- label && /* @__PURE__ */ jsx("label", { htmlFor: id, className: "cursor-pointer text-[13px]", children: label })
949
+ label && /* @__PURE__ */ jsx14("label", { htmlFor: id, className: "cursor-pointer text-[13px]", children: label })
805
950
  ]
806
951
  }
807
952
  );
808
953
  });
809
954
  Switch.displayName = "Switch";
810
- var textareaStyles = cva(
955
+
956
+ // src/components/Textarea/Textarea.tsx
957
+ import { cva as cva4 } from "class-variance-authority";
958
+ import { forwardRef as forwardRef14 } from "react";
959
+ import { jsx as jsx15 } from "react/jsx-runtime";
960
+ var textareaStyles = cva4(
811
961
  [
812
962
  "w-full font-sans text-text bg-panel rounded-md p-[10px]",
813
963
  "border outline-none transition-[border-color,box-shadow] duration-(--duration-micro)",
@@ -819,26 +969,97 @@ var textareaStyles = cva(
819
969
  variants: {
820
970
  tone: {
821
971
  default: "border-border focus-visible:border-accent focus-visible:ring-accent-dim",
822
- error: "border-err focus-visible:border-err focus-visible:ring-[oklch(0.55_0.18_30/0.18)]"
972
+ err: "border-err focus-visible:border-err focus-visible:ring-err/30"
823
973
  }
824
974
  },
825
975
  defaultVariants: { tone: "default" }
826
976
  }
827
977
  );
828
- var Textarea = forwardRef(function Textarea2({ tone, error, rows = 4, className, ...props }, ref) {
829
- return /* @__PURE__ */ jsx(
978
+ var Textarea = forwardRef14(function Textarea2({ tone, error, rows = 4, className, ...props }, ref) {
979
+ return /* @__PURE__ */ jsx15(
830
980
  "textarea",
831
981
  {
832
982
  ref,
833
983
  rows,
834
984
  "aria-invalid": error || void 0,
835
- className: cn(textareaStyles({ tone: error ? "error" : tone }), className),
985
+ className: cn(textareaStyles({ tone: error ? "err" : tone }), className),
836
986
  ...props
837
987
  }
838
988
  );
839
989
  });
840
990
  Textarea.displayName = "Textarea";
841
- var sizePx = { xs: 20, sm: 24, md: 32, lg: 40, xl: 56 };
991
+
992
+ // src/components/Avatar/Avatar.tsx
993
+ import * as RadixAvatar from "@radix-ui/react-avatar";
994
+ import { forwardRef as forwardRef16 } from "react";
995
+
996
+ // src/components/StatusDot/StatusDot.tsx
997
+ import { forwardRef as forwardRef15 } from "react";
998
+ import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
999
+ var stateColor = {
1000
+ ok: "bg-ok",
1001
+ warn: "bg-warn",
1002
+ err: "bg-err",
1003
+ off: "bg-text-dim",
1004
+ sync: "bg-accent",
1005
+ accent: "bg-accent"
1006
+ };
1007
+ var stateText = {
1008
+ ok: "text-ok",
1009
+ warn: "text-warn",
1010
+ err: "text-err",
1011
+ off: "text-text-dim",
1012
+ sync: "text-accent",
1013
+ accent: "text-accent"
1014
+ };
1015
+ var stateLabel = {
1016
+ ok: "Online",
1017
+ warn: "Warning",
1018
+ err: "Error",
1019
+ off: "Offline",
1020
+ sync: "Syncing",
1021
+ accent: "Active"
1022
+ };
1023
+ var StatusDot = forwardRef15(function StatusDot2({ state = "ok", label, pulse, size = 8, className, ...props }, ref) {
1024
+ return /* @__PURE__ */ jsxs12(
1025
+ "span",
1026
+ {
1027
+ ref,
1028
+ role: label ? "status" : "img",
1029
+ "aria-label": !label ? stateLabel[state] : void 0,
1030
+ className: cn("inline-flex items-center gap-[6px]", className),
1031
+ ...props,
1032
+ children: [
1033
+ /* @__PURE__ */ jsx16(
1034
+ "span",
1035
+ {
1036
+ className: cn(
1037
+ "inline-block rounded-full",
1038
+ stateColor[state],
1039
+ pulse && "animate-[ship-pulse-ring_1.6s_infinite]",
1040
+ stateText[state]
1041
+ ),
1042
+ style: { width: size, height: size }
1043
+ }
1044
+ ),
1045
+ label && /* @__PURE__ */ jsx16("span", { className: "text-text-muted text-[12px]", children: label })
1046
+ ]
1047
+ }
1048
+ );
1049
+ });
1050
+ StatusDot.displayName = "StatusDot";
1051
+
1052
+ // src/components/Avatar/sizes.ts
1053
+ var sizePx = {
1054
+ xs: 20,
1055
+ sm: 24,
1056
+ md: 32,
1057
+ lg: 40,
1058
+ xl: 56
1059
+ };
1060
+
1061
+ // src/components/Avatar/Avatar.tsx
1062
+ import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
842
1063
  var statusBg = {
843
1064
  ok: "bg-ok",
844
1065
  warn: "bg-warn",
@@ -853,11 +1074,11 @@ function hashHue(str) {
853
1074
  for (let i = 0; i < str.length; i++) h = (h * 31 + str.charCodeAt(i)) % 360;
854
1075
  return h;
855
1076
  }
856
- var Avatar = forwardRef(function Avatar2({ name = "?", src, size = "md", status, initials, className, style, ...props }, ref) {
1077
+ var Avatar = forwardRef16(function Avatar2({ name = "?", src, size = "md", status, initials, className, style, ...props }, ref) {
857
1078
  const dim = sizePx[size];
858
1079
  const hue = hashHue(name);
859
1080
  const computedInitials = initials ?? initialsFor(name);
860
- return /* @__PURE__ */ jsxs(
1081
+ return /* @__PURE__ */ jsxs13(
861
1082
  "span",
862
1083
  {
863
1084
  ref,
@@ -865,14 +1086,16 @@ var Avatar = forwardRef(function Avatar2({ name = "?", src, size = "md", status,
865
1086
  style: { width: dim, height: dim, ...style },
866
1087
  ...props,
867
1088
  children: [
868
- /* @__PURE__ */ jsxs(
1089
+ /* @__PURE__ */ jsxs13(
869
1090
  RadixAvatar.Root,
870
1091
  {
871
1092
  className: "border-border relative inline-flex h-full w-full shrink-0 overflow-hidden rounded-full border",
872
- style: { background: src ? void 0 : `oklch(0.4 0.1 ${hue})` },
1093
+ style: {
1094
+ background: src ? void 0 : `oklch(var(--color-avatar-fallback-l) var(--color-avatar-fallback-c) ${hue})`
1095
+ },
873
1096
  children: [
874
- src && /* @__PURE__ */ jsx(RadixAvatar.Image, { src, alt: name, className: "h-full w-full object-cover" }),
875
- /* @__PURE__ */ jsx(
1097
+ src && /* @__PURE__ */ jsx17(RadixAvatar.Image, { src, alt: name, className: "h-full w-full object-cover" }),
1098
+ /* @__PURE__ */ jsx17(
876
1099
  RadixAvatar.Fallback,
877
1100
  {
878
1101
  className: "flex h-full w-full items-center justify-center font-sans font-semibold text-white",
@@ -883,11 +1106,11 @@ var Avatar = forwardRef(function Avatar2({ name = "?", src, size = "md", status,
883
1106
  ]
884
1107
  }
885
1108
  ),
886
- status && /* @__PURE__ */ jsx(
1109
+ status && /* @__PURE__ */ jsx17(
887
1110
  "span",
888
1111
  {
889
1112
  role: "img",
890
- "aria-label": `status: ${status}`,
1113
+ "aria-label": stateLabel[status],
891
1114
  className: cn(
892
1115
  "border-bg absolute right-0 bottom-0 rounded-full border-[2px]",
893
1116
  statusBg[status]
@@ -900,15 +1123,18 @@ var Avatar = forwardRef(function Avatar2({ name = "?", src, size = "md", status,
900
1123
  );
901
1124
  });
902
1125
  Avatar.displayName = "Avatar";
903
- var sizePx2 = { xs: 20, sm: 24, md: 32, lg: 40, xl: 56 };
904
- var AvatarGroup = forwardRef(function AvatarGroup2({ names, max = 3, size = "md", className, ...props }, ref) {
905
- const dim = sizePx2[size];
1126
+
1127
+ // src/components/Avatar/AvatarGroup.tsx
1128
+ import { forwardRef as forwardRef17 } from "react";
1129
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
1130
+ var AvatarGroup = forwardRef17(function AvatarGroup2({ names, max = 3, size = "md", className, ...props }, ref) {
1131
+ const dim = sizePx[size];
906
1132
  const visible = names.slice(0, max);
907
1133
  const rest = names.length - visible.length;
908
1134
  const overlap = -dim * 0.35;
909
- return /* @__PURE__ */ jsxs("div", { ref, className: cn("inline-flex", className), ...props, children: [
910
- visible.map((n, i) => /* @__PURE__ */ jsx("span", { style: { marginLeft: i === 0 ? 0 : overlap }, children: /* @__PURE__ */ jsx(Avatar, { name: n, size }) }, `${n}-${i}`)),
911
- rest > 0 && /* @__PURE__ */ jsxs(
1135
+ return /* @__PURE__ */ jsxs14("div", { ref, className: cn("inline-flex", className), ...props, children: [
1136
+ visible.map((n, i) => /* @__PURE__ */ jsx18("span", { style: { marginLeft: i === 0 ? 0 : overlap }, children: /* @__PURE__ */ jsx18(Avatar, { name: n, size }) }, `${n}-${i}`)),
1137
+ rest > 0 && /* @__PURE__ */ jsxs14(
912
1138
  "span",
913
1139
  {
914
1140
  "aria-label": `+${rest} more`,
@@ -928,7 +1154,12 @@ var AvatarGroup = forwardRef(function AvatarGroup2({ names, max = 3, size = "md"
928
1154
  ] });
929
1155
  });
930
1156
  AvatarGroup.displayName = "AvatarGroup";
931
- var badgeStyles = cva("inline-flex items-center font-sans leading-none whitespace-nowrap", {
1157
+
1158
+ // src/components/Badge/Badge.tsx
1159
+ import { cva as cva5 } from "class-variance-authority";
1160
+ import { forwardRef as forwardRef18 } from "react";
1161
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
1162
+ var badgeStyles = cva5("inline-flex items-center font-sans leading-none whitespace-nowrap", {
932
1163
  variants: {
933
1164
  variant: {
934
1165
  neutral: "bg-panel-2 text-text-muted border border-border",
@@ -961,21 +1192,28 @@ var dotColorClass = {
961
1192
  solid: "bg-bg"
962
1193
  };
963
1194
  var dotSize = { sm: "h-[5px] w-[5px]", md: "h-[6px] w-[6px]", lg: "h-[7px] w-[7px]" };
964
- var Badge = forwardRef(function Badge2({ variant = "neutral", size = "md", dot, icon, className, children, ...props }, ref) {
965
- return /* @__PURE__ */ jsxs("span", { ref, className: cn(badgeStyles({ variant, size }), className), ...props, children: [
966
- dot && /* @__PURE__ */ jsx(
1195
+ var Badge = forwardRef18(function Badge2({ variant = "neutral", size = "md", dot, icon, className, children, ...props }, ref) {
1196
+ const sz = size ?? "md";
1197
+ const v = variant ?? "neutral";
1198
+ return /* @__PURE__ */ jsxs15("span", { ref, className: cn(badgeStyles({ variant, size }), className), ...props, children: [
1199
+ dot && /* @__PURE__ */ jsx19(
967
1200
  "span",
968
1201
  {
969
1202
  "aria-hidden": true,
970
- className: cn("inline-block rounded-full", dotSize[size], dotColorClass[variant])
1203
+ className: cn("inline-block rounded-full", dotSize[sz], dotColorClass[v])
971
1204
  }
972
1205
  ),
973
- icon && /* @__PURE__ */ jsx("span", { className: "inline-flex leading-none", children: icon }),
1206
+ icon && /* @__PURE__ */ jsx19("span", { className: "inline-flex leading-none", children: icon }),
974
1207
  children
975
1208
  ] });
976
1209
  });
977
1210
  Badge.displayName = "Badge";
978
- var cardStyles = cva(
1211
+
1212
+ // src/components/Card/Card.tsx
1213
+ import { cva as cva6 } from "class-variance-authority";
1214
+ import { forwardRef as forwardRef19 } from "react";
1215
+ import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
1216
+ var cardStyles = cva6(
979
1217
  "block bg-panel border border-border rounded-base transition-[border-color,transform,box-shadow] duration-(--duration-step)",
980
1218
  {
981
1219
  variants: {
@@ -992,7 +1230,7 @@ var cardStyles = cva(
992
1230
  defaultVariants: { variant: "default", interactive: false }
993
1231
  }
994
1232
  );
995
- var Card = forwardRef(function Card2({
1233
+ var Card = forwardRef19(function Card2({
996
1234
  variant,
997
1235
  interactive,
998
1236
  title,
@@ -1002,57 +1240,96 @@ var Card = forwardRef(function Card2({
1002
1240
  className,
1003
1241
  children,
1004
1242
  onClick,
1243
+ onActivate,
1005
1244
  ...props
1006
1245
  }, ref) {
1007
- const isInteractive = interactive ?? Boolean(onClick);
1008
- return /* @__PURE__ */ jsxs(
1246
+ const wantsInteractive = interactive ?? Boolean(onClick);
1247
+ const hasActions = actions != null;
1248
+ if (wantsInteractive && hasActions && process.env.NODE_ENV !== "production") {
1249
+ console.warn(
1250
+ "[Card] `interactive` was requested but `actions` is also set, which would create a nested-interactive a11y violation. The card will render as a plain <div>. Use <CardLink> for whole-card links, or move the actions outside the card."
1251
+ );
1252
+ }
1253
+ const isInteractive = wantsInteractive && !hasActions;
1254
+ const handleKeyDown = isInteractive ? (e) => {
1255
+ if (e.key !== "Enter" && e.key !== " ") return;
1256
+ if (onActivate) {
1257
+ e.preventDefault();
1258
+ onActivate();
1259
+ } else if (onClick) {
1260
+ e.preventDefault();
1261
+ onClick(e);
1262
+ }
1263
+ } : void 0;
1264
+ return /* @__PURE__ */ jsxs16(
1009
1265
  "div",
1010
1266
  {
1011
1267
  ref,
1012
1268
  onClick,
1013
- onKeyDown: isInteractive && onClick ? (e) => {
1014
- if (e.key === "Enter" || e.key === " ") {
1015
- e.preventDefault();
1016
- onClick(e);
1017
- }
1018
- } : void 0,
1269
+ onKeyDown: handleKeyDown,
1019
1270
  role: isInteractive ? "button" : void 0,
1020
1271
  tabIndex: isInteractive ? 0 : void 0,
1021
- className: cn(cardStyles({ variant, interactive: isInteractive }), "p-[18px]", className),
1272
+ className: cn(cardStyles({ variant, interactive: wantsInteractive }), "p-[18px]", className),
1022
1273
  ...props,
1023
1274
  children: [
1024
- (title || actions) && /* @__PURE__ */ jsxs("div", { className: cn("flex items-start gap-3", (description || children) && "mb-[10px]"), children: [
1025
- title && /* @__PURE__ */ jsx("div", { className: "flex-1 text-[14px] font-medium", children: title }),
1026
- actions && /* @__PURE__ */ jsx("div", { className: "flex gap-1", children: actions })
1275
+ (title || actions) && /* @__PURE__ */ jsxs16("div", { className: cn("flex items-start gap-3", (description || children) && "mb-[10px]"), children: [
1276
+ title && /* @__PURE__ */ jsx20("div", { className: "flex-1 text-[14px] font-medium", children: title }),
1277
+ actions && /* @__PURE__ */ jsx20("div", { className: "flex gap-1", children: actions })
1027
1278
  ] }),
1028
- description && /* @__PURE__ */ jsx("div", { className: cn("text-text-muted text-[12px] leading-[1.55]", children && "mb-[14px]"), children: description }),
1279
+ description && /* @__PURE__ */ jsx20("div", { className: cn("text-text-muted text-[12px] leading-[1.55]", children && "mb-[14px]"), children: description }),
1029
1280
  children,
1030
- footer && /* @__PURE__ */ jsx("div", { className: "border-border text-text-dim mt-[14px] border-t pt-3 text-[11px]", children: footer })
1281
+ footer && /* @__PURE__ */ jsx20("div", { className: "border-border text-text-dim mt-[14px] border-t pt-3 text-[11px]", children: footer })
1031
1282
  ]
1032
1283
  }
1033
1284
  );
1034
1285
  });
1035
1286
  Card.displayName = "Card";
1287
+ var CardLink = forwardRef19(function CardLink2({ variant, title, description, footer, className, children, href, ...props }, ref) {
1288
+ return /* @__PURE__ */ jsxs16(
1289
+ "a",
1290
+ {
1291
+ ref,
1292
+ href,
1293
+ className: cn(
1294
+ cardStyles({ variant, interactive: true }),
1295
+ "focus-visible:ring-accent-dim p-[18px] no-underline outline-none focus-visible:ring-[3px]",
1296
+ className
1297
+ ),
1298
+ ...props,
1299
+ children: [
1300
+ title && /* @__PURE__ */ jsx20("div", { className: cn("flex items-start", (description || children) && "mb-[10px]"), children: /* @__PURE__ */ jsx20("div", { className: "flex-1 text-[14px] font-medium", children: title }) }),
1301
+ description && /* @__PURE__ */ jsx20("div", { className: cn("text-text-muted text-[12px] leading-[1.55]", children && "mb-[14px]"), children: description }),
1302
+ children,
1303
+ footer && /* @__PURE__ */ jsx20("div", { className: "border-border text-text-dim mt-[14px] border-t pt-3 text-[11px]", children: footer })
1304
+ ]
1305
+ }
1306
+ );
1307
+ });
1308
+ CardLink.displayName = "CardLink";
1309
+
1310
+ // src/components/Card/StatCard.tsx
1311
+ import { forwardRef as forwardRef20 } from "react";
1312
+ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
1036
1313
  var trendClasses = {
1037
1314
  up: "text-ok",
1038
1315
  down: "text-err",
1039
1316
  flat: "text-text-dim"
1040
1317
  };
1041
1318
  var trendArrows = { up: "\u2191", down: "\u2193", flat: "\u2192" };
1042
- var StatCard = forwardRef(function StatCard2({ label, value, delta, trend = "flat", icon, className, ...props }, ref) {
1043
- return /* @__PURE__ */ jsxs(
1319
+ var StatCard = forwardRef20(function StatCard2({ label, value, delta, trend = "flat", icon, className, ...props }, ref) {
1320
+ return /* @__PURE__ */ jsxs17(
1044
1321
  "div",
1045
1322
  {
1046
1323
  ref,
1047
1324
  className: cn("bg-panel border-border rounded-base block border p-[18px]", className),
1048
1325
  ...props,
1049
1326
  children: [
1050
- /* @__PURE__ */ jsxs("div", { className: "mb-[10px] flex items-center justify-between", children: [
1051
- /* @__PURE__ */ jsx("div", { className: "text-text-dim font-mono text-[10px] tracking-wide uppercase", children: label }),
1052
- icon && /* @__PURE__ */ jsx("div", { className: "text-text-dim text-[14px]", children: icon })
1327
+ /* @__PURE__ */ jsxs17("div", { className: "mb-[10px] flex items-center justify-between", children: [
1328
+ /* @__PURE__ */ jsx21("div", { className: "text-text-dim font-mono text-[10px] tracking-wide uppercase", children: label }),
1329
+ icon && /* @__PURE__ */ jsx21("div", { className: "text-text-dim text-[14px]", children: icon })
1053
1330
  ] }),
1054
- /* @__PURE__ */ jsx("div", { className: "text-text font-mono text-[26px] leading-none font-medium tracking-tight", children: value }),
1055
- delta !== void 0 && /* @__PURE__ */ jsxs("div", { className: cn("mt-[6px] font-mono text-[11px]", trendClasses[trend]), children: [
1331
+ /* @__PURE__ */ jsx21("div", { className: "text-text font-mono text-[26px] leading-none font-medium tracking-tight", children: value }),
1332
+ delta !== void 0 && /* @__PURE__ */ jsxs17("div", { className: cn("mt-[6px] font-mono text-[11px]", trendClasses[trend]), children: [
1056
1333
  trendArrows[trend],
1057
1334
  " ",
1058
1335
  delta
@@ -1062,8 +1339,12 @@ var StatCard = forwardRef(function StatCard2({ label, value, delta, trend = "fla
1062
1339
  );
1063
1340
  });
1064
1341
  StatCard.displayName = "StatCard";
1065
- var Chip = forwardRef(function Chip2({ icon, removable, onRemove, className, children, ...props }, ref) {
1066
- return /* @__PURE__ */ jsxs(
1342
+
1343
+ // src/components/Chip/Chip.tsx
1344
+ import { forwardRef as forwardRef21 } from "react";
1345
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
1346
+ var Chip = forwardRef21(function Chip2({ icon, onRemove, className, children, ...props }, ref) {
1347
+ return /* @__PURE__ */ jsxs18(
1067
1348
  "span",
1068
1349
  {
1069
1350
  ref,
@@ -1074,9 +1355,9 @@ var Chip = forwardRef(function Chip2({ icon, removable, onRemove, className, chi
1074
1355
  ),
1075
1356
  ...props,
1076
1357
  children: [
1077
- icon && /* @__PURE__ */ jsx("span", { className: "text-text-dim inline-flex text-[10px]", children: icon }),
1358
+ icon && /* @__PURE__ */ jsx22("span", { className: "text-text-dim inline-flex text-[10px]", children: icon }),
1078
1359
  children,
1079
- removable && /* @__PURE__ */ jsx(
1360
+ onRemove && /* @__PURE__ */ jsx22(
1080
1361
  "button",
1081
1362
  {
1082
1363
  type: "button",
@@ -1091,8 +1372,12 @@ var Chip = forwardRef(function Chip2({ icon, removable, onRemove, className, chi
1091
1372
  );
1092
1373
  });
1093
1374
  Chip.displayName = "Chip";
1094
- var Kbd = forwardRef(function Kbd2({ className, children, ...props }, ref) {
1095
- return /* @__PURE__ */ jsx(
1375
+
1376
+ // src/components/Kbd/Kbd.tsx
1377
+ import { forwardRef as forwardRef22 } from "react";
1378
+ import { jsx as jsx23 } from "react/jsx-runtime";
1379
+ var Kbd = forwardRef22(function Kbd2({ className, children, ...props }, ref) {
1380
+ return /* @__PURE__ */ jsx23(
1096
1381
  "kbd",
1097
1382
  {
1098
1383
  ref,
@@ -1108,7 +1393,12 @@ var Kbd = forwardRef(function Kbd2({ className, children, ...props }, ref) {
1108
1393
  );
1109
1394
  });
1110
1395
  Kbd.displayName = "Kbd";
1111
- var skeletonStyles = cva("block bg-panel-2 animate-[ship-skeleton_1.4s_infinite]", {
1396
+
1397
+ // src/components/Skeleton/Skeleton.tsx
1398
+ import { cva as cva7 } from "class-variance-authority";
1399
+ import { forwardRef as forwardRef23 } from "react";
1400
+ import { jsx as jsx24 } from "react/jsx-runtime";
1401
+ var skeletonStyles = cva7("block bg-panel-2 animate-[ship-skeleton_1.4s_infinite]", {
1112
1402
  variants: {
1113
1403
  shape: {
1114
1404
  line: "rounded-xs",
@@ -1119,16 +1409,15 @@ var skeletonStyles = cva("block bg-panel-2 animate-[ship-skeleton_1.4s_infinite]
1119
1409
  defaultVariants: { shape: "line" }
1120
1410
  });
1121
1411
  var defaultHeight = { line: 14, block: 80, circle: 40 };
1122
- var Skeleton = forwardRef(function Skeleton2({ shape = "line", width = "100%", height, className, style, ...props }, ref) {
1412
+ var Skeleton = forwardRef23(function Skeleton2({ shape = "line", width = "100%", height, standalone = false, className, style, ...props }, ref) {
1123
1413
  const h = height ?? defaultHeight[shape];
1124
1414
  const w = shape === "circle" ? h : width;
1125
- return /* @__PURE__ */ jsx(
1415
+ const a11yProps = standalone ? { role: "status", "aria-busy": true, "aria-label": "Loading" } : { "aria-hidden": true };
1416
+ return /* @__PURE__ */ jsx24(
1126
1417
  "div",
1127
1418
  {
1128
1419
  ref,
1129
- role: "status",
1130
- "aria-busy": "true",
1131
- "aria-label": "Loading",
1420
+ ...a11yProps,
1132
1421
  className: cn(skeletonStyles({ shape }), className),
1133
1422
  style: { width: w, height: h, ...style },
1134
1423
  ...props
@@ -1136,52 +1425,30 @@ var Skeleton = forwardRef(function Skeleton2({ shape = "line", width = "100%", h
1136
1425
  );
1137
1426
  });
1138
1427
  Skeleton.displayName = "Skeleton";
1139
- var stateColor = {
1140
- ok: "bg-ok",
1141
- warn: "bg-warn",
1142
- err: "bg-err",
1143
- off: "bg-text-dim",
1144
- sync: "bg-accent",
1145
- accent: "bg-accent"
1146
- };
1147
- var stateText = {
1148
- ok: "text-ok",
1149
- warn: "text-warn",
1150
- err: "text-err",
1151
- off: "text-text-dim",
1152
- sync: "text-accent",
1153
- accent: "text-accent"
1154
- };
1155
- var StatusDot = forwardRef(function StatusDot2({ state = "ok", label, pulse, size = 8, className, ...props }, ref) {
1156
- return /* @__PURE__ */ jsxs(
1157
- "span",
1428
+ var SkeletonGroup = forwardRef23(function SkeletonGroup2({ label = "Loading", loading = true, className, children, ...props }, ref) {
1429
+ if (!loading) {
1430
+ return /* @__PURE__ */ jsx24("div", { ref, className, ...props, children });
1431
+ }
1432
+ return /* @__PURE__ */ jsx24(
1433
+ "div",
1158
1434
  {
1159
1435
  ref,
1160
- role: label ? "status" : "img",
1161
- "aria-label": !label && typeof state === "string" ? state : void 0,
1162
- className: cn("inline-flex items-center gap-[6px]", className),
1436
+ role: "status",
1437
+ "aria-busy": "true",
1438
+ "aria-label": label,
1439
+ className,
1163
1440
  ...props,
1164
- children: [
1165
- /* @__PURE__ */ jsx(
1166
- "span",
1167
- {
1168
- className: cn(
1169
- "inline-block rounded-full",
1170
- stateColor[state],
1171
- pulse && "animate-[ship-pulse-ring_1.6s_infinite]",
1172
- stateText[state]
1173
- ),
1174
- style: { width: size, height: size }
1175
- }
1176
- ),
1177
- label && /* @__PURE__ */ jsx("span", { className: "text-text-muted text-[12px]", children: label })
1178
- ]
1441
+ children
1179
1442
  }
1180
1443
  );
1181
1444
  });
1182
- StatusDot.displayName = "StatusDot";
1183
- var Tag = forwardRef(function Tag2({ onRemove, icon, size = 22, className, children, ...props }, ref) {
1184
- return /* @__PURE__ */ jsxs(
1445
+ SkeletonGroup.displayName = "SkeletonGroup";
1446
+
1447
+ // src/components/Tag/Tag.tsx
1448
+ import { forwardRef as forwardRef24 } from "react";
1449
+ import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
1450
+ var Tag = forwardRef24(function Tag2({ onRemove, icon, size = 22, className, children, ...props }, ref) {
1451
+ return /* @__PURE__ */ jsxs19(
1185
1452
  "span",
1186
1453
  {
1187
1454
  ref,
@@ -1193,9 +1460,9 @@ var Tag = forwardRef(function Tag2({ onRemove, icon, size = 22, className, child
1193
1460
  style: { height: size },
1194
1461
  ...props,
1195
1462
  children: [
1196
- icon && /* @__PURE__ */ jsx("span", { className: "text-text-dim inline-flex", children: icon }),
1463
+ icon && /* @__PURE__ */ jsx25("span", { className: "text-text-dim inline-flex", children: icon }),
1197
1464
  children,
1198
- onRemove && /* @__PURE__ */ jsx(
1465
+ onRemove && /* @__PURE__ */ jsx25(
1199
1466
  "button",
1200
1467
  {
1201
1468
  type: "button",
@@ -1210,17 +1477,22 @@ var Tag = forwardRef(function Tag2({ onRemove, icon, size = 22, className, child
1210
1477
  );
1211
1478
  });
1212
1479
  Tag.displayName = "Tag";
1480
+
1481
+ // src/components/ContextMenu/ContextMenu.tsx
1482
+ import * as RadixContext from "@radix-ui/react-context-menu";
1483
+ import { forwardRef as forwardRef25 } from "react";
1484
+ import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
1213
1485
  var ContextMenuRoot = RadixContext.Root;
1214
1486
  var ContextMenuTrigger = RadixContext.Trigger;
1215
1487
  var ContextMenuPortal = RadixContext.Portal;
1216
- var ContextMenuContent = forwardRef(
1488
+ var ContextMenuContent = forwardRef25(
1217
1489
  function ContextMenuContent2({ className, ...props }, ref) {
1218
- return /* @__PURE__ */ jsx(RadixContext.Portal, { children: /* @__PURE__ */ jsx(
1490
+ return /* @__PURE__ */ jsx26(RadixContext.Portal, { children: /* @__PURE__ */ jsx26(
1219
1491
  RadixContext.Content,
1220
1492
  {
1221
1493
  ref,
1222
1494
  className: cn(
1223
- "bg-panel border-border-strong z-40 min-w-[180px] rounded-md border p-1 shadow-lg outline-none",
1495
+ "bg-panel border-border-strong z-popover min-w-[180px] rounded-md border p-1 shadow-lg outline-none",
1224
1496
  "data-[state=open]:animate-[ship-pop-in_140ms_var(--easing-out)]",
1225
1497
  className
1226
1498
  ),
@@ -1235,26 +1507,26 @@ var itemBase = cn(
1235
1507
  "data-[highlighted]:bg-panel-2",
1236
1508
  "data-[disabled]:opacity-40 data-[disabled]:cursor-not-allowed"
1237
1509
  );
1238
- var ContextMenuItem = forwardRef(
1510
+ var ContextMenuItem = forwardRef25(
1239
1511
  function ContextMenuItem2({ icon, trailing, destructive, className, children, ...props }, ref) {
1240
- return /* @__PURE__ */ jsxs(
1512
+ return /* @__PURE__ */ jsxs20(
1241
1513
  RadixContext.Item,
1242
1514
  {
1243
1515
  ref,
1244
1516
  className: cn(itemBase, destructive ? "text-err" : "text-text", className),
1245
1517
  ...props,
1246
1518
  children: [
1247
- icon && /* @__PURE__ */ jsx("span", { className: "w-[14px] text-[12px] opacity-70", children: icon }),
1248
- /* @__PURE__ */ jsx("span", { className: "flex-1", children }),
1249
- trailing && /* @__PURE__ */ jsx("span", { className: "text-text-dim font-mono text-[10px]", children: trailing })
1519
+ icon && /* @__PURE__ */ jsx26("span", { className: "w-[14px] text-[12px] opacity-70", children: icon }),
1520
+ /* @__PURE__ */ jsx26("span", { className: "flex-1", children }),
1521
+ trailing && /* @__PURE__ */ jsx26("span", { className: "text-text-dim font-mono text-[10px]", children: trailing })
1250
1522
  ]
1251
1523
  }
1252
1524
  );
1253
1525
  }
1254
1526
  );
1255
1527
  ContextMenuItem.displayName = "ContextMenuItem";
1256
- var ContextMenuSeparator = forwardRef(function ContextMenuSeparator2({ className, ...props }, ref) {
1257
- return /* @__PURE__ */ jsx(
1528
+ var ContextMenuSeparator = forwardRef25(function ContextMenuSeparator2({ className, ...props }, ref) {
1529
+ return /* @__PURE__ */ jsx26(
1258
1530
  RadixContext.Separator,
1259
1531
  {
1260
1532
  ref,
@@ -1265,18 +1537,23 @@ var ContextMenuSeparator = forwardRef(function ContextMenuSeparator2({ className
1265
1537
  });
1266
1538
  ContextMenuSeparator.displayName = "ContextMenuSeparator";
1267
1539
  var ContextMenu = RadixContext.Root;
1540
+
1541
+ // src/components/Dialog/Dialog.tsx
1542
+ import * as RadixDialog from "@radix-ui/react-dialog";
1543
+ import { forwardRef as forwardRef26 } from "react";
1544
+ import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
1268
1545
  var DialogRoot = RadixDialog.Root;
1269
1546
  var DialogTrigger = RadixDialog.Trigger;
1270
1547
  var DialogClose = RadixDialog.Close;
1271
1548
  var DialogPortal = RadixDialog.Portal;
1272
- var DialogOverlay = forwardRef(
1549
+ var DialogOverlay = forwardRef26(
1273
1550
  function DialogOverlay2({ className, ...props }, ref) {
1274
- return /* @__PURE__ */ jsx(
1551
+ return /* @__PURE__ */ jsx27(
1275
1552
  RadixDialog.Overlay,
1276
1553
  {
1277
1554
  ref,
1278
1555
  className: cn(
1279
- "fixed inset-0 z-50 bg-black/55 backdrop-blur-[4px]",
1556
+ "z-overlay fixed inset-0 bg-black/55 backdrop-blur-[4px]",
1280
1557
  "data-[state=open]:animate-[ship-fade-in_150ms_ease]",
1281
1558
  className
1282
1559
  ),
@@ -1286,15 +1563,15 @@ var DialogOverlay = forwardRef(
1286
1563
  }
1287
1564
  );
1288
1565
  DialogOverlay.displayName = "DialogOverlay";
1289
- var DialogContent = forwardRef(function DialogContent2({ className, width = 460, style, children, ...props }, ref) {
1290
- return /* @__PURE__ */ jsxs(DialogPortal, { children: [
1291
- /* @__PURE__ */ jsx(DialogOverlay, {}),
1292
- /* @__PURE__ */ jsx(
1566
+ var DialogContent = forwardRef26(function DialogContent2({ className, width = 460, style, children, ...props }, ref) {
1567
+ return /* @__PURE__ */ jsxs21(DialogPortal, { children: [
1568
+ /* @__PURE__ */ jsx27(DialogOverlay, {}),
1569
+ /* @__PURE__ */ jsx27(
1293
1570
  RadixDialog.Content,
1294
1571
  {
1295
1572
  ref,
1296
1573
  className: cn(
1297
- "fixed top-1/2 left-1/2 z-[51] w-[calc(100%-40px)] -translate-x-1/2 -translate-y-1/2 p-6",
1574
+ "z-modal fixed top-1/2 left-1/2 w-[calc(100%-40px)] -translate-x-1/2 -translate-y-1/2 p-6",
1298
1575
  "bg-panel border-border-strong rounded-lg border shadow-lg",
1299
1576
  "data-[state=open]:animate-[ship-dialog-in_180ms_var(--easing-out)]",
1300
1577
  "outline-none",
@@ -1309,27 +1586,32 @@ var DialogContent = forwardRef(function DialogContent2({ className, width = 460,
1309
1586
  });
1310
1587
  DialogContent.displayName = "DialogContent";
1311
1588
  function Dialog({ title, description, footer, width, children, ...rootProps }) {
1312
- return /* @__PURE__ */ jsx(DialogRoot, { ...rootProps, children: /* @__PURE__ */ jsxs(DialogContent, { width, children: [
1313
- title && /* @__PURE__ */ jsx(
1589
+ return /* @__PURE__ */ jsx27(DialogRoot, { ...rootProps, children: /* @__PURE__ */ jsxs21(DialogContent, { width, children: [
1590
+ title && /* @__PURE__ */ jsx27(
1314
1591
  RadixDialog.Title,
1315
1592
  {
1316
1593
  className: cn("text-[16px] font-medium", description ? "mb-[6px]" : "mb-4"),
1317
1594
  children: title
1318
1595
  }
1319
1596
  ),
1320
- description && /* @__PURE__ */ jsx(RadixDialog.Description, { className: "text-text-muted mb-[18px] text-[13px] leading-[1.55]", children: description }),
1597
+ description && /* @__PURE__ */ jsx27(RadixDialog.Description, { className: "text-text-muted mb-[18px] text-[13px] leading-[1.55]", children: description }),
1321
1598
  children,
1322
- footer && /* @__PURE__ */ jsx("div", { className: "mt-5 flex justify-end gap-2", children: footer })
1599
+ footer && /* @__PURE__ */ jsx27("div", { className: "mt-5 flex justify-end gap-2", children: footer })
1323
1600
  ] }) });
1324
1601
  }
1602
+
1603
+ // src/components/Dialog/Drawer.tsx
1604
+ import * as RadixDialog2 from "@radix-ui/react-dialog";
1605
+ import { forwardRef as forwardRef27 } from "react";
1606
+ import { jsx as jsx28, jsxs as jsxs22 } from "react/jsx-runtime";
1325
1607
  var sideClasses = {
1326
1608
  left: "left-0 border-r border-border-strong data-[state=open]:animate-[ship-slide-in-left_220ms_var(--easing-out)]",
1327
1609
  right: "right-0 border-l border-border-strong data-[state=open]:animate-[ship-slide-in-right_220ms_var(--easing-out)]"
1328
1610
  };
1329
- var DrawerHeader = ({ title, onClose }) => /* @__PURE__ */ jsxs("div", { className: "border-border flex items-center justify-between border-b p-[16px] px-5", children: [
1330
- /* @__PURE__ */ jsx("span", { className: "text-[14px] font-medium", children: title }),
1331
- /* @__PURE__ */ jsx(
1332
- RadixDialog.Close,
1611
+ var DrawerHeader = ({ title, onClose }) => /* @__PURE__ */ jsxs22("div", { className: "border-border flex items-center justify-between border-b p-[16px] px-5", children: [
1612
+ /* @__PURE__ */ jsx28(RadixDialog2.Title, { className: "text-[14px] font-medium", children: title }),
1613
+ /* @__PURE__ */ jsx28(
1614
+ RadixDialog2.Close,
1333
1615
  {
1334
1616
  onClick: onClose,
1335
1617
  "aria-label": "Close",
@@ -1338,43 +1620,49 @@ var DrawerHeader = ({ title, onClose }) => /* @__PURE__ */ jsxs("div", { classNa
1338
1620
  }
1339
1621
  )
1340
1622
  ] });
1341
- var Drawer = forwardRef(function Drawer2({ side = "right", title, width = 420, children, ...rootProps }, ref) {
1342
- return /* @__PURE__ */ jsx(DialogRoot, { ...rootProps, children: /* @__PURE__ */ jsxs(DialogPortal, { children: [
1343
- /* @__PURE__ */ jsx(DialogOverlay, {}),
1344
- /* @__PURE__ */ jsxs(
1345
- RadixDialog.Content,
1623
+ var Drawer = forwardRef27(function Drawer2({ side = "right", title, width = 420, children, ...rootProps }, ref) {
1624
+ return /* @__PURE__ */ jsx28(DialogRoot, { ...rootProps, children: /* @__PURE__ */ jsxs22(DialogPortal, { children: [
1625
+ /* @__PURE__ */ jsx28(DialogOverlay, {}),
1626
+ /* @__PURE__ */ jsxs22(
1627
+ RadixDialog2.Content,
1346
1628
  {
1347
1629
  ref,
1630
+ "aria-describedby": void 0,
1348
1631
  className: cn(
1349
- "bg-panel fixed top-0 bottom-0 z-[51] flex flex-col shadow-lg outline-none",
1632
+ "bg-panel z-modal fixed top-0 bottom-0 flex flex-col shadow-lg outline-none",
1350
1633
  sideClasses[side]
1351
1634
  ),
1352
1635
  style: { width },
1353
1636
  children: [
1354
- title && /* @__PURE__ */ jsx(DrawerHeader, { title }),
1355
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-auto p-5", children })
1637
+ title ? /* @__PURE__ */ jsx28(DrawerHeader, { title }) : /* @__PURE__ */ jsx28(RadixDialog2.Title, { className: "sr-only", children: "Drawer" }),
1638
+ /* @__PURE__ */ jsx28("div", { className: "flex-1 overflow-auto p-5", children })
1356
1639
  ]
1357
1640
  }
1358
1641
  )
1359
1642
  ] }) });
1360
1643
  });
1361
1644
  Drawer.displayName = "Drawer";
1362
- var Sheet = forwardRef(function Sheet2({ title, width = "min(640px, 90vw)", children, ...rootProps }, ref) {
1363
- return /* @__PURE__ */ jsx(DialogRoot, { ...rootProps, children: /* @__PURE__ */ jsxs(DialogPortal, { children: [
1364
- /* @__PURE__ */ jsx(DialogOverlay, {}),
1365
- /* @__PURE__ */ jsxs(
1366
- RadixDialog.Content,
1645
+
1646
+ // src/components/Dialog/Sheet.tsx
1647
+ import * as RadixDialog3 from "@radix-ui/react-dialog";
1648
+ import { forwardRef as forwardRef28 } from "react";
1649
+ import { jsx as jsx29, jsxs as jsxs23 } from "react/jsx-runtime";
1650
+ var Sheet = forwardRef28(function Sheet2({ title, width = "min(640px, 90vw)", children, ...rootProps }, ref) {
1651
+ return /* @__PURE__ */ jsx29(DialogRoot, { ...rootProps, children: /* @__PURE__ */ jsxs23(DialogPortal, { children: [
1652
+ /* @__PURE__ */ jsx29(DialogOverlay, {}),
1653
+ /* @__PURE__ */ jsxs23(
1654
+ RadixDialog3.Content,
1367
1655
  {
1368
1656
  ref,
1657
+ "aria-describedby": void 0,
1369
1658
  className: cn(
1370
- "fixed bottom-0 left-1/2 z-[51] -translate-x-1/2 p-5",
1659
+ "z-modal fixed bottom-0 left-1/2 -translate-x-1/2 p-5",
1371
1660
  "bg-panel border-border-strong rounded-tl-lg rounded-tr-lg border-t shadow-lg outline-none",
1372
1661
  "data-[state=open]:animate-[ship-slide-in-bottom_220ms_var(--easing-out)]"
1373
1662
  ),
1374
1663
  style: { width },
1375
1664
  children: [
1376
- /* @__PURE__ */ jsx("div", { className: "bg-border mx-auto mb-[14px] h-1 w-9 rounded-full", "aria-hidden": true }),
1377
- title && /* @__PURE__ */ jsx(RadixDialog.Title, { className: "mb-1 text-[15px] font-medium", children: title }),
1665
+ title ? /* @__PURE__ */ jsx29(RadixDialog3.Title, { className: "mb-1 text-[15px] font-medium", children: title }) : /* @__PURE__ */ jsx29(RadixDialog3.Title, { className: "sr-only", children: "Sheet" }),
1378
1666
  children
1379
1667
  ]
1380
1668
  }
@@ -1382,64 +1670,74 @@ var Sheet = forwardRef(function Sheet2({ title, width = "min(640px, 90vw)", chil
1382
1670
  ] }) });
1383
1671
  });
1384
1672
  Sheet.displayName = "Sheet";
1673
+
1674
+ // src/components/Dialog/AlertDialog.tsx
1675
+ import * as RadixAlert from "@radix-ui/react-alert-dialog";
1676
+ import { forwardRef as forwardRef29 } from "react";
1677
+ import { jsx as jsx30, jsxs as jsxs24 } from "react/jsx-runtime";
1385
1678
  var AlertDialogRoot = RadixAlert.Root;
1386
1679
  var AlertDialogTrigger = RadixAlert.Trigger;
1387
1680
  var AlertDialogAction = RadixAlert.Action;
1388
1681
  var AlertDialogCancel = RadixAlert.Cancel;
1389
- var AlertDialog = forwardRef(function AlertDialog2({ title, description, footer, width = 460, children, ...rootProps }, ref) {
1390
- return /* @__PURE__ */ jsx(AlertDialogRoot, { ...rootProps, children: /* @__PURE__ */ jsxs(RadixAlert.Portal, { children: [
1391
- /* @__PURE__ */ jsx(
1682
+ var AlertDialog = forwardRef29(function AlertDialog2({ title, description, footer, width = 460, children, ...rootProps }, ref) {
1683
+ return /* @__PURE__ */ jsx30(AlertDialogRoot, { ...rootProps, children: /* @__PURE__ */ jsxs24(RadixAlert.Portal, { children: [
1684
+ /* @__PURE__ */ jsx30(
1392
1685
  RadixAlert.Overlay,
1393
1686
  {
1394
1687
  className: cn(
1395
- "fixed inset-0 z-50 bg-black/55 backdrop-blur-[4px]",
1688
+ "z-overlay fixed inset-0 bg-black/55 backdrop-blur-[4px]",
1396
1689
  "data-[state=open]:animate-[ship-fade-in_150ms_ease]"
1397
1690
  )
1398
1691
  }
1399
1692
  ),
1400
- /* @__PURE__ */ jsxs(
1693
+ /* @__PURE__ */ jsxs24(
1401
1694
  RadixAlert.Content,
1402
1695
  {
1403
1696
  ref,
1404
1697
  style: { maxWidth: width },
1405
1698
  className: cn(
1406
- "fixed top-1/2 left-1/2 z-[51] w-[calc(100%-40px)] -translate-x-1/2 -translate-y-1/2 p-6",
1699
+ "z-modal fixed top-1/2 left-1/2 w-[calc(100%-40px)] -translate-x-1/2 -translate-y-1/2 p-6",
1407
1700
  "bg-panel border-border-strong rounded-lg border shadow-lg outline-none",
1408
1701
  "data-[state=open]:animate-[ship-dialog-in_180ms_var(--easing-out)]"
1409
1702
  ),
1410
1703
  children: [
1411
- /* @__PURE__ */ jsx(
1704
+ /* @__PURE__ */ jsx30(
1412
1705
  RadixAlert.Title,
1413
1706
  {
1414
1707
  className: cn("text-[16px] font-medium", description ? "mb-[6px]" : "mb-4"),
1415
1708
  children: title
1416
1709
  }
1417
1710
  ),
1418
- description && /* @__PURE__ */ jsx(RadixAlert.Description, { className: "text-text-muted mb-[18px] text-[13px] leading-[1.55]", children: description }),
1711
+ description && /* @__PURE__ */ jsx30(RadixAlert.Description, { className: "text-text-muted mb-[18px] text-[13px] leading-[1.55]", children: description }),
1419
1712
  children,
1420
- footer && /* @__PURE__ */ jsx("div", { className: "mt-5 flex justify-end gap-2", children: footer })
1713
+ footer && /* @__PURE__ */ jsx30("div", { className: "mt-5 flex justify-end gap-2", children: footer })
1421
1714
  ]
1422
1715
  }
1423
1716
  )
1424
1717
  ] }) });
1425
1718
  });
1426
1719
  AlertDialog.displayName = "AlertDialog";
1720
+
1721
+ // src/components/DropdownMenu/DropdownMenu.tsx
1722
+ import * as RadixMenu from "@radix-ui/react-dropdown-menu";
1723
+ import { forwardRef as forwardRef30 } from "react";
1724
+ import { jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
1427
1725
  var DropdownMenuRoot = RadixMenu.Root;
1428
1726
  var DropdownMenuTrigger = RadixMenu.Trigger;
1429
1727
  var DropdownMenuPortal = RadixMenu.Portal;
1430
1728
  var DropdownMenuGroup = RadixMenu.Group;
1431
1729
  var DropdownMenuLabel = RadixMenu.Label;
1432
1730
  var DropdownMenuRadioGroup = RadixMenu.RadioGroup;
1433
- var DropdownMenuContent = forwardRef(
1731
+ var DropdownMenuContent = forwardRef30(
1434
1732
  function DropdownMenuContent2({ className, sideOffset = 6, align = "start", ...props }, ref) {
1435
- return /* @__PURE__ */ jsx(RadixMenu.Portal, { children: /* @__PURE__ */ jsx(
1733
+ return /* @__PURE__ */ jsx31(RadixMenu.Portal, { children: /* @__PURE__ */ jsx31(
1436
1734
  RadixMenu.Content,
1437
1735
  {
1438
1736
  ref,
1439
1737
  sideOffset,
1440
1738
  align,
1441
1739
  className: cn(
1442
- "bg-panel border-border-strong z-40 min-w-[180px] rounded-md border p-1 shadow-lg outline-none",
1740
+ "bg-panel border-border-strong z-popover min-w-[180px] rounded-md border p-1 shadow-lg outline-none",
1443
1741
  "data-[state=open]:animate-[ship-pop-in_140ms_var(--easing-out)]",
1444
1742
  className
1445
1743
  ),
@@ -1454,32 +1752,32 @@ var itemBase2 = cn(
1454
1752
  "data-[highlighted]:bg-panel-2",
1455
1753
  "data-[disabled]:opacity-40 data-[disabled]:cursor-not-allowed"
1456
1754
  );
1457
- var MenuItem = forwardRef(function MenuItem2({ icon, trailing, destructive, className, children, ...props }, ref) {
1458
- return /* @__PURE__ */ jsxs(
1755
+ var MenuItem = forwardRef30(function MenuItem2({ icon, trailing, destructive, className, children, ...props }, ref) {
1756
+ return /* @__PURE__ */ jsxs25(
1459
1757
  RadixMenu.Item,
1460
1758
  {
1461
1759
  ref,
1462
1760
  className: cn(itemBase2, destructive ? "text-err" : "text-text", className),
1463
1761
  ...props,
1464
1762
  children: [
1465
- icon && /* @__PURE__ */ jsx("span", { className: "w-[14px] text-[12px] opacity-70", children: icon }),
1466
- /* @__PURE__ */ jsx("span", { className: "flex-1", children }),
1467
- trailing && /* @__PURE__ */ jsx("span", { className: "text-text-dim font-mono text-[10px]", children: trailing })
1763
+ icon && /* @__PURE__ */ jsx31("span", { className: "w-[14px] text-[12px] opacity-70", children: icon }),
1764
+ /* @__PURE__ */ jsx31("span", { className: "flex-1", children }),
1765
+ trailing && /* @__PURE__ */ jsx31("span", { className: "text-text-dim font-mono text-[10px]", children: trailing })
1468
1766
  ]
1469
1767
  }
1470
1768
  );
1471
1769
  });
1472
1770
  MenuItem.displayName = "MenuItem";
1473
- var MenuCheckboxItem = forwardRef(
1771
+ var MenuCheckboxItem = forwardRef30(
1474
1772
  function MenuCheckboxItem2({ className, children, ...props }, ref) {
1475
- return /* @__PURE__ */ jsxs(
1773
+ return /* @__PURE__ */ jsxs25(
1476
1774
  RadixMenu.CheckboxItem,
1477
1775
  {
1478
1776
  ref,
1479
1777
  className: cn(itemBase2, "text-text relative pl-[26px]", className),
1480
1778
  ...props,
1481
1779
  children: [
1482
- /* @__PURE__ */ jsx(RadixMenu.ItemIndicator, { className: "text-accent absolute top-1/2 left-2 -translate-y-1/2 text-[10px]", children: "\u2713" }),
1780
+ /* @__PURE__ */ jsx31(RadixMenu.ItemIndicator, { className: "text-accent absolute top-1/2 left-2 -translate-y-1/2 text-[10px]", children: "\u2713" }),
1483
1781
  children
1484
1782
  ]
1485
1783
  }
@@ -1487,9 +1785,9 @@ var MenuCheckboxItem = forwardRef(
1487
1785
  }
1488
1786
  );
1489
1787
  MenuCheckboxItem.displayName = "MenuCheckboxItem";
1490
- var MenuSeparator = forwardRef(
1788
+ var MenuSeparator = forwardRef30(
1491
1789
  function MenuSeparator2({ className, ...props }, ref) {
1492
- return /* @__PURE__ */ jsx(
1790
+ return /* @__PURE__ */ jsx31(
1493
1791
  RadixMenu.Separator,
1494
1792
  {
1495
1793
  ref,
@@ -1501,18 +1799,23 @@ var MenuSeparator = forwardRef(
1501
1799
  );
1502
1800
  MenuSeparator.displayName = "MenuSeparator";
1503
1801
  var DropdownMenu = RadixMenu.Root;
1802
+
1803
+ // src/components/HoverCard/HoverCard.tsx
1804
+ import * as RadixHoverCard from "@radix-ui/react-hover-card";
1805
+ import { forwardRef as forwardRef31 } from "react";
1806
+ import { jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
1504
1807
  var HoverCardRoot = RadixHoverCard.Root;
1505
1808
  var HoverCardTrigger = RadixHoverCard.Trigger;
1506
1809
  var HoverCardPortal = RadixHoverCard.Portal;
1507
- var HoverCardContent = forwardRef(
1810
+ var HoverCardContent = forwardRef31(
1508
1811
  function HoverCardContent2({ className, sideOffset = 4, ...props }, ref) {
1509
- return /* @__PURE__ */ jsx(RadixHoverCard.Portal, { children: /* @__PURE__ */ jsx(
1812
+ return /* @__PURE__ */ jsx32(RadixHoverCard.Portal, { children: /* @__PURE__ */ jsx32(
1510
1813
  RadixHoverCard.Content,
1511
1814
  {
1512
1815
  ref,
1513
1816
  sideOffset,
1514
1817
  className: cn(
1515
- "rounded-base bg-panel border-border-strong z-40 border p-[14px] shadow-lg outline-none",
1818
+ "rounded-base bg-panel border-border-strong z-popover border p-[14px] shadow-lg outline-none",
1516
1819
  "data-[state=open]:animate-[ship-pop-in_140ms_var(--easing-out)]",
1517
1820
  className
1518
1821
  ),
@@ -1523,27 +1826,32 @@ var HoverCardContent = forwardRef(
1523
1826
  );
1524
1827
  HoverCardContent.displayName = "HoverCardContent";
1525
1828
  function HoverCard({ trigger, content, ...rootProps }) {
1526
- return /* @__PURE__ */ jsxs(RadixHoverCard.Root, { openDelay: 200, closeDelay: 120, ...rootProps, children: [
1527
- /* @__PURE__ */ jsx(RadixHoverCard.Trigger, { asChild: true, children: trigger }),
1528
- /* @__PURE__ */ jsx(HoverCardContent, { children: content })
1829
+ return /* @__PURE__ */ jsxs26(RadixHoverCard.Root, { openDelay: 200, closeDelay: 120, ...rootProps, children: [
1830
+ /* @__PURE__ */ jsx32(RadixHoverCard.Trigger, { asChild: true, children: trigger }),
1831
+ /* @__PURE__ */ jsx32(HoverCardContent, { children: content })
1529
1832
  ] });
1530
1833
  }
1834
+
1835
+ // src/components/Popover/Popover.tsx
1836
+ import * as RadixPopover from "@radix-ui/react-popover";
1837
+ import { forwardRef as forwardRef32 } from "react";
1838
+ import { jsx as jsx33 } from "react/jsx-runtime";
1531
1839
  var PopoverRoot = RadixPopover.Root;
1532
1840
  var PopoverTrigger = RadixPopover.Trigger;
1533
1841
  var PopoverAnchor = RadixPopover.Anchor;
1534
1842
  var PopoverPortal = RadixPopover.Portal;
1535
1843
  var PopoverClose = RadixPopover.Close;
1536
1844
  var PopoverArrow = RadixPopover.Arrow;
1537
- var PopoverContent = forwardRef(
1845
+ var PopoverContent = forwardRef32(
1538
1846
  function PopoverContent2({ className, align = "start", sideOffset = 6, ...props }, ref) {
1539
- return /* @__PURE__ */ jsx(RadixPopover.Portal, { children: /* @__PURE__ */ jsx(
1847
+ return /* @__PURE__ */ jsx33(RadixPopover.Portal, { children: /* @__PURE__ */ jsx33(
1540
1848
  RadixPopover.Content,
1541
1849
  {
1542
1850
  ref,
1543
1851
  align,
1544
1852
  sideOffset,
1545
1853
  className: cn(
1546
- "bg-panel border-border-strong z-40 rounded-md border p-[6px] shadow-lg outline-none",
1854
+ "bg-panel border-border-strong z-popover rounded-md border p-[6px] shadow-lg outline-none",
1547
1855
  "data-[state=open]:animate-[ship-pop-in_140ms_var(--easing-out)]",
1548
1856
  className
1549
1857
  ),
@@ -1554,6 +1862,18 @@ var PopoverContent = forwardRef(
1554
1862
  );
1555
1863
  PopoverContent.displayName = "PopoverContent";
1556
1864
  var Popover = RadixPopover.Root;
1865
+
1866
+ // src/components/Toast/Toast.tsx
1867
+ import * as RadixToast from "@radix-ui/react-toast";
1868
+ import {
1869
+ createContext,
1870
+ forwardRef as forwardRef33,
1871
+ useCallback as useCallback5,
1872
+ useContext,
1873
+ useMemo,
1874
+ useState as useState6
1875
+ } from "react";
1876
+ import { jsx as jsx34, jsxs as jsxs27 } from "react/jsx-runtime";
1557
1877
  var ToastContext = createContext(null);
1558
1878
  var variantIcon = {
1559
1879
  default: "\u25CF",
@@ -1576,21 +1896,30 @@ var variantBorderLeft = {
1576
1896
  warn: "border-l-warn",
1577
1897
  err: "border-l-err"
1578
1898
  };
1899
+ var toastIdCounter = 0;
1900
+ var nextToastId = () => `toast-${++toastIdCounter}`;
1579
1901
  function ToastProvider({ children }) {
1580
- const [toasts, setToasts] = useState([]);
1581
- const toast = useCallback((t) => {
1582
- const id = t.id ?? Math.random().toString(36).slice(2);
1583
- setToasts((prev) => [...prev, { ...t, id }]);
1902
+ const [toasts, setToasts] = useState6([]);
1903
+ const toast = useCallback5((t) => {
1904
+ const explicitId = t.id;
1905
+ const id = explicitId ?? nextToastId();
1906
+ const entry = { ...t, id };
1907
+ setToasts((prev) => {
1908
+ if (explicitId !== void 0 && prev.some((existing) => existing.id === explicitId)) {
1909
+ return prev.map((existing) => existing.id === explicitId ? entry : existing);
1910
+ }
1911
+ return [...prev, entry];
1912
+ });
1584
1913
  return id;
1585
1914
  }, []);
1586
- const dismiss = useCallback((id) => {
1915
+ const dismiss = useCallback5((id) => {
1587
1916
  setToasts((prev) => prev.filter((t) => t.id !== id));
1588
1917
  }, []);
1589
1918
  const value = useMemo(() => ({ toast, dismiss }), [toast, dismiss]);
1590
- return /* @__PURE__ */ jsx(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs(RadixToast.Provider, { swipeDirection: "right", children: [
1919
+ return /* @__PURE__ */ jsx34(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs27(RadixToast.Provider, { swipeDirection: "right", children: [
1591
1920
  children,
1592
- toasts.map((t) => /* @__PURE__ */ jsx(ToastCard, { toast: t, onDismiss: () => dismiss(t.id) }, t.id)),
1593
- /* @__PURE__ */ jsx(RadixToast.Viewport, { className: "fixed right-5 bottom-5 z-[70] flex w-[380px] max-w-[calc(100vw-40px)] flex-col gap-2 outline-none" })
1921
+ toasts.map((t) => /* @__PURE__ */ jsx34(ToastCard, { toast: t, onDismiss: () => dismiss(t.id) }, t.id)),
1922
+ /* @__PURE__ */ jsx34(RadixToast.Viewport, { className: "z-toast fixed right-5 bottom-5 flex w-[380px] max-w-[calc(100vw-40px)] flex-col gap-2 outline-none" })
1594
1923
  ] }) });
1595
1924
  }
1596
1925
  function useToast() {
@@ -1598,9 +1927,9 @@ function useToast() {
1598
1927
  if (!ctx) throw new Error("useToast must be inside <ToastProvider>");
1599
1928
  return ctx;
1600
1929
  }
1601
- var ToastCard = forwardRef(function ToastCard2({ toast, onDismiss }, ref) {
1930
+ var ToastCard = forwardRef33(function ToastCard2({ toast, onDismiss }, ref) {
1602
1931
  const variant = toast.variant ?? "default";
1603
- return /* @__PURE__ */ jsxs(
1932
+ return /* @__PURE__ */ jsxs27(
1604
1933
  RadixToast.Root,
1605
1934
  {
1606
1935
  ref,
@@ -1615,13 +1944,13 @@ var ToastCard = forwardRef(function ToastCard2({ toast, onDismiss }, ref) {
1615
1944
  variantBorderLeft[variant]
1616
1945
  ),
1617
1946
  children: [
1618
- /* @__PURE__ */ jsx("span", { className: cn("mt-px text-[14px] leading-none", variantTextColor[variant]), children: variantIcon[variant] }),
1619
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
1620
- /* @__PURE__ */ jsx(RadixToast.Title, { className: "text-text text-[13px] font-medium", children: toast.title }),
1621
- toast.description && /* @__PURE__ */ jsx(RadixToast.Description, { className: "text-text-muted mt-[2px] text-[12px] leading-[1.5]", children: toast.description }),
1622
- toast.action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: toast.action })
1947
+ /* @__PURE__ */ jsx34("span", { className: cn("mt-px text-[14px] leading-none", variantTextColor[variant]), children: variantIcon[variant] }),
1948
+ /* @__PURE__ */ jsxs27("div", { className: "min-w-0 flex-1", children: [
1949
+ /* @__PURE__ */ jsx34(RadixToast.Title, { className: "text-text text-[13px] font-medium", children: toast.title }),
1950
+ toast.description && /* @__PURE__ */ jsx34(RadixToast.Description, { className: "text-text-muted mt-[2px] text-[12px] leading-[1.5]", children: toast.description }),
1951
+ toast.action && /* @__PURE__ */ jsx34("div", { className: "mt-2", children: toast.action })
1623
1952
  ] }),
1624
- /* @__PURE__ */ jsx(
1953
+ /* @__PURE__ */ jsx34(
1625
1954
  RadixToast.Close,
1626
1955
  {
1627
1956
  "aria-label": "Dismiss",
@@ -1634,20 +1963,25 @@ var ToastCard = forwardRef(function ToastCard2({ toast, onDismiss }, ref) {
1634
1963
  );
1635
1964
  });
1636
1965
  ToastCard.displayName = "ToastCard";
1966
+
1967
+ // src/components/Tooltip/Tooltip.tsx
1968
+ import * as RadixTooltip from "@radix-ui/react-tooltip";
1969
+ import { forwardRef as forwardRef34 } from "react";
1970
+ import { jsx as jsx35, jsxs as jsxs28 } from "react/jsx-runtime";
1637
1971
  var TooltipProvider = RadixTooltip.Provider;
1638
1972
  var TooltipRoot = RadixTooltip.Root;
1639
1973
  var TooltipTrigger = RadixTooltip.Trigger;
1640
1974
  var TooltipPortal = RadixTooltip.Portal;
1641
1975
  var TooltipArrow = RadixTooltip.Arrow;
1642
- var TooltipContent = forwardRef(
1976
+ var TooltipContent = forwardRef34(
1643
1977
  function TooltipContent2({ className, sideOffset = 6, ...props }, ref) {
1644
- return /* @__PURE__ */ jsx(RadixTooltip.Portal, { children: /* @__PURE__ */ jsx(
1978
+ return /* @__PURE__ */ jsx35(RadixTooltip.Portal, { children: /* @__PURE__ */ jsx35(
1645
1979
  RadixTooltip.Content,
1646
1980
  {
1647
1981
  ref,
1648
1982
  sideOffset,
1649
1983
  className: cn(
1650
- "pointer-events-none z-[60] rounded-sm px-2 py-[5px] text-[11px] whitespace-nowrap",
1984
+ "z-tooltip pointer-events-none rounded-sm px-2 py-[5px] text-[11px] whitespace-nowrap",
1651
1985
  "bg-text text-bg",
1652
1986
  "data-[state=delayed-open]:animate-[ship-pop-in_120ms_var(--easing-out)]",
1653
1987
  className
@@ -1659,124 +1993,152 @@ var TooltipContent = forwardRef(
1659
1993
  );
1660
1994
  TooltipContent.displayName = "TooltipContent";
1661
1995
  function Tooltip({ content, children, side = "top", delayDuration = 400 }) {
1662
- return /* @__PURE__ */ jsx(TooltipProvider, { delayDuration, children: /* @__PURE__ */ jsxs(TooltipRoot, { children: [
1663
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children }),
1664
- /* @__PURE__ */ jsx(TooltipContent, { side, children: content })
1996
+ return /* @__PURE__ */ jsx35(TooltipProvider, { delayDuration, children: /* @__PURE__ */ jsxs28(TooltipRoot, { children: [
1997
+ /* @__PURE__ */ jsx35(TooltipTrigger, { asChild: true, children }),
1998
+ /* @__PURE__ */ jsx35(TooltipContent, { side, children: content })
1665
1999
  ] }) });
1666
2000
  }
1667
- var alertStyles = cva("flex items-start gap-3 rounded-base border bg-panel p-3 text-[13px]", {
2001
+
2002
+ // src/patterns/Alert/Alert.tsx
2003
+ import { cva as cva8 } from "class-variance-authority";
2004
+ import { forwardRef as forwardRef35 } from "react";
2005
+ import { jsx as jsx36, jsxs as jsxs29 } from "react/jsx-runtime";
2006
+ var alertStyles = cva8("flex items-start gap-3 rounded-base border bg-panel p-3 text-[13px]", {
1668
2007
  variants: {
1669
- variant: {
1670
- info: "border-border border-l-2 border-l-accent",
2008
+ tone: {
2009
+ accent: "border-border border-l-2 border-l-accent",
1671
2010
  ok: "border-border border-l-2 border-l-ok",
1672
2011
  warn: "border-border border-l-2 border-l-warn",
1673
2012
  err: "border-border border-l-2 border-l-err"
1674
2013
  }
1675
2014
  },
1676
- defaultVariants: { variant: "info" }
2015
+ defaultVariants: { tone: "accent" }
1677
2016
  });
1678
2017
  var iconColorClass = {
1679
- info: "text-accent",
2018
+ accent: "text-accent",
1680
2019
  ok: "text-ok",
1681
2020
  warn: "text-warn",
1682
2021
  err: "text-err"
1683
2022
  };
1684
2023
  var defaultGlyph = {
1685
- info: "\u2139",
2024
+ accent: "\u2139",
1686
2025
  ok: "\u2713",
1687
2026
  warn: "!",
1688
2027
  err: "\xD7"
1689
2028
  };
1690
- var Alert = forwardRef(function Alert2({ variant = "info", title, description, icon, action, className, children, ...props }, ref) {
1691
- return /* @__PURE__ */ jsxs(
2029
+ var Alert = forwardRef35(function Alert2({
2030
+ tone = "accent",
2031
+ title,
2032
+ description,
2033
+ icon,
2034
+ action,
2035
+ live = "polite",
2036
+ className,
2037
+ children,
2038
+ ...props
2039
+ }, ref) {
2040
+ const t = tone ?? "accent";
2041
+ return /* @__PURE__ */ jsxs29(
1692
2042
  "div",
1693
2043
  {
1694
2044
  ref,
1695
- role: variant === "err" || variant === "warn" ? "alert" : "status",
1696
- className: cn(alertStyles({ variant }), className),
2045
+ role: live === "assertive" ? "alert" : "status",
2046
+ "aria-live": live === "off" ? void 0 : live,
2047
+ className: cn(alertStyles({ tone }), className),
1697
2048
  ...props,
1698
2049
  children: [
1699
- /* @__PURE__ */ jsx(
1700
- "span",
1701
- {
1702
- "aria-hidden": true,
1703
- className: cn("mt-[1px] text-[14px] leading-none", iconColorClass[variant]),
1704
- children: icon ?? defaultGlyph[variant]
1705
- }
1706
- ),
1707
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
1708
- title && /* @__PURE__ */ jsx("div", { className: "font-medium", children: title }),
1709
- description && /* @__PURE__ */ jsx("div", { className: "text-text-muted mt-[2px] text-[12px]", children: description }),
2050
+ /* @__PURE__ */ jsx36("span", { "aria-hidden": true, className: cn("mt-[1px] text-[14px] leading-none", iconColorClass[t]), children: icon ?? defaultGlyph[t] }),
2051
+ /* @__PURE__ */ jsxs29("div", { className: "min-w-0 flex-1", children: [
2052
+ title && /* @__PURE__ */ jsx36("div", { className: "font-medium", children: title }),
2053
+ description && /* @__PURE__ */ jsx36("div", { className: "text-text-muted mt-[2px] text-[12px]", children: description }),
1710
2054
  children
1711
2055
  ] }),
1712
- action && /* @__PURE__ */ jsx("div", { className: "ml-1 shrink-0", children: action })
2056
+ action && /* @__PURE__ */ jsx36("div", { className: "ml-1 shrink-0", children: action })
1713
2057
  ]
1714
2058
  }
1715
2059
  );
1716
2060
  });
1717
2061
  Alert.displayName = "Alert";
1718
- var bannerStyles = cva(
1719
- "flex items-center gap-[10px] border-b border-border px-[14px] py-2 text-[12px]",
2062
+
2063
+ // src/patterns/Banner/Banner.tsx
2064
+ import { cva as cva9 } from "class-variance-authority";
2065
+ import { forwardRef as forwardRef36 } from "react";
2066
+ import { jsx as jsx37, jsxs as jsxs30 } from "react/jsx-runtime";
2067
+ var bannerStyles = cva9(
2068
+ "flex items-center gap-3 border-b border-border px-[14px] py-2 text-[12px]",
1720
2069
  {
1721
2070
  variants: {
1722
- variant: {
1723
- info: "bg-[color-mix(in_oklab,var(--color-accent),transparent_82%)] text-accent",
2071
+ tone: {
2072
+ accent: "bg-[color-mix(in_oklab,var(--color-accent),transparent_82%)] text-accent",
1724
2073
  ok: "bg-[color-mix(in_oklab,var(--color-ok),transparent_82%)] text-ok",
1725
2074
  warn: "bg-[color-mix(in_oklab,var(--color-warn),transparent_82%)] text-warn",
1726
2075
  err: "bg-[color-mix(in_oklab,var(--color-err),transparent_82%)] text-err"
1727
2076
  },
1728
2077
  sticky: {
1729
- true: "sticky top-0 z-30",
2078
+ true: "sticky top-0 z-sticky",
1730
2079
  false: ""
1731
2080
  }
1732
2081
  },
1733
- defaultVariants: { variant: "info", sticky: false }
2082
+ defaultVariants: { tone: "accent", sticky: false }
1734
2083
  }
1735
2084
  );
1736
2085
  var defaultGlyph2 = {
1737
- info: "\u2726",
2086
+ accent: "\u2726",
1738
2087
  ok: "\u2713",
1739
2088
  warn: "!",
1740
2089
  err: "\xD7"
1741
2090
  };
1742
- var Banner = forwardRef(function Banner2({ variant = "info", sticky, icon, action, className, children, ...props }, ref) {
1743
- return /* @__PURE__ */ jsxs(
2091
+ var Banner = forwardRef36(function Banner2({ tone = "accent", sticky, icon, action, live = "polite", className, children, ...props }, ref) {
2092
+ const t = tone ?? "accent";
2093
+ return /* @__PURE__ */ jsxs30(
1744
2094
  "div",
1745
2095
  {
1746
2096
  ref,
1747
- role: variant === "err" || variant === "warn" ? "alert" : "status",
1748
- className: cn(bannerStyles({ variant, sticky }), className),
2097
+ role: live === "assertive" ? "alert" : "status",
2098
+ "aria-live": live === "off" ? void 0 : live,
2099
+ className: cn(bannerStyles({ tone, sticky }), className),
1749
2100
  ...props,
1750
2101
  children: [
1751
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "leading-none", children: icon ?? defaultGlyph2[variant] }),
1752
- /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children }),
1753
- action && /* @__PURE__ */ jsx("div", { className: "ml-auto", children: action })
2102
+ /* @__PURE__ */ jsx37("span", { "aria-hidden": true, className: "leading-none", children: icon ?? defaultGlyph2[t] }),
2103
+ /* @__PURE__ */ jsx37("div", { className: "min-w-0 flex-1", children }),
2104
+ action && /* @__PURE__ */ jsx37("div", { className: "ml-auto", children: action })
1754
2105
  ]
1755
2106
  }
1756
2107
  );
1757
2108
  });
1758
2109
  Banner.displayName = "Banner";
1759
- var Breadcrumbs = forwardRef(function Breadcrumbs2({ separator = "/", className, children, ...props }, ref) {
1760
- const crumbs = Children.toArray(children).filter(isValidElement);
2110
+
2111
+ // src/patterns/Breadcrumbs/Breadcrumbs.tsx
2112
+ import {
2113
+ Children as Children2,
2114
+ forwardRef as forwardRef37,
2115
+ isValidElement as isValidElement2
2116
+ } from "react";
2117
+ import { jsx as jsx38, jsxs as jsxs31 } from "react/jsx-runtime";
2118
+ var Breadcrumbs = forwardRef37(function Breadcrumbs2({ separator = "/", className, children, ...props }, ref) {
2119
+ const crumbs = Children2.toArray(children).filter(isValidElement2);
1761
2120
  const last = crumbs.length - 1;
1762
- return /* @__PURE__ */ jsx("nav", { ref, "aria-label": "Breadcrumb", className: cn("text-[13px]", className), ...props, children: /* @__PURE__ */ jsx("ol", { className: "text-text-muted flex flex-wrap items-center gap-[6px]", children: crumbs.map((crumb, i) => {
2121
+ return /* @__PURE__ */ jsx38("nav", { ref, "aria-label": "Breadcrumb", className: cn("text-[13px]", className), ...props, children: /* @__PURE__ */ jsx38("ol", { className: "text-text-muted flex flex-wrap items-center gap-[6px]", children: crumbs.map((crumb, i) => {
1763
2122
  const isCurrent = i === last;
1764
- return /* @__PURE__ */ jsxs("li", { className: "inline-flex items-center gap-[6px]", children: [
1765
- isCurrent ? /* @__PURE__ */ jsx(Crumb, { ...crumb.props, current: true }) : crumb,
1766
- !isCurrent && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-text-dim", children: separator })
2123
+ return /* @__PURE__ */ jsxs31("li", { className: "inline-flex items-center gap-[6px]", children: [
2124
+ isCurrent ? /* @__PURE__ */ jsx38(Crumb, { ...crumb.props, current: true }) : crumb,
2125
+ !isCurrent && /* @__PURE__ */ jsx38("span", { "aria-hidden": true, className: "text-text-dim", children: separator })
1767
2126
  ] }, i);
1768
2127
  }) }) });
1769
2128
  });
1770
2129
  Breadcrumbs.displayName = "Breadcrumbs";
1771
- var Crumb = forwardRef(function Crumb2({ current, className, href, children, ...props }, ref) {
2130
+ var Crumb = forwardRef37(function Crumb2({ current, className, href, children, ...props }, ref) {
1772
2131
  if (current) {
1773
- return /* @__PURE__ */ jsx("span", { "aria-current": "page", className: cn("text-text", className), children });
2132
+ return /* @__PURE__ */ jsx38("span", { "aria-current": "page", className: cn("text-text", className), children });
1774
2133
  }
1775
- return /* @__PURE__ */ jsx(
2134
+ if (href === void 0) {
2135
+ return /* @__PURE__ */ jsx38("span", { className: cn("text-text-dim", className), children });
2136
+ }
2137
+ return /* @__PURE__ */ jsx38(
1776
2138
  "a",
1777
2139
  {
1778
2140
  ref,
1779
- href: href ?? "#",
2141
+ href,
1780
2142
  className: cn("hover:text-text transition-colors duration-(--duration-micro)", className),
1781
2143
  ...props,
1782
2144
  children
@@ -1784,6 +2146,17 @@ var Crumb = forwardRef(function Crumb2({ current, className, href, children, ...
1784
2146
  );
1785
2147
  });
1786
2148
  Crumb.displayName = "Crumb";
2149
+
2150
+ // src/patterns/Combobox/Combobox.tsx
2151
+ import {
2152
+ forwardRef as forwardRef38,
2153
+ useEffect as useEffect5,
2154
+ useId as useId6,
2155
+ useMemo as useMemo2,
2156
+ useRef as useRef4,
2157
+ useState as useState7
2158
+ } from "react";
2159
+ import { jsx as jsx39, jsxs as jsxs32 } from "react/jsx-runtime";
1787
2160
  function normalize(option) {
1788
2161
  if (typeof option === "string") {
1789
2162
  return { value: option, label: option, searchText: option.toLowerCase() };
@@ -1799,7 +2172,7 @@ function normalize(option) {
1799
2172
  };
1800
2173
  }
1801
2174
  var defaultFilter = (option, query) => option.searchText.includes(query.toLowerCase());
1802
- var Combobox = forwardRef(function Combobox2({
2175
+ var Combobox = forwardRef38(function Combobox2({
1803
2176
  options,
1804
2177
  value: valueProp,
1805
2178
  defaultValue,
@@ -1816,16 +2189,16 @@ var Combobox = forwardRef(function Combobox2({
1816
2189
  id,
1817
2190
  "aria-label": ariaLabel
1818
2191
  }, ref) {
1819
- const reactId = useId();
2192
+ const reactId = useId6();
1820
2193
  const listboxId = `${id ?? reactId}-listbox`;
1821
2194
  const inputId = id ?? `${reactId}-input`;
1822
- const normalized = useMemo(() => options.map(normalize), [options]);
2195
+ const normalized = useMemo2(() => options.map(normalize), [options]);
1823
2196
  const [value, setValue] = useControllableState({
1824
2197
  value: valueProp,
1825
2198
  defaultValue,
1826
2199
  onChange: onValueChange
1827
2200
  });
1828
- const initialQuery = useMemo(() => {
2201
+ const initialQuery = useMemo2(() => {
1829
2202
  if (defaultQuery !== void 0) return defaultQuery;
1830
2203
  if (defaultValue !== void 0) {
1831
2204
  const opt = normalized.find((o) => o.value === defaultValue);
@@ -1838,10 +2211,10 @@ var Combobox = forwardRef(function Combobox2({
1838
2211
  defaultValue: initialQuery,
1839
2212
  onChange: onQueryChange
1840
2213
  });
1841
- const [open, setOpen] = useState(false);
1842
- const wrapperRef = useRef(null);
2214
+ const [open, setOpen] = useState7(false);
2215
+ const wrapperRef = useRef4(null);
1843
2216
  useOutsideClick(wrapperRef, () => setOpen(false));
1844
- const filtered = useMemo(
2217
+ const filtered = useMemo2(
1845
2218
  () => query ? normalized.filter((o) => filter(o, query)) : normalized,
1846
2219
  [normalized, query, filter]
1847
2220
  );
@@ -1853,7 +2226,7 @@ var Combobox = forwardRef(function Combobox2({
1853
2226
  if (item && !item.disabled) commit(item);
1854
2227
  }
1855
2228
  });
1856
- useEffect(() => {
2229
+ useEffect5(() => {
1857
2230
  setCursor(0);
1858
2231
  }, [query, setCursor]);
1859
2232
  function commit(option) {
@@ -1876,8 +2249,8 @@ var Combobox = forwardRef(function Combobox2({
1876
2249
  setOpen(false);
1877
2250
  }
1878
2251
  };
1879
- return /* @__PURE__ */ jsxs("div", { ref: wrapperRef, className: "relative", style: { width }, children: [
1880
- /* @__PURE__ */ jsx(
2252
+ return /* @__PURE__ */ jsxs32("div", { ref: wrapperRef, className: "relative", style: { width }, children: [
2253
+ /* @__PURE__ */ jsx39(
1881
2254
  "input",
1882
2255
  {
1883
2256
  ref,
@@ -1911,19 +2284,19 @@ var Combobox = forwardRef(function Combobox2({
1911
2284
  )
1912
2285
  }
1913
2286
  ),
1914
- open && /* @__PURE__ */ jsx(
2287
+ open && /* @__PURE__ */ jsx39(
1915
2288
  "ul",
1916
2289
  {
1917
2290
  id: listboxId,
1918
2291
  role: "listbox",
1919
2292
  "aria-label": ariaLabel ?? "Suggestions",
1920
2293
  className: cn(
1921
- "absolute top-full right-0 left-0 z-30 mt-1 max-h-[220px] overflow-auto",
2294
+ "z-dropdown absolute top-full right-0 left-0 mt-1 max-h-[220px] overflow-auto",
1922
2295
  "border-border bg-panel rounded-md border p-1 shadow-lg"
1923
2296
  ),
1924
- children: filtered.length === 0 ? /* @__PURE__ */ jsx("li", { className: "text-text-dim px-2 py-3 text-center text-[12px]", role: "presentation", children: emptyState ?? "No matches" }) : filtered.map((option, i) => {
2297
+ children: filtered.length === 0 ? /* @__PURE__ */ jsx39("li", { className: "text-text-dim px-2 py-3 text-center text-[12px]", role: "presentation", children: emptyState ?? "No matches" }) : filtered.map((option, i) => {
1925
2298
  const isActive = i === cursor;
1926
- return /* @__PURE__ */ jsxs(
2299
+ return /* @__PURE__ */ jsxs32(
1927
2300
  "li",
1928
2301
  {
1929
2302
  id: `${listboxId}-option-${i}`,
@@ -1941,8 +2314,8 @@ var Combobox = forwardRef(function Combobox2({
1941
2314
  option.disabled && "pointer-events-none opacity-40"
1942
2315
  ),
1943
2316
  children: [
1944
- /* @__PURE__ */ jsx("div", { children: option.label }),
1945
- option.description && /* @__PURE__ */ jsx("div", { className: "text-text-dim text-[11px]", children: option.description })
2317
+ /* @__PURE__ */ jsx39("div", { children: option.label }),
2318
+ option.description && /* @__PURE__ */ jsx39("div", { className: "text-text-dim text-[11px]", children: option.description })
1946
2319
  ]
1947
2320
  },
1948
2321
  option.value
@@ -1950,14 +2323,19 @@ var Combobox = forwardRef(function Combobox2({
1950
2323
  })
1951
2324
  }
1952
2325
  ),
1953
- name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: value ?? "", readOnly: true })
2326
+ name && /* @__PURE__ */ jsx39("input", { type: "hidden", name, value: value ?? "", readOnly: true })
1954
2327
  ] });
1955
2328
  });
1956
2329
  Combobox.displayName = "Combobox";
2330
+
2331
+ // src/patterns/CommandPalette/CommandPalette.tsx
2332
+ import * as RadixDialog4 from "@radix-ui/react-dialog";
2333
+ import { forwardRef as forwardRef39, useEffect as useEffect6, useId as useId7, useMemo as useMemo3 } from "react";
2334
+ import { Fragment, jsx as jsx40, jsxs as jsxs33 } from "react/jsx-runtime";
1957
2335
  function flatItems(groups) {
1958
2336
  return groups.flatMap((g) => g.items);
1959
2337
  }
1960
- var CommandPalette = forwardRef(
2338
+ var CommandPalette = forwardRef39(
1961
2339
  function CommandPalette2({
1962
2340
  open,
1963
2341
  onOpenChange,
@@ -1970,7 +2348,7 @@ var CommandPalette = forwardRef(
1970
2348
  emptyState,
1971
2349
  width = 540
1972
2350
  }, ref) {
1973
- const flat = useMemo(() => flatItems(groups), [groups]);
2351
+ const flat = useMemo3(() => flatItems(groups), [groups]);
1974
2352
  const { cursor, setCursor, onKeyDown } = useKeyboardList({
1975
2353
  count: flat.length,
1976
2354
  defaultCursor: 0,
@@ -1979,37 +2357,41 @@ var CommandPalette = forwardRef(
1979
2357
  if (item) onSelect(item.id);
1980
2358
  }
1981
2359
  });
1982
- useEffect(() => {
2360
+ const reactId = useId7();
2361
+ const listboxId = `${reactId}-listbox`;
2362
+ const optionId = (i) => `${listboxId}-option-${i}`;
2363
+ const hasMatches = flat.length > 0;
2364
+ useEffect6(() => {
1983
2365
  setCursor(0);
1984
2366
  }, [query, groups, setCursor]);
1985
- return /* @__PURE__ */ jsx(RadixDialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs(RadixDialog.Portal, { children: [
1986
- /* @__PURE__ */ jsx(
1987
- RadixDialog.Overlay,
2367
+ return /* @__PURE__ */ jsx40(RadixDialog4.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs33(RadixDialog4.Portal, { children: [
2368
+ /* @__PURE__ */ jsx40(
2369
+ RadixDialog4.Overlay,
1988
2370
  {
1989
2371
  className: cn(
1990
- "fixed inset-0 z-50 bg-black/55 backdrop-blur-[4px]",
2372
+ "z-overlay fixed inset-0 bg-black/55 backdrop-blur-[4px]",
1991
2373
  "data-[state=open]:animate-[ship-fade-in_150ms_ease]"
1992
2374
  )
1993
2375
  }
1994
2376
  ),
1995
- /* @__PURE__ */ jsxs(
1996
- RadixDialog.Content,
2377
+ /* @__PURE__ */ jsxs33(
2378
+ RadixDialog4.Content,
1997
2379
  {
1998
2380
  ref,
1999
2381
  "aria-label": "Command palette",
2000
2382
  "aria-describedby": void 0,
2001
2383
  style: { width },
2002
2384
  className: cn(
2003
- "fixed top-[20%] left-1/2 z-[51] max-w-[calc(100%-40px)] -translate-x-1/2",
2385
+ "z-modal fixed top-[20%] left-1/2 max-w-[calc(100%-40px)] -translate-x-1/2",
2004
2386
  "border-border-strong bg-panel overflow-hidden rounded-xl border shadow-lg",
2005
2387
  "outline-none data-[state=open]:animate-[ship-dialog-in_180ms_var(--easing-out)]"
2006
2388
  ),
2007
2389
  onKeyDown,
2008
2390
  children: [
2009
- /* @__PURE__ */ jsx(RadixDialog.Title, { className: "sr-only", children: "Command palette" }),
2010
- /* @__PURE__ */ jsxs("div", { className: "border-border flex items-center gap-[10px] border-b px-4 py-[14px]", children: [
2011
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-text-dim", children: "\u2315" }),
2012
- /* @__PURE__ */ jsx(
2391
+ /* @__PURE__ */ jsx40(RadixDialog4.Title, { className: "sr-only", children: "Command palette" }),
2392
+ /* @__PURE__ */ jsxs33("div", { className: "border-border flex items-center gap-[10px] border-b px-4 py-[14px]", children: [
2393
+ /* @__PURE__ */ jsx40("span", { "aria-hidden": true, className: "text-text-dim", children: "\u2315" }),
2394
+ /* @__PURE__ */ jsx40(
2013
2395
  "input",
2014
2396
  {
2015
2397
  autoFocus: true,
@@ -2018,22 +2400,27 @@ var CommandPalette = forwardRef(
2018
2400
  onChange: (e) => onQueryChange(e.target.value),
2019
2401
  placeholder,
2020
2402
  "aria-label": "Search",
2403
+ role: "combobox",
2021
2404
  "aria-autocomplete": "list",
2405
+ "aria-expanded": true,
2406
+ "aria-controls": listboxId,
2407
+ "aria-activedescendant": hasMatches ? optionId(cursor) : void 0,
2022
2408
  className: "text-text placeholder:text-text-dim flex-1 border-0 bg-transparent text-[14px] outline-none"
2023
2409
  }
2024
2410
  ),
2025
- /* @__PURE__ */ jsx("span", { className: "border-border text-text-dim rounded-xs border px-[6px] py-[2px] font-mono text-[10px]", children: "ESC" })
2411
+ /* @__PURE__ */ jsx40("span", { className: "border-border text-text-dim rounded-xs border px-[6px] py-[2px] font-mono text-[10px]", children: "ESC" })
2026
2412
  ] }),
2027
- /* @__PURE__ */ jsx("div", { className: "min-h-[220px] p-2", role: "listbox", "aria-label": "Results", children: flat.length === 0 ? emptyState ?? /* @__PURE__ */ jsx("div", { className: "text-text-dim px-3 py-5 text-center text-[12px]", children: "No matches" }) : /* @__PURE__ */ jsx(
2413
+ /* @__PURE__ */ jsx40("div", { id: listboxId, className: "min-h-[220px] p-2", role: "listbox", "aria-label": "Results", children: flat.length === 0 ? emptyState ?? /* @__PURE__ */ jsx40("div", { className: "text-text-dim px-3 py-5 text-center text-[12px]", children: "No matches" }) : /* @__PURE__ */ jsx40(
2028
2414
  CommandGroups,
2029
2415
  {
2030
2416
  groups,
2031
2417
  cursor,
2032
2418
  setCursor,
2033
- onSelect
2419
+ onSelect,
2420
+ optionId
2034
2421
  }
2035
2422
  ) }),
2036
- footer && /* @__PURE__ */ jsx("div", { className: "border-border text-text-dim flex gap-4 border-t px-[14px] py-[10px] font-mono text-[10px]", children: footer })
2423
+ footer && /* @__PURE__ */ jsx40("div", { className: "border-border text-text-dim flex gap-4 border-t px-[14px] py-[10px] font-mono text-[10px]", children: footer })
2037
2424
  ]
2038
2425
  }
2039
2426
  )
@@ -2041,12 +2428,12 @@ var CommandPalette = forwardRef(
2041
2428
  }
2042
2429
  );
2043
2430
  CommandPalette.displayName = "CommandPalette";
2044
- function CommandGroups({ groups, cursor, setCursor, onSelect }) {
2431
+ function CommandGroups({ groups, cursor, setCursor, onSelect, optionId }) {
2045
2432
  let runningIndex = 0;
2046
- return /* @__PURE__ */ jsx(Fragment, { children: groups.map((group, gIdx) => {
2433
+ return /* @__PURE__ */ jsx40(Fragment, { children: groups.map((group, gIdx) => {
2047
2434
  if (group.items.length === 0) return null;
2048
- return /* @__PURE__ */ jsxs("div", { children: [
2049
- group.label && /* @__PURE__ */ jsxs("div", { className: "text-text-dim px-2 pt-2 pb-1 font-mono text-[9px] tracking-[1.4px] uppercase", children: [
2435
+ return /* @__PURE__ */ jsxs33("div", { children: [
2436
+ group.label && /* @__PURE__ */ jsxs33("div", { className: "text-text-dim px-2 pt-2 pb-1 font-mono text-[9px] tracking-[1.4px] uppercase", children: [
2050
2437
  group.label,
2051
2438
  " \xB7 ",
2052
2439
  group.items.length
@@ -2054,9 +2441,10 @@ function CommandGroups({ groups, cursor, setCursor, onSelect }) {
2054
2441
  group.items.map((item) => {
2055
2442
  const myIndex = runningIndex++;
2056
2443
  const isActive = cursor === myIndex;
2057
- return /* @__PURE__ */ jsxs(
2444
+ return /* @__PURE__ */ jsxs33(
2058
2445
  "button",
2059
2446
  {
2447
+ id: optionId(myIndex),
2060
2448
  type: "button",
2061
2449
  role: "option",
2062
2450
  "aria-selected": isActive,
@@ -2067,7 +2455,7 @@ function CommandGroups({ groups, cursor, setCursor, onSelect }) {
2067
2455
  isActive ? "bg-accent-dim text-accent" : "text-text hover:bg-panel-2"
2068
2456
  ),
2069
2457
  children: [
2070
- item.glyph != null && /* @__PURE__ */ jsx(
2458
+ item.glyph != null && /* @__PURE__ */ jsx40(
2071
2459
  "span",
2072
2460
  {
2073
2461
  "aria-hidden": true,
@@ -2078,11 +2466,11 @@ function CommandGroups({ groups, cursor, setCursor, onSelect }) {
2078
2466
  children: item.glyph
2079
2467
  }
2080
2468
  ),
2081
- /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
2082
- /* @__PURE__ */ jsx("span", { className: "block truncate text-[13px]", children: item.label }),
2083
- item.description && /* @__PURE__ */ jsx("span", { className: "text-text-dim block truncate text-[11px]", children: item.description })
2469
+ /* @__PURE__ */ jsxs33("span", { className: "min-w-0 flex-1", children: [
2470
+ /* @__PURE__ */ jsx40("span", { className: "block truncate text-[13px]", children: item.label }),
2471
+ item.description && /* @__PURE__ */ jsx40("span", { className: "text-text-dim block truncate text-[11px]", children: item.description })
2084
2472
  ] }),
2085
- item.trailing && /* @__PURE__ */ jsx("span", { className: "text-text-dim font-mono text-[10px]", children: item.trailing })
2473
+ item.trailing && /* @__PURE__ */ jsx40("span", { className: "text-text-dim font-mono text-[10px]", children: item.trailing })
2086
2474
  ]
2087
2475
  },
2088
2476
  item.id
@@ -2102,11 +2490,16 @@ function filterCommandItems(query, groups) {
2102
2490
  })
2103
2491
  })).filter((g) => g.items.length > 0);
2104
2492
  }
2493
+
2494
+ // src/patterns/DataTable/DataTable.tsx
2495
+ import { useEffect as useEffect7, useMemo as useMemo4, useRef as useRef5 } from "react";
2496
+ import { jsx as jsx41, jsxs as jsxs34 } from "react/jsx-runtime";
2105
2497
  var alignClass = {
2106
2498
  left: "text-left",
2107
2499
  right: "text-right",
2108
2500
  center: "text-center"
2109
2501
  };
2502
+ var EMPTY_SET = /* @__PURE__ */ new Set();
2110
2503
  function DataTable(props) {
2111
2504
  const {
2112
2505
  data,
@@ -2131,16 +2524,16 @@ function DataTable(props) {
2131
2524
  onChange: onSortChange
2132
2525
  });
2133
2526
  const [selected, setSelected] = useControllableState({
2134
- value: selectedProp instanceof Set ? selectedProp : selectedProp,
2527
+ value: selectedProp,
2135
2528
  defaultValue: new Set(defaultSelected ?? []),
2136
2529
  onChange: onSelectionChange
2137
2530
  });
2138
- const sortableMap = useMemo(() => {
2531
+ const sortableMap = useMemo4(() => {
2139
2532
  const m = /* @__PURE__ */ new Map();
2140
2533
  for (const c of columns) if (c.accessor) m.set(c.key, c);
2141
2534
  return m;
2142
2535
  }, [columns]);
2143
- const sortedData = useMemo(() => {
2536
+ const sortedData = useMemo4(() => {
2144
2537
  if (!sort) return [...data];
2145
2538
  const col = sortableMap.get(sort.key);
2146
2539
  if (!col || !col.accessor) return [...data];
@@ -2152,11 +2545,12 @@ function DataTable(props) {
2152
2545
  return String(av).localeCompare(String(bv)) * factor;
2153
2546
  });
2154
2547
  }, [data, sort, sortableMap]);
2155
- const allIds = useMemo(() => sortedData.map(rowKey), [sortedData, rowKey]);
2156
- const allSelected = allIds.length > 0 && allIds.every((id) => selected.has(id));
2157
- const someSelected = !allSelected && allIds.some((id) => selected.has(id));
2158
- const headerCheckRef = useRef(null);
2159
- useEffect(() => {
2548
+ const allIds = useMemo4(() => sortedData.map(rowKey), [sortedData, rowKey]);
2549
+ const selectedSet = selected ?? EMPTY_SET;
2550
+ const allSelected = allIds.length > 0 && allIds.every((id) => selectedSet.has(id));
2551
+ const someSelected = !allSelected && allIds.some((id) => selectedSet.has(id));
2552
+ const headerCheckRef = useRef5(null);
2553
+ useEffect7(() => {
2160
2554
  if (headerCheckRef.current) headerCheckRef.current.indeterminate = someSelected;
2161
2555
  }, [someSelected]);
2162
2556
  const toggleSort = (key) => {
@@ -2187,10 +2581,10 @@ function DataTable(props) {
2187
2581
  return next;
2188
2582
  });
2189
2583
  };
2190
- return /* @__PURE__ */ jsxs("table", { ref, className: cn("w-full border-collapse text-[12px]", className), children: [
2191
- caption && /* @__PURE__ */ jsx("caption", { className: "sr-only", children: caption }),
2192
- /* @__PURE__ */ jsx("thead", { className: cn("bg-panel-2", stickyHeader && "sticky top-0 z-10"), children: /* @__PURE__ */ jsxs("tr", { children: [
2193
- selectable && /* @__PURE__ */ jsx("th", { scope: "col", className: "border-border w-8 border-b px-3 py-2 text-left", children: /* @__PURE__ */ jsx(
2584
+ return /* @__PURE__ */ jsxs34("table", { ref, className: cn("w-full border-collapse text-[12px]", className), children: [
2585
+ caption && /* @__PURE__ */ jsx41("caption", { className: "sr-only", children: caption }),
2586
+ /* @__PURE__ */ jsx41("thead", { className: cn("bg-panel-2", stickyHeader && "z-raised sticky top-0"), children: /* @__PURE__ */ jsxs34("tr", { children: [
2587
+ selectable && /* @__PURE__ */ jsx41("th", { scope: "col", className: "border-border w-8 border-b px-3 py-2 text-left", children: /* @__PURE__ */ jsx41(
2194
2588
  "input",
2195
2589
  {
2196
2590
  ref: headerCheckRef,
@@ -2206,12 +2600,12 @@ function DataTable(props) {
2206
2600
  const isSorted = sort?.key === col.key;
2207
2601
  const ariaSort = !sortable ? void 0 : isSorted ? sort?.direction === "asc" ? "ascending" : "descending" : "none";
2208
2602
  const align = col.align ?? "left";
2209
- return /* @__PURE__ */ jsxs(
2603
+ const indicator = sortable && isSorted && /* @__PURE__ */ jsx41("span", { "aria-hidden": true, className: "ml-1", children: sort?.direction === "asc" ? "\u2191" : "\u2193" });
2604
+ return /* @__PURE__ */ jsx41(
2210
2605
  "th",
2211
2606
  {
2212
2607
  scope: "col",
2213
2608
  "aria-sort": ariaSort,
2214
- onClick: sortable ? () => toggleSort(col.key) : void 0,
2215
2609
  style: col.width != null ? { width: col.width } : void 0,
2216
2610
  className: cn(
2217
2611
  "border-border border-b px-3 py-2 font-mono text-[10px] font-medium tracking-[1.4px] uppercase select-none",
@@ -2219,17 +2613,25 @@ function DataTable(props) {
2219
2613
  sortable && "cursor-pointer",
2220
2614
  isSorted ? "text-accent" : "text-text-dim"
2221
2615
  ),
2222
- children: [
2223
- col.header,
2224
- sortable && isSorted && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "ml-1", children: sort?.direction === "asc" ? "\u2191" : "\u2193" })
2225
- ]
2616
+ children: sortable ? /* @__PURE__ */ jsxs34(
2617
+ "button",
2618
+ {
2619
+ type: "button",
2620
+ onClick: () => toggleSort(col.key),
2621
+ className: "focus-visible:ring-accent-dim inline-flex cursor-pointer items-center gap-1 font-mono text-[10px] font-medium tracking-[1.4px] uppercase outline-none focus-visible:ring-[3px]",
2622
+ children: [
2623
+ col.header,
2624
+ indicator
2625
+ ]
2626
+ }
2627
+ ) : col.header
2226
2628
  },
2227
2629
  col.key
2228
2630
  );
2229
2631
  })
2230
2632
  ] }) }),
2231
- /* @__PURE__ */ jsxs("tbody", { children: [
2232
- sortedData.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
2633
+ /* @__PURE__ */ jsxs34("tbody", { children: [
2634
+ sortedData.length === 0 && /* @__PURE__ */ jsx41("tr", { children: /* @__PURE__ */ jsx41(
2233
2635
  "td",
2234
2636
  {
2235
2637
  colSpan: columns.length + (selectable ? 1 : 0),
@@ -2239,8 +2641,8 @@ function DataTable(props) {
2239
2641
  ) }),
2240
2642
  sortedData.map((row) => {
2241
2643
  const id = rowKey(row);
2242
- const isSelected = selected.has(id);
2243
- return /* @__PURE__ */ jsxs(
2644
+ const isSelected = selectedSet.has(id);
2645
+ return /* @__PURE__ */ jsxs34(
2244
2646
  "tr",
2245
2647
  {
2246
2648
  "data-state": isSelected ? "selected" : void 0,
@@ -2249,7 +2651,7 @@ function DataTable(props) {
2249
2651
  isSelected ? "bg-accent-dim/50" : "hover:bg-panel-2"
2250
2652
  ),
2251
2653
  children: [
2252
- selectable && /* @__PURE__ */ jsx("td", { className: "px-3 py-[10px]", children: /* @__PURE__ */ jsx(
2654
+ selectable && /* @__PURE__ */ jsx41("td", { className: "px-3 py-[10px]", children: /* @__PURE__ */ jsx41(
2253
2655
  "input",
2254
2656
  {
2255
2657
  type: "checkbox",
@@ -2259,7 +2661,7 @@ function DataTable(props) {
2259
2661
  className: "cursor-pointer accent-[var(--color-accent)]"
2260
2662
  }
2261
2663
  ) }),
2262
- columns.map((col) => /* @__PURE__ */ jsx("td", { className: cn("px-3 py-[10px]", alignClass[col.align ?? "left"]), children: col.cell ? col.cell(row) : col.accessor ? String(col.accessor(row)) : null }, col.key))
2664
+ columns.map((col) => /* @__PURE__ */ jsx41("td", { className: cn("px-3 py-[10px]", alignClass[col.align ?? "left"]), children: col.cell ? col.cell(row) : col.accessor ? String(col.accessor(row)) : null }, col.key))
2263
2665
  ]
2264
2666
  },
2265
2667
  id
@@ -2268,29 +2670,30 @@ function DataTable(props) {
2268
2670
  ] })
2269
2671
  ] });
2270
2672
  }
2271
- var MONTHS = [
2272
- "Jan",
2273
- "Feb",
2274
- "Mar",
2275
- "April",
2276
- "May",
2277
- "June",
2278
- "July",
2279
- "Aug",
2280
- "Sep",
2281
- "Oct",
2282
- "Nov",
2283
- "Dec"
2284
- ];
2673
+
2674
+ // src/patterns/DatePicker/Calendar.tsx
2675
+ import {
2676
+ forwardRef as forwardRef40,
2677
+ useCallback as useCallback6,
2678
+ useEffect as useEffect8,
2679
+ useRef as useRef6,
2680
+ useState as useState8
2681
+ } from "react";
2682
+ import { jsx as jsx42, jsxs as jsxs35 } from "react/jsx-runtime";
2683
+ var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
2285
2684
  var DAYS = ["S", "M", "T", "W", "T", "F", "S"];
2286
2685
  function isSameDay(a, b) {
2287
2686
  if (!a) return false;
2288
2687
  return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
2289
2688
  }
2290
- var Calendar = forwardRef(function Calendar2({
2291
- selected,
2292
- defaultSelected,
2293
- onSelect,
2689
+ function clampDay(year, month, day) {
2690
+ const max = new Date(year, month + 1, 0).getDate();
2691
+ return Math.min(Math.max(1, day), max);
2692
+ }
2693
+ var Calendar = forwardRef40(function Calendar2({
2694
+ value,
2695
+ defaultValue,
2696
+ onValueChange,
2294
2697
  month: monthProp,
2295
2698
  year: yearProp,
2296
2699
  defaultMonth,
@@ -2300,39 +2703,125 @@ var Calendar = forwardRef(function Calendar2({
2300
2703
  className,
2301
2704
  ...props
2302
2705
  }, ref) {
2303
- const today = /* @__PURE__ */ new Date();
2706
+ const [today] = useState8(() => /* @__PURE__ */ new Date());
2707
+ const [hydrated, setHydrated] = useState8(false);
2708
+ useEffect8(() => setHydrated(true), []);
2304
2709
  const [selectedDate, setSelectedDate] = useControllableState({
2305
- value: selected,
2306
- defaultValue: defaultSelected,
2307
- onChange: onSelect
2710
+ value,
2711
+ defaultValue,
2712
+ onChange: onValueChange
2308
2713
  });
2309
- const initialMonth = defaultMonth ?? defaultSelected?.getMonth() ?? today.getMonth();
2310
- const initialYear = defaultYear ?? defaultSelected?.getFullYear() ?? today.getFullYear();
2311
- const [internalMonth, setInternalMonth] = useState(initialMonth);
2312
- const [internalYear, setInternalYear] = useState(initialYear);
2714
+ const initialMonth = defaultMonth ?? defaultValue?.getMonth() ?? today.getMonth();
2715
+ const initialYear = defaultYear ?? defaultValue?.getFullYear() ?? today.getFullYear();
2716
+ const [internalMonth, setInternalMonth] = useState8(initialMonth);
2717
+ const [internalYear, setInternalYear] = useState8(initialYear);
2313
2718
  const month = monthProp ?? internalMonth;
2314
2719
  const year = yearProp ?? internalYear;
2315
2720
  const isControlled = monthProp !== void 0 && yearProp !== void 0;
2316
- const setVisible = (m, y) => {
2317
- if (!isControlled) {
2318
- setInternalMonth(m);
2319
- setInternalYear(y);
2320
- }
2321
- onVisibleMonthChange?.({ month: m, year: y });
2322
- };
2323
- const goPrev = () => {
2721
+ const setVisible = useCallback6(
2722
+ (m, y) => {
2723
+ if (!isControlled) {
2724
+ setInternalMonth(m);
2725
+ setInternalYear(y);
2726
+ }
2727
+ onVisibleMonthChange?.({ month: m, year: y });
2728
+ },
2729
+ [isControlled, onVisibleMonthChange]
2730
+ );
2731
+ const goPrev = useCallback6(() => {
2324
2732
  const m = month === 0 ? 11 : month - 1;
2325
2733
  const y = month === 0 ? year - 1 : year;
2326
2734
  setVisible(m, y);
2327
- };
2328
- const goNext = () => {
2735
+ }, [month, year, setVisible]);
2736
+ const goNext = useCallback6(() => {
2329
2737
  const m = month === 11 ? 0 : month + 1;
2330
2738
  const y = month === 11 ? year + 1 : year;
2331
2739
  setVisible(m, y);
2332
- };
2740
+ }, [month, year, setVisible]);
2333
2741
  const daysInMonth = new Date(year, month + 1, 0).getDate();
2334
2742
  const firstDayOfMonth = new Date(year, month, 1).getDay();
2335
- return /* @__PURE__ */ jsxs(
2743
+ const [focusedDate, setFocusedDate] = useState8(() => {
2744
+ if (selectedDate) return selectedDate;
2745
+ return new Date(initialYear, initialMonth, 1);
2746
+ });
2747
+ useEffect8(() => {
2748
+ if (selectedDate) setFocusedDate(selectedDate);
2749
+ }, [selectedDate]);
2750
+ const focusedInVisibleMonth = focusedDate.getMonth() === month && focusedDate.getFullYear() === year;
2751
+ const effectiveFocusDay = focusedInVisibleMonth ? focusedDate.getDate() : clampDay(year, month, focusedDate.getDate());
2752
+ const dayRefs = useRef6(/* @__PURE__ */ new Map());
2753
+ const shouldFocusRef = useRef6(false);
2754
+ useEffect8(() => {
2755
+ if (!shouldFocusRef.current) return;
2756
+ shouldFocusRef.current = false;
2757
+ const node = dayRefs.current.get(effectiveFocusDay);
2758
+ node?.focus();
2759
+ }, [effectiveFocusDay, month, year]);
2760
+ const moveFocus = useCallback6(
2761
+ (next) => {
2762
+ setFocusedDate(next);
2763
+ shouldFocusRef.current = true;
2764
+ const nextMonth = next.getMonth();
2765
+ const nextYear = next.getFullYear();
2766
+ if (nextMonth !== month || nextYear !== year) {
2767
+ setVisible(nextMonth, nextYear);
2768
+ }
2769
+ },
2770
+ [month, year, setVisible]
2771
+ );
2772
+ const onCellKeyDown = useCallback6(
2773
+ (e, day) => {
2774
+ const current = new Date(year, month, day);
2775
+ let next = null;
2776
+ let handled = true;
2777
+ switch (e.key) {
2778
+ case "ArrowLeft":
2779
+ next = new Date(year, month, day - 1);
2780
+ break;
2781
+ case "ArrowRight":
2782
+ next = new Date(year, month, day + 1);
2783
+ break;
2784
+ case "ArrowUp":
2785
+ next = new Date(year, month, day - 7);
2786
+ break;
2787
+ case "ArrowDown":
2788
+ next = new Date(year, month, day + 7);
2789
+ break;
2790
+ case "Home": {
2791
+ const dow = current.getDay();
2792
+ next = new Date(year, month, day - dow);
2793
+ break;
2794
+ }
2795
+ case "End": {
2796
+ const dow = current.getDay();
2797
+ next = new Date(year, month, day + (6 - dow));
2798
+ break;
2799
+ }
2800
+ case "PageUp": {
2801
+ const targetMonth = month === 0 ? 11 : month - 1;
2802
+ const targetYear = month === 0 ? year - 1 : year;
2803
+ const targetDay = clampDay(targetYear, targetMonth, day);
2804
+ next = new Date(targetYear, targetMonth, targetDay);
2805
+ break;
2806
+ }
2807
+ case "PageDown": {
2808
+ const targetMonth = month === 11 ? 0 : month + 1;
2809
+ const targetYear = month === 11 ? year + 1 : year;
2810
+ const targetDay = clampDay(targetYear, targetMonth, day);
2811
+ next = new Date(targetYear, targetMonth, targetDay);
2812
+ break;
2813
+ }
2814
+ default:
2815
+ handled = false;
2816
+ }
2817
+ if (handled && next) {
2818
+ e.preventDefault();
2819
+ moveFocus(next);
2820
+ }
2821
+ },
2822
+ [month, year, moveFocus]
2823
+ );
2824
+ return /* @__PURE__ */ jsxs35(
2336
2825
  "div",
2337
2826
  {
2338
2827
  ref,
@@ -2344,14 +2833,14 @@ var Calendar = forwardRef(function Calendar2({
2344
2833
  ),
2345
2834
  ...props,
2346
2835
  children: [
2347
- /* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-center justify-between", children: [
2348
- /* @__PURE__ */ jsxs("span", { className: "text-[13px] font-medium", "aria-live": "polite", children: [
2836
+ /* @__PURE__ */ jsxs35("div", { className: "mb-3 flex items-center justify-between", children: [
2837
+ /* @__PURE__ */ jsxs35("span", { className: "text-[13px] font-medium", "aria-live": "polite", children: [
2349
2838
  MONTHS[month],
2350
2839
  " ",
2351
2840
  year
2352
2841
  ] }),
2353
- /* @__PURE__ */ jsxs("div", { className: "flex gap-1", children: [
2354
- /* @__PURE__ */ jsx(
2842
+ /* @__PURE__ */ jsxs35("div", { className: "flex gap-1", children: [
2843
+ /* @__PURE__ */ jsx42(
2355
2844
  IconButton,
2356
2845
  {
2357
2846
  size: "sm",
@@ -2361,48 +2850,89 @@ var Calendar = forwardRef(function Calendar2({
2361
2850
  onClick: goPrev
2362
2851
  }
2363
2852
  ),
2364
- /* @__PURE__ */ jsx(IconButton, { size: "sm", variant: "ghost", icon: "\u203A", "aria-label": "Next month", onClick: goNext })
2853
+ /* @__PURE__ */ jsx42(IconButton, { size: "sm", variant: "ghost", icon: "\u203A", "aria-label": "Next month", onClick: goNext })
2365
2854
  ] })
2366
2855
  ] }),
2367
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-7 gap-[2px]", children: [
2368
- DAYS.map((d, i) => /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "text-text-dim p-1 text-center font-mono text-[10px]", children: d }, i)),
2369
- Array.from({ length: firstDayOfMonth }).map((_, i) => /* @__PURE__ */ jsx("div", { "aria-hidden": true }, `pad-${i}`)),
2370
- Array.from({ length: daysInMonth }).map((_, i) => {
2371
- const d = i + 1;
2372
- const date = new Date(year, month, d);
2373
- const isSelected = isSameDay(selectedDate, date);
2374
- const isToday = isSameDay(today, date);
2375
- const disabled = isDateDisabled?.(date) ?? false;
2376
- return /* @__PURE__ */ jsx(
2377
- "button",
2378
- {
2379
- type: "button",
2380
- disabled,
2381
- "aria-pressed": isSelected,
2382
- "aria-current": isToday ? "date" : void 0,
2383
- "aria-label": date.toDateString(),
2384
- onClick: () => setSelectedDate(date),
2385
- className: cn(
2386
- "cursor-pointer rounded-xs border-0 bg-transparent py-[6px] text-center text-[12px] outline-none",
2387
- "focus-visible:ring-accent-dim focus-visible:ring-[3px]",
2388
- "disabled:cursor-not-allowed disabled:opacity-30",
2389
- !isSelected && !disabled && "text-text hover:bg-panel-2",
2390
- isSelected && "bg-accent text-on-accent font-semibold",
2391
- !isSelected && isToday && "border-border-strong border"
2392
- ),
2393
- children: d
2394
- },
2395
- d
2396
- );
2397
- })
2856
+ /* @__PURE__ */ jsxs35("div", { role: "grid", "aria-label": `${MONTHS[month]} ${year}`, className: "flex flex-col gap-[2px]", children: [
2857
+ /* @__PURE__ */ jsx42("div", { role: "row", className: "grid grid-cols-7 gap-[2px]", children: DAYS.map((d, i) => /* @__PURE__ */ jsx42(
2858
+ "div",
2859
+ {
2860
+ role: "columnheader",
2861
+ "aria-label": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][i],
2862
+ className: "text-text-dim p-1 text-center font-mono text-[10px]",
2863
+ children: d
2864
+ },
2865
+ i
2866
+ )) }),
2867
+ (() => {
2868
+ const totalCells = firstDayOfMonth + daysInMonth;
2869
+ const rowCount = Math.ceil(totalCells / 7);
2870
+ const rows = [];
2871
+ for (let r = 0; r < rowCount; r++) {
2872
+ const cells = [];
2873
+ for (let c = 0; c < 7; c++) {
2874
+ const cellIndex = r * 7 + c;
2875
+ const dayNum = cellIndex - firstDayOfMonth + 1;
2876
+ if (dayNum < 1 || dayNum > daysInMonth) {
2877
+ cells.push(/* @__PURE__ */ jsx42("div", { role: "gridcell", "aria-hidden": true }, `pad-${r}-${c}`));
2878
+ continue;
2879
+ }
2880
+ const date = new Date(year, month, dayNum);
2881
+ const isSelected = isSameDay(selectedDate, date);
2882
+ const isToday = hydrated && isSameDay(today, date);
2883
+ const disabled = isDateDisabled?.(date) ?? false;
2884
+ const isFocused = dayNum === effectiveFocusDay;
2885
+ const day = dayNum;
2886
+ cells.push(
2887
+ /* @__PURE__ */ jsx42("div", { role: "gridcell", "aria-selected": isSelected, children: /* @__PURE__ */ jsx42(
2888
+ "button",
2889
+ {
2890
+ ref: (node) => {
2891
+ if (node) dayRefs.current.set(day, node);
2892
+ else dayRefs.current.delete(day);
2893
+ },
2894
+ type: "button",
2895
+ disabled,
2896
+ "aria-current": isToday ? "date" : void 0,
2897
+ "aria-label": date.toDateString(),
2898
+ tabIndex: isFocused ? 0 : -1,
2899
+ onClick: () => {
2900
+ setSelectedDate(date);
2901
+ setFocusedDate(date);
2902
+ },
2903
+ onKeyDown: (e) => onCellKeyDown(e, day),
2904
+ className: cn(
2905
+ "w-full cursor-pointer rounded-xs border-0 bg-transparent py-[6px] text-center text-[12px] outline-none",
2906
+ "focus-visible:ring-accent-dim focus-visible:ring-[3px]",
2907
+ "disabled:cursor-not-allowed disabled:opacity-30",
2908
+ !isSelected && !disabled && "text-text hover:bg-panel-2",
2909
+ isSelected && "bg-accent text-on-accent font-semibold",
2910
+ !isSelected && isToday && "border-border-strong border"
2911
+ ),
2912
+ children: day
2913
+ }
2914
+ ) }, day)
2915
+ );
2916
+ }
2917
+ rows.push(
2918
+ /* @__PURE__ */ jsx42("div", { role: "row", className: "grid grid-cols-7 gap-[2px]", children: cells }, `row-${r}`)
2919
+ );
2920
+ }
2921
+ return rows;
2922
+ })()
2398
2923
  ] })
2399
2924
  ]
2400
2925
  }
2401
2926
  );
2402
2927
  });
2403
2928
  Calendar.displayName = "Calendar";
2929
+
2930
+ // src/patterns/DatePicker/DatePicker.tsx
2931
+ import * as RadixPopover2 from "@radix-ui/react-popover";
2932
+ import { forwardRef as forwardRef41, useState as useState9 } from "react";
2933
+ import { jsx as jsx43, jsxs as jsxs36 } from "react/jsx-runtime";
2404
2934
  var defaultFormat = (d) => d.toLocaleDateString();
2405
- var DatePicker = forwardRef(function DatePicker2({
2935
+ var DatePicker = forwardRef41(function DatePicker2({
2406
2936
  value: valueProp,
2407
2937
  defaultValue,
2408
2938
  onValueChange,
@@ -2416,14 +2946,14 @@ var DatePicker = forwardRef(function DatePicker2({
2416
2946
  id,
2417
2947
  name
2418
2948
  }, ref) {
2419
- const [open, setOpen] = useState(false);
2949
+ const [open, setOpen] = useState9(false);
2420
2950
  const [value, setValue] = useControllableState({
2421
2951
  value: valueProp,
2422
2952
  defaultValue,
2423
2953
  onChange: onValueChange
2424
2954
  });
2425
- return /* @__PURE__ */ jsxs(RadixPopover.Root, { open, onOpenChange: setOpen, children: [
2426
- /* @__PURE__ */ jsx(RadixPopover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
2955
+ return /* @__PURE__ */ jsxs36(RadixPopover2.Root, { open, onOpenChange: setOpen, children: [
2956
+ /* @__PURE__ */ jsx43(RadixPopover2.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs36(
2427
2957
  "button",
2428
2958
  {
2429
2959
  ref,
@@ -2440,24 +2970,24 @@ var DatePicker = forwardRef(function DatePicker2({
2440
2970
  ),
2441
2971
  style: { width },
2442
2972
  children: [
2443
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-text-dim", children: "\u25A2" }),
2444
- /* @__PURE__ */ jsx("span", { className: cn("flex-1 truncate", !value && "text-text-dim"), children: value ? format(value) : emptyLabel ?? placeholder })
2973
+ /* @__PURE__ */ jsx43("span", { "aria-hidden": true, className: "text-text-dim", children: "\u25A2" }),
2974
+ /* @__PURE__ */ jsx43("span", { className: cn("flex-1 truncate", !value && "text-text-dim"), children: value ? format(value) : emptyLabel ?? placeholder })
2445
2975
  ]
2446
2976
  }
2447
2977
  ) }),
2448
- /* @__PURE__ */ jsx(RadixPopover.Portal, { children: /* @__PURE__ */ jsx(
2449
- RadixPopover.Content,
2978
+ /* @__PURE__ */ jsx43(RadixPopover2.Portal, { children: /* @__PURE__ */ jsx43(
2979
+ RadixPopover2.Content,
2450
2980
  {
2451
2981
  align: "start",
2452
2982
  sideOffset: 6,
2453
- className: "z-40 outline-none data-[state=open]:animate-[ship-pop-in_140ms_var(--easing-out)]",
2454
- children: /* @__PURE__ */ jsx(
2983
+ className: "z-popover outline-none data-[state=open]:animate-[ship-pop-in_140ms_var(--easing-out)]",
2984
+ children: /* @__PURE__ */ jsx43(
2455
2985
  Calendar,
2456
2986
  {
2457
- selected: value,
2987
+ value,
2458
2988
  defaultMonth: value?.getMonth(),
2459
2989
  defaultYear: value?.getFullYear(),
2460
- onSelect: (date) => {
2990
+ onValueChange: (date) => {
2461
2991
  setValue(date);
2462
2992
  setOpen(false);
2463
2993
  },
@@ -2466,13 +2996,17 @@ var DatePicker = forwardRef(function DatePicker2({
2466
2996
  )
2467
2997
  }
2468
2998
  ) }),
2469
- name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: value ? value.toISOString() : "", readOnly: true })
2999
+ name && /* @__PURE__ */ jsx43("input", { type: "hidden", name, value: value ? value.toISOString() : "", readOnly: true })
2470
3000
  ] });
2471
3001
  });
2472
3002
  DatePicker.displayName = "DatePicker";
2473
- var Dots = forwardRef(function Dots2({ total, current, onChange, className, "aria-label": ariaLabel = "Progress", ...props }, ref) {
3003
+
3004
+ // src/patterns/Dots/Dots.tsx
3005
+ import { forwardRef as forwardRef42 } from "react";
3006
+ import { jsx as jsx44 } from "react/jsx-runtime";
3007
+ var Dots = forwardRef42(function Dots2({ total, current, onChange, className, "aria-label": ariaLabel = "Progress", ...props }, ref) {
2474
3008
  const interactive = typeof onChange === "function";
2475
- return /* @__PURE__ */ jsx(
3009
+ return /* @__PURE__ */ jsx44(
2476
3010
  "nav",
2477
3011
  {
2478
3012
  ref,
@@ -2486,7 +3020,7 @@ var Dots = forwardRef(function Dots2({ total, current, onChange, className, "ari
2486
3020
  isActive ? "w-[18px] bg-accent" : "w-[6px] bg-panel-2"
2487
3021
  );
2488
3022
  if (interactive) {
2489
- return /* @__PURE__ */ jsx(
3023
+ return /* @__PURE__ */ jsx44(
2490
3024
  "button",
2491
3025
  {
2492
3026
  type: "button",
@@ -2503,24 +3037,31 @@ var Dots = forwardRef(function Dots2({ total, current, onChange, className, "ari
2503
3037
  i
2504
3038
  );
2505
3039
  }
2506
- return /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: sharedClass }, i);
3040
+ return /* @__PURE__ */ jsx44("span", { "aria-hidden": true, className: sharedClass }, i);
2507
3041
  })
2508
3042
  }
2509
3043
  );
2510
3044
  });
2511
3045
  Dots.displayName = "Dots";
2512
- var plateStyles = cva("grid h-12 w-12 place-items-center rounded-base text-[22px]", {
3046
+
3047
+ // src/patterns/EmptyState/EmptyState.tsx
3048
+ import { cva as cva10 } from "class-variance-authority";
3049
+ import { forwardRef as forwardRef43 } from "react";
3050
+ import { jsx as jsx45, jsxs as jsxs37 } from "react/jsx-runtime";
3051
+ var plateStyles = cva10("grid h-12 w-12 place-items-center rounded-base text-[22px]", {
2513
3052
  variants: {
2514
3053
  tone: {
3054
+ neutral: "bg-panel-2 text-text-muted",
2515
3055
  accent: "bg-accent-dim text-accent",
2516
- danger: "bg-[color-mix(in_oklab,var(--color-err),transparent_85%)] text-err",
2517
- muted: "bg-panel-2 text-text-muted"
3056
+ ok: "bg-[color-mix(in_oklab,var(--color-ok),transparent_85%)] text-ok",
3057
+ warn: "bg-[color-mix(in_oklab,var(--color-warn),transparent_85%)] text-warn",
3058
+ err: "bg-[color-mix(in_oklab,var(--color-err),transparent_85%)] text-err"
2518
3059
  }
2519
3060
  },
2520
- defaultVariants: { tone: "accent" }
3061
+ defaultVariants: { tone: "neutral" }
2521
3062
  });
2522
- var EmptyState = forwardRef(function EmptyState2({ icon, title, description, action, chips, tone, className, ...props }, ref) {
2523
- return /* @__PURE__ */ jsxs(
3063
+ var EmptyState = forwardRef43(function EmptyState2({ icon, title, description, action, chips, tone, className, ...props }, ref) {
3064
+ return /* @__PURE__ */ jsxs37(
2524
3065
  "div",
2525
3066
  {
2526
3067
  ref,
@@ -2530,10 +3071,10 @@ var EmptyState = forwardRef(function EmptyState2({ icon, title, description, act
2530
3071
  ),
2531
3072
  ...props,
2532
3073
  children: [
2533
- icon != null && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: plateStyles({ tone }), children: icon }),
2534
- /* @__PURE__ */ jsx("div", { className: "text-[14px] font-medium", children: title }),
2535
- description && /* @__PURE__ */ jsx("div", { className: "text-text-muted max-w-[260px] text-[12px] leading-[1.5]", children: description }),
2536
- chips && chips.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col gap-1", children: chips.map((c, i) => /* @__PURE__ */ jsx(
3074
+ icon != null && /* @__PURE__ */ jsx45("span", { "aria-hidden": true, className: plateStyles({ tone: tone ?? "neutral" }), children: icon }),
3075
+ /* @__PURE__ */ jsx45("div", { className: "text-[14px] font-medium", children: title }),
3076
+ description && /* @__PURE__ */ jsx45("div", { className: "text-text-muted max-w-[260px] text-[12px] leading-[1.5]", children: description }),
3077
+ chips && chips.length > 0 && /* @__PURE__ */ jsx45("div", { className: "flex w-full flex-col gap-1", children: chips.map((c, i) => /* @__PURE__ */ jsx45(
2537
3078
  "button",
2538
3079
  {
2539
3080
  type: "button",
@@ -2553,16 +3094,20 @@ var EmptyState = forwardRef(function EmptyState2({ icon, title, description, act
2553
3094
  );
2554
3095
  });
2555
3096
  EmptyState.displayName = "EmptyState";
3097
+
3098
+ // src/patterns/FileChip/FileChip.tsx
3099
+ import { forwardRef as forwardRef44 } from "react";
3100
+ import { jsx as jsx46, jsxs as jsxs38 } from "react/jsx-runtime";
2556
3101
  function deriveExt(name) {
2557
3102
  const dot = name.lastIndexOf(".");
2558
3103
  if (dot < 0) return "FILE";
2559
3104
  return name.slice(dot + 1).slice(0, 4).toUpperCase();
2560
3105
  }
2561
- var FileChip = forwardRef(function FileChip2({ name, size, progress, icon, onRemove, failed, className, ...props }, ref) {
3106
+ var FileChip = forwardRef44(function FileChip2({ name, size, progress, icon, onRemove, failed, className, ...props }, ref) {
2562
3107
  const ext = deriveExt(name);
2563
3108
  const showProgress = typeof progress === "number";
2564
3109
  const isComplete = showProgress && progress >= 100;
2565
- return /* @__PURE__ */ jsxs(
3110
+ return /* @__PURE__ */ jsxs38(
2566
3111
  "div",
2567
3112
  {
2568
3113
  ref,
@@ -2572,7 +3117,7 @@ var FileChip = forwardRef(function FileChip2({ name, size, progress, icon, onRem
2572
3117
  ),
2573
3118
  ...props,
2574
3119
  children: [
2575
- /* @__PURE__ */ jsx(
3120
+ /* @__PURE__ */ jsx46(
2576
3121
  "span",
2577
3122
  {
2578
3123
  "aria-hidden": true,
@@ -2580,17 +3125,17 @@ var FileChip = forwardRef(function FileChip2({ name, size, progress, icon, onRem
2580
3125
  children: icon ?? ext
2581
3126
  }
2582
3127
  ),
2583
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
2584
- /* @__PURE__ */ jsx("div", { className: "truncate text-[12px] font-medium", children: name }),
2585
- /* @__PURE__ */ jsxs("div", { className: cn("font-mono text-[10px]", failed ? "text-err" : "text-text-dim"), children: [
3128
+ /* @__PURE__ */ jsxs38("div", { className: "min-w-0 flex-1", children: [
3129
+ /* @__PURE__ */ jsx46("div", { className: "truncate text-[12px] font-medium", children: name }),
3130
+ /* @__PURE__ */ jsxs38("div", { className: cn("font-mono text-[10px]", failed ? "text-err" : "text-text-dim"), children: [
2586
3131
  size,
2587
- showProgress && !isComplete && /* @__PURE__ */ jsxs("span", { children: [
3132
+ showProgress && !isComplete && /* @__PURE__ */ jsxs38("span", { children: [
2588
3133
  " \xB7 ",
2589
3134
  Math.round(progress),
2590
3135
  "%"
2591
3136
  ] })
2592
3137
  ] }),
2593
- showProgress && !isComplete && /* @__PURE__ */ jsx("div", { className: "bg-panel mt-1 h-[2px] overflow-hidden rounded-full", children: /* @__PURE__ */ jsx(
3138
+ showProgress && !isComplete && /* @__PURE__ */ jsx46("div", { className: "bg-panel mt-1 h-[2px] overflow-hidden rounded-full", children: /* @__PURE__ */ jsx46(
2594
3139
  "div",
2595
3140
  {
2596
3141
  className: cn(
@@ -2601,7 +3146,7 @@ var FileChip = forwardRef(function FileChip2({ name, size, progress, icon, onRem
2601
3146
  }
2602
3147
  ) })
2603
3148
  ] }),
2604
- onRemove && /* @__PURE__ */ jsx(
3149
+ onRemove && /* @__PURE__ */ jsx46(
2605
3150
  "button",
2606
3151
  {
2607
3152
  type: "button",
@@ -2619,8 +3164,13 @@ var FileChip = forwardRef(function FileChip2({ name, size, progress, icon, onRem
2619
3164
  );
2620
3165
  });
2621
3166
  FileChip.displayName = "FileChip";
2622
- var Menubar = forwardRef(function Menubar2({ className, ...props }, ref) {
2623
- return /* @__PURE__ */ jsx(
3167
+
3168
+ // src/patterns/Menubar/Menubar.tsx
3169
+ import * as RadixMenubar from "@radix-ui/react-menubar";
3170
+ import { forwardRef as forwardRef45 } from "react";
3171
+ import { jsx as jsx47, jsxs as jsxs39 } from "react/jsx-runtime";
3172
+ var Menubar = forwardRef45(function Menubar2({ className, ...props }, ref) {
3173
+ return /* @__PURE__ */ jsx47(
2624
3174
  RadixMenubar.Root,
2625
3175
  {
2626
3176
  ref,
@@ -2634,9 +3184,9 @@ var Menubar = forwardRef(function Menubar2({ className, ...props }, ref) {
2634
3184
  });
2635
3185
  Menubar.displayName = "Menubar";
2636
3186
  var MenubarMenu = RadixMenubar.Menu;
2637
- var MenubarTrigger = forwardRef(
3187
+ var MenubarTrigger = forwardRef45(
2638
3188
  function MenubarTrigger2({ className, ...props }, ref) {
2639
- return /* @__PURE__ */ jsx(
3189
+ return /* @__PURE__ */ jsx47(
2640
3190
  RadixMenubar.Trigger,
2641
3191
  {
2642
3192
  ref,
@@ -2653,16 +3203,16 @@ var MenubarTrigger = forwardRef(
2653
3203
  }
2654
3204
  );
2655
3205
  MenubarTrigger.displayName = "MenubarTrigger";
2656
- var MenubarContent = forwardRef(
3206
+ var MenubarContent = forwardRef45(
2657
3207
  function MenubarContent2({ className, sideOffset = 6, align = "start", ...props }, ref) {
2658
- return /* @__PURE__ */ jsx(RadixMenubar.Portal, { children: /* @__PURE__ */ jsx(
3208
+ return /* @__PURE__ */ jsx47(RadixMenubar.Portal, { children: /* @__PURE__ */ jsx47(
2659
3209
  RadixMenubar.Content,
2660
3210
  {
2661
3211
  ref,
2662
3212
  sideOffset,
2663
3213
  align,
2664
3214
  className: cn(
2665
- "border-border-strong bg-panel z-40 min-w-[180px] rounded-md border p-1 shadow-lg outline-none",
3215
+ "border-border-strong bg-panel z-popover min-w-[180px] rounded-md border p-1 shadow-lg outline-none",
2666
3216
  "data-[state=open]:animate-[ship-pop-in_140ms_var(--easing-out)]",
2667
3217
  className
2668
3218
  ),
@@ -2677,24 +3227,24 @@ var itemBase3 = cn(
2677
3227
  "data-[highlighted]:bg-panel-2",
2678
3228
  "data-[disabled]:opacity-40 data-[disabled]:cursor-not-allowed"
2679
3229
  );
2680
- var MenubarItem = forwardRef(function MenubarItem2({ trailing, destructive, className, children, ...props }, ref) {
2681
- return /* @__PURE__ */ jsxs(
3230
+ var MenubarItem = forwardRef45(function MenubarItem2({ trailing, destructive, className, children, ...props }, ref) {
3231
+ return /* @__PURE__ */ jsxs39(
2682
3232
  RadixMenubar.Item,
2683
3233
  {
2684
3234
  ref,
2685
3235
  className: cn(itemBase3, destructive ? "text-err" : "text-text", className),
2686
3236
  ...props,
2687
3237
  children: [
2688
- /* @__PURE__ */ jsx("span", { className: "flex-1", children }),
2689
- trailing && /* @__PURE__ */ jsx("span", { className: "text-text-dim font-mono text-[10px]", children: trailing })
3238
+ /* @__PURE__ */ jsx47("span", { className: "flex-1", children }),
3239
+ trailing && /* @__PURE__ */ jsx47("span", { className: "text-text-dim font-mono text-[10px]", children: trailing })
2690
3240
  ]
2691
3241
  }
2692
3242
  );
2693
3243
  });
2694
3244
  MenubarItem.displayName = "MenubarItem";
2695
- var MenubarSeparator = forwardRef(
3245
+ var MenubarSeparator = forwardRef45(
2696
3246
  function MenubarSeparator2({ className, ...props }, ref) {
2697
- return /* @__PURE__ */ jsx(
3247
+ return /* @__PURE__ */ jsx47(
2698
3248
  RadixMenubar.Separator,
2699
3249
  {
2700
3250
  ref,
@@ -2705,6 +3255,10 @@ var MenubarSeparator = forwardRef(
2705
3255
  }
2706
3256
  );
2707
3257
  MenubarSeparator.displayName = "MenubarSeparator";
3258
+
3259
+ // src/patterns/Pagination/Pagination.tsx
3260
+ import { forwardRef as forwardRef46 } from "react";
3261
+ import { jsx as jsx48, jsxs as jsxs40 } from "react/jsx-runtime";
2708
3262
  function buildRange(page, total, siblings) {
2709
3263
  if (total <= 0) return [];
2710
3264
  const items = [];
@@ -2717,9 +3271,9 @@ function buildRange(page, total, siblings) {
2717
3271
  if (total > 1) items.push(total);
2718
3272
  return items;
2719
3273
  }
2720
- var Pagination = forwardRef(function Pagination2({ page, total, onPageChange, siblings = 1, className, ...props }, ref) {
3274
+ var Pagination = forwardRef46(function Pagination2({ page, total, onPageChange, siblings = 1, className, ...props }, ref) {
2721
3275
  const items = buildRange(page, total, siblings);
2722
- return /* @__PURE__ */ jsxs(
3276
+ return /* @__PURE__ */ jsxs40(
2723
3277
  "nav",
2724
3278
  {
2725
3279
  ref,
@@ -2727,7 +3281,7 @@ var Pagination = forwardRef(function Pagination2({ page, total, onPageChange, si
2727
3281
  className: cn("inline-flex items-center gap-1", className),
2728
3282
  ...props,
2729
3283
  children: [
2730
- /* @__PURE__ */ jsx(
3284
+ /* @__PURE__ */ jsx48(
2731
3285
  IconButton,
2732
3286
  {
2733
3287
  size: "sm",
@@ -2740,7 +3294,7 @@ var Pagination = forwardRef(function Pagination2({ page, total, onPageChange, si
2740
3294
  ),
2741
3295
  items.map((item, i) => {
2742
3296
  if (item === "start-ellipsis" || item === "end-ellipsis") {
2743
- return /* @__PURE__ */ jsx(
3297
+ return /* @__PURE__ */ jsx48(
2744
3298
  "span",
2745
3299
  {
2746
3300
  "aria-hidden": true,
@@ -2751,7 +3305,7 @@ var Pagination = forwardRef(function Pagination2({ page, total, onPageChange, si
2751
3305
  );
2752
3306
  }
2753
3307
  const isActive = item === page;
2754
- return /* @__PURE__ */ jsx(
3308
+ return /* @__PURE__ */ jsx48(
2755
3309
  "button",
2756
3310
  {
2757
3311
  type: "button",
@@ -2769,7 +3323,7 @@ var Pagination = forwardRef(function Pagination2({ page, total, onPageChange, si
2769
3323
  item
2770
3324
  );
2771
3325
  }),
2772
- /* @__PURE__ */ jsx(
3326
+ /* @__PURE__ */ jsx48(
2773
3327
  IconButton,
2774
3328
  {
2775
3329
  size: "sm",
@@ -2785,7 +3339,12 @@ var Pagination = forwardRef(function Pagination2({ page, total, onPageChange, si
2785
3339
  );
2786
3340
  });
2787
3341
  Pagination.displayName = "Pagination";
2788
- var trackStyles = cva("w-full rounded-full bg-panel-2 overflow-hidden", {
3342
+
3343
+ // src/patterns/Progress/Progress.tsx
3344
+ import { cva as cva11 } from "class-variance-authority";
3345
+ import { forwardRef as forwardRef47 } from "react";
3346
+ import { jsx as jsx49, jsxs as jsxs41 } from "react/jsx-runtime";
3347
+ var trackStyles = cva11("w-full rounded-full bg-panel-2 overflow-hidden", {
2789
3348
  variants: {
2790
3349
  size: {
2791
3350
  sm: "h-[3px]",
@@ -2795,7 +3354,7 @@ var trackStyles = cva("w-full rounded-full bg-panel-2 overflow-hidden", {
2795
3354
  },
2796
3355
  defaultVariants: { size: "md" }
2797
3356
  });
2798
- var fillStyles = cva("h-full rounded-full transition-[width] duration-(--duration-step)", {
3357
+ var fillStyles = cva11("h-full rounded-full transition-[width] duration-(--duration-step)", {
2799
3358
  variants: {
2800
3359
  tone: {
2801
3360
  accent: "bg-accent",
@@ -2806,7 +3365,7 @@ var fillStyles = cva("h-full rounded-full transition-[width] duration-(--duratio
2806
3365
  },
2807
3366
  defaultVariants: { tone: "accent" }
2808
3367
  });
2809
- var Progress = forwardRef(function Progress2({
3368
+ var Progress = forwardRef47(function Progress2({
2810
3369
  value = 0,
2811
3370
  max = 100,
2812
3371
  indeterminate = false,
@@ -2820,15 +3379,15 @@ var Progress = forwardRef(function Progress2({
2820
3379
  const clamped = Math.min(max, Math.max(0, value));
2821
3380
  const pct = max > 0 ? clamped / max * 100 : 0;
2822
3381
  const display = Math.round(pct);
2823
- return /* @__PURE__ */ jsxs("div", { ref, className: cn("flex w-full flex-col gap-2", className), ...props, children: [
2824
- label != null && /* @__PURE__ */ jsxs("div", { className: "flex text-[12px]", children: [
2825
- /* @__PURE__ */ jsx("span", { className: "text-text-muted", children: label }),
2826
- showValue && !indeterminate && /* @__PURE__ */ jsxs("span", { className: "text-text ml-auto font-mono tabular-nums", children: [
3382
+ return /* @__PURE__ */ jsxs41("div", { ref, className: cn("flex w-full flex-col gap-2", className), ...props, children: [
3383
+ label != null && /* @__PURE__ */ jsxs41("div", { className: "flex text-[12px]", children: [
3384
+ /* @__PURE__ */ jsx49("span", { className: "text-text-muted", children: label }),
3385
+ showValue && !indeterminate && /* @__PURE__ */ jsxs41("span", { className: "text-text ml-auto font-mono tabular-nums", children: [
2827
3386
  display,
2828
3387
  "%"
2829
3388
  ] })
2830
3389
  ] }),
2831
- /* @__PURE__ */ jsx(
3390
+ /* @__PURE__ */ jsx49(
2832
3391
  "div",
2833
3392
  {
2834
3393
  role: "progressbar",
@@ -2837,7 +3396,7 @@ var Progress = forwardRef(function Progress2({
2837
3396
  "aria-valuenow": indeterminate ? void 0 : display,
2838
3397
  "aria-label": typeof label === "string" ? label : void 0,
2839
3398
  className: trackStyles({ size }),
2840
- children: indeterminate ? /* @__PURE__ */ jsx(
3399
+ children: indeterminate ? /* @__PURE__ */ jsx49(
2841
3400
  "span",
2842
3401
  {
2843
3402
  "aria-hidden": true,
@@ -2847,19 +3406,23 @@ var Progress = forwardRef(function Progress2({
2847
3406
  "animate-[ship-indeterminate_1.4s_linear_infinite]"
2848
3407
  )
2849
3408
  }
2850
- ) : /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: fillStyles({ tone }), style: { width: `${pct}%` } })
3409
+ ) : /* @__PURE__ */ jsx49("span", { "aria-hidden": true, className: fillStyles({ tone }), style: { width: `${pct}%` } })
2851
3410
  }
2852
3411
  )
2853
3412
  ] });
2854
3413
  });
2855
3414
  Progress.displayName = "Progress";
3415
+
3416
+ // src/patterns/RadialProgress/RadialProgress.tsx
3417
+ import { forwardRef as forwardRef48 } from "react";
3418
+ import { jsx as jsx50, jsxs as jsxs42 } from "react/jsx-runtime";
2856
3419
  var toneStrokeClass = {
2857
3420
  accent: "stroke-accent",
2858
3421
  ok: "stroke-ok",
2859
3422
  warn: "stroke-warn",
2860
3423
  err: "stroke-err"
2861
3424
  };
2862
- var RadialProgress = forwardRef(
3425
+ var RadialProgress = forwardRef48(
2863
3426
  function RadialProgress2({
2864
3427
  value,
2865
3428
  max = 100,
@@ -2877,7 +3440,7 @@ var RadialProgress = forwardRef(
2877
3440
  const c = 2 * Math.PI * r;
2878
3441
  const dash = pct / 100 * c;
2879
3442
  const resolvedTone = tone ?? (clamped >= max ? "ok" : "accent");
2880
- return /* @__PURE__ */ jsxs(
3443
+ return /* @__PURE__ */ jsxs42(
2881
3444
  "div",
2882
3445
  {
2883
3446
  ref,
@@ -2890,8 +3453,8 @@ var RadialProgress = forwardRef(
2890
3453
  style: { width: size, height: size },
2891
3454
  ...props,
2892
3455
  children: [
2893
- /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, children: [
2894
- /* @__PURE__ */ jsx(
3456
+ /* @__PURE__ */ jsxs42("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, children: [
3457
+ /* @__PURE__ */ jsx50(
2895
3458
  "circle",
2896
3459
  {
2897
3460
  cx: size / 2,
@@ -2902,7 +3465,7 @@ var RadialProgress = forwardRef(
2902
3465
  className: "stroke-panel-2"
2903
3466
  }
2904
3467
  ),
2905
- /* @__PURE__ */ jsx(
3468
+ /* @__PURE__ */ jsx50(
2906
3469
  "circle",
2907
3470
  {
2908
3471
  cx: size / 2,
@@ -2920,15 +3483,19 @@ var RadialProgress = forwardRef(
2920
3483
  }
2921
3484
  )
2922
3485
  ] }),
2923
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0 grid place-items-center font-mono text-[11px] font-medium tabular-nums", children: children ?? `${Math.round(pct)}%` })
3486
+ /* @__PURE__ */ jsx50("div", { className: "absolute inset-0 grid place-items-center font-mono text-[11px] font-medium tabular-nums", children: children ?? `${Math.round(pct)}%` })
2924
3487
  ]
2925
3488
  }
2926
3489
  );
2927
3490
  }
2928
3491
  );
2929
3492
  RadialProgress.displayName = "RadialProgress";
2930
- var Sidebar = forwardRef(function Sidebar2({ width = 240, className, style, ...props }, ref) {
2931
- return /* @__PURE__ */ jsx(
3493
+
3494
+ // src/patterns/Sidebar/Sidebar.tsx
3495
+ import { forwardRef as forwardRef49 } from "react";
3496
+ import { Fragment as Fragment2, jsx as jsx51, jsxs as jsxs43 } from "react/jsx-runtime";
3497
+ var Sidebar = forwardRef49(function Sidebar2({ width = 240, className, style, ...props }, ref) {
3498
+ return /* @__PURE__ */ jsx51(
2932
3499
  "aside",
2933
3500
  {
2934
3501
  ref,
@@ -2942,76 +3509,75 @@ var Sidebar = forwardRef(function Sidebar2({ width = 240, className, style, ...p
2942
3509
  );
2943
3510
  });
2944
3511
  Sidebar.displayName = "Sidebar";
2945
- var NavItem = forwardRef(function NavItem2({ icon, label, active, badge, href, disabled, className, onClick, ...props }, ref) {
2946
- const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
2947
- icon && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "w-[14px] text-center opacity-80", children: icon }),
2948
- /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: label }),
2949
- badge != null && /* @__PURE__ */ jsx(
2950
- "span",
2951
- {
2952
- className: cn(
2953
- "rounded-xs px-[6px] py-px font-mono text-[10px]",
2954
- active ? "bg-accent text-on-accent" : "bg-panel-2 text-text-muted"
2955
- ),
2956
- children: badge
2957
- }
2958
- )
2959
- ] });
2960
- const baseClass = cn(
2961
- "flex cursor-pointer items-center gap-[10px] rounded-xs px-2 py-[6px] text-[13px] outline-none",
2962
- "transition-colors duration-(--duration-micro)",
2963
- "focus-visible:ring-[3px] focus-visible:ring-accent-dim",
2964
- active ? "bg-accent-dim text-accent" : "text-text hover:bg-panel-2",
2965
- disabled && "opacity-50 pointer-events-none",
2966
- className
2967
- );
2968
- if (href) {
2969
- return /* @__PURE__ */ jsx(
2970
- "a",
3512
+ var NavItem = forwardRef49(
3513
+ function NavItem2({ icon, label, active, badge, href, disabled, className, ...props }, ref) {
3514
+ const inner = /* @__PURE__ */ jsxs43(Fragment2, { children: [
3515
+ icon && /* @__PURE__ */ jsx51("span", { "aria-hidden": true, className: "w-[14px] text-center opacity-80", children: icon }),
3516
+ /* @__PURE__ */ jsx51("span", { className: "flex-1 truncate", children: label }),
3517
+ badge != null && /* @__PURE__ */ jsx51(
3518
+ "span",
3519
+ {
3520
+ className: cn(
3521
+ "rounded-xs px-[6px] py-px font-mono text-[10px]",
3522
+ active ? "bg-accent text-on-accent" : "bg-panel-2 text-text-muted"
3523
+ ),
3524
+ children: badge
3525
+ }
3526
+ )
3527
+ ] });
3528
+ const baseClass = cn(
3529
+ "flex cursor-pointer items-center gap-[10px] rounded-xs px-2 py-[6px] text-[13px] outline-none",
3530
+ "transition-colors duration-(--duration-micro)",
3531
+ "focus-visible:ring-[3px] focus-visible:ring-accent-dim",
3532
+ active ? "bg-accent-dim text-accent" : "text-text hover:bg-panel-2",
3533
+ disabled && "opacity-50 pointer-events-none",
3534
+ className
3535
+ );
3536
+ if (href) {
3537
+ const anchorProps = props;
3538
+ return /* @__PURE__ */ jsx51(
3539
+ "a",
3540
+ {
3541
+ ref,
3542
+ href,
3543
+ "aria-current": active ? "page" : void 0,
3544
+ "aria-disabled": disabled || void 0,
3545
+ className: baseClass,
3546
+ ...anchorProps,
3547
+ children: inner
3548
+ }
3549
+ );
3550
+ }
3551
+ const buttonProps = props;
3552
+ return /* @__PURE__ */ jsx51(
3553
+ "button",
2971
3554
  {
2972
3555
  ref,
2973
- href,
3556
+ type: "button",
2974
3557
  "aria-current": active ? "page" : void 0,
2975
- "aria-disabled": disabled || void 0,
2976
- className: baseClass,
2977
- onClick,
2978
- ...props,
3558
+ disabled,
3559
+ className: cn(baseClass, "w-full text-left"),
3560
+ ...buttonProps,
2979
3561
  children: inner
2980
3562
  }
2981
3563
  );
2982
3564
  }
2983
- return /* @__PURE__ */ jsx(
2984
- "a",
2985
- {
2986
- ref,
2987
- role: "button",
2988
- tabIndex: disabled ? -1 : 0,
2989
- "aria-current": active ? "page" : void 0,
2990
- "aria-disabled": disabled || void 0,
2991
- className: baseClass,
2992
- onClick,
2993
- onKeyDown: (e) => {
2994
- if (e.key === "Enter" || e.key === " ") {
2995
- e.preventDefault();
2996
- e.currentTarget.click();
2997
- }
2998
- },
2999
- ...props,
3000
- children: inner
3001
- }
3002
- );
3003
- });
3565
+ );
3004
3566
  NavItem.displayName = "NavItem";
3005
- var NavSection = forwardRef(function NavSection2({ label, action, className, children, ...props }, ref) {
3006
- return /* @__PURE__ */ jsxs("div", { ref, className: cn("flex flex-col gap-1", className), ...props, children: [
3007
- /* @__PURE__ */ jsxs("div", { className: "text-text-dim flex items-center px-2 pt-2 font-mono text-[9px] tracking-[1.4px] uppercase", children: [
3008
- /* @__PURE__ */ jsx("span", { className: "flex-1", children: label }),
3567
+ var NavSection = forwardRef49(function NavSection2({ label, action, className, children, ...props }, ref) {
3568
+ return /* @__PURE__ */ jsxs43("div", { ref, className: cn("flex flex-col gap-1", className), ...props, children: [
3569
+ /* @__PURE__ */ jsxs43("div", { className: "text-text-dim flex items-center px-2 pt-2 font-mono text-[9px] tracking-[1.4px] uppercase", children: [
3570
+ /* @__PURE__ */ jsx51("span", { className: "flex-1", children: label }),
3009
3571
  action
3010
3572
  ] }),
3011
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[2px]", children })
3573
+ /* @__PURE__ */ jsx51("div", { className: "flex flex-col gap-[2px]", children })
3012
3574
  ] });
3013
3575
  });
3014
3576
  NavSection.displayName = "NavSection";
3577
+
3578
+ // src/patterns/Sparkline/Sparkline.tsx
3579
+ import { forwardRef as forwardRef50, useMemo as useMemo5 } from "react";
3580
+ import { jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
3015
3581
  function buildPath(values, w, h) {
3016
3582
  if (values.length === 0) return { line: "", area: "" };
3017
3583
  const pad = 2;
@@ -3030,7 +3596,7 @@ function buildPath(values, w, h) {
3030
3596
  )} L${pad.toFixed(2)},${(h - pad).toFixed(2)} Z`;
3031
3597
  return { line, area };
3032
3598
  }
3033
- var Sparkline = forwardRef(function Sparkline2({
3599
+ var Sparkline = forwardRef50(function Sparkline2({
3034
3600
  values,
3035
3601
  width = 160,
3036
3602
  height = 32,
@@ -3041,8 +3607,8 @@ var Sparkline = forwardRef(function Sparkline2({
3041
3607
  "aria-label": ariaLabel = "Trend",
3042
3608
  ...props
3043
3609
  }, ref) {
3044
- const { line, area } = useMemo(() => buildPath(values, width, height), [values, width, height]);
3045
- return /* @__PURE__ */ jsxs(
3610
+ const { line, area } = useMemo5(() => buildPath(values, width, height), [values, width, height]);
3611
+ return /* @__PURE__ */ jsxs44(
3046
3612
  "svg",
3047
3613
  {
3048
3614
  ref,
@@ -3054,8 +3620,8 @@ var Sparkline = forwardRef(function Sparkline2({
3054
3620
  className: cn("inline-block", className),
3055
3621
  ...props,
3056
3622
  children: [
3057
- fill && /* @__PURE__ */ jsx("path", { d: area, fill: stroke, fillOpacity: 0.16, stroke: "none" }),
3058
- /* @__PURE__ */ jsx(
3623
+ fill && /* @__PURE__ */ jsx52("path", { d: area, fill: stroke, fillOpacity: 0.16, stroke: "none" }),
3624
+ /* @__PURE__ */ jsx52(
3059
3625
  "path",
3060
3626
  {
3061
3627
  d: line,
@@ -3071,14 +3637,18 @@ var Sparkline = forwardRef(function Sparkline2({
3071
3637
  );
3072
3638
  });
3073
3639
  Sparkline.displayName = "Sparkline";
3640
+
3641
+ // src/patterns/Spinner/Spinner.tsx
3642
+ import { forwardRef as forwardRef51 } from "react";
3643
+ import { jsx as jsx53 } from "react/jsx-runtime";
3074
3644
  var sizes = {
3075
3645
  sm: { box: "h-3 w-3", border: "border-[2px]" },
3076
3646
  md: { box: "h-4 w-4", border: "border-[2px]" },
3077
3647
  lg: { box: "h-5 w-5", border: "border-[2px]" }
3078
3648
  };
3079
- var Spinner2 = forwardRef(function Spinner3({ size = "md", label = "Loading", className, ...props }, ref) {
3649
+ var Spinner2 = forwardRef51(function Spinner3({ size = "md", label = "Loading", className, ...props }, ref) {
3080
3650
  const s = sizes[size];
3081
- return /* @__PURE__ */ jsx(
3651
+ return /* @__PURE__ */ jsx53(
3082
3652
  "span",
3083
3653
  {
3084
3654
  ref,
@@ -3086,7 +3656,7 @@ var Spinner2 = forwardRef(function Spinner3({ size = "md", label = "Loading", cl
3086
3656
  "aria-label": label,
3087
3657
  className: cn("inline-block", className),
3088
3658
  ...props,
3089
- children: /* @__PURE__ */ jsx(
3659
+ children: /* @__PURE__ */ jsx53(
3090
3660
  "span",
3091
3661
  {
3092
3662
  "aria-hidden": true,
@@ -3101,6 +3671,10 @@ var Spinner2 = forwardRef(function Spinner3({ size = "md", label = "Loading", cl
3101
3671
  );
3102
3672
  });
3103
3673
  Spinner2.displayName = "Spinner";
3674
+
3675
+ // src/patterns/Stepper/Stepper.tsx
3676
+ import { forwardRef as forwardRef52, Fragment as Fragment3 } from "react";
3677
+ import { jsx as jsx54, jsxs as jsxs45 } from "react/jsx-runtime";
3104
3678
  var dotBase = "h-6 w-6 rounded-full grid place-items-center text-[11px] font-mono font-semibold border";
3105
3679
  var dotStateClass = {
3106
3680
  done: "bg-accent text-on-accent border-accent",
@@ -3117,46 +3691,52 @@ function stateFor(index, current) {
3117
3691
  if (index === current) return "current";
3118
3692
  return "upcoming";
3119
3693
  }
3120
- var Stepper = forwardRef(function Stepper2({ steps, current, className, ...props }, ref) {
3121
- return /* @__PURE__ */ jsx(
3122
- "div",
3694
+ var Stepper = forwardRef52(function Stepper2({ steps, current, className, ...props }, ref) {
3695
+ return /* @__PURE__ */ jsx54(
3696
+ "ol",
3123
3697
  {
3124
3698
  ref,
3125
- role: "list",
3126
3699
  "aria-label": "Progress",
3127
- className: cn("flex w-full items-center", className),
3700
+ className: cn("m-0 flex w-full list-none items-center p-0", className),
3128
3701
  ...props,
3129
- children: steps.map((label, i) => {
3702
+ children: steps.map((step, i) => {
3703
+ const label = typeof step === "string" ? step : step.label;
3704
+ const id = typeof step === "string" ? void 0 : step.id;
3130
3705
  const state = stateFor(i, current);
3131
3706
  const connectorActive = i < current;
3132
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
3133
- /* @__PURE__ */ jsxs(
3134
- "div",
3707
+ return /* @__PURE__ */ jsxs45(Fragment3, { children: [
3708
+ /* @__PURE__ */ jsxs45(
3709
+ "li",
3135
3710
  {
3136
- role: "listitem",
3137
3711
  "aria-current": state === "current" ? "step" : void 0,
3138
3712
  className: "flex items-center gap-2",
3139
3713
  children: [
3140
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn(dotBase, dotStateClass[state]), children: state === "done" ? "\u2713" : i + 1 }),
3141
- /* @__PURE__ */ jsx("span", { className: cn("text-[12px]", labelStateClass[state]), children: label })
3714
+ /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: cn(dotBase, dotStateClass[state]), children: state === "done" ? "\u2713" : i + 1 }),
3715
+ /* @__PURE__ */ jsx54("span", { className: cn("text-[12px]", labelStateClass[state]), children: label })
3142
3716
  ]
3143
3717
  }
3144
3718
  ),
3145
- i < steps.length - 1 && /* @__PURE__ */ jsx(
3719
+ i < steps.length - 1 && /* @__PURE__ */ jsx54(
3146
3720
  "span",
3147
3721
  {
3148
3722
  "aria-hidden": true,
3149
3723
  className: cn("mx-3 h-px flex-1", connectorActive ? "bg-accent" : "bg-border")
3150
3724
  }
3151
3725
  )
3152
- ] }, label);
3726
+ ] }, id ?? i);
3153
3727
  })
3154
3728
  }
3155
3729
  );
3156
3730
  });
3157
3731
  Stepper.displayName = "Stepper";
3158
- var TabsVariantContext = createContext("underline");
3159
- var tabsListStyles = cva("", {
3732
+
3733
+ // src/patterns/Tabs/Tabs.tsx
3734
+ import * as RadixTabs from "@radix-ui/react-tabs";
3735
+ import { cva as cva12 } from "class-variance-authority";
3736
+ import { createContext as createContext2, forwardRef as forwardRef53, useContext as useContext2 } from "react";
3737
+ import { jsx as jsx55 } from "react/jsx-runtime";
3738
+ var TabsVariantContext = createContext2("underline");
3739
+ var tabsListStyles = cva12("", {
3160
3740
  variants: {
3161
3741
  variant: {
3162
3742
  underline: "flex gap-6 border-b border-border",
@@ -3164,7 +3744,7 @@ var tabsListStyles = cva("", {
3164
3744
  }
3165
3745
  }
3166
3746
  });
3167
- var tabsTriggerStyles = cva(
3747
+ var tabsTriggerStyles = cva12(
3168
3748
  "cursor-pointer outline-none transition-colors duration-(--duration-micro) focus-visible:ring-[3px] focus-visible:ring-accent-dim",
3169
3749
  {
3170
3750
  variants: {
@@ -3185,8 +3765,8 @@ var tabsTriggerStyles = cva(
3185
3765
  }
3186
3766
  }
3187
3767
  );
3188
- var Tabs = forwardRef(function Tabs2({ variant = "underline", className, ...props }, ref) {
3189
- return /* @__PURE__ */ jsx(TabsVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx(
3768
+ var Tabs = forwardRef53(function Tabs2({ variant = "underline", className, ...props }, ref) {
3769
+ return /* @__PURE__ */ jsx55(TabsVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx55(
3190
3770
  RadixTabs.Root,
3191
3771
  {
3192
3772
  ref,
@@ -3196,14 +3776,14 @@ var Tabs = forwardRef(function Tabs2({ variant = "underline", className, ...prop
3196
3776
  ) });
3197
3777
  });
3198
3778
  Tabs.displayName = "Tabs";
3199
- var TabsList = forwardRef(function TabsList2({ className, ...props }, ref) {
3200
- const variant = useContext(TabsVariantContext);
3201
- return /* @__PURE__ */ jsx(RadixTabs.List, { ref, className: cn(tabsListStyles({ variant }), className), ...props });
3779
+ var TabsList = forwardRef53(function TabsList2({ className, ...props }, ref) {
3780
+ const variant = useContext2(TabsVariantContext);
3781
+ return /* @__PURE__ */ jsx55(RadixTabs.List, { ref, className: cn(tabsListStyles({ variant }), className), ...props });
3202
3782
  });
3203
3783
  TabsList.displayName = "TabsList";
3204
- var Tab = forwardRef(function Tab2({ className, ...props }, ref) {
3205
- const variant = useContext(TabsVariantContext);
3206
- return /* @__PURE__ */ jsx(
3784
+ var Tab = forwardRef53(function Tab2({ className, ...props }, ref) {
3785
+ const variant = useContext2(TabsVariantContext);
3786
+ return /* @__PURE__ */ jsx55(
3207
3787
  RadixTabs.Trigger,
3208
3788
  {
3209
3789
  ref,
@@ -3213,9 +3793,9 @@ var Tab = forwardRef(function Tab2({ className, ...props }, ref) {
3213
3793
  );
3214
3794
  });
3215
3795
  Tab.displayName = "Tab";
3216
- var TabsContent = forwardRef(
3796
+ var TabsContent = forwardRef53(
3217
3797
  function TabsContent2({ className, ...props }, ref) {
3218
- return /* @__PURE__ */ jsx(
3798
+ return /* @__PURE__ */ jsx55(
3219
3799
  RadixTabs.Content,
3220
3800
  {
3221
3801
  ref,
@@ -3229,6 +3809,10 @@ var TabsContent = forwardRef(
3229
3809
  }
3230
3810
  );
3231
3811
  TabsContent.displayName = "TabsContent";
3812
+
3813
+ // src/patterns/Timeline/Timeline.tsx
3814
+ import { forwardRef as forwardRef54 } from "react";
3815
+ import { jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
3232
3816
  var ringClass = {
3233
3817
  accent: "border-accent",
3234
3818
  ok: "border-ok",
@@ -3236,8 +3820,8 @@ var ringClass = {
3236
3820
  err: "border-err",
3237
3821
  muted: "border-text-dim"
3238
3822
  };
3239
- var Timeline = forwardRef(function Timeline2({ events, className, children, ...props }, ref) {
3240
- return /* @__PURE__ */ jsx(
3823
+ var Timeline = forwardRef54(function Timeline2({ events, className, children, ...props }, ref) {
3824
+ return /* @__PURE__ */ jsx56(
3241
3825
  "ol",
3242
3826
  {
3243
3827
  ref,
@@ -3247,14 +3831,14 @@ var Timeline = forwardRef(function Timeline2({ events, className, children, ...p
3247
3831
  className
3248
3832
  ),
3249
3833
  ...props,
3250
- children: events ? events.map((e, i) => /* @__PURE__ */ jsx(TimelineItem, { tone: e.tone, time: e.time, description: e.description, children: e.title }, i)) : children
3834
+ children: events ? events.map((e, i) => /* @__PURE__ */ jsx56(TimelineItem, { tone: e.tone, time: e.time, description: e.description, children: e.title }, i)) : children
3251
3835
  }
3252
3836
  );
3253
3837
  });
3254
3838
  Timeline.displayName = "Timeline";
3255
- var TimelineItem = forwardRef(function TimelineItem2({ tone = "accent", description, time, className, children, ...props }, ref) {
3256
- return /* @__PURE__ */ jsxs("li", { ref, className: cn("relative mb-[18px] last:mb-0", className), ...props, children: [
3257
- /* @__PURE__ */ jsx(
3839
+ var TimelineItem = forwardRef54(function TimelineItem2({ tone = "accent", description, time, className, children, ...props }, ref) {
3840
+ return /* @__PURE__ */ jsxs46("li", { ref, className: cn("relative mb-[18px] last:mb-0", className), ...props, children: [
3841
+ /* @__PURE__ */ jsx56(
3258
3842
  "span",
3259
3843
  {
3260
3844
  "aria-hidden": true,
@@ -3264,14 +3848,18 @@ var TimelineItem = forwardRef(function TimelineItem2({ tone = "accent", descript
3264
3848
  )
3265
3849
  }
3266
3850
  ),
3267
- /* @__PURE__ */ jsx("div", { className: "text-[13px] font-medium", children }),
3268
- description && /* @__PURE__ */ jsx("div", { className: "text-text-muted text-[12px]", children: description }),
3269
- time && /* @__PURE__ */ jsx("div", { className: "text-text-dim mt-[2px] font-mono text-[10px]", children: time })
3851
+ /* @__PURE__ */ jsx56("div", { className: "text-[13px] font-medium", children }),
3852
+ description && /* @__PURE__ */ jsx56("div", { className: "text-text-muted text-[12px]", children: description }),
3853
+ time && /* @__PURE__ */ jsx56("div", { className: "text-text-dim mt-[2px] font-mono text-[10px]", children: time })
3270
3854
  ] });
3271
3855
  });
3272
3856
  TimelineItem.displayName = "TimelineItem";
3273
- var Topbar = forwardRef(function Topbar2({ title, leading, actions, className, children, ...props }, ref) {
3274
- return /* @__PURE__ */ jsxs(
3857
+
3858
+ // src/patterns/Topbar/Topbar.tsx
3859
+ import { forwardRef as forwardRef55 } from "react";
3860
+ import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
3861
+ var Topbar = forwardRef55(function Topbar2({ title, leading, actions, className, children, ...props }, ref) {
3862
+ return /* @__PURE__ */ jsxs47(
3275
3863
  "header",
3276
3864
  {
3277
3865
  ref,
@@ -3282,40 +3870,101 @@ var Topbar = forwardRef(function Topbar2({ title, leading, actions, className, c
3282
3870
  ...props,
3283
3871
  children: [
3284
3872
  leading,
3285
- title && /* @__PURE__ */ jsx("div", { className: "text-[13px] font-medium", children: title }),
3286
- /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center" }),
3287
- actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: actions }),
3873
+ title && /* @__PURE__ */ jsx57("div", { className: "text-[13px] font-medium", children: title }),
3874
+ /* @__PURE__ */ jsx57("div", { className: "flex flex-1 items-center" }),
3875
+ actions && /* @__PURE__ */ jsx57("div", { className: "flex items-center gap-3", children: actions }),
3288
3876
  children
3289
3877
  ]
3290
3878
  }
3291
3879
  );
3292
3880
  });
3293
3881
  Topbar.displayName = "Topbar";
3294
- var Tree = forwardRef(function Tree2({
3882
+
3883
+ // src/patterns/Tree/Tree.tsx
3884
+ import {
3885
+ forwardRef as forwardRef56,
3886
+ useCallback as useCallback7,
3887
+ useEffect as useEffect9,
3888
+ useMemo as useMemo6,
3889
+ useRef as useRef7,
3890
+ useState as useState10
3891
+ } from "react";
3892
+ import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
3893
+ var EMPTY_SET2 = /* @__PURE__ */ new Set();
3894
+ function flattenVisible(items, expanded, level, parentId, out) {
3895
+ for (const item of items) {
3896
+ const hasChildren = !!item.children && item.children.length > 0;
3897
+ out.push({ id: item.id, level, hasChildren, parentId });
3898
+ if (hasChildren && expanded.has(item.id)) {
3899
+ flattenVisible(item.children ?? [], expanded, level + 1, item.id, out);
3900
+ }
3901
+ }
3902
+ }
3903
+ var Tree = forwardRef56(function Tree2({
3295
3904
  items,
3296
3905
  expanded: expandedProp,
3297
3906
  defaultExpanded,
3298
3907
  onExpandedChange,
3299
- selected: selectedProp,
3300
- defaultSelected,
3301
- onSelect,
3908
+ value: valueProp,
3909
+ defaultValue,
3910
+ onValueChange,
3302
3911
  className,
3912
+ onKeyDown,
3303
3913
  ...props
3304
3914
  }, ref) {
3305
3915
  const [expanded, setExpanded] = useControllableState({
3306
- value: expandedProp instanceof Set ? expandedProp : expandedProp,
3307
- defaultValue: defaultExpanded ? new Set(defaultExpanded) : /* @__PURE__ */ new Set(),
3916
+ value: expandedProp,
3917
+ defaultValue: defaultExpanded ? new Set(defaultExpanded) : void 0,
3308
3918
  onChange: onExpandedChange
3309
3919
  });
3310
- const [selected, setSelected] = useControllableState({
3311
- value: selectedProp,
3312
- defaultValue: defaultSelected,
3313
- onChange: onSelect
3920
+ const [value, setValue] = useControllableState({
3921
+ value: valueProp,
3922
+ defaultValue,
3923
+ onChange: onValueChange
3314
3924
  });
3315
- const toggle = useCallback(
3925
+ const expandedSet = expanded ?? EMPTY_SET2;
3926
+ const flatVisible = useMemo6(() => {
3927
+ const out = [];
3928
+ flattenVisible(items, expandedSet, 1, null, out);
3929
+ return out;
3930
+ }, [items, expandedSet]);
3931
+ const [activeId, setActiveId] = useState10(null);
3932
+ useEffect9(() => {
3933
+ if (activeId && !flatVisible.some((f) => f.id === activeId)) {
3934
+ setActiveId(null);
3935
+ }
3936
+ }, [activeId, flatVisible]);
3937
+ const tabStopId = useMemo6(() => {
3938
+ if (activeId && flatVisible.some((f) => f.id === activeId)) return activeId;
3939
+ if (value && flatVisible.some((f) => f.id === value)) return value;
3940
+ return flatVisible[0]?.id ?? null;
3941
+ }, [activeId, flatVisible, value]);
3942
+ const listRef = useRef7(null);
3943
+ const setRefs = useCallback7(
3944
+ (node) => {
3945
+ listRef.current = node;
3946
+ if (typeof ref === "function") ref(node);
3947
+ else if (ref) ref.current = node;
3948
+ },
3949
+ [ref]
3950
+ );
3951
+ const focusItem = useCallback7((id) => {
3952
+ const root = listRef.current;
3953
+ if (!root) return;
3954
+ const el = root.querySelector(`[data-treeitem-id="${CSS.escape(id)}"]`);
3955
+ el?.focus();
3956
+ }, []);
3957
+ const moveActive = useCallback7(
3958
+ (id) => {
3959
+ setActiveId(id);
3960
+ queueMicrotask(() => focusItem(id));
3961
+ },
3962
+ [focusItem]
3963
+ );
3964
+ const toggle = useCallback7(
3316
3965
  (id) => {
3317
3966
  setExpanded((prev) => {
3318
- const next = new Set(prev ?? []);
3967
+ const next = new Set(prev ?? EMPTY_SET2);
3319
3968
  if (next.has(id)) next.delete(id);
3320
3969
  else next.add(id);
3321
3970
  return next;
@@ -3323,22 +3972,138 @@ var Tree = forwardRef(function Tree2({
3323
3972
  },
3324
3973
  [setExpanded]
3325
3974
  );
3326
- return /* @__PURE__ */ jsx(
3975
+ const expand = useCallback7(
3976
+ (id) => {
3977
+ setExpanded((prev) => {
3978
+ const base = prev ?? EMPTY_SET2;
3979
+ if (base.has(id)) return base;
3980
+ const next = new Set(base);
3981
+ next.add(id);
3982
+ return next;
3983
+ });
3984
+ },
3985
+ [setExpanded]
3986
+ );
3987
+ const collapse = useCallback7(
3988
+ (id) => {
3989
+ setExpanded((prev) => {
3990
+ const base = prev ?? EMPTY_SET2;
3991
+ if (!base.has(id)) return base;
3992
+ const next = new Set(base);
3993
+ next.delete(id);
3994
+ return next;
3995
+ });
3996
+ },
3997
+ [setExpanded]
3998
+ );
3999
+ const selectItem = useCallback7(
4000
+ (id) => {
4001
+ setValue(id);
4002
+ },
4003
+ [setValue]
4004
+ );
4005
+ const handleKeyDown = useCallback7(
4006
+ (e) => {
4007
+ onKeyDown?.(e);
4008
+ if (e.defaultPrevented) return;
4009
+ if (flatVisible.length === 0) return;
4010
+ const currentId = tabStopId;
4011
+ const currentIndex = currentId ? flatVisible.findIndex((f) => f.id === currentId) : -1;
4012
+ const current = currentIndex >= 0 ? flatVisible[currentIndex] : void 0;
4013
+ switch (e.key) {
4014
+ case "ArrowDown": {
4015
+ e.preventDefault();
4016
+ const next = flatVisible[Math.min(flatVisible.length - 1, currentIndex + 1)];
4017
+ if (next) moveActive(next.id);
4018
+ break;
4019
+ }
4020
+ case "ArrowUp": {
4021
+ e.preventDefault();
4022
+ const prev = flatVisible[Math.max(0, currentIndex - 1)];
4023
+ if (prev) moveActive(prev.id);
4024
+ break;
4025
+ }
4026
+ case "ArrowRight": {
4027
+ if (!current) return;
4028
+ e.preventDefault();
4029
+ if (current.hasChildren) {
4030
+ if (!expandedSet.has(current.id)) {
4031
+ expand(current.id);
4032
+ } else {
4033
+ const child = flatVisible[currentIndex + 1];
4034
+ if (child && child.parentId === current.id) moveActive(child.id);
4035
+ }
4036
+ }
4037
+ break;
4038
+ }
4039
+ case "ArrowLeft": {
4040
+ if (!current) return;
4041
+ e.preventDefault();
4042
+ if (current.hasChildren && expandedSet.has(current.id)) {
4043
+ collapse(current.id);
4044
+ } else if (current.parentId) {
4045
+ moveActive(current.parentId);
4046
+ }
4047
+ break;
4048
+ }
4049
+ case "Home": {
4050
+ e.preventDefault();
4051
+ const first = flatVisible[0];
4052
+ if (first) moveActive(first.id);
4053
+ break;
4054
+ }
4055
+ case "End": {
4056
+ e.preventDefault();
4057
+ const last = flatVisible[flatVisible.length - 1];
4058
+ if (last) moveActive(last.id);
4059
+ break;
4060
+ }
4061
+ case "Enter":
4062
+ case " ": {
4063
+ if (!current) return;
4064
+ e.preventDefault();
4065
+ selectItem(current.id);
4066
+ if (current.hasChildren) toggle(current.id);
4067
+ break;
4068
+ }
4069
+ default:
4070
+ break;
4071
+ }
4072
+ },
4073
+ [
4074
+ collapse,
4075
+ expand,
4076
+ expandedSet,
4077
+ flatVisible,
4078
+ moveActive,
4079
+ onKeyDown,
4080
+ selectItem,
4081
+ tabStopId,
4082
+ toggle
4083
+ ]
4084
+ );
4085
+ return /* @__PURE__ */ jsx58(
3327
4086
  "ul",
3328
4087
  {
3329
- ref,
4088
+ ref: setRefs,
3330
4089
  role: "tree",
3331
4090
  className: cn("flex flex-col gap-px text-[12px]", className),
4091
+ onKeyDown: handleKeyDown,
3332
4092
  ...props,
3333
- children: items.map((item) => /* @__PURE__ */ jsx(
4093
+ children: items.map((item) => /* @__PURE__ */ jsx58(
3334
4094
  TreeItemRow,
3335
4095
  {
3336
4096
  item,
3337
4097
  level: 1,
3338
- expanded: expanded ?? /* @__PURE__ */ new Set(),
3339
- selected,
3340
- onToggle: toggle,
3341
- onSelect: (id) => setSelected(id)
4098
+ expanded: expandedSet,
4099
+ selected: value,
4100
+ tabStopId,
4101
+ onFocusItem: setActiveId,
4102
+ onActivate: (id) => {
4103
+ setActiveId(id);
4104
+ selectItem(id);
4105
+ },
4106
+ onToggle: toggle
3342
4107
  },
3343
4108
  item.id
3344
4109
  ))
@@ -3346,36 +4111,37 @@ var Tree = forwardRef(function Tree2({
3346
4111
  );
3347
4112
  });
3348
4113
  Tree.displayName = "Tree";
3349
- function TreeItemRow({ item, level, expanded, selected, onToggle, onSelect }) {
4114
+ function TreeItemRow({
4115
+ item,
4116
+ level,
4117
+ expanded,
4118
+ selected,
4119
+ tabStopId,
4120
+ onFocusItem,
4121
+ onActivate,
4122
+ onToggle
4123
+ }) {
3350
4124
  const hasChildren = !!item.children && item.children.length > 0;
3351
4125
  const isExpanded = hasChildren && expanded.has(item.id);
3352
4126
  const isSelected = selected === item.id;
3353
- return /* @__PURE__ */ jsxs("li", { role: "none", children: [
3354
- /* @__PURE__ */ jsxs(
4127
+ const isTabStop = tabStopId === item.id;
4128
+ return /* @__PURE__ */ jsxs48("li", { role: "none", children: [
4129
+ /* @__PURE__ */ jsxs48(
3355
4130
  "div",
3356
4131
  {
3357
4132
  role: "treeitem",
4133
+ "data-treeitem-id": item.id,
3358
4134
  "aria-level": level,
3359
4135
  "aria-expanded": hasChildren ? isExpanded : void 0,
3360
4136
  "aria-selected": isSelected,
3361
- tabIndex: isSelected ? 0 : -1,
4137
+ tabIndex: isTabStop ? 0 : -1,
4138
+ onFocus: (e) => {
4139
+ if (e.target === e.currentTarget) onFocusItem(item.id);
4140
+ },
3362
4141
  onClick: () => {
3363
- onSelect(item.id);
4142
+ onActivate(item.id);
3364
4143
  if (hasChildren) onToggle(item.id);
3365
4144
  },
3366
- onKeyDown: (e) => {
3367
- if (e.key === "Enter" || e.key === " ") {
3368
- e.preventDefault();
3369
- onSelect(item.id);
3370
- if (hasChildren) onToggle(item.id);
3371
- } else if (e.key === "ArrowRight" && hasChildren && !isExpanded) {
3372
- e.preventDefault();
3373
- onToggle(item.id);
3374
- } else if (e.key === "ArrowLeft" && hasChildren && isExpanded) {
3375
- e.preventDefault();
3376
- onToggle(item.id);
3377
- }
3378
- },
3379
4145
  style: { paddingLeft: 4 + (level - 1) * 16 },
3380
4146
  className: cn(
3381
4147
  "flex cursor-pointer items-center gap-[6px] rounded-xs py-[5px] pr-2 outline-none",
@@ -3383,28 +4149,167 @@ function TreeItemRow({ item, level, expanded, selected, onToggle, onSelect }) {
3383
4149
  isSelected ? "bg-accent-dim text-accent" : "text-text hover:bg-panel-2"
3384
4150
  ),
3385
4151
  children: [
3386
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-text-dim grid w-3 place-items-center text-[10px]", children: hasChildren ? isExpanded ? "\u25BE" : "\u25B8" : "" }),
3387
- item.icon && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-[12px] opacity-80", children: item.icon }),
3388
- /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: item.label }),
4152
+ /* @__PURE__ */ jsx58("span", { "aria-hidden": true, className: "text-text-dim grid w-3 place-items-center text-[10px]", children: hasChildren ? isExpanded ? "\u25BE" : "\u25B8" : "" }),
4153
+ item.icon && /* @__PURE__ */ jsx58("span", { "aria-hidden": true, className: "text-[12px] opacity-80", children: item.icon }),
4154
+ /* @__PURE__ */ jsx58("span", { className: "flex-1 truncate", children: item.label }),
3389
4155
  item.trailing
3390
4156
  ]
3391
4157
  }
3392
4158
  ),
3393
- hasChildren && isExpanded && /* @__PURE__ */ jsx("ul", { role: "group", className: "flex flex-col gap-px", children: item.children.map((child) => /* @__PURE__ */ jsx(
4159
+ hasChildren && isExpanded && /* @__PURE__ */ jsx58("ul", { role: "group", className: "flex flex-col gap-px", children: (item.children ?? []).map((child) => /* @__PURE__ */ jsx58(
3394
4160
  TreeItemRow,
3395
4161
  {
3396
4162
  item: child,
3397
4163
  level: level + 1,
3398
4164
  expanded,
3399
4165
  selected,
3400
- onToggle,
3401
- onSelect
4166
+ tabStopId,
4167
+ onFocusItem,
4168
+ onActivate,
4169
+ onToggle
3402
4170
  },
3403
4171
  child.id
3404
4172
  )) })
3405
4173
  ] });
3406
4174
  }
3407
-
3408
- export { Alert, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogRoot, AlertDialogTrigger, Avatar, AvatarGroup, Badge, Banner, Breadcrumbs, Button, ButtonGroup, Calendar, Card, Checkbox, Chip, Combobox, CommandPalette, ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuPortal, ContextMenuRoot, ContextMenuSeparator, ContextMenuTrigger, Crumb, DataTable, DatePicker, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogRoot, DialogTrigger, Dots, Drawer, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRoot, DropdownMenuTrigger, EmptyState, FAB, Field, FileChip, HoverCard, HoverCardContent, HoverCardPortal, HoverCardRoot, HoverCardTrigger, IconButton, Input, Kbd, MenuCheckboxItem, MenuItem, MenuSeparator, Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarTrigger, NavItem, NavSection, OTP, Pagination, Popover, PopoverAnchor, PopoverArrow, PopoverClose, PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger, Progress, RadialProgress, Radio, RadioGroup, SearchInput, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectRoot, SelectTrigger, SelectValue, Sheet, Sidebar, Skeleton, Slider, Sparkline, Spinner2 as Spinner, SplitButton, StatCard, StatusDot, Stepper, Switch, Tab, Tabs, TabsContent, TabsList, Tag, Textarea, Timeline, TimelineItem, ToastCard, ToastProvider, Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger, Topbar, Tree, badgeStyles, buttonStyles, cardStyles, cn, filterCommandItems, iconButtonStyles, useControllableState, useDisclosure, useEscape, useKeyboardList, useOutsideClick, useTheme, useToast };
3409
- //# sourceMappingURL=index.js.map
4175
+ export {
4176
+ Alert,
4177
+ AlertDialog,
4178
+ AlertDialogAction,
4179
+ AlertDialogCancel,
4180
+ AlertDialogRoot,
4181
+ AlertDialogTrigger,
4182
+ Avatar,
4183
+ AvatarGroup,
4184
+ Badge,
4185
+ Banner,
4186
+ Breadcrumbs,
4187
+ Button,
4188
+ ButtonGroup,
4189
+ Calendar,
4190
+ Card,
4191
+ CardLink,
4192
+ Checkbox,
4193
+ Chip,
4194
+ Combobox,
4195
+ CommandPalette,
4196
+ ContextMenu,
4197
+ ContextMenuContent,
4198
+ ContextMenuItem,
4199
+ ContextMenuPortal,
4200
+ ContextMenuRoot,
4201
+ ContextMenuSeparator,
4202
+ ContextMenuTrigger,
4203
+ Crumb,
4204
+ DataTable,
4205
+ DatePicker,
4206
+ Dialog,
4207
+ DialogClose,
4208
+ DialogContent,
4209
+ DialogOverlay,
4210
+ DialogPortal,
4211
+ DialogRoot,
4212
+ DialogTrigger,
4213
+ Dots,
4214
+ Drawer,
4215
+ DropdownMenu,
4216
+ DropdownMenuContent,
4217
+ DropdownMenuGroup,
4218
+ DropdownMenuLabel,
4219
+ DropdownMenuPortal,
4220
+ DropdownMenuRadioGroup,
4221
+ DropdownMenuRoot,
4222
+ DropdownMenuTrigger,
4223
+ EmptyState,
4224
+ FAB,
4225
+ Field,
4226
+ FileChip,
4227
+ HoverCard,
4228
+ HoverCardContent,
4229
+ HoverCardPortal,
4230
+ HoverCardRoot,
4231
+ HoverCardTrigger,
4232
+ IconButton,
4233
+ Input,
4234
+ Kbd,
4235
+ MenuCheckboxItem,
4236
+ MenuItem,
4237
+ MenuSeparator,
4238
+ Menubar,
4239
+ MenubarContent,
4240
+ MenubarItem,
4241
+ MenubarMenu,
4242
+ MenubarSeparator,
4243
+ MenubarTrigger,
4244
+ NavItem,
4245
+ NavSection,
4246
+ OTP,
4247
+ Pagination,
4248
+ Popover,
4249
+ PopoverAnchor,
4250
+ PopoverArrow,
4251
+ PopoverClose,
4252
+ PopoverContent,
4253
+ PopoverPortal,
4254
+ PopoverRoot,
4255
+ PopoverTrigger,
4256
+ Progress,
4257
+ RadialProgress,
4258
+ Radio,
4259
+ RadioGroup,
4260
+ SearchInput,
4261
+ Select,
4262
+ SelectContent,
4263
+ SelectGroup,
4264
+ SelectItem,
4265
+ SelectLabel,
4266
+ SelectRoot,
4267
+ SelectTrigger,
4268
+ SelectValue,
4269
+ Sheet,
4270
+ Sidebar,
4271
+ Skeleton,
4272
+ SkeletonGroup,
4273
+ Slider,
4274
+ Sparkline,
4275
+ Spinner2 as Spinner,
4276
+ SplitButton,
4277
+ StatCard,
4278
+ StatusDot,
4279
+ Stepper,
4280
+ Switch,
4281
+ Tab,
4282
+ Tabs,
4283
+ TabsContent,
4284
+ TabsList,
4285
+ Tag,
4286
+ Textarea,
4287
+ Timeline,
4288
+ TimelineItem,
4289
+ ToastCard,
4290
+ ToastProvider,
4291
+ Tooltip,
4292
+ TooltipArrow,
4293
+ TooltipContent,
4294
+ TooltipPortal,
4295
+ TooltipProvider,
4296
+ TooltipRoot,
4297
+ TooltipTrigger,
4298
+ Topbar,
4299
+ Tree,
4300
+ badgeStyles,
4301
+ buttonStyles,
4302
+ cardStyles,
4303
+ cn,
4304
+ filterCommandItems,
4305
+ iconButtonStyles,
4306
+ useControllableState,
4307
+ useDisclosure,
4308
+ useEscape,
4309
+ useIsomorphicLayoutEffect,
4310
+ useKeyboardList,
4311
+ useOutsideClick,
4312
+ useTheme,
4313
+ useToast
4314
+ };
3410
4315
  //# sourceMappingURL=index.js.map