@inzumer/ui-library 1.1.0 → 1.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.
Files changed (47) hide show
  1. package/dist/{chunk-PVDRNAYK.js → chunk-3YRDRHO3.js} +33 -22
  2. package/dist/chunk-3YRDRHO3.js.map +1 -0
  3. package/dist/chunk-53YMHM24.js +20 -0
  4. package/dist/chunk-53YMHM24.js.map +1 -0
  5. package/dist/{chunk-CJ4LRU6X.js → chunk-A26UWAU4.js} +12 -6
  6. package/dist/chunk-A26UWAU4.js.map +1 -0
  7. package/dist/chunk-CX3GARWU.js +142 -0
  8. package/dist/chunk-CX3GARWU.js.map +1 -0
  9. package/dist/chunk-DP274HDM.js +34 -0
  10. package/dist/chunk-DP274HDM.js.map +1 -0
  11. package/dist/chunk-FFKHEBQ7.js +41 -0
  12. package/dist/chunk-FFKHEBQ7.js.map +1 -0
  13. package/dist/chunk-GQMA2AQI.js +3 -0
  14. package/dist/chunk-GQMA2AQI.js.map +1 -0
  15. package/dist/{chunk-DXJQNQ5K.js → chunk-KL6I2JFC.js} +3 -3
  16. package/dist/{chunk-DXJQNQ5K.js.map → chunk-KL6I2JFC.js.map} +1 -1
  17. package/dist/chunk-QT62VC36.js +50 -0
  18. package/dist/chunk-QT62VC36.js.map +1 -0
  19. package/dist/{chunk-ZEGQFAYE.js → chunk-RRIE5LFQ.js} +12 -6
  20. package/dist/chunk-RRIE5LFQ.js.map +1 -0
  21. package/dist/chunk-WUEVXL76.js +91 -0
  22. package/dist/chunk-WUEVXL76.js.map +1 -0
  23. package/dist/components/atoms/Button/index.js +2 -1
  24. package/dist/components/atoms/Input/index.js +2 -1
  25. package/dist/components/atoms/Select/index.d.ts +29 -0
  26. package/dist/components/atoms/Select/index.js +6 -0
  27. package/dist/components/atoms/Select/index.js.map +1 -0
  28. package/dist/components/atoms/Textarea/index.d.ts +28 -0
  29. package/dist/components/atoms/Textarea/index.js +6 -0
  30. package/dist/components/atoms/Textarea/index.js.map +1 -0
  31. package/dist/components/molecules/BottomSheet/index.js +4 -2
  32. package/dist/components/molecules/Drawer/index.d.ts +44 -0
  33. package/dist/components/molecules/Drawer/index.js +11 -0
  34. package/dist/components/molecules/Drawer/index.js.map +1 -0
  35. package/dist/components/molecules/Modal/index.js +4 -2
  36. package/dist/hooks/useFocusTrap/index.d.ts +9 -0
  37. package/dist/hooks/useFocusTrap/index.js +3 -0
  38. package/dist/hooks/useFocusTrap/index.js.map +1 -0
  39. package/dist/hooks/useScrollLock/index.d.ts +4 -0
  40. package/dist/hooks/useScrollLock/index.js +3 -0
  41. package/dist/hooks/useScrollLock/index.js.map +1 -0
  42. package/dist/index.d.ts +5 -0
  43. package/dist/index.js +15 -8
  44. package/package.json +21 -1
  45. package/dist/chunk-CJ4LRU6X.js.map +0 -1
  46. package/dist/chunk-PVDRNAYK.js.map +0 -1
  47. package/dist/chunk-ZEGQFAYE.js.map +0 -1
@@ -1,21 +1,20 @@
1
+ import { inputLabelStyles, inputErrorStyles, inputHintStyles } from './chunk-FFKHEBQ7.js';
1
2
  import { RichText } from './chunk-P4CV2EPR.js';
2
3
  import { cn } from './chunk-6LLGTBM6.js';
3
4
  import { forwardRef, useId } from 'react';
4
5
  import { cva } from 'class-variance-authority';
5
6
  import { jsxs, jsx } from 'react/jsx-runtime';
6
7
 
7
- var inputStyles = cva(
8
+ var textareaStyles = cva(
8
9
  [
9
- "flex w-full rounded-md px-3 py-2",
10
- "text-sm text-[var(--input-text)]",
11
- "bg-[var(--input-bg)]",
10
+ "flex min-h-24 w-full rounded-md px-3 py-2",
11
+ "text-[var(--input-text)] bg-[var(--input-bg)]",
12
12
  "border border-[var(--input-border)]",
13
13
  "placeholder:text-[var(--input-placeholder)]",
14
14
  "transition-colors duration-150 ease-in-out",
15
15
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] focus-visible:ring-offset-0",
16
16
  "focus-visible:border-[var(--input-border-focus)]",
17
- "disabled:cursor-not-allowed disabled:opacity-50",
18
- "file:border-0 file:bg-transparent file:text-sm file:font-medium"
17
+ "disabled:cursor-not-allowed disabled:opacity-50"
19
18
  ],
20
19
  {
21
20
  variants: {
@@ -24,45 +23,57 @@ var inputStyles = cva(
24
23
  error: "border-[var(--input-border-error)] focus-visible:ring-[var(--border-error)]"
25
24
  },
26
25
  inputSize: {
27
- sm: "h-8 px-2 text-xs",
28
- md: "h-10 px-3 text-sm",
29
- lg: "h-12 px-4 text-base"
26
+ sm: "text-xs",
27
+ md: "text-sm",
28
+ lg: "text-base"
29
+ },
30
+ resize: {
31
+ vertical: "resize-y",
32
+ none: "resize-none"
30
33
  }
31
34
  },
32
35
  defaultVariants: {
33
36
  state: "default",
34
- inputSize: "md"
37
+ inputSize: "md",
38
+ resize: "vertical"
35
39
  }
36
40
  }
37
41
  );
38
- var inputLabelStyles = "text-sm font-medium text-[var(--text-primary)]";
39
- var inputErrorStyles = "text-xs text-[var(--border-error)]";
40
- var inputHintStyles = "text-xs text-[var(--text-secondary)]";
41
- var Input = forwardRef(
42
- ({ className, state, inputSize, label, hint, error, id: idProp, ...props }, ref) => {
42
+ var Textarea = forwardRef(
43
+ ({ className, state, inputSize, resize, label, hint, error, id: idProp, ...props }, ref) => {
43
44
  const generatedId = useId();
44
45
  const id = idProp ?? generatedId;
45
46
  const resolvedState = error ? "error" : state;
46
47
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
47
48
  label && /* @__PURE__ */ jsx("label", { htmlFor: id, children: /* @__PURE__ */ jsx(RichText, { as: "span", variant: "p3", className: inputLabelStyles, children: label }) }),
48
49
  /* @__PURE__ */ jsx(
49
- "input",
50
+ "textarea",
50
51
  {
51
52
  ref,
52
53
  id,
53
54
  "aria-describedby": error ? `${id}-error` : hint ? `${id}-hint` : void 0,
54
55
  "aria-invalid": error ? "true" : void 0,
55
- className: cn(inputStyles({ state: resolvedState, inputSize }), className),
56
+ className: cn(textareaStyles({ state: resolvedState, inputSize, resize }), className),
56
57
  ...props
57
58
  }
58
59
  ),
59
- error && /* @__PURE__ */ jsx(RichText, { as: "p", id: `${id}-error`, role: "alert", variant: "p4", className: inputErrorStyles, children: error }),
60
+ error && /* @__PURE__ */ jsx(
61
+ RichText,
62
+ {
63
+ as: "p",
64
+ id: `${id}-error`,
65
+ role: "alert",
66
+ variant: "p4",
67
+ className: inputErrorStyles,
68
+ children: error
69
+ }
70
+ ),
60
71
  !error && hint && /* @__PURE__ */ jsx(RichText, { as: "p", id: `${id}-hint`, variant: "p4", className: inputHintStyles, children: hint })
61
72
  ] });
62
73
  }
63
74
  );
64
- Input.displayName = "Input";
75
+ Textarea.displayName = "Textarea";
65
76
 
66
- export { Input };
67
- //# sourceMappingURL=chunk-PVDRNAYK.js.map
68
- //# sourceMappingURL=chunk-PVDRNAYK.js.map
77
+ export { Textarea };
78
+ //# sourceMappingURL=chunk-3YRDRHO3.js.map
79
+ //# sourceMappingURL=chunk-3YRDRHO3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/atoms/Textarea/Textarea.styles.ts","../src/components/atoms/Textarea/Textarea.tsx"],"names":[],"mappings":";;;;;;;AAEO,IAAM,cAAA,GAAiB,GAAA;AAAA,EAC5B;AAAA,IACE,2CAAA;AAAA,IACA,+CAAA;AAAA,IACA,qCAAA;AAAA,IACA,6CAAA;AAAA,IACA,4CAAA;AAAA,IACA,sHAAA;AAAA,IACA,kDAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,EAAA;AAAA,QACT,KAAA,EAAO;AAAA,OACT;AAAA,MACA,SAAA,EAAW;AAAA,QACT,EAAA,EAAI,SAAA;AAAA,QACJ,EAAA,EAAI,SAAA;AAAA,QACJ,EAAA,EAAI;AAAA,OACN;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,QAAA,EAAU,UAAA;AAAA,QACV,IAAA,EAAM;AAAA;AACR,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,KAAA,EAAO,SAAA;AAAA,MACP,SAAA,EAAW,IAAA;AAAA,MACX,MAAA,EAAQ;AAAA;AACV;AAEJ,CAAA;AChBO,IAAM,QAAA,GAAW,UAAA;AAAA,EACtB,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,WAAW,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,EAAA,EAAI,MAAA,EAAQ,GAAG,KAAA,IAAS,GAAA,KAAQ;AAC1F,IAAA,MAAM,cAAc,KAAA,EAAM;AAC1B,IAAA,MAAM,KAAK,MAAA,IAAU,WAAA;AACrB,IAAA,MAAM,aAAA,GAAgB,QAAQ,OAAA,GAAU,KAAA;AAExC,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EACZ,QAAA,EAAA;AAAA,MAAA,KAAA,oBACC,GAAA,CAAC,OAAA,EAAA,EAAM,OAAA,EAAS,EAAA,EACd,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,EAAA,EAAG,MAAA,EAAO,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,gBAAA,EACzC,iBACH,CAAA,EACF,CAAA;AAAA,sBAEF,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,EAAA;AAAA,UACA,kBAAA,EAAkB,QAAQ,CAAA,EAAG,EAAE,WAAW,IAAA,GAAO,CAAA,EAAG,EAAE,CAAA,KAAA,CAAA,GAAU,MAAA;AAAA,UAChE,cAAA,EAAc,QAAQ,MAAA,GAAS,MAAA;AAAA,UAC/B,SAAA,EAAW,EAAA,CAAG,cAAA,CAAe,EAAE,KAAA,EAAO,eAAe,SAAA,EAAW,MAAA,EAAQ,CAAA,EAAG,SAAS,CAAA;AAAA,UACnF,GAAG;AAAA;AAAA,OACN;AAAA,MACC,KAAA,oBACC,GAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,EAAA,EAAG,GAAA;AAAA,UACH,EAAA,EAAI,GAAG,EAAE,CAAA,MAAA,CAAA;AAAA,UACT,IAAA,EAAK,OAAA;AAAA,UACL,OAAA,EAAQ,IAAA;AAAA,UACR,SAAA,EAAW,gBAAA;AAAA,UAEV,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,MAED,CAAC,KAAA,IAAS,IAAA,oBACT,GAAA,CAAC,YAAS,EAAA,EAAG,GAAA,EAAI,EAAA,EAAI,CAAA,EAAG,EAAE,CAAA,KAAA,CAAA,EAAS,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,iBACxD,QAAA,EAAA,IAAA,EACH;AAAA,KAAA,EAEJ,CAAA;AAAA,EAEJ;AACF;AAEA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-3YRDRHO3.js","sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const textareaStyles = cva(\n [\n 'flex min-h-24 w-full rounded-md px-3 py-2',\n 'text-[var(--input-text)] bg-[var(--input-bg)]',\n 'border border-[var(--input-border)]',\n 'placeholder:text-[var(--input-placeholder)]',\n 'transition-colors duration-150 ease-in-out',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] focus-visible:ring-offset-0',\n 'focus-visible:border-[var(--input-border-focus)]',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n ],\n {\n variants: {\n state: {\n default: '',\n error: 'border-[var(--input-border-error)] focus-visible:ring-[var(--border-error)]',\n },\n inputSize: {\n sm: 'text-xs',\n md: 'text-sm',\n lg: 'text-base',\n },\n resize: {\n vertical: 'resize-y',\n none: 'resize-none',\n },\n },\n defaultVariants: {\n state: 'default',\n inputSize: 'md',\n resize: 'vertical',\n },\n },\n);\n","import { RichText } from '@components';\nimport { cn } from '@utils';\nimport type { VariantProps } from 'class-variance-authority';\nimport { forwardRef, useId, type TextareaHTMLAttributes } from 'react';\nimport {\n inputErrorStyles,\n inputHintStyles,\n inputLabelStyles,\n} from '@components/atoms/Input/Input.styles';\nimport { textareaStyles } from './Textarea.styles';\n\nexport type TextareaProps = TextareaHTMLAttributes<HTMLTextAreaElement> &\n VariantProps<typeof textareaStyles> & {\n label?: string;\n hint?: string;\n error?: string;\n };\n\n/** Multi-line text entry with the same label / hint / error contract and look as `Input`. */\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, state, inputSize, resize, label, hint, error, id: idProp, ...props }, ref) => {\n const generatedId = useId();\n const id = idProp ?? generatedId;\n const resolvedState = error ? 'error' : state;\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <label htmlFor={id}>\n <RichText as=\"span\" variant=\"p3\" className={inputLabelStyles}>\n {label}\n </RichText>\n </label>\n )}\n <textarea\n ref={ref}\n id={id}\n aria-describedby={error ? `${id}-error` : hint ? `${id}-hint` : undefined}\n aria-invalid={error ? 'true' : undefined}\n className={cn(textareaStyles({ state: resolvedState, inputSize, resize }), className)}\n {...props}\n />\n {error && (\n <RichText\n as=\"p\"\n id={`${id}-error`}\n role=\"alert\"\n variant=\"p4\"\n className={inputErrorStyles}\n >\n {error}\n </RichText>\n )}\n {!error && hint && (\n <RichText as=\"p\" id={`${id}-hint`} variant=\"p4\" className={inputHintStyles}>\n {hint}\n </RichText>\n )}\n </div>\n );\n },\n);\n\nTextarea.displayName = 'Textarea';\n"]}
@@ -0,0 +1,20 @@
1
+ import { useEffect } from 'react';
2
+
3
+ // src/hooks/useScrollLock/useScrollLock.ts
4
+ var useScrollLock = (active) => {
5
+ useEffect(() => {
6
+ if (!active) {
7
+ return;
8
+ }
9
+ const { style } = document.body;
10
+ const previous = style.overflow;
11
+ style.overflow = "hidden";
12
+ return () => {
13
+ style.overflow = previous;
14
+ };
15
+ }, [active]);
16
+ };
17
+
18
+ export { useScrollLock };
19
+ //# sourceMappingURL=chunk-53YMHM24.js.map
20
+ //# sourceMappingURL=chunk-53YMHM24.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/useScrollLock/useScrollLock.ts"],"names":[],"mappings":";;;AAGO,IAAM,aAAA,GAAgB,CAAC,MAAA,KAA0B;AACtD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA;AAAA,IACF;AACA,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,QAAA,CAAS,IAAA;AAC3B,IAAA,MAAM,WAAW,KAAA,CAAM,QAAA;AACvB,IAAA,KAAA,CAAM,QAAA,GAAW,QAAA;AACjB,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,CAAM,QAAA,GAAW,QAAA;AAAA,IACnB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AACb","file":"chunk-53YMHM24.js","sourcesContent":["import { useEffect } from 'react';\n\n/** Prevents the page behind an open overlay from scrolling; restores the previous value on release. */\nexport const useScrollLock = (active: boolean): void => {\n useEffect(() => {\n if (!active) {\n return;\n }\n const { style } = document.body;\n const previous = style.overflow;\n style.overflow = 'hidden';\n return () => {\n style.overflow = previous;\n };\n }, [active]);\n};\n"]}
@@ -1,9 +1,11 @@
1
- import { useDismissableLayer } from './chunk-JCJP427C.js';
2
1
  import { useDelayedUnmount } from './chunk-BNEEI7S5.js';
2
+ import { useDismissableLayer } from './chunk-JCJP427C.js';
3
+ import { useFocusTrap } from './chunk-QT62VC36.js';
4
+ import { useScrollLock } from './chunk-53YMHM24.js';
3
5
  import { useMergedRef } from './chunk-P4Z7HH66.js';
4
6
  import { RichText } from './chunk-P4CV2EPR.js';
5
7
  import { cn } from './chunk-6LLGTBM6.js';
6
- import { forwardRef, useRef } from 'react';
8
+ import { forwardRef, useRef, useId } from 'react';
7
9
  import { cva } from 'class-variance-authority';
8
10
  import { jsx, jsxs } from 'react/jsx-runtime';
9
11
 
@@ -48,8 +50,11 @@ var Modal = forwardRef(
48
50
  ({ open, onClose, title, footer, closeOnBackdropClick = true, className, children, ...props }, ref) => {
49
51
  const panelRef = useRef(null);
50
52
  const setPanelRef = useMergedRef(ref, panelRef);
53
+ const titleId = useId();
51
54
  const { mounted, visible } = useDelayedUnmount(open, EXIT_DURATION_MS);
52
55
  useDismissableLayer(open, onClose, panelRef, closeOnBackdropClick);
56
+ useFocusTrap(open && mounted, panelRef);
57
+ useScrollLock(open);
53
58
  if (!mounted) {
54
59
  return null;
55
60
  }
@@ -59,11 +64,12 @@ var Modal = forwardRef(
59
64
  ref: setPanelRef,
60
65
  role: "dialog",
61
66
  "aria-modal": "true",
62
- "aria-labelledby": title ? "modal-title" : void 0,
67
+ "aria-labelledby": title ? titleId : void 0,
68
+ tabIndex: -1,
63
69
  className: cn(modalPanelStyles({ visible }), className),
64
70
  ...props,
65
71
  children: [
66
- title && /* @__PURE__ */ jsx(RichText, { as: "h2", id: "modal-title", variant: "s1", className: modalTitleStyles, children: title }),
72
+ title && /* @__PURE__ */ jsx(RichText, { as: "h2", id: titleId, variant: "s1", className: modalTitleStyles, children: title }),
67
73
  children,
68
74
  footer && /* @__PURE__ */ jsx("div", { className: modalFooterStyles, children: footer })
69
75
  ]
@@ -74,5 +80,5 @@ var Modal = forwardRef(
74
80
  Modal.displayName = "Modal";
75
81
 
76
82
  export { Modal };
77
- //# sourceMappingURL=chunk-CJ4LRU6X.js.map
78
- //# sourceMappingURL=chunk-CJ4LRU6X.js.map
83
+ //# sourceMappingURL=chunk-A26UWAU4.js.map
84
+ //# sourceMappingURL=chunk-A26UWAU4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/molecules/Modal/Modal.styles.ts","../src/components/molecules/Modal/Modal.tsx"],"names":[],"mappings":";;;;;;;;;;;AAEO,IAAM,kBAAA,GAAqB,GAAA;AAAA,EAChC;AAAA,IACE,qFAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ,CAAA;AAEO,IAAM,gBAAA,GAAmB,GAAA;AAAA,EAC9B;AAAA,IACE,8GAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,uBAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ,CAAA;AAEO,IAAM,gBAAA,GAAmB,uDAAA;AAEzB,IAAM,iBAAA,GAAoB,0CAAA;ACvBjC,IAAM,gBAAA,GAAmB,GAAA;AAUlB,IAAM,KAAA,GAAQ,UAAA;AAAA,EACnB,CACE,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,MAAA,EAAQ,oBAAA,GAAuB,IAAA,EAAM,SAAA,EAAW,QAAA,EAAU,GAAG,KAAA,IACrF,GAAA,KACG;AACH,IAAA,MAAM,QAAA,GAAW,OAA8B,IAAI,CAAA;AACnD,IAAA,MAAM,WAAA,GAAc,YAAA,CAAa,GAAA,EAAK,QAAQ,CAAA;AAC9C,IAAA,MAAM,UAAU,KAAA,EAAM;AACtB,IAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAQ,GAAI,iBAAA,CAAkB,MAAM,gBAAgB,CAAA;AAErE,IAAA,mBAAA,CAAoB,IAAA,EAAM,OAAA,EAAS,QAAA,EAAU,oBAAoB,CAAA;AAEjE,IAAA,YAAA,CAAa,IAAA,IAAQ,SAAS,QAAQ,CAAA;AACtC,IAAA,aAAA,CAAc,IAAI,CAAA;AAElB,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,2BACG,KAAA,EAAA,EAAI,SAAA,EAAW,mBAAmB,EAAE,OAAA,EAAS,CAAA,EAC5C,QAAA,kBAAA,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,WAAA;AAAA,QACL,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAW,MAAA;AAAA,QACX,iBAAA,EAAiB,QAAQ,OAAA,GAAU,MAAA;AAAA,QACnC,QAAA,EAAU,EAAA;AAAA,QACV,WAAW,EAAA,CAAG,gBAAA,CAAiB,EAAE,OAAA,EAAS,GAAG,SAAS,CAAA;AAAA,QACrD,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,KAAA,oBACC,GAAA,CAAC,QAAA,EAAA,EAAS,EAAA,EAAG,IAAA,EAAK,EAAA,EAAI,SAAS,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,gBAAA,EACpD,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,UAED,QAAA;AAAA,UACA,MAAA,oBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,mBAAoB,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA;AAAA,KACxD,EACF,CAAA;AAAA,EAEJ;AACF;AAEA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-A26UWAU4.js","sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const modalOverlayStyles = cva(\n [\n 'fixed inset-0 z-50 flex items-center justify-center bg-[var(--surface-overlay)] p-4',\n 'transition-opacity duration-200 ease-out',\n ],\n {\n variants: {\n visible: {\n true: 'opacity-100',\n false: 'opacity-0',\n },\n },\n defaultVariants: {\n visible: false,\n },\n },\n);\n\nexport const modalPanelStyles = cva(\n [\n 'w-full max-w-md rounded-xl border border-[var(--border-default)] bg-[var(--surface-secondary)] p-6 shadow-lg',\n 'transition-all duration-200 ease-out',\n ],\n {\n variants: {\n visible: {\n true: 'scale-100 opacity-100',\n false: 'scale-95 opacity-0',\n },\n },\n defaultVariants: {\n visible: false,\n },\n },\n);\n\nexport const modalTitleStyles = 'mb-4 text-lg font-semibold text-[var(--text-primary)]';\n\nexport const modalFooterStyles = 'mt-6 flex items-center justify-end gap-2';\n","import { forwardRef, useId, useRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { RichText } from '@components';\nimport {\n useDelayedUnmount,\n useDismissableLayer,\n useFocusTrap,\n useMergedRef,\n useScrollLock,\n} from '@hooks';\nimport { cn } from '@utils';\nimport {\n modalFooterStyles,\n modalOverlayStyles,\n modalPanelStyles,\n modalTitleStyles,\n} from './Modal.styles';\n\nconst EXIT_DURATION_MS = 200;\n\nexport type ModalProps = Omit<HTMLAttributes<HTMLDivElement>, 'title'> & {\n open: boolean;\n onClose: () => void;\n title?: ReactNode;\n footer?: ReactNode;\n closeOnBackdropClick?: boolean;\n};\n\nexport const Modal = forwardRef<HTMLDivElement, ModalProps>(\n (\n { open, onClose, title, footer, closeOnBackdropClick = true, className, children, ...props },\n ref,\n ) => {\n const panelRef = useRef<HTMLDivElement | null>(null);\n const setPanelRef = useMergedRef(ref, panelRef);\n const titleId = useId();\n const { mounted, visible } = useDelayedUnmount(open, EXIT_DURATION_MS);\n\n useDismissableLayer(open, onClose, panelRef, closeOnBackdropClick);\n // The panel mounts one render after `open` flips, so the trap starts once it exists.\n useFocusTrap(open && mounted, panelRef);\n useScrollLock(open);\n\n if (!mounted) {\n return null;\n }\n\n return (\n <div className={modalOverlayStyles({ visible })}>\n <div\n ref={setPanelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n tabIndex={-1}\n className={cn(modalPanelStyles({ visible }), className)}\n {...props}\n >\n {title && (\n <RichText as=\"h2\" id={titleId} variant=\"s1\" className={modalTitleStyles}>\n {title}\n </RichText>\n )}\n {children}\n {footer && <div className={modalFooterStyles}>{footer}</div>}\n </div>\n </div>\n );\n },\n);\n\nModal.displayName = 'Modal';\n"]}
@@ -0,0 +1,142 @@
1
+ import { useDelayedUnmount } from './chunk-BNEEI7S5.js';
2
+ import { useDismissableLayer } from './chunk-JCJP427C.js';
3
+ import { useFocusTrap } from './chunk-QT62VC36.js';
4
+ import { useScrollLock } from './chunk-53YMHM24.js';
5
+ import { Button } from './chunk-KL6I2JFC.js';
6
+ import { useMergedRef } from './chunk-P4Z7HH66.js';
7
+ import { RichText } from './chunk-P4CV2EPR.js';
8
+ import { cn } from './chunk-6LLGTBM6.js';
9
+ import { forwardRef, useRef, useId } from 'react';
10
+ import { cva } from 'class-variance-authority';
11
+ import { jsxs, jsx } from 'react/jsx-runtime';
12
+
13
+ var drawerOverlayStyles = cva(
14
+ "absolute inset-0 bg-[var(--surface-overlay)] transition-opacity duration-200 ease-out",
15
+ {
16
+ variants: {
17
+ visible: {
18
+ true: "opacity-100",
19
+ false: "opacity-0"
20
+ }
21
+ },
22
+ defaultVariants: {
23
+ visible: false
24
+ }
25
+ }
26
+ );
27
+ var drawerPanelStyles = cva(
28
+ [
29
+ "absolute inset-y-0 flex w-full max-w-80 flex-col gap-6 overflow-y-auto",
30
+ "border-[var(--border-default)] bg-[var(--surface-primary)] p-6 shadow-xl",
31
+ "transition-transform duration-200 ease-out focus:outline-none"
32
+ ],
33
+ {
34
+ variants: {
35
+ side: {
36
+ left: "left-0 border-r",
37
+ right: "right-0 border-l"
38
+ },
39
+ visible: {
40
+ true: "translate-x-0",
41
+ false: ""
42
+ }
43
+ },
44
+ compoundVariants: [
45
+ { side: "left", visible: false, className: "-translate-x-full" },
46
+ { side: "right", visible: false, className: "translate-x-full" }
47
+ ],
48
+ defaultVariants: {
49
+ side: "right",
50
+ visible: false
51
+ }
52
+ }
53
+ );
54
+ var drawerHeaderStyles = "flex items-center justify-between gap-4";
55
+ var drawerTitleStyles = "text-lg font-semibold text-[var(--text-primary)]";
56
+ var drawerFooterStyles = "mt-auto flex flex-col gap-4";
57
+ var EXIT_DURATION_MS = 200;
58
+ var Drawer = forwardRef(
59
+ ({
60
+ open,
61
+ onClose,
62
+ side,
63
+ title,
64
+ titleClassName,
65
+ closeLabel,
66
+ footer,
67
+ closeOnBackdropClick = true,
68
+ className,
69
+ children,
70
+ ...props
71
+ }, ref) => {
72
+ const panelRef = useRef(null);
73
+ const setPanelRef = useMergedRef(ref, panelRef);
74
+ const titleId = useId();
75
+ const { mounted, visible } = useDelayedUnmount(open, EXIT_DURATION_MS);
76
+ useDismissableLayer(open, onClose, panelRef, closeOnBackdropClick);
77
+ useFocusTrap(open && mounted, panelRef);
78
+ useScrollLock(open);
79
+ if (!mounted) {
80
+ return null;
81
+ }
82
+ return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50", children: [
83
+ /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: drawerOverlayStyles({ visible }) }),
84
+ /* @__PURE__ */ jsxs(
85
+ "div",
86
+ {
87
+ ref: setPanelRef,
88
+ role: "dialog",
89
+ "aria-modal": "true",
90
+ "aria-labelledby": title ? titleId : void 0,
91
+ tabIndex: -1,
92
+ className: cn(drawerPanelStyles({ side, visible }), className),
93
+ ...props,
94
+ children: [
95
+ (title || closeLabel) && /* @__PURE__ */ jsxs("div", { className: drawerHeaderStyles, children: [
96
+ title && /* @__PURE__ */ jsx(
97
+ RichText,
98
+ {
99
+ as: "h2",
100
+ id: titleId,
101
+ variant: "s1",
102
+ className: cn(drawerTitleStyles, titleClassName),
103
+ children: title
104
+ }
105
+ ),
106
+ closeLabel && /* @__PURE__ */ jsx(
107
+ Button,
108
+ {
109
+ variant: "ghost",
110
+ size: "icon",
111
+ "aria-label": closeLabel,
112
+ onClick: onClose,
113
+ className: "ml-auto size-11",
114
+ children: /* @__PURE__ */ jsx(
115
+ "svg",
116
+ {
117
+ "aria-hidden": true,
118
+ viewBox: "0 0 24 24",
119
+ fill: "none",
120
+ stroke: "currentColor",
121
+ strokeWidth: 2,
122
+ strokeLinecap: "round",
123
+ className: "size-6",
124
+ children: /* @__PURE__ */ jsx("path", { d: "M6 6l12 12M18 6L6 18" })
125
+ }
126
+ )
127
+ }
128
+ )
129
+ ] }),
130
+ children,
131
+ footer && /* @__PURE__ */ jsx("div", { className: drawerFooterStyles, children: footer })
132
+ ]
133
+ }
134
+ )
135
+ ] });
136
+ }
137
+ );
138
+ Drawer.displayName = "Drawer";
139
+
140
+ export { Drawer };
141
+ //# sourceMappingURL=chunk-CX3GARWU.js.map
142
+ //# sourceMappingURL=chunk-CX3GARWU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/molecules/Drawer/Drawer.styles.ts","../src/components/molecules/Drawer/Drawer.tsx"],"names":[],"mappings":"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","file":"chunk-CX3GARWU.js","sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const drawerOverlayStyles = cva(\n 'absolute inset-0 bg-[var(--surface-overlay)] transition-opacity duration-200 ease-out',\n {\n variants: {\n visible: {\n true: 'opacity-100',\n false: 'opacity-0',\n },\n },\n defaultVariants: {\n visible: false,\n },\n },\n);\n\nexport const drawerPanelStyles = cva(\n [\n 'absolute inset-y-0 flex w-full max-w-80 flex-col gap-6 overflow-y-auto',\n 'border-[var(--border-default)] bg-[var(--surface-primary)] p-6 shadow-xl',\n 'transition-transform duration-200 ease-out focus:outline-none',\n ],\n {\n variants: {\n side: {\n left: 'left-0 border-r',\n right: 'right-0 border-l',\n },\n visible: {\n true: 'translate-x-0',\n false: '',\n },\n },\n compoundVariants: [\n { side: 'left', visible: false, className: '-translate-x-full' },\n { side: 'right', visible: false, className: 'translate-x-full' },\n ],\n defaultVariants: {\n side: 'right',\n visible: false,\n },\n },\n);\n\nexport const drawerHeaderStyles = 'flex items-center justify-between gap-4';\n\nexport const drawerTitleStyles = 'text-lg font-semibold text-[var(--text-primary)]';\n\nexport const drawerFooterStyles = 'mt-auto flex flex-col gap-4';\n","import { Button, RichText } from '@components';\nimport {\n useDelayedUnmount,\n useDismissableLayer,\n useFocusTrap,\n useMergedRef,\n useScrollLock,\n} from '@hooks';\nimport { cn } from '@utils';\nimport type { VariantProps } from 'class-variance-authority';\nimport { forwardRef, useId, useRef, type HTMLAttributes, type ReactNode } from 'react';\nimport {\n drawerFooterStyles,\n drawerHeaderStyles,\n drawerOverlayStyles,\n drawerPanelStyles,\n drawerTitleStyles,\n} from './Drawer.styles';\n\nconst EXIT_DURATION_MS = 200;\n\nexport type DrawerProps = Omit<HTMLAttributes<HTMLDivElement>, 'title'> &\n Pick<VariantProps<typeof drawerPanelStyles>, 'side'> & {\n open: boolean;\n onClose: () => void;\n title?: ReactNode;\n /** Extra classes for the title (e.g. a display font). */\n titleClassName?: string;\n /** Accessible name of the close button; the button is only rendered when this is set. */\n closeLabel?: string;\n /** Pinned to the bottom of the panel (preferences, actions). */\n footer?: ReactNode;\n closeOnBackdropClick?: boolean;\n };\n\n/**\n * A side panel (navigation menus, filters, settings) that slides in from the left or right.\n * Modal dialog semantics: focus moves inside and is trapped, Escape and backdrop clicks close it,\n * the page behind doesn't scroll, and focus returns to the trigger when it closes.\n */\nexport const Drawer = forwardRef<HTMLDivElement, DrawerProps>(\n (\n {\n open,\n onClose,\n side,\n title,\n titleClassName,\n closeLabel,\n footer,\n closeOnBackdropClick = true,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const panelRef = useRef<HTMLDivElement | null>(null);\n const setPanelRef = useMergedRef(ref, panelRef);\n const titleId = useId();\n const { mounted, visible } = useDelayedUnmount(open, EXIT_DURATION_MS);\n\n useDismissableLayer(open, onClose, panelRef, closeOnBackdropClick);\n // The panel mounts one render after `open` flips, so the trap starts once it exists.\n useFocusTrap(open && mounted, panelRef);\n useScrollLock(open);\n\n if (!mounted) {\n return null;\n }\n\n return (\n <div className=\"fixed inset-0 z-50\">\n <div aria-hidden=\"true\" className={drawerOverlayStyles({ visible })} />\n <div\n ref={setPanelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n tabIndex={-1}\n className={cn(drawerPanelStyles({ side, visible }), className)}\n {...props}\n >\n {(title || closeLabel) && (\n <div className={drawerHeaderStyles}>\n {title && (\n <RichText\n as=\"h2\"\n id={titleId}\n variant=\"s1\"\n className={cn(drawerTitleStyles, titleClassName)}\n >\n {title}\n </RichText>\n )}\n {closeLabel && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={closeLabel}\n onClick={onClose}\n className=\"ml-auto size-11\"\n >\n <svg\n aria-hidden\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n className=\"size-6\"\n >\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n </Button>\n )}\n </div>\n )}\n {children}\n {footer && <div className={drawerFooterStyles}>{footer}</div>}\n </div>\n </div>\n );\n },\n);\n\nDrawer.displayName = 'Drawer';\n"]}
@@ -0,0 +1,34 @@
1
+ import { inputLabelStyles, inputStyles, inputErrorStyles, inputHintStyles } from './chunk-FFKHEBQ7.js';
2
+ import { RichText } from './chunk-P4CV2EPR.js';
3
+ import { cn } from './chunk-6LLGTBM6.js';
4
+ import { forwardRef, useId } from 'react';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ var Input = forwardRef(
8
+ ({ className, state, inputSize, label, hint, error, id: idProp, ...props }, ref) => {
9
+ const generatedId = useId();
10
+ const id = idProp ?? generatedId;
11
+ const resolvedState = error ? "error" : state;
12
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
13
+ label && /* @__PURE__ */ jsx("label", { htmlFor: id, children: /* @__PURE__ */ jsx(RichText, { as: "span", variant: "p3", className: inputLabelStyles, children: label }) }),
14
+ /* @__PURE__ */ jsx(
15
+ "input",
16
+ {
17
+ ref,
18
+ id,
19
+ "aria-describedby": error ? `${id}-error` : hint ? `${id}-hint` : void 0,
20
+ "aria-invalid": error ? "true" : void 0,
21
+ className: cn(inputStyles({ state: resolvedState, inputSize }), className),
22
+ ...props
23
+ }
24
+ ),
25
+ error && /* @__PURE__ */ jsx(RichText, { as: "p", id: `${id}-error`, role: "alert", variant: "p4", className: inputErrorStyles, children: error }),
26
+ !error && hint && /* @__PURE__ */ jsx(RichText, { as: "p", id: `${id}-hint`, variant: "p4", className: inputHintStyles, children: hint })
27
+ ] });
28
+ }
29
+ );
30
+ Input.displayName = "Input";
31
+
32
+ export { Input };
33
+ //# sourceMappingURL=chunk-DP274HDM.js.map
34
+ //# sourceMappingURL=chunk-DP274HDM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/atoms/Input/Input.tsx"],"names":[],"mappings":";;;;;;AAkBO,IAAM,KAAA,GAAQ,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,SAAA,EAAW,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,EAAA,EAAI,MAAA,EAAQ,GAAG,KAAA,IAAS,GAAA,KAAQ;AAClF,IAAA,MAAM,cAAc,KAAA,EAAM;AAC1B,IAAA,MAAM,KAAK,MAAA,IAAU,WAAA;AACrB,IAAA,MAAM,aAAA,GAAgB,QAAQ,OAAA,GAAU,KAAA;AAExC,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EACZ,QAAA,EAAA;AAAA,MAAA,KAAA,oBACC,GAAA,CAAC,OAAA,EAAA,EAAM,OAAA,EAAS,EAAA,EACd,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,EAAA,EAAG,MAAA,EAAO,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,gBAAA,EACzC,iBACH,CAAA,EACF,CAAA;AAAA,sBAEF,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,EAAA;AAAA,UACA,kBAAA,EAAkB,QAAQ,CAAA,EAAG,EAAE,WAAW,IAAA,GAAO,CAAA,EAAG,EAAE,CAAA,KAAA,CAAA,GAAU,MAAA;AAAA,UAChE,cAAA,EAAc,QAAQ,MAAA,GAAS,MAAA;AAAA,UAC/B,SAAA,EAAW,GAAG,WAAA,CAAY,EAAE,OAAO,aAAA,EAAe,SAAA,EAAW,CAAA,EAAG,SAAS,CAAA;AAAA,UACxE,GAAG;AAAA;AAAA,OACN;AAAA,MACC,KAAA,oBACC,GAAA,CAAC,QAAA,EAAA,EAAS,EAAA,EAAG,KAAI,EAAA,EAAI,CAAA,EAAG,EAAE,CAAA,MAAA,CAAA,EAAU,MAAK,OAAA,EAAQ,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,kBACtE,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,MAED,CAAC,KAAA,IAAS,IAAA,oBACT,GAAA,CAAC,YAAS,EAAA,EAAG,GAAA,EAAI,EAAA,EAAI,CAAA,EAAG,EAAE,CAAA,KAAA,CAAA,EAAS,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,iBACxD,QAAA,EAAA,IAAA,EACH;AAAA,KAAA,EAEJ,CAAA;AAAA,EAEJ;AACF;AAEA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-DP274HDM.js","sourcesContent":["import type { VariantProps } from 'class-variance-authority';\nimport { forwardRef, useId, type InputHTMLAttributes } from 'react';\nimport { RichText } from '@components';\nimport { cn } from '@utils';\nimport {\n inputErrorStyles,\n inputHintStyles,\n inputLabelStyles,\n inputStyles,\n} from './Input.styles';\n\nexport type InputProps = InputHTMLAttributes<HTMLInputElement> &\n VariantProps<typeof inputStyles> & {\n label?: string;\n hint?: string;\n error?: string;\n };\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n ({ className, state, inputSize, label, hint, error, id: idProp, ...props }, ref) => {\n const generatedId = useId();\n const id = idProp ?? generatedId;\n const resolvedState = error ? 'error' : state;\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <label htmlFor={id}>\n <RichText as=\"span\" variant=\"p3\" className={inputLabelStyles}>\n {label}\n </RichText>\n </label>\n )}\n <input\n ref={ref}\n id={id}\n aria-describedby={error ? `${id}-error` : hint ? `${id}-hint` : undefined}\n aria-invalid={error ? 'true' : undefined}\n className={cn(inputStyles({ state: resolvedState, inputSize }), className)}\n {...props}\n />\n {error && (\n <RichText as=\"p\" id={`${id}-error`} role=\"alert\" variant=\"p4\" className={inputErrorStyles}>\n {error}\n </RichText>\n )}\n {!error && hint && (\n <RichText as=\"p\" id={`${id}-hint`} variant=\"p4\" className={inputHintStyles}>\n {hint}\n </RichText>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = 'Input';\n"]}
@@ -0,0 +1,41 @@
1
+ import { cva } from 'class-variance-authority';
2
+
3
+ // src/components/atoms/Input/Input.styles.ts
4
+ var inputStyles = cva(
5
+ [
6
+ "flex w-full rounded-md px-3 py-2",
7
+ "text-sm text-[var(--input-text)]",
8
+ "bg-[var(--input-bg)]",
9
+ "border border-[var(--input-border)]",
10
+ "placeholder:text-[var(--input-placeholder)]",
11
+ "transition-colors duration-150 ease-in-out",
12
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] focus-visible:ring-offset-0",
13
+ "focus-visible:border-[var(--input-border-focus)]",
14
+ "disabled:cursor-not-allowed disabled:opacity-50",
15
+ "file:border-0 file:bg-transparent file:text-sm file:font-medium"
16
+ ],
17
+ {
18
+ variants: {
19
+ state: {
20
+ default: "",
21
+ error: "border-[var(--input-border-error)] focus-visible:ring-[var(--border-error)]"
22
+ },
23
+ inputSize: {
24
+ sm: "h-8 px-2 text-xs",
25
+ md: "h-10 px-3 text-sm",
26
+ lg: "h-12 px-4 text-base"
27
+ }
28
+ },
29
+ defaultVariants: {
30
+ state: "default",
31
+ inputSize: "md"
32
+ }
33
+ }
34
+ );
35
+ var inputLabelStyles = "text-sm font-medium text-[var(--text-primary)]";
36
+ var inputErrorStyles = "text-xs text-[var(--border-error)]";
37
+ var inputHintStyles = "text-xs text-[var(--text-secondary)]";
38
+
39
+ export { inputErrorStyles, inputHintStyles, inputLabelStyles, inputStyles };
40
+ //# sourceMappingURL=chunk-FFKHEBQ7.js.map
41
+ //# sourceMappingURL=chunk-FFKHEBQ7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/atoms/Input/Input.styles.ts"],"names":[],"mappings":";;;AAEO,IAAM,WAAA,GAAc,GAAA;AAAA,EACzB;AAAA,IACE,kCAAA;AAAA,IACA,kCAAA;AAAA,IACA,sBAAA;AAAA,IACA,qCAAA;AAAA,IACA,6CAAA;AAAA,IACA,4CAAA;AAAA,IACA,sHAAA;AAAA,IACA,kDAAA;AAAA,IACA,iDAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,EAAA;AAAA,QACT,KAAA,EAAO;AAAA,OACT;AAAA,MACA,SAAA,EAAW;AAAA,QACT,EAAA,EAAI,kBAAA;AAAA,QACJ,EAAA,EAAI,mBAAA;AAAA,QACJ,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,KAAA,EAAO,SAAA;AAAA,MACP,SAAA,EAAW;AAAA;AACb;AAEJ;AAEO,IAAM,gBAAA,GAAmB;AACzB,IAAM,gBAAA,GAAmB;AACzB,IAAM,eAAA,GAAkB","file":"chunk-FFKHEBQ7.js","sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const inputStyles = cva(\n [\n 'flex w-full rounded-md px-3 py-2',\n 'text-sm text-[var(--input-text)]',\n 'bg-[var(--input-bg)]',\n 'border border-[var(--input-border)]',\n 'placeholder:text-[var(--input-placeholder)]',\n 'transition-colors duration-150 ease-in-out',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] focus-visible:ring-offset-0',\n 'focus-visible:border-[var(--input-border-focus)]',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'file:border-0 file:bg-transparent file:text-sm file:font-medium',\n ],\n {\n variants: {\n state: {\n default: '',\n error: 'border-[var(--input-border-error)] focus-visible:ring-[var(--border-error)]',\n },\n inputSize: {\n sm: 'h-8 px-2 text-xs',\n md: 'h-10 px-3 text-sm',\n lg: 'h-12 px-4 text-base',\n },\n },\n defaultVariants: {\n state: 'default',\n inputSize: 'md',\n },\n },\n);\n\nexport const inputLabelStyles = 'text-sm font-medium text-[var(--text-primary)]';\nexport const inputErrorStyles = 'text-xs text-[var(--border-error)]';\nexport const inputHintStyles = 'text-xs text-[var(--text-secondary)]';\n"]}
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=chunk-GQMA2AQI.js.map
3
+ //# sourceMappingURL=chunk-GQMA2AQI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-GQMA2AQI.js"}
@@ -1,7 +1,7 @@
1
1
  import { useMergedRef } from './chunk-P4Z7HH66.js';
2
2
  import { cn } from './chunk-6LLGTBM6.js';
3
- import { forwardRef, Children, isValidElement, cloneElement } from 'react';
4
3
  import { cva } from 'class-variance-authority';
4
+ import { forwardRef, Children, isValidElement, cloneElement } from 'react';
5
5
  import { jsx } from 'react/jsx-runtime';
6
6
 
7
7
  var buttonStyles = cva(
@@ -103,5 +103,5 @@ var Button = forwardRef(
103
103
  Button.displayName = "Button";
104
104
 
105
105
  export { Button, buttonStyles };
106
- //# sourceMappingURL=chunk-DXJQNQ5K.js.map
107
- //# sourceMappingURL=chunk-DXJQNQ5K.js.map
106
+ //# sourceMappingURL=chunk-KL6I2JFC.js.map
107
+ //# sourceMappingURL=chunk-KL6I2JFC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/atoms/Button/Button.styles.ts","../src/components/atoms/Button/Slot.tsx","../src/components/atoms/Button/Button.tsx"],"names":["forwardRef"],"mappings":"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","file":"chunk-DXJQNQ5K.js","sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const buttonStyles = cva(\n [\n 'inline-flex items-center justify-center gap-2',\n 'font-medium text-sm leading-none',\n 'rounded-md',\n 'transition-colors duration-150 ease-in-out',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] focus-visible:ring-offset-2',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'select-none',\n ],\n {\n variants: {\n variant: {\n primary: [\n 'bg-[var(--btn-primary-bg)] text-[var(--btn-primary-text)]',\n 'border border-[var(--btn-primary-border)]',\n 'hover:bg-[var(--btn-primary-bg-hover)]',\n 'active:bg-[var(--btn-primary-bg-active)]',\n ],\n secondary: [\n 'bg-[var(--btn-secondary-bg)] text-[var(--btn-secondary-text)]',\n 'border border-[var(--btn-secondary-border)]',\n 'hover:bg-[var(--btn-secondary-bg-hover)]',\n 'active:bg-[var(--btn-secondary-bg-active)]',\n ],\n ghost: [\n 'bg-[var(--btn-ghost-bg)] text-[var(--btn-ghost-text)]',\n 'border border-[var(--btn-ghost-border)]',\n 'hover:bg-[var(--btn-ghost-bg-hover)]',\n 'active:bg-[var(--btn-ghost-bg-active)]',\n ],\n destructive: [\n 'bg-[var(--btn-destructive-bg)] text-[var(--btn-destructive-text)]',\n 'border border-[var(--btn-destructive-border)]',\n 'hover:bg-[var(--btn-destructive-bg-hover)]',\n 'active:bg-[var(--btn-destructive-bg-active)]',\n ],\n },\n size: {\n sm: 'h-8 px-3 text-xs',\n md: 'h-10 px-4 text-sm',\n lg: 'h-12 px-6 text-base',\n icon: 'h-10 w-10',\n },\n fullWidth: {\n true: 'w-full',\n },\n },\n defaultVariants: {\n variant: 'primary',\n size: 'md',\n },\n },\n);\n","import { useMergedRef } from '@hooks';\nimport { cn } from '@utils';\nimport {\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n type CSSProperties,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n} from 'react';\n\ntype AnyProps = Record<string, unknown>;\n\nexport type SlotProps = HTMLAttributes<HTMLElement> & { children?: ReactNode };\n\nconst isHandler = (key: string, value: unknown): value is (...args: unknown[]) => void =>\n /^on[A-Z]/.test(key) && typeof value === 'function';\n\n/** Slot props first, child props override — except handlers (both run) and className/style (merged). */\nconst mergeProps = (slotProps: AnyProps, childProps: AnyProps): AnyProps => {\n const merged: AnyProps = { ...slotProps, ...childProps };\n for (const [key, slotValue] of Object.entries(slotProps)) {\n const childValue = childProps[key];\n if (isHandler(key, slotValue) && isHandler(key, childValue)) {\n merged[key] = (...args: unknown[]) => {\n childValue(...args);\n slotValue(...args);\n };\n }\n }\n merged['className'] = cn(slotProps['className'] as string, childProps['className'] as string);\n merged['style'] = {\n ...(slotProps['style'] as CSSProperties),\n ...(childProps['style'] as CSSProperties),\n };\n return merged;\n};\n\n/**\n * Renders its single child element instead of its own DOM node, merging its props into it\n * (Radix-style `asChild`). Used by `Button` so a link can look like a button and stay an `<a>`.\n */\nexport const Slot = forwardRef<HTMLElement, SlotProps>(\n ({ children, ...slotProps }, forwardedRef) => {\n // Text or several children can't receive props: render nothing rather than throwing.\n const child = Children.count(children) === 1 ? Children.toArray(children)[0] : null;\n const childProps = isValidElement<AnyProps>(child) ? child.props : {};\n // React 19 exposes `ref` as a prop; React 18 keeps it on the element.\n const childRef = (childProps['ref'] ??\n (child as unknown as { ref?: Ref<HTMLElement> } | null)?.ref) as Ref<HTMLElement> | undefined;\n const ref = useMergedRef(forwardedRef, childRef);\n\n if (!isValidElement<AnyProps>(child)) {\n return null;\n }\n return cloneElement(child, { ...mergeProps(slotProps as AnyProps, childProps), ref });\n },\n);\n\nSlot.displayName = 'Slot';\n","import { cn } from '@utils';\nimport type { VariantProps } from 'class-variance-authority';\nimport { forwardRef, type ButtonHTMLAttributes, type Ref } from 'react';\nimport { buttonStyles } from './Button.styles';\nimport { Slot } from './Slot';\n\nexport type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> &\n VariantProps<typeof buttonStyles> & {\n /**\n * Render the single child element (e.g. an `<a>`) with the button styles and props instead of\n * a `<button>`. Use it for navigation that must look like a button.\n */\n asChild?: boolean;\n };\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, fullWidth, asChild = false, ...props }, ref) => {\n const classes = cn(buttonStyles({ variant, size, fullWidth }), className);\n\n if (asChild) {\n // The ref points at whatever element the child renders (usually an <a>), not a <button>.\n const slotRef = ref as unknown as Ref<HTMLElement>;\n return <Slot ref={slotRef} className={classes} {...props} />;\n }\n\n return <button ref={ref} className={classes} {...props} />;\n },\n);\n\nButton.displayName = 'Button';\n"]}
1
+ {"version":3,"sources":["../src/components/atoms/Button/Button.styles.ts","../src/components/atoms/Button/Slot.tsx","../src/components/atoms/Button/Button.tsx"],"names":["forwardRef"],"mappings":"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","file":"chunk-KL6I2JFC.js","sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const buttonStyles = cva(\n [\n 'inline-flex items-center justify-center gap-2',\n 'font-medium text-sm leading-none',\n 'rounded-md',\n 'transition-colors duration-150 ease-in-out',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] focus-visible:ring-offset-2',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'select-none',\n ],\n {\n variants: {\n variant: {\n primary: [\n 'bg-[var(--btn-primary-bg)] text-[var(--btn-primary-text)]',\n 'border border-[var(--btn-primary-border)]',\n 'hover:bg-[var(--btn-primary-bg-hover)]',\n 'active:bg-[var(--btn-primary-bg-active)]',\n ],\n secondary: [\n 'bg-[var(--btn-secondary-bg)] text-[var(--btn-secondary-text)]',\n 'border border-[var(--btn-secondary-border)]',\n 'hover:bg-[var(--btn-secondary-bg-hover)]',\n 'active:bg-[var(--btn-secondary-bg-active)]',\n ],\n ghost: [\n 'bg-[var(--btn-ghost-bg)] text-[var(--btn-ghost-text)]',\n 'border border-[var(--btn-ghost-border)]',\n 'hover:bg-[var(--btn-ghost-bg-hover)]',\n 'active:bg-[var(--btn-ghost-bg-active)]',\n ],\n destructive: [\n 'bg-[var(--btn-destructive-bg)] text-[var(--btn-destructive-text)]',\n 'border border-[var(--btn-destructive-border)]',\n 'hover:bg-[var(--btn-destructive-bg-hover)]',\n 'active:bg-[var(--btn-destructive-bg-active)]',\n ],\n },\n size: {\n sm: 'h-8 px-3 text-xs',\n md: 'h-10 px-4 text-sm',\n lg: 'h-12 px-6 text-base',\n icon: 'h-10 w-10',\n },\n fullWidth: {\n true: 'w-full',\n },\n },\n defaultVariants: {\n variant: 'primary',\n size: 'md',\n },\n },\n);\n","import { useMergedRef } from '@hooks';\nimport { cn } from '@utils';\nimport {\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n type CSSProperties,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n} from 'react';\n\ntype AnyProps = Record<string, unknown>;\n\nexport type SlotProps = HTMLAttributes<HTMLElement> & { children?: ReactNode };\n\nconst isHandler = (key: string, value: unknown): value is (...args: unknown[]) => void =>\n /^on[A-Z]/.test(key) && typeof value === 'function';\n\n/** Slot props first, child props override — except handlers (both run) and className/style (merged). */\nconst mergeProps = (slotProps: AnyProps, childProps: AnyProps): AnyProps => {\n const merged: AnyProps = { ...slotProps, ...childProps };\n for (const [key, slotValue] of Object.entries(slotProps)) {\n const childValue = childProps[key];\n if (isHandler(key, slotValue) && isHandler(key, childValue)) {\n merged[key] = (...args: unknown[]) => {\n childValue(...args);\n slotValue(...args);\n };\n }\n }\n merged['className'] = cn(slotProps['className'] as string, childProps['className'] as string);\n merged['style'] = {\n ...(slotProps['style'] as CSSProperties),\n ...(childProps['style'] as CSSProperties),\n };\n return merged;\n};\n\n/**\n * Renders its single child element instead of its own DOM node, merging its props into it\n * (Radix-style `asChild`). Used by `Button` so a link can look like a button and stay an `<a>`.\n */\nexport const Slot = forwardRef<HTMLElement, SlotProps>(\n ({ children, ...slotProps }, forwardedRef) => {\n // Text or several children can't receive props: render nothing rather than throwing.\n const child = Children.count(children) === 1 ? Children.toArray(children)[0] : null;\n const childProps = isValidElement<AnyProps>(child) ? child.props : {};\n // React 19 exposes `ref` as a prop; React 18 keeps it on the element.\n const childRef = (childProps['ref'] ??\n (child as unknown as { ref?: Ref<HTMLElement> } | null)?.ref) as Ref<HTMLElement> | undefined;\n const ref = useMergedRef(forwardedRef, childRef);\n\n if (!isValidElement<AnyProps>(child)) {\n return null;\n }\n return cloneElement(child, { ...mergeProps(slotProps as AnyProps, childProps), ref });\n },\n);\n\nSlot.displayName = 'Slot';\n","import { cn } from '@utils';\nimport type { VariantProps } from 'class-variance-authority';\nimport { forwardRef, type ButtonHTMLAttributes, type Ref } from 'react';\nimport { buttonStyles } from './Button.styles';\nimport { Slot } from './Slot';\n\nexport type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> &\n VariantProps<typeof buttonStyles> & {\n /**\n * Render the single child element (e.g. an `<a>`) with the button styles and props instead of\n * a `<button>`. Use it for navigation that must look like a button.\n */\n asChild?: boolean;\n };\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, fullWidth, asChild = false, ...props }, ref) => {\n const classes = cn(buttonStyles({ variant, size, fullWidth }), className);\n\n if (asChild) {\n // The ref points at whatever element the child renders (usually an <a>), not a <button>.\n const slotRef = ref as unknown as Ref<HTMLElement>;\n return <Slot ref={slotRef} className={classes} {...props} />;\n }\n\n return <button ref={ref} className={classes} {...props} />;\n },\n);\n\nButton.displayName = 'Button';\n"]}
@@ -0,0 +1,50 @@
1
+ import { useEffect } from 'react';
2
+
3
+ // src/hooks/useFocusTrap/useFocusTrap.ts
4
+ var FOCUSABLE = [
5
+ "a[href]",
6
+ "button:not([disabled])",
7
+ "input:not([disabled])",
8
+ "select:not([disabled])",
9
+ "textarea:not([disabled])",
10
+ '[tabindex]:not([tabindex="-1"])'
11
+ ].join(",");
12
+ var getFocusable = (container) => Array.from(container.querySelectorAll(FOCUSABLE));
13
+ var useFocusTrap = (active, containerRef) => {
14
+ useEffect(() => {
15
+ const container = containerRef.current;
16
+ if (!active || !container) {
17
+ return;
18
+ }
19
+ const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
20
+ (getFocusable(container)[0] ?? container).focus();
21
+ const handleKeyDown = (event) => {
22
+ if (event.key !== "Tab") {
23
+ return;
24
+ }
25
+ const focusable = getFocusable(container);
26
+ const first = focusable[0];
27
+ const last = focusable.at(-1);
28
+ if (!first || !last) {
29
+ event.preventDefault();
30
+ return;
31
+ }
32
+ if (event.shiftKey && document.activeElement === first) {
33
+ event.preventDefault();
34
+ last.focus();
35
+ } else if (!event.shiftKey && document.activeElement === last) {
36
+ event.preventDefault();
37
+ first.focus();
38
+ }
39
+ };
40
+ container.addEventListener("keydown", handleKeyDown);
41
+ return () => {
42
+ container.removeEventListener("keydown", handleKeyDown);
43
+ previouslyFocused?.focus();
44
+ };
45
+ }, [active, containerRef]);
46
+ };
47
+
48
+ export { useFocusTrap };
49
+ //# sourceMappingURL=chunk-QT62VC36.js.map
50
+ //# sourceMappingURL=chunk-QT62VC36.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/useFocusTrap/useFocusTrap.ts"],"names":[],"mappings":";;;AAEA,IAAM,SAAA,GAAY;AAAA,EAChB,SAAA;AAAA,EACA,wBAAA;AAAA,EACA,uBAAA;AAAA,EACA,wBAAA;AAAA,EACA,0BAAA;AAAA,EACA;AACF,CAAA,CAAE,KAAK,GAAG,CAAA;AAEV,IAAM,YAAA,GAAe,CAAC,SAAA,KACpB,KAAA,CAAM,KAAK,SAAA,CAAU,gBAAA,CAA8B,SAAS,CAAC,CAAA;AAMxD,IAAM,YAAA,GAAe,CAC1B,MAAA,EACA,YAAA,KACS;AACT,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,SAAA,EAAW;AACzB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,iBAAA,GACJ,QAAA,CAAS,aAAA,YAAyB,WAAA,GAAc,SAAS,aAAA,GAAgB,IAAA;AAC3E,IAAA,CAAC,aAAa,SAAS,CAAA,CAAE,CAAC,CAAA,IAAK,WAAW,KAAA,EAAM;AAEhD,IAAA,MAAM,aAAA,GAAgB,CAAC,KAAA,KAAyB;AAC9C,MAAA,IAAI,KAAA,CAAM,QAAQ,KAAA,EAAO;AACvB,QAAA;AAAA,MACF;AACA,MAAA,MAAM,SAAA,GAAY,aAAa,SAAS,CAAA;AACxC,MAAA,MAAM,KAAA,GAAQ,UAAU,CAAC,CAAA;AACzB,MAAA,MAAM,IAAA,GAAO,SAAA,CAAU,EAAA,CAAG,EAAE,CAAA;AAC5B,MAAA,IAAI,CAAC,KAAA,IAAS,CAAC,IAAA,EAAM;AACnB,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA;AAAA,MACF;AACA,MAAA,IAAI,KAAA,CAAM,QAAA,IAAY,QAAA,CAAS,aAAA,KAAkB,KAAA,EAAO;AACtD,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,WAAW,CAAC,KAAA,CAAM,QAAA,IAAY,QAAA,CAAS,kBAAkB,IAAA,EAAM;AAC7D,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,KAAA,CAAM,KAAA,EAAM;AAAA,MACd;AAAA,IACF,CAAA;AAEA,IAAA,SAAA,CAAU,gBAAA,CAAiB,WAAW,aAAa,CAAA;AACnD,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,CAAU,mBAAA,CAAoB,WAAW,aAAa,CAAA;AACtD,MAAA,iBAAA,EAAmB,KAAA,EAAM;AAAA,IAC3B,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,YAAY,CAAC,CAAA;AAC3B","file":"chunk-QT62VC36.js","sourcesContent":["import { useEffect, type RefObject } from 'react';\n\nconst FOCUSABLE = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',');\n\nconst getFocusable = (container: HTMLElement): HTMLElement[] =>\n Array.from(container.querySelectorAll<HTMLElement>(FOCUSABLE));\n\n/**\n * While `active`, keeps Tab / Shift+Tab inside `containerRef`, moves focus into it, and returns\n * focus to the previously focused element when it deactivates (WCAG dialog pattern).\n */\nexport const useFocusTrap = (\n active: boolean,\n containerRef: RefObject<HTMLElement | null>,\n): void => {\n useEffect(() => {\n const container = containerRef.current;\n if (!active || !container) {\n return;\n }\n\n const previouslyFocused =\n document.activeElement instanceof HTMLElement ? document.activeElement : null;\n (getFocusable(container)[0] ?? container).focus();\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') {\n return;\n }\n const focusable = getFocusable(container);\n const first = focusable[0];\n const last = focusable.at(-1);\n if (!first || !last) {\n event.preventDefault();\n return;\n }\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n };\n\n container.addEventListener('keydown', handleKeyDown);\n return () => {\n container.removeEventListener('keydown', handleKeyDown);\n previouslyFocused?.focus();\n };\n }, [active, containerRef]);\n};\n"]}
@@ -1,9 +1,11 @@
1
- import { useDismissableLayer } from './chunk-JCJP427C.js';
2
1
  import { useDelayedUnmount } from './chunk-BNEEI7S5.js';
2
+ import { useDismissableLayer } from './chunk-JCJP427C.js';
3
+ import { useFocusTrap } from './chunk-QT62VC36.js';
4
+ import { useScrollLock } from './chunk-53YMHM24.js';
3
5
  import { useMergedRef } from './chunk-P4Z7HH66.js';
4
6
  import { RichText } from './chunk-P4CV2EPR.js';
5
7
  import { cn } from './chunk-6LLGTBM6.js';
6
- import { forwardRef, useRef } from 'react';
8
+ import { forwardRef, useRef, useId } from 'react';
7
9
  import { cva } from 'class-variance-authority';
8
10
  import { jsx, jsxs } from 'react/jsx-runtime';
9
11
 
@@ -50,8 +52,11 @@ var BottomSheet = forwardRef(
50
52
  ({ open, onClose, title, footer, closeOnBackdropClick = true, className, children, ...props }, ref) => {
51
53
  const panelRef = useRef(null);
52
54
  const setPanelRef = useMergedRef(ref, panelRef);
55
+ const titleId = useId();
53
56
  const { mounted, visible } = useDelayedUnmount(open, EXIT_DURATION_MS);
54
57
  useDismissableLayer(open, onClose, panelRef, closeOnBackdropClick);
58
+ useFocusTrap(open && mounted, panelRef);
59
+ useScrollLock(open);
55
60
  if (!mounted) {
56
61
  return null;
57
62
  }
@@ -61,12 +66,13 @@ var BottomSheet = forwardRef(
61
66
  ref: setPanelRef,
62
67
  role: "dialog",
63
68
  "aria-modal": "true",
64
- "aria-labelledby": title ? "bottom-sheet-title" : void 0,
69
+ "aria-labelledby": title ? titleId : void 0,
70
+ tabIndex: -1,
65
71
  className: cn(bottomSheetPanelStyles({ visible }), className),
66
72
  ...props,
67
73
  children: [
68
74
  /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: bottomSheetHandleStyles }),
69
- title && /* @__PURE__ */ jsx(RichText, { as: "h2", id: "bottom-sheet-title", variant: "s1", className: bottomSheetTitleStyles, children: title }),
75
+ title && /* @__PURE__ */ jsx(RichText, { as: "h2", id: titleId, variant: "s1", className: bottomSheetTitleStyles, children: title }),
70
76
  children,
71
77
  footer && /* @__PURE__ */ jsx("div", { className: bottomSheetFooterStyles, children: footer })
72
78
  ]
@@ -77,5 +83,5 @@ var BottomSheet = forwardRef(
77
83
  BottomSheet.displayName = "BottomSheet";
78
84
 
79
85
  export { BottomSheet };
80
- //# sourceMappingURL=chunk-ZEGQFAYE.js.map
81
- //# sourceMappingURL=chunk-ZEGQFAYE.js.map
86
+ //# sourceMappingURL=chunk-RRIE5LFQ.js.map
87
+ //# sourceMappingURL=chunk-RRIE5LFQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/molecules/BottomSheet/BottomSheet.styles.ts","../src/components/molecules/BottomSheet/BottomSheet.tsx"],"names":[],"mappings":";;;;;;;;;;;AAEO,IAAM,wBAAA,GAA2B,GAAA;AAAA,EACtC;AAAA,IACE,8EAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ,CAAA;AAEO,IAAM,sBAAA,GAAyB,GAAA;AAAA,EACpC;AAAA,IACE,+EAAA;AAAA,IACA,6CAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,eAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ,CAAA;AAEO,IAAM,uBAAA,GACX,gEAAA;AAEK,IAAM,sBAAA,GAAyB,uDAAA;AAE/B,IAAM,uBAAA,GAA0B,0CAAA;AC1BvC,IAAM,gBAAA,GAAmB,GAAA;AAUlB,IAAM,WAAA,GAAc,UAAA;AAAA,EACzB,CACE,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,MAAA,EAAQ,oBAAA,GAAuB,IAAA,EAAM,SAAA,EAAW,QAAA,EAAU,GAAG,KAAA,IACrF,GAAA,KACG;AACH,IAAA,MAAM,QAAA,GAAW,OAA8B,IAAI,CAAA;AACnD,IAAA,MAAM,WAAA,GAAc,YAAA,CAAa,GAAA,EAAK,QAAQ,CAAA;AAC9C,IAAA,MAAM,UAAU,KAAA,EAAM;AACtB,IAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAQ,GAAI,iBAAA,CAAkB,MAAM,gBAAgB,CAAA;AAErE,IAAA,mBAAA,CAAoB,IAAA,EAAM,OAAA,EAAS,QAAA,EAAU,oBAAoB,CAAA;AAEjE,IAAA,YAAA,CAAa,IAAA,IAAQ,SAAS,QAAQ,CAAA;AACtC,IAAA,aAAA,CAAc,IAAI,CAAA;AAElB,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,2BACG,KAAA,EAAA,EAAI,SAAA,EAAW,yBAAyB,EAAE,OAAA,EAAS,CAAA,EAClD,QAAA,kBAAA,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,WAAA;AAAA,QACL,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAW,MAAA;AAAA,QACX,iBAAA,EAAiB,QAAQ,OAAA,GAAU,MAAA;AAAA,QACnC,QAAA,EAAU,EAAA;AAAA,QACV,WAAW,EAAA,CAAG,sBAAA,CAAuB,EAAE,OAAA,EAAS,GAAG,SAAS,CAAA;AAAA,QAC3D,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,KAAA,EAAA,EAAI,aAAA,EAAW,IAAA,EAAC,SAAA,EAAW,uBAAA,EAAyB,CAAA;AAAA,UACpD,KAAA,oBACC,GAAA,CAAC,QAAA,EAAA,EAAS,EAAA,EAAG,IAAA,EAAK,EAAA,EAAI,OAAA,EAAS,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,sBAAA,EACpD,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,UAED,QAAA;AAAA,UACA,MAAA,oBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,yBAA0B,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA;AAAA,KAC9D,EACF,CAAA;AAAA,EAEJ;AACF;AAEA,WAAA,CAAY,WAAA,GAAc,aAAA","file":"chunk-RRIE5LFQ.js","sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const bottomSheetOverlayStyles = cva(\n [\n 'fixed inset-0 z-50 flex items-end justify-center bg-[var(--surface-overlay)]',\n 'transition-opacity duration-200 ease-out',\n ],\n {\n variants: {\n visible: {\n true: 'opacity-100',\n false: 'opacity-0',\n },\n },\n defaultVariants: {\n visible: false,\n },\n },\n);\n\nexport const bottomSheetPanelStyles = cva(\n [\n 'w-full max-w-md rounded-t-xl border border-b-0 border-[var(--border-default)]',\n 'bg-[var(--surface-secondary)] p-6 shadow-lg',\n 'transition-transform duration-200 ease-out',\n ],\n {\n variants: {\n visible: {\n true: 'translate-y-0',\n false: 'translate-y-full',\n },\n },\n defaultVariants: {\n visible: false,\n },\n },\n);\n\nexport const bottomSheetHandleStyles =\n 'mx-auto mb-4 h-1.5 w-10 rounded-full bg-[var(--border-strong)]';\n\nexport const bottomSheetTitleStyles = 'mb-4 text-lg font-semibold text-[var(--text-primary)]';\n\nexport const bottomSheetFooterStyles = 'mt-6 flex items-center justify-end gap-2';\n","import { forwardRef, useId, useRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { RichText } from '@components';\nimport {\n useDelayedUnmount,\n useDismissableLayer,\n useFocusTrap,\n useMergedRef,\n useScrollLock,\n} from '@hooks';\nimport { cn } from '@utils';\nimport {\n bottomSheetFooterStyles,\n bottomSheetHandleStyles,\n bottomSheetOverlayStyles,\n bottomSheetPanelStyles,\n bottomSheetTitleStyles,\n} from './BottomSheet.styles';\n\nconst EXIT_DURATION_MS = 200;\n\nexport type BottomSheetProps = Omit<HTMLAttributes<HTMLDivElement>, 'title'> & {\n open: boolean;\n onClose: () => void;\n title?: ReactNode;\n footer?: ReactNode;\n closeOnBackdropClick?: boolean;\n};\n\nexport const BottomSheet = forwardRef<HTMLDivElement, BottomSheetProps>(\n (\n { open, onClose, title, footer, closeOnBackdropClick = true, className, children, ...props },\n ref,\n ) => {\n const panelRef = useRef<HTMLDivElement | null>(null);\n const setPanelRef = useMergedRef(ref, panelRef);\n const titleId = useId();\n const { mounted, visible } = useDelayedUnmount(open, EXIT_DURATION_MS);\n\n useDismissableLayer(open, onClose, panelRef, closeOnBackdropClick);\n // The panel mounts one render after `open` flips, so the trap starts once it exists.\n useFocusTrap(open && mounted, panelRef);\n useScrollLock(open);\n\n if (!mounted) {\n return null;\n }\n\n return (\n <div className={bottomSheetOverlayStyles({ visible })}>\n <div\n ref={setPanelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n tabIndex={-1}\n className={cn(bottomSheetPanelStyles({ visible }), className)}\n {...props}\n >\n <div aria-hidden className={bottomSheetHandleStyles} />\n {title && (\n <RichText as=\"h2\" id={titleId} variant=\"s1\" className={bottomSheetTitleStyles}>\n {title}\n </RichText>\n )}\n {children}\n {footer && <div className={bottomSheetFooterStyles}>{footer}</div>}\n </div>\n </div>\n );\n },\n);\n\nBottomSheet.displayName = 'BottomSheet';\n"]}
@@ -0,0 +1,91 @@
1
+ import { inputLabelStyles, inputErrorStyles, inputHintStyles } from './chunk-FFKHEBQ7.js';
2
+ import { RichText } from './chunk-P4CV2EPR.js';
3
+ import { cn } from './chunk-6LLGTBM6.js';
4
+ import { forwardRef, useId } from 'react';
5
+ import { cva } from 'class-variance-authority';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ var selectStyles = cva(
9
+ [
10
+ "flex w-full appearance-none rounded-md bg-no-repeat pr-10",
11
+ "text-[var(--input-text)] bg-[var(--input-bg)]",
12
+ "border border-[var(--input-border)]",
13
+ "transition-colors duration-150 ease-in-out",
14
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] focus-visible:ring-offset-0",
15
+ "focus-visible:border-[var(--input-border-focus)]",
16
+ "disabled:cursor-not-allowed disabled:opacity-50"
17
+ ],
18
+ {
19
+ variants: {
20
+ state: {
21
+ default: "",
22
+ error: "border-[var(--input-border-error)] focus-visible:ring-[var(--border-error)]"
23
+ },
24
+ inputSize: {
25
+ sm: "h-8 px-2 text-xs",
26
+ md: "h-10 px-3 text-sm",
27
+ lg: "h-12 px-4 text-base"
28
+ }
29
+ },
30
+ defaultVariants: {
31
+ state: "default",
32
+ inputSize: "md"
33
+ }
34
+ }
35
+ );
36
+ var selectChevronStyles = "pointer-events-none absolute right-3 top-1/2 size-4 -translate-y-1/2 text-[var(--text-secondary)]";
37
+ var Select = forwardRef(
38
+ ({ className, state, inputSize, label, hint, error, id: idProp, children, ...props }, ref) => {
39
+ const generatedId = useId();
40
+ const id = idProp ?? generatedId;
41
+ const resolvedState = error ? "error" : state;
42
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
43
+ label && /* @__PURE__ */ jsx("label", { htmlFor: id, children: /* @__PURE__ */ jsx(RichText, { as: "span", variant: "p3", className: inputLabelStyles, children: label }) }),
44
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
45
+ /* @__PURE__ */ jsx(
46
+ "select",
47
+ {
48
+ ref,
49
+ id,
50
+ "aria-describedby": error ? `${id}-error` : hint ? `${id}-hint` : void 0,
51
+ "aria-invalid": error ? "true" : void 0,
52
+ className: cn(selectStyles({ state: resolvedState, inputSize }), className),
53
+ ...props,
54
+ children
55
+ }
56
+ ),
57
+ /* @__PURE__ */ jsx(
58
+ "svg",
59
+ {
60
+ "aria-hidden": true,
61
+ viewBox: "0 0 24 24",
62
+ fill: "none",
63
+ stroke: "currentColor",
64
+ strokeWidth: 2,
65
+ strokeLinecap: "round",
66
+ strokeLinejoin: "round",
67
+ className: selectChevronStyles,
68
+ children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
69
+ }
70
+ )
71
+ ] }),
72
+ error && /* @__PURE__ */ jsx(
73
+ RichText,
74
+ {
75
+ as: "p",
76
+ id: `${id}-error`,
77
+ role: "alert",
78
+ variant: "p4",
79
+ className: inputErrorStyles,
80
+ children: error
81
+ }
82
+ ),
83
+ !error && hint && /* @__PURE__ */ jsx(RichText, { as: "p", id: `${id}-hint`, variant: "p4", className: inputHintStyles, children: hint })
84
+ ] });
85
+ }
86
+ );
87
+ Select.displayName = "Select";
88
+
89
+ export { Select };
90
+ //# sourceMappingURL=chunk-WUEVXL76.js.map
91
+ //# sourceMappingURL=chunk-WUEVXL76.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/atoms/Select/Select.styles.ts","../src/components/atoms/Select/Select.tsx"],"names":[],"mappings":"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","file":"chunk-WUEVXL76.js","sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const selectStyles = cva(\n [\n 'flex w-full appearance-none rounded-md bg-no-repeat pr-10',\n 'text-[var(--input-text)] bg-[var(--input-bg)]',\n 'border border-[var(--input-border)]',\n 'transition-colors duration-150 ease-in-out',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] focus-visible:ring-offset-0',\n 'focus-visible:border-[var(--input-border-focus)]',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n ],\n {\n variants: {\n state: {\n default: '',\n error: 'border-[var(--input-border-error)] focus-visible:ring-[var(--border-error)]',\n },\n inputSize: {\n sm: 'h-8 px-2 text-xs',\n md: 'h-10 px-3 text-sm',\n lg: 'h-12 px-4 text-base',\n },\n },\n defaultVariants: {\n state: 'default',\n inputSize: 'md',\n },\n },\n);\n\n/** Chevron drawn with `currentColor`, positioned over the right padding of the select. */\nexport const selectChevronStyles =\n 'pointer-events-none absolute right-3 top-1/2 size-4 -translate-y-1/2 text-[var(--text-secondary)]';\n","import { RichText } from '@components';\nimport { cn } from '@utils';\nimport type { VariantProps } from 'class-variance-authority';\nimport { forwardRef, useId, type SelectHTMLAttributes } from 'react';\nimport {\n inputErrorStyles,\n inputHintStyles,\n inputLabelStyles,\n} from '@components/atoms/Input/Input.styles';\nimport { selectChevronStyles, selectStyles } from './Select.styles';\n\nexport type SelectProps = SelectHTMLAttributes<HTMLSelectElement> &\n VariantProps<typeof selectStyles> & {\n label?: string;\n hint?: string;\n error?: string;\n };\n\n/**\n * A native `<select>` with the same label / hint / error contract and look as `Input`. Native on\n * purpose: it gets the platform picker on mobile, typeahead and full screen reader support for free.\n */\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(\n ({ className, state, inputSize, label, hint, error, id: idProp, children, ...props }, ref) => {\n const generatedId = useId();\n const id = idProp ?? generatedId;\n const resolvedState = error ? 'error' : state;\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <label htmlFor={id}>\n <RichText as=\"span\" variant=\"p3\" className={inputLabelStyles}>\n {label}\n </RichText>\n </label>\n )}\n <div className=\"relative\">\n <select\n ref={ref}\n id={id}\n aria-describedby={error ? `${id}-error` : hint ? `${id}-hint` : undefined}\n aria-invalid={error ? 'true' : undefined}\n className={cn(selectStyles({ state: resolvedState, inputSize }), className)}\n {...props}\n >\n {children}\n </select>\n <svg\n aria-hidden\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={selectChevronStyles}\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </div>\n {error && (\n <RichText\n as=\"p\"\n id={`${id}-error`}\n role=\"alert\"\n variant=\"p4\"\n className={inputErrorStyles}\n >\n {error}\n </RichText>\n )}\n {!error && hint && (\n <RichText as=\"p\" id={`${id}-hint`} variant=\"p4\" className={inputHintStyles}>\n {hint}\n </RichText>\n )}\n </div>\n );\n },\n);\n\nSelect.displayName = 'Select';\n"]}
@@ -1,4 +1,5 @@
1
- export { Button, buttonStyles } from '../../../chunk-DXJQNQ5K.js';
1
+ import '../../../chunk-GQMA2AQI.js';
2
+ export { Button, buttonStyles } from '../../../chunk-KL6I2JFC.js';
2
3
  import '../../../chunk-P4Z7HH66.js';
3
4
  import '../../../chunk-6LLGTBM6.js';
4
5
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,5 @@
1
- export { Input } from '../../../chunk-PVDRNAYK.js';
1
+ export { Input } from '../../../chunk-DP274HDM.js';
2
+ import '../../../chunk-FFKHEBQ7.js';
2
3
  import '../../../chunk-P4CV2EPR.js';
3
4
  import '../../../chunk-6LLGTBM6.js';
4
5
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,29 @@
1
+ import * as react from 'react';
2
+ import { SelectHTMLAttributes } from 'react';
3
+ import * as class_variance_authority_types from 'class-variance-authority/types';
4
+ import { VariantProps } from 'class-variance-authority';
5
+
6
+ declare const selectStyles: (props?: ({
7
+ state?: "error" | "default" | null | undefined;
8
+ inputSize?: "sm" | "md" | "lg" | null | undefined;
9
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
10
+
11
+ type SelectProps = SelectHTMLAttributes<HTMLSelectElement> & VariantProps<typeof selectStyles> & {
12
+ label?: string;
13
+ hint?: string;
14
+ error?: string;
15
+ };
16
+ /**
17
+ * A native `<select>` with the same label / hint / error contract and look as `Input`. Native on
18
+ * purpose: it gets the platform picker on mobile, typeahead and full screen reader support for free.
19
+ */
20
+ declare const Select: react.ForwardRefExoticComponent<SelectHTMLAttributes<HTMLSelectElement> & VariantProps<(props?: ({
21
+ state?: "error" | "default" | null | undefined;
22
+ inputSize?: "sm" | "md" | "lg" | null | undefined;
23
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & {
24
+ label?: string;
25
+ hint?: string;
26
+ error?: string;
27
+ } & react.RefAttributes<HTMLSelectElement>>;
28
+
29
+ export { Select, type SelectProps };
@@ -0,0 +1,6 @@
1
+ export { Select } from '../../../chunk-WUEVXL76.js';
2
+ import '../../../chunk-FFKHEBQ7.js';
3
+ import '../../../chunk-P4CV2EPR.js';
4
+ import '../../../chunk-6LLGTBM6.js';
5
+ //# sourceMappingURL=index.js.map
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,28 @@
1
+ import * as react from 'react';
2
+ import { TextareaHTMLAttributes } from 'react';
3
+ import * as class_variance_authority_types from 'class-variance-authority/types';
4
+ import { VariantProps } from 'class-variance-authority';
5
+
6
+ declare const textareaStyles: (props?: ({
7
+ state?: "error" | "default" | null | undefined;
8
+ inputSize?: "sm" | "md" | "lg" | null | undefined;
9
+ resize?: "none" | "vertical" | null | undefined;
10
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
11
+
12
+ type TextareaProps = TextareaHTMLAttributes<HTMLTextAreaElement> & VariantProps<typeof textareaStyles> & {
13
+ label?: string;
14
+ hint?: string;
15
+ error?: string;
16
+ };
17
+ /** Multi-line text entry with the same label / hint / error contract and look as `Input`. */
18
+ declare const Textarea: react.ForwardRefExoticComponent<TextareaHTMLAttributes<HTMLTextAreaElement> & VariantProps<(props?: ({
19
+ state?: "error" | "default" | null | undefined;
20
+ inputSize?: "sm" | "md" | "lg" | null | undefined;
21
+ resize?: "none" | "vertical" | null | undefined;
22
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & {
23
+ label?: string;
24
+ hint?: string;
25
+ error?: string;
26
+ } & react.RefAttributes<HTMLTextAreaElement>>;
27
+
28
+ export { Textarea, type TextareaProps };
@@ -0,0 +1,6 @@
1
+ export { Textarea } from '../../../chunk-3YRDRHO3.js';
2
+ import '../../../chunk-FFKHEBQ7.js';
3
+ import '../../../chunk-P4CV2EPR.js';
4
+ import '../../../chunk-6LLGTBM6.js';
5
+ //# sourceMappingURL=index.js.map
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -1,6 +1,8 @@
1
- export { BottomSheet } from '../../../chunk-ZEGQFAYE.js';
2
- import '../../../chunk-JCJP427C.js';
1
+ export { BottomSheet } from '../../../chunk-RRIE5LFQ.js';
3
2
  import '../../../chunk-BNEEI7S5.js';
3
+ import '../../../chunk-JCJP427C.js';
4
+ import '../../../chunk-QT62VC36.js';
5
+ import '../../../chunk-53YMHM24.js';
4
6
  import '../../../chunk-P4Z7HH66.js';
5
7
  import '../../../chunk-P4CV2EPR.js';
6
8
  import '../../../chunk-6LLGTBM6.js';
@@ -0,0 +1,44 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+ import * as class_variance_authority_types from 'class-variance-authority/types';
4
+ import { VariantProps } from 'class-variance-authority';
5
+
6
+ declare const drawerPanelStyles: (props?: ({
7
+ side?: "left" | "right" | null | undefined;
8
+ visible?: boolean | null | undefined;
9
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
10
+
11
+ type DrawerProps = Omit<HTMLAttributes<HTMLDivElement>, 'title'> & Pick<VariantProps<typeof drawerPanelStyles>, 'side'> & {
12
+ open: boolean;
13
+ onClose: () => void;
14
+ title?: ReactNode;
15
+ /** Extra classes for the title (e.g. a display font). */
16
+ titleClassName?: string;
17
+ /** Accessible name of the close button; the button is only rendered when this is set. */
18
+ closeLabel?: string;
19
+ /** Pinned to the bottom of the panel (preferences, actions). */
20
+ footer?: ReactNode;
21
+ closeOnBackdropClick?: boolean;
22
+ };
23
+ /**
24
+ * A side panel (navigation menus, filters, settings) that slides in from the left or right.
25
+ * Modal dialog semantics: focus moves inside and is trapped, Escape and backdrop clicks close it,
26
+ * the page behind doesn't scroll, and focus returns to the trigger when it closes.
27
+ */
28
+ declare const Drawer: react.ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "title"> & Pick<VariantProps<(props?: ({
29
+ side?: "left" | "right" | null | undefined;
30
+ visible?: boolean | null | undefined;
31
+ } & class_variance_authority_types.ClassProp) | undefined) => string>, "side"> & {
32
+ open: boolean;
33
+ onClose: () => void;
34
+ title?: ReactNode;
35
+ /** Extra classes for the title (e.g. a display font). */
36
+ titleClassName?: string;
37
+ /** Accessible name of the close button; the button is only rendered when this is set. */
38
+ closeLabel?: string;
39
+ /** Pinned to the bottom of the panel (preferences, actions). */
40
+ footer?: ReactNode;
41
+ closeOnBackdropClick?: boolean;
42
+ } & react.RefAttributes<HTMLDivElement>>;
43
+
44
+ export { Drawer, type DrawerProps };
@@ -0,0 +1,11 @@
1
+ export { Drawer } from '../../../chunk-CX3GARWU.js';
2
+ import '../../../chunk-BNEEI7S5.js';
3
+ import '../../../chunk-JCJP427C.js';
4
+ import '../../../chunk-QT62VC36.js';
5
+ import '../../../chunk-53YMHM24.js';
6
+ import '../../../chunk-KL6I2JFC.js';
7
+ import '../../../chunk-P4Z7HH66.js';
8
+ import '../../../chunk-P4CV2EPR.js';
9
+ import '../../../chunk-6LLGTBM6.js';
10
+ //# sourceMappingURL=index.js.map
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -1,6 +1,8 @@
1
- export { Modal } from '../../../chunk-CJ4LRU6X.js';
2
- import '../../../chunk-JCJP427C.js';
1
+ export { Modal } from '../../../chunk-A26UWAU4.js';
3
2
  import '../../../chunk-BNEEI7S5.js';
3
+ import '../../../chunk-JCJP427C.js';
4
+ import '../../../chunk-QT62VC36.js';
5
+ import '../../../chunk-53YMHM24.js';
4
6
  import '../../../chunk-P4Z7HH66.js';
5
7
  import '../../../chunk-P4CV2EPR.js';
6
8
  import '../../../chunk-6LLGTBM6.js';
@@ -0,0 +1,9 @@
1
+ import { RefObject } from 'react';
2
+
3
+ /**
4
+ * While `active`, keeps Tab / Shift+Tab inside `containerRef`, moves focus into it, and returns
5
+ * focus to the previously focused element when it deactivates (WCAG dialog pattern).
6
+ */
7
+ declare const useFocusTrap: (active: boolean, containerRef: RefObject<HTMLElement | null>) => void;
8
+
9
+ export { useFocusTrap };
@@ -0,0 +1,3 @@
1
+ export { useFocusTrap } from '../../chunk-QT62VC36.js';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,4 @@
1
+ /** Prevents the page behind an open overlay from scrolling; restores the previous value on release. */
2
+ declare const useScrollLock: (active: boolean) => void;
3
+
4
+ export { useScrollLock };
@@ -0,0 +1,3 @@
1
+ export { useScrollLock } from '../../chunk-53YMHM24.js';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
package/dist/index.d.ts CHANGED
@@ -4,18 +4,23 @@ export { Image, ImageProps } from './components/atoms/Image/index.js';
4
4
  export { Input, InputProps } from './components/atoms/Input/index.js';
5
5
  export { Link, LinkProps } from './components/atoms/Link/index.js';
6
6
  export { RichText, RichTextProps, RichTextVariant, elementByVariant } from './components/atoms/RichText/index.js';
7
+ export { Select, SelectProps } from './components/atoms/Select/index.js';
7
8
  export { Switch, SwitchProps } from './components/atoms/Switch/index.js';
9
+ export { Textarea, TextareaProps } from './components/atoms/Textarea/index.js';
8
10
  export { BottomSheet, BottomSheetProps } from './components/molecules/BottomSheet/index.js';
9
11
  export { BreadcrumbItem, Breadcrumbs, BreadcrumbsProps } from './components/molecules/Breadcrumbs/index.js';
10
12
  export { Card, CardContent, CardContentProps, CardDescription, CardDescriptionProps, CardFooter, CardFooterProps, CardHeader, CardHeaderProps, CardProps, CardTitle, CardTitleProps } from './components/molecules/Card/index.js';
13
+ export { Drawer, DrawerProps } from './components/molecules/Drawer/index.js';
11
14
  export { Language, LanguageOption, LanguageProps } from './components/molecules/Language/index.js';
12
15
  export { Modal, ModalProps } from './components/molecules/Modal/index.js';
13
16
  export { Snackbar, SnackbarProps } from './components/molecules/Snackbar/index.js';
14
17
  export { Timeline, TimelineItem, TimelineProps } from './components/molecules/Timeline/index.js';
15
18
  export { useDelayedUnmount } from './hooks/useDelayedUnmount/index.js';
16
19
  export { useDismissableLayer } from './hooks/useDismissableLayer/index.js';
20
+ export { useFocusTrap } from './hooks/useFocusTrap/index.js';
17
21
  export { useMediaQuery } from './hooks/useMediaQuery/index.js';
18
22
  export { useMergedRef } from './hooks/useMergedRef/index.js';
23
+ export { useScrollLock } from './hooks/useScrollLock/index.js';
19
24
  export { cn } from './utils/cn/index.js';
20
25
  import 'react';
21
26
  import 'class-variance-authority/types';
package/dist/index.js CHANGED
@@ -1,20 +1,27 @@
1
+ export { Snackbar } from './chunk-BKPP4D3Q.js';
2
+ export { Timeline } from './chunk-UL33H4AD.js';
1
3
  export { useMediaQuery } from './chunk-2HCMNEIQ.js';
2
- export { BottomSheet } from './chunk-ZEGQFAYE.js';
4
+ export { Switch } from './chunk-ZABQF65Z.js';
5
+ export { Textarea } from './chunk-3YRDRHO3.js';
6
+ export { BottomSheet } from './chunk-RRIE5LFQ.js';
3
7
  export { Breadcrumbs } from './chunk-PE6XEC7Y.js';
4
8
  export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-N5CLCKR3.js';
9
+ export { Drawer } from './chunk-CX3GARWU.js';
5
10
  export { Language } from './chunk-2YBZCUME.js';
6
- export { Modal } from './chunk-CJ4LRU6X.js';
7
- export { useDismissableLayer } from './chunk-JCJP427C.js';
8
- export { Snackbar } from './chunk-BKPP4D3Q.js';
9
- export { Timeline } from './chunk-UL33H4AD.js';
11
+ export { Modal } from './chunk-A26UWAU4.js';
10
12
  export { useDelayedUnmount } from './chunk-BNEEI7S5.js';
11
- export { Button, buttonStyles } from './chunk-DXJQNQ5K.js';
13
+ export { useDismissableLayer } from './chunk-JCJP427C.js';
14
+ export { useFocusTrap } from './chunk-QT62VC36.js';
15
+ export { useScrollLock } from './chunk-53YMHM24.js';
16
+ import './chunk-GQMA2AQI.js';
17
+ export { Button, buttonStyles } from './chunk-KL6I2JFC.js';
12
18
  export { useMergedRef } from './chunk-P4Z7HH66.js';
13
19
  export { Icon } from './chunk-7HQFLM4A.js';
14
20
  export { Image } from './chunk-5IHM2545.js';
15
- export { Input } from './chunk-PVDRNAYK.js';
21
+ export { Input } from './chunk-DP274HDM.js';
16
22
  export { Link } from './chunk-D4I5OF3C.js';
17
- export { Switch } from './chunk-ZABQF65Z.js';
23
+ export { Select } from './chunk-WUEVXL76.js';
24
+ import './chunk-FFKHEBQ7.js';
18
25
  export { RichText, elementByVariant } from './chunk-P4CV2EPR.js';
19
26
  export { cn } from './chunk-6LLGTBM6.js';
20
27
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inzumer/ui-library",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "private": false,
5
5
  "description": "React UI component library for the Inzumer design system",
6
6
  "license": "MIT",
@@ -56,10 +56,18 @@
56
56
  "types": "./dist/components/atoms/RichText/index.d.ts",
57
57
  "import": "./dist/components/atoms/RichText/index.js"
58
58
  },
59
+ "./select": {
60
+ "types": "./dist/components/atoms/Select/index.d.ts",
61
+ "import": "./dist/components/atoms/Select/index.js"
62
+ },
59
63
  "./switch": {
60
64
  "types": "./dist/components/atoms/Switch/index.d.ts",
61
65
  "import": "./dist/components/atoms/Switch/index.js"
62
66
  },
67
+ "./textarea": {
68
+ "types": "./dist/components/atoms/Textarea/index.d.ts",
69
+ "import": "./dist/components/atoms/Textarea/index.js"
70
+ },
63
71
  "./bottom-sheet": {
64
72
  "types": "./dist/components/molecules/BottomSheet/index.d.ts",
65
73
  "import": "./dist/components/molecules/BottomSheet/index.js"
@@ -72,6 +80,10 @@
72
80
  "types": "./dist/components/molecules/Card/index.d.ts",
73
81
  "import": "./dist/components/molecules/Card/index.js"
74
82
  },
83
+ "./drawer": {
84
+ "types": "./dist/components/molecules/Drawer/index.d.ts",
85
+ "import": "./dist/components/molecules/Drawer/index.js"
86
+ },
75
87
  "./language": {
76
88
  "types": "./dist/components/molecules/Language/index.d.ts",
77
89
  "import": "./dist/components/molecules/Language/index.js"
@@ -96,6 +108,10 @@
96
108
  "types": "./dist/hooks/useDismissableLayer/index.d.ts",
97
109
  "import": "./dist/hooks/useDismissableLayer/index.js"
98
110
  },
111
+ "./use-focus-trap": {
112
+ "types": "./dist/hooks/useFocusTrap/index.d.ts",
113
+ "import": "./dist/hooks/useFocusTrap/index.js"
114
+ },
99
115
  "./use-media-query": {
100
116
  "types": "./dist/hooks/useMediaQuery/index.d.ts",
101
117
  "import": "./dist/hooks/useMediaQuery/index.js"
@@ -104,6 +120,10 @@
104
120
  "types": "./dist/hooks/useMergedRef/index.d.ts",
105
121
  "import": "./dist/hooks/useMergedRef/index.js"
106
122
  },
123
+ "./use-scroll-lock": {
124
+ "types": "./dist/hooks/useScrollLock/index.d.ts",
125
+ "import": "./dist/hooks/useScrollLock/index.js"
126
+ },
107
127
  "./cn": {
108
128
  "types": "./dist/utils/cn/index.d.ts",
109
129
  "import": "./dist/utils/cn/index.js"
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/molecules/Modal/Modal.styles.ts","../src/components/molecules/Modal/Modal.tsx"],"names":[],"mappings":";;;;;;;;;AAEO,IAAM,kBAAA,GAAqB,GAAA;AAAA,EAChC;AAAA,IACE,qFAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ,CAAA;AAEO,IAAM,gBAAA,GAAmB,GAAA;AAAA,EAC9B;AAAA,IACE,8GAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,uBAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ,CAAA;AAEO,IAAM,gBAAA,GAAmB,uDAAA;AAEzB,IAAM,iBAAA,GAAoB,0CAAA;AC7BjC,IAAM,gBAAA,GAAmB,GAAA;AAUlB,IAAM,KAAA,GAAQ,UAAA;AAAA,EACnB,CACE,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,MAAA,EAAQ,oBAAA,GAAuB,IAAA,EAAM,SAAA,EAAW,QAAA,EAAU,GAAG,KAAA,IACrF,GAAA,KACG;AACH,IAAA,MAAM,QAAA,GAAW,OAA8B,IAAI,CAAA;AACnD,IAAA,MAAM,WAAA,GAAc,YAAA,CAAa,GAAA,EAAK,QAAQ,CAAA;AAC9C,IAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAQ,GAAI,iBAAA,CAAkB,MAAM,gBAAgB,CAAA;AAErE,IAAA,mBAAA,CAAoB,IAAA,EAAM,OAAA,EAAS,QAAA,EAAU,oBAAoB,CAAA;AAEjE,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,2BACG,KAAA,EAAA,EAAI,SAAA,EAAW,mBAAmB,EAAE,OAAA,EAAS,CAAA,EAC5C,QAAA,kBAAA,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,WAAA;AAAA,QACL,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAW,MAAA;AAAA,QACX,iBAAA,EAAiB,QAAQ,aAAA,GAAgB,MAAA;AAAA,QACzC,WAAW,EAAA,CAAG,gBAAA,CAAiB,EAAE,OAAA,EAAS,GAAG,SAAS,CAAA;AAAA,QACrD,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,KAAA,oBACC,GAAA,CAAC,QAAA,EAAA,EAAS,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,eAAc,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,gBAAA,EACxD,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,UAED,QAAA;AAAA,UACA,MAAA,oBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,mBAAoB,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA;AAAA,KACxD,EACF,CAAA;AAAA,EAEJ;AACF;AAEA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-CJ4LRU6X.js","sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const modalOverlayStyles = cva(\n [\n 'fixed inset-0 z-50 flex items-center justify-center bg-[var(--surface-overlay)] p-4',\n 'transition-opacity duration-200 ease-out',\n ],\n {\n variants: {\n visible: {\n true: 'opacity-100',\n false: 'opacity-0',\n },\n },\n defaultVariants: {\n visible: false,\n },\n },\n);\n\nexport const modalPanelStyles = cva(\n [\n 'w-full max-w-md rounded-xl border border-[var(--border-default)] bg-[var(--surface-secondary)] p-6 shadow-lg',\n 'transition-all duration-200 ease-out',\n ],\n {\n variants: {\n visible: {\n true: 'scale-100 opacity-100',\n false: 'scale-95 opacity-0',\n },\n },\n defaultVariants: {\n visible: false,\n },\n },\n);\n\nexport const modalTitleStyles = 'mb-4 text-lg font-semibold text-[var(--text-primary)]';\n\nexport const modalFooterStyles = 'mt-6 flex items-center justify-end gap-2';\n","import { forwardRef, useRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { RichText } from '@components';\nimport { useDelayedUnmount, useDismissableLayer, useMergedRef } from '@hooks';\nimport { cn } from '@utils';\nimport {\n modalFooterStyles,\n modalOverlayStyles,\n modalPanelStyles,\n modalTitleStyles,\n} from './Modal.styles';\n\nconst EXIT_DURATION_MS = 200;\n\nexport type ModalProps = Omit<HTMLAttributes<HTMLDivElement>, 'title'> & {\n open: boolean;\n onClose: () => void;\n title?: ReactNode;\n footer?: ReactNode;\n closeOnBackdropClick?: boolean;\n};\n\nexport const Modal = forwardRef<HTMLDivElement, ModalProps>(\n (\n { open, onClose, title, footer, closeOnBackdropClick = true, className, children, ...props },\n ref,\n ) => {\n const panelRef = useRef<HTMLDivElement | null>(null);\n const setPanelRef = useMergedRef(ref, panelRef);\n const { mounted, visible } = useDelayedUnmount(open, EXIT_DURATION_MS);\n\n useDismissableLayer(open, onClose, panelRef, closeOnBackdropClick);\n\n if (!mounted) {\n return null;\n }\n\n return (\n <div className={modalOverlayStyles({ visible })}>\n <div\n ref={setPanelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? 'modal-title' : undefined}\n className={cn(modalPanelStyles({ visible }), className)}\n {...props}\n >\n {title && (\n <RichText as=\"h2\" id=\"modal-title\" variant=\"s1\" className={modalTitleStyles}>\n {title}\n </RichText>\n )}\n {children}\n {footer && <div className={modalFooterStyles}>{footer}</div>}\n </div>\n </div>\n );\n },\n);\n\nModal.displayName = 'Modal';\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/atoms/Input/Input.styles.ts","../src/components/atoms/Input/Input.tsx"],"names":[],"mappings":";;;;;;AAEO,IAAM,WAAA,GAAc,GAAA;AAAA,EACzB;AAAA,IACE,kCAAA;AAAA,IACA,kCAAA;AAAA,IACA,sBAAA;AAAA,IACA,qCAAA;AAAA,IACA,6CAAA;AAAA,IACA,4CAAA;AAAA,IACA,sHAAA;AAAA,IACA,kDAAA;AAAA,IACA,iDAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,EAAA;AAAA,QACT,KAAA,EAAO;AAAA,OACT;AAAA,MACA,SAAA,EAAW;AAAA,QACT,EAAA,EAAI,kBAAA;AAAA,QACJ,EAAA,EAAI,mBAAA;AAAA,QACJ,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,KAAA,EAAO,SAAA;AAAA,MACP,SAAA,EAAW;AAAA;AACb;AAEJ,CAAA;AAEO,IAAM,gBAAA,GAAmB,gDAAA;AACzB,IAAM,gBAAA,GAAmB,oCAAA;AACzB,IAAM,eAAA,GAAkB,sCAAA;AClBxB,IAAM,KAAA,GAAQ,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,SAAA,EAAW,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,EAAA,EAAI,MAAA,EAAQ,GAAG,KAAA,IAAS,GAAA,KAAQ;AAClF,IAAA,MAAM,cAAc,KAAA,EAAM;AAC1B,IAAA,MAAM,KAAK,MAAA,IAAU,WAAA;AACrB,IAAA,MAAM,aAAA,GAAgB,QAAQ,OAAA,GAAU,KAAA;AAExC,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EACZ,QAAA,EAAA;AAAA,MAAA,KAAA,oBACC,GAAA,CAAC,OAAA,EAAA,EAAM,OAAA,EAAS,EAAA,EACd,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,EAAA,EAAG,MAAA,EAAO,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,gBAAA,EACzC,iBACH,CAAA,EACF,CAAA;AAAA,sBAEF,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,EAAA;AAAA,UACA,kBAAA,EAAkB,QAAQ,CAAA,EAAG,EAAE,WAAW,IAAA,GAAO,CAAA,EAAG,EAAE,CAAA,KAAA,CAAA,GAAU,MAAA;AAAA,UAChE,cAAA,EAAc,QAAQ,MAAA,GAAS,MAAA;AAAA,UAC/B,SAAA,EAAW,GAAG,WAAA,CAAY,EAAE,OAAO,aAAA,EAAe,SAAA,EAAW,CAAA,EAAG,SAAS,CAAA;AAAA,UACxE,GAAG;AAAA;AAAA,OACN;AAAA,MACC,KAAA,oBACC,GAAA,CAAC,QAAA,EAAA,EAAS,EAAA,EAAG,KAAI,EAAA,EAAI,CAAA,EAAG,EAAE,CAAA,MAAA,CAAA,EAAU,MAAK,OAAA,EAAQ,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,kBACtE,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,MAED,CAAC,KAAA,IAAS,IAAA,oBACT,GAAA,CAAC,YAAS,EAAA,EAAG,GAAA,EAAI,EAAA,EAAI,CAAA,EAAG,EAAE,CAAA,KAAA,CAAA,EAAS,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,iBACxD,QAAA,EAAA,IAAA,EACH;AAAA,KAAA,EAEJ,CAAA;AAAA,EAEJ;AACF;AAEA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-PVDRNAYK.js","sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const inputStyles = cva(\n [\n 'flex w-full rounded-md px-3 py-2',\n 'text-sm text-[var(--input-text)]',\n 'bg-[var(--input-bg)]',\n 'border border-[var(--input-border)]',\n 'placeholder:text-[var(--input-placeholder)]',\n 'transition-colors duration-150 ease-in-out',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] focus-visible:ring-offset-0',\n 'focus-visible:border-[var(--input-border-focus)]',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'file:border-0 file:bg-transparent file:text-sm file:font-medium',\n ],\n {\n variants: {\n state: {\n default: '',\n error: 'border-[var(--input-border-error)] focus-visible:ring-[var(--border-error)]',\n },\n inputSize: {\n sm: 'h-8 px-2 text-xs',\n md: 'h-10 px-3 text-sm',\n lg: 'h-12 px-4 text-base',\n },\n },\n defaultVariants: {\n state: 'default',\n inputSize: 'md',\n },\n },\n);\n\nexport const inputLabelStyles = 'text-sm font-medium text-[var(--text-primary)]';\nexport const inputErrorStyles = 'text-xs text-[var(--border-error)]';\nexport const inputHintStyles = 'text-xs text-[var(--text-secondary)]';\n","import type { VariantProps } from 'class-variance-authority';\nimport { forwardRef, useId, type InputHTMLAttributes } from 'react';\nimport { RichText } from '@components';\nimport { cn } from '@utils';\nimport {\n inputErrorStyles,\n inputHintStyles,\n inputLabelStyles,\n inputStyles,\n} from './Input.styles';\n\nexport type InputProps = InputHTMLAttributes<HTMLInputElement> &\n VariantProps<typeof inputStyles> & {\n label?: string;\n hint?: string;\n error?: string;\n };\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n ({ className, state, inputSize, label, hint, error, id: idProp, ...props }, ref) => {\n const generatedId = useId();\n const id = idProp ?? generatedId;\n const resolvedState = error ? 'error' : state;\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <label htmlFor={id}>\n <RichText as=\"span\" variant=\"p3\" className={inputLabelStyles}>\n {label}\n </RichText>\n </label>\n )}\n <input\n ref={ref}\n id={id}\n aria-describedby={error ? `${id}-error` : hint ? `${id}-hint` : undefined}\n aria-invalid={error ? 'true' : undefined}\n className={cn(inputStyles({ state: resolvedState, inputSize }), className)}\n {...props}\n />\n {error && (\n <RichText as=\"p\" id={`${id}-error`} role=\"alert\" variant=\"p4\" className={inputErrorStyles}>\n {error}\n </RichText>\n )}\n {!error && hint && (\n <RichText as=\"p\" id={`${id}-hint`} variant=\"p4\" className={inputHintStyles}>\n {hint}\n </RichText>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = 'Input';\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/molecules/BottomSheet/BottomSheet.styles.ts","../src/components/molecules/BottomSheet/BottomSheet.tsx"],"names":[],"mappings":";;;;;;;;;AAEO,IAAM,wBAAA,GAA2B,GAAA;AAAA,EACtC;AAAA,IACE,8EAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ,CAAA;AAEO,IAAM,sBAAA,GAAyB,GAAA;AAAA,EACpC;AAAA,IACE,+EAAA;AAAA,IACA,6CAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,eAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ,CAAA;AAEO,IAAM,uBAAA,GACX,gEAAA;AAEK,IAAM,sBAAA,GAAyB,uDAAA;AAE/B,IAAM,uBAAA,GAA0B,0CAAA;AChCvC,IAAM,gBAAA,GAAmB,GAAA;AAUlB,IAAM,WAAA,GAAc,UAAA;AAAA,EACzB,CACE,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,MAAA,EAAQ,oBAAA,GAAuB,IAAA,EAAM,SAAA,EAAW,QAAA,EAAU,GAAG,KAAA,IACrF,GAAA,KACG;AACH,IAAA,MAAM,QAAA,GAAW,OAA8B,IAAI,CAAA;AACnD,IAAA,MAAM,WAAA,GAAc,YAAA,CAAa,GAAA,EAAK,QAAQ,CAAA;AAC9C,IAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAQ,GAAI,iBAAA,CAAkB,MAAM,gBAAgB,CAAA;AAErE,IAAA,mBAAA,CAAoB,IAAA,EAAM,OAAA,EAAS,QAAA,EAAU,oBAAoB,CAAA;AAEjE,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,2BACG,KAAA,EAAA,EAAI,SAAA,EAAW,yBAAyB,EAAE,OAAA,EAAS,CAAA,EAClD,QAAA,kBAAA,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,WAAA;AAAA,QACL,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAW,MAAA;AAAA,QACX,iBAAA,EAAiB,QAAQ,oBAAA,GAAuB,MAAA;AAAA,QAChD,WAAW,EAAA,CAAG,sBAAA,CAAuB,EAAE,OAAA,EAAS,GAAG,SAAS,CAAA;AAAA,QAC3D,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,KAAA,EAAA,EAAI,aAAA,EAAW,IAAA,EAAC,SAAA,EAAW,uBAAA,EAAyB,CAAA;AAAA,UACpD,KAAA,oBACC,GAAA,CAAC,QAAA,EAAA,EAAS,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,oBAAA,EAAqB,OAAA,EAAQ,IAAA,EAAK,SAAA,EAAW,sBAAA,EAC/D,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,UAED,QAAA;AAAA,UACA,MAAA,oBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,yBAA0B,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA;AAAA,KAC9D,EACF,CAAA;AAAA,EAEJ;AACF;AAEA,WAAA,CAAY,WAAA,GAAc,aAAA","file":"chunk-ZEGQFAYE.js","sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const bottomSheetOverlayStyles = cva(\n [\n 'fixed inset-0 z-50 flex items-end justify-center bg-[var(--surface-overlay)]',\n 'transition-opacity duration-200 ease-out',\n ],\n {\n variants: {\n visible: {\n true: 'opacity-100',\n false: 'opacity-0',\n },\n },\n defaultVariants: {\n visible: false,\n },\n },\n);\n\nexport const bottomSheetPanelStyles = cva(\n [\n 'w-full max-w-md rounded-t-xl border border-b-0 border-[var(--border-default)]',\n 'bg-[var(--surface-secondary)] p-6 shadow-lg',\n 'transition-transform duration-200 ease-out',\n ],\n {\n variants: {\n visible: {\n true: 'translate-y-0',\n false: 'translate-y-full',\n },\n },\n defaultVariants: {\n visible: false,\n },\n },\n);\n\nexport const bottomSheetHandleStyles =\n 'mx-auto mb-4 h-1.5 w-10 rounded-full bg-[var(--border-strong)]';\n\nexport const bottomSheetTitleStyles = 'mb-4 text-lg font-semibold text-[var(--text-primary)]';\n\nexport const bottomSheetFooterStyles = 'mt-6 flex items-center justify-end gap-2';\n","import { forwardRef, useRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { RichText } from '@components';\nimport { useDelayedUnmount, useDismissableLayer, useMergedRef } from '@hooks';\nimport { cn } from '@utils';\nimport {\n bottomSheetFooterStyles,\n bottomSheetHandleStyles,\n bottomSheetOverlayStyles,\n bottomSheetPanelStyles,\n bottomSheetTitleStyles,\n} from './BottomSheet.styles';\n\nconst EXIT_DURATION_MS = 200;\n\nexport type BottomSheetProps = Omit<HTMLAttributes<HTMLDivElement>, 'title'> & {\n open: boolean;\n onClose: () => void;\n title?: ReactNode;\n footer?: ReactNode;\n closeOnBackdropClick?: boolean;\n};\n\nexport const BottomSheet = forwardRef<HTMLDivElement, BottomSheetProps>(\n (\n { open, onClose, title, footer, closeOnBackdropClick = true, className, children, ...props },\n ref,\n ) => {\n const panelRef = useRef<HTMLDivElement | null>(null);\n const setPanelRef = useMergedRef(ref, panelRef);\n const { mounted, visible } = useDelayedUnmount(open, EXIT_DURATION_MS);\n\n useDismissableLayer(open, onClose, panelRef, closeOnBackdropClick);\n\n if (!mounted) {\n return null;\n }\n\n return (\n <div className={bottomSheetOverlayStyles({ visible })}>\n <div\n ref={setPanelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? 'bottom-sheet-title' : undefined}\n className={cn(bottomSheetPanelStyles({ visible }), className)}\n {...props}\n >\n <div aria-hidden className={bottomSheetHandleStyles} />\n {title && (\n <RichText as=\"h2\" id=\"bottom-sheet-title\" variant=\"s1\" className={bottomSheetTitleStyles}>\n {title}\n </RichText>\n )}\n {children}\n {footer && <div className={bottomSheetFooterStyles}>{footer}</div>}\n </div>\n </div>\n );\n },\n);\n\nBottomSheet.displayName = 'BottomSheet';\n"]}