@g4rcez/components 5.0.2 → 5.0.3

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 (273) hide show
  1. package/dist/AnimatePresence-j36AYeOQ.js +181 -0
  2. package/dist/AnimatePresence-j36AYeOQ.js.map +1 -0
  3. package/dist/Calendar.es-xICmgvjq.js +23 -0
  4. package/dist/Calendar.es-xICmgvjq.js.map +1 -0
  5. package/dist/Funnel.es-DjKVl8Nj.js +23 -0
  6. package/dist/Funnel.es-DjKVl8Nj.js.map +1 -0
  7. package/dist/{MotionConfig-DKKYqBH2.js → MotionConfig-CXHoPGbK.js} +2 -2
  8. package/dist/{MotionConfig-DKKYqBH2.js.map → MotionConfig-CXHoPGbK.js.map} +1 -1
  9. package/dist/Plus.es-DbyRkEE2.js +23 -0
  10. package/dist/Plus.es-DbyRkEE2.js.map +1 -0
  11. package/dist/Trash.es-BFAc8PMf.js +23 -0
  12. package/dist/Trash.es-BFAc8PMf.js.map +1 -0
  13. package/dist/{calendar-PCCZDUIL.js → calendar-DEPkz8sw.js} +364 -502
  14. package/dist/calendar-DEPkz8sw.js.map +1 -0
  15. package/dist/calendar-header-Dfr-CwkY.js +174 -0
  16. package/dist/calendar-header-Dfr-CwkY.js.map +1 -0
  17. package/dist/chunk-jwUa06l-.js +23 -0
  18. package/dist/components/core/button.js +1 -1
  19. package/dist/components/core/heading.js +11 -0
  20. package/dist/components/core/heading.js.map +1 -0
  21. package/dist/{polymorph-BLXhrn9n.js → components/core/polymorph.js} +2 -2
  22. package/dist/components/core/polymorph.js.map +1 -0
  23. package/dist/components/core/render-on-view.js +29 -0
  24. package/dist/components/core/render-on-view.js.map +1 -0
  25. package/dist/components/core/resizable.d.ts +7 -1
  26. package/dist/components/core/resizable.d.ts.map +1 -1
  27. package/dist/components/core/resizable.js +60 -0
  28. package/dist/components/core/resizable.js.map +1 -0
  29. package/dist/components/core/resizable.jsx +46 -40
  30. package/dist/{slot-pC8kH9De.js → components/core/slot.js} +2 -2
  31. package/dist/components/core/slot.js.map +1 -0
  32. package/dist/components/core/tag.js +1 -1
  33. package/dist/components/core/typography.js +40 -0
  34. package/dist/components/core/typography.js.map +1 -0
  35. package/dist/components/display/alert.d.ts.map +1 -1
  36. package/dist/components/display/alert.js +83 -102
  37. package/dist/components/display/alert.js.map +1 -1
  38. package/dist/components/display/alert.jsx +26 -29
  39. package/dist/components/display/calendar.d.ts.map +1 -1
  40. package/dist/components/display/calendar.js +1 -1
  41. package/dist/components/display/calendar.jsx +15 -10
  42. package/dist/components/display/card.js +2 -2
  43. package/dist/components/display/empty.d.ts.map +1 -1
  44. package/dist/components/display/empty.js +25 -0
  45. package/dist/components/display/empty.js.map +1 -0
  46. package/dist/components/display/empty.jsx +3 -1
  47. package/dist/components/display/list.d.ts.map +1 -1
  48. package/dist/components/display/list.js +132 -122
  49. package/dist/components/display/list.js.map +1 -1
  50. package/dist/components/display/list.jsx +30 -25
  51. package/dist/components/display/notifications.d.ts.map +1 -1
  52. package/dist/components/display/notifications.js +1 -1
  53. package/dist/components/display/notifications.jsx +8 -6
  54. package/dist/components/display/progress.d.ts.map +1 -1
  55. package/dist/components/display/progress.js +3 -0
  56. package/dist/components/display/progress.jsx +6 -8
  57. package/dist/components/display/shortcut.js +2 -0
  58. package/dist/components/display/skeleton.js +41 -0
  59. package/dist/components/display/skeleton.js.map +1 -0
  60. package/dist/components/display/spinner.js +17 -0
  61. package/dist/components/display/spinner.js.map +1 -0
  62. package/dist/components/display/step.d.ts.map +1 -1
  63. package/dist/components/display/step.js +3 -0
  64. package/dist/components/display/step.jsx +5 -5
  65. package/dist/components/display/tabs.js +1 -1
  66. package/dist/components/display/timeline.js +1 -1
  67. package/dist/components/floating/command-palette.d.ts.map +1 -1
  68. package/dist/components/floating/command-palette.js +255 -0
  69. package/dist/components/floating/command-palette.js.map +1 -0
  70. package/dist/components/floating/command-palette.jsx +34 -25
  71. package/dist/components/floating/dropdown.js +1 -1
  72. package/dist/components/floating/dropdown.js.map +1 -1
  73. package/dist/components/floating/dropdown.jsx +1 -1
  74. package/dist/components/floating/expand.js +15 -14
  75. package/dist/components/floating/expand.js.map +1 -1
  76. package/dist/components/floating/menu.js +1 -1
  77. package/dist/components/floating/modal.d.ts +14 -11
  78. package/dist/components/floating/modal.d.ts.map +1 -1
  79. package/dist/components/floating/modal.js +1 -1
  80. package/dist/components/floating/modal.jsx +56 -17
  81. package/dist/components/floating/toolbar.d.ts +3 -3
  82. package/dist/components/floating/toolbar.d.ts.map +1 -1
  83. package/dist/components/floating/toolbar.js +20 -0
  84. package/dist/components/floating/toolbar.js.map +1 -0
  85. package/dist/components/floating/toolbar.jsx +7 -3
  86. package/dist/components/floating/tooltip.js +2 -2
  87. package/dist/components/floating/tooltip.js.map +1 -1
  88. package/dist/components/floating/tooltip.jsx +1 -1
  89. package/dist/components/floating/wizard.js +3 -0
  90. package/dist/components/form/autocomplete.d.ts.map +1 -1
  91. package/dist/components/form/autocomplete.js +344 -2
  92. package/dist/components/form/autocomplete.js.map +1 -0
  93. package/dist/components/form/autocomplete.jsx +27 -18
  94. package/dist/components/form/checkbox.d.ts.map +1 -1
  95. package/dist/components/form/checkbox.js +29 -27
  96. package/dist/components/form/checkbox.js.map +1 -1
  97. package/dist/components/form/checkbox.jsx +21 -6
  98. package/dist/components/form/date-picker.js +1 -1
  99. package/dist/components/form/date-picker.jsx +1 -1
  100. package/dist/components/form/file-upload.d.ts +6 -1
  101. package/dist/components/form/file-upload.d.ts.map +1 -1
  102. package/dist/components/form/file-upload.js +1 -1
  103. package/dist/components/form/file-upload.jsx +34 -12
  104. package/dist/components/form/formReset.js +10 -0
  105. package/dist/components/form/formReset.js.map +1 -0
  106. package/dist/components/form/free-text.js +70 -0
  107. package/dist/components/form/free-text.js.map +1 -0
  108. package/dist/components/form/free-text.jsx +1 -1
  109. package/dist/components/form/input-field.d.ts.map +1 -1
  110. package/dist/components/form/input-field.js +3 -0
  111. package/dist/components/form/input-field.jsx +14 -8
  112. package/dist/components/form/input.js +1 -1
  113. package/dist/components/form/multi-select.d.ts.map +1 -1
  114. package/dist/components/form/multi-select.js +420 -0
  115. package/dist/components/form/multi-select.js.map +1 -0
  116. package/dist/components/form/multi-select.jsx +41 -33
  117. package/dist/components/form/select.d.ts.map +1 -1
  118. package/dist/components/form/select.js +55 -51
  119. package/dist/components/form/select.js.map +1 -1
  120. package/dist/components/form/select.jsx +8 -5
  121. package/dist/components/form/slider.js +3 -0
  122. package/dist/components/form/switch.d.ts +2 -1
  123. package/dist/components/form/switch.d.ts.map +1 -1
  124. package/dist/components/form/switch.js +32 -26
  125. package/dist/components/form/switch.js.map +1 -1
  126. package/dist/components/form/switch.jsx +26 -13
  127. package/dist/components/form/textarea.js +19 -0
  128. package/dist/components/form/textarea.js.map +1 -0
  129. package/dist/components/page-calendar/calendar-header.d.ts.map +1 -1
  130. package/dist/components/page-calendar/calendar-header.js +2 -0
  131. package/dist/components/page-calendar/calendar-header.jsx +6 -4
  132. package/dist/components/page-calendar/day-view.js +124 -0
  133. package/dist/components/page-calendar/day-view.js.map +1 -0
  134. package/dist/components/page-calendar/event-pill.js +44 -0
  135. package/dist/components/page-calendar/event-pill.js.map +1 -0
  136. package/dist/components/page-calendar/month-view.d.ts.map +1 -1
  137. package/dist/components/page-calendar/month-view.js +109 -0
  138. package/dist/components/page-calendar/month-view.js.map +1 -0
  139. package/dist/components/page-calendar/month-view.jsx +78 -31
  140. package/dist/components/page-calendar/page-calendar.d.ts.map +1 -1
  141. package/dist/components/page-calendar/page-calendar.js +75 -0
  142. package/dist/components/page-calendar/page-calendar.js.map +1 -0
  143. package/dist/components/page-calendar/page-calendar.jsx +2 -2
  144. package/dist/components/page-calendar/week-view.js +88 -0
  145. package/dist/components/page-calendar/week-view.js.map +1 -0
  146. package/dist/components/table/filter.d.ts.map +1 -1
  147. package/dist/components/table/filter.js +239 -0
  148. package/dist/components/table/filter.js.map +1 -0
  149. package/dist/components/table/filter.jsx +9 -4
  150. package/dist/components/table/group.d.ts.map +1 -1
  151. package/dist/components/table/group.js +3 -0
  152. package/dist/components/table/group.jsx +5 -3
  153. package/dist/components/table/index.js +102 -0
  154. package/dist/components/table/index.js.map +1 -0
  155. package/dist/components/table/inner-table.js +2 -0
  156. package/dist/components/table/inner-table.jsx +1 -1
  157. package/dist/components/table/metadata.js +73 -0
  158. package/dist/components/table/metadata.js.map +1 -0
  159. package/dist/components/table/metadata.jsx +1 -1
  160. package/dist/components/table/pagination.js +70 -0
  161. package/dist/components/table/pagination.js.map +1 -0
  162. package/dist/components/table/row.js +58 -0
  163. package/dist/components/table/row.js.map +1 -0
  164. package/dist/components/table/sort.d.ts.map +1 -1
  165. package/dist/components/table/sort.js +3 -0
  166. package/dist/components/table/sort.jsx +3 -1
  167. package/dist/components/table/thead.js +3 -0
  168. package/dist/config/default-translations.d.ts +18 -0
  169. package/dist/config/default-translations.d.ts.map +1 -1
  170. package/dist/config/default-translations.jsx +18 -0
  171. package/dist/{use-translations-DTLfPE3_.js → context-CsnUsfeP.js} +55 -40
  172. package/dist/context-CsnUsfeP.js.map +1 -0
  173. package/dist/{date-picker-BhKEFZew.js → date-picker-DNzupG8R.js} +301 -317
  174. package/dist/date-picker-DNzupG8R.js.map +1 -0
  175. package/dist/dict-CisoYSMO.js +28 -0
  176. package/dist/dict-CisoYSMO.js.map +1 -0
  177. package/dist/dist-ChfJ5LO9.js +498 -0
  178. package/dist/dist-ChfJ5LO9.js.map +1 -0
  179. package/dist/{dist-BrGpYRaj.js → dist-DIjUECx9.js} +56 -56
  180. package/dist/{dist-BrGpYRaj.js.map → dist-DIjUECx9.js.map} +1 -1
  181. package/dist/dom-Bn4wY_Zx.js.map +1 -1
  182. package/dist/{file-upload-DWbZfeG5.js → file-upload-C2zNnv9n.js} +501 -481
  183. package/dist/{file-upload-DWbZfeG5.js.map → file-upload-C2zNnv9n.js.map} +1 -1
  184. package/dist/fzf-CPGDDCoU.js +64 -0
  185. package/dist/fzf-CPGDDCoU.js.map +1 -0
  186. package/dist/getISOWeek-EcB4Ebqp.js +72 -0
  187. package/dist/getISOWeek-EcB4Ebqp.js.map +1 -0
  188. package/dist/group-Dl14TJXO.js +222 -0
  189. package/dist/group-Dl14TJXO.js.map +1 -0
  190. package/dist/hooks/use-translations.d.ts +18 -0
  191. package/dist/hooks/use-translations.d.ts.map +1 -1
  192. package/dist/index.css +1 -1
  193. package/dist/index.js.map +1 -1
  194. package/dist/inner-table-CeDX60cL.js +151 -0
  195. package/dist/inner-table-CeDX60cL.js.map +1 -0
  196. package/dist/input-Cmyuea4Y.js +412 -0
  197. package/dist/input-Cmyuea4Y.js.map +1 -0
  198. package/dist/{input-field-B_whI66Q.js → input-field-ffx1MbHo.js} +29 -16
  199. package/dist/input-field-ffx1MbHo.js.map +1 -0
  200. package/dist/isSameMonth-C3lsSwcg.js +10 -0
  201. package/dist/isSameMonth-C3lsSwcg.js.map +1 -0
  202. package/dist/isToday-COXfxFui.js +32 -0
  203. package/dist/isToday-COXfxFui.js.map +1 -0
  204. package/dist/lib/dom.d.ts.map +1 -1
  205. package/dist/modal-Df8-6i-o.js +408 -0
  206. package/dist/modal-Df8-6i-o.js.map +1 -0
  207. package/dist/notifications-NhCESJUV.js +1697 -0
  208. package/dist/notifications-NhCESJUV.js.map +1 -0
  209. package/dist/page-calendar.utils-Bd0PHktL.js +102 -0
  210. package/dist/page-calendar.utils-Bd0PHktL.js.map +1 -0
  211. package/dist/preset/preset.tailwind.d.ts.map +1 -1
  212. package/dist/preset/preset.tailwind.js +6 -7
  213. package/dist/preset/src/styles/dark.js +1 -1
  214. package/dist/progress-8LO5gWLp.js +104 -0
  215. package/dist/progress-8LO5gWLp.js.map +1 -0
  216. package/dist/{proxy-BcJ_5Dwq.js → proxy-fP2NxmhM.js} +658 -844
  217. package/dist/proxy-fP2NxmhM.js.map +1 -0
  218. package/dist/shim-Czv-YhKR.js +93 -0
  219. package/dist/shim-Czv-YhKR.js.map +1 -0
  220. package/dist/shortcut-CQCmgmlU.js +100 -0
  221. package/dist/shortcut-CQCmgmlU.js.map +1 -0
  222. package/dist/slider-TX9hiHO-.js +1196 -0
  223. package/dist/slider-TX9hiHO-.js.map +1 -0
  224. package/dist/sort-DGmiselV.js +195 -0
  225. package/dist/sort-DGmiselV.js.map +1 -0
  226. package/dist/step-DFpJ7zCG.js +185 -0
  227. package/dist/step-DFpJ7zCG.js.map +1 -0
  228. package/dist/styles/dark.js +1 -1
  229. package/dist/subMonths-QcCnE3Yh.js +43 -0
  230. package/dist/subMonths-QcCnE3Yh.js.map +1 -0
  231. package/dist/table-lib-1bkYSklk.js +174 -0
  232. package/dist/table-lib-1bkYSklk.js.map +1 -0
  233. package/dist/{tabs-Ciy0l9OF.js → tabs-Brc963EW.js} +2 -2
  234. package/dist/{tabs-Ciy0l9OF.js.map → tabs-Brc963EW.js.map} +1 -1
  235. package/dist/thead-B6WELJZ-.js +211 -0
  236. package/dist/thead-B6WELJZ-.js.map +1 -0
  237. package/dist/use-locale-DPM_sg4s.js +12 -0
  238. package/dist/use-locale-DPM_sg4s.js.map +1 -0
  239. package/dist/use-remove-scroll-pAgC09Sq.js +38 -0
  240. package/dist/use-remove-scroll-pAgC09Sq.js.map +1 -0
  241. package/dist/use-translations-BE4PuhLm.js +11 -0
  242. package/dist/use-translations-BE4PuhLm.js.map +1 -0
  243. package/dist/useAnimationFrame-DnKbaXfi.js +223 -0
  244. package/dist/useAnimationFrame-DnKbaXfi.js.map +1 -0
  245. package/dist/valueToPercent-DZc_m1tm.js +43 -0
  246. package/dist/valueToPercent-DZc_m1tm.js.map +1 -0
  247. package/dist/visuallyHidden-B7wI86yi.js +303 -0
  248. package/dist/visuallyHidden-B7wI86yi.js.map +1 -0
  249. package/dist/with-selector-BFW5n-pb.js +102 -0
  250. package/dist/with-selector-BFW5n-pb.js.map +1 -0
  251. package/dist/wizard-7u_qZ-78.js +218 -0
  252. package/dist/wizard-7u_qZ-78.js.map +1 -0
  253. package/package.json +19 -11
  254. package/dist/autocomplete-D3VOTihi.js +0 -415
  255. package/dist/autocomplete-D3VOTihi.js.map +0 -1
  256. package/dist/calendar-PCCZDUIL.js.map +0 -1
  257. package/dist/components/table/table.js +0 -3
  258. package/dist/date-picker-BhKEFZew.js.map +0 -1
  259. package/dist/input-B7jqwPG4.js +0 -473
  260. package/dist/input-B7jqwPG4.js.map +0 -1
  261. package/dist/input-field-B_whI66Q.js.map +0 -1
  262. package/dist/modal-Bz-61ays.js +0 -373
  263. package/dist/modal-Bz-61ays.js.map +0 -1
  264. package/dist/notifications-MT4XkLov.js +0 -2203
  265. package/dist/notifications-MT4XkLov.js.map +0 -1
  266. package/dist/polymorph-BLXhrn9n.js.map +0 -1
  267. package/dist/proxy-BcJ_5Dwq.js.map +0 -1
  268. package/dist/skeleton-CBYEq3lM.js +0 -26
  269. package/dist/skeleton-CBYEq3lM.js.map +0 -1
  270. package/dist/slot-pC8kH9De.js.map +0 -1
  271. package/dist/table-CUFbAI2k.js +0 -1914
  272. package/dist/table-CUFbAI2k.js.map +0 -1
  273. package/dist/use-translations-DTLfPE3_.js.map +0 -1
@@ -1,18 +1,16 @@
1
1
  "use client";
2
- import { autoPlacement, autoUpdate, FloatingFocusManager, FloatingOverlay, FloatingPortal, offset, size, useDismiss, useFloating, useInteractions, useListNavigation, useRole, useTransitionStyles, } from "@floating-ui/react";
2
+ import { autoPlacement, autoUpdate, FloatingFocusManager, FloatingOverlay, FloatingPortal, offset, size, useDismiss, useFloating, useInteractions, useListNavigation, useTransitionStyles, } from "@floating-ui/react";
3
3
  import { CaretDownIcon, XIcon } from "@phosphor-icons/react";
4
4
  import { AnimatePresence, motion } from "motion/react";
5
- import React, { forwardRef, Fragment, useEffect, useMemo, useRef, useState } from "react";
5
+ import React, { forwardRef, Fragment, useEffect, useId, useMemo, useRef, useState } from "react";
6
6
  import { flushSync } from "react-dom";
7
7
  import { Virtuoso } from "react-virtuoso";
8
8
  import { useRemoveScroll } from "../../hooks/use-remove-scroll";
9
9
  import { useTranslations } from "../../hooks/use-translations";
10
10
  import { Dict } from "../../lib/dict";
11
11
  import { css, getRemainingSize, initializeInputDataset } from "../../lib/dom";
12
- import { noop } from "../../lib/fns";
13
12
  import { fzf } from "../../lib/fzf";
14
13
  import { Tag } from "../core/tag";
15
- import { Checkbox } from "./checkbox";
16
14
  import { InputField } from "./input-field";
17
15
  const MIN_SIZE = 40;
18
16
  const Frag = (props) => <Fragment>{props.children}</Fragment>;
@@ -24,11 +22,11 @@ const transitionStyles = {
24
22
  };
25
23
  const EMPTY_NODES = [];
26
24
  const EMPTY_VALUES = [];
27
- const List = forwardRef(function VirtualItem({ item: _item, context: _context, ...props }, ref) {
28
- return <motion.li {...props} ref={ref} className="last:rounded-t-dropdown-radius"/>;
25
+ const List = forwardRef(function VirtualList({ context, ...props }, ref) {
26
+ return <motion.div {...props} id={context?.listboxId} ref={ref} role="listbox" className="last:rounded-t-dropdown-radius"/>;
29
27
  });
30
28
  const Item = forwardRef(function VirtualList({ context: _context, ...props }, ref) {
31
- return (<motion.div {...props} ref={ref} className="w-full rounded-b-dropdown-radius border-b border-tooltip-border last:border-transparent">
29
+ return (<motion.div {...props} ref={ref} role="presentation" className="w-full">
32
30
  <AnimatePresence>{props.children}</AnimatePresence>
33
31
  </motion.div>);
34
32
  });
@@ -64,6 +62,7 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
64
62
  const searchInputRef = useRef(null);
65
63
  const defaults = props.value ?? props.defaultValue ?? EMPTY_VALUES;
66
64
  const translation = useTranslations();
65
+ const generatedId = useId();
67
66
  const [open, setOpen] = useState(false);
68
67
  const [shadow, setShadow] = useState("");
69
68
  const [value, setValue] = useState(() => {
@@ -128,7 +127,6 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
128
127
  const isTopPlacement = placement === "top" || placement === "top-start";
129
128
  const transitions = useTransitionStyles(context, transitionStyles);
130
129
  const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([
131
- useRole(context, { role: "listbox" }),
132
130
  useDismiss(context),
133
131
  useListNavigation(context, {
134
132
  cols: 0,
@@ -186,6 +184,7 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
186
184
  setLabel((prev) => prev.concat(opt.label ?? ""));
187
185
  setShadow("");
188
186
  setIndex(i);
187
+ searchInputRef.current?.focus();
189
188
  };
190
189
  const onChange = (event) => {
191
190
  const v = event.target.value;
@@ -211,7 +210,10 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
211
210
  onChangeOptions?.([]);
212
211
  setClosed();
213
212
  };
214
- const id = props.id || props.name;
213
+ const id = props.id || props.name || generatedId;
214
+ const shadowId = `${id}-shadow`;
215
+ const listboxId = `${shadowId}-listbox`;
216
+ const activeOptionId = open && index !== null && displayList[index] ? `${shadowId}-option-${index}` : undefined;
215
217
  const tags = value.map((x, i) => (<Tag size="small" key={`MultiSelect-${x.value}-x`} icon={<button type="button" aria-label={`Remove ${x.label ?? x.value}`} className="text-current hover:text-danger focus:text-danger" onClick={(e) => {
216
218
  e.preventDefault();
217
219
  e.stopPropagation();
@@ -221,7 +223,7 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
221
223
  </button>}>
222
224
  {x.label ?? x.value}
223
225
  </Tag>));
224
- return (<InputField {...props} left={left} error={error} ref={fieldset} form={props.form} name={props.name} feedback={feedback} hideLeft={hideLeft} required={required} title={props.title} container={container} rightLabel={rightLabel} interactive={interactive} id={props.name || props.id} optionalText={optionalText} componentName="autocomplete" labelClassName={labelClassName} placeholder={props.placeholder} right={<span className="flex items-center gap-0.5">
226
+ return (<InputField {...props} left={left} error={error} ref={fieldset} form={props.form} name={props.name} feedback={feedback} hideLeft={hideLeft} required={required} title={props.title} container={container} rightLabel={rightLabel} interactive={interactive} id={id} optionalText={optionalText} componentName="autocomplete" labelClassName={labelClassName} placeholder={props.placeholder} right={<span className="flex items-center gap-0.5">
225
227
  {right}
226
228
  <button type="button" className="transition-colors link:text-primary" onClick={onCaretDownClick}>
227
229
  <CaretDownIcon size={20}/>
@@ -233,17 +235,23 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
233
235
  </svg>
234
236
  </button>) : null}
235
237
  </span>}>
236
- <ul {...getReferenceProps({
238
+ <div {...getReferenceProps({
237
239
  ...props,
238
- tabIndex: 0,
240
+ tabIndex: open ? -1 : 0,
239
241
  onFocus,
240
- id: `${id}-shadow`,
241
- name: `${id}-shadow`,
242
+ id: shadowId,
243
+ role: open ? "presentation" : "combobox",
244
+ name: shadowId,
242
245
  ref: refs.setReference,
246
+ "aria-expanded": open,
247
+ "aria-haspopup": "listbox",
248
+ "aria-controls": listboxId,
249
+ "aria-activedescendant": activeOptionId,
250
+ "aria-labelledby": `${id}-label`,
243
251
  })} data-name={id} data-target={id} data-shadow="true" data-error={!!error} data-value={values.join(",")} className={css("input placeholder-input-mask group h-input-height w-full text-input-text", "rounded-input-radius bg-transparent px-input-padding-x py-input-padding-y text-foreground", "outline-none transition-colors focus:ring-2 focus:ring-inset focus:ring-primary", "group-error:text-danger group-error:placeholder-input-mask-error", "group-focus-within:border-primary group-hover:border-primary", "flex flex-row items-center gap-input-gap whitespace-nowrap text-left", "max-w-full overflow-x-auto truncate overflow-ellipsis", props.className)}>
244
- {values.length > 0 ? null : <li className="text-input-placeholder">{props.placeholder}</li>}
252
+ {values.length > 0 ? null : <span className="text-input-placeholder">{props.placeholder}</span>}
245
253
  <OverflowControl label={selectedLabel}>{tags}</OverflowControl>
246
- </ul>
254
+ </div>
247
255
  <input id={id} name={id} type="hidden" data-origin={id} ref={externalRef} required={required} defaultValue={props.value || values || undefined}/>
248
256
  <FloatingPortal preserveTabOrder>
249
257
  {open ? (<FloatingOverlay lockScroll className="z-floating">
@@ -257,26 +265,28 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
257
265
  position: strategy,
258
266
  },
259
267
  })} data-floating="true" className={css("relative shadow-floating overflow-clip isolate z-floating m-0 max-h-dropdown-max-h list-none overscroll-contain rounded-dropdown-radius border border-floating-border bg-floating-background p-0 text-foreground ease-in-out", isTopPlacement ? "origin-[bottom_center]" : "origin-[top_center]")}>
260
- <input ref={searchInputRef} value={shadow} onChange={onChange} title={props.title} placeholder={translation.multiSelectInnerPlaceholder} className="input placeholder-input-mask group mb-1 h-input-height w-full flex-1 rounded-none border-b border-input-border bg-transparent px-input-padding-x py-input-padding-y outline-none transition-colors focus:border-primary" onKeyDown={(event) => {
268
+ <input ref={searchInputRef} value={shadow} onChange={onChange} title={props.title} role="combobox" aria-autocomplete="list" aria-expanded={open} aria-haspopup="listbox" aria-controls={listboxId} aria-activedescendant={activeOptionId} aria-labelledby={`${id}-label`} autoComplete="off" placeholder={translation.multiSelectInnerPlaceholder} className="input placeholder-input-mask group mb-1 h-input-height w-full flex-1 rounded-none border-b border-input-border bg-transparent px-input-padding-x py-input-padding-y outline-none transition-colors focus:border-primary" onKeyDown={(event) => {
261
269
  if (event.key === "ArrowDown") {
262
- let next = index + 1;
270
+ event.preventDefault();
271
+ let next = index === null ? 0 : index + 1;
263
272
  if (next > displayList.length - 1)
264
273
  next = 0;
265
274
  virtuoso.current?.scrollIntoView({ index: next });
266
275
  return setIndex(next);
267
276
  }
268
277
  if (event.key === "ArrowUp") {
269
- let next = index - 1;
278
+ event.preventDefault();
279
+ let next = index === null ? displayList.length - 1 : index - 1;
270
280
  if (next < 0)
271
281
  next = displayList.length - 1;
272
282
  virtuoso.current?.scrollIntoView({ index: next });
273
283
  return setIndex(next);
274
284
  }
275
285
  if (event.key === "Escape") {
276
- event.currentTarget.blur();
286
+ event.preventDefault();
277
287
  return setClosed();
278
288
  }
279
- if (event.key === "Enter") {
289
+ if (event.key === "Enter" || event.key === " " || event.code === "Space") {
280
290
  if (index !== null && displayList[index]) {
281
291
  event.preventDefault();
282
292
  return onSelect(displayList[index], index);
@@ -301,7 +311,7 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
301
311
  const sum = (li?.getBoundingClientRect().height ?? MIN_SIZE) * displayList.length;
302
312
  flushSync(() => setH(Math.min(320, sum + 2)));
303
313
  }}>
304
- <Virtuoso overscan={40} ref={virtuoso} hidden={isEmpty} data={displayList} style={{ height: h }} defaultItemHeight={MIN_SIZE} components={components} totalListHeightChanged={(totalHeight) => setH(Math.min(320, totalHeight))} scrollerRef={(e) => {
314
+ <Virtuoso overscan={40} ref={virtuoso} hidden={isEmpty} data={displayList} context={{ listboxId }} style={{ height: h }} initialItemCount={displayList.length} defaultItemHeight={MIN_SIZE} components={components} totalListHeightChanged={(totalHeight) => setH(Math.min(320, totalHeight))} scrollerRef={(e) => {
305
315
  scroller.current = e;
306
316
  removeScrollRef.current = e;
307
317
  }} className="max-h-72 border-floating-border bg-floating-background p-0 text-foreground" itemContent={(i, option) => {
@@ -309,26 +319,24 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
309
319
  const active = value.has(option.value) || value.has(option.label ?? "");
310
320
  const selected = index === i;
311
321
  const children = option.label ?? option.value;
312
- return (<button data-value={option.value} {...getItemProps({
322
+ return (<div id={`${shadowId}-option-${i}`} data-value={option.value} {...getItemProps({
313
323
  ref: (node) => {
314
324
  listRef.current[i] = node;
315
325
  },
316
326
  role: "option",
317
- type: "button",
318
- "aria-checked": active,
319
- "aria-current": active,
320
327
  "aria-selected": active,
321
328
  "aria-disabled": option.disabled,
322
- onClick: () => onSelect(option, i),
323
- })} className={`flex w-full max-w-full cursor-pointer items-center justify-start p-menu-item-p text-left hover:bg-floating-hover focus:bg-floating-hover ${active || selected ? "bg-floating-hover text-floating-foreground" : ""}`}>
324
- <Checkbox onChange={noop} checked={active} aria-checked={active} onClick={(e) => {
325
- e.stopPropagation();
326
- onSelect(option, i);
327
- }}/>
329
+ tabIndex: -1,
330
+ onClick: () => {
331
+ if (!option.disabled)
332
+ onSelect(option, i);
333
+ },
334
+ })} className={css("flex w-full max-w-full cursor-pointer items-center justify-start p-menu-item-p text-left hover:bg-floating-hover focus:bg-floating-hover", active || selected ? "bg-floating-hover text-floating-foreground" : "")}>
335
+ <span aria-hidden="true" data-selected={active} className="mr-checkbox-gap inline-block size-checkbox-size rounded-checkbox-radius border border-card-border data-[selected=true]:bg-primary"/>
328
336
  <Label {...option} label={option.label} value={option.value}>
329
337
  {children}
330
338
  </Label>
331
- </button>);
339
+ </div>);
332
340
  }}/>
333
341
  </motion.div>)}
334
342
  <div className="gap-menu-item-gap sticky bottom-0 flex w-full flex-nowrap items-center overflow-x-auto rounded-b-dropdown-radius bg-floating-background p-menu-item-p">
@@ -1 +1 @@
1
- {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/form/select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA6D,MAAM,OAAO,CAAC;AAGlF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAE5D,MAAM,MAAM,WAAW,GAAG,QAAQ,CAC9B,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAC9B;IACI,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAChD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,CAC9B,eAAe,CAAC,QAAQ,CAAC,EACzB;IACI,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,CACJ,CAAC;AAEF,eAAO,MAAM,MAAM,oGA4GlB,CAAC"}
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/form/select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAoE,MAAM,OAAO,CAAC;AAGzF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAE5D,MAAM,MAAM,WAAW,GAAG,QAAQ,CAC9B,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAC9B;IACI,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAChD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,CAC9B,eAAe,CAAC,QAAQ,CAAC,EACzB;IACI,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,CACJ,CAAC;AAEF,eAAO,MAAM,MAAM,oGA+GlB,CAAC"}
@@ -1,77 +1,81 @@
1
1
  "use client";
2
2
  import { o as e, t, u as n } from "../../dom-Bn4wY_Zx.js";
3
3
  import { t as r } from "../../CaretDown.es-BXl0Ixp3.js";
4
- import { n as i } from "../../input-field-B_whI66Q.js";
5
- import { t as a } from "../../use-translations-DTLfPE3_.js";
6
- import { createElement as o, forwardRef as s, useEffect as c, useImperativeHandle as l, useRef as u } from "react";
7
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
4
+ import { n as i } from "../../input-field-ffx1MbHo.js";
5
+ import { t as a } from "../../use-translations-BE4PuhLm.js";
6
+ import { createElement as o, forwardRef as s, useEffect as c, useId as l, useImperativeHandle as u, useRef as d } from "react";
7
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
8
8
  //#region src/components/form/select.tsx
9
- var p = s(({ required: s = !0, options: p, info: m, selectContainer: h = "", feedback: g = null, labelClassName: _, interactive: v, rightLabel: y, hiddenLabel: b, loading: x, optionalText: S, container: C, hideLeft: w = !1, right: T, left: E, error: D, ...O }, k) => {
10
- let A = a(), j = u(null), M = O.id ?? O.name;
11
- return l(k, () => j.current), c(() => {
12
- if (j.current === null) return;
13
- let t = new AbortController(), n = j.current, r = e(j.current);
9
+ var m = s(({ required: s = !0, options: m, info: h, selectContainer: g = "", feedback: _ = null, labelClassName: v, interactive: y, rightLabel: b, hiddenLabel: x, loading: S, optionalText: C, container: w, hideLeft: T = !1, right: E, left: D, error: O, ...k }, A) => {
10
+ let j = a(), M = d(null), N = l(), P = k.id ?? k.name ?? N, F = [
11
+ k["aria-describedby"],
12
+ _ ? `${P}-feedback` : void 0,
13
+ O ? `${P}-error` : void 0
14
+ ].filter(Boolean).join(" ") || void 0;
15
+ return u(A, () => M.current), c(() => {
16
+ if (M.current === null) return;
17
+ let t = new AbortController(), n = M.current, r = e(M.current);
14
18
  return n.addEventListener("change", () => n.setAttribute("data-selected", "true"), {
15
19
  once: !0,
16
20
  signal: t.signal
17
21
  }), () => {
18
22
  r(), t.abort();
19
23
  };
20
- }, []), /* @__PURE__ */ d(i, {
21
- info: m,
22
- left: E,
23
- error: D,
24
- form: O.form,
25
- loading: x,
26
- name: O.name,
27
- feedback: g,
28
- hideLeft: w,
24
+ }, []), /* @__PURE__ */ f(i, {
25
+ info: h,
26
+ left: D,
27
+ error: O,
28
+ form: k.form,
29
+ loading: S,
30
+ name: k.name ?? P,
31
+ feedback: _,
32
+ hideLeft: T,
29
33
  required: s,
30
- title: O.title,
31
- container: C,
34
+ title: k.title,
35
+ container: w,
32
36
  componentName: "select",
33
- rightLabel: y,
34
- hiddenLabel: b,
35
- interactive: v,
36
- id: O.name || O.id,
37
- optionalText: S,
38
- labelClassName: _,
39
- placeholder: O.placeholder,
40
- right: /* @__PURE__ */ f("label", {
41
- htmlFor: M,
42
- children: [T, /* @__PURE__ */ f("button", {
43
- onClick: () => j.current?.focus(),
44
- type: "button",
45
- className: "mt-2 transition-colors hover:text-primary",
46
- children: [/* @__PURE__ */ d(r, { size: 20 }), /* @__PURE__ */ d("span", {
47
- className: "sr-only",
48
- children: A.inputCaretDown
49
- })]
37
+ rightLabel: b,
38
+ hiddenLabel: x,
39
+ interactive: y,
40
+ id: P,
41
+ optionalText: C,
42
+ labelClassName: v,
43
+ placeholder: k.placeholder,
44
+ right: /* @__PURE__ */ p("span", { children: [E, /* @__PURE__ */ p("button", {
45
+ onClick: () => M.current?.focus(),
46
+ type: "button",
47
+ className: "mt-2 transition-colors hover:text-primary",
48
+ children: [/* @__PURE__ */ f(r, { size: 20 }), /* @__PURE__ */ f("span", {
49
+ className: "sr-only",
50
+ children: j.inputCaretDown
50
51
  })]
51
- }),
52
- children: /* @__PURE__ */ f("select", {
53
- ...O,
54
- id: M,
55
- name: M,
52
+ })] }),
53
+ children: /* @__PURE__ */ p("select", {
54
+ ...k,
55
+ id: P,
56
+ name: k.name ?? P,
56
57
  required: s,
57
- ref: n(k, j),
58
- "data-selected": !!O.value || !1,
59
- title: typeof O.title == "string" ? O.title : void 0,
60
- className: t("input select group h-input-height w-full flex-1 appearance-none rounded-input-radius text-input-text", "bg-transparent px-input-padding-x py-input-padding-y text-foreground placeholder-input-placeholder", "outline-none transition-colors group-error:text-danger group-error:placeholder-input-mask-error", "data-[selected=false]:text-input-placeholder", O.className),
61
- children: [/* @__PURE__ */ d("option", {
58
+ ref: n(A, M),
59
+ "aria-invalid": O ? !0 : k["aria-invalid"],
60
+ "aria-labelledby": `${P}-label`,
61
+ "aria-describedby": F,
62
+ "data-selected": !!k.value || !1,
63
+ title: typeof k.title == "string" ? k.title : void 0,
64
+ className: t("input select group h-input-height w-full flex-1 appearance-none rounded-input-radius text-input-text", "bg-transparent px-input-padding-x py-input-padding-y text-foreground placeholder-input-placeholder", "outline-none transition-colors group-error:text-danger group-error:placeholder-input-mask-error", "data-[selected=false]:text-input-placeholder", k.className),
65
+ children: [/* @__PURE__ */ f("option", {
62
66
  value: "",
63
67
  disabled: !0,
64
68
  hidden: !0,
65
- children: O.placeholder
66
- }), p.map((e) => /* @__PURE__ */ o("option", {
69
+ children: k.placeholder
70
+ }), m.map((e) => /* @__PURE__ */ o("option", {
67
71
  ...e,
68
72
  value: e.value,
69
- key: `${M}-select-option-${e.value}`
73
+ key: `${P}-select-option-${e.value}`
70
74
  }, e.label ?? e.value))]
71
75
  })
72
76
  });
73
77
  });
74
78
  //#endregion
75
- export { p as Select };
79
+ export { m as Select };
76
80
 
77
81
  //# sourceMappingURL=select.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"select.js","names":[],"sources":["../../../src/components/form/select.tsx"],"sourcesContent":["\"use client\";\nimport { CaretDownIcon } from \"@phosphor-icons/react\";\nimport React, { forwardRef, useEffect, useImperativeHandle, useRef } from \"react\";\nimport { useTranslations } from \"../../hooks/use-translations\";\nimport { css, initializeInputDataset, mergeRefs } from \"../../lib/dom\";\nimport { Override } from \"../../types\";\nimport { InputField, InputFieldProps } from \"./input-field\";\n\nexport type OptionProps = Override<\n React.ComponentProps<\"option\">,\n {\n value: string;\n \"data-dynamic\"?: string;\n } & Partial<Record<`data-${string}`, string>>\n>;\n\nexport type SelectProps = Override<\n InputFieldProps<\"select\">,\n {\n options: OptionProps[];\n selectContainer?: string;\n }\n>;\n\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(\n (\n {\n required = true,\n options,\n info,\n selectContainer: _selectContainer = \"\",\n feedback = null,\n labelClassName,\n interactive,\n rightLabel,\n hiddenLabel,\n loading,\n optionalText,\n container,\n hideLeft = false,\n right,\n left,\n error,\n ...props\n }: SelectProps,\n ref\n ) => {\n const translation = useTranslations();\n const inputRef = useRef<HTMLSelectElement>(null);\n const id = props.id ?? props.name;\n useImperativeHandle(ref, () => inputRef.current!);\n\n useEffect(() => {\n if (inputRef.current === null) return;\n const controller = new AbortController();\n const input = inputRef.current;\n const focus = initializeInputDataset(inputRef.current);\n input.addEventListener(\"change\", () => input.setAttribute(\"data-selected\", \"true\"), {\n once: true,\n signal: controller.signal,\n });\n return () => {\n focus();\n controller.abort();\n };\n }, []);\n\n const onClickLabel = () => inputRef.current?.focus();\n\n return (\n <InputField<\"select\">\n info={info}\n left={left}\n error={error}\n form={props.form}\n loading={loading}\n name={props.name}\n feedback={feedback}\n hideLeft={hideLeft}\n required={required}\n title={props.title}\n container={container}\n componentName=\"select\"\n rightLabel={rightLabel}\n hiddenLabel={hiddenLabel}\n interactive={interactive}\n id={props.name || props.id}\n optionalText={optionalText}\n labelClassName={labelClassName}\n placeholder={props.placeholder}\n right={\n <label htmlFor={id}>\n {right}\n <button onClick={onClickLabel} type=\"button\" className=\"mt-2 transition-colors hover:text-primary\">\n <CaretDownIcon size={20} />\n <span className=\"sr-only\">{translation.inputCaretDown}</span>\n </button>\n </label>\n }\n >\n <select\n {...props}\n id={id}\n name={id}\n required={required}\n ref={mergeRefs(ref, inputRef)}\n data-selected={!!props.value || false}\n title={typeof props.title === \"string\" ? props.title : undefined}\n className={css(\n \"input select group h-input-height w-full flex-1 appearance-none rounded-input-radius text-input-text\",\n \"bg-transparent px-input-padding-x py-input-padding-y text-foreground placeholder-input-placeholder\",\n \"outline-none transition-colors group-error:text-danger group-error:placeholder-input-mask-error\",\n \"data-[selected=false]:text-input-placeholder\",\n props.className\n )}\n >\n <option value=\"\" disabled hidden>\n {props.placeholder}\n </option>\n {options.map((option) => (\n <option\n {...option}\n value={option.value}\n key={`${id}-select-option-${option.value}`}\n >\n {option.label ?? option.value}\n </option>\n ))}\n </select>\n </InputField>\n );\n }\n);\n"],"mappings":";;;;;;;;AAwBA,IAAa,IAAS,GAEd,EACI,cAAW,IACX,YACA,SACA,iBAAiB,IAAmB,IACpC,cAAW,MACX,mBACA,gBACA,eACA,gBACA,YACA,iBACA,cACA,cAAW,IACX,UACA,SACA,UACA,GAAG,KAEP,MACC;CACD,IAAM,IAAc,EAAgB,GAC9B,IAAW,EAA0B,IAAI,GACzC,IAAK,EAAM,MAAM,EAAM;CAoB7B,OAnBA,EAAoB,SAAW,EAAS,OAAQ,GAEhD,QAAgB;EACZ,IAAI,EAAS,YAAY,MAAM;EAC/B,IAAM,IAAa,IAAI,gBAAgB,GACjC,IAAQ,EAAS,SACjB,IAAQ,EAAuB,EAAS,OAAO;EAKrD,OAJA,EAAM,iBAAiB,gBAAgB,EAAM,aAAa,iBAAiB,MAAM,GAAG;GAChF,MAAM;GACN,QAAQ,EAAW;EACvB,CAAC,SACY;GAET,AADA,EAAM,GACN,EAAW,MAAM;EACrB;CACJ,GAAG,CAAC,CAAC,GAKD,kBAAC,GAAD;EACU;EACA;EACC;EACP,MAAM,EAAM;EACH;EACT,MAAM,EAAM;EACF;EACA;EACA;EACV,OAAO,EAAM;EACF;EACX,eAAc;EACF;EACC;EACA;EACb,IAAI,EAAM,QAAQ,EAAM;EACV;EACE;EAChB,aAAa,EAAM;EACnB,OACI,kBAAC,SAAD;GAAO,SAAS;aAAhB,CACK,GACD,kBAAC,UAAD;IAAQ,eA1BG,EAAS,SAAS,MAAM;IA0BJ,MAAK;IAAS,WAAU;cAAvD,CACI,kBAAC,GAAD,EAAe,MAAM,GAAK,CAAA,GAC1B,kBAAC,QAAD;KAAM,WAAU;eAAW,EAAY;IAAqB,CAAA,CACxD;KACL;;YAGX,kBAAC,UAAD;GACI,GAAI;GACA;GACJ,MAAM;GACI;GACV,KAAK,EAAU,GAAK,CAAQ;GAC5B,iBAAe,CAAC,CAAC,EAAM,SAAS;GAChC,OAAO,OAAO,EAAM,SAAU,WAAW,EAAM,QAAQ,KAAA;GACvD,WAAW,EACP,wGACA,sGACA,mGACA,gDACA,EAAM,SACV;aAdJ,CAgBI,kBAAC,UAAD;IAAQ,OAAM;IAAG,UAAA;IAAS,QAAA;cACrB,EAAM;GACH,CAAA,GACP,EAAQ,KAAK,MACV,kBAAC,UAAD;IACI,GAAI;IACJ,OAAO,EAAO;IACd,KAAK,GAAG,EAAG,iBAAiB,EAAO;GAG/B,GADH,EAAO,SAAS,EAAO,KACpB,CACX,CACG;;CACA,CAAA;AAEpB,CACJ"}
1
+ {"version":3,"file":"select.js","names":[],"sources":["../../../src/components/form/select.tsx"],"sourcesContent":["\"use client\";\nimport { CaretDownIcon } from \"@phosphor-icons/react\";\nimport React, { forwardRef, useEffect, useId, useImperativeHandle, useRef } from \"react\";\nimport { useTranslations } from \"../../hooks/use-translations\";\nimport { css, initializeInputDataset, mergeRefs } from \"../../lib/dom\";\nimport { Override } from \"../../types\";\nimport { InputField, InputFieldProps } from \"./input-field\";\n\nexport type OptionProps = Override<\n React.ComponentProps<\"option\">,\n {\n value: string;\n \"data-dynamic\"?: string;\n } & Partial<Record<`data-${string}`, string>>\n>;\n\nexport type SelectProps = Override<\n InputFieldProps<\"select\">,\n {\n options: OptionProps[];\n selectContainer?: string;\n }\n>;\n\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(\n (\n {\n required = true,\n options,\n info,\n selectContainer: _selectContainer = \"\",\n feedback = null,\n labelClassName,\n interactive,\n rightLabel,\n hiddenLabel,\n loading,\n optionalText,\n container,\n hideLeft = false,\n right,\n left,\n error,\n ...props\n }: SelectProps,\n ref\n ) => {\n const translation = useTranslations();\n const inputRef = useRef<HTMLSelectElement>(null);\n const generatedId = useId();\n const id = props.id ?? props.name ?? generatedId;\n const describedBy =\n [props[\"aria-describedby\"], feedback ? `${id}-feedback` : undefined, error ? `${id}-error` : undefined].filter(Boolean).join(\" \") ||\n undefined;\n useImperativeHandle(ref, () => inputRef.current!);\n\n useEffect(() => {\n if (inputRef.current === null) return;\n const controller = new AbortController();\n const input = inputRef.current;\n const focus = initializeInputDataset(inputRef.current);\n input.addEventListener(\"change\", () => input.setAttribute(\"data-selected\", \"true\"), {\n once: true,\n signal: controller.signal,\n });\n return () => {\n focus();\n controller.abort();\n };\n }, []);\n\n const onClickLabel = () => inputRef.current?.focus();\n\n return (\n <InputField<\"select\">\n info={info}\n left={left}\n error={error}\n form={props.form}\n loading={loading}\n name={props.name ?? id}\n feedback={feedback}\n hideLeft={hideLeft}\n required={required}\n title={props.title}\n container={container}\n componentName=\"select\"\n rightLabel={rightLabel}\n hiddenLabel={hiddenLabel}\n interactive={interactive}\n id={id}\n optionalText={optionalText}\n labelClassName={labelClassName}\n placeholder={props.placeholder}\n right={\n <span>\n {right}\n <button onClick={onClickLabel} type=\"button\" className=\"mt-2 transition-colors hover:text-primary\">\n <CaretDownIcon size={20} />\n <span className=\"sr-only\">{translation.inputCaretDown}</span>\n </button>\n </span>\n }\n >\n <select\n {...props}\n id={id}\n name={props.name ?? id}\n required={required}\n ref={mergeRefs(ref, inputRef)}\n aria-invalid={error ? true : props[\"aria-invalid\"]}\n aria-labelledby={`${id}-label`}\n aria-describedby={describedBy}\n data-selected={!!props.value || false}\n title={typeof props.title === \"string\" ? props.title : undefined}\n className={css(\n \"input select group h-input-height w-full flex-1 appearance-none rounded-input-radius text-input-text\",\n \"bg-transparent px-input-padding-x py-input-padding-y text-foreground placeholder-input-placeholder\",\n \"outline-none transition-colors group-error:text-danger group-error:placeholder-input-mask-error\",\n \"data-[selected=false]:text-input-placeholder\",\n props.className\n )}\n >\n <option value=\"\" disabled hidden>\n {props.placeholder}\n </option>\n {options.map((option) => (\n <option {...option} value={option.value} key={`${id}-select-option-${option.value}`}>\n {option.label ?? option.value}\n </option>\n ))}\n </select>\n </InputField>\n );\n }\n);\n"],"mappings":";;;;;;;;AAwBA,IAAa,IAAS,GAEd,EACI,cAAW,IACX,YACA,SACA,iBAAiB,IAAmB,IACpC,cAAW,MACX,mBACA,gBACA,eACA,gBACA,YACA,iBACA,cACA,cAAW,IACX,UACA,SACA,UACA,GAAG,KAEP,MACC;CACD,IAAM,IAAc,EAAgB,GAC9B,IAAW,EAA0B,IAAI,GACzC,IAAc,EAAM,GACpB,IAAK,EAAM,MAAM,EAAM,QAAQ,GAC/B,IACF;EAAC,EAAM;EAAqB,IAAW,GAAG,EAAG,aAAa,KAAA;EAAW,IAAQ,GAAG,EAAG,UAAU,KAAA;CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,KAChI,KAAA;CAoBJ,OAnBA,EAAoB,SAAW,EAAS,OAAQ,GAEhD,QAAgB;EACZ,IAAI,EAAS,YAAY,MAAM;EAC/B,IAAM,IAAa,IAAI,gBAAgB,GACjC,IAAQ,EAAS,SACjB,IAAQ,EAAuB,EAAS,OAAO;EAKrD,OAJA,EAAM,iBAAiB,gBAAgB,EAAM,aAAa,iBAAiB,MAAM,GAAG;GAChF,MAAM;GACN,QAAQ,EAAW;EACvB,CAAC,SACY;GAET,AADA,EAAM,GACN,EAAW,MAAM;EACrB;CACJ,GAAG,CAAC,CAAC,GAKD,kBAAC,GAAD;EACU;EACA;EACC;EACP,MAAM,EAAM;EACH;EACT,MAAM,EAAM,QAAQ;EACV;EACA;EACA;EACV,OAAO,EAAM;EACF;EACX,eAAc;EACF;EACC;EACA;EACT;EACU;EACE;EAChB,aAAa,EAAM;EACnB,OACI,kBAAC,QAAD,EAAA,UAAA,CACK,GACD,kBAAC,UAAD;GAAQ,eA1BG,EAAS,SAAS,MAAM;GA0BJ,MAAK;GAAS,WAAU;aAAvD,CACI,kBAAC,GAAD,EAAe,MAAM,GAAK,CAAA,GAC1B,kBAAC,QAAD;IAAM,WAAU;cAAW,EAAY;GAAqB,CAAA,CACxD;IACN,EAAA,CAAA;YAGV,kBAAC,UAAD;GACI,GAAI;GACA;GACJ,MAAM,EAAM,QAAQ;GACV;GACV,KAAK,EAAU,GAAK,CAAQ;GAC5B,gBAAc,IAAQ,KAAO,EAAM;GACnC,mBAAiB,GAAG,EAAG;GACvB,oBAAkB;GAClB,iBAAe,CAAC,CAAC,EAAM,SAAS;GAChC,OAAO,OAAO,EAAM,SAAU,WAAW,EAAM,QAAQ,KAAA;GACvD,WAAW,EACP,wGACA,sGACA,mGACA,gDACA,EAAM,SACV;aAjBJ,CAmBI,kBAAC,UAAD;IAAQ,OAAM;IAAG,UAAA;IAAS,QAAA;cACrB,EAAM;GACH,CAAA,GACP,EAAQ,KAAK,MACV,kBAAC,UAAD;IAAQ,GAAI;IAAQ,OAAO,EAAO;IAAO,KAAK,GAAG,EAAG,iBAAiB,EAAO;GAEpE,GADH,EAAO,SAAS,EAAO,KACpB,CACX,CACG;;CACA,CAAA;AAEpB,CACJ"}
@@ -1,13 +1,16 @@
1
1
  "use client";
2
2
  import { CaretDownIcon } from "@phosphor-icons/react";
3
- import React, { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
3
+ import React, { forwardRef, useEffect, useId, useImperativeHandle, useRef } from "react";
4
4
  import { useTranslations } from "../../hooks/use-translations";
5
5
  import { css, initializeInputDataset, mergeRefs } from "../../lib/dom";
6
6
  import { InputField } from "./input-field";
7
7
  export const Select = forwardRef(({ required = true, options, info, selectContainer: _selectContainer = "", feedback = null, labelClassName, interactive, rightLabel, hiddenLabel, loading, optionalText, container, hideLeft = false, right, left, error, ...props }, ref) => {
8
8
  const translation = useTranslations();
9
9
  const inputRef = useRef(null);
10
- const id = props.id ?? props.name;
10
+ const generatedId = useId();
11
+ const id = props.id ?? props.name ?? generatedId;
12
+ const describedBy = [props["aria-describedby"], feedback ? `${id}-feedback` : undefined, error ? `${id}-error` : undefined].filter(Boolean).join(" ") ||
13
+ undefined;
11
14
  useImperativeHandle(ref, () => inputRef.current);
12
15
  useEffect(() => {
13
16
  if (inputRef.current === null)
@@ -25,14 +28,14 @@ export const Select = forwardRef(({ required = true, options, info, selectContai
25
28
  };
26
29
  }, []);
27
30
  const onClickLabel = () => inputRef.current?.focus();
28
- return (<InputField info={info} left={left} error={error} form={props.form} loading={loading} name={props.name} feedback={feedback} hideLeft={hideLeft} required={required} title={props.title} container={container} componentName="select" rightLabel={rightLabel} hiddenLabel={hiddenLabel} interactive={interactive} id={props.name || props.id} optionalText={optionalText} labelClassName={labelClassName} placeholder={props.placeholder} right={<label htmlFor={id}>
31
+ return (<InputField info={info} left={left} error={error} form={props.form} loading={loading} name={props.name ?? id} feedback={feedback} hideLeft={hideLeft} required={required} title={props.title} container={container} componentName="select" rightLabel={rightLabel} hiddenLabel={hiddenLabel} interactive={interactive} id={id} optionalText={optionalText} labelClassName={labelClassName} placeholder={props.placeholder} right={<span>
29
32
  {right}
30
33
  <button onClick={onClickLabel} type="button" className="mt-2 transition-colors hover:text-primary">
31
34
  <CaretDownIcon size={20}/>
32
35
  <span className="sr-only">{translation.inputCaretDown}</span>
33
36
  </button>
34
- </label>}>
35
- <select {...props} id={id} name={id} required={required} ref={mergeRefs(ref, inputRef)} data-selected={!!props.value || false} title={typeof props.title === "string" ? props.title : undefined} className={css("input select group h-input-height w-full flex-1 appearance-none rounded-input-radius text-input-text", "bg-transparent px-input-padding-x py-input-padding-y text-foreground placeholder-input-placeholder", "outline-none transition-colors group-error:text-danger group-error:placeholder-input-mask-error", "data-[selected=false]:text-input-placeholder", props.className)}>
37
+ </span>}>
38
+ <select {...props} id={id} name={props.name ?? id} required={required} ref={mergeRefs(ref, inputRef)} aria-invalid={error ? true : props["aria-invalid"]} aria-labelledby={`${id}-label`} aria-describedby={describedBy} data-selected={!!props.value || false} title={typeof props.title === "string" ? props.title : undefined} className={css("input select group h-input-height w-full flex-1 appearance-none rounded-input-radius text-input-text", "bg-transparent px-input-padding-x py-input-padding-y text-foreground placeholder-input-placeholder", "outline-none transition-colors group-error:text-danger group-error:placeholder-input-mask-error", "data-[selected=false]:text-input-placeholder", props.className)}>
36
39
  <option value="" disabled hidden>
37
40
  {props.placeholder}
38
41
  </option>
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import { t as e } from "../../slider-TX9hiHO-.js";
3
+ export { e as Slider };
@@ -1,8 +1,9 @@
1
1
  import React from "react";
2
- export type SwitchProps = React.ComponentProps<"input"> & {
2
+ export type SwitchProps = Omit<React.ComponentProps<"input">, "onKeyDown"> & {
3
3
  error?: string;
4
4
  loading?: boolean;
5
5
  container?: string;
6
+ onKeyDown?: React.KeyboardEventHandler<HTMLButtonElement>;
6
7
  onCheck?: (nextValue: boolean) => void;
7
8
  };
8
9
  export declare const Switch: React.ForwardRefExoticComponent<Omit<SwitchProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
@@ -1 +1 @@
1
- {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/components/form/switch.tsx"],"names":[],"mappings":"AACA,OAAO,KAA8E,MAAM,OAAO,CAAC;AAInG,MAAM,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C,CAAC;AAEF,eAAO,MAAM,MAAM,mGAqEjB,CAAC"}
1
+ {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/components/form/switch.tsx"],"names":[],"mappings":"AACA,OAAO,KAA8E,MAAM,OAAO,CAAC;AAInG,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,GAAG;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAC1D,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C,CAAC;AAEF,eAAO,MAAM,MAAM,mGA2FlB,CAAC"}
@@ -4,58 +4,63 @@ import { t } from "../../use-stable-ref-D5LFCx0u.js";
4
4
  import { forwardRef as n, useEffect as r, useId as i, useImperativeHandle as a, useRef as o, useState as s } from "react";
5
5
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
6
6
  //#region src/components/form/switch.tsx
7
- var u = n(({ children: n, loading: u, container: d, error: f, ...p }, m) => {
8
- let h = i(), [g, _] = s(p.checked ?? !1), v = g, y = o(null), b = t(p.onChange);
9
- a(m, () => y.current), r(() => {
10
- if (y.current !== null && b.current) {
7
+ var u = n(({ children: n, loading: u, container: d, error: f, onKeyDown: p, onCheck: m, ...h }, g) => {
8
+ let _ = i(), v = f ? `${h.id || _}-error` : void 0, y = [h["aria-describedby"], v].filter(Boolean).join(" ") || void 0, b = f ? !0 : h["aria-invalid"], [x, S] = s(h.checked ?? !1), C = x, w = o(null), T = t(h.onChange);
9
+ a(g, () => w.current), r(() => {
10
+ if (w.current !== null && T.current) {
11
11
  let e = (e) => {
12
- b.current && b.current(e);
13
- }, t = y.current;
12
+ T.current && T.current(e);
13
+ }, t = w.current;
14
14
  return t.addEventListener("change", e), () => t?.removeEventListener("change", e);
15
15
  }
16
- }, [b]);
17
- let x = () => {
18
- let e = !y.current?.checked;
19
- _(e), p?.onCheck?.(e), y.current !== null && (y.current.checked = e, y.current.dispatchEvent(new Event("change", { bubbles: !0 })));
16
+ }, [T]);
17
+ let E = () => {
18
+ let e = !w.current?.checked;
19
+ S(e), m?.(e), w.current !== null && (w.current.checked = e, w.current.dispatchEvent(new Event("change", { bubbles: !0 })));
20
20
  };
21
21
  return /* @__PURE__ */ l("fieldset", {
22
22
  className: e("flex flex-col flex-wrap justify-center", d),
23
23
  "data-component": "switch",
24
- disabled: p.disabled || u,
24
+ disabled: h.disabled || u,
25
25
  children: [/* @__PURE__ */ l("span", {
26
26
  className: "flex flex-row flex-wrap items-center",
27
27
  children: [
28
28
  /* @__PURE__ */ c("input", {
29
- ...p,
29
+ ...h,
30
30
  hidden: !0,
31
- ref: y,
31
+ ref: w,
32
32
  type: "checkbox",
33
- checked: v,
34
- id: p.id || h,
33
+ checked: C,
34
+ id: h.id || _,
35
35
  "data-trigger": "change",
36
- "data-checked": v,
37
- disabled: p.disabled || u,
38
- onChange: (e) => _(e.target.checked)
36
+ "data-checked": C,
37
+ disabled: h.disabled || u,
38
+ onChange: (e) => S(e.target.checked)
39
39
  }),
40
40
  /* @__PURE__ */ c("button", {
41
41
  role: "switch",
42
42
  type: "button",
43
- onClick: x,
44
- "aria-checked": v,
45
- "data-checked": v,
46
- "aria-labelledby": `${h}-label`,
47
- disabled: p.disabled || u,
43
+ onClick: E,
44
+ onKeyDown: (e) => {
45
+ p?.(e), !e.defaultPrevented && (e.key === " " || e.key === "Space" || e.code === "Space" || e.key === "Enter") && (e.preventDefault(), E());
46
+ },
47
+ "aria-checked": C,
48
+ "aria-invalid": b,
49
+ "aria-describedby": y,
50
+ "data-checked": C,
51
+ "aria-labelledby": `${_}-label`,
52
+ disabled: h.disabled || u,
48
53
  className: "relative inline-flex h-switch-track-h w-switch-track-w flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-300 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 data-[checked=false]:bg-input-switch-bg data-[checked=true]:bg-primary",
49
54
  children: /* @__PURE__ */ c("span", {
50
55
  "aria-hidden": "true",
51
- "data-checked": v,
56
+ "data-checked": C,
52
57
  className: "inline-block aspect-square size-switch-thumb-size transform rounded-full shadow ring-0 transition duration-300 ease-in-out data-[checked=false]:translate-x-0 data-[checked=true]:translate-x-5 data-[checked=false]:bg-disabled data-[checked=true]:bg-input-switch"
53
58
  })
54
59
  }),
55
60
  /* @__PURE__ */ c("label", {
56
- htmlFor: p.id || h,
61
+ htmlFor: h.id || _,
57
62
  className: "ml-switch-gap inline-block text-switch-label-text",
58
- id: `${h}-label`,
63
+ id: `${_}-label`,
59
64
  children: /* @__PURE__ */ c("span", {
60
65
  className: "font-medium text-foreground",
61
66
  children: n
@@ -63,6 +68,7 @@ var u = n(({ children: n, loading: u, container: d, error: f, ...p }, m) => {
63
68
  })
64
69
  ]
65
70
  }), /* @__PURE__ */ c("span", {
71
+ id: v,
66
72
  className: "mt-switch-hint-mt flex-1 whitespace-nowrap text-switch-hint-text text-danger empty:mt-0 empty:hidden",
67
73
  children: f
68
74
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"switch.js","names":[],"sources":["../../../src/components/form/switch.tsx"],"sourcesContent":["\"use client\";\nimport React, { forwardRef, useEffect, useId, useImperativeHandle, useRef, useState } from \"react\";\nimport { useStableRef } from \"../../hooks/use-stable-ref\";\nimport { css } from \"../../lib/dom\";\n\nexport type SwitchProps = React.ComponentProps<\"input\"> & {\n error?: string;\n loading?: boolean;\n container?: string;\n onCheck?: (nextValue: boolean) => void;\n};\n\nexport const Switch = forwardRef<HTMLInputElement, SwitchProps>(({ children, loading, container, error, ...props }: SwitchProps, ref) => {\n const id = useId();\n const [innerChecked, setInnerChecked] = useState(props.checked ?? false);\n const checked = innerChecked;\n const innerRef = useRef<HTMLInputElement>(null);\n const stableOnChange = useStableRef(props.onChange);\n useImperativeHandle(ref, () => innerRef.current!);\n\n useEffect(() => {\n if (innerRef.current !== null) {\n if (stableOnChange.current) {\n const onChange = (e: Event) => {\n if (stableOnChange.current) stableOnChange.current(e as unknown as React.ChangeEvent<HTMLInputElement>);\n };\n const ref = innerRef.current;\n ref.addEventListener(\"change\", onChange);\n return () => ref?.removeEventListener(\"change\", onChange);\n }\n }\n }, [stableOnChange]);\n\n const onCheck = () => {\n const checked = !innerRef.current?.checked;\n setInnerChecked(checked);\n props?.onCheck?.(checked);\n if (innerRef.current !== null) {\n innerRef.current.checked = checked;\n innerRef.current.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n };\n\n return (\n <fieldset className={css(\"flex flex-col flex-wrap justify-center\", container)} data-component=\"switch\" disabled={props.disabled || loading}>\n <span className=\"flex flex-row flex-wrap items-center\">\n <input\n {...props}\n hidden\n ref={innerRef}\n type=\"checkbox\"\n checked={checked}\n id={props.id || id}\n data-trigger=\"change\"\n data-checked={checked}\n disabled={props.disabled || loading}\n onChange={(e) => setInnerChecked(e.target.checked)}\n />\n <button\n role=\"switch\"\n type=\"button\"\n onClick={onCheck}\n aria-checked={checked}\n data-checked={checked}\n aria-labelledby={`${id}-label`}\n disabled={props.disabled || loading}\n className=\"relative inline-flex h-switch-track-h w-switch-track-w flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-300 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 data-[checked=false]:bg-input-switch-bg data-[checked=true]:bg-primary\"\n >\n <span\n aria-hidden=\"true\"\n data-checked={checked}\n className=\"inline-block aspect-square size-switch-thumb-size transform rounded-full shadow ring-0 transition duration-300 ease-in-out data-[checked=false]:translate-x-0 data-[checked=true]:translate-x-5 data-[checked=false]:bg-disabled data-[checked=true]:bg-input-switch\"\n />\n </button>\n <label htmlFor={props.id || id} className=\"ml-switch-gap inline-block text-switch-label-text\" id={`${id}-label`}>\n <span className=\"font-medium text-foreground\">{children}</span>\n </label>\n </span>\n <span className=\"mt-switch-hint-mt flex-1 whitespace-nowrap text-switch-hint-text text-danger empty:mt-0 empty:hidden\">{error}</span>\n </fieldset>\n );\n});\n"],"mappings":";;;;;;AAYA,IAAa,IAAS,GAA2C,EAAE,aAAU,YAAS,cAAW,UAAO,GAAG,KAAsB,MAAQ;CACrI,IAAM,IAAK,EAAM,GACX,CAAC,GAAc,KAAmB,EAAS,EAAM,WAAW,EAAK,GACjE,IAAU,GACV,IAAW,EAAyB,IAAI,GACxC,IAAiB,EAAa,EAAM,QAAQ;CAGlD,AAFA,EAAoB,SAAW,EAAS,OAAQ,GAEhD,QAAgB;EACZ,IAAI,EAAS,YAAY,QACjB,EAAe,SAAS;GACxB,IAAM,KAAY,MAAa;IAC3B,AAAI,EAAe,WAAS,EAAe,QAAQ,CAAmD;GAC1G,GACM,IAAM,EAAS;GAErB,OADA,EAAI,iBAAiB,UAAU,CAAQ,SAC1B,GAAK,oBAAoB,UAAU,CAAQ;EAC5D;CAER,GAAG,CAAC,CAAc,CAAC;CAEnB,IAAM,UAAgB;EAClB,IAAM,IAAU,CAAC,EAAS,SAAS;EAGnC,AAFA,EAAgB,CAAO,GACvB,GAAO,UAAU,CAAO,GACpB,EAAS,YAAY,SACrB,EAAS,QAAQ,UAAU,GAC3B,EAAS,QAAQ,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,GAAK,CAAC,CAAC;CAE7E;CAEA,OACI,kBAAC,YAAD;EAAU,WAAW,EAAI,0CAA0C,CAAS;EAAG,kBAAe;EAAS,UAAU,EAAM,YAAY;YAAnI,CACI,kBAAC,QAAD;GAAM,WAAU;aAAhB;IACI,kBAAC,SAAD;KACI,GAAI;KACJ,QAAA;KACA,KAAK;KACL,MAAK;KACI;KACT,IAAI,EAAM,MAAM;KAChB,gBAAa;KACb,gBAAc;KACd,UAAU,EAAM,YAAY;KAC5B,WAAW,MAAM,EAAgB,EAAE,OAAO,OAAO;IACpD,CAAA;IACD,kBAAC,UAAD;KACI,MAAK;KACL,MAAK;KACL,SAAS;KACT,gBAAc;KACd,gBAAc;KACd,mBAAiB,GAAG,EAAG;KACvB,UAAU,EAAM,YAAY;KAC5B,WAAU;eAEV,kBAAC,QAAD;MACI,eAAY;MACZ,gBAAc;MACd,WAAU;KACb,CAAA;IACG,CAAA;IACR,kBAAC,SAAD;KAAO,SAAS,EAAM,MAAM;KAAI,WAAU;KAAoD,IAAI,GAAG,EAAG;eACpG,kBAAC,QAAD;MAAM,WAAU;MAA+B;KAAe,CAAA;IAC3D,CAAA;GACL;MACN,kBAAC,QAAD;GAAM,WAAU;aAAwG;EAAY,CAAA,CAC9H;;AAElB,CAAC"}
1
+ {"version":3,"file":"switch.js","names":[],"sources":["../../../src/components/form/switch.tsx"],"sourcesContent":["\"use client\";\nimport React, { forwardRef, useEffect, useId, useImperativeHandle, useRef, useState } from \"react\";\nimport { useStableRef } from \"../../hooks/use-stable-ref\";\nimport { css } from \"../../lib/dom\";\n\nexport type SwitchProps = Omit<React.ComponentProps<\"input\">, \"onKeyDown\"> & {\n error?: string;\n loading?: boolean;\n container?: string;\n onKeyDown?: React.KeyboardEventHandler<HTMLButtonElement>;\n onCheck?: (nextValue: boolean) => void;\n};\n\nexport const Switch = forwardRef<HTMLInputElement, SwitchProps>(\n ({ children, loading, container, error, onKeyDown, onCheck: onCheckProp, ...props }: SwitchProps, ref) => {\n const id = useId();\n const errorId = error ? `${props.id || id}-error` : undefined;\n const describedBy = [props[\"aria-describedby\"], errorId].filter(Boolean).join(\" \") || undefined;\n const ariaInvalid = error ? true : props[\"aria-invalid\"];\n const [innerChecked, setInnerChecked] = useState(props.checked ?? false);\n const checked = innerChecked;\n const innerRef = useRef<HTMLInputElement>(null);\n const stableOnChange = useStableRef(props.onChange);\n useImperativeHandle(ref, () => innerRef.current!);\n\n useEffect(() => {\n if (innerRef.current !== null) {\n if (stableOnChange.current) {\n const onChange = (e: Event) => {\n if (stableOnChange.current) stableOnChange.current(e as unknown as React.ChangeEvent<HTMLInputElement>);\n };\n const ref = innerRef.current;\n ref.addEventListener(\"change\", onChange);\n return () => ref?.removeEventListener(\"change\", onChange);\n }\n }\n }, [stableOnChange]);\n\n const onCheck = () => {\n const checked = !innerRef.current?.checked;\n setInnerChecked(checked);\n onCheckProp?.(checked);\n if (innerRef.current !== null) {\n innerRef.current.checked = checked;\n innerRef.current.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n };\n\n return (\n <fieldset\n className={css(\"flex flex-col flex-wrap justify-center\", container)}\n data-component=\"switch\"\n disabled={props.disabled || loading}\n >\n <span className=\"flex flex-row flex-wrap items-center\">\n <input\n {...props}\n hidden\n ref={innerRef}\n type=\"checkbox\"\n checked={checked}\n id={props.id || id}\n data-trigger=\"change\"\n data-checked={checked}\n disabled={props.disabled || loading}\n onChange={(e) => setInnerChecked(e.target.checked)}\n />\n <button\n role=\"switch\"\n type=\"button\"\n onClick={onCheck}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n\n if (event.defaultPrevented) return;\n if (event.key === \" \" || event.key === \"Space\" || event.code === \"Space\" || event.key === \"Enter\") {\n event.preventDefault();\n onCheck();\n }\n }}\n aria-checked={checked}\n aria-invalid={ariaInvalid}\n aria-describedby={describedBy}\n data-checked={checked}\n aria-labelledby={`${id}-label`}\n disabled={props.disabled || loading}\n className=\"relative inline-flex h-switch-track-h w-switch-track-w flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-300 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 data-[checked=false]:bg-input-switch-bg data-[checked=true]:bg-primary\"\n >\n <span\n aria-hidden=\"true\"\n data-checked={checked}\n className=\"inline-block aspect-square size-switch-thumb-size transform rounded-full shadow ring-0 transition duration-300 ease-in-out data-[checked=false]:translate-x-0 data-[checked=true]:translate-x-5 data-[checked=false]:bg-disabled data-[checked=true]:bg-input-switch\"\n />\n </button>\n <label htmlFor={props.id || id} className=\"ml-switch-gap inline-block text-switch-label-text\" id={`${id}-label`}>\n <span className=\"font-medium text-foreground\">{children}</span>\n </label>\n </span>\n <span id={errorId} className=\"mt-switch-hint-mt flex-1 whitespace-nowrap text-switch-hint-text text-danger empty:mt-0 empty:hidden\">\n {error}\n </span>\n </fieldset>\n );\n }\n);\n"],"mappings":";;;;;;AAaA,IAAa,IAAS,GACjB,EAAE,aAAU,YAAS,cAAW,UAAO,cAAW,SAAS,GAAa,GAAG,KAAsB,MAAQ;CACtG,IAAM,IAAK,EAAM,GACX,IAAU,IAAQ,GAAG,EAAM,MAAM,EAAG,UAAU,KAAA,GAC9C,IAAc,CAAC,EAAM,qBAAqB,CAAO,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK,KAAA,GAChF,IAAc,IAAQ,KAAO,EAAM,iBACnC,CAAC,GAAc,KAAmB,EAAS,EAAM,WAAW,EAAK,GACjE,IAAU,GACV,IAAW,EAAyB,IAAI,GACxC,IAAiB,EAAa,EAAM,QAAQ;CAGlD,AAFA,EAAoB,SAAW,EAAS,OAAQ,GAEhD,QAAgB;EACZ,IAAI,EAAS,YAAY,QACjB,EAAe,SAAS;GACxB,IAAM,KAAY,MAAa;IAC3B,AAAI,EAAe,WAAS,EAAe,QAAQ,CAAmD;GAC1G,GACM,IAAM,EAAS;GAErB,OADA,EAAI,iBAAiB,UAAU,CAAQ,SAC1B,GAAK,oBAAoB,UAAU,CAAQ;EAC5D;CAER,GAAG,CAAC,CAAc,CAAC;CAEnB,IAAM,UAAgB;EAClB,IAAM,IAAU,CAAC,EAAS,SAAS;EAGnC,AAFA,EAAgB,CAAO,GACvB,IAAc,CAAO,GACjB,EAAS,YAAY,SACrB,EAAS,QAAQ,UAAU,GAC3B,EAAS,QAAQ,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,GAAK,CAAC,CAAC;CAE7E;CAEA,OACI,kBAAC,YAAD;EACI,WAAW,EAAI,0CAA0C,CAAS;EAClE,kBAAe;EACf,UAAU,EAAM,YAAY;YAHhC,CAKI,kBAAC,QAAD;GAAM,WAAU;aAAhB;IACI,kBAAC,SAAD;KACI,GAAI;KACJ,QAAA;KACA,KAAK;KACL,MAAK;KACI;KACT,IAAI,EAAM,MAAM;KAChB,gBAAa;KACb,gBAAc;KACd,UAAU,EAAM,YAAY;KAC5B,WAAW,MAAM,EAAgB,EAAE,OAAO,OAAO;IACpD,CAAA;IACD,kBAAC,UAAD;KACI,MAAK;KACL,MAAK;KACL,SAAS;KACT,YAAY,MAAU;MAClB,IAAY,CAAK,GAEb,GAAM,qBACN,EAAM,QAAQ,OAAO,EAAM,QAAQ,WAAW,EAAM,SAAS,WAAW,EAAM,QAAQ,aACtF,EAAM,eAAe,GACrB,EAAQ;KAEhB;KACA,gBAAc;KACd,gBAAc;KACd,oBAAkB;KAClB,gBAAc;KACd,mBAAiB,GAAG,EAAG;KACvB,UAAU,EAAM,YAAY;KAC5B,WAAU;eAEV,kBAAC,QAAD;MACI,eAAY;MACZ,gBAAc;MACd,WAAU;KACb,CAAA;IACG,CAAA;IACR,kBAAC,SAAD;KAAO,SAAS,EAAM,MAAM;KAAI,WAAU;KAAoD,IAAI,GAAG,EAAG;eACpG,kBAAC,QAAD;MAAM,WAAU;MAA+B;KAAe,CAAA;IAC3D,CAAA;GACL;MACN,kBAAC,QAAD;GAAM,IAAI;GAAS,WAAU;aACxB;EACC,CAAA,CACA;;AAElB,CACJ"}