@wow-two-beta/ui 0.0.12 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/actions/index.d.ts +1 -0
  2. package/dist/actions/index.d.ts.map +1 -1
  3. package/dist/actions/index.js +2 -2
  4. package/dist/actions/toolbar/Toolbar.d.ts +23 -0
  5. package/dist/actions/toolbar/Toolbar.d.ts.map +1 -0
  6. package/dist/actions/toolbar/index.d.ts +2 -0
  7. package/dist/actions/toolbar/index.d.ts.map +1 -0
  8. package/dist/chunk-ASXB42MH.js +1670 -0
  9. package/dist/chunk-ASXB42MH.js.map +1 -0
  10. package/dist/{chunk-K6V4KLRO.js → chunk-BQTO7XY6.js} +1299 -478
  11. package/dist/chunk-BQTO7XY6.js.map +1 -0
  12. package/dist/{chunk-52DFDWY3.js → chunk-FS6DTWWH.js} +121 -146
  13. package/dist/chunk-FS6DTWWH.js.map +1 -0
  14. package/dist/{chunk-ZTHJ5OTI.js → chunk-UGHPZ3I7.js} +212 -6
  15. package/dist/chunk-UGHPZ3I7.js.map +1 -0
  16. package/dist/{chunk-D5CHR6RX.js → chunk-ULAOIBCP.js} +113 -5
  17. package/dist/chunk-ULAOIBCP.js.map +1 -0
  18. package/dist/{chunk-YANOG5YR.js → chunk-YMSAS7M7.js} +104 -55
  19. package/dist/chunk-YMSAS7M7.js.map +1 -0
  20. package/dist/display/accordion/Accordion.d.ts +41 -0
  21. package/dist/display/accordion/Accordion.d.ts.map +1 -0
  22. package/dist/display/accordion/index.d.ts +2 -0
  23. package/dist/display/accordion/index.d.ts.map +1 -0
  24. package/dist/display/collapsible/Collapsible.d.ts +26 -0
  25. package/dist/display/collapsible/Collapsible.d.ts.map +1 -0
  26. package/dist/display/collapsible/index.d.ts +2 -0
  27. package/dist/display/collapsible/index.d.ts.map +1 -0
  28. package/dist/display/dataTable/DataTable.d.ts +34 -0
  29. package/dist/display/dataTable/DataTable.d.ts.map +1 -0
  30. package/dist/display/dataTable/index.d.ts +2 -0
  31. package/dist/display/dataTable/index.d.ts.map +1 -0
  32. package/dist/display/index.d.ts +8 -0
  33. package/dist/display/index.d.ts.map +1 -1
  34. package/dist/display/index.js +2 -3
  35. package/dist/display/list/List.d.ts +23 -0
  36. package/dist/display/list/List.d.ts.map +1 -0
  37. package/dist/display/list/List.variants.d.ts +89 -0
  38. package/dist/display/list/List.variants.d.ts.map +1 -0
  39. package/dist/display/list/index.d.ts +2 -0
  40. package/dist/display/list/index.d.ts.map +1 -0
  41. package/dist/display/table/Table.d.ts +35 -0
  42. package/dist/display/table/Table.d.ts.map +1 -0
  43. package/dist/display/table/index.d.ts +2 -0
  44. package/dist/display/table/index.d.ts.map +1 -0
  45. package/dist/display/tabs/Tabs.d.ts +31 -0
  46. package/dist/display/tabs/Tabs.d.ts.map +1 -0
  47. package/dist/display/tabs/index.d.ts +2 -0
  48. package/dist/display/tabs/index.d.ts.map +1 -0
  49. package/dist/display/timeline/Timeline.d.ts +29 -0
  50. package/dist/display/timeline/Timeline.d.ts.map +1 -0
  51. package/dist/display/timeline/index.d.ts +2 -0
  52. package/dist/display/timeline/index.d.ts.map +1 -0
  53. package/dist/display/tree/Tree.d.ts +30 -0
  54. package/dist/display/tree/Tree.d.ts.map +1 -0
  55. package/dist/display/tree/index.d.ts +2 -0
  56. package/dist/display/tree/index.d.ts.map +1 -0
  57. package/dist/forms/MonthGrid.d.ts +29 -0
  58. package/dist/forms/MonthGrid.d.ts.map +1 -0
  59. package/dist/forms/calendar/Calendar.d.ts.map +1 -1
  60. package/dist/forms/datePicker/DatePicker.d.ts.map +1 -1
  61. package/dist/forms/dateRangePicker/DateRangePicker.d.ts.map +1 -1
  62. package/dist/forms/index.d.ts +8 -0
  63. package/dist/forms/index.d.ts.map +1 -1
  64. package/dist/forms/index.js +3 -3
  65. package/dist/forms/multiSelect/MultiSelect.d.ts +4 -5
  66. package/dist/forms/multiSelect/MultiSelect.d.ts.map +1 -1
  67. package/dist/forms/rangeCalendar/RangeCalendar.d.ts.map +1 -1
  68. package/dist/forms/select/Select.d.ts +5 -9
  69. package/dist/forms/select/Select.d.ts.map +1 -1
  70. package/dist/forms/stepper/Stepper.d.ts +32 -0
  71. package/dist/forms/stepper/Stepper.d.ts.map +1 -0
  72. package/dist/forms/stepper/index.d.ts +2 -0
  73. package/dist/forms/stepper/index.d.ts.map +1 -0
  74. package/dist/forms/timePicker/TimePicker.d.ts.map +1 -1
  75. package/dist/index.js +6 -7
  76. package/dist/nav/index.d.ts +1 -0
  77. package/dist/nav/index.d.ts.map +1 -1
  78. package/dist/nav/index.js +2 -3
  79. package/dist/nav/navigationMenu/NavigationMenu.d.ts +39 -0
  80. package/dist/nav/navigationMenu/NavigationMenu.d.ts.map +1 -0
  81. package/dist/nav/navigationMenu/index.d.ts +2 -0
  82. package/dist/nav/navigationMenu/index.d.ts.map +1 -0
  83. package/dist/overlays/OverlayChrome.d.ts +34 -0
  84. package/dist/overlays/OverlayChrome.d.ts.map +1 -0
  85. package/dist/overlays/dialog/Dialog.d.ts +7 -25
  86. package/dist/overlays/dialog/Dialog.d.ts.map +1 -1
  87. package/dist/overlays/dialog/index.d.ts +1 -1
  88. package/dist/overlays/dialog/index.d.ts.map +1 -1
  89. package/dist/overlays/drawer/Drawer.d.ts +7 -21
  90. package/dist/overlays/drawer/Drawer.d.ts.map +1 -1
  91. package/dist/overlays/drawer/index.d.ts +1 -1
  92. package/dist/overlays/drawer/index.d.ts.map +1 -1
  93. package/dist/overlays/index.js +2 -3
  94. package/dist/overlays/popover/Popover.d.ts +7 -0
  95. package/dist/overlays/popover/Popover.d.ts.map +1 -1
  96. package/dist/primitives/anchoredPositioner/AnchoredPositioner.d.ts +8 -0
  97. package/dist/primitives/anchoredPositioner/AnchoredPositioner.d.ts.map +1 -1
  98. package/dist/primitives/index.js +1 -2
  99. package/dist/primitives/rovingFocusGroup/RovingFocusGroup.d.ts +1 -1
  100. package/dist/primitives/rovingFocusGroup/RovingFocusGroup.d.ts.map +1 -1
  101. package/package.json +1 -1
  102. package/dist/chunk-33IOXQYO.js +0 -47
  103. package/dist/chunk-33IOXQYO.js.map +0 -1
  104. package/dist/chunk-52DFDWY3.js.map +0 -1
  105. package/dist/chunk-D5CHR6RX.js.map +0 -1
  106. package/dist/chunk-K6V4KLRO.js.map +0 -1
  107. package/dist/chunk-VTLWHUMD.js +0 -774
  108. package/dist/chunk-VTLWHUMD.js.map +0 -1
  109. package/dist/chunk-YANOG5YR.js.map +0 -1
  110. package/dist/chunk-ZTHJ5OTI.js.map +0 -1
@@ -1,15 +1,15 @@
1
- import { useFormControl, FormControlProvider, Portal, AnchoredPositioner, DismissableLayer } from './chunk-YANOG5YR.js';
1
+ import { PopoverTrigger, Popover, PopoverContent } from './chunk-FS6DTWWH.js';
2
2
  import { useControlled } from './chunk-4P2TFUVW.js';
3
+ import { useFormControl, FormControlProvider, RovingFocusGroup, useRovingFocusItem, Portal, AnchoredPositioner, DismissableLayer } from './chunk-YMSAS7M7.js';
3
4
  import { useId } from './chunk-KDXJQNB6.js';
4
- import { tv } from './chunk-BMBIZLO4.js';
5
+ import { tv, dataAttr } from './chunk-BMBIZLO4.js';
5
6
  import { Icon } from './chunk-TDX22OWF.js';
6
7
  import { composeRefs } from './chunk-DN7WBRIV.js';
7
8
  import { cn } from './chunk-KZ4VFY2T.js';
8
9
  import * as React from 'react';
9
10
  import { forwardRef, useRef, useImperativeHandle, useState, Children, isValidElement, cloneElement, useId as useId$1, createContext, useMemo, useCallback, useEffect, useContext } from 'react';
10
11
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
11
- import { Minus, Plus, EyeOff, Eye, Search, X, Check, Upload, ChevronDown, ChevronLeft, ChevronRight, Calendar as Calendar$1, Clock } from 'lucide-react';
12
- import { FocusScope } from '@radix-ui/react-focus-scope';
12
+ import { Minus, Plus, EyeOff, Eye, Search, X, Check, Upload, ChevronDown, Calendar as Calendar$1, Clock, ChevronLeft, ChevronRight } from 'lucide-react';
13
13
 
14
14
  var Label = forwardRef(
15
15
  ({ className, required, htmlFor, id, children, ...props }, ref) => {
@@ -1388,6 +1388,7 @@ function Select({
1388
1388
  defaultOpen = false,
1389
1389
  open: openProp,
1390
1390
  onOpenChange,
1391
+ placement = "bottom",
1391
1392
  children
1392
1393
  }) {
1393
1394
  const [openState, setOpenState] = useControlled({
@@ -1400,7 +1401,6 @@ function Select({
1400
1401
  default: defaultValue ?? "",
1401
1402
  onChange: onValueChange
1402
1403
  });
1403
- const triggerRef = useRef(null);
1404
1404
  const [labels, setLabels] = useState({});
1405
1405
  const registerLabel = useCallback((v, label) => {
1406
1406
  setLabels((prev) => prev[v] === label ? prev : { ...prev, [v]: label });
@@ -1417,7 +1417,6 @@ function Select({
1417
1417
  (next) => {
1418
1418
  setValueState(next);
1419
1419
  setOpenState(false);
1420
- requestAnimationFrame(() => triggerRef.current?.focus());
1421
1420
  },
1422
1421
  [setValueState, setOpenState]
1423
1422
  );
@@ -1427,7 +1426,6 @@ function Select({
1427
1426
  setOpen: setOpenState,
1428
1427
  value: valueState,
1429
1428
  onSelect,
1430
- triggerRef,
1431
1429
  labels,
1432
1430
  registerLabel,
1433
1431
  unregisterLabel,
@@ -1448,26 +1446,27 @@ function Select({
1448
1446
  invalid
1449
1447
  ]
1450
1448
  );
1451
- return /* @__PURE__ */ jsx(SelectContext.Provider, { value: ctx, children });
1449
+ return /* @__PURE__ */ jsx(SelectContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
1450
+ Popover,
1451
+ {
1452
+ open: openState,
1453
+ onOpenChange: setOpenState,
1454
+ placement,
1455
+ offset: 6,
1456
+ children
1457
+ }
1458
+ ) });
1452
1459
  }
1453
1460
  var SelectTrigger = forwardRef(
1454
- function SelectTrigger2({ size, state, className, onClick, children, ...rest }, forwardedRef) {
1461
+ function SelectTrigger2({ size, state, className, children, ...rest }, ref) {
1455
1462
  const ctx = useSelectContext();
1456
1463
  const triggerState = state ?? (ctx.invalid ? "invalid" : "default");
1457
- return /* @__PURE__ */ jsxs(
1464
+ return /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1458
1465
  "button",
1459
1466
  {
1460
- ref: composeRefs(forwardedRef, ctx.triggerRef),
1467
+ ref,
1461
1468
  type: "button",
1462
- "aria-haspopup": "listbox",
1463
- "aria-expanded": ctx.open,
1464
- "data-state": ctx.open ? "open" : "closed",
1465
1469
  disabled: ctx.disabled,
1466
- onClick: (e) => {
1467
- onClick?.(e);
1468
- if (e.defaultPrevented) return;
1469
- ctx.setOpen(!ctx.open);
1470
- },
1471
1470
  className: cn(selectTriggerVariants({ size, state: triggerState }), className),
1472
1471
  ...rest,
1473
1472
  children: [
@@ -1483,7 +1482,7 @@ var SelectTrigger = forwardRef(
1483
1482
  )
1484
1483
  ]
1485
1484
  }
1486
- );
1485
+ ) });
1487
1486
  }
1488
1487
  );
1489
1488
  function SelectValue({ placeholder, children }) {
@@ -1492,35 +1491,18 @@ function SelectValue({ placeholder, children }) {
1492
1491
  const label = ctx.value ? ctx.labels[ctx.value] ?? ctx.value : null;
1493
1492
  return /* @__PURE__ */ jsx("span", { className: cn("truncate", !label && "text-subtle-foreground"), children: label ?? placeholder });
1494
1493
  }
1495
- function SelectContent({
1496
- className,
1497
- placement = "bottom",
1498
- offset = 6,
1499
- children
1500
- }) {
1494
+ function SelectContent({ className, children }) {
1501
1495
  const ctx = useSelectContext();
1502
- if (!ctx.open) return null;
1503
- return /* @__PURE__ */ jsxs(Portal, { children: [
1504
- /* @__PURE__ */ jsx(AnchoredPositioner, { anchor: ctx.triggerRef.current, placement, offset, children: /* @__PURE__ */ jsx(FocusScope, { asChild: true, trapped: true, loop: true, children: /* @__PURE__ */ jsx(
1505
- DismissableLayer,
1496
+ return /* @__PURE__ */ jsxs(PopoverContent, { bare: true, children: [
1497
+ /* @__PURE__ */ jsx(
1498
+ Listbox,
1506
1499
  {
1507
- onEscape: () => ctx.setOpen(false),
1508
- onOutsidePointerDown: (e) => {
1509
- if (ctx.triggerRef.current?.contains(e.target)) return;
1510
- ctx.setOpen(false);
1511
- },
1512
- children: /* @__PURE__ */ jsx(
1513
- Listbox,
1514
- {
1515
- value: ctx.value,
1516
- onValueChange: (v) => ctx.onSelect(v),
1517
- className: cn("min-w-[var(--radix-anchor-width)]", className),
1518
- style: ctx.triggerRef.current ? { minWidth: ctx.triggerRef.current.offsetWidth } : void 0,
1519
- children
1520
- }
1521
- )
1500
+ value: ctx.value,
1501
+ onValueChange: (v) => ctx.onSelect(v),
1502
+ className: cn("min-w-[var(--anchor-width)]", className),
1503
+ children
1522
1504
  }
1523
- ) }) }),
1505
+ ),
1524
1506
  ctx.name && /* @__PURE__ */ jsx("input", { type: "hidden", name: ctx.name, value: ctx.value })
1525
1507
  ] });
1526
1508
  }
@@ -1555,6 +1537,7 @@ function MultiSelect({
1555
1537
  defaultOpen = false,
1556
1538
  open: openProp,
1557
1539
  onOpenChange,
1540
+ placement = "bottom",
1558
1541
  children
1559
1542
  }) {
1560
1543
  const [openState, setOpenState] = useControlled({
@@ -1567,7 +1550,6 @@ function MultiSelect({
1567
1550
  default: defaultValue ?? [],
1568
1551
  onChange: onValueChange
1569
1552
  });
1570
- const triggerRef = useRef(null);
1571
1553
  const [labels, setLabels] = useState({});
1572
1554
  const registerLabel = useCallback((v, label) => {
1573
1555
  setLabels((prev) => prev[v] === label ? prev : { ...prev, [v]: label });
@@ -1586,7 +1568,6 @@ function MultiSelect({
1586
1568
  setOpen: setOpenState,
1587
1569
  values: valuesState,
1588
1570
  setValues: setValuesState,
1589
- triggerRef,
1590
1571
  labels,
1591
1572
  registerLabel,
1592
1573
  unregisterLabel,
@@ -1607,26 +1588,27 @@ function MultiSelect({
1607
1588
  invalid
1608
1589
  ]
1609
1590
  );
1610
- return /* @__PURE__ */ jsx(MultiSelectContext.Provider, { value: ctx, children });
1591
+ return /* @__PURE__ */ jsx(MultiSelectContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
1592
+ Popover,
1593
+ {
1594
+ open: openState,
1595
+ onOpenChange: setOpenState,
1596
+ placement,
1597
+ offset: 6,
1598
+ children
1599
+ }
1600
+ ) });
1611
1601
  }
1612
1602
  var MultiSelectTrigger = forwardRef(
1613
- function MultiSelectTrigger2({ size, state, className, onClick, onKeyDown, children, ...rest }, forwardedRef) {
1603
+ function MultiSelectTrigger2({ size, state, className, onKeyDown, children, ...rest }, ref) {
1614
1604
  const ctx = useMultiSelectContext();
1615
1605
  const triggerState = state ?? (ctx.invalid ? "invalid" : "default");
1616
- return /* @__PURE__ */ jsxs(
1606
+ return /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1617
1607
  "button",
1618
1608
  {
1619
- ref: composeRefs(forwardedRef, ctx.triggerRef),
1609
+ ref,
1620
1610
  type: "button",
1621
- "aria-haspopup": "listbox",
1622
- "aria-expanded": ctx.open,
1623
- "data-state": ctx.open ? "open" : "closed",
1624
1611
  disabled: ctx.disabled,
1625
- onClick: (e) => {
1626
- onClick?.(e);
1627
- if (e.defaultPrevented) return;
1628
- ctx.setOpen(!ctx.open);
1629
- },
1630
1612
  onKeyDown: (e) => {
1631
1613
  onKeyDown?.(e);
1632
1614
  if (e.defaultPrevented) return;
@@ -1653,7 +1635,7 @@ var MultiSelectTrigger = forwardRef(
1653
1635
  )
1654
1636
  ]
1655
1637
  }
1656
- );
1638
+ ) });
1657
1639
  }
1658
1640
  );
1659
1641
  function MultiSelectTags({ placeholder }) {
@@ -1687,39 +1669,19 @@ function MultiSelectTags({ placeholder }) {
1687
1669
  v
1688
1670
  )) });
1689
1671
  }
1690
- function MultiSelectContent({
1691
- className,
1692
- placement = "bottom",
1693
- offset = 6,
1694
- children
1695
- }) {
1672
+ function MultiSelectContent({ className, children }) {
1696
1673
  const ctx = useMultiSelectContext();
1697
- if (!ctx.open) return null;
1698
- return /* @__PURE__ */ jsxs(Portal, { children: [
1699
- /* @__PURE__ */ jsx(AnchoredPositioner, { anchor: ctx.triggerRef.current, placement, offset, children: /* @__PURE__ */ jsx(FocusScope, { asChild: true, trapped: true, loop: true, children: /* @__PURE__ */ jsx(
1700
- DismissableLayer,
1674
+ return /* @__PURE__ */ jsxs(PopoverContent, { bare: true, children: [
1675
+ /* @__PURE__ */ jsx(
1676
+ Listbox,
1701
1677
  {
1702
- onEscape: () => {
1703
- ctx.setOpen(false);
1704
- requestAnimationFrame(() => ctx.triggerRef.current?.focus());
1705
- },
1706
- onOutsidePointerDown: (e) => {
1707
- if (ctx.triggerRef.current?.contains(e.target)) return;
1708
- ctx.setOpen(false);
1709
- },
1710
- children: /* @__PURE__ */ jsx(
1711
- Listbox,
1712
- {
1713
- multiple: true,
1714
- value: ctx.values,
1715
- onValueChange: (v) => ctx.setValues(v),
1716
- className: cn(className),
1717
- style: ctx.triggerRef.current ? { minWidth: ctx.triggerRef.current.offsetWidth } : void 0,
1718
- children
1719
- }
1720
- )
1678
+ multiple: true,
1679
+ value: ctx.values,
1680
+ onValueChange: (v) => ctx.setValues(v),
1681
+ className: cn("min-w-[var(--anchor-width)]", className),
1682
+ children
1721
1683
  }
1722
- ) }) }),
1684
+ ),
1723
1685
  ctx.name && ctx.values.map((v) => /* @__PURE__ */ jsx("input", { type: "hidden", name: ctx.name, value: v }, v))
1724
1686
  ] });
1725
1687
  }
@@ -2129,29 +2091,17 @@ function isInRange(d, start, end) {
2129
2091
  const e = startOfDay(end).getTime();
2130
2092
  return t >= Math.min(s, e) && t <= Math.max(s, e);
2131
2093
  }
2132
- var Calendar = forwardRef(function Calendar2({
2133
- value,
2134
- defaultValue,
2135
- onChange,
2136
- defaultMonth,
2137
- min,
2138
- max,
2139
- isDisabled,
2094
+ function MonthGrid({
2095
+ viewMonth,
2096
+ onViewMonthChange,
2097
+ focusedDate,
2098
+ onFocusedDateChange,
2099
+ isDayDisabled,
2100
+ onDayActivate,
2101
+ dayProps,
2140
2102
  "aria-label": ariaLabel = "Calendar",
2141
- className,
2142
- ...rest
2143
- }, ref) {
2144
- const [selected, setSelected] = useControlled({
2145
- controlled: value,
2146
- default: defaultValue ?? null,
2147
- onChange
2148
- });
2149
- const [viewMonth, setViewMonth] = useState(
2150
- () => startOfMonth(defaultMonth ?? selected ?? /* @__PURE__ */ new Date())
2151
- );
2152
- const [focusedDate, setFocusedDate] = useState(
2153
- () => selected ?? /* @__PURE__ */ new Date()
2154
- );
2103
+ className
2104
+ }) {
2155
2105
  const gridRef = useRef(null);
2156
2106
  useEffect(() => {
2157
2107
  const cell = gridRef.current?.querySelector(
@@ -2162,14 +2112,14 @@ var Calendar = forwardRef(function Calendar2({
2162
2112
  const moveFocus = useCallback(
2163
2113
  (next) => {
2164
2114
  if (next.getMonth() !== viewMonth.getMonth() || next.getFullYear() !== viewMonth.getFullYear()) {
2165
- setViewMonth(startOfMonth(next));
2115
+ onViewMonthChange(startOfMonth(next));
2166
2116
  }
2167
- setFocusedDate(next);
2117
+ onFocusedDateChange(next);
2168
2118
  },
2169
- [viewMonth]
2119
+ [viewMonth, onViewMonthChange, onFocusedDateChange]
2170
2120
  );
2171
2121
  const onCellKeyDown = useCallback(
2172
- (e, date) => {
2122
+ (e, date, outOfMonth) => {
2173
2123
  switch (e.key) {
2174
2124
  case "ArrowRight":
2175
2125
  e.preventDefault();
@@ -2206,26 +2156,22 @@ var Calendar = forwardRef(function Calendar2({
2206
2156
  case "Enter":
2207
2157
  case " ":
2208
2158
  e.preventDefault();
2209
- if (!isDateDisabled(date, { min, max, isDisabled })) {
2210
- setSelected(date);
2211
- }
2159
+ if (!isDayDisabled?.(date)) onDayActivate?.(date, { outOfMonth });
2212
2160
  break;
2213
2161
  }
2214
2162
  },
2215
- [moveFocus, setSelected, min, max, isDisabled]
2163
+ [moveFocus, onDayActivate, isDayDisabled]
2216
2164
  );
2217
2165
  const cells = buildMonthGrid(viewMonth.getFullYear(), viewMonth.getMonth());
2218
2166
  return /* @__PURE__ */ jsxs(
2219
2167
  "div",
2220
2168
  {
2221
- ref,
2222
2169
  role: "application",
2223
2170
  "aria-label": ariaLabel,
2224
2171
  className: cn(
2225
2172
  "inline-flex flex-col gap-2 rounded-md border border-border bg-popover p-3 text-popover-foreground",
2226
2173
  className
2227
2174
  ),
2228
- ...rest,
2229
2175
  children: [
2230
2176
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-1", children: [
2231
2177
  /* @__PURE__ */ jsx(
@@ -2233,7 +2179,7 @@ var Calendar = forwardRef(function Calendar2({
2233
2179
  {
2234
2180
  type: "button",
2235
2181
  "aria-label": "Previous month",
2236
- onClick: () => setViewMonth((m) => addMonths(m, -1)),
2182
+ onClick: () => onViewMonthChange(addMonths(viewMonth, -1)),
2237
2183
  className: "grid h-7 w-7 place-items-center rounded-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2238
2184
  children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
2239
2185
  }
@@ -2248,7 +2194,7 @@ var Calendar = forwardRef(function Calendar2({
2248
2194
  {
2249
2195
  type: "button",
2250
2196
  "aria-label": "Next month",
2251
- onClick: () => setViewMonth((m) => addMonths(m, 1)),
2197
+ onClick: () => onViewMonthChange(addMonths(viewMonth, 1)),
2252
2198
  className: "grid h-7 w-7 place-items-center rounded-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2253
2199
  children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
2254
2200
  }
@@ -2263,18 +2209,17 @@ var Calendar = forwardRef(function Calendar2({
2263
2209
  w
2264
2210
  )) }),
2265
2211
  /* @__PURE__ */ jsx("div", { ref: gridRef, className: "grid grid-cols-7 gap-0 px-1", role: "grid", children: cells.map(({ date, outOfMonth }) => {
2266
- const disabled = isDateDisabled(date, { min, max, isDisabled });
2267
- const isSelectedCell = isSameDay(selected, date);
2212
+ const disabled = isDayDisabled?.(date) ?? false;
2268
2213
  const isFocusedCell = isSameDay(focusedDate, date);
2214
+ const consumerProps = dayProps?.(date, { outOfMonth }) ?? {};
2215
+ const { className: cellClassName, ...consumerRest } = consumerProps;
2269
2216
  return /* @__PURE__ */ jsx(
2270
2217
  "button",
2271
2218
  {
2272
2219
  type: "button",
2273
2220
  role: "gridcell",
2274
2221
  "data-date": date.toDateString(),
2275
- "aria-selected": isSelectedCell,
2276
2222
  "aria-disabled": disabled || void 0,
2277
- "data-selected": isSelectedCell ? "" : void 0,
2278
2223
  "data-today": isToday(date) ? "" : void 0,
2279
2224
  "data-out-of-month": outOfMonth ? "" : void 0,
2280
2225
  "data-disabled": disabled ? "" : void 0,
@@ -2282,19 +2227,19 @@ var Calendar = forwardRef(function Calendar2({
2282
2227
  disabled,
2283
2228
  onClick: () => {
2284
2229
  if (disabled) return;
2285
- setSelected(date);
2286
- setFocusedDate(date);
2287
- if (outOfMonth) setViewMonth(startOfMonth(date));
2230
+ onDayActivate?.(date, { outOfMonth });
2231
+ onFocusedDateChange(date);
2232
+ if (outOfMonth) onViewMonthChange(startOfMonth(date));
2288
2233
  },
2289
- onKeyDown: (e) => onCellKeyDown(e, date),
2234
+ onKeyDown: (e) => onCellKeyDown(e, date, outOfMonth),
2235
+ ...consumerRest,
2290
2236
  className: cn(
2291
- "grid h-9 w-9 place-items-center rounded-sm text-sm transition-colors",
2237
+ "grid h-9 w-9 place-items-center text-sm transition-colors",
2292
2238
  "hover:bg-muted hover:text-foreground",
2293
2239
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2294
2240
  outOfMonth && "text-muted-foreground/60",
2295
- isToday(date) && !isSelectedCell && "border border-border",
2296
- isSelectedCell && "bg-primary text-primary-foreground hover:bg-primary",
2297
- disabled && "pointer-events-none opacity-40"
2241
+ disabled && "pointer-events-none opacity-40",
2242
+ cellClassName
2298
2243
  ),
2299
2244
  children: date.getDate()
2300
2245
  },
@@ -2304,6 +2249,52 @@ var Calendar = forwardRef(function Calendar2({
2304
2249
  ]
2305
2250
  }
2306
2251
  );
2252
+ }
2253
+ var Calendar = forwardRef(function Calendar2({
2254
+ value,
2255
+ defaultValue,
2256
+ onChange,
2257
+ defaultMonth,
2258
+ min,
2259
+ max,
2260
+ isDisabled,
2261
+ "aria-label": ariaLabel = "Calendar",
2262
+ className,
2263
+ ...rest
2264
+ }, ref) {
2265
+ const [selected, setSelected] = useControlled({
2266
+ controlled: value,
2267
+ default: defaultValue ?? null,
2268
+ onChange
2269
+ });
2270
+ const [viewMonth, setViewMonth] = useState(
2271
+ () => startOfMonth(defaultMonth ?? selected ?? /* @__PURE__ */ new Date())
2272
+ );
2273
+ const [focusedDate, setFocusedDate] = useState(() => selected ?? /* @__PURE__ */ new Date());
2274
+ return /* @__PURE__ */ jsx("div", { ref, className: cn(className), ...rest, children: /* @__PURE__ */ jsx(
2275
+ MonthGrid,
2276
+ {
2277
+ viewMonth,
2278
+ onViewMonthChange: setViewMonth,
2279
+ focusedDate,
2280
+ onFocusedDateChange: setFocusedDate,
2281
+ isDayDisabled: (d) => isDateDisabled(d, { min, max, isDisabled }),
2282
+ onDayActivate: (d) => setSelected(d),
2283
+ dayProps: (date) => {
2284
+ const isSelectedCell = isSameDay(selected, date);
2285
+ return {
2286
+ "aria-selected": isSelectedCell,
2287
+ "data-selected": isSelectedCell ? "" : void 0,
2288
+ className: cn(
2289
+ "rounded-sm",
2290
+ isToday(date) && !isSelectedCell && "border border-border",
2291
+ isSelectedCell && "bg-primary text-primary-foreground hover:bg-primary"
2292
+ )
2293
+ };
2294
+ },
2295
+ "aria-label": ariaLabel
2296
+ }
2297
+ ) });
2307
2298
  });
2308
2299
  var DateField = forwardRef(function DateField2({ value, defaultValue, onChange, min, max, size, state, className, id, disabled, required, ...rest }, ref) {
2309
2300
  const ctx = useFormControl();
@@ -2382,190 +2373,59 @@ var RangeCalendar = forwardRef(
2382
2373
  const [viewMonth, setViewMonth] = useState(
2383
2374
  () => startOfMonth(defaultMonth ?? range?.start ?? /* @__PURE__ */ new Date())
2384
2375
  );
2385
- const [focusedDate, setFocusedDate] = useState(
2386
- () => range?.start ?? /* @__PURE__ */ new Date()
2387
- );
2376
+ const [focusedDate, setFocusedDate] = useState(() => range?.start ?? /* @__PURE__ */ new Date());
2388
2377
  const [hoveredDate, setHoveredDate] = useState(null);
2389
2378
  const [pendingStart, setPendingStart] = useState(null);
2390
- const gridRef = useRef(null);
2391
- useEffect(() => {
2392
- const cell = gridRef.current?.querySelector(
2393
- `[data-date="${focusedDate.toDateString()}"]`
2394
- );
2395
- cell?.focus();
2396
- }, [focusedDate]);
2397
- const moveFocus = useCallback(
2398
- (next) => {
2399
- if (next.getMonth() !== viewMonth.getMonth() || next.getFullYear() !== viewMonth.getFullYear()) {
2400
- setViewMonth(startOfMonth(next));
2401
- }
2402
- setFocusedDate(next);
2403
- },
2404
- [viewMonth]
2405
- );
2406
- const onSelectDay = useCallback(
2407
- (date) => {
2408
- if (isDateDisabled(date, { min, max, isDisabled })) return;
2409
- if (!pendingStart) {
2410
- setPendingStart(date);
2411
- setRange({ start: date, end: null });
2412
- return;
2413
- }
2414
- const startTime = startOfDay(pendingStart).getTime();
2415
- const endTime = startOfDay(date).getTime();
2416
- const finalStart = startTime <= endTime ? pendingStart : date;
2417
- const finalEnd = startTime <= endTime ? date : pendingStart;
2418
- setRange({ start: finalStart, end: finalEnd });
2419
- setPendingStart(null);
2420
- },
2421
- [pendingStart, setRange, min, max, isDisabled]
2422
- );
2423
- const onCellKeyDown = useCallback(
2424
- (e, date) => {
2425
- switch (e.key) {
2426
- case "ArrowRight":
2427
- e.preventDefault();
2428
- moveFocus(addDays(date, 1));
2429
- break;
2430
- case "ArrowLeft":
2431
- e.preventDefault();
2432
- moveFocus(addDays(date, -1));
2433
- break;
2434
- case "ArrowDown":
2435
- e.preventDefault();
2436
- moveFocus(addDays(date, 7));
2437
- break;
2438
- case "ArrowUp":
2439
- e.preventDefault();
2440
- moveFocus(addDays(date, -7));
2441
- break;
2442
- case "Home":
2443
- e.preventDefault();
2444
- moveFocus(addDays(date, -date.getDay()));
2445
- break;
2446
- case "End":
2447
- e.preventDefault();
2448
- moveFocus(addDays(date, 6 - date.getDay()));
2449
- break;
2450
- case "PageDown":
2451
- e.preventDefault();
2452
- moveFocus(addMonths(date, e.shiftKey ? 12 : 1));
2453
- break;
2454
- case "PageUp":
2455
- e.preventDefault();
2456
- moveFocus(addMonths(date, e.shiftKey ? -12 : -1));
2457
- break;
2458
- case "Enter":
2459
- case " ":
2460
- e.preventDefault();
2461
- onSelectDay(date);
2462
- break;
2463
- }
2464
- },
2465
- [moveFocus, onSelectDay]
2466
- );
2467
- const cells = buildMonthGrid(viewMonth.getFullYear(), viewMonth.getMonth());
2379
+ const handleActivate = (date) => {
2380
+ if (!pendingStart) {
2381
+ setPendingStart(date);
2382
+ setRange({ start: date, end: null });
2383
+ return;
2384
+ }
2385
+ const startTime = startOfDay(pendingStart).getTime();
2386
+ const endTime = startOfDay(date).getTime();
2387
+ const finalStart = startTime <= endTime ? pendingStart : date;
2388
+ const finalEnd = startTime <= endTime ? date : pendingStart;
2389
+ setRange({ start: finalStart, end: finalEnd });
2390
+ setPendingStart(null);
2391
+ };
2468
2392
  const previewEnd = pendingStart ? hoveredDate : range?.end;
2469
2393
  const isStart = (d) => isSameDay(d, range?.start ?? null) || isSameDay(d, pendingStart);
2470
2394
  const isEnd = (d) => isSameDay(d, range?.end ?? null);
2471
2395
  const inRange = (d) => isInRange(d, pendingStart ?? range?.start, previewEnd ?? null);
2472
- return /* @__PURE__ */ jsxs(
2473
- "div",
2396
+ return /* @__PURE__ */ jsx("div", { ref, className: cn(className), ...rest, children: /* @__PURE__ */ jsx(
2397
+ MonthGrid,
2474
2398
  {
2475
- ref,
2476
- role: "application",
2477
- "aria-label": ariaLabel,
2478
- className: cn(
2479
- "inline-flex flex-col gap-2 rounded-md border border-border bg-popover p-3 text-popover-foreground",
2480
- className
2481
- ),
2482
- ...rest,
2483
- children: [
2484
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-1", children: [
2485
- /* @__PURE__ */ jsx(
2486
- "button",
2487
- {
2488
- type: "button",
2489
- "aria-label": "Previous month",
2490
- onClick: () => setViewMonth((m) => addMonths(m, -1)),
2491
- className: "grid h-7 w-7 place-items-center rounded-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2492
- children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
2493
- }
2494
- ),
2495
- /* @__PURE__ */ jsxs("div", { className: "text-sm font-medium", "aria-live": "polite", children: [
2496
- MONTHS_LONG[viewMonth.getMonth()],
2497
- " ",
2498
- viewMonth.getFullYear()
2499
- ] }),
2500
- /* @__PURE__ */ jsx(
2501
- "button",
2502
- {
2503
- type: "button",
2504
- "aria-label": "Next month",
2505
- onClick: () => setViewMonth((m) => addMonths(m, 1)),
2506
- className: "grid h-7 w-7 place-items-center rounded-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2507
- children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
2508
- }
2399
+ viewMonth,
2400
+ onViewMonthChange: setViewMonth,
2401
+ focusedDate,
2402
+ onFocusedDateChange: setFocusedDate,
2403
+ isDayDisabled: (d) => isDateDisabled(d, { min, max, isDisabled }),
2404
+ onDayActivate: handleActivate,
2405
+ dayProps: (date) => {
2406
+ const startCell = isStart(date);
2407
+ const endCell = isEnd(date);
2408
+ const rangeCell = inRange(date) && !startCell && !endCell;
2409
+ const selected = startCell || endCell;
2410
+ return {
2411
+ "aria-selected": selected,
2412
+ "data-range-start": startCell ? "" : void 0,
2413
+ "data-range-end": endCell ? "" : void 0,
2414
+ "data-in-range": rangeCell ? "" : void 0,
2415
+ onPointerEnter: () => setHoveredDate(date),
2416
+ onPointerLeave: () => setHoveredDate((h) => isSameDay(h, date) ? null : h),
2417
+ className: cn(
2418
+ isToday(date) && !startCell && !endCell && "border border-border rounded-sm",
2419
+ rangeCell && "bg-primary-soft text-primary-soft-foreground",
2420
+ startCell && "bg-primary text-primary-foreground rounded-l-sm",
2421
+ endCell && "bg-primary text-primary-foreground rounded-r-sm",
2422
+ !startCell && !endCell && !rangeCell && "rounded-sm"
2509
2423
  )
2510
- ] }),
2511
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-0 px-1", children: WEEKDAYS_SHORT.map((w) => /* @__PURE__ */ jsx(
2512
- "div",
2513
- {
2514
- className: "grid h-7 w-9 place-items-center text-xs font-medium text-muted-foreground",
2515
- children: w
2516
- },
2517
- w
2518
- )) }),
2519
- /* @__PURE__ */ jsx("div", { ref: gridRef, className: "grid grid-cols-7 gap-0 px-1", role: "grid", children: cells.map(({ date, outOfMonth }) => {
2520
- const disabled = isDateDisabled(date, { min, max, isDisabled });
2521
- const startCell = isStart(date);
2522
- const endCell = isEnd(date);
2523
- const rangeCell = inRange(date) && !startCell && !endCell;
2524
- const isFocusedCell = isSameDay(focusedDate, date);
2525
- return /* @__PURE__ */ jsx(
2526
- "button",
2527
- {
2528
- type: "button",
2529
- role: "gridcell",
2530
- "data-date": date.toDateString(),
2531
- "data-range-start": startCell ? "" : void 0,
2532
- "data-range-end": endCell ? "" : void 0,
2533
- "data-in-range": rangeCell ? "" : void 0,
2534
- "data-today": isToday(date) ? "" : void 0,
2535
- "data-out-of-month": outOfMonth ? "" : void 0,
2536
- "data-disabled": disabled ? "" : void 0,
2537
- "aria-selected": startCell || endCell,
2538
- "aria-disabled": disabled || void 0,
2539
- tabIndex: isFocusedCell ? 0 : -1,
2540
- disabled,
2541
- onPointerEnter: () => setHoveredDate(date),
2542
- onPointerLeave: () => setHoveredDate((h) => isSameDay(h, date) ? null : h),
2543
- onClick: () => {
2544
- onSelectDay(date);
2545
- setFocusedDate(date);
2546
- if (outOfMonth) setViewMonth(startOfMonth(date));
2547
- },
2548
- onKeyDown: (e) => onCellKeyDown(e, date),
2549
- className: cn(
2550
- "grid h-9 w-9 place-items-center text-sm transition-colors",
2551
- "hover:bg-muted hover:text-foreground",
2552
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2553
- outOfMonth && "text-muted-foreground/60",
2554
- isToday(date) && !startCell && !endCell && "border border-border rounded-sm",
2555
- rangeCell && "bg-primary-soft text-primary-soft-foreground",
2556
- startCell && "bg-primary text-primary-foreground rounded-l-sm",
2557
- endCell && "bg-primary text-primary-foreground rounded-r-sm",
2558
- !startCell && !endCell && !rangeCell && "rounded-sm",
2559
- disabled && "pointer-events-none opacity-40"
2560
- ),
2561
- children: date.getDate()
2562
- },
2563
- date.toDateString()
2564
- );
2565
- }) })
2566
- ]
2424
+ };
2425
+ },
2426
+ "aria-label": ariaLabel
2567
2427
  }
2568
- );
2428
+ ) });
2569
2429
  }
2570
2430
  );
2571
2431
  var defaultFormat = (d) => d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
@@ -2584,7 +2444,6 @@ var DatePicker = forwardRef(function DatePicker2({
2584
2444
  state,
2585
2445
  className,
2586
2446
  disabled,
2587
- onClick,
2588
2447
  ...rest
2589
2448
  }, forwardedRef) {
2590
2449
  const [date, setDate] = useControlled({
@@ -2596,23 +2455,14 @@ var DatePicker = forwardRef(function DatePicker2({
2596
2455
  controlled: void 0,
2597
2456
  default: false
2598
2457
  });
2599
- const triggerRef = useRef(null);
2600
2458
  const triggerState = state ?? (invalid ? "invalid" : "default");
2601
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2602
- /* @__PURE__ */ jsxs(
2459
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, placement: "bottom-start", offset: 6, children: [
2460
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
2603
2461
  "button",
2604
2462
  {
2605
- ref: composeRefs(forwardedRef, triggerRef),
2463
+ ref: forwardedRef,
2606
2464
  type: "button",
2607
- "aria-haspopup": "dialog",
2608
- "aria-expanded": open,
2609
- "data-state": open ? "open" : "closed",
2610
2465
  disabled,
2611
- onClick: (e) => {
2612
- onClick?.(e);
2613
- if (e.defaultPrevented) return;
2614
- setOpen(!open);
2615
- },
2616
2466
  className: cn(selectTriggerVariants({ size, state: triggerState }), className),
2617
2467
  ...rest,
2618
2468
  children: [
@@ -2620,36 +2470,21 @@ var DatePicker = forwardRef(function DatePicker2({
2620
2470
  /* @__PURE__ */ jsx(Calendar$1, { className: "h-4 w-4 shrink-0 text-muted-foreground" })
2621
2471
  ]
2622
2472
  }
2623
- ),
2624
- open && /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(AnchoredPositioner, { anchor: triggerRef.current, placement: "bottom-start", offset: 6, children: /* @__PURE__ */ jsx(FocusScope, { asChild: true, trapped: true, loop: true, children: /* @__PURE__ */ jsx(
2625
- DismissableLayer,
2473
+ ) }),
2474
+ /* @__PURE__ */ jsx(PopoverContent, { bare: true, children: /* @__PURE__ */ jsx(
2475
+ Calendar,
2626
2476
  {
2627
- onEscape: () => {
2628
- setOpen(false);
2629
- requestAnimationFrame(() => triggerRef.current?.focus());
2630
- },
2631
- onOutsidePointerDown: (e) => {
2632
- if (triggerRef.current?.contains(e.target)) return;
2477
+ value: date,
2478
+ onChange: (d) => {
2479
+ setDate(d);
2633
2480
  setOpen(false);
2634
2481
  },
2635
- children: /* @__PURE__ */ jsx(
2636
- Calendar,
2637
- {
2638
- value: date,
2639
- onChange: (d) => {
2640
- setDate(d);
2641
- setOpen(false);
2642
- requestAnimationFrame(() => triggerRef.current?.focus());
2643
- },
2644
- defaultMonth: date ?? /* @__PURE__ */ new Date(),
2645
- min,
2646
- max,
2647
- isDisabled: dayDisabled,
2648
- className: "shadow-md"
2649
- }
2650
- )
2482
+ defaultMonth: date ?? /* @__PURE__ */ new Date(),
2483
+ min,
2484
+ max,
2485
+ isDisabled: dayDisabled
2651
2486
  }
2652
- ) }) }) }),
2487
+ ) }),
2653
2488
  name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: formatISODate(date) })
2654
2489
  ] });
2655
2490
  });
@@ -2668,7 +2503,6 @@ var TimePicker = forwardRef(function TimePicker2({
2668
2503
  state,
2669
2504
  className,
2670
2505
  disabled,
2671
- onClick,
2672
2506
  ...rest
2673
2507
  }, forwardedRef) {
2674
2508
  const [time, setTime] = useControlled({
@@ -2680,7 +2514,6 @@ var TimePicker = forwardRef(function TimePicker2({
2680
2514
  controlled: void 0,
2681
2515
  default: false
2682
2516
  });
2683
- const triggerRef = useRef(null);
2684
2517
  const hoursRef = useRef(null);
2685
2518
  const minutesRef = useRef(null);
2686
2519
  const minutes = useMemo(() => {
@@ -2703,21 +2536,13 @@ var TimePicker = forwardRef(function TimePicker2({
2703
2536
  };
2704
2537
  setTime(merged);
2705
2538
  };
2706
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2707
- /* @__PURE__ */ jsxs(
2539
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, placement: "bottom-start", offset: 6, children: [
2540
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
2708
2541
  "button",
2709
2542
  {
2710
- ref: composeRefs(forwardedRef, triggerRef),
2543
+ ref: forwardedRef,
2711
2544
  type: "button",
2712
- "aria-haspopup": "dialog",
2713
- "aria-expanded": open,
2714
- "data-state": open ? "open" : "closed",
2715
2545
  disabled,
2716
- onClick: (e) => {
2717
- onClick?.(e);
2718
- if (e.defaultPrevented) return;
2719
- setOpen(!open);
2720
- },
2721
2546
  className: cn(selectTriggerVariants({ size, state: triggerState }), className),
2722
2547
  ...rest,
2723
2548
  children: [
@@ -2725,79 +2550,66 @@ var TimePicker = forwardRef(function TimePicker2({
2725
2550
  /* @__PURE__ */ jsx(Clock, { className: "h-4 w-4 shrink-0 text-muted-foreground" })
2726
2551
  ]
2727
2552
  }
2728
- ),
2729
- open && /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(AnchoredPositioner, { anchor: triggerRef.current, placement: "bottom-start", offset: 6, children: /* @__PURE__ */ jsx(FocusScope, { asChild: true, trapped: true, loop: true, children: /* @__PURE__ */ jsx(
2730
- DismissableLayer,
2731
- {
2732
- onEscape: () => {
2733
- setOpen(false);
2734
- requestAnimationFrame(() => triggerRef.current?.focus());
2735
- },
2736
- onOutsidePointerDown: (e) => {
2737
- if (triggerRef.current?.contains(e.target)) return;
2738
- setOpen(false);
2739
- },
2740
- children: /* @__PURE__ */ jsxs("div", { className: "z-50 flex gap-1 rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-md outline-none animate-in fade-in-0 zoom-in-95", children: [
2741
- /* @__PURE__ */ jsx(
2742
- "div",
2743
- {
2744
- ref: hoursRef,
2745
- role: "listbox",
2746
- "aria-label": "Hours",
2747
- className: "flex max-h-56 flex-col gap-0.5 overflow-y-auto pr-1",
2748
- children: HOURS.map((h) => {
2749
- const selected = time?.hours === h;
2750
- return /* @__PURE__ */ jsx(
2751
- "button",
2752
- {
2753
- type: "button",
2754
- role: "option",
2755
- "aria-selected": selected,
2756
- "data-selected": selected ? "" : void 0,
2757
- onClick: () => update({ hours: h }),
2758
- className: cn(
2759
- "grid h-8 w-12 place-items-center rounded-sm text-sm transition-colors hover:bg-muted",
2760
- selected && "bg-primary text-primary-foreground hover:bg-primary"
2761
- ),
2762
- children: String(h).padStart(2, "0")
2763
- },
2764
- h
2765
- );
2766
- })
2767
- }
2768
- ),
2769
- /* @__PURE__ */ jsx("div", { className: "w-px self-stretch bg-border" }),
2770
- /* @__PURE__ */ jsx(
2771
- "div",
2772
- {
2773
- ref: minutesRef,
2774
- role: "listbox",
2775
- "aria-label": "Minutes",
2776
- className: "flex max-h-56 flex-col gap-0.5 overflow-y-auto pl-1",
2777
- children: minutes.map((m) => {
2778
- const selected = time?.minutes === m;
2779
- return /* @__PURE__ */ jsx(
2780
- "button",
2781
- {
2782
- type: "button",
2783
- role: "option",
2784
- "aria-selected": selected,
2785
- "data-selected": selected ? "" : void 0,
2786
- onClick: () => update({ minutes: m }),
2787
- className: cn(
2788
- "grid h-8 w-12 place-items-center rounded-sm text-sm transition-colors hover:bg-muted",
2789
- selected && "bg-primary text-primary-foreground hover:bg-primary"
2790
- ),
2791
- children: String(m).padStart(2, "0")
2792
- },
2793
- m
2794
- );
2795
- })
2796
- }
2797
- )
2798
- ] })
2799
- }
2800
- ) }) }) }),
2553
+ ) }),
2554
+ /* @__PURE__ */ jsx(PopoverContent, { bare: true, children: /* @__PURE__ */ jsxs("div", { className: "flex gap-1 rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-md", children: [
2555
+ /* @__PURE__ */ jsx(
2556
+ "div",
2557
+ {
2558
+ ref: hoursRef,
2559
+ role: "listbox",
2560
+ "aria-label": "Hours",
2561
+ className: "flex max-h-56 flex-col gap-0.5 overflow-y-auto pr-1",
2562
+ children: HOURS.map((h) => {
2563
+ const selected = time?.hours === h;
2564
+ return /* @__PURE__ */ jsx(
2565
+ "button",
2566
+ {
2567
+ type: "button",
2568
+ role: "option",
2569
+ "aria-selected": selected,
2570
+ "data-selected": selected ? "" : void 0,
2571
+ onClick: () => update({ hours: h }),
2572
+ className: cn(
2573
+ "grid h-8 w-12 place-items-center rounded-sm text-sm transition-colors hover:bg-muted",
2574
+ selected && "bg-primary text-primary-foreground hover:bg-primary"
2575
+ ),
2576
+ children: String(h).padStart(2, "0")
2577
+ },
2578
+ h
2579
+ );
2580
+ })
2581
+ }
2582
+ ),
2583
+ /* @__PURE__ */ jsx("div", { className: "w-px self-stretch bg-border" }),
2584
+ /* @__PURE__ */ jsx(
2585
+ "div",
2586
+ {
2587
+ ref: minutesRef,
2588
+ role: "listbox",
2589
+ "aria-label": "Minutes",
2590
+ className: "flex max-h-56 flex-col gap-0.5 overflow-y-auto pl-1",
2591
+ children: minutes.map((m) => {
2592
+ const selected = time?.minutes === m;
2593
+ return /* @__PURE__ */ jsx(
2594
+ "button",
2595
+ {
2596
+ type: "button",
2597
+ role: "option",
2598
+ "aria-selected": selected,
2599
+ "data-selected": selected ? "" : void 0,
2600
+ onClick: () => update({ minutes: m }),
2601
+ className: cn(
2602
+ "grid h-8 w-12 place-items-center rounded-sm text-sm transition-colors hover:bg-muted",
2603
+ selected && "bg-primary text-primary-foreground hover:bg-primary"
2604
+ ),
2605
+ children: String(m).padStart(2, "0")
2606
+ },
2607
+ m
2608
+ );
2609
+ })
2610
+ }
2611
+ )
2612
+ ] }) }),
2801
2613
  name && time && /* @__PURE__ */ jsx(
2802
2614
  "input",
2803
2615
  {
@@ -2825,7 +2637,6 @@ var DateRangePicker = forwardRef(
2825
2637
  state,
2826
2638
  className,
2827
2639
  disabled,
2828
- onClick,
2829
2640
  ...rest
2830
2641
  }, forwardedRef) {
2831
2642
  const [range, setRange] = useControlled({
@@ -2837,33 +2648,23 @@ var DateRangePicker = forwardRef(
2837
2648
  controlled: void 0,
2838
2649
  default: false
2839
2650
  });
2840
- const triggerRef = useRef(null);
2841
2651
  const triggerState = state ?? (invalid ? "invalid" : "default");
2842
2652
  const wasComplete = useRef(false);
2843
2653
  useEffect(() => {
2844
2654
  const complete = !!(range?.start && range?.end);
2845
2655
  if (complete && !wasComplete.current && open) {
2846
2656
  setOpen(false);
2847
- requestAnimationFrame(() => triggerRef.current?.focus());
2848
2657
  }
2849
2658
  wasComplete.current = complete;
2850
2659
  }, [range, open, setOpen]);
2851
2660
  const display = range?.start ? range.end ? `${format(range.start)} \u2192 ${format(range.end)}` : `${format(range.start)} \u2192 \u2026` : null;
2852
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2853
- /* @__PURE__ */ jsxs(
2661
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, placement: "bottom-start", offset: 6, children: [
2662
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
2854
2663
  "button",
2855
2664
  {
2856
- ref: composeRefs(forwardedRef, triggerRef),
2665
+ ref: forwardedRef,
2857
2666
  type: "button",
2858
- "aria-haspopup": "dialog",
2859
- "aria-expanded": open,
2860
- "data-state": open ? "open" : "closed",
2861
2667
  disabled,
2862
- onClick: (e) => {
2863
- onClick?.(e);
2864
- if (e.defaultPrevented) return;
2865
- setOpen(!open);
2866
- },
2867
2668
  className: cn(selectTriggerVariants({ size, state: triggerState }), className),
2868
2669
  ...rest,
2869
2670
  children: [
@@ -2871,32 +2672,18 @@ var DateRangePicker = forwardRef(
2871
2672
  /* @__PURE__ */ jsx(Calendar$1, { className: "h-4 w-4 shrink-0 text-muted-foreground" })
2872
2673
  ]
2873
2674
  }
2874
- ),
2875
- open && /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(AnchoredPositioner, { anchor: triggerRef.current, placement: "bottom-start", offset: 6, children: /* @__PURE__ */ jsx(FocusScope, { asChild: true, trapped: true, loop: true, children: /* @__PURE__ */ jsx(
2876
- DismissableLayer,
2675
+ ) }),
2676
+ /* @__PURE__ */ jsx(PopoverContent, { bare: true, children: /* @__PURE__ */ jsx(
2677
+ RangeCalendar,
2877
2678
  {
2878
- onEscape: () => {
2879
- setOpen(false);
2880
- requestAnimationFrame(() => triggerRef.current?.focus());
2881
- },
2882
- onOutsidePointerDown: (e) => {
2883
- if (triggerRef.current?.contains(e.target)) return;
2884
- setOpen(false);
2885
- },
2886
- children: /* @__PURE__ */ jsx(
2887
- RangeCalendar,
2888
- {
2889
- value: range,
2890
- onChange: setRange,
2891
- defaultMonth: range?.start ?? /* @__PURE__ */ new Date(),
2892
- min,
2893
- max,
2894
- isDisabled: dayDisabled,
2895
- className: "shadow-md"
2896
- }
2897
- )
2679
+ value: range,
2680
+ onChange: setRange,
2681
+ defaultMonth: range?.start ?? /* @__PURE__ */ new Date(),
2682
+ min,
2683
+ max,
2684
+ isDisabled: dayDisabled
2898
2685
  }
2899
- ) }) }) }),
2686
+ ) }),
2900
2687
  name && /* @__PURE__ */ jsxs(Fragment, { children: [
2901
2688
  /* @__PURE__ */ jsx("input", { type: "hidden", name: `${name}_start`, value: formatISODate(range?.start) }),
2902
2689
  /* @__PURE__ */ jsx("input", { type: "hidden", name: `${name}_end`, value: formatISODate(range?.end) })
@@ -2905,6 +2692,1040 @@ var DateRangePicker = forwardRef(
2905
2692
  }
2906
2693
  );
2907
2694
 
2908
- export { Calendar, CharacterCount, Checkbox, CheckboxField, CheckboxGroup, ChoiceCard, Combobox, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxSeparator, CurrencyInput, DateField, DatePicker, DateRangePicker, EmailInput, Fieldset, FilePicker, FormErrorMessage, FormField, FormHelperText, InputAddon, InputGroup, Label, LabeledInput, Legend, Listbox, ListboxEmpty, ListboxGroup, ListboxItem, ListboxSeparator, MaskedInput, MultiSelect, MultiSelectContent, MultiSelectItem, MultiSelectTags, MultiSelectTrigger, NumberInput, PasswordInput, PasswordStrength, PercentInput, PinInput, Radio, RadioField, RadioGroup, RangeCalendar, SearchInput, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider, Switch, SwitchField, TelInput, TextInput, Textarea, TimeField, TimePicker, UrlInput };
2909
- //# sourceMappingURL=chunk-K6V4KLRO.js.map
2910
- //# sourceMappingURL=chunk-K6V4KLRO.js.map
2695
+ // src/forms/colorSwatch/ColorSwatch.variants.ts
2696
+ var colorSwatchVariants = tv({
2697
+ base: "inline-block shrink-0 border border-border bg-[image:linear-gradient(45deg,_#ddd_25%,_transparent_25%),_linear-gradient(-45deg,_#ddd_25%,_transparent_25%),_linear-gradient(45deg,_transparent_75%,_#ddd_75%),_linear-gradient(-45deg,_transparent_75%,_#ddd_75%)] bg-[length:8px_8px] bg-[position:0_0,_0_4px,_4px_-4px,_-4px_0px]",
2698
+ variants: {
2699
+ size: {
2700
+ xs: "h-4 w-4",
2701
+ sm: "h-5 w-5",
2702
+ md: "h-6 w-6",
2703
+ lg: "h-9 w-9"
2704
+ },
2705
+ shape: {
2706
+ square: "rounded-sm",
2707
+ circle: "rounded-full"
2708
+ },
2709
+ interactive: {
2710
+ true: "cursor-pointer transition-shadow focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 hover:shadow-sm",
2711
+ false: ""
2712
+ },
2713
+ selected: {
2714
+ true: "ring-2 ring-ring ring-offset-1",
2715
+ false: ""
2716
+ },
2717
+ disabled: {
2718
+ true: "cursor-not-allowed opacity-50",
2719
+ false: ""
2720
+ }
2721
+ },
2722
+ defaultVariants: {
2723
+ size: "md",
2724
+ shape: "square",
2725
+ interactive: false,
2726
+ selected: false,
2727
+ disabled: false
2728
+ }
2729
+ });
2730
+ var ColorSwatch = forwardRef(function ColorSwatch2({ color = "#000000", size, shape, selected, disabled, className, onClick, style, ...rest }, ref) {
2731
+ const interactive = !!onClick;
2732
+ const classes = cn(
2733
+ colorSwatchVariants({ size, shape, interactive, selected, disabled }),
2734
+ className
2735
+ );
2736
+ const styleWithColor = {
2737
+ ...style,
2738
+ boxShadow: `inset 0 0 0 100px ${color}`
2739
+ };
2740
+ if (interactive) {
2741
+ const buttonProps = rest;
2742
+ return /* @__PURE__ */ jsx(
2743
+ "button",
2744
+ {
2745
+ ref,
2746
+ type: "button",
2747
+ disabled,
2748
+ onClick,
2749
+ style: styleWithColor,
2750
+ className: classes,
2751
+ ...buttonProps
2752
+ }
2753
+ );
2754
+ }
2755
+ const divProps = rest;
2756
+ return /* @__PURE__ */ jsx(
2757
+ "div",
2758
+ {
2759
+ ref,
2760
+ style: styleWithColor,
2761
+ className: classes,
2762
+ ...divProps
2763
+ }
2764
+ );
2765
+ });
2766
+
2767
+ // src/forms/ColorExtensions.ts
2768
+ function clamp01(n) {
2769
+ return Math.max(0, Math.min(1, n));
2770
+ }
2771
+ function clampHue(h) {
2772
+ let v = h % 360;
2773
+ if (v < 0) v += 360;
2774
+ return v;
2775
+ }
2776
+ function clampByte(n) {
2777
+ return Math.max(0, Math.min(255, Math.round(n)));
2778
+ }
2779
+ function parseHex(input) {
2780
+ if (!input) return null;
2781
+ const s = input.trim().replace(/^#/, "");
2782
+ let m = null;
2783
+ if (/^[0-9a-fA-F]{3}$/.test(s)) {
2784
+ m = s.split("").map((c) => c + c).join("");
2785
+ } else if (/^[0-9a-fA-F]{4}$/.test(s)) {
2786
+ m = s.split("").map((c) => c + c).join("");
2787
+ } else if (/^[0-9a-fA-F]{6}$/.test(s) || /^[0-9a-fA-F]{8}$/.test(s)) {
2788
+ m = s;
2789
+ }
2790
+ if (!m) return null;
2791
+ const r = parseInt(m.slice(0, 2), 16);
2792
+ const g = parseInt(m.slice(2, 4), 16);
2793
+ const b = parseInt(m.slice(4, 6), 16);
2794
+ const a = m.length === 8 ? parseInt(m.slice(6, 8), 16) / 255 : 1;
2795
+ return { r, g, b, a };
2796
+ }
2797
+ function formatHex(rgb, options) {
2798
+ if (!rgb) return "";
2799
+ const r = clampByte(rgb.r).toString(16).padStart(2, "0");
2800
+ const g = clampByte(rgb.g).toString(16).padStart(2, "0");
2801
+ const b = clampByte(rgb.b).toString(16).padStart(2, "0");
2802
+ const includeAlpha = options?.withAlpha ?? (rgb.a !== void 0 && rgb.a < 1);
2803
+ if (includeAlpha) {
2804
+ const a = clampByte((rgb.a ?? 1) * 255).toString(16).padStart(2, "0");
2805
+ return `#${r}${g}${b}${a}`;
2806
+ }
2807
+ return `#${r}${g}${b}`;
2808
+ }
2809
+ function rgbToHsv({ r, g, b, a = 1 }) {
2810
+ const rn = r / 255;
2811
+ const gn = g / 255;
2812
+ const bn = b / 255;
2813
+ const max = Math.max(rn, gn, bn);
2814
+ const min = Math.min(rn, gn, bn);
2815
+ const d = max - min;
2816
+ let h = 0;
2817
+ if (d !== 0) {
2818
+ if (max === rn) h = (gn - bn) / d % 6;
2819
+ else if (max === gn) h = (bn - rn) / d + 2;
2820
+ else h = (rn - gn) / d + 4;
2821
+ h *= 60;
2822
+ if (h < 0) h += 360;
2823
+ }
2824
+ const s = max === 0 ? 0 : d / max;
2825
+ const v = max;
2826
+ return { h, s, v, a };
2827
+ }
2828
+ function hsvToRgb({ h, s, v, a = 1 }) {
2829
+ const c = v * s;
2830
+ const hh = clampHue(h) / 60;
2831
+ const x = c * (1 - Math.abs(hh % 2 - 1));
2832
+ let r1 = 0;
2833
+ let g1 = 0;
2834
+ let b1 = 0;
2835
+ if (hh >= 0 && hh < 1) [r1, g1, b1] = [c, x, 0];
2836
+ else if (hh < 2) [r1, g1, b1] = [x, c, 0];
2837
+ else if (hh < 3) [r1, g1, b1] = [0, c, x];
2838
+ else if (hh < 4) [r1, g1, b1] = [0, x, c];
2839
+ else if (hh < 5) [r1, g1, b1] = [x, 0, c];
2840
+ else [r1, g1, b1] = [c, 0, x];
2841
+ const m = v - c;
2842
+ return {
2843
+ r: Math.round((r1 + m) * 255),
2844
+ g: Math.round((g1 + m) * 255),
2845
+ b: Math.round((b1 + m) * 255),
2846
+ a
2847
+ };
2848
+ }
2849
+ function parseColorToHsv(input) {
2850
+ const rgb = parseHex(input);
2851
+ if (!rgb) return null;
2852
+ return rgbToHsv(rgb);
2853
+ }
2854
+ function hsvToHex(hsv, options) {
2855
+ return formatHex(hsvToRgb(hsv), options);
2856
+ }
2857
+ function commitHex(text, withAlpha) {
2858
+ const normalised = text.startsWith("#") ? text : `#${text}`;
2859
+ const rgb = parseHex(normalised);
2860
+ if (!rgb) return null;
2861
+ return formatHex(rgb, { withAlpha });
2862
+ }
2863
+ var ColorField = forwardRef(function ColorField2({
2864
+ value,
2865
+ defaultValue,
2866
+ onChange,
2867
+ swatchShape = "square",
2868
+ withAlpha = false,
2869
+ size,
2870
+ state,
2871
+ className,
2872
+ id,
2873
+ disabled,
2874
+ required,
2875
+ onBlur,
2876
+ onKeyDown,
2877
+ ...rest
2878
+ }, ref) {
2879
+ const ctx = useFormControl();
2880
+ const [committed, setCommitted] = useControlled({
2881
+ controlled: value,
2882
+ default: defaultValue ?? null,
2883
+ onChange
2884
+ });
2885
+ const [draft, setDraft] = useState(committed ?? "");
2886
+ useEffect(() => {
2887
+ setDraft(committed ?? "");
2888
+ }, [committed]);
2889
+ const commit = () => {
2890
+ if (!draft) {
2891
+ setCommitted(null);
2892
+ return;
2893
+ }
2894
+ const next = commitHex(draft, withAlpha);
2895
+ if (next) {
2896
+ setCommitted(next);
2897
+ setDraft(next);
2898
+ } else {
2899
+ setDraft(committed ?? "");
2900
+ }
2901
+ };
2902
+ return /* @__PURE__ */ jsxs("div", { className: "relative inline-flex w-full items-stretch", children: [
2903
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute inset-y-0 left-2 flex items-center", children: /* @__PURE__ */ jsx(ColorSwatch, { color: committed ?? "#00000000", size: "sm", shape: swatchShape }) }),
2904
+ /* @__PURE__ */ jsx(
2905
+ "input",
2906
+ {
2907
+ ref,
2908
+ type: "text",
2909
+ id: id ?? ctx?.id,
2910
+ disabled: disabled ?? ctx?.isDisabled,
2911
+ required: required ?? ctx?.isRequired,
2912
+ "aria-invalid": ctx?.isInvalid || void 0,
2913
+ "aria-describedby": ctx ? `${ctx.helperId} ${ctx.errorId}` : void 0,
2914
+ spellCheck: false,
2915
+ autoCapitalize: "none",
2916
+ autoCorrect: "off",
2917
+ value: draft,
2918
+ onChange: (e) => setDraft(e.target.value),
2919
+ onBlur: (e) => {
2920
+ onBlur?.(e);
2921
+ commit();
2922
+ },
2923
+ onKeyDown: (e) => {
2924
+ onKeyDown?.(e);
2925
+ if (e.defaultPrevented) return;
2926
+ if (e.key === "Enter") {
2927
+ e.preventDefault();
2928
+ commit();
2929
+ }
2930
+ },
2931
+ className: cn(
2932
+ inputBaseVariants({ size, state: state ?? (ctx?.isInvalid ? "invalid" : "default") }),
2933
+ "pl-9 font-mono uppercase",
2934
+ className
2935
+ ),
2936
+ ...rest
2937
+ }
2938
+ )
2939
+ ] });
2940
+ });
2941
+ function channelMax(channel) {
2942
+ return channel === "hue" ? 360 : 1;
2943
+ }
2944
+ function defaultStep(channel) {
2945
+ return channel === "hue" ? 1 : 0.01;
2946
+ }
2947
+ function buildGradient(channel, color) {
2948
+ if (channel === "hue") {
2949
+ return "linear-gradient(to right, hsl(0,100%,50%), hsl(60,100%,50%), hsl(120,100%,50%), hsl(180,100%,50%), hsl(240,100%,50%), hsl(300,100%,50%), hsl(360,100%,50%))";
2950
+ }
2951
+ const ctx = color ?? { h: 0, s: 1, v: 1 };
2952
+ if (channel === "saturation") {
2953
+ const start = hsvToHex({ h: ctx.h, s: 0, v: ctx.v });
2954
+ const end = hsvToHex({ h: ctx.h, s: 1, v: ctx.v });
2955
+ return `linear-gradient(to right, ${start}, ${end})`;
2956
+ }
2957
+ if (channel === "value") {
2958
+ const end = hsvToHex({ h: ctx.h, s: ctx.s, v: 1 });
2959
+ return `linear-gradient(to right, #000000, ${end})`;
2960
+ }
2961
+ const opaque = hsvToHex({ h: ctx.h, s: ctx.s, v: ctx.v });
2962
+ return `linear-gradient(to right, transparent, ${opaque})`;
2963
+ }
2964
+ var CHECKERBOARD = {
2965
+ backgroundImage: "linear-gradient(45deg, #ddd 25%, transparent 25%), linear-gradient(-45deg, #ddd 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #ddd 75%), linear-gradient(-45deg, transparent 75%, #ddd 75%)",
2966
+ backgroundSize: "8px 8px",
2967
+ backgroundPosition: "0 0, 0 4px, 4px -4px, -4px 0px"
2968
+ };
2969
+ var ColorSlider = forwardRef(function ColorSlider2({
2970
+ channel = "hue",
2971
+ value,
2972
+ defaultValue,
2973
+ onChange,
2974
+ color,
2975
+ step,
2976
+ disabled = false,
2977
+ className,
2978
+ "aria-label": ariaLabel,
2979
+ ...rest
2980
+ }, forwardedRef) {
2981
+ const max = channelMax(channel);
2982
+ const stepValue = step ?? defaultStep(channel);
2983
+ const [val, setVal] = useControlled({
2984
+ controlled: value,
2985
+ default: defaultValue ?? 0,
2986
+ onChange
2987
+ });
2988
+ const trackRef = useRef(null);
2989
+ const updateFromClientX = useCallback(
2990
+ (clientX) => {
2991
+ const track = trackRef.current;
2992
+ if (!track) return;
2993
+ const rect = track.getBoundingClientRect();
2994
+ const ratio2 = clamp01((clientX - rect.left) / rect.width);
2995
+ const next = ratio2 * max;
2996
+ setVal(channel === "hue" ? clampHue(next) : clamp01(next));
2997
+ },
2998
+ [channel, max, setVal]
2999
+ );
3000
+ const handlePointerDown = useCallback(
3001
+ (e) => {
3002
+ if (disabled) return;
3003
+ e.preventDefault();
3004
+ e.target.setPointerCapture?.(e.pointerId);
3005
+ updateFromClientX(e.clientX);
3006
+ },
3007
+ [disabled, updateFromClientX]
3008
+ );
3009
+ const handlePointerMove = useCallback(
3010
+ (e) => {
3011
+ if (disabled) return;
3012
+ if (e.buttons !== 1) return;
3013
+ updateFromClientX(e.clientX);
3014
+ },
3015
+ [disabled, updateFromClientX]
3016
+ );
3017
+ const handleKeyDown = useCallback(
3018
+ (e) => {
3019
+ if (disabled) return;
3020
+ let next = val;
3021
+ switch (e.key) {
3022
+ case "ArrowRight":
3023
+ case "ArrowUp":
3024
+ next = val + stepValue;
3025
+ break;
3026
+ case "ArrowLeft":
3027
+ case "ArrowDown":
3028
+ next = val - stepValue;
3029
+ break;
3030
+ case "PageUp":
3031
+ next = val + stepValue * 10;
3032
+ break;
3033
+ case "PageDown":
3034
+ next = val - stepValue * 10;
3035
+ break;
3036
+ case "Home":
3037
+ next = 0;
3038
+ break;
3039
+ case "End":
3040
+ next = max;
3041
+ break;
3042
+ default:
3043
+ return;
3044
+ }
3045
+ e.preventDefault();
3046
+ setVal(channel === "hue" ? clampHue(next) : clamp01(next));
3047
+ },
3048
+ [channel, disabled, max, setVal, stepValue, val]
3049
+ );
3050
+ const ratio = channel === "hue" ? clampHue(val) / 360 : clamp01(val);
3051
+ const gradient = buildGradient(channel, color);
3052
+ const trackStyle = {
3053
+ backgroundImage: gradient,
3054
+ ...channel === "alpha" ? { backgroundColor: "transparent" } : null
3055
+ };
3056
+ return /* @__PURE__ */ jsxs(
3057
+ "div",
3058
+ {
3059
+ ref: forwardedRef,
3060
+ className: cn("relative inline-flex w-full select-none items-center", className),
3061
+ ...rest,
3062
+ children: [
3063
+ channel === "alpha" && /* @__PURE__ */ jsx(
3064
+ "div",
3065
+ {
3066
+ "aria-hidden": "true",
3067
+ className: "absolute inset-0 rounded-full",
3068
+ style: CHECKERBOARD
3069
+ }
3070
+ ),
3071
+ /* @__PURE__ */ jsx(
3072
+ "div",
3073
+ {
3074
+ ref: composeRefs(trackRef),
3075
+ role: "slider",
3076
+ tabIndex: disabled ? -1 : 0,
3077
+ "aria-label": ariaLabel ?? `${channel} slider`,
3078
+ "aria-valuemin": 0,
3079
+ "aria-valuemax": max,
3080
+ "aria-valuenow": Math.round(val * 100) / 100,
3081
+ "aria-disabled": disabled || void 0,
3082
+ "aria-orientation": "horizontal",
3083
+ "data-disabled": disabled ? "" : void 0,
3084
+ onPointerDown: handlePointerDown,
3085
+ onPointerMove: handlePointerMove,
3086
+ onKeyDown: handleKeyDown,
3087
+ style: trackStyle,
3088
+ className: cn(
3089
+ "relative h-3 w-full rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
3090
+ disabled && "pointer-events-none opacity-50"
3091
+ ),
3092
+ children: /* @__PURE__ */ jsx(
3093
+ "div",
3094
+ {
3095
+ "aria-hidden": "true",
3096
+ className: "absolute top-1/2 h-4 w-4 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white bg-transparent shadow-md ring-1 ring-black/20",
3097
+ style: { left: `${ratio * 100}%` }
3098
+ }
3099
+ )
3100
+ }
3101
+ )
3102
+ ]
3103
+ }
3104
+ );
3105
+ });
3106
+ var ColorArea = forwardRef(function ColorArea2({
3107
+ hue = 0,
3108
+ saturation,
3109
+ defaultSaturation,
3110
+ value,
3111
+ defaultValue,
3112
+ onChange,
3113
+ step = 0.01,
3114
+ disabled = false,
3115
+ className,
3116
+ "aria-label": ariaLabel = "Saturation and value",
3117
+ ...rest
3118
+ }, forwardedRef) {
3119
+ const [s, setS] = useControlled({
3120
+ controlled: saturation,
3121
+ default: defaultSaturation ?? 1
3122
+ });
3123
+ const [v, setV] = useControlled({
3124
+ controlled: value,
3125
+ default: defaultValue ?? 1
3126
+ });
3127
+ const trackRef = useRef(null);
3128
+ const emit = useCallback(
3129
+ (nextS, nextV) => {
3130
+ const cs = clamp01(nextS);
3131
+ const cv = clamp01(nextV);
3132
+ setS(cs);
3133
+ setV(cv);
3134
+ onChange?.({ saturation: cs, value: cv });
3135
+ },
3136
+ [onChange, setS, setV]
3137
+ );
3138
+ const updateFromClient = useCallback(
3139
+ (clientX, clientY) => {
3140
+ const track = trackRef.current;
3141
+ if (!track) return;
3142
+ const rect = track.getBoundingClientRect();
3143
+ const xRatio = clamp01((clientX - rect.left) / rect.width);
3144
+ const yRatio = clamp01((clientY - rect.top) / rect.height);
3145
+ emit(xRatio, 1 - yRatio);
3146
+ },
3147
+ [emit]
3148
+ );
3149
+ const handlePointerDown = useCallback(
3150
+ (e) => {
3151
+ if (disabled) return;
3152
+ e.preventDefault();
3153
+ e.target.setPointerCapture?.(e.pointerId);
3154
+ updateFromClient(e.clientX, e.clientY);
3155
+ },
3156
+ [disabled, updateFromClient]
3157
+ );
3158
+ const handlePointerMove = useCallback(
3159
+ (e) => {
3160
+ if (disabled || e.buttons !== 1) return;
3161
+ updateFromClient(e.clientX, e.clientY);
3162
+ },
3163
+ [disabled, updateFromClient]
3164
+ );
3165
+ const handleKeyDown = useCallback(
3166
+ (e) => {
3167
+ if (disabled) return;
3168
+ const big = step * 10;
3169
+ let nextS = s;
3170
+ let nextV = v;
3171
+ switch (e.key) {
3172
+ case "ArrowRight":
3173
+ nextS = s + step;
3174
+ break;
3175
+ case "ArrowLeft":
3176
+ nextS = s - step;
3177
+ break;
3178
+ case "ArrowUp":
3179
+ nextV = v + step;
3180
+ break;
3181
+ case "ArrowDown":
3182
+ nextV = v - step;
3183
+ break;
3184
+ case "PageUp":
3185
+ nextV = v + big;
3186
+ break;
3187
+ case "PageDown":
3188
+ nextV = v - big;
3189
+ break;
3190
+ case "Home":
3191
+ nextS = 0;
3192
+ nextV = 1;
3193
+ break;
3194
+ case "End":
3195
+ nextS = 1;
3196
+ nextV = 0;
3197
+ break;
3198
+ default:
3199
+ return;
3200
+ }
3201
+ e.preventDefault();
3202
+ emit(nextS, nextV);
3203
+ },
3204
+ [disabled, emit, s, step, v]
3205
+ );
3206
+ const baseColor = `hsl(${hue}, 100%, 50%)`;
3207
+ const trackStyle = {
3208
+ backgroundImage: `linear-gradient(to bottom, transparent, #000), linear-gradient(to right, #fff, transparent)`,
3209
+ backgroundColor: baseColor
3210
+ };
3211
+ const thumbColor = hsvToHex({ h: hue, s, v });
3212
+ const thumbStyle = {
3213
+ left: `${s * 100}%`,
3214
+ top: `${(1 - v) * 100}%`,
3215
+ backgroundColor: thumbColor
3216
+ };
3217
+ return /* @__PURE__ */ jsx(
3218
+ "div",
3219
+ {
3220
+ ref: composeRefs(forwardedRef, trackRef),
3221
+ role: "slider",
3222
+ tabIndex: disabled ? -1 : 0,
3223
+ "aria-label": ariaLabel,
3224
+ "aria-valuetext": `saturation ${(s * 100).toFixed(0)}%, value ${(v * 100).toFixed(0)}%`,
3225
+ "aria-disabled": disabled || void 0,
3226
+ "data-disabled": disabled ? "" : void 0,
3227
+ onPointerDown: handlePointerDown,
3228
+ onPointerMove: handlePointerMove,
3229
+ onKeyDown: handleKeyDown,
3230
+ style: trackStyle,
3231
+ className: cn(
3232
+ "relative aspect-square w-full select-none rounded-md border border-border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
3233
+ disabled && "pointer-events-none opacity-50",
3234
+ className
3235
+ ),
3236
+ ...rest,
3237
+ children: /* @__PURE__ */ jsx(
3238
+ "div",
3239
+ {
3240
+ "aria-hidden": "true",
3241
+ style: thumbStyle,
3242
+ className: "absolute h-4 w-4 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white shadow-md ring-1 ring-black/20"
3243
+ }
3244
+ )
3245
+ }
3246
+ );
3247
+ });
3248
+ function angleFromCenter(clientX, clientY, rect) {
3249
+ const cx = rect.left + rect.width / 2;
3250
+ const cy = rect.top + rect.height / 2;
3251
+ const dx = clientX - cx;
3252
+ const dy = clientY - cy;
3253
+ const angle = Math.atan2(dx, -dy) * 180 / Math.PI;
3254
+ return (angle + 360) % 360;
3255
+ }
3256
+ var ColorWheel = forwardRef(function ColorWheel2({
3257
+ value,
3258
+ defaultValue,
3259
+ onChange,
3260
+ size = 200,
3261
+ thickness = 30,
3262
+ step = 1,
3263
+ disabled = false,
3264
+ className,
3265
+ "aria-label": ariaLabel = "Hue",
3266
+ ...rest
3267
+ }, forwardedRef) {
3268
+ const [hue, setHue] = useControlled({
3269
+ controlled: value,
3270
+ default: defaultValue ?? 0,
3271
+ onChange
3272
+ });
3273
+ const trackRef = useRef(null);
3274
+ const updateFromClient = useCallback(
3275
+ (clientX, clientY) => {
3276
+ const track = trackRef.current;
3277
+ if (!track) return;
3278
+ setHue(clampHue(angleFromCenter(clientX, clientY, track.getBoundingClientRect())));
3279
+ },
3280
+ [setHue]
3281
+ );
3282
+ const handlePointerDown = useCallback(
3283
+ (e) => {
3284
+ if (disabled) return;
3285
+ e.preventDefault();
3286
+ e.target.setPointerCapture?.(e.pointerId);
3287
+ updateFromClient(e.clientX, e.clientY);
3288
+ },
3289
+ [disabled, updateFromClient]
3290
+ );
3291
+ const handlePointerMove = useCallback(
3292
+ (e) => {
3293
+ if (disabled || e.buttons !== 1) return;
3294
+ updateFromClient(e.clientX, e.clientY);
3295
+ },
3296
+ [disabled, updateFromClient]
3297
+ );
3298
+ const handleKeyDown = useCallback(
3299
+ (e) => {
3300
+ if (disabled) return;
3301
+ let next = hue;
3302
+ switch (e.key) {
3303
+ case "ArrowRight":
3304
+ case "ArrowDown":
3305
+ next = hue + step;
3306
+ break;
3307
+ case "ArrowLeft":
3308
+ case "ArrowUp":
3309
+ next = hue - step;
3310
+ break;
3311
+ case "PageUp":
3312
+ next = hue + step * 10;
3313
+ break;
3314
+ case "PageDown":
3315
+ next = hue - step * 10;
3316
+ break;
3317
+ case "Home":
3318
+ next = 0;
3319
+ break;
3320
+ case "End":
3321
+ next = 359;
3322
+ break;
3323
+ default:
3324
+ return;
3325
+ }
3326
+ e.preventDefault();
3327
+ setHue(clampHue(next));
3328
+ },
3329
+ [disabled, hue, setHue, step]
3330
+ );
3331
+ const radius = (size - thickness) / 2;
3332
+ const angleRad = hue * Math.PI / 180;
3333
+ const thumbX = size / 2 + radius * Math.sin(angleRad);
3334
+ const thumbY = size / 2 - radius * Math.cos(angleRad);
3335
+ const wheelStyle = {
3336
+ width: size,
3337
+ height: size,
3338
+ background: "conic-gradient(from 0deg, hsl(0,100%,50%), hsl(60,100%,50%), hsl(120,100%,50%), hsl(180,100%,50%), hsl(240,100%,50%), hsl(300,100%,50%), hsl(360,100%,50%))",
3339
+ WebkitMaskImage: `radial-gradient(circle, transparent ${radius - thickness / 2}px, black ${radius - thickness / 2 + 1}px, black ${radius + thickness / 2}px, transparent ${radius + thickness / 2 + 1}px)`,
3340
+ maskImage: `radial-gradient(circle, transparent ${radius - thickness / 2}px, black ${radius - thickness / 2 + 1}px, black ${radius + thickness / 2}px, transparent ${radius + thickness / 2 + 1}px)`
3341
+ };
3342
+ return /* @__PURE__ */ jsx(
3343
+ "div",
3344
+ {
3345
+ ref: composeRefs(forwardedRef, trackRef),
3346
+ role: "slider",
3347
+ tabIndex: disabled ? -1 : 0,
3348
+ "aria-label": ariaLabel,
3349
+ "aria-valuemin": 0,
3350
+ "aria-valuemax": 360,
3351
+ "aria-valuenow": Math.round(hue),
3352
+ "aria-disabled": disabled || void 0,
3353
+ "data-disabled": disabled ? "" : void 0,
3354
+ onPointerDown: handlePointerDown,
3355
+ onPointerMove: handlePointerMove,
3356
+ onKeyDown: handleKeyDown,
3357
+ style: wheelStyle,
3358
+ className: cn(
3359
+ "relative inline-block select-none rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3360
+ disabled && "pointer-events-none opacity-50",
3361
+ className
3362
+ ),
3363
+ ...rest,
3364
+ children: /* @__PURE__ */ jsx(
3365
+ "div",
3366
+ {
3367
+ "aria-hidden": "true",
3368
+ style: {
3369
+ left: thumbX,
3370
+ top: thumbY,
3371
+ backgroundColor: `hsl(${hue}, 100%, 50%)`
3372
+ },
3373
+ className: "pointer-events-none absolute h-5 w-5 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white shadow-md ring-1 ring-black/30"
3374
+ }
3375
+ )
3376
+ }
3377
+ );
3378
+ });
3379
+ function ColorSwatchItem({ color, selected, disabled, size, shape, onSelect }) {
3380
+ const roving = useRovingFocusItem();
3381
+ return /* @__PURE__ */ jsx(
3382
+ ColorSwatch,
3383
+ {
3384
+ ref: roving.ref,
3385
+ color,
3386
+ size,
3387
+ shape,
3388
+ selected,
3389
+ disabled,
3390
+ tabIndex: roving.tabIndex,
3391
+ onClick: () => onSelect(color),
3392
+ onKeyDown: (e) => {
3393
+ roving.onKeyDown(e);
3394
+ if (e.defaultPrevented) return;
3395
+ if (e.key === "Enter" || e.key === " ") {
3396
+ e.preventDefault();
3397
+ onSelect(color);
3398
+ }
3399
+ },
3400
+ onFocus: roving.onFocus,
3401
+ "data-roving-focus-item": true,
3402
+ "aria-label": color
3403
+ }
3404
+ );
3405
+ }
3406
+ function ColorSwatchPicker({
3407
+ colors,
3408
+ value,
3409
+ defaultValue,
3410
+ onChange,
3411
+ swatchSize = "md",
3412
+ swatchShape = "square",
3413
+ disabled = false,
3414
+ className,
3415
+ ...rest
3416
+ }) {
3417
+ const [selected, setSelected] = useControlled({
3418
+ controlled: value,
3419
+ default: defaultValue ?? null,
3420
+ onChange
3421
+ });
3422
+ return /* @__PURE__ */ jsx(
3423
+ RovingFocusGroup,
3424
+ {
3425
+ orientation: "both",
3426
+ loop: true,
3427
+ className: cn("flex flex-wrap gap-1.5", className),
3428
+ ...rest,
3429
+ children: colors.map((c) => /* @__PURE__ */ jsx(
3430
+ ColorSwatchItem,
3431
+ {
3432
+ color: c,
3433
+ selected: selected === c,
3434
+ disabled,
3435
+ size: swatchSize,
3436
+ shape: swatchShape,
3437
+ onSelect: (color) => setSelected(color)
3438
+ },
3439
+ c
3440
+ ))
3441
+ }
3442
+ );
3443
+ }
3444
+ var FALLBACK_HSV = { h: 217, s: 0.91, v: 0.96, a: 1 };
3445
+ var ColorPicker = forwardRef(function ColorPicker2({
3446
+ value,
3447
+ defaultValue = "#3b82f6",
3448
+ onChange,
3449
+ withAlpha = false,
3450
+ presets,
3451
+ triggerSize = "md",
3452
+ disabled = false,
3453
+ name,
3454
+ className,
3455
+ "aria-label": ariaLabel = "Pick a color"
3456
+ }, ref) {
3457
+ const [hex, setHex] = useControlled({
3458
+ controlled: value,
3459
+ default: defaultValue ?? null,
3460
+ onChange
3461
+ });
3462
+ const [hsv, setHsvState] = useState(() => parseColorToHsv(hex) ?? FALLBACK_HSV);
3463
+ useEffect(() => {
3464
+ if (!hex) return;
3465
+ const parsed = parseColorToHsv(hex);
3466
+ if (!parsed) return;
3467
+ const currentHex = hsvToHex(hsv, { withAlpha });
3468
+ if (currentHex.toLowerCase() !== hex.toLowerCase()) {
3469
+ setHsvState({ ...parsed, a: hsv.a });
3470
+ }
3471
+ }, [hex, withAlpha]);
3472
+ const updateHsv = (next) => {
3473
+ setHsvState(next);
3474
+ setHex(hsvToHex(next, { withAlpha }));
3475
+ };
3476
+ return /* @__PURE__ */ jsxs(Popover, { children: [
3477
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
3478
+ "button",
3479
+ {
3480
+ ref,
3481
+ type: "button",
3482
+ "aria-label": ariaLabel,
3483
+ disabled,
3484
+ className: cn(
3485
+ "inline-flex items-center gap-2 rounded-md border border-border bg-background px-2 py-1 text-sm transition-colors hover:border-border-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-60",
3486
+ className
3487
+ ),
3488
+ children: [
3489
+ /* @__PURE__ */ jsx(ColorSwatch, { color: hex ?? "#00000000", size: triggerSize }),
3490
+ /* @__PURE__ */ jsx("span", { className: "font-mono uppercase", children: hex ?? "\u2014" })
3491
+ ]
3492
+ }
3493
+ ) }),
3494
+ /* @__PURE__ */ jsxs(PopoverContent, { className: "flex w-64 flex-col gap-3", children: [
3495
+ /* @__PURE__ */ jsx(
3496
+ ColorArea,
3497
+ {
3498
+ hue: hsv.h,
3499
+ saturation: hsv.s,
3500
+ value: hsv.v,
3501
+ onChange: ({ saturation, value: value2 }) => updateHsv({ ...hsv, s: saturation, v: value2 })
3502
+ }
3503
+ ),
3504
+ /* @__PURE__ */ jsx(
3505
+ ColorSlider,
3506
+ {
3507
+ channel: "hue",
3508
+ value: hsv.h,
3509
+ onChange: (h) => updateHsv({ ...hsv, h }),
3510
+ "aria-label": "Hue"
3511
+ }
3512
+ ),
3513
+ withAlpha && /* @__PURE__ */ jsx(
3514
+ ColorSlider,
3515
+ {
3516
+ channel: "alpha",
3517
+ value: hsv.a ?? 1,
3518
+ color: hsv,
3519
+ onChange: (a) => updateHsv({ ...hsv, a }),
3520
+ "aria-label": "Alpha"
3521
+ }
3522
+ ),
3523
+ /* @__PURE__ */ jsx(
3524
+ ColorField,
3525
+ {
3526
+ value: hex,
3527
+ onChange: (next) => setHex(next),
3528
+ withAlpha
3529
+ }
3530
+ ),
3531
+ presets && presets.length > 0 && /* @__PURE__ */ jsx(
3532
+ ColorSwatchPicker,
3533
+ {
3534
+ colors: presets,
3535
+ value: hex,
3536
+ onChange: setHex,
3537
+ swatchSize: "sm"
3538
+ }
3539
+ )
3540
+ ] }),
3541
+ name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: hex ?? "" })
3542
+ ] });
3543
+ });
3544
+ var StepperContext = createContext(null);
3545
+ function useStepperContext() {
3546
+ const ctx = useContext(StepperContext);
3547
+ if (!ctx) throw new Error("Stepper.* must be used inside <Stepper>");
3548
+ return ctx;
3549
+ }
3550
+ var Stepper = forwardRef(function Stepper2({
3551
+ value,
3552
+ defaultValue,
3553
+ onValueChange,
3554
+ orientation = "horizontal",
3555
+ className,
3556
+ children,
3557
+ ...rest
3558
+ }, ref) {
3559
+ const [active, setActive] = useControlled({
3560
+ controlled: value,
3561
+ default: defaultValue ?? "",
3562
+ onChange: onValueChange
3563
+ });
3564
+ const baseId = useId$1();
3565
+ const stepsRef = useRef([]);
3566
+ const registerStep = useCallback((v) => {
3567
+ if (!stepsRef.current.includes(v)) stepsRef.current.push(v);
3568
+ }, []);
3569
+ const unregisterStep = useCallback((v) => {
3570
+ stepsRef.current = stepsRef.current.filter((x) => x !== v);
3571
+ }, []);
3572
+ const ctx = useMemo(
3573
+ () => ({
3574
+ value: active,
3575
+ setValue: setActive,
3576
+ orientation,
3577
+ baseId,
3578
+ registerStep,
3579
+ unregisterStep,
3580
+ stepsRef
3581
+ }),
3582
+ [active, setActive, orientation, baseId, registerStep, unregisterStep]
3583
+ );
3584
+ return /* @__PURE__ */ jsx(StepperContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
3585
+ "div",
3586
+ {
3587
+ ref,
3588
+ "data-orientation": orientation,
3589
+ className: cn(
3590
+ orientation === "vertical" ? "flex gap-4" : "flex flex-col gap-4",
3591
+ className
3592
+ ),
3593
+ ...rest,
3594
+ children
3595
+ }
3596
+ ) });
3597
+ });
3598
+ var StepperList = forwardRef(function StepperList2({ className, children, ...rest }, ref) {
3599
+ const ctx = useStepperContext();
3600
+ return /* @__PURE__ */ jsx(
3601
+ RovingFocusGroup,
3602
+ {
3603
+ ref,
3604
+ orientation: ctx.orientation,
3605
+ role: "tablist",
3606
+ "aria-orientation": ctx.orientation,
3607
+ "data-orientation": ctx.orientation,
3608
+ className: cn(
3609
+ "flex",
3610
+ ctx.orientation === "vertical" ? "flex-col gap-4" : "flex-row items-center gap-2",
3611
+ className
3612
+ ),
3613
+ ...rest,
3614
+ children
3615
+ }
3616
+ );
3617
+ });
3618
+ var StepperStep = forwardRef(function StepperStep2({ value, description, disabled = false, className, onClick, children, ...rest }, ref) {
3619
+ const ctx = useStepperContext();
3620
+ const roving = useRovingFocusItem();
3621
+ useEffect(() => {
3622
+ ctx.registerStep(value);
3623
+ return () => ctx.unregisterStep(value);
3624
+ }, [ctx, value]);
3625
+ const ordered = ctx.stepsRef.current;
3626
+ const idx = ordered.indexOf(value);
3627
+ const activeIdx = ordered.indexOf(ctx.value);
3628
+ const status = idx < activeIdx ? "complete" : idx === activeIdx ? "active" : "pending";
3629
+ const stepId = `${ctx.baseId}-step-${value}`;
3630
+ const panelId = `${ctx.baseId}-panel-${value}`;
3631
+ const stepNumber = idx + 1;
3632
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 items-center gap-2", children: [
3633
+ /* @__PURE__ */ jsxs(
3634
+ "button",
3635
+ {
3636
+ ref: (node) => {
3637
+ roving.ref(node);
3638
+ if (typeof ref === "function") ref(node);
3639
+ else if (ref) ref.current = node;
3640
+ },
3641
+ id: stepId,
3642
+ type: "button",
3643
+ role: "tab",
3644
+ "aria-selected": status === "active",
3645
+ "aria-controls": panelId,
3646
+ "aria-current": status === "active" ? "step" : void 0,
3647
+ "data-status": status,
3648
+ "data-disabled": dataAttr(disabled),
3649
+ tabIndex: roving.tabIndex,
3650
+ disabled,
3651
+ onClick: (e) => {
3652
+ onClick?.(e);
3653
+ if (e.defaultPrevented || disabled) return;
3654
+ ctx.setValue(value);
3655
+ },
3656
+ onFocus: roving.onFocus,
3657
+ onKeyDown: roving.onKeyDown,
3658
+ className: cn(
3659
+ "group flex items-center gap-2 text-left text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-sm",
3660
+ disabled && "pointer-events-none opacity-50",
3661
+ className
3662
+ ),
3663
+ ...rest,
3664
+ children: [
3665
+ /* @__PURE__ */ jsx(
3666
+ "span",
3667
+ {
3668
+ "aria-hidden": "true",
3669
+ className: cn(
3670
+ "grid h-7 w-7 shrink-0 place-items-center rounded-full border-2 text-xs font-semibold transition-colors",
3671
+ status === "pending" && "border-border text-muted-foreground",
3672
+ status === "active" && "border-primary bg-primary text-primary-foreground",
3673
+ status === "complete" && "border-primary bg-primary text-primary-foreground"
3674
+ ),
3675
+ children: status === "complete" ? /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) : stepNumber
3676
+ }
3677
+ ),
3678
+ /* @__PURE__ */ jsxs("span", { className: "flex flex-col", children: [
3679
+ /* @__PURE__ */ jsx(
3680
+ "span",
3681
+ {
3682
+ className: cn(
3683
+ "font-medium",
3684
+ status === "pending" ? "text-muted-foreground" : "text-foreground"
3685
+ ),
3686
+ children
3687
+ }
3688
+ ),
3689
+ description && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: description })
3690
+ ] })
3691
+ ]
3692
+ }
3693
+ ),
3694
+ ctx.orientation === "horizontal" && idx < ordered.length - 1 && /* @__PURE__ */ jsx(
3695
+ "span",
3696
+ {
3697
+ "aria-hidden": "true",
3698
+ className: cn(
3699
+ "h-px flex-1 transition-colors",
3700
+ status === "pending" ? "bg-border" : "bg-primary"
3701
+ )
3702
+ }
3703
+ )
3704
+ ] });
3705
+ });
3706
+ var StepperPanel = forwardRef(function StepperPanel2({ value, className, children, ...rest }, ref) {
3707
+ const ctx = useStepperContext();
3708
+ if (ctx.value !== value) return null;
3709
+ const stepId = `${ctx.baseId}-step-${value}`;
3710
+ const panelId = `${ctx.baseId}-panel-${value}`;
3711
+ return /* @__PURE__ */ jsx(
3712
+ "div",
3713
+ {
3714
+ ref,
3715
+ id: panelId,
3716
+ role: "tabpanel",
3717
+ "aria-labelledby": stepId,
3718
+ tabIndex: 0,
3719
+ className: cn("flex-1 outline-none", className),
3720
+ ...rest,
3721
+ children
3722
+ }
3723
+ );
3724
+ });
3725
+ Stepper.List = StepperList;
3726
+ Stepper.Step = StepperStep;
3727
+ Stepper.Panel = StepperPanel;
3728
+
3729
+ export { Calendar, CharacterCount, Checkbox, CheckboxField, CheckboxGroup, ChoiceCard, ColorArea, ColorField, ColorPicker, ColorSlider, ColorSwatch, ColorSwatchPicker, ColorWheel, Combobox, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxSeparator, CurrencyInput, DateField, DatePicker, DateRangePicker, EmailInput, Fieldset, FilePicker, FormErrorMessage, FormField, FormHelperText, InputAddon, InputGroup, Label, LabeledInput, Legend, Listbox, ListboxEmpty, ListboxGroup, ListboxItem, ListboxSeparator, MaskedInput, MultiSelect, MultiSelectContent, MultiSelectItem, MultiSelectTags, MultiSelectTrigger, NumberInput, PasswordInput, PasswordStrength, PercentInput, PinInput, Radio, RadioField, RadioGroup, RangeCalendar, SearchInput, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider, Stepper, StepperList, StepperPanel, StepperStep, Switch, SwitchField, TelInput, TextInput, Textarea, TimeField, TimePicker, UrlInput, colorSwatchVariants };
3730
+ //# sourceMappingURL=chunk-BQTO7XY6.js.map
3731
+ //# sourceMappingURL=chunk-BQTO7XY6.js.map