@inzumer/ui-library 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-PVDRNAYK.js → chunk-3YRDRHO3.js} +33 -22
- package/dist/chunk-3YRDRHO3.js.map +1 -0
- package/dist/chunk-53YMHM24.js +20 -0
- package/dist/chunk-53YMHM24.js.map +1 -0
- package/dist/chunk-DP274HDM.js +34 -0
- package/dist/chunk-DP274HDM.js.map +1 -0
- package/dist/chunk-FFKHEBQ7.js +41 -0
- package/dist/chunk-FFKHEBQ7.js.map +1 -0
- package/dist/chunk-GQMA2AQI.js +3 -0
- package/dist/chunk-GQMA2AQI.js.map +1 -0
- package/dist/{chunk-DXJQNQ5K.js → chunk-KL6I2JFC.js} +3 -3
- package/dist/{chunk-DXJQNQ5K.js.map → chunk-KL6I2JFC.js.map} +1 -1
- package/dist/chunk-NKNSSH2Q.js +142 -0
- package/dist/chunk-NKNSSH2Q.js.map +1 -0
- package/dist/{chunk-ZEGQFAYE.js → chunk-PF5PSCG4.js} +12 -6
- package/dist/chunk-PF5PSCG4.js.map +1 -0
- package/dist/chunk-QT62VC36.js +50 -0
- package/dist/chunk-QT62VC36.js.map +1 -0
- package/dist/{chunk-CJ4LRU6X.js → chunk-SMKLV4ET.js} +12 -6
- package/dist/chunk-SMKLV4ET.js.map +1 -0
- package/dist/chunk-V3YXRI7M.js +41 -0
- package/dist/chunk-V3YXRI7M.js.map +1 -0
- package/dist/chunk-WUEVXL76.js +91 -0
- package/dist/chunk-WUEVXL76.js.map +1 -0
- package/dist/chunk-XCUA543I.js +59 -0
- package/dist/chunk-XCUA543I.js.map +1 -0
- package/dist/components/atoms/Button/index.js +2 -1
- package/dist/components/atoms/Input/index.js +2 -1
- package/dist/components/atoms/Select/index.d.ts +29 -0
- package/dist/components/atoms/Select/index.js +6 -0
- package/dist/components/atoms/Select/index.js.map +1 -0
- package/dist/components/atoms/Textarea/index.d.ts +28 -0
- package/dist/components/atoms/Textarea/index.js +6 -0
- package/dist/components/atoms/Textarea/index.js.map +1 -0
- package/dist/components/molecules/Accordion/index.d.ts +26 -0
- package/dist/components/molecules/Accordion/index.js +4 -0
- package/dist/components/molecules/Accordion/index.js.map +1 -0
- package/dist/components/molecules/BottomSheet/index.js +4 -2
- package/dist/components/molecules/Drawer/index.d.ts +44 -0
- package/dist/components/molecules/Drawer/index.js +11 -0
- package/dist/components/molecules/Drawer/index.js.map +1 -0
- package/dist/components/molecules/Modal/index.js +4 -2
- package/dist/components/molecules/Table/index.d.ts +39 -0
- package/dist/components/molecules/Table/index.js +4 -0
- package/dist/components/molecules/Table/index.js.map +1 -0
- package/dist/hooks/useFocusTrap/index.d.ts +9 -0
- package/dist/hooks/useFocusTrap/index.js +3 -0
- package/dist/hooks/useFocusTrap/index.js.map +1 -0
- package/dist/hooks/useScrollLock/index.d.ts +4 -0
- package/dist/hooks/useScrollLock/index.js +3 -0
- package/dist/hooks/useScrollLock/index.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +18 -9
- package/package.json +29 -1
- package/dist/chunk-CJ4LRU6X.js.map +0 -1
- package/dist/chunk-PVDRNAYK.js.map +0 -1
- 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
|
|
8
|
+
var textareaStyles = cva(
|
|
8
9
|
[
|
|
9
|
-
"flex w-full rounded-md px-3 py-2",
|
|
10
|
-
"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: "
|
|
28
|
-
md: "
|
|
29
|
-
lg: "
|
|
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
|
|
39
|
-
|
|
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
|
-
"
|
|
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(
|
|
56
|
+
className: cn(textareaStyles({ state: resolvedState, inputSize, resize }), className),
|
|
56
57
|
...props
|
|
57
58
|
}
|
|
58
59
|
),
|
|
59
|
-
error && /* @__PURE__ */ jsx(
|
|
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
|
-
|
|
75
|
+
Textarea.displayName = "Textarea";
|
|
65
76
|
|
|
66
|
-
export {
|
|
67
|
-
//# sourceMappingURL=chunk-
|
|
68
|
-
//# sourceMappingURL=chunk-
|
|
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"]}
|
|
@@ -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 @@
|
|
|
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-
|
|
107
|
-
//# sourceMappingURL=chunk-
|
|
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-
|
|
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,142 @@
|
|
|
1
|
+
import { useScrollLock } from './chunk-53YMHM24.js';
|
|
2
|
+
import { useDelayedUnmount } from './chunk-BNEEI7S5.js';
|
|
3
|
+
import { useDismissableLayer } from './chunk-JCJP427C.js';
|
|
4
|
+
import { useFocusTrap } from './chunk-QT62VC36.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-NKNSSH2Q.js.map
|
|
142
|
+
//# sourceMappingURL=chunk-NKNSSH2Q.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-NKNSSH2Q.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"]}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useScrollLock } from './chunk-53YMHM24.js';
|
|
2
2
|
import { useDelayedUnmount } from './chunk-BNEEI7S5.js';
|
|
3
|
+
import { useDismissableLayer } from './chunk-JCJP427C.js';
|
|
4
|
+
import { useFocusTrap } from './chunk-QT62VC36.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 ?
|
|
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:
|
|
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-
|
|
81
|
-
//# sourceMappingURL=chunk-
|
|
86
|
+
//# sourceMappingURL=chunk-PF5PSCG4.js.map
|
|
87
|
+
//# sourceMappingURL=chunk-PF5PSCG4.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-PF5PSCG4.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,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"]}
|