@dododog/ui 0.15.0 → 0.17.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-L7OYR6U3.js → chunk-2NMA3AXV.js} +37 -8
- package/dist/{chunk-ZZ4EWC53.mjs → chunk-52M2KUC4.mjs} +37 -8
- package/dist/{chunk-BKM5VCUS.mjs → chunk-CPBDDGRX.mjs} +4 -1
- package/dist/{chunk-FLKEMER2.js → chunk-DJTFRMRY.js} +4 -1
- package/dist/chunk-DUCRCDLI.mjs +78 -0
- package/dist/{chunk-HH4X2JYO.js → chunk-EKOGDJUT.js} +32 -4
- package/dist/{chunk-NHB2TI2B.js → chunk-FHAWYXPX.js} +1 -1
- package/dist/{chunk-5UNG2O64.js → chunk-FR46MMNP.js} +7 -1
- package/dist/{chunk-EEIPCJQ2.mjs → chunk-KWQKC5TG.mjs} +1 -1
- package/dist/{chunk-IJIUUBFT.js → chunk-OUN5BU4Z.js} +1 -1
- package/dist/{chunk-QWDKSY6Y.js → chunk-OZ4RJDDZ.js} +46 -2
- package/dist/{chunk-762LQMWP.js → chunk-RAXPJ7VC.js} +66 -8
- package/dist/{chunk-F2BUMJYW.mjs → chunk-RBVTV3LA.mjs} +1 -1
- package/dist/{chunk-B47HQHX3.mjs → chunk-RGZHSI2G.mjs} +1 -1
- package/dist/{chunk-GXKON34B.js → chunk-RTI25IBR.js} +1 -1
- package/dist/{chunk-LJSMPON7.js → chunk-USJDHMKS.js} +1 -1
- package/dist/{chunk-N5ZNXNCO.mjs → chunk-UYOPZZBN.mjs} +32 -4
- package/dist/{chunk-EAATIFYL.mjs → chunk-WNBZXXFA.mjs} +1 -1
- package/dist/{chunk-JWOV5H6G.mjs → chunk-X53C3IQC.mjs} +7 -1
- package/dist/chunk-YGAWCP65.mjs +109 -0
- package/dist/components/Autocomplete/index.js +3 -3
- package/dist/components/Autocomplete/index.mjs +1 -1
- package/dist/components/Checkbox/index.js +2 -2
- package/dist/components/Checkbox/index.mjs +1 -1
- package/dist/components/DateRangePicker/index.js +3 -3
- package/dist/components/DateRangePicker/index.mjs +1 -1
- package/dist/components/Input/index.js +3 -3
- package/dist/components/Input/index.mjs +1 -1
- package/dist/components/Modal/index.d.mts +42 -1
- package/dist/components/Modal/index.d.ts +42 -1
- package/dist/components/Modal/index.js +2 -2
- package/dist/components/Modal/index.mjs +1 -1
- package/dist/components/RadioGroup/index.js +2 -2
- package/dist/components/RadioGroup/index.mjs +1 -1
- package/dist/components/SegmentedControl/index.d.mts +16 -0
- package/dist/components/SegmentedControl/index.d.ts +16 -0
- package/dist/components/SegmentedControl/index.js +2 -2
- package/dist/components/SegmentedControl/index.mjs +1 -1
- package/dist/components/Select/index.js +3 -3
- package/dist/components/Select/index.mjs +1 -1
- package/dist/components/Tabs/index.d.mts +21 -0
- package/dist/components/Tabs/index.d.ts +21 -0
- package/dist/components/Tabs/index.js +2 -2
- package/dist/components/Tabs/index.mjs +1 -1
- package/dist/components/Textarea/index.js +3 -3
- package/dist/components/Textarea/index.mjs +1 -1
- package/dist/index.d.mts +16 -3
- package/dist/index.d.ts +16 -3
- package/dist/index.js +95 -93
- package/dist/index.mjs +23 -21
- package/package.json +11 -11
- package/dist/chunk-36Y7UU32.mjs +0 -34
- package/dist/chunk-VOZPGXQD.mjs +0 -51
|
@@ -46,26 +46,55 @@ var textareaVariants = classVarianceAuthority.cva(
|
|
|
46
46
|
}
|
|
47
47
|
);
|
|
48
48
|
var Textarea = React__namespace.forwardRef(
|
|
49
|
-
({
|
|
49
|
+
({
|
|
50
|
+
className,
|
|
51
|
+
size,
|
|
52
|
+
variant,
|
|
53
|
+
label,
|
|
54
|
+
error,
|
|
55
|
+
required,
|
|
56
|
+
rows = 4,
|
|
57
|
+
id,
|
|
58
|
+
"aria-describedby": ariaDescribedBy,
|
|
59
|
+
"aria-invalid": ariaInvalid,
|
|
60
|
+
"aria-required": ariaRequired,
|
|
61
|
+
...props
|
|
62
|
+
}, ref) => {
|
|
63
|
+
const generatedId = React__namespace.useId();
|
|
64
|
+
const textareaId = id ?? generatedId;
|
|
65
|
+
const errorId = `${textareaId}-error`;
|
|
50
66
|
const resolvedVariant = error ? "error" : variant ?? "default";
|
|
67
|
+
const describedBy = [ariaDescribedBy, error ? errorId : null].filter(Boolean).join(" ") || void 0;
|
|
51
68
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
52
|
-
label && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
53
|
-
label,
|
|
54
|
-
|
|
55
|
-
|
|
69
|
+
label && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
70
|
+
"label",
|
|
71
|
+
{
|
|
72
|
+
htmlFor: textareaId,
|
|
73
|
+
className: "block text-sm font-medium text-primary mb-1.5",
|
|
74
|
+
children: [
|
|
75
|
+
label,
|
|
76
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-secondary", "aria-hidden": "true", children: " *" })
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
),
|
|
56
80
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
57
81
|
"textarea",
|
|
58
82
|
{
|
|
83
|
+
...props,
|
|
59
84
|
ref,
|
|
85
|
+
id: textareaId,
|
|
60
86
|
rows,
|
|
87
|
+
required,
|
|
88
|
+
"aria-required": ariaRequired ?? (required ? true : void 0),
|
|
89
|
+
"aria-invalid": ariaInvalid ?? (error ? true : void 0),
|
|
90
|
+
"aria-describedby": describedBy,
|
|
61
91
|
className: chunkADIDI7AJ_js.cn(
|
|
62
92
|
textareaVariants({ size, variant: resolvedVariant }),
|
|
63
93
|
className
|
|
64
|
-
)
|
|
65
|
-
...props
|
|
94
|
+
)
|
|
66
95
|
}
|
|
67
96
|
),
|
|
68
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-red-
|
|
97
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, role: "alert", className: "mt-1 text-sm text-red-600", children: error })
|
|
69
98
|
] });
|
|
70
99
|
}
|
|
71
100
|
);
|
|
@@ -24,26 +24,55 @@ var textareaVariants = cva(
|
|
|
24
24
|
}
|
|
25
25
|
);
|
|
26
26
|
var Textarea = React.forwardRef(
|
|
27
|
-
({
|
|
27
|
+
({
|
|
28
|
+
className,
|
|
29
|
+
size,
|
|
30
|
+
variant,
|
|
31
|
+
label,
|
|
32
|
+
error,
|
|
33
|
+
required,
|
|
34
|
+
rows = 4,
|
|
35
|
+
id,
|
|
36
|
+
"aria-describedby": ariaDescribedBy,
|
|
37
|
+
"aria-invalid": ariaInvalid,
|
|
38
|
+
"aria-required": ariaRequired,
|
|
39
|
+
...props
|
|
40
|
+
}, ref) => {
|
|
41
|
+
const generatedId = React.useId();
|
|
42
|
+
const textareaId = id ?? generatedId;
|
|
43
|
+
const errorId = `${textareaId}-error`;
|
|
28
44
|
const resolvedVariant = error ? "error" : variant ?? "default";
|
|
45
|
+
const describedBy = [ariaDescribedBy, error ? errorId : null].filter(Boolean).join(" ") || void 0;
|
|
29
46
|
return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
|
|
30
|
-
label && /* @__PURE__ */ jsxs(
|
|
31
|
-
label,
|
|
32
|
-
|
|
33
|
-
|
|
47
|
+
label && /* @__PURE__ */ jsxs(
|
|
48
|
+
"label",
|
|
49
|
+
{
|
|
50
|
+
htmlFor: textareaId,
|
|
51
|
+
className: "block text-sm font-medium text-primary mb-1.5",
|
|
52
|
+
children: [
|
|
53
|
+
label,
|
|
54
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-secondary", "aria-hidden": "true", children: " *" })
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
),
|
|
34
58
|
/* @__PURE__ */ jsx(
|
|
35
59
|
"textarea",
|
|
36
60
|
{
|
|
61
|
+
...props,
|
|
37
62
|
ref,
|
|
63
|
+
id: textareaId,
|
|
38
64
|
rows,
|
|
65
|
+
required,
|
|
66
|
+
"aria-required": ariaRequired ?? (required ? true : void 0),
|
|
67
|
+
"aria-invalid": ariaInvalid ?? (error ? true : void 0),
|
|
68
|
+
"aria-describedby": describedBy,
|
|
39
69
|
className: cn(
|
|
40
70
|
textareaVariants({ size, variant: resolvedVariant }),
|
|
41
71
|
className
|
|
42
|
-
)
|
|
43
|
-
...props
|
|
72
|
+
)
|
|
44
73
|
}
|
|
45
74
|
),
|
|
46
|
-
error && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-red-
|
|
75
|
+
error && /* @__PURE__ */ jsx("p", { id: errorId, role: "alert", className: "mt-1 text-sm text-red-600", children: error })
|
|
47
76
|
] });
|
|
48
77
|
}
|
|
49
78
|
);
|
|
@@ -8,8 +8,11 @@ function startOfDay(d) {
|
|
|
8
8
|
return r;
|
|
9
9
|
}
|
|
10
10
|
function addMonths(d, n) {
|
|
11
|
+
const year = d.getFullYear();
|
|
12
|
+
const month = d.getMonth() + n;
|
|
13
|
+
const lastDayOfTargetMonth = new Date(year, month + 1, 0).getDate();
|
|
11
14
|
const r = new Date(d);
|
|
12
|
-
r.
|
|
15
|
+
r.setFullYear(year, month, Math.min(d.getDate(), lastDayOfTargetMonth));
|
|
13
16
|
return r;
|
|
14
17
|
}
|
|
15
18
|
function addDays(d, n) {
|
|
@@ -30,8 +30,11 @@ function startOfDay(d) {
|
|
|
30
30
|
return r;
|
|
31
31
|
}
|
|
32
32
|
function addMonths(d, n) {
|
|
33
|
+
const year = d.getFullYear();
|
|
34
|
+
const month = d.getMonth() + n;
|
|
35
|
+
const lastDayOfTargetMonth = new Date(year, month + 1, 0).getDate();
|
|
33
36
|
const r = new Date(d);
|
|
34
|
-
r.
|
|
37
|
+
r.setFullYear(year, month, Math.min(d.getDate(), lastDayOfTargetMonth));
|
|
35
38
|
return r;
|
|
36
39
|
}
|
|
37
40
|
function addDays(d, n) {
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { cn } from './chunk-IMKLN273.mjs';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var SegmentedControl = React.forwardRef(
|
|
6
|
+
({
|
|
7
|
+
options,
|
|
8
|
+
value,
|
|
9
|
+
onChange,
|
|
10
|
+
className,
|
|
11
|
+
"aria-label": ariaLabel,
|
|
12
|
+
"aria-labelledby": ariaLabelledBy
|
|
13
|
+
}, ref) => {
|
|
14
|
+
const optionRefs = React.useRef([]);
|
|
15
|
+
const selectedIndex = options.findIndex((option) => option.value === value);
|
|
16
|
+
const rovingIndex = selectedIndex === -1 ? 0 : selectedIndex;
|
|
17
|
+
const handleKeyDown = (event, index) => {
|
|
18
|
+
const lastIndex = options.length - 1;
|
|
19
|
+
let nextIndex;
|
|
20
|
+
switch (event.key) {
|
|
21
|
+
case "ArrowRight":
|
|
22
|
+
case "ArrowDown":
|
|
23
|
+
nextIndex = index === lastIndex ? 0 : index + 1;
|
|
24
|
+
break;
|
|
25
|
+
case "ArrowLeft":
|
|
26
|
+
case "ArrowUp":
|
|
27
|
+
nextIndex = index === 0 ? lastIndex : index - 1;
|
|
28
|
+
break;
|
|
29
|
+
case "Home":
|
|
30
|
+
nextIndex = 0;
|
|
31
|
+
break;
|
|
32
|
+
case "End":
|
|
33
|
+
nextIndex = lastIndex;
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
event.preventDefault();
|
|
39
|
+
const nextOption = options[nextIndex];
|
|
40
|
+
if (!nextOption) return;
|
|
41
|
+
onChange(nextOption.value);
|
|
42
|
+
optionRefs.current[nextIndex]?.focus();
|
|
43
|
+
};
|
|
44
|
+
return /* @__PURE__ */ jsx(
|
|
45
|
+
"div",
|
|
46
|
+
{
|
|
47
|
+
ref,
|
|
48
|
+
className: cn("flex gap-1 bg-gray-100 rounded-full p-1", className),
|
|
49
|
+
role: "radiogroup",
|
|
50
|
+
"aria-label": ariaLabelledBy ? void 0 : ariaLabel,
|
|
51
|
+
"aria-labelledby": ariaLabelledBy,
|
|
52
|
+
children: options.map((option, index) => /* @__PURE__ */ jsx(
|
|
53
|
+
"button",
|
|
54
|
+
{
|
|
55
|
+
type: "button",
|
|
56
|
+
role: "radio",
|
|
57
|
+
"aria-checked": value === option.value,
|
|
58
|
+
tabIndex: index === rovingIndex ? 0 : -1,
|
|
59
|
+
ref: (node) => {
|
|
60
|
+
optionRefs.current[index] = node;
|
|
61
|
+
},
|
|
62
|
+
onKeyDown: (event) => handleKeyDown(event, index),
|
|
63
|
+
onClick: () => onChange(option.value),
|
|
64
|
+
className: cn(
|
|
65
|
+
"px-3 py-1.5 text-sm rounded-full transition-all",
|
|
66
|
+
value === option.value ? "bg-white text-gray-900 shadow-sm font-medium" : "text-gray-600 hover:text-gray-900"
|
|
67
|
+
),
|
|
68
|
+
children: option.label
|
|
69
|
+
},
|
|
70
|
+
option.value
|
|
71
|
+
))
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
SegmentedControl.displayName = "SegmentedControl";
|
|
77
|
+
|
|
78
|
+
export { SegmentedControl };
|
|
@@ -37,6 +37,7 @@ var FOCUSABLE_SELECTOR = [
|
|
|
37
37
|
"[contenteditable]:not([contenteditable='false'])",
|
|
38
38
|
'[tabindex]:not([tabindex="-1"])'
|
|
39
39
|
].join(", ");
|
|
40
|
+
var DEFAULT_Z_INDEX_CLASS = "z-50";
|
|
40
41
|
function getFocusableElements(panel) {
|
|
41
42
|
return Array.from(panel.querySelectorAll(FOCUSABLE_SELECTOR)).filter(
|
|
42
43
|
(element) => !element.closest("[hidden], [aria-hidden='true'], details:not([open])")
|
|
@@ -54,6 +55,11 @@ var Modal = React__namespace.forwardRef(
|
|
|
54
55
|
children,
|
|
55
56
|
title,
|
|
56
57
|
className,
|
|
58
|
+
variant = "centered",
|
|
59
|
+
overlayClassName,
|
|
60
|
+
zIndexClassName = DEFAULT_Z_INDEX_CLASS,
|
|
61
|
+
initialFocusRef,
|
|
62
|
+
returnFocusTo,
|
|
57
63
|
"aria-label": ariaLabel,
|
|
58
64
|
"aria-labelledby": ariaLabelledBy,
|
|
59
65
|
"aria-describedby": ariaDescribedBy
|
|
@@ -62,10 +68,20 @@ var Modal = React__namespace.forwardRef(
|
|
|
62
68
|
const generatedTitleId = React__namespace.useId();
|
|
63
69
|
const titleId = title ? `${generatedTitleId}-title` : void 0;
|
|
64
70
|
const labelledBy = ariaLabelledBy ?? titleId;
|
|
71
|
+
const isFullBleed = variant === "fullBleed";
|
|
72
|
+
const initialFocusRefLatest = React__namespace.useRef(initialFocusRef);
|
|
73
|
+
initialFocusRefLatest.current = initialFocusRef;
|
|
74
|
+
const returnFocusToLatest = React__namespace.useRef(returnFocusTo);
|
|
75
|
+
returnFocusToLatest.current = returnFocusTo;
|
|
65
76
|
React__namespace.useEffect(() => {
|
|
66
77
|
if (!isOpen) return;
|
|
67
78
|
const trigger = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
68
79
|
return () => {
|
|
80
|
+
const designated = returnFocusToLatest.current?.current ?? null;
|
|
81
|
+
if (designated && designated.isConnected) {
|
|
82
|
+
designated.focus();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
69
85
|
if (trigger && trigger.isConnected) trigger.focus();
|
|
70
86
|
};
|
|
71
87
|
}, [isOpen]);
|
|
@@ -73,6 +89,11 @@ var Modal = React__namespace.forwardRef(
|
|
|
73
89
|
if (!isOpen) return;
|
|
74
90
|
const panel = panelRef.current;
|
|
75
91
|
if (!panel) return;
|
|
92
|
+
const preferred = initialFocusRefLatest.current?.current ?? null;
|
|
93
|
+
if (preferred) {
|
|
94
|
+
preferred.focus();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
76
97
|
const focusable = getFocusableElements(panel);
|
|
77
98
|
(focusable[0] ?? panel).focus();
|
|
78
99
|
}, [isOpen]);
|
|
@@ -124,14 +145,21 @@ var Modal = React__namespace.forwardRef(
|
|
|
124
145
|
"div",
|
|
125
146
|
{
|
|
126
147
|
ref,
|
|
127
|
-
className:
|
|
148
|
+
className: chunkADIDI7AJ_js.cn(
|
|
149
|
+
"fixed inset-0",
|
|
150
|
+
zIndexClassName,
|
|
151
|
+
// La mise en page centree (et sa marge de 16 px) n'existe que dans la
|
|
152
|
+
// variante `centered` : une surface bord a bord n'en veut pas.
|
|
153
|
+
!isFullBleed && "flex items-center justify-center p-4",
|
|
154
|
+
overlayClassName
|
|
155
|
+
),
|
|
128
156
|
role: "dialog",
|
|
129
157
|
"aria-modal": "true",
|
|
130
158
|
"aria-labelledby": labelledBy,
|
|
131
159
|
"aria-label": labelledBy ? void 0 : ariaLabel,
|
|
132
160
|
"aria-describedby": ariaDescribedBy,
|
|
133
161
|
children: [
|
|
134
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
162
|
+
!isFullBleed && /* @__PURE__ */ jsxRuntime.jsx(
|
|
135
163
|
"div",
|
|
136
164
|
{
|
|
137
165
|
className: "absolute inset-0 bg-black/50",
|
|
@@ -145,7 +173,7 @@ var Modal = React__namespace.forwardRef(
|
|
|
145
173
|
ref: panelRef,
|
|
146
174
|
tabIndex: -1,
|
|
147
175
|
className: chunkADIDI7AJ_js.cn(
|
|
148
|
-
"relative bg-white rounded-2xl shadow-xl max-w-md w-full max-h-[90vh] overflow-auto outline-none",
|
|
176
|
+
isFullBleed ? "relative h-full w-full outline-none" : "relative bg-white rounded-2xl shadow-xl max-w-md w-full max-h-[90vh] overflow-auto outline-none",
|
|
149
177
|
className
|
|
150
178
|
),
|
|
151
179
|
children: [
|
|
@@ -186,7 +214,7 @@ var Modal = React__namespace.forwardRef(
|
|
|
186
214
|
}
|
|
187
215
|
)
|
|
188
216
|
] }),
|
|
189
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkADIDI7AJ_js.cn(title ? "px-6 pb-6" : "p-6"), children })
|
|
217
|
+
isFullBleed ? children : /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkADIDI7AJ_js.cn(title ? "px-6 pb-6" : "p-6"), children })
|
|
190
218
|
]
|
|
191
219
|
}
|
|
192
220
|
)
|
|
@@ -200,7 +200,7 @@ var Autocomplete = React__namespace.forwardRef(
|
|
|
200
200
|
}
|
|
201
201
|
)
|
|
202
202
|
] }),
|
|
203
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-red-
|
|
203
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "mt-1 text-sm text-red-600", children: error })
|
|
204
204
|
] });
|
|
205
205
|
}
|
|
206
206
|
);
|
|
@@ -100,7 +100,13 @@ var Input = React__namespace.forwardRef(
|
|
|
100
100
|
),
|
|
101
101
|
rightIcon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 text-text-muted", children: rightIcon })
|
|
102
102
|
] }),
|
|
103
|
-
error &&
|
|
103
|
+
error && // Pas de `role="alert"` ici, contrairement aux autres champs de la
|
|
104
|
+
// bibliotheque : les trois seuls consommateurs de cette prop
|
|
105
|
+
// (BookingForm, PaymentForm, EscalationForm) sont des formulaires du
|
|
106
|
+
// tunnel, et BookingForm annonce deja ses fautes par un resume en
|
|
107
|
+
// region live (TTR-651). Un second canal produirait des annonces
|
|
108
|
+
// concurrentes sur le chemin de paiement.
|
|
109
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, className: "mt-1 text-sm text-red-600", children: error })
|
|
104
110
|
] });
|
|
105
111
|
}
|
|
106
112
|
);
|
|
@@ -63,7 +63,7 @@ var Checkbox = React.forwardRef(
|
|
|
63
63
|
]
|
|
64
64
|
}
|
|
65
65
|
),
|
|
66
|
-
error && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-red-
|
|
66
|
+
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "mt-1 text-sm text-red-600", children: error })
|
|
67
67
|
] });
|
|
68
68
|
}
|
|
69
69
|
);
|
|
@@ -85,7 +85,7 @@ var Checkbox = React__namespace.forwardRef(
|
|
|
85
85
|
]
|
|
86
86
|
}
|
|
87
87
|
),
|
|
88
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-red-
|
|
88
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "mt-1 text-sm text-red-600", children: error })
|
|
89
89
|
] });
|
|
90
90
|
}
|
|
91
91
|
);
|
|
@@ -25,19 +25,63 @@ function _interopNamespace(e) {
|
|
|
25
25
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
26
26
|
|
|
27
27
|
var SegmentedControl = React__namespace.forwardRef(
|
|
28
|
-
({
|
|
28
|
+
({
|
|
29
|
+
options,
|
|
30
|
+
value,
|
|
31
|
+
onChange,
|
|
32
|
+
className,
|
|
33
|
+
"aria-label": ariaLabel,
|
|
34
|
+
"aria-labelledby": ariaLabelledBy
|
|
35
|
+
}, ref) => {
|
|
36
|
+
const optionRefs = React__namespace.useRef([]);
|
|
37
|
+
const selectedIndex = options.findIndex((option) => option.value === value);
|
|
38
|
+
const rovingIndex = selectedIndex === -1 ? 0 : selectedIndex;
|
|
39
|
+
const handleKeyDown = (event, index) => {
|
|
40
|
+
const lastIndex = options.length - 1;
|
|
41
|
+
let nextIndex;
|
|
42
|
+
switch (event.key) {
|
|
43
|
+
case "ArrowRight":
|
|
44
|
+
case "ArrowDown":
|
|
45
|
+
nextIndex = index === lastIndex ? 0 : index + 1;
|
|
46
|
+
break;
|
|
47
|
+
case "ArrowLeft":
|
|
48
|
+
case "ArrowUp":
|
|
49
|
+
nextIndex = index === 0 ? lastIndex : index - 1;
|
|
50
|
+
break;
|
|
51
|
+
case "Home":
|
|
52
|
+
nextIndex = 0;
|
|
53
|
+
break;
|
|
54
|
+
case "End":
|
|
55
|
+
nextIndex = lastIndex;
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
const nextOption = options[nextIndex];
|
|
62
|
+
if (!nextOption) return;
|
|
63
|
+
onChange(nextOption.value);
|
|
64
|
+
optionRefs.current[nextIndex]?.focus();
|
|
65
|
+
};
|
|
29
66
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
30
67
|
"div",
|
|
31
68
|
{
|
|
32
69
|
ref,
|
|
33
70
|
className: chunkADIDI7AJ_js.cn("flex gap-1 bg-gray-100 rounded-full p-1", className),
|
|
34
71
|
role: "radiogroup",
|
|
35
|
-
|
|
72
|
+
"aria-label": ariaLabelledBy ? void 0 : ariaLabel,
|
|
73
|
+
"aria-labelledby": ariaLabelledBy,
|
|
74
|
+
children: options.map((option, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
36
75
|
"button",
|
|
37
76
|
{
|
|
38
77
|
type: "button",
|
|
39
78
|
role: "radio",
|
|
40
79
|
"aria-checked": value === option.value,
|
|
80
|
+
tabIndex: index === rovingIndex ? 0 : -1,
|
|
81
|
+
ref: (node) => {
|
|
82
|
+
optionRefs.current[index] = node;
|
|
83
|
+
},
|
|
84
|
+
onKeyDown: (event) => handleKeyDown(event, index),
|
|
41
85
|
onClick: () => onChange(option.value),
|
|
42
86
|
className: chunkADIDI7AJ_js.cn(
|
|
43
87
|
"px-3 py-1.5 text-sm rounded-full transition-all",
|
|
@@ -25,17 +25,57 @@ function _interopNamespace(e) {
|
|
|
25
25
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
26
26
|
|
|
27
27
|
var Tabs = React__namespace.forwardRef(
|
|
28
|
-
({
|
|
28
|
+
({
|
|
29
|
+
tabs,
|
|
30
|
+
defaultTab,
|
|
31
|
+
value,
|
|
32
|
+
onChange,
|
|
33
|
+
className,
|
|
34
|
+
"aria-label": ariaLabel,
|
|
35
|
+
"aria-labelledby": ariaLabelledBy
|
|
36
|
+
}, ref) => {
|
|
29
37
|
const [internalValue, setInternalValue] = React__namespace.useState(
|
|
30
38
|
defaultTab || tabs[0]?.key || ""
|
|
31
39
|
);
|
|
32
40
|
const activeKey = value ?? internalValue;
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
const idPrefix = React__namespace.useId();
|
|
42
|
+
const tabId = (key) => `${idPrefix}-tab-${key}`;
|
|
43
|
+
const panelId = (key) => `${idPrefix}-panel-${key}`;
|
|
44
|
+
const tabRefs = React__namespace.useRef([]);
|
|
45
|
+
const handleChange = React__namespace.useCallback(
|
|
46
|
+
(key) => {
|
|
47
|
+
if (onChange) {
|
|
48
|
+
onChange(key);
|
|
49
|
+
} else {
|
|
50
|
+
setInternalValue(key);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
[onChange]
|
|
54
|
+
);
|
|
55
|
+
const handleKeyDown = (event, index) => {
|
|
56
|
+
const lastIndex = tabs.length - 1;
|
|
57
|
+
let nextIndex;
|
|
58
|
+
switch (event.key) {
|
|
59
|
+
case "ArrowRight":
|
|
60
|
+
nextIndex = index === lastIndex ? 0 : index + 1;
|
|
61
|
+
break;
|
|
62
|
+
case "ArrowLeft":
|
|
63
|
+
nextIndex = index === 0 ? lastIndex : index - 1;
|
|
64
|
+
break;
|
|
65
|
+
case "Home":
|
|
66
|
+
nextIndex = 0;
|
|
67
|
+
break;
|
|
68
|
+
case "End":
|
|
69
|
+
nextIndex = lastIndex;
|
|
70
|
+
break;
|
|
71
|
+
default:
|
|
72
|
+
return;
|
|
38
73
|
}
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
const nextTab = tabs[nextIndex];
|
|
76
|
+
if (!nextTab) return;
|
|
77
|
+
handleChange(nextTab.key);
|
|
78
|
+
tabRefs.current[nextIndex]?.focus();
|
|
39
79
|
};
|
|
40
80
|
const activeTab = tabs.find((t) => t.key === activeKey);
|
|
41
81
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: chunkADIDI7AJ_js.cn("w-full", className), children: [
|
|
@@ -43,13 +83,22 @@ var Tabs = React__namespace.forwardRef(
|
|
|
43
83
|
"div",
|
|
44
84
|
{
|
|
45
85
|
role: "tablist",
|
|
86
|
+
"aria-label": ariaLabelledBy ? void 0 : ariaLabel,
|
|
87
|
+
"aria-labelledby": ariaLabelledBy,
|
|
46
88
|
className: "flex border-b border-gray-200 gap-1 overflow-x-auto",
|
|
47
|
-
children: tabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
89
|
+
children: tabs.map((tab, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
48
90
|
"button",
|
|
49
91
|
{
|
|
92
|
+
id: tabId(tab.key),
|
|
50
93
|
role: "tab",
|
|
51
94
|
type: "button",
|
|
52
95
|
"aria-selected": tab.key === activeKey,
|
|
96
|
+
"aria-controls": panelId(tab.key),
|
|
97
|
+
tabIndex: tab.key === activeKey ? 0 : -1,
|
|
98
|
+
ref: (node) => {
|
|
99
|
+
tabRefs.current[index] = node;
|
|
100
|
+
},
|
|
101
|
+
onKeyDown: (event) => handleKeyDown(event, index),
|
|
53
102
|
onClick: () => handleChange(tab.key),
|
|
54
103
|
className: chunkADIDI7AJ_js.cn(
|
|
55
104
|
"flex items-center gap-2 px-4 py-3 text-sm font-medium whitespace-nowrap border-b-2 transition-colors -mb-px",
|
|
@@ -64,7 +113,16 @@ var Tabs = React__namespace.forwardRef(
|
|
|
64
113
|
))
|
|
65
114
|
}
|
|
66
115
|
),
|
|
67
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
116
|
+
activeTab && /* @__PURE__ */ jsxRuntime.jsx(
|
|
117
|
+
"div",
|
|
118
|
+
{
|
|
119
|
+
role: "tabpanel",
|
|
120
|
+
id: panelId(activeTab.key),
|
|
121
|
+
"aria-labelledby": tabId(activeTab.key),
|
|
122
|
+
className: "py-4",
|
|
123
|
+
children: activeTab.content
|
|
124
|
+
}
|
|
125
|
+
)
|
|
68
126
|
] });
|
|
69
127
|
}
|
|
70
128
|
);
|
|
@@ -55,7 +55,7 @@ var RadioGroup = React.forwardRef(
|
|
|
55
55
|
})
|
|
56
56
|
}
|
|
57
57
|
),
|
|
58
|
-
error && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-red-
|
|
58
|
+
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "mt-1 text-sm text-red-600", children: error })
|
|
59
59
|
] });
|
|
60
60
|
}
|
|
61
61
|
);
|
|
@@ -178,7 +178,7 @@ var Autocomplete = React.forwardRef(
|
|
|
178
178
|
}
|
|
179
179
|
)
|
|
180
180
|
] }),
|
|
181
|
-
error && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-red-
|
|
181
|
+
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "mt-1 text-sm text-red-600", children: error })
|
|
182
182
|
] });
|
|
183
183
|
}
|
|
184
184
|
);
|
|
@@ -77,7 +77,7 @@ var RadioGroup = React__namespace.forwardRef(
|
|
|
77
77
|
})
|
|
78
78
|
}
|
|
79
79
|
),
|
|
80
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-red-
|
|
80
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "mt-1 text-sm text-red-600", children: error })
|
|
81
81
|
] });
|
|
82
82
|
}
|
|
83
83
|
);
|
|
@@ -239,7 +239,7 @@ var Select = React__namespace.forwardRef(
|
|
|
239
239
|
}
|
|
240
240
|
)
|
|
241
241
|
] }),
|
|
242
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, className: "mt-1 text-sm text-red-
|
|
242
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, role: "alert", className: "mt-1 text-sm text-red-600", children: error })
|
|
243
243
|
] });
|
|
244
244
|
}
|
|
245
245
|
);
|