@5voltfx/design-system 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/dist/chunk-2KHDM6UP.js +58 -0
  2. package/dist/chunk-2KHDM6UP.js.map +1 -0
  3. package/dist/chunk-45346SXP.js +65 -0
  4. package/dist/chunk-45346SXP.js.map +1 -0
  5. package/dist/chunk-BAISLPWP.js +14 -0
  6. package/dist/chunk-BAISLPWP.js.map +1 -0
  7. package/dist/chunk-CT2TMR44.js +1 -0
  8. package/dist/chunk-CT2TMR44.js.map +1 -0
  9. package/dist/chunk-DD5VKG3L.js +22 -0
  10. package/dist/chunk-DD5VKG3L.js.map +1 -0
  11. package/dist/chunk-HLP2MPQ6.js +110 -0
  12. package/dist/chunk-HLP2MPQ6.js.map +1 -0
  13. package/dist/chunk-HPOL5NKF.js +22 -0
  14. package/dist/chunk-HPOL5NKF.js.map +1 -0
  15. package/dist/chunk-I3NS5MAC.js +23 -0
  16. package/dist/chunk-I3NS5MAC.js.map +1 -0
  17. package/dist/chunk-LPEUQ2DE.js +48 -0
  18. package/dist/chunk-LPEUQ2DE.js.map +1 -0
  19. package/dist/chunk-LY5MPGW2.js +129 -0
  20. package/dist/chunk-LY5MPGW2.js.map +1 -0
  21. package/dist/chunk-NJ2SBQYA.js +1208 -0
  22. package/dist/chunk-NJ2SBQYA.js.map +1 -0
  23. package/dist/chunk-R42A3ZCY.js +16 -0
  24. package/dist/chunk-R42A3ZCY.js.map +1 -0
  25. package/dist/chunk-UZW4E2UH.js +206 -0
  26. package/dist/chunk-UZW4E2UH.js.map +1 -0
  27. package/dist/chunk-VRGTUKSJ.js +20 -0
  28. package/dist/chunk-VRGTUKSJ.js.map +1 -0
  29. package/dist/chunk-YLUQANAI.js +1023 -0
  30. package/dist/chunk-YLUQANAI.js.map +1 -0
  31. package/dist/chunk-ZVUDPTFZ.js +76 -0
  32. package/dist/chunk-ZVUDPTFZ.js.map +1 -0
  33. package/dist/components/Accordion/Accordion.d.ts +29 -0
  34. package/dist/components/Accordion/Accordion.d.ts.map +1 -0
  35. package/dist/components/Accordion/index.css +58 -0
  36. package/dist/components/Accordion/index.css.map +1 -0
  37. package/dist/components/Accordion/index.d.ts +2 -0
  38. package/dist/components/Accordion/index.d.ts.map +1 -0
  39. package/dist/components/Accordion/index.js +7 -0
  40. package/dist/components/Accordion/index.js.map +1 -0
  41. package/dist/components/Button/Button.d.ts +8 -0
  42. package/dist/components/Button/Button.d.ts.map +1 -0
  43. package/dist/components/Button/index.d.ts +2 -0
  44. package/dist/components/Button/index.d.ts.map +1 -0
  45. package/dist/components/Card/Card.d.ts +6 -0
  46. package/dist/components/Card/Card.d.ts.map +1 -0
  47. package/dist/components/Card/index.d.ts +2 -0
  48. package/dist/components/Card/index.d.ts.map +1 -0
  49. package/dist/components/Checkbox/Checkbox.d.ts +15 -0
  50. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -0
  51. package/dist/components/Checkbox/index.css +57 -0
  52. package/dist/components/Checkbox/index.css.map +1 -0
  53. package/dist/components/Checkbox/index.d.ts +2 -0
  54. package/dist/components/Checkbox/index.d.ts.map +1 -0
  55. package/dist/components/Checkbox/index.js +7 -0
  56. package/dist/components/Checkbox/index.js.map +1 -0
  57. package/dist/components/DialNav/DialNav.d.ts +48 -0
  58. package/dist/components/DialNav/DialNav.d.ts.map +1 -0
  59. package/dist/components/DialNav/geometry.d.ts +159 -0
  60. package/dist/components/DialNav/geometry.d.ts.map +1 -0
  61. package/dist/components/DialNav/index.css +321 -0
  62. package/dist/components/DialNav/index.css.map +1 -0
  63. package/dist/components/DialNav/index.d.ts +2 -0
  64. package/dist/components/DialNav/index.d.ts.map +1 -0
  65. package/dist/components/DialNav/index.js +8 -0
  66. package/dist/components/DialNav/index.js.map +1 -0
  67. package/dist/components/DialNav/variants/Concentric.d.ts +10 -0
  68. package/dist/components/DialNav/variants/Concentric.d.ts.map +1 -0
  69. package/dist/components/DialNav/variants/RatchetFan.d.ts +12 -0
  70. package/dist/components/DialNav/variants/RatchetFan.d.ts.map +1 -0
  71. package/dist/components/DialNav/variants/Volvelle.d.ts +12 -0
  72. package/dist/components/DialNav/variants/Volvelle.d.ts.map +1 -0
  73. package/dist/components/Footer/Footer.d.ts +15 -0
  74. package/dist/components/Footer/Footer.d.ts.map +1 -0
  75. package/dist/components/Footer/index.d.ts +2 -0
  76. package/dist/components/Footer/index.d.ts.map +1 -0
  77. package/dist/components/FormField/FormField.d.ts +27 -0
  78. package/dist/components/FormField/FormField.d.ts.map +1 -0
  79. package/dist/components/FormField/index.css +31 -0
  80. package/dist/components/FormField/index.css.map +1 -0
  81. package/dist/components/FormField/index.d.ts +2 -0
  82. package/dist/components/FormField/index.d.ts.map +1 -0
  83. package/dist/components/FormField/index.js +8 -0
  84. package/dist/components/FormField/index.js.map +1 -0
  85. package/dist/components/Header/Header.d.ts +15 -0
  86. package/dist/components/Header/Header.d.ts.map +1 -0
  87. package/dist/components/Header/index.d.ts +2 -0
  88. package/dist/components/Header/index.d.ts.map +1 -0
  89. package/dist/components/Input/Input.d.ts +16 -0
  90. package/dist/components/Input/Input.d.ts.map +1 -0
  91. package/dist/components/Input/index.css +45 -0
  92. package/dist/components/Input/index.css.map +1 -0
  93. package/dist/components/Input/index.d.ts +2 -0
  94. package/dist/components/Input/index.d.ts.map +1 -0
  95. package/dist/components/Input/index.js +7 -0
  96. package/dist/components/Input/index.js.map +1 -0
  97. package/dist/components/Label/Label.d.ts +15 -0
  98. package/dist/components/Label/Label.d.ts.map +1 -0
  99. package/dist/components/Label/index.css +14 -0
  100. package/dist/components/Label/index.css.map +1 -0
  101. package/dist/components/Label/index.d.ts +2 -0
  102. package/dist/components/Label/index.d.ts.map +1 -0
  103. package/dist/components/Label/index.js +8 -0
  104. package/dist/components/Label/index.js.map +1 -0
  105. package/dist/components/Layout/Container.d.ts +6 -0
  106. package/dist/components/Layout/Container.d.ts.map +1 -0
  107. package/dist/components/Layout/Grid.d.ts +9 -0
  108. package/dist/components/Layout/Grid.d.ts.map +1 -0
  109. package/dist/components/Layout/Stack.d.ts +10 -0
  110. package/dist/components/Layout/Stack.d.ts.map +1 -0
  111. package/dist/components/Layout/index.d.ts +4 -0
  112. package/dist/components/Layout/index.d.ts.map +1 -0
  113. package/dist/components/Menu/Menu.d.ts +30 -0
  114. package/dist/components/Menu/Menu.d.ts.map +1 -0
  115. package/dist/components/Menu/index.css +77 -0
  116. package/dist/components/Menu/index.css.map +1 -0
  117. package/dist/components/Menu/index.d.ts +2 -0
  118. package/dist/components/Menu/index.d.ts.map +1 -0
  119. package/dist/components/Menu/index.js +7 -0
  120. package/dist/components/Menu/index.js.map +1 -0
  121. package/dist/components/Modal/Modal.d.ts +24 -0
  122. package/dist/components/Modal/Modal.d.ts.map +1 -0
  123. package/dist/components/Modal/index.css +101 -0
  124. package/dist/components/Modal/index.css.map +1 -0
  125. package/dist/components/Modal/index.d.ts +2 -0
  126. package/dist/components/Modal/index.d.ts.map +1 -0
  127. package/dist/components/Modal/index.js +7 -0
  128. package/dist/components/Modal/index.js.map +1 -0
  129. package/dist/components/Nav/Nav.d.ts +10 -0
  130. package/dist/components/Nav/Nav.d.ts.map +1 -0
  131. package/dist/components/Nav/index.d.ts +2 -0
  132. package/dist/components/Nav/index.d.ts.map +1 -0
  133. package/dist/components/Radio/Radio.d.ts +17 -0
  134. package/dist/components/Radio/Radio.d.ts.map +1 -0
  135. package/dist/components/Radio/RadioGroup.d.ts +25 -0
  136. package/dist/components/Radio/RadioGroup.d.ts.map +1 -0
  137. package/dist/components/Radio/RadioGroupContext.d.ts +7 -0
  138. package/dist/components/Radio/RadioGroupContext.d.ts.map +1 -0
  139. package/dist/components/Radio/index.css +57 -0
  140. package/dist/components/Radio/index.css.map +1 -0
  141. package/dist/components/Radio/index.d.ts +3 -0
  142. package/dist/components/Radio/index.d.ts.map +1 -0
  143. package/dist/components/Radio/index.js +9 -0
  144. package/dist/components/Radio/index.js.map +1 -0
  145. package/dist/components/Select/Select.d.ts +18 -0
  146. package/dist/components/Select/Select.d.ts.map +1 -0
  147. package/dist/components/Select/index.css +52 -0
  148. package/dist/components/Select/index.css.map +1 -0
  149. package/dist/components/Select/index.d.ts +2 -0
  150. package/dist/components/Select/index.d.ts.map +1 -0
  151. package/dist/components/Select/index.js +7 -0
  152. package/dist/components/Select/index.js.map +1 -0
  153. package/dist/components/SlideRuleNav/SlideRuleNav.d.ts +54 -0
  154. package/dist/components/SlideRuleNav/SlideRuleNav.d.ts.map +1 -0
  155. package/dist/components/SlideRuleNav/geometry.d.ts +168 -0
  156. package/dist/components/SlideRuleNav/geometry.d.ts.map +1 -0
  157. package/dist/components/SlideRuleNav/index.css +196 -0
  158. package/dist/components/SlideRuleNav/index.css.map +1 -0
  159. package/dist/components/SlideRuleNav/index.d.ts +2 -0
  160. package/dist/components/SlideRuleNav/index.d.ts.map +1 -0
  161. package/dist/components/SlideRuleNav/index.js +8 -0
  162. package/dist/components/SlideRuleNav/index.js.map +1 -0
  163. package/dist/components/SlideRuleNav/variants/CursorRule.d.ts +11 -0
  164. package/dist/components/SlideRuleNav/variants/CursorRule.d.ts.map +1 -0
  165. package/dist/components/SlideRuleNav/variants/SlideStator.d.ts +13 -0
  166. package/dist/components/SlideRuleNav/variants/SlideStator.d.ts.map +1 -0
  167. package/dist/components/SlideRuleNav/variants/VernierCarriage.d.ts +13 -0
  168. package/dist/components/SlideRuleNav/variants/VernierCarriage.d.ts.map +1 -0
  169. package/dist/components/Switch/Switch.d.ts +15 -0
  170. package/dist/components/Switch/Switch.d.ts.map +1 -0
  171. package/dist/components/Switch/index.css +49 -0
  172. package/dist/components/Switch/index.css.map +1 -0
  173. package/dist/components/Switch/index.d.ts +2 -0
  174. package/dist/components/Switch/index.d.ts.map +1 -0
  175. package/dist/components/Switch/index.js +7 -0
  176. package/dist/components/Switch/index.js.map +1 -0
  177. package/dist/components/Tabs/Tabs.d.ts +34 -0
  178. package/dist/components/Tabs/Tabs.d.ts.map +1 -0
  179. package/dist/components/Tabs/index.css +54 -0
  180. package/dist/components/Tabs/index.css.map +1 -0
  181. package/dist/components/Tabs/index.d.ts +2 -0
  182. package/dist/components/Tabs/index.d.ts.map +1 -0
  183. package/dist/components/Tabs/index.js +7 -0
  184. package/dist/components/Tabs/index.js.map +1 -0
  185. package/dist/components/Textarea/Textarea.d.ts +16 -0
  186. package/dist/components/Textarea/Textarea.d.ts.map +1 -0
  187. package/dist/components/Textarea/index.css +36 -0
  188. package/dist/components/Textarea/index.css.map +1 -0
  189. package/dist/components/Textarea/index.d.ts +2 -0
  190. package/dist/components/Textarea/index.d.ts.map +1 -0
  191. package/dist/components/Textarea/index.js +7 -0
  192. package/dist/components/Textarea/index.js.map +1 -0
  193. package/dist/components/ThemeSwitcher/ThemeSwitcher.d.ts +4 -0
  194. package/dist/components/ThemeSwitcher/ThemeSwitcher.d.ts.map +1 -0
  195. package/dist/components/ThemeSwitcher/index.d.ts +2 -0
  196. package/dist/components/ThemeSwitcher/index.d.ts.map +1 -0
  197. package/dist/components/Typography/Heading.d.ts +9 -0
  198. package/dist/components/Typography/Heading.d.ts.map +1 -0
  199. package/dist/components/Typography/Text.d.ts +9 -0
  200. package/dist/components/Typography/Text.d.ts.map +1 -0
  201. package/dist/components/Typography/index.d.ts +3 -0
  202. package/dist/components/Typography/index.d.ts.map +1 -0
  203. package/dist/components/_shared/useDetentTravel.d.ts +87 -0
  204. package/dist/components/_shared/useDetentTravel.d.ts.map +1 -0
  205. package/dist/components/_shared/usePointerDrag.d.ts +24 -0
  206. package/dist/components/_shared/usePointerDrag.d.ts.map +1 -0
  207. package/dist/components/_shared/useReducedMotion.d.ts +7 -0
  208. package/dist/components/_shared/useReducedMotion.d.ts.map +1 -0
  209. package/dist/components/_shared/validateStationCount.d.ts +13 -0
  210. package/dist/components/_shared/validateStationCount.d.ts.map +1 -0
  211. package/dist/index.css +1175 -0
  212. package/dist/index.css.map +1 -1
  213. package/dist/index.d.ts +26 -0
  214. package/dist/index.d.ts.map +1 -0
  215. package/dist/index.js +70 -10
  216. package/dist/index.js.map +1 -1
  217. package/dist/theme/ThemeContext.d.ts +2 -0
  218. package/dist/theme/ThemeContext.d.ts.map +1 -0
  219. package/dist/theme/ThemeProvider.d.ts +12 -0
  220. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  221. package/dist/theme/themeConstants.d.ts +8 -0
  222. package/dist/theme/themeConstants.d.ts.map +1 -0
  223. package/dist/theme/useTheme.d.ts +2 -0
  224. package/dist/theme/useTheme.d.ts.map +1 -0
  225. package/package.json +21 -5
@@ -0,0 +1,58 @@
1
+ // src/components/Accordion/Accordion.jsx
2
+ import { useId, useState } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ function Accordion({
5
+ items = [],
6
+ multiple = false,
7
+ defaultOpen = [],
8
+ className = ""
9
+ }) {
10
+ const baseId = useId();
11
+ const [openIds, setOpenIds] = useState(() => new Set(defaultOpen));
12
+ function toggle(id) {
13
+ setOpenIds((prev) => {
14
+ const next = new Set(multiple ? prev : []);
15
+ if (prev.has(id)) next.delete(id);
16
+ else next.add(id);
17
+ return next;
18
+ });
19
+ }
20
+ return /* @__PURE__ */ jsx("div", { className: ["ds-accordion", className].filter(Boolean).join(" "), children: items.map((item) => {
21
+ const isOpen = openIds.has(item.id);
22
+ const headerId = `${baseId}-${item.id}-header`;
23
+ const panelId = `${baseId}-${item.id}-panel`;
24
+ return /* @__PURE__ */ jsxs("div", { className: "ds-accordion__item", children: [
25
+ /* @__PURE__ */ jsx("h3", { className: "ds-accordion__heading", children: /* @__PURE__ */ jsxs(
26
+ "button",
27
+ {
28
+ type: "button",
29
+ id: headerId,
30
+ className: "ds-accordion__trigger",
31
+ "aria-expanded": isOpen,
32
+ "aria-controls": panelId,
33
+ onClick: () => toggle(item.id),
34
+ children: [
35
+ /* @__PURE__ */ jsx("span", { children: item.title }),
36
+ /* @__PURE__ */ jsx("span", { className: "ds-accordion__icon", "aria-hidden": "true" })
37
+ ]
38
+ }
39
+ ) }),
40
+ /* @__PURE__ */ jsx(
41
+ "div",
42
+ {
43
+ id: panelId,
44
+ className: "ds-accordion__panel",
45
+ role: "region",
46
+ "aria-labelledby": headerId,
47
+ hidden: !isOpen,
48
+ children: /* @__PURE__ */ jsx("div", { className: "ds-accordion__content", children: item.content })
49
+ }
50
+ )
51
+ ] }, item.id);
52
+ }) });
53
+ }
54
+
55
+ export {
56
+ Accordion
57
+ };
58
+ //# sourceMappingURL=chunk-2KHDM6UP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Accordion/Accordion.jsx"],"sourcesContent":["import { useId, useState } from \"react\";\nimport \"./Accordion.css\";\n\n/**\n * @typedef {object} AccordionItem\n * @property {string} id\n * @property {import(\"react\").ReactNode} title\n * @property {import(\"react\").ReactNode} content\n */\n\n/**\n * Disclosure list built on native <button aria-expanded> + a region panel.\n * Single-open by default; set `multiple` to allow several panels open at once.\n *\n * @param {object} props\n * @param {AccordionItem[]} props.items\n * @param {boolean} [props.multiple] - Allow multiple panels open. Default false.\n * @param {string[]} [props.defaultOpen] - Item ids open initially.\n * @param {string} [props.className]\n * @returns {import(\"react\").ReactElement}\n */\nexport function Accordion({\n items = [],\n multiple = false,\n defaultOpen = [],\n className = \"\",\n}) {\n const baseId = useId();\n const [openIds, setOpenIds] = useState(() => new Set(defaultOpen));\n\n function toggle(id) {\n setOpenIds((prev) => {\n const next = new Set(multiple ? prev : []);\n if (prev.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }\n\n return (\n <div className={[\"ds-accordion\", className].filter(Boolean).join(\" \")}>\n {items.map((item) => {\n const isOpen = openIds.has(item.id);\n const headerId = `${baseId}-${item.id}-header`;\n const panelId = `${baseId}-${item.id}-panel`;\n return (\n <div className=\"ds-accordion__item\" key={item.id}>\n <h3 className=\"ds-accordion__heading\">\n <button\n type=\"button\"\n id={headerId}\n className=\"ds-accordion__trigger\"\n aria-expanded={isOpen}\n aria-controls={panelId}\n onClick={() => toggle(item.id)}\n >\n <span>{item.title}</span>\n <span className=\"ds-accordion__icon\" aria-hidden=\"true\" />\n </button>\n </h3>\n <div\n id={panelId}\n className=\"ds-accordion__panel\"\n role=\"region\"\n aria-labelledby={headerId}\n hidden={!isOpen}\n >\n <div className=\"ds-accordion__content\">{item.content}</div>\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":";AAAA,SAAS,OAAO,gBAAgB;AAgDlB,SAQE,KARF;AA3BP,SAAS,UAAU;AAAA,EACxB,QAAQ,CAAC;AAAA,EACT,WAAW;AAAA,EACX,cAAc,CAAC;AAAA,EACf,YAAY;AACd,GAAG;AACD,QAAM,SAAS,MAAM;AACrB,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,MAAM,IAAI,IAAI,WAAW,CAAC;AAEjE,WAAS,OAAO,IAAI;AAClB,eAAW,CAAC,SAAS;AACnB,YAAM,OAAO,IAAI,IAAI,WAAW,OAAO,CAAC,CAAC;AACzC,UAAI,KAAK,IAAI,EAAE,EAAG,MAAK,OAAO,EAAE;AAAA,UAC3B,MAAK,IAAI,EAAE;AAChB,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,SACE,oBAAC,SAAI,WAAW,CAAC,gBAAgB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACjE,gBAAM,IAAI,CAAC,SAAS;AACnB,UAAM,SAAS,QAAQ,IAAI,KAAK,EAAE;AAClC,UAAM,WAAW,GAAG,MAAM,IAAI,KAAK,EAAE;AACrC,UAAM,UAAU,GAAG,MAAM,IAAI,KAAK,EAAE;AACpC,WACE,qBAAC,SAAI,WAAU,sBACb;AAAA,0BAAC,QAAG,WAAU,yBACZ;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,IAAI;AAAA,UACJ,WAAU;AAAA,UACV,iBAAe;AAAA,UACf,iBAAe;AAAA,UACf,SAAS,MAAM,OAAO,KAAK,EAAE;AAAA,UAE7B;AAAA,gCAAC,UAAM,eAAK,OAAM;AAAA,YAClB,oBAAC,UAAK,WAAU,sBAAqB,eAAY,QAAO;AAAA;AAAA;AAAA,MAC1D,GACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,IAAI;AAAA,UACJ,WAAU;AAAA,UACV,MAAK;AAAA,UACL,mBAAiB;AAAA,UACjB,QAAQ,CAAC;AAAA,UAET,8BAAC,SAAI,WAAU,yBAAyB,eAAK,SAAQ;AAAA;AAAA,MACvD;AAAA,SAtBuC,KAAK,EAuB9C;AAAA,EAEJ,CAAC,GACH;AAEJ;","names":[]}
@@ -0,0 +1,65 @@
1
+ // src/components/Radio/Radio.jsx
2
+ import { useContext } from "react";
3
+
4
+ // src/components/Radio/RadioGroupContext.js
5
+ import { createContext } from "react";
6
+ var RadioGroupContext = createContext(null);
7
+
8
+ // src/components/Radio/Radio.jsx
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ function Radio({ label, value, className = "", ...rest }) {
11
+ const group = useContext(RadioGroupContext);
12
+ const groupProps = group ? {
13
+ name: group.name,
14
+ checked: group.value === value,
15
+ onChange: () => group.onChange?.(value)
16
+ } : {};
17
+ return /* @__PURE__ */ jsxs("label", { className: ["ds-radio", className].filter(Boolean).join(" "), children: [
18
+ /* @__PURE__ */ jsx(
19
+ "input",
20
+ {
21
+ type: "radio",
22
+ className: "ds-radio__input",
23
+ value,
24
+ ...groupProps,
25
+ ...rest
26
+ }
27
+ ),
28
+ /* @__PURE__ */ jsx("span", { className: "ds-radio__dot", "aria-hidden": "true" }),
29
+ label != null && /* @__PURE__ */ jsx("span", { className: "ds-radio__label", children: label })
30
+ ] });
31
+ }
32
+
33
+ // src/components/Radio/RadioGroup.jsx
34
+ import { useId, useMemo } from "react";
35
+ import { jsx as jsx2 } from "react/jsx-runtime";
36
+ function RadioGroup({
37
+ name,
38
+ value,
39
+ onChange,
40
+ options,
41
+ children,
42
+ className = "",
43
+ ...rest
44
+ }) {
45
+ const autoName = useId();
46
+ const ctx = useMemo(
47
+ () => ({ name: name ?? autoName, value, onChange }),
48
+ [name, autoName, value, onChange]
49
+ );
50
+ return /* @__PURE__ */ jsx2(RadioGroupContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx2(
51
+ "div",
52
+ {
53
+ role: "radiogroup",
54
+ className: ["ds-radio-group", className].filter(Boolean).join(" "),
55
+ ...rest,
56
+ children: options ? options.map((opt) => /* @__PURE__ */ jsx2(Radio, { value: opt.value, label: opt.label }, opt.value)) : children
57
+ }
58
+ ) });
59
+ }
60
+
61
+ export {
62
+ Radio,
63
+ RadioGroup
64
+ };
65
+ //# sourceMappingURL=chunk-45346SXP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Radio/Radio.jsx","../src/components/Radio/RadioGroupContext.js","../src/components/Radio/RadioGroup.jsx"],"sourcesContent":["import { useContext } from \"react\";\nimport { RadioGroupContext } from \"./RadioGroupContext.js\";\nimport \"./Radio.css\";\n\n/**\n * Radio button with a styled indicator over a native <input type=\"radio\">.\n * Inside a RadioGroup it inherits `name` and selection state automatically;\n * standalone, pass `name`/`checked`/`onChange` yourself via `...rest`.\n *\n * @param {object} props\n * @param {import(\"react\").ReactNode} [props.label] - Visible label text.\n * @param {string} [props.value] - This option's value (used by RadioGroup).\n * @param {string} [props.className]\n * @returns {import(\"react\").ReactElement}\n */\nexport function Radio({ label, value, className = \"\", ...rest }) {\n const group = useContext(RadioGroupContext);\n\n const groupProps = group\n ? {\n name: group.name,\n checked: group.value === value,\n onChange: () => group.onChange?.(value),\n }\n : {};\n\n return (\n <label className={[\"ds-radio\", className].filter(Boolean).join(\" \")}>\n <input\n type=\"radio\"\n className=\"ds-radio__input\"\n value={value}\n {...groupProps}\n {...rest}\n />\n <span className=\"ds-radio__dot\" aria-hidden=\"true\" />\n {label != null && <span className=\"ds-radio__label\">{label}</span>}\n </label>\n );\n}\n","import { createContext } from \"react\";\n\n/**\n * Lets a RadioGroup share its `name` and controlled value/onChange with any\n * Radio rendered inside it, without prop-drilling. `null` when a Radio is\n * used standalone.\n */\nexport const RadioGroupContext = createContext(null);\n","import { useId, useMemo } from \"react\";\nimport { RadioGroupContext } from \"./RadioGroupContext.js\";\nimport { Radio } from \"./Radio.jsx\";\nimport \"./Radio.css\";\n\n/**\n * Groups Radios under one `name` with a single controlled selection. Provide\n * either an `options` array or Radio children.\n *\n * @param {object} props\n * @param {string} [props.name] - Shared input name. Auto-generated if omitted.\n * @param {string} [props.value] - Currently selected value (controlled).\n * @param {(value: string) => void} [props.onChange]\n * @param {{ value: string, label: import(\"react\").ReactNode }[]} [props.options]\n * @param {import(\"react\").ReactNode} [props.children]\n * @param {string} [props.className]\n * @returns {import(\"react\").ReactElement}\n */\nexport function RadioGroup({\n name,\n value,\n onChange,\n options,\n children,\n className = \"\",\n ...rest\n}) {\n const autoName = useId();\n const ctx = useMemo(\n () => ({ name: name ?? autoName, value, onChange }),\n [name, autoName, value, onChange]\n );\n\n return (\n <RadioGroupContext.Provider value={ctx}>\n <div\n role=\"radiogroup\"\n className={[\"ds-radio-group\", className].filter(Boolean).join(\" \")}\n {...rest}\n >\n {options\n ? options.map((opt) => (\n <Radio key={opt.value} value={opt.value} label={opt.label} />\n ))\n : children}\n </div>\n </RadioGroupContext.Provider>\n );\n}\n"],"mappings":";AAAA,SAAS,kBAAkB;;;ACA3B,SAAS,qBAAqB;AAOvB,IAAM,oBAAoB,cAAc,IAAI;;;ADoB/C,SACE,KADF;AAZG,SAAS,MAAM,EAAE,OAAO,OAAO,YAAY,IAAI,GAAG,KAAK,GAAG;AAC/D,QAAM,QAAQ,WAAW,iBAAiB;AAE1C,QAAM,aAAa,QACf;AAAA,IACE,MAAM,MAAM;AAAA,IACZ,SAAS,MAAM,UAAU;AAAA,IACzB,UAAU,MAAM,MAAM,WAAW,KAAK;AAAA,EACxC,IACA,CAAC;AAEL,SACE,qBAAC,WAAM,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAChE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV;AAAA,QACC,GAAG;AAAA,QACH,GAAG;AAAA;AAAA,IACN;AAAA,IACA,oBAAC,UAAK,WAAU,iBAAgB,eAAY,QAAO;AAAA,IAClD,SAAS,QAAQ,oBAAC,UAAK,WAAU,mBAAmB,iBAAM;AAAA,KAC7D;AAEJ;;;AEvCA,SAAS,OAAO,eAAe;AA0CjB,gBAAAA,YAAA;AAxBP,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,GAAG;AACL,GAAG;AACD,QAAM,WAAW,MAAM;AACvB,QAAM,MAAM;AAAA,IACV,OAAO,EAAE,MAAM,QAAQ,UAAU,OAAO,SAAS;AAAA,IACjD,CAAC,MAAM,UAAU,OAAO,QAAQ;AAAA,EAClC;AAEA,SACE,gBAAAA,KAAC,kBAAkB,UAAlB,EAA2B,OAAO,KACjC,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAW,CAAC,kBAAkB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAChE,GAAG;AAAA,MAEH,oBACG,QAAQ,IAAI,CAAC,QACX,gBAAAA,KAAC,SAAsB,OAAO,IAAI,OAAO,OAAO,IAAI,SAAxC,IAAI,KAA2C,CAC5D,IACD;AAAA;AAAA,EACN,GACF;AAEJ;","names":["jsx"]}
@@ -0,0 +1,14 @@
1
+ // src/components/Checkbox/Checkbox.jsx
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ function Checkbox({ label, className = "", ...rest }) {
4
+ return /* @__PURE__ */ jsxs("label", { className: ["ds-checkbox", className].filter(Boolean).join(" "), children: [
5
+ /* @__PURE__ */ jsx("input", { type: "checkbox", className: "ds-checkbox__input", ...rest }),
6
+ /* @__PURE__ */ jsx("span", { className: "ds-checkbox__box", "aria-hidden": "true" }),
7
+ label != null && /* @__PURE__ */ jsx("span", { className: "ds-checkbox__label", children: label })
8
+ ] });
9
+ }
10
+
11
+ export {
12
+ Checkbox
13
+ };
14
+ //# sourceMappingURL=chunk-BAISLPWP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Checkbox/Checkbox.jsx"],"sourcesContent":["import \"./Checkbox.css\";\n\n/**\n * Checkbox with a styled indicator over a native <input type=\"checkbox\">, so\n * keyboard/focus/toggle behavior stays native. Controlled or uncontrolled via\n * `...rest` (checked/defaultChecked, onChange).\n *\n * @param {object} props\n * @param {import(\"react\").ReactNode} [props.label] - Visible label text.\n * @param {string} [props.className]\n * @returns {import(\"react\").ReactElement}\n */\nexport function Checkbox({ label, className = \"\", ...rest }) {\n return (\n <label className={[\"ds-checkbox\", className].filter(Boolean).join(\" \")}>\n <input type=\"checkbox\" className=\"ds-checkbox__input\" {...rest} />\n <span className=\"ds-checkbox__box\" aria-hidden=\"true\" />\n {label != null && <span className=\"ds-checkbox__label\">{label}</span>}\n </label>\n );\n}\n"],"mappings":";AAcI,SACE,KADF;AAFG,SAAS,SAAS,EAAE,OAAO,YAAY,IAAI,GAAG,KAAK,GAAG;AAC3D,SACE,qBAAC,WAAM,WAAW,CAAC,eAAe,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACnE;AAAA,wBAAC,WAAM,MAAK,YAAW,WAAU,sBAAsB,GAAG,MAAM;AAAA,IAChE,oBAAC,UAAK,WAAU,oBAAmB,eAAY,QAAO;AAAA,IACrD,SAAS,QAAQ,oBAAC,UAAK,WAAU,sBAAsB,iBAAM;AAAA,KAChE;AAEJ;","names":[]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-CT2TMR44.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,22 @@
1
+ // src/components/Switch/Switch.jsx
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ function Switch({ label, className = "", ...rest }) {
4
+ return /* @__PURE__ */ jsxs("label", { className: ["ds-switch", className].filter(Boolean).join(" "), children: [
5
+ /* @__PURE__ */ jsx(
6
+ "input",
7
+ {
8
+ type: "checkbox",
9
+ role: "switch",
10
+ className: "ds-switch__input",
11
+ ...rest
12
+ }
13
+ ),
14
+ /* @__PURE__ */ jsx("span", { className: "ds-switch__track", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", { className: "ds-switch__thumb" }) }),
15
+ label != null && /* @__PURE__ */ jsx("span", { className: "ds-switch__label", children: label })
16
+ ] });
17
+ }
18
+
19
+ export {
20
+ Switch
21
+ };
22
+ //# sourceMappingURL=chunk-DD5VKG3L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Switch/Switch.jsx"],"sourcesContent":["import \"./Switch.css\";\n\n/**\n * Toggle switch built on a native <input type=\"checkbox\"> — same semantics as\n * a checkbox, styled as a sliding track. Controlled or uncontrolled via\n * `...rest` (checked/defaultChecked, onChange).\n *\n * @param {object} props\n * @param {import(\"react\").ReactNode} [props.label] - Visible label text.\n * @param {string} [props.className]\n * @returns {import(\"react\").ReactElement}\n */\nexport function Switch({ label, className = \"\", ...rest }) {\n return (\n <label className={[\"ds-switch\", className].filter(Boolean).join(\" \")}>\n <input\n type=\"checkbox\"\n role=\"switch\"\n className=\"ds-switch__input\"\n {...rest}\n />\n <span className=\"ds-switch__track\" aria-hidden=\"true\">\n <span className=\"ds-switch__thumb\" />\n </span>\n {label != null && <span className=\"ds-switch__label\">{label}</span>}\n </label>\n );\n}\n"],"mappings":";AAcI,SACE,KADF;AAFG,SAAS,OAAO,EAAE,OAAO,YAAY,IAAI,GAAG,KAAK,GAAG;AACzD,SACE,qBAAC,WAAM,WAAW,CAAC,aAAa,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACjE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,MAAK;AAAA,QACL,WAAU;AAAA,QACT,GAAG;AAAA;AAAA,IACN;AAAA,IACA,oBAAC,UAAK,WAAU,oBAAmB,eAAY,QAC7C,8BAAC,UAAK,WAAU,oBAAmB,GACrC;AAAA,IACC,SAAS,QAAQ,oBAAC,UAAK,WAAU,oBAAoB,iBAAM;AAAA,KAC9D;AAEJ;","names":[]}
@@ -0,0 +1,110 @@
1
+ // src/components/Modal/Modal.jsx
2
+ import { useCallback, useEffect, useRef } from "react";
3
+ import { createPortal } from "react-dom";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ var FOCUSABLE = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
6
+ function Modal({
7
+ open,
8
+ onClose,
9
+ title,
10
+ size = "md",
11
+ children,
12
+ className = ""
13
+ }) {
14
+ const panelRef = useRef(null);
15
+ const titleId = useRef(
16
+ `ds-modal-${Math.random().toString(36).slice(2, 9)}`
17
+ ).current;
18
+ const handleKeyDown = useCallback(
19
+ (event) => {
20
+ if (event.key === "Escape") {
21
+ event.stopPropagation();
22
+ onClose?.();
23
+ return;
24
+ }
25
+ if (event.key !== "Tab") return;
26
+ const nodes = panelRef.current?.querySelectorAll(FOCUSABLE);
27
+ if (!nodes || nodes.length === 0) {
28
+ event.preventDefault();
29
+ return;
30
+ }
31
+ const first = nodes[0];
32
+ const last = nodes[nodes.length - 1];
33
+ const active = document.activeElement;
34
+ if (event.shiftKey && active === first) {
35
+ event.preventDefault();
36
+ last.focus();
37
+ } else if (!event.shiftKey && active === last) {
38
+ event.preventDefault();
39
+ first.focus();
40
+ }
41
+ },
42
+ [onClose]
43
+ );
44
+ useEffect(() => {
45
+ if (!open) return void 0;
46
+ const previouslyFocused = document.activeElement;
47
+ const { overflow } = document.body.style;
48
+ document.body.style.overflow = "hidden";
49
+ const nodes = panelRef.current?.querySelectorAll(FOCUSABLE);
50
+ if (nodes && nodes.length > 0) nodes[0].focus();
51
+ else panelRef.current?.focus();
52
+ return () => {
53
+ document.body.style.overflow = overflow;
54
+ if (previouslyFocused instanceof HTMLElement) previouslyFocused.focus();
55
+ };
56
+ }, [open]);
57
+ if (!open) return null;
58
+ return createPortal(
59
+ /* @__PURE__ */ jsxs(
60
+ "div",
61
+ {
62
+ className: ["ds-modal", className].filter(Boolean).join(" "),
63
+ onKeyDown: handleKeyDown,
64
+ children: [
65
+ /* @__PURE__ */ jsx(
66
+ "div",
67
+ {
68
+ className: "ds-modal__backdrop",
69
+ onClick: onClose,
70
+ "data-testid": "ds-modal-backdrop"
71
+ }
72
+ ),
73
+ /* @__PURE__ */ jsxs(
74
+ "div",
75
+ {
76
+ ref: panelRef,
77
+ className: `ds-modal__panel ds-modal__panel--${size}`,
78
+ role: "dialog",
79
+ "aria-modal": "true",
80
+ "aria-labelledby": title ? titleId : void 0,
81
+ tabIndex: -1,
82
+ children: [
83
+ title != null && /* @__PURE__ */ jsxs("div", { className: "ds-modal__header", children: [
84
+ /* @__PURE__ */ jsx("h2", { id: titleId, className: "ds-modal__title", children: title }),
85
+ /* @__PURE__ */ jsx(
86
+ "button",
87
+ {
88
+ type: "button",
89
+ className: "ds-modal__close",
90
+ "aria-label": "Close",
91
+ onClick: onClose,
92
+ children: "\xD7"
93
+ }
94
+ )
95
+ ] }),
96
+ /* @__PURE__ */ jsx("div", { className: "ds-modal__body", children })
97
+ ]
98
+ }
99
+ )
100
+ ]
101
+ }
102
+ ),
103
+ document.body
104
+ );
105
+ }
106
+
107
+ export {
108
+ Modal
109
+ };
110
+ //# sourceMappingURL=chunk-HLP2MPQ6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Modal/Modal.jsx"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport \"./Modal.css\";\n\nconst FOCUSABLE =\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * Accessible dialog rendered in a portal on document.body. Handles focus trap,\n * Escape-to-close, backdrop click, body scroll lock, and returns focus to the\n * element that was focused before it opened. Nothing renders when `open` is\n * false.\n *\n * @param {object} props\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {import(\"react\").ReactNode} [props.title]\n * @param {\"sm\"|\"md\"|\"lg\"} [props.size] - Panel max-width. Default \"md\".\n * @param {import(\"react\").ReactNode} [props.children]\n * @param {string} [props.className]\n * @returns {import(\"react\").ReactPortal | null}\n */\nexport function Modal({\n open,\n onClose,\n title,\n size = \"md\",\n children,\n className = \"\",\n}) {\n const panelRef = useRef(null);\n const titleId = useRef(\n `ds-modal-${Math.random().toString(36).slice(2, 9)}`\n ).current;\n\n const handleKeyDown = useCallback(\n (event) => {\n if (event.key === \"Escape\") {\n event.stopPropagation();\n onClose?.();\n return;\n }\n if (event.key !== \"Tab\") return;\n\n const nodes = panelRef.current?.querySelectorAll(FOCUSABLE);\n if (!nodes || nodes.length === 0) {\n event.preventDefault();\n return;\n }\n const first = nodes[0];\n const last = nodes[nodes.length - 1];\n const active = document.activeElement;\n\n if (event.shiftKey && active === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first.focus();\n }\n },\n [onClose]\n );\n\n useEffect(() => {\n if (!open) return undefined;\n\n const previouslyFocused = document.activeElement;\n const { overflow } = document.body.style;\n document.body.style.overflow = \"hidden\";\n\n // Focus the first focusable element (or the panel itself) on open.\n const nodes = panelRef.current?.querySelectorAll(FOCUSABLE);\n if (nodes && nodes.length > 0) nodes[0].focus();\n else panelRef.current?.focus();\n\n return () => {\n document.body.style.overflow = overflow;\n if (previouslyFocused instanceof HTMLElement) previouslyFocused.focus();\n };\n }, [open]);\n\n if (!open) return null;\n\n return createPortal(\n <div\n className={[\"ds-modal\", className].filter(Boolean).join(\" \")}\n onKeyDown={handleKeyDown}\n >\n <div\n className=\"ds-modal__backdrop\"\n onClick={onClose}\n data-testid=\"ds-modal-backdrop\"\n />\n <div\n ref={panelRef}\n className={`ds-modal__panel ds-modal__panel--${size}`}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n tabIndex={-1}\n >\n {title != null && (\n <div className=\"ds-modal__header\">\n <h2 id={titleId} className=\"ds-modal__title\">\n {title}\n </h2>\n <button\n type=\"button\"\n className=\"ds-modal__close\"\n aria-label=\"Close\"\n onClick={onClose}\n >\n ×\n </button>\n </div>\n )}\n <div className=\"ds-modal__body\">{children}</div>\n </div>\n </div>,\n document.body\n );\n}\n"],"mappings":";AAAA,SAAS,aAAa,WAAW,cAAc;AAC/C,SAAS,oBAAoB;AAwFvB,cAcI,YAdJ;AArFN,IAAM,YACJ;AAiBK,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA,YAAY;AACd,GAAG;AACD,QAAM,WAAW,OAAO,IAAI;AAC5B,QAAM,UAAU;AAAA,IACd,YAAY,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,EACpD,EAAE;AAEF,QAAM,gBAAgB;AAAA,IACpB,CAAC,UAAU;AACT,UAAI,MAAM,QAAQ,UAAU;AAC1B,cAAM,gBAAgB;AACtB,kBAAU;AACV;AAAA,MACF;AACA,UAAI,MAAM,QAAQ,MAAO;AAEzB,YAAM,QAAQ,SAAS,SAAS,iBAAiB,SAAS;AAC1D,UAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,cAAM,eAAe;AACrB;AAAA,MACF;AACA,YAAM,QAAQ,MAAM,CAAC;AACrB,YAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,YAAM,SAAS,SAAS;AAExB,UAAI,MAAM,YAAY,WAAW,OAAO;AACtC,cAAM,eAAe;AACrB,aAAK,MAAM;AAAA,MACb,WAAW,CAAC,MAAM,YAAY,WAAW,MAAM;AAC7C,cAAM,eAAe;AACrB,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,YAAU,MAAM;AACd,QAAI,CAAC,KAAM,QAAO;AAElB,UAAM,oBAAoB,SAAS;AACnC,UAAM,EAAE,SAAS,IAAI,SAAS,KAAK;AACnC,aAAS,KAAK,MAAM,WAAW;AAG/B,UAAM,QAAQ,SAAS,SAAS,iBAAiB,SAAS;AAC1D,QAAI,SAAS,MAAM,SAAS,EAAG,OAAM,CAAC,EAAE,MAAM;AAAA,QACzC,UAAS,SAAS,MAAM;AAE7B,WAAO,MAAM;AACX,eAAS,KAAK,MAAM,WAAW;AAC/B,UAAI,6BAA6B,YAAa,mBAAkB,MAAM;AAAA,IACxE;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,MAAI,CAAC,KAAM,QAAO;AAElB,SAAO;AAAA,IACL;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QAC3D,WAAW;AAAA,QAEX;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,SAAS;AAAA,cACT,eAAY;AAAA;AAAA,UACd;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,WAAW,oCAAoC,IAAI;AAAA,cACnD,MAAK;AAAA,cACL,cAAW;AAAA,cACX,mBAAiB,QAAQ,UAAU;AAAA,cACnC,UAAU;AAAA,cAET;AAAA,yBAAS,QACR,qBAAC,SAAI,WAAU,oBACb;AAAA,sCAAC,QAAG,IAAI,SAAS,WAAU,mBACxB,iBACH;AAAA,kBACA;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,WAAU;AAAA,sBACV,cAAW;AAAA,sBACX,SAAS;AAAA,sBACV;AAAA;AAAA,kBAED;AAAA,mBACF;AAAA,gBAEF,oBAAC,SAAI,WAAU,kBAAkB,UAAS;AAAA;AAAA;AAAA,UAC5C;AAAA;AAAA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,EACX;AACF;","names":[]}
@@ -0,0 +1,22 @@
1
+ // src/components/Select/Select.jsx
2
+ import { jsx } from "react/jsx-runtime";
3
+ function Select({
4
+ size = "md",
5
+ invalid = false,
6
+ className = "",
7
+ children,
8
+ ...rest
9
+ }) {
10
+ const classes = [
11
+ "ds-select",
12
+ `ds-select--${size}`,
13
+ invalid ? "ds-select--invalid" : "",
14
+ className
15
+ ].filter(Boolean).join(" ");
16
+ return /* @__PURE__ */ jsx("select", { className: classes, "aria-invalid": invalid || void 0, ...rest, children });
17
+ }
18
+
19
+ export {
20
+ Select
21
+ };
22
+ //# sourceMappingURL=chunk-HPOL5NKF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Select/Select.jsx"],"sourcesContent":["import \"./Select.css\";\n\n/**\n * Native <select> styled to match Input. Keeping it native avoids a\n * dependency and stays accessible for free. Pass <option> children.\n *\n * @param {object} props\n * @param {\"sm\"|\"md\"|\"lg\"} [props.size] - Control height/padding. Default \"md\".\n * @param {boolean} [props.invalid] - Applies error styling + aria-invalid.\n * @param {import(\"react\").ReactNode} [props.children]\n * @param {string} [props.className]\n * @returns {import(\"react\").ReactElement}\n */\nexport function Select({\n size = \"md\",\n invalid = false,\n className = \"\",\n children,\n ...rest\n}) {\n const classes = [\n \"ds-select\",\n `ds-select--${size}`,\n invalid ? \"ds-select--invalid\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <select className={classes} aria-invalid={invalid || undefined} {...rest}>\n {children}\n </select>\n );\n}\n"],"mappings":";AA8BI;AAjBG,SAAS,OAAO;AAAA,EACrB,OAAO;AAAA,EACP,UAAU;AAAA,EACV,YAAY;AAAA,EACZ;AAAA,EACA,GAAG;AACL,GAAG;AACD,QAAM,UAAU;AAAA,IACd;AAAA,IACA,cAAc,IAAI;AAAA,IAClB,UAAU,uBAAuB;AAAA,IACjC;AAAA,EACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,SACE,oBAAC,YAAO,WAAW,SAAS,gBAAc,WAAW,QAAY,GAAG,MACjE,UACH;AAEJ;","names":[]}
@@ -0,0 +1,23 @@
1
+ // src/components/Textarea/Textarea.jsx
2
+ import { jsx } from "react/jsx-runtime";
3
+ function Textarea({ invalid = false, rows = 4, className = "", ...rest }) {
4
+ const classes = [
5
+ "ds-textarea",
6
+ invalid ? "ds-textarea--invalid" : "",
7
+ className
8
+ ].filter(Boolean).join(" ");
9
+ return /* @__PURE__ */ jsx(
10
+ "textarea",
11
+ {
12
+ className: classes,
13
+ rows,
14
+ "aria-invalid": invalid || void 0,
15
+ ...rest
16
+ }
17
+ );
18
+ }
19
+
20
+ export {
21
+ Textarea
22
+ };
23
+ //# sourceMappingURL=chunk-I3NS5MAC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Textarea/Textarea.jsx"],"sourcesContent":["import \"./Textarea.css\";\n\n/**\n * Multi-line text input. Shares Input's field styling. All native <textarea>\n * props pass through via `...rest`.\n *\n * @param {object} props\n * @param {boolean} [props.invalid] - Applies error styling + aria-invalid.\n * @param {number} [props.rows] - Default 4.\n * @param {string} [props.className]\n * @returns {import(\"react\").ReactElement}\n */\nexport function Textarea({ invalid = false, rows = 4, className = \"\", ...rest }) {\n const classes = [\n \"ds-textarea\",\n invalid ? \"ds-textarea--invalid\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <textarea\n className={classes}\n rows={rows}\n aria-invalid={invalid || undefined}\n {...rest}\n />\n );\n}\n"],"mappings":";AAsBI;AAVG,SAAS,SAAS,EAAE,UAAU,OAAO,OAAO,GAAG,YAAY,IAAI,GAAG,KAAK,GAAG;AAC/E,QAAM,UAAU;AAAA,IACd;AAAA,IACA,UAAU,yBAAyB;AAAA,IACnC;AAAA,EACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,MACX;AAAA,MACA,gBAAc,WAAW;AAAA,MACxB,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
@@ -0,0 +1,48 @@
1
+ import {
2
+ Label
3
+ } from "./chunk-VRGTUKSJ.js";
4
+
5
+ // src/components/FormField/FormField.jsx
6
+ import { cloneElement, isValidElement, useId } from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ function FormField({
9
+ label,
10
+ help,
11
+ error,
12
+ required = false,
13
+ htmlFor,
14
+ children,
15
+ className = "",
16
+ ...rest
17
+ }) {
18
+ const autoId = useId();
19
+ const id = htmlFor ?? autoId;
20
+ const helpId = help ? `${id}-help` : void 0;
21
+ const errorId = error ? `${id}-error` : void 0;
22
+ const describedBy = [helpId, errorId].filter(Boolean).join(" ") || void 0;
23
+ const control = isValidElement(children) ? cloneElement(children, {
24
+ id,
25
+ // Preserve any describedby the control already declared.
26
+ "aria-describedby": [children.props["aria-describedby"], describedBy].filter(Boolean).join(" ") || void 0,
27
+ invalid: error ? true : children.props.invalid,
28
+ required: required || children.props.required
29
+ }) : children;
30
+ return /* @__PURE__ */ jsxs(
31
+ "div",
32
+ {
33
+ className: ["ds-form-field", className].filter(Boolean).join(" "),
34
+ ...rest,
35
+ children: [
36
+ label != null && /* @__PURE__ */ jsx(Label, { htmlFor: id, required, children: label }),
37
+ control,
38
+ help != null && /* @__PURE__ */ jsx("span", { id: helpId, className: "ds-form-field__help", children: help }),
39
+ error != null && /* @__PURE__ */ jsx("span", { id: errorId, className: "ds-form-field__error", role: "alert", children: error })
40
+ ]
41
+ }
42
+ );
43
+ }
44
+
45
+ export {
46
+ FormField
47
+ };
48
+ //# sourceMappingURL=chunk-LPEUQ2DE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/FormField/FormField.jsx"],"sourcesContent":["import { cloneElement, isValidElement, useId } from \"react\";\nimport { Label } from \"../Label/Label.jsx\";\nimport \"./FormField.css\";\n\n/**\n * Wraps a single form control with a label plus optional help/error text, and\n * wires up accessibility: it generates an id, links the label via `htmlFor`,\n * connects help/error text through `aria-describedby`, and sets `aria-invalid`\n * + the control's `invalid` styling when `error` is present. The control is\n * passed as the only child (Input, Textarea, Select, etc.).\n *\n * @param {object} props\n * @param {import(\"react\").ReactNode} [props.label]\n * @param {import(\"react\").ReactNode} [props.help] - Hint text below the control.\n * @param {import(\"react\").ReactNode} [props.error] - Error text; also marks the control invalid.\n * @param {boolean} [props.required]\n * @param {string} [props.htmlFor] - Override the auto-generated control id.\n * @param {import(\"react\").ReactElement} props.children - The control element.\n * @param {string} [props.className]\n * @returns {import(\"react\").ReactElement}\n */\nexport function FormField({\n label,\n help,\n error,\n required = false,\n htmlFor,\n children,\n className = \"\",\n ...rest\n}) {\n const autoId = useId();\n const id = htmlFor ?? autoId;\n const helpId = help ? `${id}-help` : undefined;\n const errorId = error ? `${id}-error` : undefined;\n const describedBy = [helpId, errorId].filter(Boolean).join(\" \") || undefined;\n\n const control = isValidElement(children)\n ? cloneElement(children, {\n id,\n // Preserve any describedby the control already declared.\n \"aria-describedby\":\n [children.props[\"aria-describedby\"], describedBy]\n .filter(Boolean)\n .join(\" \") || undefined,\n invalid: error ? true : children.props.invalid,\n required: required || children.props.required,\n })\n : children;\n\n return (\n <div\n className={[\"ds-form-field\", className].filter(Boolean).join(\" \")}\n {...rest}\n >\n {label != null && (\n <Label htmlFor={id} required={required}>\n {label}\n </Label>\n )}\n {control}\n {help != null && (\n <span id={helpId} className=\"ds-form-field__help\">\n {help}\n </span>\n )}\n {error != null && (\n <span id={errorId} className=\"ds-form-field__error\" role=\"alert\">\n {error}\n </span>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;AAAA,SAAS,cAAc,gBAAgB,aAAa;AAmDhD,SAKI,KALJ;AA9BG,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,GAAG;AACL,GAAG;AACD,QAAM,SAAS,MAAM;AACrB,QAAM,KAAK,WAAW;AACtB,QAAM,SAAS,OAAO,GAAG,EAAE,UAAU;AACrC,QAAM,UAAU,QAAQ,GAAG,EAAE,WAAW;AACxC,QAAM,cAAc,CAAC,QAAQ,OAAO,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK;AAEnE,QAAM,UAAU,eAAe,QAAQ,IACnC,aAAa,UAAU;AAAA,IACrB;AAAA;AAAA,IAEA,oBACE,CAAC,SAAS,MAAM,kBAAkB,GAAG,WAAW,EAC7C,OAAO,OAAO,EACd,KAAK,GAAG,KAAK;AAAA,IAClB,SAAS,QAAQ,OAAO,SAAS,MAAM;AAAA,IACvC,UAAU,YAAY,SAAS,MAAM;AAAA,EACvC,CAAC,IACD;AAEJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,CAAC,iBAAiB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAC/D,GAAG;AAAA,MAEH;AAAA,iBAAS,QACR,oBAAC,SAAM,SAAS,IAAI,UACjB,iBACH;AAAA,QAED;AAAA,QACA,QAAQ,QACP,oBAAC,UAAK,IAAI,QAAQ,WAAU,uBACzB,gBACH;AAAA,QAED,SAAS,QACR,oBAAC,UAAK,IAAI,SAAS,WAAU,wBAAuB,MAAK,SACtD,iBACH;AAAA;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
@@ -0,0 +1,129 @@
1
+ // src/components/Menu/Menu.jsx
2
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ function Menu({ trigger, items = [], align = "start", className = "" }) {
5
+ const [open, setOpen] = useState(false);
6
+ const [activeIndex, setActiveIndex] = useState(-1);
7
+ const rootRef = useRef(null);
8
+ const itemRefs = useRef([]);
9
+ const close = useCallback(() => {
10
+ setOpen(false);
11
+ setActiveIndex(-1);
12
+ }, []);
13
+ useEffect(() => {
14
+ if (!open) return void 0;
15
+ function onPointerDown(event) {
16
+ if (!rootRef.current?.contains(event.target)) close();
17
+ }
18
+ document.addEventListener("pointerdown", onPointerDown);
19
+ return () => document.removeEventListener("pointerdown", onPointerDown);
20
+ }, [open, close]);
21
+ useLayoutEffect(() => {
22
+ if (open && activeIndex >= 0) itemRefs.current[activeIndex]?.focus();
23
+ }, [open, activeIndex]);
24
+ const firstEnabled = () => items.findIndex((it) => !it.disabled);
25
+ const lastEnabled = () => {
26
+ for (let i = items.length - 1; i >= 0; i -= 1)
27
+ if (!items[i].disabled) return i;
28
+ return -1;
29
+ };
30
+ const nextEnabled = (from, dir) => {
31
+ let i = from;
32
+ for (let step = 0; step < items.length; step += 1) {
33
+ i = (i + dir + items.length) % items.length;
34
+ if (!items[i].disabled) return i;
35
+ }
36
+ return from;
37
+ };
38
+ function onTriggerKeyDown(event) {
39
+ if (event.key === "ArrowDown" || event.key === "Enter" || event.key === " ") {
40
+ event.preventDefault();
41
+ setOpen(true);
42
+ setActiveIndex(firstEnabled());
43
+ } else if (event.key === "ArrowUp") {
44
+ event.preventDefault();
45
+ setOpen(true);
46
+ setActiveIndex(lastEnabled());
47
+ }
48
+ }
49
+ function onMenuKeyDown(event) {
50
+ switch (event.key) {
51
+ case "ArrowDown":
52
+ event.preventDefault();
53
+ setActiveIndex((i) => nextEnabled(i < 0 ? -1 : i, 1));
54
+ break;
55
+ case "ArrowUp":
56
+ event.preventDefault();
57
+ setActiveIndex((i) => nextEnabled(i < 0 ? 0 : i, -1));
58
+ break;
59
+ case "Home":
60
+ event.preventDefault();
61
+ setActiveIndex(firstEnabled());
62
+ break;
63
+ case "End":
64
+ event.preventDefault();
65
+ setActiveIndex(lastEnabled());
66
+ break;
67
+ case "Escape":
68
+ event.preventDefault();
69
+ close();
70
+ rootRef.current?.querySelector(".ds-menu__trigger")?.focus();
71
+ break;
72
+ default:
73
+ break;
74
+ }
75
+ }
76
+ function select(item) {
77
+ if (item.disabled) return;
78
+ item.onSelect?.();
79
+ close();
80
+ rootRef.current?.querySelector(".ds-menu__trigger")?.focus();
81
+ }
82
+ return /* @__PURE__ */ jsxs(
83
+ "div",
84
+ {
85
+ ref: rootRef,
86
+ className: ["ds-menu", className].filter(Boolean).join(" "),
87
+ children: [
88
+ /* @__PURE__ */ jsx(
89
+ "button",
90
+ {
91
+ type: "button",
92
+ className: "ds-menu__trigger",
93
+ "aria-haspopup": "menu",
94
+ "aria-expanded": open,
95
+ onClick: () => open ? close() : setOpen(true),
96
+ onKeyDown: onTriggerKeyDown,
97
+ children: trigger
98
+ }
99
+ ),
100
+ open && /* @__PURE__ */ jsx(
101
+ "ul",
102
+ {
103
+ className: `ds-menu__list ds-menu__list--${align}`,
104
+ role: "menu",
105
+ onKeyDown: onMenuKeyDown,
106
+ children: items.map((item, index) => /* @__PURE__ */ jsx("li", { role: "none", children: /* @__PURE__ */ jsx(
107
+ "button",
108
+ {
109
+ type: "button",
110
+ role: "menuitem",
111
+ ref: (el) => itemRefs.current[index] = el,
112
+ className: "ds-menu__item",
113
+ tabIndex: index === activeIndex ? 0 : -1,
114
+ disabled: item.disabled,
115
+ onClick: () => select(item),
116
+ children: item.label
117
+ }
118
+ ) }, index))
119
+ }
120
+ )
121
+ ]
122
+ }
123
+ );
124
+ }
125
+
126
+ export {
127
+ Menu
128
+ };
129
+ //# sourceMappingURL=chunk-LY5MPGW2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Menu/Menu.jsx"],"sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport \"./Menu.css\";\n\n/**\n * @typedef {object} MenuItem\n * @property {import(\"react\").ReactNode} label\n * @property {() => void} [onSelect]\n * @property {boolean} [disabled]\n */\n\n/**\n * Dropdown menu: a trigger button that toggles a popover list. Closes on\n * outside click and Escape; Up/Down arrows move a roving focus between items,\n * Enter/Space activates. Uses role=\"menu\"/\"menuitem\".\n *\n * @param {object} props\n * @param {import(\"react\").ReactNode} props.trigger - Trigger button content.\n * @param {MenuItem[]} props.items\n * @param {\"start\"|\"end\"} [props.align] - Which edge the menu aligns to. Default \"start\".\n * @param {string} [props.className]\n * @returns {import(\"react\").ReactElement}\n */\nexport function Menu({ trigger, items = [], align = \"start\", className = \"\" }) {\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n const rootRef = useRef(null);\n const itemRefs = useRef([]);\n\n const close = useCallback(() => {\n setOpen(false);\n setActiveIndex(-1);\n }, []);\n\n useEffect(() => {\n if (!open) return undefined;\n function onPointerDown(event) {\n if (!rootRef.current?.contains(event.target)) close();\n }\n document.addEventListener(\"pointerdown\", onPointerDown);\n return () => document.removeEventListener(\"pointerdown\", onPointerDown);\n }, [open, close]);\n\n // Keep DOM focus on the active item so screen readers track it.\n useLayoutEffect(() => {\n if (open && activeIndex >= 0) itemRefs.current[activeIndex]?.focus();\n }, [open, activeIndex]);\n\n const firstEnabled = () => items.findIndex((it) => !it.disabled);\n const lastEnabled = () => {\n for (let i = items.length - 1; i >= 0; i -= 1)\n if (!items[i].disabled) return i;\n return -1;\n };\n const nextEnabled = (from, dir) => {\n let i = from;\n for (let step = 0; step < items.length; step += 1) {\n i = (i + dir + items.length) % items.length;\n if (!items[i].disabled) return i;\n }\n return from;\n };\n\n function onTriggerKeyDown(event) {\n if (event.key === \"ArrowDown\" || event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setOpen(true);\n setActiveIndex(firstEnabled());\n } else if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setOpen(true);\n setActiveIndex(lastEnabled());\n }\n }\n\n function onMenuKeyDown(event) {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n setActiveIndex((i) => nextEnabled(i < 0 ? -1 : i, 1));\n break;\n case \"ArrowUp\":\n event.preventDefault();\n setActiveIndex((i) => nextEnabled(i < 0 ? 0 : i, -1));\n break;\n case \"Home\":\n event.preventDefault();\n setActiveIndex(firstEnabled());\n break;\n case \"End\":\n event.preventDefault();\n setActiveIndex(lastEnabled());\n break;\n case \"Escape\":\n event.preventDefault();\n close();\n rootRef.current?.querySelector(\".ds-menu__trigger\")?.focus();\n break;\n default:\n break;\n }\n }\n\n function select(item) {\n if (item.disabled) return;\n item.onSelect?.();\n close();\n rootRef.current?.querySelector(\".ds-menu__trigger\")?.focus();\n }\n\n return (\n <div\n ref={rootRef}\n className={[\"ds-menu\", className].filter(Boolean).join(\" \")}\n >\n <button\n type=\"button\"\n className=\"ds-menu__trigger\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={() => (open ? close() : setOpen(true))}\n onKeyDown={onTriggerKeyDown}\n >\n {trigger}\n </button>\n {open && (\n <ul\n className={`ds-menu__list ds-menu__list--${align}`}\n role=\"menu\"\n onKeyDown={onMenuKeyDown}\n >\n {items.map((item, index) => (\n <li key={index} role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n ref={(el) => (itemRefs.current[index] = el)}\n className=\"ds-menu__item\"\n tabIndex={index === activeIndex ? 0 : -1}\n disabled={item.disabled}\n onClick={() => select(item)}\n >\n {item.label}\n </button>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}