@5voltfx/design-system 0.1.0 → 0.2.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.
- package/dist/chunk-2KHDM6UP.js +58 -0
- package/dist/chunk-2KHDM6UP.js.map +1 -0
- package/dist/chunk-3LTHHL5C.js +11 -0
- package/dist/chunk-3LTHHL5C.js.map +1 -0
- package/dist/chunk-45346SXP.js +65 -0
- package/dist/chunk-45346SXP.js.map +1 -0
- package/dist/chunk-5KN5TPGG.js +30 -0
- package/dist/chunk-5KN5TPGG.js.map +1 -0
- package/dist/chunk-AYAMNHNF.js +1 -0
- package/dist/chunk-AYAMNHNF.js.map +1 -0
- package/dist/chunk-BAISLPWP.js +14 -0
- package/dist/chunk-BAISLPWP.js.map +1 -0
- package/dist/chunk-BOPVPQLB.js +25 -0
- package/dist/chunk-BOPVPQLB.js.map +1 -0
- package/dist/chunk-CT2TMR44.js +1 -0
- package/dist/chunk-CT2TMR44.js.map +1 -0
- package/dist/chunk-DD5VKG3L.js +22 -0
- package/dist/chunk-DD5VKG3L.js.map +1 -0
- package/dist/chunk-EW3S3GK6.js +41 -0
- package/dist/chunk-EW3S3GK6.js.map +1 -0
- package/dist/chunk-HLP2MPQ6.js +110 -0
- package/dist/chunk-HLP2MPQ6.js.map +1 -0
- package/dist/chunk-HPOL5NKF.js +22 -0
- package/dist/chunk-HPOL5NKF.js.map +1 -0
- package/dist/chunk-I3NS5MAC.js +23 -0
- package/dist/chunk-I3NS5MAC.js.map +1 -0
- package/dist/chunk-LPEUQ2DE.js +48 -0
- package/dist/chunk-LPEUQ2DE.js.map +1 -0
- package/dist/chunk-LY5MPGW2.js +129 -0
- package/dist/chunk-LY5MPGW2.js.map +1 -0
- package/dist/chunk-NE25337V.js +1 -0
- package/dist/chunk-NE25337V.js.map +1 -0
- package/dist/chunk-R42A3ZCY.js +16 -0
- package/dist/chunk-R42A3ZCY.js.map +1 -0
- package/dist/chunk-SFECTSQP.js +68 -0
- package/dist/chunk-SFECTSQP.js.map +1 -0
- package/dist/chunk-SUYKOWXJ.js +1219 -0
- package/dist/chunk-SUYKOWXJ.js.map +1 -0
- package/dist/chunk-TNWQQ56F.js +19 -0
- package/dist/chunk-TNWQQ56F.js.map +1 -0
- package/dist/chunk-U6JTDANG.js +22 -0
- package/dist/chunk-U6JTDANG.js.map +1 -0
- package/dist/chunk-VRGTUKSJ.js +20 -0
- package/dist/chunk-VRGTUKSJ.js.map +1 -0
- package/dist/chunk-YCZXDQJZ.js +41 -0
- package/dist/chunk-YCZXDQJZ.js.map +1 -0
- package/dist/chunk-ZVUDPTFZ.js +76 -0
- package/dist/chunk-ZVUDPTFZ.js.map +1 -0
- package/dist/components/Accordion/Accordion.d.ts +29 -0
- package/dist/components/Accordion/Accordion.d.ts.map +1 -0
- package/dist/components/Accordion/index.css +58 -0
- package/dist/components/Accordion/index.css.map +1 -0
- package/dist/components/Accordion/index.d.ts +2 -0
- package/dist/components/Accordion/index.d.ts.map +1 -0
- package/dist/components/Accordion/index.js +7 -0
- package/dist/components/Accordion/index.js.map +1 -0
- package/dist/components/Button/Button.d.ts +8 -0
- package/dist/components/Button/Button.d.ts.map +1 -0
- package/{src/components/Button/Button.css → dist/components/Button/index.css} +2 -11
- package/dist/components/Button/index.css.map +1 -0
- package/{src/components/Button/index.js → dist/components/Button/index.d.ts} +1 -0
- package/dist/components/Button/index.d.ts.map +1 -0
- package/dist/components/Button/index.js +7 -0
- package/dist/components/Button/index.js.map +1 -0
- package/dist/components/Card/Card.d.ts +6 -0
- package/dist/components/Card/Card.d.ts.map +1 -0
- package/{src/components/Card/Card.css → dist/components/Card/index.css} +3 -3
- package/dist/components/Card/index.css.map +1 -0
- package/{src/components/Card/index.js → dist/components/Card/index.d.ts} +1 -0
- package/dist/components/Card/index.d.ts.map +1 -0
- package/dist/components/Card/index.js +7 -0
- package/dist/components/Card/index.js.map +1 -0
- package/dist/components/Checkbox/Checkbox.d.ts +15 -0
- package/dist/components/Checkbox/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox/index.css +57 -0
- package/dist/components/Checkbox/index.css.map +1 -0
- package/dist/components/Checkbox/index.d.ts +2 -0
- package/dist/components/Checkbox/index.d.ts.map +1 -0
- package/dist/components/Checkbox/index.js +7 -0
- package/dist/components/Checkbox/index.js.map +1 -0
- package/dist/components/Footer/Footer.d.ts +15 -0
- package/dist/components/Footer/Footer.d.ts.map +1 -0
- package/{src/components/Footer/Footer.css → dist/components/Footer/index.css} +28 -7
- package/dist/components/Footer/index.css.map +1 -0
- package/{src/components/Footer/index.js → dist/components/Footer/index.d.ts} +1 -0
- package/dist/components/Footer/index.d.ts.map +1 -0
- package/dist/components/Footer/index.js +8 -0
- package/dist/components/Footer/index.js.map +1 -0
- package/dist/components/FormField/FormField.d.ts +27 -0
- package/dist/components/FormField/FormField.d.ts.map +1 -0
- package/dist/components/FormField/index.css +31 -0
- package/dist/components/FormField/index.css.map +1 -0
- package/dist/components/FormField/index.d.ts +2 -0
- package/dist/components/FormField/index.d.ts.map +1 -0
- package/dist/components/FormField/index.js +8 -0
- package/dist/components/FormField/index.js.map +1 -0
- package/dist/components/Header/Header.d.ts +15 -0
- package/dist/components/Header/Header.d.ts.map +1 -0
- package/dist/components/Header/index.css +98 -0
- package/dist/components/Header/index.css.map +1 -0
- package/{src/components/Header/index.js → dist/components/Header/index.d.ts} +1 -0
- package/dist/components/Header/index.d.ts.map +1 -0
- package/dist/components/Header/index.js +8 -0
- package/dist/components/Header/index.js.map +1 -0
- package/dist/components/Input/Input.d.ts +16 -0
- package/dist/components/Input/Input.d.ts.map +1 -0
- package/dist/components/Input/index.css +45 -0
- package/dist/components/Input/index.css.map +1 -0
- package/dist/components/Input/index.d.ts +2 -0
- package/dist/components/Input/index.d.ts.map +1 -0
- package/dist/components/Input/index.js +7 -0
- package/dist/components/Input/index.js.map +1 -0
- package/dist/components/Label/Label.d.ts +15 -0
- package/dist/components/Label/Label.d.ts.map +1 -0
- package/dist/components/Label/index.css +14 -0
- package/dist/components/Label/index.css.map +1 -0
- package/dist/components/Label/index.d.ts +2 -0
- package/dist/components/Label/index.d.ts.map +1 -0
- package/dist/components/Label/index.js +8 -0
- package/dist/components/Label/index.js.map +1 -0
- package/dist/components/Layout/Container.d.ts +6 -0
- package/dist/components/Layout/Container.d.ts.map +1 -0
- package/dist/components/Layout/Grid.d.ts +9 -0
- package/dist/components/Layout/Grid.d.ts.map +1 -0
- package/dist/components/Layout/Stack.d.ts +10 -0
- package/dist/components/Layout/Stack.d.ts.map +1 -0
- package/{src/components/Layout/Layout.css → dist/components/Layout/index.css} +2 -4
- package/dist/components/Layout/index.css.map +1 -0
- package/{src/components/Layout/index.js → dist/components/Layout/index.d.ts} +1 -0
- package/dist/components/Layout/index.d.ts.map +1 -0
- package/dist/components/Layout/index.js +11 -0
- package/dist/components/Layout/index.js.map +1 -0
- package/dist/components/Menu/Menu.d.ts +30 -0
- package/dist/components/Menu/Menu.d.ts.map +1 -0
- package/dist/components/Menu/index.css +77 -0
- package/dist/components/Menu/index.css.map +1 -0
- package/dist/components/Menu/index.d.ts +2 -0
- package/dist/components/Menu/index.d.ts.map +1 -0
- package/dist/components/Menu/index.js +7 -0
- package/dist/components/Menu/index.js.map +1 -0
- package/dist/components/Modal/Modal.d.ts +24 -0
- package/dist/components/Modal/Modal.d.ts.map +1 -0
- package/dist/components/Modal/index.css +101 -0
- package/dist/components/Modal/index.css.map +1 -0
- package/dist/components/Modal/index.d.ts +2 -0
- package/dist/components/Modal/index.d.ts.map +1 -0
- package/dist/components/Modal/index.js +7 -0
- package/dist/components/Modal/index.js.map +1 -0
- package/dist/components/Nav/Nav.d.ts +10 -0
- package/dist/components/Nav/Nav.d.ts.map +1 -0
- package/{src/components/Nav/Nav.css → dist/components/Nav/index.css} +2 -8
- package/dist/components/Nav/index.css.map +1 -0
- package/dist/components/Nav/index.d.ts +2 -0
- package/dist/components/Nav/index.d.ts.map +1 -0
- package/dist/components/Nav/index.js +8 -0
- package/dist/components/Nav/index.js.map +1 -0
- package/dist/components/Radio/Radio.d.ts +17 -0
- package/dist/components/Radio/Radio.d.ts.map +1 -0
- package/dist/components/Radio/RadioGroup.d.ts +25 -0
- package/dist/components/Radio/RadioGroup.d.ts.map +1 -0
- package/dist/components/Radio/RadioGroupContext.d.ts +7 -0
- package/dist/components/Radio/RadioGroupContext.d.ts.map +1 -0
- package/dist/components/Radio/index.css +57 -0
- package/dist/components/Radio/index.css.map +1 -0
- package/dist/components/Radio/index.d.ts +3 -0
- package/dist/components/Radio/index.d.ts.map +1 -0
- package/dist/components/Radio/index.js +9 -0
- package/dist/components/Radio/index.js.map +1 -0
- package/dist/components/Select/Select.d.ts +18 -0
- package/dist/components/Select/Select.d.ts.map +1 -0
- package/dist/components/Select/index.css +52 -0
- package/dist/components/Select/index.css.map +1 -0
- package/dist/components/Select/index.d.ts +2 -0
- package/dist/components/Select/index.d.ts.map +1 -0
- package/dist/components/Select/index.js +7 -0
- package/dist/components/Select/index.js.map +1 -0
- package/dist/components/SlideRuleNav/SlideRuleNav.d.ts +54 -0
- package/dist/components/SlideRuleNav/SlideRuleNav.d.ts.map +1 -0
- package/dist/components/SlideRuleNav/geometry.d.ts +168 -0
- package/dist/components/SlideRuleNav/geometry.d.ts.map +1 -0
- package/dist/components/SlideRuleNav/index.css +196 -0
- package/dist/components/SlideRuleNav/index.css.map +1 -0
- package/dist/components/SlideRuleNav/index.d.ts +2 -0
- package/dist/components/SlideRuleNav/index.d.ts.map +1 -0
- package/dist/components/SlideRuleNav/index.js +7 -0
- package/dist/components/SlideRuleNav/index.js.map +1 -0
- package/dist/components/SlideRuleNav/variants/CursorRule.d.ts +11 -0
- package/dist/components/SlideRuleNav/variants/CursorRule.d.ts.map +1 -0
- package/dist/components/SlideRuleNav/variants/SlideStator.d.ts +13 -0
- package/dist/components/SlideRuleNav/variants/SlideStator.d.ts.map +1 -0
- package/dist/components/SlideRuleNav/variants/VernierCarriage.d.ts +13 -0
- package/dist/components/SlideRuleNav/variants/VernierCarriage.d.ts.map +1 -0
- package/dist/components/Switch/Switch.d.ts +15 -0
- package/dist/components/Switch/Switch.d.ts.map +1 -0
- package/dist/components/Switch/index.css +49 -0
- package/dist/components/Switch/index.css.map +1 -0
- package/dist/components/Switch/index.d.ts +2 -0
- package/dist/components/Switch/index.d.ts.map +1 -0
- package/dist/components/Switch/index.js +7 -0
- package/dist/components/Switch/index.js.map +1 -0
- package/dist/components/Tabs/Tabs.d.ts +34 -0
- package/dist/components/Tabs/Tabs.d.ts.map +1 -0
- package/dist/components/Tabs/index.css +54 -0
- package/dist/components/Tabs/index.css.map +1 -0
- package/dist/components/Tabs/index.d.ts +2 -0
- package/dist/components/Tabs/index.d.ts.map +1 -0
- package/dist/components/Tabs/index.js +7 -0
- package/dist/components/Tabs/index.js.map +1 -0
- package/dist/components/Textarea/Textarea.d.ts +16 -0
- package/dist/components/Textarea/Textarea.d.ts.map +1 -0
- package/dist/components/Textarea/index.css +36 -0
- package/dist/components/Textarea/index.css.map +1 -0
- package/dist/components/Textarea/index.d.ts +2 -0
- package/dist/components/Textarea/index.d.ts.map +1 -0
- package/dist/components/Textarea/index.js +7 -0
- package/dist/components/Textarea/index.js.map +1 -0
- package/dist/components/ThemeSwitcher/ThemeSwitcher.d.ts +4 -0
- package/dist/components/ThemeSwitcher/ThemeSwitcher.d.ts.map +1 -0
- package/{src/components/ThemeSwitcher/ThemeSwitcher.css → dist/components/ThemeSwitcher/index.css} +3 -7
- package/dist/components/ThemeSwitcher/index.css.map +1 -0
- package/{src/components/ThemeSwitcher/index.js → dist/components/ThemeSwitcher/index.d.ts} +1 -0
- package/dist/components/ThemeSwitcher/index.d.ts.map +1 -0
- package/dist/components/ThemeSwitcher/index.js +8 -0
- package/dist/components/ThemeSwitcher/index.js.map +1 -0
- package/dist/components/Typography/Heading.d.ts +9 -0
- package/dist/components/Typography/Heading.d.ts.map +1 -0
- package/dist/components/Typography/Text.d.ts +9 -0
- package/dist/components/Typography/Text.d.ts.map +1 -0
- package/dist/components/Typography/index.css +50 -0
- package/dist/components/Typography/index.css.map +1 -0
- package/{src/components/Typography/index.js → dist/components/Typography/index.d.ts} +1 -0
- package/dist/components/Typography/index.d.ts.map +1 -0
- package/dist/components/Typography/index.js +9 -0
- package/dist/components/Typography/index.js.map +1 -0
- package/dist/components/_shared/useDetentTravel.d.ts +87 -0
- package/dist/components/_shared/useDetentTravel.d.ts.map +1 -0
- package/dist/components/_shared/usePointerDrag.d.ts +24 -0
- package/dist/components/_shared/usePointerDrag.d.ts.map +1 -0
- package/dist/components/_shared/useReducedMotion.d.ts +7 -0
- package/dist/components/_shared/useReducedMotion.d.ts.map +1 -0
- package/dist/components/_shared/validateStationCount.d.ts +13 -0
- package/dist/components/_shared/validateStationCount.d.ts.map +1 -0
- package/dist/index.css +1398 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +171 -0
- package/dist/index.js.map +1 -0
- package/dist/theme/ThemeContext.d.ts +2 -0
- package/dist/theme/ThemeContext.d.ts.map +1 -0
- package/dist/theme/ThemeProvider.d.ts +12 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/themeConstants.d.ts +8 -0
- package/dist/theme/themeConstants.d.ts.map +1 -0
- package/dist/theme/useTheme.d.ts +2 -0
- package/dist/theme/useTheme.d.ts.map +1 -0
- package/package.json +35 -6
- package/vite-plugin.js +13 -10
- package/src/components/Button/Button.jsx +0 -20
- package/src/components/Card/Card.jsx +0 -6
- package/src/components/Footer/Footer.jsx +0 -37
- package/src/components/Header/Header.css +0 -47
- package/src/components/Header/Header.jsx +0 -30
- package/src/components/Layout/Container.jsx +0 -10
- package/src/components/Layout/Grid.jsx +0 -22
- package/src/components/Layout/Stack.jsx +0 -24
- package/src/components/Nav/Nav.jsx +0 -29
- package/src/components/Nav/index.js +0 -1
- package/src/components/ThemeSwitcher/ThemeSwitcher.jsx +0 -26
- package/src/components/Typography/Heading.jsx +0 -29
- package/src/components/Typography/Text.jsx +0 -20
- package/src/components/Typography/Typography.css +0 -35
- package/src/index.js +0 -12
- package/src/theme/ThemeContext.js +0 -3
- package/src/theme/ThemeProvider.jsx +0 -66
- package/src/theme/themeConstants.js +0 -12
- package/src/theme/useTheme.js +0 -10
- package/src/tokens/base.css +0 -21
- package/src/tokens/colors.css +0 -29
- package/src/tokens/elevation.css +0 -10
- package/src/tokens/index.css +0 -8
- package/src/tokens/motion.css +0 -6
- package/src/tokens/radius.css +0 -6
- package/src/tokens/spacing.css +0 -10
- package/src/tokens/themes.css +0 -156
- package/src/tokens/typography.css +0 -29
|
@@ -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,11 @@
|
|
|
1
|
+
// src/components/Card/Card.jsx
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
function Card({ as: Component = "div", className = "", ...rest }) {
|
|
4
|
+
const classes = ["ds-card", className].filter(Boolean).join(" ");
|
|
5
|
+
return /* @__PURE__ */ jsx(Component, { className: classes, ...rest });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
Card
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=chunk-3LTHHL5C.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Card/Card.jsx"],"sourcesContent":["import \"./Card.css\";\n\nexport function Card({ as: Component = \"div\", className = \"\", ...rest }) {\n const classes = [\"ds-card\", className].filter(Boolean).join(\" \");\n return <Component className={classes} {...rest} />;\n}\n"],"mappings":";AAIS;AAFF,SAAS,KAAK,EAAE,IAAI,YAAY,OAAO,YAAY,IAAI,GAAG,KAAK,GAAG;AACvE,QAAM,UAAU,CAAC,WAAW,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAC/D,SAAO,oBAAC,aAAU,WAAW,SAAU,GAAG,MAAM;AAClD;","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,30 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ThemeSwitcher
|
|
3
|
+
} from "./chunk-YCZXDQJZ.js";
|
|
4
|
+
|
|
5
|
+
// src/components/Footer/Footer.jsx
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
function Footer({
|
|
8
|
+
brand = "5VoltFX/Matt Welker",
|
|
9
|
+
showThemeSwitcher = true,
|
|
10
|
+
left,
|
|
11
|
+
right,
|
|
12
|
+
className = ""
|
|
13
|
+
}) {
|
|
14
|
+
const year = (/* @__PURE__ */ new Date()).getFullYear();
|
|
15
|
+
return /* @__PURE__ */ jsx("footer", { className: ["ds-footer", className].filter(Boolean).join(" "), children: /* @__PURE__ */ jsxs("div", { className: "ds-footer__inner", children: [
|
|
16
|
+
/* @__PURE__ */ jsx("div", { className: "ds-footer__left", children: left }),
|
|
17
|
+
/* @__PURE__ */ jsx("div", { className: "ds-footer__center", children: showThemeSwitcher && /* @__PURE__ */ jsx(ThemeSwitcher, {}) }),
|
|
18
|
+
/* @__PURE__ */ jsx("div", { className: "ds-footer__right", children: right ?? /* @__PURE__ */ jsxs("span", { className: "ds-footer__copyright", children: [
|
|
19
|
+
"\xA9 ",
|
|
20
|
+
year,
|
|
21
|
+
" ",
|
|
22
|
+
brand
|
|
23
|
+
] }) })
|
|
24
|
+
] }) });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
Footer
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=chunk-5KN5TPGG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Footer/Footer.jsx"],"sourcesContent":["import { ThemeSwitcher } from \"../ThemeSwitcher/ThemeSwitcher.jsx\";\nimport \"./Footer.css\";\n\n/**\n * Generalizes the 3 existing footers: 5voltfx.com's simple centered\n * copyright, song-chart's minimal bar, and mattwelker.com's 3-column\n * layout (auth links / theme swatches / copyright). `left` and `right`\n * default to nothing and a copyright string respectively, so a single\n * centered ThemeSwitcher is the only thing rendered out of the box.\n */\nexport function Footer({\n brand = \"5VoltFX/Matt Welker\",\n showThemeSwitcher = true,\n left,\n right,\n className = \"\",\n}) {\n const year = new Date().getFullYear();\n\n return (\n <footer className={[\"ds-footer\", className].filter(Boolean).join(\" \")}>\n <div className=\"ds-footer__inner\">\n <div className=\"ds-footer__left\">{left}</div>\n <div className=\"ds-footer__center\">\n {showThemeSwitcher && <ThemeSwitcher />}\n </div>\n <div className=\"ds-footer__right\">\n {right ?? (\n <span className=\"ds-footer__copyright\">\n © {year} {brand}\n </span>\n )}\n </div>\n </div>\n </footer>\n );\n}\n"],"mappings":";;;;;AAsBQ,cAMI,YANJ;AAZD,SAAS,OAAO;AAAA,EACrB,QAAQ;AAAA,EACR,oBAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAAG;AACD,QAAM,QAAO,oBAAI,KAAK,GAAE,YAAY;AAEpC,SACE,oBAAC,YAAO,WAAW,CAAC,aAAa,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAClE,+BAAC,SAAI,WAAU,oBACb;AAAA,wBAAC,SAAI,WAAU,mBAAmB,gBAAK;AAAA,IACvC,oBAAC,SAAI,WAAU,qBACZ,+BAAqB,oBAAC,iBAAc,GACvC;AAAA,IACA,oBAAC,SAAI,WAAU,oBACZ,mBACC,qBAAC,UAAK,WAAU,wBAAuB;AAAA;AAAA,MAClC;AAAA,MAAK;AAAA,MAAE;AAAA,OACZ,GAEJ;AAAA,KACF,GACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-AYAMNHNF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -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,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Nav
|
|
3
|
+
} from "./chunk-TNWQQ56F.js";
|
|
4
|
+
|
|
5
|
+
// src/components/Header/Header.jsx
|
|
6
|
+
import { Link } from "react-router-dom";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
function Header({
|
|
9
|
+
brand,
|
|
10
|
+
brandHref = "/",
|
|
11
|
+
links = [],
|
|
12
|
+
actions,
|
|
13
|
+
className = ""
|
|
14
|
+
}) {
|
|
15
|
+
return /* @__PURE__ */ jsx("header", { className: ["ds-header", className].filter(Boolean).join(" "), children: /* @__PURE__ */ jsxs("div", { className: "ds-header__inner", children: [
|
|
16
|
+
/* @__PURE__ */ jsx(Link, { to: brandHref, className: "ds-header__brand", children: brand }),
|
|
17
|
+
links.length > 0 && /* @__PURE__ */ jsx(Nav, { links, className: "ds-header__nav" }),
|
|
18
|
+
actions && /* @__PURE__ */ jsx("div", { className: "ds-header__actions", children: actions })
|
|
19
|
+
] }) });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
Header
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=chunk-BOPVPQLB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Header/Header.jsx"],"sourcesContent":["import { Link } from \"react-router-dom\";\nimport { Nav } from \"../Nav/Nav.jsx\";\nimport \"./Header.css\";\n\n/**\n * Generic header shell with brand/nav/actions slots, so each site's\n * bespoke chrome (song-chart's auth-aware menu + fullscreen toggle,\n * mattwelker.com's audio-loop toggle + Venmo link, 5voltfx.com's plain\n * logo-with-text-fallback) stays app-specific and is passed in rather\n * than encoded into this component.\n */\nexport function Header({\n brand,\n brandHref = \"/\",\n links = [],\n actions,\n className = \"\",\n}) {\n return (\n <header className={[\"ds-header\", className].filter(Boolean).join(\" \")}>\n <div className=\"ds-header__inner\">\n <Link to={brandHref} className=\"ds-header__brand\">\n {brand}\n </Link>\n {links.length > 0 && <Nav links={links} className=\"ds-header__nav\" />}\n {actions && <div className=\"ds-header__actions\">{actions}</div>}\n </div>\n </header>\n );\n}\n"],"mappings":";;;;;AAAA,SAAS,YAAY;AAoBf,SACE,KADF;AATC,SAAS,OAAO;AAAA,EACrB;AAAA,EACA,YAAY;AAAA,EACZ,QAAQ,CAAC;AAAA,EACT;AAAA,EACA,YAAY;AACd,GAAG;AACD,SACE,oBAAC,YAAO,WAAW,CAAC,aAAa,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAClE,+BAAC,SAAI,WAAU,oBACb;AAAA,wBAAC,QAAK,IAAI,WAAW,WAAU,oBAC5B,iBACH;AAAA,IACC,MAAM,SAAS,KAAK,oBAAC,OAAI,OAAc,WAAU,kBAAiB;AAAA,IAClE,WAAW,oBAAC,SAAI,WAAU,sBAAsB,mBAAQ;AAAA,KAC3D,GACF;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,41 @@
|
|
|
1
|
+
// src/components/Typography/Heading.jsx
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
var SCALE_BY_LEVEL = { 1: "700", 2: "600", 3: "500", 4: "400", 5: "300", 6: "200" };
|
|
4
|
+
function Heading({
|
|
5
|
+
level = 1,
|
|
6
|
+
size,
|
|
7
|
+
decorative = false,
|
|
8
|
+
className = "",
|
|
9
|
+
children,
|
|
10
|
+
...rest
|
|
11
|
+
}) {
|
|
12
|
+
const Component = `h${level}`;
|
|
13
|
+
const scale = size ?? SCALE_BY_LEVEL[level] ?? "300";
|
|
14
|
+
const classes = [
|
|
15
|
+
"ds-heading",
|
|
16
|
+
`ds-heading--${scale}`,
|
|
17
|
+
decorative ? "ds-heading--decorative" : "",
|
|
18
|
+
className
|
|
19
|
+
].filter(Boolean).join(" ");
|
|
20
|
+
return /* @__PURE__ */ jsx(Component, { className: classes, ...rest, children });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/components/Typography/Text.jsx
|
|
24
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
25
|
+
function Text({
|
|
26
|
+
as: Component = "p",
|
|
27
|
+
size = "200",
|
|
28
|
+
tone = "default",
|
|
29
|
+
className = "",
|
|
30
|
+
children,
|
|
31
|
+
...rest
|
|
32
|
+
}) {
|
|
33
|
+
const classes = ["ds-text", `ds-text--${size}`, `ds-text--${tone}`, className].filter(Boolean).join(" ");
|
|
34
|
+
return /* @__PURE__ */ jsx2(Component, { className: classes, ...rest, children });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
Heading,
|
|
39
|
+
Text
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=chunk-EW3S3GK6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Typography/Heading.jsx","../src/components/Typography/Text.jsx"],"sourcesContent":["import \"./Typography.css\";\n\nconst SCALE_BY_LEVEL = { 1: \"700\", 2: \"600\", 3: \"500\", 4: \"400\", 5: \"300\", 6: \"200\" };\n\nexport function Heading({\n level = 1,\n size,\n decorative = false,\n className = \"\",\n children,\n ...rest\n}) {\n const Component = `h${level}`;\n const scale = size ?? SCALE_BY_LEVEL[level] ?? \"300\";\n const classes = [\n \"ds-heading\",\n `ds-heading--${scale}`,\n decorative ? \"ds-heading--decorative\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <Component className={classes} {...rest}>\n {children}\n </Component>\n );\n}\n","import \"./Typography.css\";\n\nexport function Text({\n as: Component = \"p\",\n size = \"200\",\n tone = \"default\",\n className = \"\",\n children,\n ...rest\n}) {\n const classes = [\"ds-text\", `ds-text--${size}`, `ds-text--${tone}`, className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <Component className={classes} {...rest}>\n {children}\n </Component>\n );\n}\n"],"mappings":";AAwBI;AAtBJ,IAAM,iBAAiB,EAAE,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM;AAE7E,SAAS,QAAQ;AAAA,EACtB,QAAQ;AAAA,EACR;AAAA,EACA,aAAa;AAAA,EACb,YAAY;AAAA,EACZ;AAAA,EACA,GAAG;AACL,GAAG;AACD,QAAM,YAAY,IAAI,KAAK;AAC3B,QAAM,QAAQ,QAAQ,eAAe,KAAK,KAAK;AAC/C,QAAM,UAAU;AAAA,IACd;AAAA,IACA,eAAe,KAAK;AAAA,IACpB,aAAa,2BAA2B;AAAA,IACxC;AAAA,EACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,SACE,oBAAC,aAAU,WAAW,SAAU,GAAG,MAChC,UACH;AAEJ;;;ACbI,gBAAAA,YAAA;AAbG,SAAS,KAAK;AAAA,EACnB,IAAI,YAAY;AAAA,EAChB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AAAA,EACZ;AAAA,EACA,GAAG;AACL,GAAG;AACD,QAAM,UAAU,CAAC,WAAW,YAAY,IAAI,IAAI,YAAY,IAAI,IAAI,SAAS,EAC1E,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,SACE,gBAAAA,KAAC,aAAU,WAAW,SAAU,GAAG,MAChC,UACH;AAEJ;","names":["jsx"]}
|
|
@@ -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":[]}
|