@page-speed/forms 0.4.7 → 0.4.9
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/core.cjs +15 -2
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +15 -2
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +86 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -2
- package/dist/index.d.ts +38 -2
- package/dist/index.js +82 -3
- package/dist/index.js.map +1 -1
- package/dist/inputs.cjs +946 -697
- package/dist/inputs.cjs.map +1 -1
- package/dist/inputs.d.cts +93 -182
- package/dist/inputs.d.ts +93 -182
- package/dist/inputs.js +943 -695
- package/dist/inputs.js.map +1 -1
- package/dist/{types-4ppM117e.d.cts → types-DuX3q6A4.d.cts} +1 -1
- package/dist/{types-4ppM117e.d.ts → types-DuX3q6A4.d.ts} +1 -1
- package/dist/validation-rules.d.cts +1 -1
- package/dist/validation-rules.d.ts +1 -1
- package/dist/validation-utils.d.cts +1 -1
- package/dist/validation-utils.d.ts +1 -1
- package/dist/validation-valibot.d.cts +1 -1
- package/dist/validation-valibot.d.ts +1 -1
- package/dist/validation.d.cts +1 -1
- package/dist/validation.d.ts +1 -1
- package/package.json +12 -2
package/dist/inputs.cjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React17 = require('react');
|
|
4
4
|
var clsx = require('clsx');
|
|
5
5
|
var tailwindMerge = require('tailwind-merge');
|
|
6
|
+
var radixUi = require('radix-ui');
|
|
6
7
|
var useOnClickOutside = require('@opensite/hooks/useOnClickOutside');
|
|
7
8
|
|
|
8
9
|
function _interopNamespace(e) {
|
|
@@ -23,7 +24,7 @@ function _interopNamespace(e) {
|
|
|
23
24
|
return Object.freeze(n);
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
var
|
|
27
|
+
var React17__namespace = /*#__PURE__*/_interopNamespace(React17);
|
|
27
28
|
|
|
28
29
|
// src/inputs/TextInput.tsx
|
|
29
30
|
function cn(...inputs) {
|
|
@@ -31,6 +32,36 @@ function cn(...inputs) {
|
|
|
31
32
|
}
|
|
32
33
|
var INPUT_AUTOFILL_RESET_CLASSES = "autofill:bg-transparent autofill:text-foreground [&:-webkit-autofill]:[-webkit-text-fill-color:hsl(var(--foreground))] [&:-webkit-autofill]:[caret-color:hsl(var(--foreground))] [&:-webkit-autofill]:[box-shadow:0_0_0px_1000px_hsl(var(--background))_inset] [&:-webkit-autofill:hover]:[box-shadow:0_0_0px_1000px_hsl(var(--background))_inset] [&:-webkit-autofill:focus]:[box-shadow:0_0_0px_1000px_hsl(var(--background))_inset] [&:-webkit-autofill]:[transition:background-color_9999s_ease-out,color_9999s_ease-out]";
|
|
33
34
|
|
|
35
|
+
// src/components/ui/input.tsx
|
|
36
|
+
function Input({ className, type, ...props }) {
|
|
37
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
38
|
+
"input",
|
|
39
|
+
{
|
|
40
|
+
type,
|
|
41
|
+
"data-slot": "input",
|
|
42
|
+
className: cn(
|
|
43
|
+
// Core structure - no hardcoded colors, uses CSS variables
|
|
44
|
+
"flex h-9 w-full min-w-0 rounded-md border border-input",
|
|
45
|
+
"bg-transparent px-3 py-1 text-base shadow-sm",
|
|
46
|
+
"transition-colors outline-none md:text-sm",
|
|
47
|
+
// Focus state - uses ring-ring CSS variable (adapts to theme)
|
|
48
|
+
"focus-visible:ring-1 focus-visible:ring-ring",
|
|
49
|
+
// Error state - uses destructive CSS variables (adapts to theme)
|
|
50
|
+
"aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive",
|
|
51
|
+
// Disabled state - no color hardcoding
|
|
52
|
+
"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
53
|
+
// File input specific - inherits text color from parent
|
|
54
|
+
"file:inline-flex file:h-7 file:border-0 file:bg-transparent",
|
|
55
|
+
"file:text-sm file:font-medium",
|
|
56
|
+
// Autofill reset - prevents browser from overriding our dynamic colors
|
|
57
|
+
INPUT_AUTOFILL_RESET_CLASSES,
|
|
58
|
+
className
|
|
59
|
+
),
|
|
60
|
+
...props
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
34
65
|
// src/inputs/TextInput.tsx
|
|
35
66
|
function TextInput({
|
|
36
67
|
name,
|
|
@@ -53,17 +84,8 @@ function TextInput({
|
|
|
53
84
|
onBlur?.();
|
|
54
85
|
};
|
|
55
86
|
const hasValue = String(value ?? "").trim().length > 0;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
59
|
-
"disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
60
|
-
INPUT_AUTOFILL_RESET_CLASSES,
|
|
61
|
-
!error && hasValue && "ring-2 ring-ring",
|
|
62
|
-
error && "border-destructive ring-1 ring-destructive",
|
|
63
|
-
className
|
|
64
|
-
);
|
|
65
|
-
return /* @__PURE__ */ React9__namespace.createElement(
|
|
66
|
-
"input",
|
|
87
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
88
|
+
Input,
|
|
67
89
|
{
|
|
68
90
|
type,
|
|
69
91
|
id,
|
|
@@ -74,7 +96,12 @@ function TextInput({
|
|
|
74
96
|
placeholder,
|
|
75
97
|
disabled,
|
|
76
98
|
required,
|
|
77
|
-
className:
|
|
99
|
+
className: cn(
|
|
100
|
+
// Valid value indicator - ring-2 when has value and no error
|
|
101
|
+
!error && hasValue && "ring-2 ring-ring",
|
|
102
|
+
// Error state - handled by Input component via aria-invalid
|
|
103
|
+
className
|
|
104
|
+
),
|
|
78
105
|
"aria-invalid": error || props["aria-invalid"],
|
|
79
106
|
"aria-describedby": props["aria-describedby"],
|
|
80
107
|
"aria-required": required || props["aria-required"],
|
|
@@ -83,6 +110,30 @@ function TextInput({
|
|
|
83
110
|
);
|
|
84
111
|
}
|
|
85
112
|
TextInput.displayName = "TextInput";
|
|
113
|
+
function Textarea({ className, ...props }) {
|
|
114
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
115
|
+
"textarea",
|
|
116
|
+
{
|
|
117
|
+
"data-slot": "textarea",
|
|
118
|
+
className: cn(
|
|
119
|
+
// Core structure - uses CSS variables only
|
|
120
|
+
"flex field-sizing-content min-h-16 w-full rounded-md border border-input",
|
|
121
|
+
"bg-transparent px-3 py-2 text-base shadow-xs",
|
|
122
|
+
"transition-[color,box-shadow] outline-none md:text-sm",
|
|
123
|
+
// Focus state - uses ring-ring CSS variable
|
|
124
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
125
|
+
// Error state - uses destructive CSS variables
|
|
126
|
+
"aria-invalid:border-destructive aria-invalid:ring-destructive/20",
|
|
127
|
+
// Disabled state
|
|
128
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
129
|
+
className
|
|
130
|
+
),
|
|
131
|
+
...props
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/inputs/TextArea.tsx
|
|
86
137
|
function TextArea({
|
|
87
138
|
name,
|
|
88
139
|
value,
|
|
@@ -107,17 +158,8 @@ function TextArea({
|
|
|
107
158
|
onBlur?.();
|
|
108
159
|
};
|
|
109
160
|
const hasValue = String(value ?? "").trim().length > 0;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
113
|
-
"disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
114
|
-
INPUT_AUTOFILL_RESET_CLASSES,
|
|
115
|
-
!error && hasValue && "ring-2 ring-ring",
|
|
116
|
-
error && "border-destructive ring-1 ring-destructive",
|
|
117
|
-
className
|
|
118
|
-
);
|
|
119
|
-
return /* @__PURE__ */ React9__namespace.createElement(
|
|
120
|
-
"textarea",
|
|
161
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
162
|
+
Textarea,
|
|
121
163
|
{
|
|
122
164
|
name,
|
|
123
165
|
value: value ?? "",
|
|
@@ -126,7 +168,12 @@ function TextArea({
|
|
|
126
168
|
placeholder,
|
|
127
169
|
disabled,
|
|
128
170
|
required,
|
|
129
|
-
className:
|
|
171
|
+
className: cn(
|
|
172
|
+
// Valid value indicator - ring-2 when has value and no error
|
|
173
|
+
!error && hasValue && "ring-2 ring-ring",
|
|
174
|
+
// Error state - handled by Textarea component via aria-invalid
|
|
175
|
+
className
|
|
176
|
+
),
|
|
130
177
|
rows,
|
|
131
178
|
cols,
|
|
132
179
|
maxLength,
|
|
@@ -140,6 +187,175 @@ function TextArea({
|
|
|
140
187
|
);
|
|
141
188
|
}
|
|
142
189
|
TextArea.displayName = "TextArea";
|
|
190
|
+
function Checkbox({
|
|
191
|
+
className,
|
|
192
|
+
...props
|
|
193
|
+
}) {
|
|
194
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
195
|
+
radixUi.Checkbox.Root,
|
|
196
|
+
{
|
|
197
|
+
"data-slot": "checkbox",
|
|
198
|
+
className: cn(
|
|
199
|
+
// Core structure - uses CSS variables
|
|
200
|
+
"peer size-4 shrink-0 rounded-[4px] border border-input bg-transparent shadow-xs",
|
|
201
|
+
"transition-shadow outline-none",
|
|
202
|
+
// Checked state - uses primary CSS variables
|
|
203
|
+
"data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
|
|
204
|
+
"data-[state=checked]:border-primary",
|
|
205
|
+
// Focus state - uses ring-ring CSS variable
|
|
206
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
207
|
+
// Error state - uses destructive CSS variables
|
|
208
|
+
"aria-invalid:border-destructive aria-invalid:ring-destructive/20",
|
|
209
|
+
// Disabled state
|
|
210
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
211
|
+
className
|
|
212
|
+
),
|
|
213
|
+
...props
|
|
214
|
+
},
|
|
215
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
216
|
+
radixUi.Checkbox.Indicator,
|
|
217
|
+
{
|
|
218
|
+
"data-slot": "checkbox-indicator",
|
|
219
|
+
className: "grid place-content-center text-current transition-none"
|
|
220
|
+
},
|
|
221
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
222
|
+
"svg",
|
|
223
|
+
{
|
|
224
|
+
className: "size-3.5",
|
|
225
|
+
viewBox: "0 0 24 24",
|
|
226
|
+
fill: "none",
|
|
227
|
+
stroke: "currentColor",
|
|
228
|
+
strokeWidth: "3",
|
|
229
|
+
strokeLinecap: "round",
|
|
230
|
+
strokeLinejoin: "round"
|
|
231
|
+
},
|
|
232
|
+
/* @__PURE__ */ React17__namespace.createElement("polyline", { points: "20 6 9 17 4 12" })
|
|
233
|
+
)
|
|
234
|
+
)
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
function Label({
|
|
238
|
+
className,
|
|
239
|
+
...props
|
|
240
|
+
}) {
|
|
241
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
242
|
+
radixUi.Label.Root,
|
|
243
|
+
{
|
|
244
|
+
"data-slot": "label",
|
|
245
|
+
className: cn(
|
|
246
|
+
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
247
|
+
className
|
|
248
|
+
),
|
|
249
|
+
...props
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// src/inputs/Checkbox.tsx
|
|
255
|
+
function Checkbox2({
|
|
256
|
+
name,
|
|
257
|
+
value,
|
|
258
|
+
onChange,
|
|
259
|
+
onBlur,
|
|
260
|
+
disabled = false,
|
|
261
|
+
required = false,
|
|
262
|
+
error = false,
|
|
263
|
+
className = "",
|
|
264
|
+
label,
|
|
265
|
+
description,
|
|
266
|
+
useChoiceCard = false,
|
|
267
|
+
...props
|
|
268
|
+
}) {
|
|
269
|
+
const checkboxId = props.id || `checkbox-${name}`;
|
|
270
|
+
const handleCheckedChange = (checked) => {
|
|
271
|
+
onChange(checked);
|
|
272
|
+
};
|
|
273
|
+
const handleBlur = () => {
|
|
274
|
+
onBlur?.();
|
|
275
|
+
};
|
|
276
|
+
const showChoiceCard = useChoiceCard || !!description;
|
|
277
|
+
const checkbox = /* @__PURE__ */ React17__namespace.createElement(React17__namespace.Fragment, null, /* @__PURE__ */ React17__namespace.createElement(
|
|
278
|
+
"input",
|
|
279
|
+
{
|
|
280
|
+
type: "checkbox",
|
|
281
|
+
name,
|
|
282
|
+
checked: value,
|
|
283
|
+
onChange: () => {
|
|
284
|
+
},
|
|
285
|
+
disabled,
|
|
286
|
+
required,
|
|
287
|
+
tabIndex: -1,
|
|
288
|
+
"aria-hidden": "true",
|
|
289
|
+
style: {
|
|
290
|
+
position: "absolute",
|
|
291
|
+
width: "1px",
|
|
292
|
+
height: "1px",
|
|
293
|
+
padding: 0,
|
|
294
|
+
margin: "-1px",
|
|
295
|
+
overflow: "hidden",
|
|
296
|
+
clip: "rect(0, 0, 0, 0)",
|
|
297
|
+
whiteSpace: "nowrap",
|
|
298
|
+
border: 0
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
), /* @__PURE__ */ React17__namespace.createElement(
|
|
302
|
+
Checkbox,
|
|
303
|
+
{
|
|
304
|
+
id: checkboxId,
|
|
305
|
+
checked: value,
|
|
306
|
+
onCheckedChange: handleCheckedChange,
|
|
307
|
+
onBlur: handleBlur,
|
|
308
|
+
disabled,
|
|
309
|
+
"aria-invalid": error || props["aria-invalid"],
|
|
310
|
+
"aria-describedby": description ? `${checkboxId}-description` : props["aria-describedby"],
|
|
311
|
+
"aria-required": required || props["aria-required"],
|
|
312
|
+
...props
|
|
313
|
+
}
|
|
314
|
+
));
|
|
315
|
+
if (!label) {
|
|
316
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { className }, checkbox);
|
|
317
|
+
}
|
|
318
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
319
|
+
"label",
|
|
320
|
+
{
|
|
321
|
+
htmlFor: checkboxId,
|
|
322
|
+
className: cn(
|
|
323
|
+
"flex gap-3 p-3 duration-200",
|
|
324
|
+
showChoiceCard && "border rounded-lg hover:ring-2 hover:ring-ring/50",
|
|
325
|
+
showChoiceCard && value && "ring-2 ring-ring",
|
|
326
|
+
showChoiceCard && error && "border-destructive",
|
|
327
|
+
disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer",
|
|
328
|
+
className
|
|
329
|
+
)
|
|
330
|
+
},
|
|
331
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
332
|
+
"div",
|
|
333
|
+
{
|
|
334
|
+
className: cn(
|
|
335
|
+
"flex w-full gap-3",
|
|
336
|
+
showChoiceCard ? "items-start" : "items-center"
|
|
337
|
+
)
|
|
338
|
+
},
|
|
339
|
+
checkbox,
|
|
340
|
+
/* @__PURE__ */ React17__namespace.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
341
|
+
Label,
|
|
342
|
+
{
|
|
343
|
+
htmlFor: checkboxId,
|
|
344
|
+
className: "cursor-pointer font-medium leading-none"
|
|
345
|
+
},
|
|
346
|
+
label
|
|
347
|
+
), description && /* @__PURE__ */ React17__namespace.createElement(
|
|
348
|
+
"p",
|
|
349
|
+
{
|
|
350
|
+
id: `${checkboxId}-description`,
|
|
351
|
+
className: "text-sm opacity-70 leading-snug"
|
|
352
|
+
},
|
|
353
|
+
description
|
|
354
|
+
))
|
|
355
|
+
)
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
Checkbox2.displayName = "Checkbox";
|
|
143
359
|
var LabelGroup = ({
|
|
144
360
|
labelHtmlFor,
|
|
145
361
|
required = false,
|
|
@@ -155,11 +371,11 @@ var LabelGroup = ({
|
|
|
155
371
|
variant === "legend" ? "mb-1.5" : "mb-1 block",
|
|
156
372
|
primaryClassName
|
|
157
373
|
);
|
|
158
|
-
const requiredIndicator = required ? /* @__PURE__ */
|
|
374
|
+
const requiredIndicator = required ? /* @__PURE__ */ React17__namespace.createElement("span", { className: "text-destructive pl-0.5", "aria-label": "required" }, "*") : null;
|
|
159
375
|
let primaryElement = null;
|
|
160
376
|
if (primary) {
|
|
161
377
|
if (variant === "label") {
|
|
162
|
-
primaryElement = /* @__PURE__ */
|
|
378
|
+
primaryElement = /* @__PURE__ */ React17__namespace.createElement(
|
|
163
379
|
"label",
|
|
164
380
|
{
|
|
165
381
|
htmlFor: labelHtmlFor,
|
|
@@ -170,12 +386,12 @@ var LabelGroup = ({
|
|
|
170
386
|
requiredIndicator
|
|
171
387
|
);
|
|
172
388
|
} else if (variant === "legend") {
|
|
173
|
-
primaryElement = /* @__PURE__ */
|
|
389
|
+
primaryElement = /* @__PURE__ */ React17__namespace.createElement("legend", { "data-slot": "field-legend", className: primaryClasses }, primary, requiredIndicator);
|
|
174
390
|
} else {
|
|
175
|
-
primaryElement = /* @__PURE__ */
|
|
391
|
+
primaryElement = /* @__PURE__ */ React17__namespace.createElement("div", { "data-slot": "field-label", className: primaryClasses }, primary, requiredIndicator);
|
|
176
392
|
}
|
|
177
393
|
}
|
|
178
|
-
const secondaryElement = secondary ? /* @__PURE__ */
|
|
394
|
+
const secondaryElement = secondary ? /* @__PURE__ */ React17__namespace.createElement(
|
|
179
395
|
"p",
|
|
180
396
|
{
|
|
181
397
|
"data-slot": "field-description",
|
|
@@ -186,148 +402,12 @@ var LabelGroup = ({
|
|
|
186
402
|
) : null;
|
|
187
403
|
if (!primaryElement && !secondaryElement) return null;
|
|
188
404
|
if (variant === "legend") {
|
|
189
|
-
return /* @__PURE__ */
|
|
405
|
+
return /* @__PURE__ */ React17__namespace.createElement(React17__namespace.Fragment, null, primaryElement, secondaryElement);
|
|
190
406
|
}
|
|
191
|
-
return /* @__PURE__ */
|
|
407
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, primaryElement, secondaryElement);
|
|
192
408
|
};
|
|
193
409
|
|
|
194
|
-
// src/inputs/
|
|
195
|
-
function Checkbox({
|
|
196
|
-
name,
|
|
197
|
-
value,
|
|
198
|
-
onChange,
|
|
199
|
-
onBlur,
|
|
200
|
-
disabled = false,
|
|
201
|
-
required = false,
|
|
202
|
-
error = false,
|
|
203
|
-
className = "",
|
|
204
|
-
indeterminate = false,
|
|
205
|
-
label,
|
|
206
|
-
description,
|
|
207
|
-
useChoiceCard = false,
|
|
208
|
-
...props
|
|
209
|
-
}) {
|
|
210
|
-
const inputRef = React9__namespace.useRef(null);
|
|
211
|
-
const checkboxId = props.id || `checkbox-${name}`;
|
|
212
|
-
React9__namespace.useEffect(() => {
|
|
213
|
-
if (inputRef.current) {
|
|
214
|
-
inputRef.current.indeterminate = indeterminate;
|
|
215
|
-
}
|
|
216
|
-
}, [indeterminate]);
|
|
217
|
-
const handleChange = (e) => {
|
|
218
|
-
onChange(e.target.checked);
|
|
219
|
-
};
|
|
220
|
-
const handleBlur = () => {
|
|
221
|
-
onBlur?.();
|
|
222
|
-
};
|
|
223
|
-
const isActive = value || indeterminate && !value;
|
|
224
|
-
const checkbox = /* @__PURE__ */ React9__namespace.createElement(
|
|
225
|
-
"div",
|
|
226
|
-
{
|
|
227
|
-
className: cn(
|
|
228
|
-
"relative inline-flex items-center justify-center",
|
|
229
|
-
!label && className
|
|
230
|
-
)
|
|
231
|
-
},
|
|
232
|
-
/* @__PURE__ */ React9__namespace.createElement(
|
|
233
|
-
"input",
|
|
234
|
-
{
|
|
235
|
-
ref: inputRef,
|
|
236
|
-
type: "checkbox",
|
|
237
|
-
id: checkboxId,
|
|
238
|
-
name,
|
|
239
|
-
checked: value,
|
|
240
|
-
onChange: handleChange,
|
|
241
|
-
onBlur: handleBlur,
|
|
242
|
-
disabled,
|
|
243
|
-
required,
|
|
244
|
-
className: "peer sr-only",
|
|
245
|
-
"aria-invalid": error || props["aria-invalid"],
|
|
246
|
-
"aria-describedby": description ? `${checkboxId}-description` : props["aria-describedby"],
|
|
247
|
-
"aria-required": required || props["aria-required"],
|
|
248
|
-
...props
|
|
249
|
-
}
|
|
250
|
-
),
|
|
251
|
-
/* @__PURE__ */ React9__namespace.createElement(
|
|
252
|
-
"div",
|
|
253
|
-
{
|
|
254
|
-
className: cn(
|
|
255
|
-
"flex shrink-0 items-center justify-center rounded-full border-2 transition-colors size-6",
|
|
256
|
-
!error && isActive && "border-primary bg-primary text-primary-foreground",
|
|
257
|
-
!error && !isActive && "border-input bg-transparent",
|
|
258
|
-
error && isActive && "border-destructive bg-destructive text-destructive-foreground",
|
|
259
|
-
error && !isActive && "border-destructive bg-transparent",
|
|
260
|
-
disabled && "opacity-50",
|
|
261
|
-
"peer-focus-visible:ring-2 peer-focus-visible:ring-ring/50 peer-focus-visible:ring-offset-1"
|
|
262
|
-
)
|
|
263
|
-
},
|
|
264
|
-
value && /* @__PURE__ */ React9__namespace.createElement(
|
|
265
|
-
"svg",
|
|
266
|
-
{
|
|
267
|
-
className: "size-3.5",
|
|
268
|
-
viewBox: "0 0 24 24",
|
|
269
|
-
fill: "none",
|
|
270
|
-
stroke: "currentColor",
|
|
271
|
-
strokeWidth: "3",
|
|
272
|
-
strokeLinecap: "round",
|
|
273
|
-
strokeLinejoin: "round"
|
|
274
|
-
},
|
|
275
|
-
/* @__PURE__ */ React9__namespace.createElement("polyline", { points: "20 6 9 17 4 12" })
|
|
276
|
-
),
|
|
277
|
-
indeterminate && !value && /* @__PURE__ */ React9__namespace.createElement(
|
|
278
|
-
"svg",
|
|
279
|
-
{
|
|
280
|
-
className: "size-3.5",
|
|
281
|
-
viewBox: "0 0 24 24",
|
|
282
|
-
fill: "none",
|
|
283
|
-
stroke: "currentColor",
|
|
284
|
-
strokeWidth: "3",
|
|
285
|
-
strokeLinecap: "round",
|
|
286
|
-
strokeLinejoin: "round"
|
|
287
|
-
},
|
|
288
|
-
/* @__PURE__ */ React9__namespace.createElement("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
|
|
289
|
-
)
|
|
290
|
-
)
|
|
291
|
-
);
|
|
292
|
-
if (label) {
|
|
293
|
-
return /* @__PURE__ */ React9__namespace.createElement(
|
|
294
|
-
"label",
|
|
295
|
-
{
|
|
296
|
-
className: cn(
|
|
297
|
-
"w-full h-full flex gap-3 p-3 duration-200",
|
|
298
|
-
useChoiceCard && "border rounded-lg hover:ring-2",
|
|
299
|
-
useChoiceCard && value && "ring-2",
|
|
300
|
-
disabled ? "opacity-50 cursor-not-allowed hover:ring-0" : "cursor-pointer",
|
|
301
|
-
className
|
|
302
|
-
),
|
|
303
|
-
htmlFor: checkboxId
|
|
304
|
-
},
|
|
305
|
-
/* @__PURE__ */ React9__namespace.createElement(
|
|
306
|
-
"div",
|
|
307
|
-
{
|
|
308
|
-
className: cn(
|
|
309
|
-
"flex w-full flex-row gap-2",
|
|
310
|
-
useChoiceCard ? "items-start" : "items-center"
|
|
311
|
-
)
|
|
312
|
-
},
|
|
313
|
-
checkbox,
|
|
314
|
-
/* @__PURE__ */ React9__namespace.createElement(
|
|
315
|
-
LabelGroup,
|
|
316
|
-
{
|
|
317
|
-
variant: "text",
|
|
318
|
-
primary: label,
|
|
319
|
-
secondary: description,
|
|
320
|
-
secondaryId: description ? `${checkboxId}-description` : void 0,
|
|
321
|
-
primaryClassName: "mb-0",
|
|
322
|
-
secondaryClassName: "text-xs opacity-75"
|
|
323
|
-
}
|
|
324
|
-
)
|
|
325
|
-
)
|
|
326
|
-
);
|
|
327
|
-
}
|
|
328
|
-
return checkbox;
|
|
329
|
-
}
|
|
330
|
-
Checkbox.displayName = "Checkbox";
|
|
410
|
+
// src/inputs/CheckboxGroup.tsx
|
|
331
411
|
function CheckboxGroup({
|
|
332
412
|
name,
|
|
333
413
|
value = [],
|
|
@@ -356,11 +436,11 @@ function CheckboxGroup({
|
|
|
356
436
|
).length;
|
|
357
437
|
const allSelected = selectedEnabledCount === enabledOptions.length;
|
|
358
438
|
const someSelected = selectedEnabledCount > 0 && !allSelected;
|
|
359
|
-
const useChoiceCard =
|
|
439
|
+
const useChoiceCard = React17__namespace.useMemo(() => {
|
|
360
440
|
if (!options) return false;
|
|
361
441
|
return options?.some((opt) => opt.description);
|
|
362
442
|
}, [options]);
|
|
363
|
-
const countableValue =
|
|
443
|
+
const countableValue = React17__namespace.useMemo(() => {
|
|
364
444
|
if (value?.length > 0) {
|
|
365
445
|
return value.length;
|
|
366
446
|
}
|
|
@@ -385,7 +465,7 @@ function CheckboxGroup({
|
|
|
385
465
|
onBlur?.();
|
|
386
466
|
};
|
|
387
467
|
const maxReached = Boolean(maxSelections && countableValue >= maxSelections);
|
|
388
|
-
const containerClass =
|
|
468
|
+
const containerClass = React17__namespace.useMemo(() => {
|
|
389
469
|
return cn(
|
|
390
470
|
"w-full gap-3 grid grid-cols-1 border-0 m-0 p-0 min-w-0",
|
|
391
471
|
(layout === "grid" || layout === "inline") && "md:grid-cols-2",
|
|
@@ -394,7 +474,7 @@ function CheckboxGroup({
|
|
|
394
474
|
}, [layout, className]);
|
|
395
475
|
const groupDescriptionId = description ? `${name}-description` : void 0;
|
|
396
476
|
const groupAriaDescribedBy = [props["aria-describedby"], groupDescriptionId].filter(Boolean).join(" ") || void 0;
|
|
397
|
-
return /* @__PURE__ */
|
|
477
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
398
478
|
"fieldset",
|
|
399
479
|
{
|
|
400
480
|
className: containerClass,
|
|
@@ -404,7 +484,7 @@ function CheckboxGroup({
|
|
|
404
484
|
"aria-required": required || props["aria-required"],
|
|
405
485
|
"aria-label": typeof label === "string" ? label : props["aria-label"]
|
|
406
486
|
},
|
|
407
|
-
/* @__PURE__ */
|
|
487
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
408
488
|
LabelGroup,
|
|
409
489
|
{
|
|
410
490
|
labelHtmlFor: name,
|
|
@@ -415,8 +495,8 @@ function CheckboxGroup({
|
|
|
415
495
|
primary: label
|
|
416
496
|
}
|
|
417
497
|
),
|
|
418
|
-
showSelectAll && enabledOptions.length > 0 && /* @__PURE__ */
|
|
419
|
-
|
|
498
|
+
showSelectAll && enabledOptions.length > 0 && /* @__PURE__ */ React17__namespace.createElement(
|
|
499
|
+
Checkbox2,
|
|
420
500
|
{
|
|
421
501
|
name: `${name}-select-all`,
|
|
422
502
|
id: `${name}-select-all`,
|
|
@@ -433,8 +513,8 @@ function CheckboxGroup({
|
|
|
433
513
|
options.map((option) => {
|
|
434
514
|
const isChecked = value.includes(option.value);
|
|
435
515
|
const isDisabled = disabled || option.disabled || maxReached && !isChecked;
|
|
436
|
-
return /* @__PURE__ */
|
|
437
|
-
|
|
516
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
517
|
+
Checkbox2,
|
|
438
518
|
{
|
|
439
519
|
key: option.value,
|
|
440
520
|
name,
|
|
@@ -451,7 +531,7 @@ function CheckboxGroup({
|
|
|
451
531
|
}
|
|
452
532
|
);
|
|
453
533
|
}),
|
|
454
|
-
(minSelections || maxSelections) && /* @__PURE__ */
|
|
534
|
+
(minSelections || maxSelections) && /* @__PURE__ */ React17__namespace.createElement(
|
|
455
535
|
"div",
|
|
456
536
|
{
|
|
457
537
|
className: cn(
|
|
@@ -460,12 +540,66 @@ function CheckboxGroup({
|
|
|
460
540
|
),
|
|
461
541
|
"aria-live": "polite"
|
|
462
542
|
},
|
|
463
|
-
minSelections && countableValue < minSelections && /* @__PURE__ */
|
|
464
|
-
maxSelections && /* @__PURE__ */
|
|
543
|
+
minSelections && countableValue < minSelections && /* @__PURE__ */ React17__namespace.createElement("span", null, "Select at least ", minSelections, " option", minSelections !== 1 ? "s" : ""),
|
|
544
|
+
maxSelections && /* @__PURE__ */ React17__namespace.createElement("span", null, countableValue, "/", maxSelections, " selected")
|
|
465
545
|
)
|
|
466
546
|
);
|
|
467
547
|
}
|
|
468
548
|
CheckboxGroup.displayName = "CheckboxGroup";
|
|
549
|
+
function RadioGroup({
|
|
550
|
+
className,
|
|
551
|
+
...props
|
|
552
|
+
}) {
|
|
553
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
554
|
+
radixUi.RadioGroup.Root,
|
|
555
|
+
{
|
|
556
|
+
"data-slot": "radio-group",
|
|
557
|
+
className: cn("grid gap-3", className),
|
|
558
|
+
...props
|
|
559
|
+
}
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
function RadioGroupItem({
|
|
563
|
+
className,
|
|
564
|
+
...props
|
|
565
|
+
}) {
|
|
566
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
567
|
+
radixUi.RadioGroup.Item,
|
|
568
|
+
{
|
|
569
|
+
"data-slot": "radio-group-item",
|
|
570
|
+
className: cn(
|
|
571
|
+
// Core structure - uses CSS variables
|
|
572
|
+
"aspect-square size-4 shrink-0 rounded-full border border-input bg-transparent shadow-xs",
|
|
573
|
+
"text-primary transition-[color,box-shadow] outline-none",
|
|
574
|
+
// Focus state - uses ring-ring CSS variable
|
|
575
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
576
|
+
// Error state - uses destructive CSS variables
|
|
577
|
+
"aria-invalid:border-destructive aria-invalid:ring-destructive/20",
|
|
578
|
+
// Disabled state
|
|
579
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
580
|
+
className
|
|
581
|
+
),
|
|
582
|
+
...props
|
|
583
|
+
},
|
|
584
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
585
|
+
radixUi.RadioGroup.Indicator,
|
|
586
|
+
{
|
|
587
|
+
"data-slot": "radio-group-indicator",
|
|
588
|
+
className: "relative flex items-center justify-center"
|
|
589
|
+
},
|
|
590
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
591
|
+
"svg",
|
|
592
|
+
{
|
|
593
|
+
className: "fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2",
|
|
594
|
+
viewBox: "0 0 24 24"
|
|
595
|
+
},
|
|
596
|
+
/* @__PURE__ */ React17__namespace.createElement("circle", { cx: "12", cy: "12", r: "12" })
|
|
597
|
+
)
|
|
598
|
+
)
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// src/inputs/Radio.tsx
|
|
469
603
|
function Radio({
|
|
470
604
|
name,
|
|
471
605
|
value,
|
|
@@ -481,146 +615,433 @@ function Radio({
|
|
|
481
615
|
options,
|
|
482
616
|
...props
|
|
483
617
|
}) {
|
|
484
|
-
const
|
|
485
|
-
onChange(
|
|
486
|
-
};
|
|
487
|
-
const handleKeyDown = (e, currentIndex) => {
|
|
488
|
-
if (e.key === "ArrowDown" || e.key === "ArrowRight") {
|
|
489
|
-
e.preventDefault();
|
|
490
|
-
let nextIndex = (currentIndex + 1) % options.length;
|
|
491
|
-
let attempts = 0;
|
|
492
|
-
while (options[nextIndex].disabled && attempts < options.length && !disabled) {
|
|
493
|
-
nextIndex = (nextIndex + 1) % options.length;
|
|
494
|
-
attempts++;
|
|
495
|
-
}
|
|
496
|
-
if (!options[nextIndex].disabled) {
|
|
497
|
-
handleChange(options[nextIndex].value);
|
|
498
|
-
}
|
|
499
|
-
} else if (e.key === "ArrowUp" || e.key === "ArrowLeft") {
|
|
500
|
-
e.preventDefault();
|
|
501
|
-
let prevIndex = (currentIndex - 1 + options.length) % options.length;
|
|
502
|
-
let attempts = 0;
|
|
503
|
-
while (options[prevIndex].disabled && attempts < options.length && !disabled) {
|
|
504
|
-
prevIndex = (prevIndex - 1 + options.length) % options.length;
|
|
505
|
-
attempts++;
|
|
506
|
-
}
|
|
507
|
-
if (!options[prevIndex].disabled) {
|
|
508
|
-
handleChange(options[prevIndex].value);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
618
|
+
const handleValueChange = (selectedValue) => {
|
|
619
|
+
onChange(selectedValue);
|
|
511
620
|
};
|
|
512
621
|
const handleBlur = () => {
|
|
513
622
|
onBlur?.();
|
|
514
623
|
};
|
|
515
|
-
const useChoiceCard =
|
|
624
|
+
const useChoiceCard = React17__namespace.useMemo(() => {
|
|
516
625
|
return options.some((option) => option.description);
|
|
517
626
|
}, [options]);
|
|
518
|
-
const containerClass = React9__namespace.useMemo(() => {
|
|
519
|
-
return cn(
|
|
520
|
-
"w-full gap-3 grid grid-cols-1 border-0 m-0 p-0 min-w-0",
|
|
521
|
-
(layout === "grid" || layout === "inline") && "md:grid-cols-2",
|
|
522
|
-
className
|
|
523
|
-
);
|
|
524
|
-
}, [layout, className]);
|
|
525
627
|
const groupDescriptionId = description ? `${name}-description` : void 0;
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
"fieldset",
|
|
628
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { className: cn("w-full", className) }, (label || description) && /* @__PURE__ */ React17__namespace.createElement("div", { className: "mb-3" }, label && /* @__PURE__ */ React17__namespace.createElement(Label, { className: "text-base font-medium block mb-1" }, label), description && /* @__PURE__ */ React17__namespace.createElement(
|
|
629
|
+
"p",
|
|
529
630
|
{
|
|
530
|
-
|
|
531
|
-
|
|
631
|
+
id: groupDescriptionId,
|
|
632
|
+
className: "text-sm opacity-70"
|
|
633
|
+
},
|
|
634
|
+
description
|
|
635
|
+
)), /* @__PURE__ */ React17__namespace.createElement(
|
|
636
|
+
RadioGroup,
|
|
637
|
+
{
|
|
638
|
+
name,
|
|
639
|
+
value,
|
|
640
|
+
onValueChange: handleValueChange,
|
|
641
|
+
onBlur: handleBlur,
|
|
642
|
+
disabled,
|
|
643
|
+
required,
|
|
644
|
+
className: cn(
|
|
645
|
+
"gap-3",
|
|
646
|
+
layout === "grid" && "grid grid-cols-1 md:grid-cols-2",
|
|
647
|
+
layout === "inline" && "flex flex-wrap"
|
|
648
|
+
),
|
|
532
649
|
"aria-invalid": error || props["aria-invalid"],
|
|
533
|
-
"aria-describedby":
|
|
534
|
-
"aria-required": required || props["aria-required"]
|
|
535
|
-
"aria-label": typeof label === "string" ? label : props["aria-label"]
|
|
650
|
+
"aria-describedby": groupDescriptionId || props["aria-describedby"],
|
|
651
|
+
"aria-required": required || props["aria-required"]
|
|
536
652
|
},
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
{
|
|
540
|
-
variant: "legend",
|
|
541
|
-
primary: label,
|
|
542
|
-
secondary: description,
|
|
543
|
-
secondaryId: groupDescriptionId
|
|
544
|
-
}
|
|
545
|
-
),
|
|
546
|
-
options.map((option, index) => {
|
|
547
|
-
const isChecked = value === option.value;
|
|
653
|
+
options.map((option) => {
|
|
654
|
+
const isSelected = value === option.value;
|
|
548
655
|
const isDisabled = disabled || option.disabled;
|
|
549
656
|
const radioId = `${name}-${option.value}`;
|
|
550
|
-
const hasDescription = option.description
|
|
551
|
-
|
|
552
|
-
"input",
|
|
553
|
-
{
|
|
554
|
-
type: "radio",
|
|
555
|
-
id: radioId,
|
|
556
|
-
name,
|
|
557
|
-
value: option.value,
|
|
558
|
-
checked: isChecked,
|
|
559
|
-
onChange: (e) => handleChange(e.target.value),
|
|
560
|
-
onBlur: handleBlur,
|
|
561
|
-
disabled: isDisabled,
|
|
562
|
-
required,
|
|
563
|
-
className: "peer sr-only",
|
|
564
|
-
"aria-describedby": hasDescription ? `${radioId}-description` : props["aria-describedby"]
|
|
565
|
-
}
|
|
566
|
-
), /* @__PURE__ */ React9__namespace.createElement(
|
|
567
|
-
"div",
|
|
568
|
-
{
|
|
569
|
-
className: cn(
|
|
570
|
-
"flex shrink-0 items-center justify-center rounded-full border-2 transition-colors size-6",
|
|
571
|
-
!error && isChecked && "border-primary bg-transparent",
|
|
572
|
-
!error && !isChecked && "border-input bg-transparent",
|
|
573
|
-
error && isChecked && "border-destructive bg-transparent",
|
|
574
|
-
error && !isChecked && "border-destructive bg-transparent",
|
|
575
|
-
isDisabled && "opacity-50",
|
|
576
|
-
"peer-focus-visible:ring-2 peer-focus-visible:ring-ring/50 peer-focus-visible:ring-offset-1"
|
|
577
|
-
)
|
|
578
|
-
},
|
|
579
|
-
isChecked && /* @__PURE__ */ React9__namespace.createElement("div", { className: "size-3 rounded-full bg-primary" })
|
|
580
|
-
));
|
|
581
|
-
const labelContent = /* @__PURE__ */ React9__namespace.createElement(
|
|
582
|
-
LabelGroup,
|
|
583
|
-
{
|
|
584
|
-
variant: "text",
|
|
585
|
-
primary: option.label,
|
|
586
|
-
secondary: hasDescription ? option.description : void 0,
|
|
587
|
-
secondaryId: hasDescription ? `${radioId}-description` : void 0,
|
|
588
|
-
primaryClassName: "mb-0",
|
|
589
|
-
secondaryClassName: "text-xs opacity-75"
|
|
590
|
-
}
|
|
591
|
-
);
|
|
592
|
-
return /* @__PURE__ */ React9__namespace.createElement(
|
|
657
|
+
const hasDescription = !!option.description;
|
|
658
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
593
659
|
"label",
|
|
594
660
|
{
|
|
595
661
|
key: option.value,
|
|
596
|
-
className: cn(
|
|
597
|
-
"w-full h-full flex gap-3 p-3 duration-200",
|
|
598
|
-
useChoiceCard && "border rounded-lg hover:ring-2",
|
|
599
|
-
useChoiceCard && isChecked && "ring-2",
|
|
600
|
-
isDisabled ? "opacity-50 cursor-not-allowed hover:ring-0" : "cursor-pointer"
|
|
601
|
-
),
|
|
602
662
|
htmlFor: radioId,
|
|
603
|
-
|
|
604
|
-
|
|
663
|
+
className: cn(
|
|
664
|
+
"flex gap-3 p-3 duration-200",
|
|
665
|
+
useChoiceCard && "border rounded-lg hover:ring-2 hover:ring-ring/50",
|
|
666
|
+
useChoiceCard && isSelected && "ring-2 ring-ring",
|
|
667
|
+
useChoiceCard && error && "border-destructive",
|
|
668
|
+
isDisabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"
|
|
669
|
+
)
|
|
605
670
|
},
|
|
606
|
-
/* @__PURE__ */
|
|
671
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
607
672
|
"div",
|
|
608
673
|
{
|
|
609
674
|
className: cn(
|
|
610
|
-
"flex w-full
|
|
675
|
+
"flex w-full gap-3",
|
|
611
676
|
useChoiceCard ? "items-start" : "items-center"
|
|
612
677
|
)
|
|
613
678
|
},
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
679
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
680
|
+
RadioGroupItem,
|
|
681
|
+
{
|
|
682
|
+
value: option.value,
|
|
683
|
+
id: radioId,
|
|
684
|
+
disabled: isDisabled,
|
|
685
|
+
className: "mt-0.5",
|
|
686
|
+
"aria-describedby": hasDescription ? `${radioId}-description` : void 0
|
|
687
|
+
}
|
|
688
|
+
),
|
|
689
|
+
/* @__PURE__ */ React17__namespace.createElement("div", { className: "flex flex-col gap-1 flex-1" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
690
|
+
Label,
|
|
691
|
+
{
|
|
692
|
+
htmlFor: radioId,
|
|
693
|
+
className: "cursor-pointer font-medium leading-none"
|
|
694
|
+
},
|
|
695
|
+
option.label
|
|
696
|
+
), option.description && /* @__PURE__ */ React17__namespace.createElement(
|
|
697
|
+
"p",
|
|
698
|
+
{
|
|
699
|
+
id: `${radioId}-description`,
|
|
700
|
+
className: "text-sm opacity-70 leading-snug"
|
|
701
|
+
},
|
|
702
|
+
option.description
|
|
703
|
+
))
|
|
617
704
|
)
|
|
618
705
|
);
|
|
619
706
|
})
|
|
707
|
+
));
|
|
708
|
+
}
|
|
709
|
+
Radio.displayName = "Radio";
|
|
710
|
+
function Switch({
|
|
711
|
+
className,
|
|
712
|
+
size = "default",
|
|
713
|
+
...props
|
|
714
|
+
}) {
|
|
715
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
716
|
+
radixUi.Switch.Root,
|
|
717
|
+
{
|
|
718
|
+
"data-slot": "switch",
|
|
719
|
+
"data-size": size,
|
|
720
|
+
className: cn(
|
|
721
|
+
// Core structure - uses CSS variables
|
|
722
|
+
"peer group/switch inline-flex shrink-0 items-center rounded-full",
|
|
723
|
+
"border border-transparent shadow-xs transition-all outline-none",
|
|
724
|
+
// State-based backgrounds - use CSS variables
|
|
725
|
+
"data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
|
|
726
|
+
// Focus state
|
|
727
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
728
|
+
// Disabled state
|
|
729
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
730
|
+
// Size variants
|
|
731
|
+
"data-[size=default]:h-[1.15rem] data-[size=default]:w-8",
|
|
732
|
+
"data-[size=sm]:h-3.5 data-[size=sm]:w-6",
|
|
733
|
+
className
|
|
734
|
+
),
|
|
735
|
+
...props
|
|
736
|
+
},
|
|
737
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
738
|
+
radixUi.Switch.Thumb,
|
|
739
|
+
{
|
|
740
|
+
"data-slot": "switch-thumb",
|
|
741
|
+
className: cn(
|
|
742
|
+
// Thumb appearance - inherits from parent theme
|
|
743
|
+
"bg-background pointer-events-none block rounded-full ring-0 transition-transform",
|
|
744
|
+
// Size variants
|
|
745
|
+
"group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3",
|
|
746
|
+
// Position based on state
|
|
747
|
+
"data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
|
|
748
|
+
)
|
|
749
|
+
}
|
|
750
|
+
)
|
|
751
|
+
);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// src/inputs/Switch.tsx
|
|
755
|
+
function Switch2({
|
|
756
|
+
name,
|
|
757
|
+
value,
|
|
758
|
+
onChange,
|
|
759
|
+
onBlur,
|
|
760
|
+
disabled = false,
|
|
761
|
+
required = false,
|
|
762
|
+
error = false,
|
|
763
|
+
className = "",
|
|
764
|
+
label,
|
|
765
|
+
description,
|
|
766
|
+
size = "default",
|
|
767
|
+
...props
|
|
768
|
+
}) {
|
|
769
|
+
const switchId = props.id || `switch-${name}`;
|
|
770
|
+
const handleCheckedChange = (checked) => {
|
|
771
|
+
onChange(checked);
|
|
772
|
+
};
|
|
773
|
+
const handleBlur = () => {
|
|
774
|
+
onBlur?.();
|
|
775
|
+
};
|
|
776
|
+
const switchElement = /* @__PURE__ */ React17__namespace.createElement(
|
|
777
|
+
Switch,
|
|
778
|
+
{
|
|
779
|
+
id: switchId,
|
|
780
|
+
checked: value,
|
|
781
|
+
onCheckedChange: handleCheckedChange,
|
|
782
|
+
onBlur: handleBlur,
|
|
783
|
+
disabled,
|
|
784
|
+
size,
|
|
785
|
+
"aria-invalid": error || props["aria-invalid"],
|
|
786
|
+
"aria-describedby": description ? `${switchId}-description` : props["aria-describedby"],
|
|
787
|
+
"aria-required": required || props["aria-required"],
|
|
788
|
+
...props
|
|
789
|
+
}
|
|
790
|
+
);
|
|
791
|
+
if (!label) {
|
|
792
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { className }, switchElement);
|
|
793
|
+
}
|
|
794
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
795
|
+
"label",
|
|
796
|
+
{
|
|
797
|
+
htmlFor: switchId,
|
|
798
|
+
className: cn(
|
|
799
|
+
"flex items-center gap-3 cursor-pointer",
|
|
800
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
801
|
+
className
|
|
802
|
+
)
|
|
803
|
+
},
|
|
804
|
+
switchElement,
|
|
805
|
+
/* @__PURE__ */ React17__namespace.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
806
|
+
Label,
|
|
807
|
+
{
|
|
808
|
+
htmlFor: switchId,
|
|
809
|
+
className: "cursor-pointer font-medium leading-none"
|
|
810
|
+
},
|
|
811
|
+
label
|
|
812
|
+
), description && /* @__PURE__ */ React17__namespace.createElement(
|
|
813
|
+
"p",
|
|
814
|
+
{
|
|
815
|
+
id: `${switchId}-description`,
|
|
816
|
+
className: "text-sm opacity-70 leading-snug"
|
|
817
|
+
},
|
|
818
|
+
description
|
|
819
|
+
))
|
|
820
|
+
);
|
|
821
|
+
}
|
|
822
|
+
Switch2.displayName = "Switch";
|
|
823
|
+
function Select({
|
|
824
|
+
...props
|
|
825
|
+
}) {
|
|
826
|
+
return /* @__PURE__ */ React17__namespace.createElement(radixUi.Select.Root, { "data-slot": "select", ...props });
|
|
827
|
+
}
|
|
828
|
+
function SelectGroup({
|
|
829
|
+
...props
|
|
830
|
+
}) {
|
|
831
|
+
return /* @__PURE__ */ React17__namespace.createElement(radixUi.Select.Group, { "data-slot": "select-group", ...props });
|
|
832
|
+
}
|
|
833
|
+
function SelectValue({
|
|
834
|
+
...props
|
|
835
|
+
}) {
|
|
836
|
+
return /* @__PURE__ */ React17__namespace.createElement(radixUi.Select.Value, { "data-slot": "select-value", ...props });
|
|
837
|
+
}
|
|
838
|
+
function SelectTrigger({
|
|
839
|
+
className,
|
|
840
|
+
size = "default",
|
|
841
|
+
children,
|
|
842
|
+
...props
|
|
843
|
+
}) {
|
|
844
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
845
|
+
radixUi.Select.Trigger,
|
|
846
|
+
{
|
|
847
|
+
"data-slot": "select-trigger",
|
|
848
|
+
"data-size": size,
|
|
849
|
+
className: cn(
|
|
850
|
+
// Core structure - uses CSS variables
|
|
851
|
+
"flex w-fit items-center justify-between gap-2 rounded-md border border-input",
|
|
852
|
+
"bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs",
|
|
853
|
+
"transition-[color,box-shadow] outline-none",
|
|
854
|
+
// Focus state
|
|
855
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
856
|
+
// Error state
|
|
857
|
+
"aria-invalid:border-destructive aria-invalid:ring-destructive/20",
|
|
858
|
+
// Disabled state
|
|
859
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
860
|
+
// Size variants
|
|
861
|
+
"data-[size=default]:h-9 data-[size=sm]:h-8",
|
|
862
|
+
// Value styling
|
|
863
|
+
"*:data-[slot=select-value]:line-clamp-1",
|
|
864
|
+
"*:data-[slot=select-value]:flex",
|
|
865
|
+
"*:data-[slot=select-value]:items-center",
|
|
866
|
+
"*:data-[slot=select-value]:gap-2",
|
|
867
|
+
// SVG styling
|
|
868
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
869
|
+
className
|
|
870
|
+
),
|
|
871
|
+
...props
|
|
872
|
+
},
|
|
873
|
+
children,
|
|
874
|
+
/* @__PURE__ */ React17__namespace.createElement(radixUi.Select.Icon, { asChild: true }, /* @__PURE__ */ React17__namespace.createElement(
|
|
875
|
+
"svg",
|
|
876
|
+
{
|
|
877
|
+
className: "size-4 opacity-50",
|
|
878
|
+
viewBox: "0 0 24 24",
|
|
879
|
+
fill: "none",
|
|
880
|
+
stroke: "currentColor",
|
|
881
|
+
strokeWidth: "2",
|
|
882
|
+
strokeLinecap: "round",
|
|
883
|
+
strokeLinejoin: "round"
|
|
884
|
+
},
|
|
885
|
+
/* @__PURE__ */ React17__namespace.createElement("polyline", { points: "6 9 12 15 18 9" })
|
|
886
|
+
))
|
|
887
|
+
);
|
|
888
|
+
}
|
|
889
|
+
function SelectContent({
|
|
890
|
+
className,
|
|
891
|
+
children,
|
|
892
|
+
position = "item-aligned",
|
|
893
|
+
align = "center",
|
|
894
|
+
...props
|
|
895
|
+
}) {
|
|
896
|
+
return /* @__PURE__ */ React17__namespace.createElement(radixUi.Select.Portal, null, /* @__PURE__ */ React17__namespace.createElement(
|
|
897
|
+
radixUi.Select.Content,
|
|
898
|
+
{
|
|
899
|
+
"data-slot": "select-content",
|
|
900
|
+
className: cn(
|
|
901
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
|
|
902
|
+
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
903
|
+
className
|
|
904
|
+
),
|
|
905
|
+
position,
|
|
906
|
+
align,
|
|
907
|
+
...props
|
|
908
|
+
},
|
|
909
|
+
/* @__PURE__ */ React17__namespace.createElement(SelectScrollUpButton, null),
|
|
910
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
911
|
+
radixUi.Select.Viewport,
|
|
912
|
+
{
|
|
913
|
+
className: cn(
|
|
914
|
+
"p-1",
|
|
915
|
+
position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
|
|
916
|
+
)
|
|
917
|
+
},
|
|
918
|
+
children
|
|
919
|
+
),
|
|
920
|
+
/* @__PURE__ */ React17__namespace.createElement(SelectScrollDownButton, null)
|
|
921
|
+
));
|
|
922
|
+
}
|
|
923
|
+
function SelectLabel({
|
|
924
|
+
className,
|
|
925
|
+
...props
|
|
926
|
+
}) {
|
|
927
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
928
|
+
radixUi.Select.Label,
|
|
929
|
+
{
|
|
930
|
+
"data-slot": "select-label",
|
|
931
|
+
className: cn("px-2 py-1.5 text-xs opacity-70", className),
|
|
932
|
+
...props
|
|
933
|
+
}
|
|
934
|
+
);
|
|
935
|
+
}
|
|
936
|
+
function SelectItem({
|
|
937
|
+
className,
|
|
938
|
+
children,
|
|
939
|
+
...props
|
|
940
|
+
}) {
|
|
941
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
942
|
+
radixUi.Select.Item,
|
|
943
|
+
{
|
|
944
|
+
"data-slot": "select-item",
|
|
945
|
+
className: cn(
|
|
946
|
+
// Core structure - inherits text color
|
|
947
|
+
"relative flex w-full cursor-default items-center gap-2 rounded-sm",
|
|
948
|
+
"py-1.5 pr-8 pl-2 text-sm outline-hidden select-none",
|
|
949
|
+
// Focus state - uses accent CSS variable
|
|
950
|
+
"focus:bg-accent focus:text-accent-foreground",
|
|
951
|
+
// Disabled state
|
|
952
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
953
|
+
// SVG styling
|
|
954
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
955
|
+
// Span styling
|
|
956
|
+
"*:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
957
|
+
className
|
|
958
|
+
),
|
|
959
|
+
...props
|
|
960
|
+
},
|
|
961
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
962
|
+
"span",
|
|
963
|
+
{
|
|
964
|
+
"data-slot": "select-item-indicator",
|
|
965
|
+
className: "absolute right-2 flex size-3.5 items-center justify-center"
|
|
966
|
+
},
|
|
967
|
+
/* @__PURE__ */ React17__namespace.createElement(radixUi.Select.ItemIndicator, null, /* @__PURE__ */ React17__namespace.createElement(
|
|
968
|
+
"svg",
|
|
969
|
+
{
|
|
970
|
+
className: "size-4",
|
|
971
|
+
viewBox: "0 0 24 24",
|
|
972
|
+
fill: "none",
|
|
973
|
+
stroke: "currentColor",
|
|
974
|
+
strokeWidth: "3",
|
|
975
|
+
strokeLinecap: "round",
|
|
976
|
+
strokeLinejoin: "round"
|
|
977
|
+
},
|
|
978
|
+
/* @__PURE__ */ React17__namespace.createElement("polyline", { points: "20 6 9 17 4 12" })
|
|
979
|
+
))
|
|
980
|
+
),
|
|
981
|
+
/* @__PURE__ */ React17__namespace.createElement(radixUi.Select.ItemText, null, children)
|
|
620
982
|
);
|
|
621
983
|
}
|
|
622
|
-
|
|
623
|
-
|
|
984
|
+
function SelectScrollUpButton({
|
|
985
|
+
className,
|
|
986
|
+
...props
|
|
987
|
+
}) {
|
|
988
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
989
|
+
radixUi.Select.ScrollUpButton,
|
|
990
|
+
{
|
|
991
|
+
"data-slot": "select-scroll-up-button",
|
|
992
|
+
className: cn(
|
|
993
|
+
"flex cursor-default items-center justify-center py-1",
|
|
994
|
+
className
|
|
995
|
+
),
|
|
996
|
+
...props
|
|
997
|
+
},
|
|
998
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
999
|
+
"svg",
|
|
1000
|
+
{
|
|
1001
|
+
className: "size-4",
|
|
1002
|
+
viewBox: "0 0 24 24",
|
|
1003
|
+
fill: "none",
|
|
1004
|
+
stroke: "currentColor",
|
|
1005
|
+
strokeWidth: "2",
|
|
1006
|
+
strokeLinecap: "round",
|
|
1007
|
+
strokeLinejoin: "round"
|
|
1008
|
+
},
|
|
1009
|
+
/* @__PURE__ */ React17__namespace.createElement("polyline", { points: "18 15 12 9 6 15" })
|
|
1010
|
+
)
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
function SelectScrollDownButton({
|
|
1014
|
+
className,
|
|
1015
|
+
...props
|
|
1016
|
+
}) {
|
|
1017
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
1018
|
+
radixUi.Select.ScrollDownButton,
|
|
1019
|
+
{
|
|
1020
|
+
"data-slot": "select-scroll-down-button",
|
|
1021
|
+
className: cn(
|
|
1022
|
+
"flex cursor-default items-center justify-center py-1",
|
|
1023
|
+
className
|
|
1024
|
+
),
|
|
1025
|
+
...props
|
|
1026
|
+
},
|
|
1027
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
1028
|
+
"svg",
|
|
1029
|
+
{
|
|
1030
|
+
className: "size-4",
|
|
1031
|
+
viewBox: "0 0 24 24",
|
|
1032
|
+
fill: "none",
|
|
1033
|
+
stroke: "currentColor",
|
|
1034
|
+
strokeWidth: "2",
|
|
1035
|
+
strokeLinecap: "round",
|
|
1036
|
+
strokeLinejoin: "round"
|
|
1037
|
+
},
|
|
1038
|
+
/* @__PURE__ */ React17__namespace.createElement("polyline", { points: "6 9 12 15 18 9" })
|
|
1039
|
+
)
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
// src/inputs/Select.tsx
|
|
1044
|
+
function Select2({
|
|
624
1045
|
name,
|
|
625
1046
|
value,
|
|
626
1047
|
onChange,
|
|
@@ -631,283 +1052,83 @@ function Select({
|
|
|
631
1052
|
error = false,
|
|
632
1053
|
className = "",
|
|
633
1054
|
placeholder = "Select...",
|
|
634
|
-
searchable = true,
|
|
635
|
-
clearable = true,
|
|
636
|
-
loading = false,
|
|
637
1055
|
options = [],
|
|
638
1056
|
optionGroups = [],
|
|
639
1057
|
renderOption,
|
|
640
1058
|
...props
|
|
641
1059
|
}) {
|
|
642
|
-
const [
|
|
643
|
-
const
|
|
644
|
-
const [focusedIndex, setFocusedIndex] = React9__namespace.useState(-1);
|
|
645
|
-
const triggerRef = React9__namespace.useRef(null);
|
|
646
|
-
const dropdownRef = React9__namespace.useRef(null);
|
|
647
|
-
const searchInputRef = React9__namespace.useRef(null);
|
|
648
|
-
const dropdownId = `${name}-dropdown`;
|
|
649
|
-
const allOptions = React9__namespace.useMemo(() => {
|
|
1060
|
+
const [hasInteracted, setHasInteracted] = React17__namespace.useState(false);
|
|
1061
|
+
const allOptions = React17__namespace.useMemo(() => {
|
|
650
1062
|
if (optionGroups.length > 0) {
|
|
651
1063
|
return optionGroups.flatMap((group) => group.options);
|
|
652
1064
|
}
|
|
653
1065
|
return options;
|
|
654
1066
|
}, [options, optionGroups]);
|
|
655
|
-
const filteredOptions = React9__namespace.useMemo(() => {
|
|
656
|
-
if (!searchQuery.trim()) {
|
|
657
|
-
return allOptions;
|
|
658
|
-
}
|
|
659
|
-
const query = searchQuery.toLowerCase();
|
|
660
|
-
return allOptions.filter((option) => {
|
|
661
|
-
const label = typeof option.label === "string" ? option.label : String(option.label);
|
|
662
|
-
return label.toLowerCase().includes(query);
|
|
663
|
-
});
|
|
664
|
-
}, [allOptions, searchQuery]);
|
|
665
|
-
const selectedOption = React9__namespace.useMemo(() => {
|
|
666
|
-
return allOptions.find((opt) => opt.value === value);
|
|
667
|
-
}, [allOptions, value]);
|
|
668
1067
|
const hasValue = Boolean(value);
|
|
669
|
-
const
|
|
670
|
-
onChange(
|
|
671
|
-
setIsOpen(false);
|
|
672
|
-
setSearchQuery("");
|
|
673
|
-
setFocusedIndex(-1);
|
|
674
|
-
};
|
|
675
|
-
const handleClear = (e) => {
|
|
676
|
-
e.stopPropagation();
|
|
677
|
-
onChange("");
|
|
678
|
-
setSearchQuery("");
|
|
679
|
-
setFocusedIndex(-1);
|
|
1068
|
+
const handleValueChange = (newValue) => {
|
|
1069
|
+
onChange(newValue);
|
|
680
1070
|
};
|
|
681
|
-
const
|
|
682
|
-
if (
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
setTimeout(() => searchInputRef.current?.focus(), 0);
|
|
687
|
-
}
|
|
688
|
-
if (newIsOpen) {
|
|
1071
|
+
const handleOpenChange = (open) => {
|
|
1072
|
+
if (open) {
|
|
1073
|
+
if (!hasInteracted) {
|
|
1074
|
+
setHasInteracted(true);
|
|
1075
|
+
}
|
|
689
1076
|
onFocus?.();
|
|
690
|
-
}
|
|
691
|
-
};
|
|
692
|
-
const handleSearchChange = (e) => {
|
|
693
|
-
setSearchQuery(e.target.value);
|
|
694
|
-
setFocusedIndex(0);
|
|
695
|
-
};
|
|
696
|
-
const handleKeyDown = (e) => {
|
|
697
|
-
if (disabled) return;
|
|
698
|
-
switch (e.key) {
|
|
699
|
-
case "ArrowDown":
|
|
700
|
-
e.preventDefault();
|
|
701
|
-
if (!isOpen) {
|
|
702
|
-
setIsOpen(true);
|
|
703
|
-
setFocusedIndex(0);
|
|
704
|
-
} else {
|
|
705
|
-
const enabledOptions = filteredOptions.filter((opt) => !opt.disabled);
|
|
706
|
-
if (enabledOptions.length > 0) {
|
|
707
|
-
const currentIndexInFiltered = focusedIndex;
|
|
708
|
-
const nextIndex = (currentIndexInFiltered + 1) % enabledOptions.length;
|
|
709
|
-
setFocusedIndex(filteredOptions.indexOf(enabledOptions[nextIndex]));
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
break;
|
|
713
|
-
case "ArrowUp":
|
|
714
|
-
e.preventDefault();
|
|
715
|
-
if (isOpen) {
|
|
716
|
-
const enabledOptions = filteredOptions.filter((opt) => !opt.disabled);
|
|
717
|
-
if (enabledOptions.length > 0) {
|
|
718
|
-
const currentIndexInFiltered = focusedIndex;
|
|
719
|
-
const prevIndex = (currentIndexInFiltered - 1 + enabledOptions.length) % enabledOptions.length;
|
|
720
|
-
setFocusedIndex(filteredOptions.indexOf(enabledOptions[prevIndex]));
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
break;
|
|
724
|
-
case "Enter":
|
|
725
|
-
e.preventDefault();
|
|
726
|
-
if (isOpen && focusedIndex >= 0 && focusedIndex < filteredOptions.length) {
|
|
727
|
-
const focusedOption = filteredOptions[focusedIndex];
|
|
728
|
-
if (!focusedOption.disabled) {
|
|
729
|
-
handleSelect(focusedOption.value);
|
|
730
|
-
}
|
|
731
|
-
} else if (!isOpen) {
|
|
732
|
-
setIsOpen(true);
|
|
733
|
-
}
|
|
734
|
-
break;
|
|
735
|
-
case "Escape":
|
|
736
|
-
e.preventDefault();
|
|
737
|
-
if (isOpen) {
|
|
738
|
-
setIsOpen(false);
|
|
739
|
-
setSearchQuery("");
|
|
740
|
-
setFocusedIndex(-1);
|
|
741
|
-
}
|
|
742
|
-
break;
|
|
743
|
-
case " ":
|
|
744
|
-
if (!isOpen && !searchable) {
|
|
745
|
-
e.preventDefault();
|
|
746
|
-
setIsOpen(true);
|
|
747
|
-
}
|
|
748
|
-
break;
|
|
749
|
-
default:
|
|
750
|
-
if (!searchable && e.key.length === 1 && !e.ctrlKey && !e.metaKey) {
|
|
751
|
-
const char = e.key.toLowerCase();
|
|
752
|
-
const matchingOption = filteredOptions.find((opt) => {
|
|
753
|
-
const label = typeof opt.label === "string" ? opt.label : String(opt.label);
|
|
754
|
-
return label.toLowerCase().startsWith(char) && !opt.disabled;
|
|
755
|
-
});
|
|
756
|
-
if (matchingOption) {
|
|
757
|
-
handleSelect(matchingOption.value);
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
break;
|
|
761
|
-
}
|
|
762
|
-
};
|
|
763
|
-
const handleBlur = (event) => {
|
|
764
|
-
const nextTarget = event?.relatedTarget;
|
|
765
|
-
const focusStayedInside = !!triggerRef.current && triggerRef.current.contains(nextTarget) || !!dropdownRef.current && dropdownRef.current.contains(nextTarget);
|
|
766
|
-
if (!nextTarget || !focusStayedInside) {
|
|
1077
|
+
} else if (hasInteracted) {
|
|
767
1078
|
onBlur?.();
|
|
768
1079
|
}
|
|
769
1080
|
};
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
setSearchQuery("");
|
|
773
|
-
setFocusedIndex(-1);
|
|
774
|
-
onBlur?.();
|
|
775
|
-
}, [onBlur]);
|
|
776
|
-
useOnClickOutside.useOnClickOutside([triggerRef, dropdownRef], closeDropdown, void 0, {
|
|
777
|
-
capture: true
|
|
778
|
-
});
|
|
779
|
-
const combinedClassName = cn("relative w-full", className);
|
|
780
|
-
return /* @__PURE__ */ React9__namespace.createElement(
|
|
781
|
-
"div",
|
|
1081
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
1082
|
+
Select,
|
|
782
1083
|
{
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
1084
|
+
name,
|
|
1085
|
+
value,
|
|
1086
|
+
onValueChange: handleValueChange,
|
|
1087
|
+
onOpenChange: handleOpenChange,
|
|
1088
|
+
disabled,
|
|
1089
|
+
required
|
|
786
1090
|
},
|
|
787
|
-
/* @__PURE__ */
|
|
788
|
-
|
|
789
|
-
{
|
|
790
|
-
name,
|
|
791
|
-
value,
|
|
792
|
-
onChange: () => {
|
|
793
|
-
},
|
|
794
|
-
disabled,
|
|
795
|
-
required,
|
|
796
|
-
"aria-hidden": "true",
|
|
797
|
-
tabIndex: -1,
|
|
798
|
-
style: { display: "none" }
|
|
799
|
-
},
|
|
800
|
-
/* @__PURE__ */ React9__namespace.createElement("option", { value: "" }, "Select..."),
|
|
801
|
-
allOptions.map((option) => /* @__PURE__ */ React9__namespace.createElement("option", { key: option.value, value: option.value }, typeof option.label === "string" ? option.label : option.value))
|
|
802
|
-
),
|
|
803
|
-
/* @__PURE__ */ React9__namespace.createElement(
|
|
804
|
-
"div",
|
|
1091
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
1092
|
+
SelectTrigger,
|
|
805
1093
|
{
|
|
806
|
-
ref: triggerRef,
|
|
807
1094
|
className: cn(
|
|
808
|
-
|
|
809
|
-
"cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
1095
|
+
// Valid value indicator - ring-2 when has value and no error
|
|
810
1096
|
!error && hasValue && "ring-2 ring-ring",
|
|
811
|
-
|
|
812
|
-
|
|
1097
|
+
// Error state - handled by SelectTrigger via aria-invalid
|
|
1098
|
+
className
|
|
813
1099
|
),
|
|
814
|
-
onClick: handleToggle,
|
|
815
|
-
role: "combobox",
|
|
816
|
-
"aria-expanded": isOpen,
|
|
817
|
-
"aria-controls": dropdownId,
|
|
818
1100
|
"aria-invalid": error || props["aria-invalid"],
|
|
819
1101
|
"aria-describedby": props["aria-describedby"],
|
|
820
|
-
"aria-required": required || props["aria-required"]
|
|
821
|
-
"aria-disabled": disabled,
|
|
822
|
-
tabIndex: disabled ? -1 : 0
|
|
1102
|
+
"aria-required": required || props["aria-required"]
|
|
823
1103
|
},
|
|
824
|
-
/* @__PURE__ */
|
|
825
|
-
|
|
826
|
-
|
|
1104
|
+
/* @__PURE__ */ React17__namespace.createElement(SelectValue, { placeholder })
|
|
1105
|
+
),
|
|
1106
|
+
/* @__PURE__ */ React17__namespace.createElement(SelectContent, null, optionGroups.length > 0 ? (
|
|
1107
|
+
// Render grouped options
|
|
1108
|
+
optionGroups.map((group, groupIndex) => /* @__PURE__ */ React17__namespace.createElement(SelectGroup, { key: groupIndex }, /* @__PURE__ */ React17__namespace.createElement(SelectLabel, null, group.label), group.options.map((option) => /* @__PURE__ */ React17__namespace.createElement(
|
|
1109
|
+
SelectItem,
|
|
827
1110
|
{
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
"aria-label": "Clear selection",
|
|
832
|
-
tabIndex: -1
|
|
1111
|
+
key: option.value,
|
|
1112
|
+
value: option.value,
|
|
1113
|
+
disabled: option.disabled
|
|
833
1114
|
},
|
|
834
|
-
|
|
835
|
-
)
|
|
836
|
-
)
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
ref: dropdownRef,
|
|
841
|
-
id: dropdownId,
|
|
842
|
-
className: "absolute z-50 top-full mt-1 min-w-full overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md",
|
|
843
|
-
role: "listbox"
|
|
844
|
-
},
|
|
845
|
-
searchable && /* @__PURE__ */ React9__namespace.createElement("div", { className: "p-2 border-b border-border" }, /* @__PURE__ */ React9__namespace.createElement(
|
|
846
|
-
"input",
|
|
1115
|
+
renderOption ? renderOption(option) : option.label
|
|
1116
|
+
))))
|
|
1117
|
+
) : (
|
|
1118
|
+
// Render flat options
|
|
1119
|
+
allOptions.map((option) => /* @__PURE__ */ React17__namespace.createElement(
|
|
1120
|
+
SelectItem,
|
|
847
1121
|
{
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
),
|
|
854
|
-
placeholder: "Search...",
|
|
855
|
-
value: searchQuery,
|
|
856
|
-
onChange: handleSearchChange,
|
|
857
|
-
onClick: (e) => e.stopPropagation(),
|
|
858
|
-
"aria-label": "Search options"
|
|
859
|
-
}
|
|
860
|
-
)),
|
|
861
|
-
/* @__PURE__ */ React9__namespace.createElement("div", { className: "max-h-64 overflow-y-auto p-1" }, filteredOptions.length === 0 ? /* @__PURE__ */ React9__namespace.createElement("div", { className: "py-2 px-3 text-center text-sm " }, "No options found") : optionGroups.length > 0 ? (
|
|
862
|
-
// Render grouped options
|
|
863
|
-
optionGroups.map((group, groupIndex) => {
|
|
864
|
-
const groupOptions = group.options.filter(
|
|
865
|
-
(opt) => filteredOptions.includes(opt)
|
|
866
|
-
);
|
|
867
|
-
if (groupOptions.length === 0) return null;
|
|
868
|
-
return /* @__PURE__ */ React9__namespace.createElement("div", { key: groupIndex, className: "py-1" }, /* @__PURE__ */ React9__namespace.createElement("div", { className: "py-1.5 px-2 text-xs font-semibold " }, group.label), groupOptions.map((option) => {
|
|
869
|
-
const globalIndex = filteredOptions.indexOf(option);
|
|
870
|
-
const isSelected = value === option.value;
|
|
871
|
-
const isFocused = globalIndex === focusedIndex;
|
|
872
|
-
const isDisabled = option.disabled;
|
|
873
|
-
return /* @__PURE__ */ React9__namespace.createElement(
|
|
874
|
-
"div",
|
|
875
|
-
{
|
|
876
|
-
key: option.value,
|
|
877
|
-
className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-muted ${isFocused ? "bg-muted" : ""} ${isSelected ? "font-medium bg-muted" : ""} ${isDisabled ? "pointer-events-none opacity-50" : ""}`,
|
|
878
|
-
onClick: () => !isDisabled && handleSelect(option.value),
|
|
879
|
-
role: "option",
|
|
880
|
-
"aria-selected": isSelected,
|
|
881
|
-
"aria-disabled": isDisabled
|
|
882
|
-
},
|
|
883
|
-
renderOption ? renderOption(option) : option.label
|
|
884
|
-
);
|
|
885
|
-
}));
|
|
886
|
-
})
|
|
887
|
-
) : (
|
|
888
|
-
// Render flat options
|
|
889
|
-
filteredOptions.map((option, index) => {
|
|
890
|
-
const isSelected = value === option.value;
|
|
891
|
-
const isFocused = index === focusedIndex;
|
|
892
|
-
const isDisabled = option.disabled;
|
|
893
|
-
return /* @__PURE__ */ React9__namespace.createElement(
|
|
894
|
-
"div",
|
|
895
|
-
{
|
|
896
|
-
key: option.value,
|
|
897
|
-
className: `relative flex w-full cursor-pointer items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-muted ${isFocused ? "bg-muted" : ""} ${isSelected ? "font-medium bg-muted" : ""} ${isDisabled ? "pointer-events-none opacity-50" : ""}`,
|
|
898
|
-
onClick: () => !isDisabled && handleSelect(option.value),
|
|
899
|
-
role: "option",
|
|
900
|
-
"aria-selected": isSelected,
|
|
901
|
-
"aria-disabled": isDisabled
|
|
902
|
-
},
|
|
903
|
-
renderOption ? renderOption(option) : option.label
|
|
904
|
-
);
|
|
905
|
-
})
|
|
1122
|
+
key: option.value,
|
|
1123
|
+
value: option.value,
|
|
1124
|
+
disabled: option.disabled
|
|
1125
|
+
},
|
|
1126
|
+
renderOption ? renderOption(option) : option.label
|
|
906
1127
|
))
|
|
907
|
-
)
|
|
1128
|
+
))
|
|
908
1129
|
);
|
|
909
1130
|
}
|
|
910
|
-
|
|
1131
|
+
Select2.displayName = "Select";
|
|
911
1132
|
function MultiSelect({
|
|
912
1133
|
name,
|
|
913
1134
|
value = [],
|
|
@@ -930,20 +1151,21 @@ function MultiSelect({
|
|
|
930
1151
|
renderValue,
|
|
931
1152
|
...props
|
|
932
1153
|
}) {
|
|
933
|
-
const [isOpen, setIsOpen] =
|
|
934
|
-
const [searchQuery, setSearchQuery] =
|
|
935
|
-
const [focusedIndex, setFocusedIndex] =
|
|
936
|
-
const
|
|
937
|
-
const
|
|
938
|
-
const
|
|
1154
|
+
const [isOpen, setIsOpen] = React17__namespace.useState(false);
|
|
1155
|
+
const [searchQuery, setSearchQuery] = React17__namespace.useState("");
|
|
1156
|
+
const [focusedIndex, setFocusedIndex] = React17__namespace.useState(-1);
|
|
1157
|
+
const [hasInteracted, setHasInteracted] = React17__namespace.useState(false);
|
|
1158
|
+
const triggerRef = React17__namespace.useRef(null);
|
|
1159
|
+
const dropdownRef = React17__namespace.useRef(null);
|
|
1160
|
+
const searchInputRef = React17__namespace.useRef(null);
|
|
939
1161
|
const dropdownId = `${name}-dropdown`;
|
|
940
|
-
const allOptions =
|
|
1162
|
+
const allOptions = React17__namespace.useMemo(() => {
|
|
941
1163
|
if (optionGroups.length > 0) {
|
|
942
1164
|
return optionGroups.flatMap((group) => group.options);
|
|
943
1165
|
}
|
|
944
1166
|
return options;
|
|
945
1167
|
}, [options, optionGroups]);
|
|
946
|
-
const filteredOptions =
|
|
1168
|
+
const filteredOptions = React17__namespace.useMemo(() => {
|
|
947
1169
|
if (!searchQuery.trim()) {
|
|
948
1170
|
return allOptions;
|
|
949
1171
|
}
|
|
@@ -953,11 +1175,11 @@ function MultiSelect({
|
|
|
953
1175
|
return label.toLowerCase().includes(query);
|
|
954
1176
|
});
|
|
955
1177
|
}, [allOptions, searchQuery]);
|
|
956
|
-
const selectedOptions =
|
|
1178
|
+
const selectedOptions = React17__namespace.useMemo(() => {
|
|
957
1179
|
return allOptions.filter((opt) => value.includes(opt.value));
|
|
958
1180
|
}, [allOptions, value]);
|
|
959
1181
|
const hasValue = value.length > 0;
|
|
960
|
-
const isMaxReached =
|
|
1182
|
+
const isMaxReached = React17__namespace.useMemo(() => {
|
|
961
1183
|
return maxSelections !== void 0 && value.length >= maxSelections;
|
|
962
1184
|
}, [maxSelections, value.length]);
|
|
963
1185
|
const handleToggleOption = (optionValue) => {
|
|
@@ -991,6 +1213,9 @@ function MultiSelect({
|
|
|
991
1213
|
if (disabled) return;
|
|
992
1214
|
const newIsOpen = !isOpen;
|
|
993
1215
|
setIsOpen(newIsOpen);
|
|
1216
|
+
if (newIsOpen && !hasInteracted) {
|
|
1217
|
+
setHasInteracted(true);
|
|
1218
|
+
}
|
|
994
1219
|
if (newIsOpen && searchable && searchInputRef.current) {
|
|
995
1220
|
setTimeout(() => searchInputRef.current?.focus(), 0);
|
|
996
1221
|
}
|
|
@@ -1070,24 +1295,27 @@ function MultiSelect({
|
|
|
1070
1295
|
onBlur?.();
|
|
1071
1296
|
}
|
|
1072
1297
|
};
|
|
1073
|
-
const closeDropdown =
|
|
1298
|
+
const closeDropdown = React17__namespace.useCallback(() => {
|
|
1299
|
+
if (!isOpen) return;
|
|
1074
1300
|
setIsOpen(false);
|
|
1075
1301
|
setSearchQuery("");
|
|
1076
1302
|
setFocusedIndex(-1);
|
|
1077
|
-
|
|
1078
|
-
|
|
1303
|
+
if (hasInteracted) {
|
|
1304
|
+
onBlur?.();
|
|
1305
|
+
}
|
|
1306
|
+
}, [isOpen, hasInteracted, onBlur]);
|
|
1079
1307
|
useOnClickOutside.useOnClickOutside([triggerRef, dropdownRef], closeDropdown, void 0, {
|
|
1080
1308
|
capture: true
|
|
1081
1309
|
});
|
|
1082
1310
|
const combinedClassName = cn("relative w-full", className);
|
|
1083
|
-
return /* @__PURE__ */
|
|
1311
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
1084
1312
|
"div",
|
|
1085
1313
|
{
|
|
1086
1314
|
className: combinedClassName,
|
|
1087
1315
|
onKeyDown: handleKeyDown,
|
|
1088
1316
|
onBlur: handleBlur
|
|
1089
1317
|
},
|
|
1090
|
-
/* @__PURE__ */
|
|
1318
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
1091
1319
|
"select",
|
|
1092
1320
|
{
|
|
1093
1321
|
name,
|
|
@@ -1101,10 +1329,10 @@ function MultiSelect({
|
|
|
1101
1329
|
style: { display: "none" },
|
|
1102
1330
|
multiple: true
|
|
1103
1331
|
},
|
|
1104
|
-
/* @__PURE__ */
|
|
1105
|
-
allOptions.map((option) => /* @__PURE__ */
|
|
1332
|
+
/* @__PURE__ */ React17__namespace.createElement("option", { value: "" }, "Select..."),
|
|
1333
|
+
allOptions.map((option) => /* @__PURE__ */ React17__namespace.createElement("option", { key: option.value, value: option.value }, typeof option.label === "string" ? option.label : option.value))
|
|
1106
1334
|
),
|
|
1107
|
-
/* @__PURE__ */
|
|
1335
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
1108
1336
|
"div",
|
|
1109
1337
|
{
|
|
1110
1338
|
ref: triggerRef,
|
|
@@ -1125,13 +1353,13 @@ function MultiSelect({
|
|
|
1125
1353
|
"aria-disabled": disabled,
|
|
1126
1354
|
tabIndex: disabled ? -1 : 0
|
|
1127
1355
|
},
|
|
1128
|
-
/* @__PURE__ */
|
|
1356
|
+
/* @__PURE__ */ React17__namespace.createElement("div", { className: "flex items-center flex-1 overflow-hidden" }, selectedOptions.length > 0 ? /* @__PURE__ */ React17__namespace.createElement("div", { className: "flex flex-wrap gap-1" }, selectedOptions.map((option) => /* @__PURE__ */ React17__namespace.createElement(
|
|
1129
1357
|
"span",
|
|
1130
1358
|
{
|
|
1131
1359
|
key: option.value,
|
|
1132
1360
|
className: "inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium"
|
|
1133
1361
|
},
|
|
1134
|
-
renderValue ? renderValue(option) : /* @__PURE__ */
|
|
1362
|
+
renderValue ? renderValue(option) : /* @__PURE__ */ React17__namespace.createElement(React17__namespace.Fragment, null, /* @__PURE__ */ React17__namespace.createElement("span", { className: "max-w-40 overflow-hidden text-ellipsis whitespace-nowrap" }, option.label), !disabled && /* @__PURE__ */ React17__namespace.createElement(
|
|
1135
1363
|
"button",
|
|
1136
1364
|
{
|
|
1137
1365
|
type: "button",
|
|
@@ -1142,8 +1370,8 @@ function MultiSelect({
|
|
|
1142
1370
|
},
|
|
1143
1371
|
"\u2715"
|
|
1144
1372
|
))
|
|
1145
|
-
))) : /* @__PURE__ */
|
|
1146
|
-
/* @__PURE__ */
|
|
1373
|
+
))) : /* @__PURE__ */ React17__namespace.createElement("span", { className: "relative" }, placeholder)),
|
|
1374
|
+
/* @__PURE__ */ React17__namespace.createElement("div", { className: "flex items-center gap-1 ml-2" }, loading && /* @__PURE__ */ React17__namespace.createElement("span", { className: "text-xs" }, "\u23F3"), clearable && value.length > 0 && !disabled && !loading && /* @__PURE__ */ React17__namespace.createElement(
|
|
1147
1375
|
"button",
|
|
1148
1376
|
{
|
|
1149
1377
|
type: "button",
|
|
@@ -1153,9 +1381,9 @@ function MultiSelect({
|
|
|
1153
1381
|
tabIndex: -1
|
|
1154
1382
|
},
|
|
1155
1383
|
"\u2715"
|
|
1156
|
-
), /* @__PURE__ */
|
|
1384
|
+
), /* @__PURE__ */ React17__namespace.createElement("span", { className: "text-xs leading-none", "aria-hidden": "true" }, isOpen ? "\u25B2" : "\u25BC"))
|
|
1157
1385
|
),
|
|
1158
|
-
isOpen && /* @__PURE__ */
|
|
1386
|
+
isOpen && /* @__PURE__ */ React17__namespace.createElement(
|
|
1159
1387
|
"div",
|
|
1160
1388
|
{
|
|
1161
1389
|
ref: dropdownRef,
|
|
@@ -1164,7 +1392,7 @@ function MultiSelect({
|
|
|
1164
1392
|
role: "listbox",
|
|
1165
1393
|
"aria-multiselectable": "true"
|
|
1166
1394
|
},
|
|
1167
|
-
searchable && /* @__PURE__ */
|
|
1395
|
+
searchable && /* @__PURE__ */ React17__namespace.createElement("div", { className: "p-2 border-b border-border" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
1168
1396
|
"input",
|
|
1169
1397
|
{
|
|
1170
1398
|
ref: searchInputRef,
|
|
@@ -1180,7 +1408,7 @@ function MultiSelect({
|
|
|
1180
1408
|
"aria-label": "Search options"
|
|
1181
1409
|
}
|
|
1182
1410
|
)),
|
|
1183
|
-
showSelectAll && filteredOptions.length > 0 && /* @__PURE__ */
|
|
1411
|
+
showSelectAll && filteredOptions.length > 0 && /* @__PURE__ */ React17__namespace.createElement("div", { className: "flex gap-2 p-2 border-b border-border" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
1184
1412
|
"button",
|
|
1185
1413
|
{
|
|
1186
1414
|
type: "button",
|
|
@@ -1189,7 +1417,7 @@ function MultiSelect({
|
|
|
1189
1417
|
disabled
|
|
1190
1418
|
},
|
|
1191
1419
|
"Select All"
|
|
1192
|
-
), value.length > 0 && /* @__PURE__ */
|
|
1420
|
+
), value.length > 0 && /* @__PURE__ */ React17__namespace.createElement(
|
|
1193
1421
|
"button",
|
|
1194
1422
|
{
|
|
1195
1423
|
type: "button",
|
|
@@ -1199,20 +1427,20 @@ function MultiSelect({
|
|
|
1199
1427
|
},
|
|
1200
1428
|
"Clear All"
|
|
1201
1429
|
)),
|
|
1202
|
-
isMaxReached && /* @__PURE__ */
|
|
1203
|
-
/* @__PURE__ */
|
|
1430
|
+
isMaxReached && /* @__PURE__ */ React17__namespace.createElement("div", { className: "px-2 py-1 text-xs font-medium text-amber-600 bg-destructive/80 text-destructive-foreground border-b border-destructive" }, "Maximum ", maxSelections, " selection", maxSelections !== 1 ? "s" : "", " ", "reached"),
|
|
1431
|
+
/* @__PURE__ */ React17__namespace.createElement("div", { className: "max-h-64 overflow-y-auto p-1" }, filteredOptions.length === 0 ? /* @__PURE__ */ React17__namespace.createElement("div", { className: "px-2 py-1 text-center text-sm" }, "No options found") : optionGroups.length > 0 ? (
|
|
1204
1432
|
// Render grouped options
|
|
1205
1433
|
optionGroups.map((group, groupIndex) => {
|
|
1206
1434
|
const groupOptions = group.options.filter(
|
|
1207
1435
|
(opt) => filteredOptions.includes(opt)
|
|
1208
1436
|
);
|
|
1209
1437
|
if (groupOptions.length === 0) return null;
|
|
1210
|
-
return /* @__PURE__ */
|
|
1438
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { key: groupIndex, className: "py-1" }, /* @__PURE__ */ React17__namespace.createElement("div", { className: "py-1.5 px-2 text-xs font-semibold " }, group.label), groupOptions.map((option) => {
|
|
1211
1439
|
const globalIndex = filteredOptions.indexOf(option);
|
|
1212
1440
|
const isSelected = value.includes(option.value);
|
|
1213
1441
|
const isFocused = globalIndex === focusedIndex;
|
|
1214
1442
|
const isDisabled = option.disabled || isMaxReached && !isSelected;
|
|
1215
|
-
return /* @__PURE__ */
|
|
1443
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
1216
1444
|
"div",
|
|
1217
1445
|
{
|
|
1218
1446
|
key: option.value,
|
|
@@ -1227,8 +1455,8 @@ function MultiSelect({
|
|
|
1227
1455
|
"aria-selected": isSelected,
|
|
1228
1456
|
"aria-disabled": isDisabled
|
|
1229
1457
|
},
|
|
1230
|
-
/* @__PURE__ */
|
|
1231
|
-
/* @__PURE__ */
|
|
1458
|
+
/* @__PURE__ */ React17__namespace.createElement("span", { className: "text-base leading-none" }, isSelected ? "\u2611" : "\u2610"),
|
|
1459
|
+
/* @__PURE__ */ React17__namespace.createElement("span", { className: "flex-1" }, renderOption ? renderOption(option) : option.label)
|
|
1232
1460
|
);
|
|
1233
1461
|
}));
|
|
1234
1462
|
})
|
|
@@ -1238,7 +1466,7 @@ function MultiSelect({
|
|
|
1238
1466
|
const isSelected = value.includes(option.value);
|
|
1239
1467
|
const isFocused = index === focusedIndex;
|
|
1240
1468
|
const isDisabled = option.disabled || isMaxReached && !isSelected;
|
|
1241
|
-
return /* @__PURE__ */
|
|
1469
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
1242
1470
|
"div",
|
|
1243
1471
|
{
|
|
1244
1472
|
key: option.value,
|
|
@@ -1253,8 +1481,8 @@ function MultiSelect({
|
|
|
1253
1481
|
"aria-selected": isSelected,
|
|
1254
1482
|
"aria-disabled": isDisabled
|
|
1255
1483
|
},
|
|
1256
|
-
/* @__PURE__ */
|
|
1257
|
-
/* @__PURE__ */
|
|
1484
|
+
/* @__PURE__ */ React17__namespace.createElement("span", { className: "text-base leading-none" }, isSelected ? "\u2611" : "\u2610"),
|
|
1485
|
+
/* @__PURE__ */ React17__namespace.createElement("span", { className: "flex-1" }, renderOption ? renderOption(option) : option.label)
|
|
1258
1486
|
);
|
|
1259
1487
|
})
|
|
1260
1488
|
))
|
|
@@ -1287,14 +1515,14 @@ function FileInput({
|
|
|
1287
1515
|
onFileRemove,
|
|
1288
1516
|
...props
|
|
1289
1517
|
}) {
|
|
1290
|
-
const inputRef =
|
|
1291
|
-
const [dragActive, setDragActive] =
|
|
1292
|
-
const [cropperOpen, setCropperOpen] =
|
|
1293
|
-
const [imageToCrop, setImageToCrop] =
|
|
1294
|
-
const [crop, setCrop] =
|
|
1295
|
-
const [zoom, setZoom] =
|
|
1296
|
-
const [croppedAreaPixels, setCroppedAreaPixels] =
|
|
1297
|
-
const validateFile =
|
|
1518
|
+
const inputRef = React17__namespace.useRef(null);
|
|
1519
|
+
const [dragActive, setDragActive] = React17__namespace.useState(false);
|
|
1520
|
+
const [cropperOpen, setCropperOpen] = React17__namespace.useState(false);
|
|
1521
|
+
const [imageToCrop, setImageToCrop] = React17__namespace.useState(null);
|
|
1522
|
+
const [crop, setCrop] = React17__namespace.useState({ x: 0, y: 0 });
|
|
1523
|
+
const [zoom, setZoom] = React17__namespace.useState(1);
|
|
1524
|
+
const [croppedAreaPixels, setCroppedAreaPixels] = React17__namespace.useState(null);
|
|
1525
|
+
const validateFile = React17__namespace.useCallback(
|
|
1298
1526
|
(file) => {
|
|
1299
1527
|
if (accept) {
|
|
1300
1528
|
const acceptedTypes = accept.split(",").map((t) => t.trim());
|
|
@@ -1329,7 +1557,7 @@ function FileInput({
|
|
|
1329
1557
|
},
|
|
1330
1558
|
[accept, maxSize]
|
|
1331
1559
|
);
|
|
1332
|
-
const handleFiles =
|
|
1560
|
+
const handleFiles = React17__namespace.useCallback(
|
|
1333
1561
|
(fileList) => {
|
|
1334
1562
|
if (!fileList || fileList.length === 0) return;
|
|
1335
1563
|
const newFiles = Array.from(fileList);
|
|
@@ -1380,7 +1608,7 @@ function FileInput({
|
|
|
1380
1608
|
onValidationError
|
|
1381
1609
|
]
|
|
1382
1610
|
);
|
|
1383
|
-
const createCroppedImage =
|
|
1611
|
+
const createCroppedImage = React17__namespace.useCallback(
|
|
1384
1612
|
async (imageUrl, cropArea) => {
|
|
1385
1613
|
return new Promise((resolve, reject) => {
|
|
1386
1614
|
const image = new Image();
|
|
@@ -1424,7 +1652,7 @@ function FileInput({
|
|
|
1424
1652
|
},
|
|
1425
1653
|
[]
|
|
1426
1654
|
);
|
|
1427
|
-
const handleCropSave =
|
|
1655
|
+
const handleCropSave = React17__namespace.useCallback(async () => {
|
|
1428
1656
|
if (!imageToCrop || !croppedAreaPixels) return;
|
|
1429
1657
|
try {
|
|
1430
1658
|
const croppedBlob = await createCroppedImage(
|
|
@@ -1457,7 +1685,7 @@ function FileInput({
|
|
|
1457
1685
|
onChange,
|
|
1458
1686
|
multiple
|
|
1459
1687
|
]);
|
|
1460
|
-
const handleCropCancel =
|
|
1688
|
+
const handleCropCancel = React17__namespace.useCallback(() => {
|
|
1461
1689
|
if (imageToCrop) {
|
|
1462
1690
|
URL.revokeObjectURL(imageToCrop.url);
|
|
1463
1691
|
}
|
|
@@ -1467,13 +1695,13 @@ function FileInput({
|
|
|
1467
1695
|
setZoom(1);
|
|
1468
1696
|
setCroppedAreaPixels(null);
|
|
1469
1697
|
}, [imageToCrop]);
|
|
1470
|
-
const onCropChange =
|
|
1698
|
+
const onCropChange = React17__namespace.useCallback((crop2) => {
|
|
1471
1699
|
setCrop(crop2);
|
|
1472
1700
|
}, []);
|
|
1473
|
-
const onZoomChange =
|
|
1701
|
+
const onZoomChange = React17__namespace.useCallback((zoom2) => {
|
|
1474
1702
|
setZoom(zoom2);
|
|
1475
1703
|
}, []);
|
|
1476
|
-
const onCropCompleteInternal =
|
|
1704
|
+
const onCropCompleteInternal = React17__namespace.useCallback(
|
|
1477
1705
|
(_, croppedAreaPixels2) => {
|
|
1478
1706
|
setCroppedAreaPixels(croppedAreaPixels2);
|
|
1479
1707
|
},
|
|
@@ -1534,7 +1762,7 @@ function FileInput({
|
|
|
1534
1762
|
}
|
|
1535
1763
|
return null;
|
|
1536
1764
|
};
|
|
1537
|
-
|
|
1765
|
+
React17__namespace.useEffect(() => {
|
|
1538
1766
|
return () => {
|
|
1539
1767
|
value.forEach((file) => {
|
|
1540
1768
|
const previewUrl = getPreviewUrl(file);
|
|
@@ -1548,7 +1776,7 @@ function FileInput({
|
|
|
1548
1776
|
};
|
|
1549
1777
|
}, [value, imageToCrop]);
|
|
1550
1778
|
const combinedClassName = `${className}`.trim();
|
|
1551
|
-
return /* @__PURE__ */
|
|
1779
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { className: combinedClassName }, /* @__PURE__ */ React17__namespace.createElement(
|
|
1552
1780
|
"input",
|
|
1553
1781
|
{
|
|
1554
1782
|
ref: inputRef,
|
|
@@ -1565,7 +1793,7 @@ function FileInput({
|
|
|
1565
1793
|
"aria-required": required || props["aria-required"],
|
|
1566
1794
|
style: { display: "none" }
|
|
1567
1795
|
}
|
|
1568
|
-
), /* @__PURE__ */
|
|
1796
|
+
), /* @__PURE__ */ React17__namespace.createElement(
|
|
1569
1797
|
"div",
|
|
1570
1798
|
{
|
|
1571
1799
|
className: `flex min-h-32 w-full cursor-pointer items-center justify-center rounded-md border-2 border-dashed border-input bg-transparent p-6 transition-colors hover:bg-primary/50 hover:border-ring ${dragActive ? "bg-primary text-primary-foreground border-ring" : ""} ${disabled ? "cursor-not-allowed opacity-50" : ""} ${error ? "border-destructive" : ""}`,
|
|
@@ -1580,7 +1808,7 @@ function FileInput({
|
|
|
1580
1808
|
"aria-label": placeholder,
|
|
1581
1809
|
"aria-disabled": disabled
|
|
1582
1810
|
},
|
|
1583
|
-
/* @__PURE__ */
|
|
1811
|
+
/* @__PURE__ */ React17__namespace.createElement("div", { className: "flex flex-col items-center gap-2 text-center" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
1584
1812
|
"svg",
|
|
1585
1813
|
{
|
|
1586
1814
|
width: "48",
|
|
@@ -1593,19 +1821,19 @@ function FileInput({
|
|
|
1593
1821
|
strokeLinejoin: "round",
|
|
1594
1822
|
"aria-hidden": "true"
|
|
1595
1823
|
},
|
|
1596
|
-
/* @__PURE__ */
|
|
1597
|
-
/* @__PURE__ */
|
|
1598
|
-
/* @__PURE__ */
|
|
1599
|
-
), /* @__PURE__ */
|
|
1600
|
-
), value.length > 0 && /* @__PURE__ */
|
|
1824
|
+
/* @__PURE__ */ React17__namespace.createElement("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
1825
|
+
/* @__PURE__ */ React17__namespace.createElement("polyline", { points: "17 8 12 3 7 8" }),
|
|
1826
|
+
/* @__PURE__ */ React17__namespace.createElement("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
|
|
1827
|
+
), /* @__PURE__ */ React17__namespace.createElement("p", { className: "text-sm font-medium" }, value.length > 0 ? `${value.length} file(s) selected` : placeholder), accept && /* @__PURE__ */ React17__namespace.createElement("p", { className: "text-xs" }, "Accepted: ", accept), maxSize && /* @__PURE__ */ React17__namespace.createElement("p", { className: "text-xs " }, "Max size: ", formatFileSize(maxSize)))
|
|
1828
|
+
), value.length > 0 && /* @__PURE__ */ React17__namespace.createElement("ul", { className: "flex flex-col gap-2 mt-4", role: "list" }, value.map((file, index) => {
|
|
1601
1829
|
const previewUrl = showPreview ? getPreviewUrl(file) : null;
|
|
1602
|
-
return /* @__PURE__ */
|
|
1830
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
1603
1831
|
"li",
|
|
1604
1832
|
{
|
|
1605
1833
|
key: `${file.name}-${index}`,
|
|
1606
1834
|
className: "flex items-center gap-3 p-3 rounded-md border border-border bg-card text-card-foreground hover:bg-primary/50 transition-colors"
|
|
1607
1835
|
},
|
|
1608
|
-
previewUrl && /* @__PURE__ */
|
|
1836
|
+
previewUrl && /* @__PURE__ */ React17__namespace.createElement(
|
|
1609
1837
|
"img",
|
|
1610
1838
|
{
|
|
1611
1839
|
src: previewUrl,
|
|
@@ -1615,7 +1843,7 @@ function FileInput({
|
|
|
1615
1843
|
height: "48"
|
|
1616
1844
|
}
|
|
1617
1845
|
),
|
|
1618
|
-
/* @__PURE__ */
|
|
1846
|
+
/* @__PURE__ */ React17__namespace.createElement("div", { className: "flex flex-col flex-1 min-w-0" }, /* @__PURE__ */ React17__namespace.createElement("span", { className: "text-sm font-medium truncate" }, file.name), /* @__PURE__ */ React17__namespace.createElement("span", { className: "text-xs" }, formatFileSize(file.size)), showProgress && uploadProgress[file.name] !== void 0 && /* @__PURE__ */ React17__namespace.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
1619
1847
|
"div",
|
|
1620
1848
|
{
|
|
1621
1849
|
className: "h-1.5 bg-muted rounded-full overflow-hidden flex-1",
|
|
@@ -1625,15 +1853,15 @@ function FileInput({
|
|
|
1625
1853
|
"aria-valuemax": 100,
|
|
1626
1854
|
"aria-label": `Upload progress: ${uploadProgress[file.name]}%`
|
|
1627
1855
|
},
|
|
1628
|
-
/* @__PURE__ */
|
|
1856
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
1629
1857
|
"div",
|
|
1630
1858
|
{
|
|
1631
1859
|
className: "h-full bg-primary transition-all",
|
|
1632
1860
|
style: { width: `${uploadProgress[file.name]}%` }
|
|
1633
1861
|
}
|
|
1634
1862
|
)
|
|
1635
|
-
), /* @__PURE__ */
|
|
1636
|
-
enableCropping && file.type.startsWith("image/") && /* @__PURE__ */
|
|
1863
|
+
), /* @__PURE__ */ React17__namespace.createElement("span", { className: "text-xs " }, uploadProgress[file.name], "%"))),
|
|
1864
|
+
enableCropping && file.type.startsWith("image/") && /* @__PURE__ */ React17__namespace.createElement(
|
|
1637
1865
|
"button",
|
|
1638
1866
|
{
|
|
1639
1867
|
type: "button",
|
|
@@ -1645,7 +1873,7 @@ function FileInput({
|
|
|
1645
1873
|
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
1646
1874
|
"aria-label": `Crop ${file.name}`
|
|
1647
1875
|
},
|
|
1648
|
-
/* @__PURE__ */
|
|
1876
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
1649
1877
|
"svg",
|
|
1650
1878
|
{
|
|
1651
1879
|
width: "20",
|
|
@@ -1658,11 +1886,11 @@ function FileInput({
|
|
|
1658
1886
|
strokeLinejoin: "round",
|
|
1659
1887
|
"aria-hidden": "true"
|
|
1660
1888
|
},
|
|
1661
|
-
/* @__PURE__ */
|
|
1662
|
-
/* @__PURE__ */
|
|
1889
|
+
/* @__PURE__ */ React17__namespace.createElement("path", { d: "M6.13 1L6 16a2 2 0 0 0 2 2h15" }),
|
|
1890
|
+
/* @__PURE__ */ React17__namespace.createElement("path", { d: "M1 6.13L16 6a2 2 0 0 1 2 2v15" })
|
|
1663
1891
|
)
|
|
1664
1892
|
),
|
|
1665
|
-
/* @__PURE__ */
|
|
1893
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
1666
1894
|
"button",
|
|
1667
1895
|
{
|
|
1668
1896
|
type: "button",
|
|
@@ -1674,7 +1902,7 @@ function FileInput({
|
|
|
1674
1902
|
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
1675
1903
|
"aria-label": `Remove ${file.name}`
|
|
1676
1904
|
},
|
|
1677
|
-
/* @__PURE__ */
|
|
1905
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
1678
1906
|
"svg",
|
|
1679
1907
|
{
|
|
1680
1908
|
width: "20",
|
|
@@ -1687,19 +1915,19 @@ function FileInput({
|
|
|
1687
1915
|
strokeLinejoin: "round",
|
|
1688
1916
|
"aria-hidden": "true"
|
|
1689
1917
|
},
|
|
1690
|
-
/* @__PURE__ */
|
|
1691
|
-
/* @__PURE__ */
|
|
1918
|
+
/* @__PURE__ */ React17__namespace.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
1919
|
+
/* @__PURE__ */ React17__namespace.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
1692
1920
|
)
|
|
1693
1921
|
)
|
|
1694
1922
|
);
|
|
1695
|
-
})), cropperOpen && imageToCrop && /* @__PURE__ */
|
|
1923
|
+
})), cropperOpen && imageToCrop && /* @__PURE__ */ React17__namespace.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
1696
1924
|
"div",
|
|
1697
1925
|
{
|
|
1698
1926
|
className: "absolute inset-0 bg-black/50",
|
|
1699
1927
|
onClick: handleCropCancel,
|
|
1700
1928
|
"aria-label": "Close cropper"
|
|
1701
1929
|
}
|
|
1702
|
-
), /* @__PURE__ */
|
|
1930
|
+
), /* @__PURE__ */ React17__namespace.createElement("div", { className: "relative bg-popover border border-border rounded-lg shadow-lg max-w-3xl w-full mx-4" }, /* @__PURE__ */ React17__namespace.createElement("div", { className: "flex items-center justify-between p-4 border-b border-border" }, /* @__PURE__ */ React17__namespace.createElement("h3", { className: "text-lg font-semibold" }, "Crop Image"), /* @__PURE__ */ React17__namespace.createElement(
|
|
1703
1931
|
"button",
|
|
1704
1932
|
{
|
|
1705
1933
|
type: "button",
|
|
@@ -1708,7 +1936,7 @@ function FileInput({
|
|
|
1708
1936
|
"aria-label": "Close"
|
|
1709
1937
|
},
|
|
1710
1938
|
"\u2715"
|
|
1711
|
-
)), /* @__PURE__ */
|
|
1939
|
+
)), /* @__PURE__ */ React17__namespace.createElement("div", { className: "p-4" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
1712
1940
|
"div",
|
|
1713
1941
|
{
|
|
1714
1942
|
className: "relative w-full h-96 bg-muted rounded-md overflow-hidden",
|
|
@@ -1730,7 +1958,7 @@ function FileInput({
|
|
|
1730
1958
|
document.addEventListener("mouseup", handleMouseUp);
|
|
1731
1959
|
}
|
|
1732
1960
|
},
|
|
1733
|
-
/* @__PURE__ */
|
|
1961
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
1734
1962
|
"img",
|
|
1735
1963
|
{
|
|
1736
1964
|
src: imageToCrop.url,
|
|
@@ -1765,7 +1993,7 @@ function FileInput({
|
|
|
1765
1993
|
}
|
|
1766
1994
|
}
|
|
1767
1995
|
),
|
|
1768
|
-
/* @__PURE__ */
|
|
1996
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
1769
1997
|
"div",
|
|
1770
1998
|
{
|
|
1771
1999
|
className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 border-2 border-primary rounded pointer-events-none",
|
|
@@ -1774,9 +2002,9 @@ function FileInput({
|
|
|
1774
2002
|
aspectRatio: cropAspectRatio ? String(cropAspectRatio) : void 0
|
|
1775
2003
|
}
|
|
1776
2004
|
},
|
|
1777
|
-
/* @__PURE__ */
|
|
2005
|
+
/* @__PURE__ */ React17__namespace.createElement("div", { className: "absolute inset-0 grid grid-cols-3 grid-rows-3" }, /* @__PURE__ */ React17__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React17__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React17__namespace.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React17__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React17__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React17__namespace.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React17__namespace.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React17__namespace.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React17__namespace.createElement("div", null))
|
|
1778
2006
|
)
|
|
1779
|
-
), /* @__PURE__ */
|
|
2007
|
+
), /* @__PURE__ */ React17__namespace.createElement("div", { className: "flex items-center gap-3 mt-4" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
1780
2008
|
"label",
|
|
1781
2009
|
{
|
|
1782
2010
|
htmlFor: "zoom-slider",
|
|
@@ -1785,7 +2013,7 @@ function FileInput({
|
|
|
1785
2013
|
"Zoom: ",
|
|
1786
2014
|
zoom.toFixed(1),
|
|
1787
2015
|
"x"
|
|
1788
|
-
), /* @__PURE__ */
|
|
2016
|
+
), /* @__PURE__ */ React17__namespace.createElement(
|
|
1789
2017
|
"input",
|
|
1790
2018
|
{
|
|
1791
2019
|
id: "zoom-slider",
|
|
@@ -1798,7 +2026,7 @@ function FileInput({
|
|
|
1798
2026
|
className: "flex-1 h-2 bg-muted rounded-lg appearance-none cursor-pointer",
|
|
1799
2027
|
"aria-label": "Zoom level"
|
|
1800
2028
|
}
|
|
1801
|
-
))), /* @__PURE__ */
|
|
2029
|
+
))), /* @__PURE__ */ React17__namespace.createElement("div", { className: "flex items-center justify-end gap-2 p-4 border-t border-border" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
1802
2030
|
"button",
|
|
1803
2031
|
{
|
|
1804
2032
|
type: "button",
|
|
@@ -1806,7 +2034,7 @@ function FileInput({
|
|
|
1806
2034
|
onClick: handleCropCancel
|
|
1807
2035
|
},
|
|
1808
2036
|
"Cancel"
|
|
1809
|
-
), /* @__PURE__ */
|
|
2037
|
+
), /* @__PURE__ */ React17__namespace.createElement(
|
|
1810
2038
|
"button",
|
|
1811
2039
|
{
|
|
1812
2040
|
type: "button",
|
|
@@ -1848,13 +2076,14 @@ function DatePicker({
|
|
|
1848
2076
|
showIcon = true,
|
|
1849
2077
|
...props
|
|
1850
2078
|
}) {
|
|
1851
|
-
const [isOpen, setIsOpen] =
|
|
1852
|
-
const [
|
|
2079
|
+
const [isOpen, setIsOpen] = React17__namespace.useState(false);
|
|
2080
|
+
const [hasInteracted, setHasInteracted] = React17__namespace.useState(false);
|
|
2081
|
+
const [selectedMonth, setSelectedMonth] = React17__namespace.useState(
|
|
1853
2082
|
value || /* @__PURE__ */ new Date()
|
|
1854
2083
|
);
|
|
1855
|
-
const inputRef =
|
|
1856
|
-
const dropdownRef =
|
|
1857
|
-
|
|
2084
|
+
const inputRef = React17__namespace.useRef(null);
|
|
2085
|
+
const dropdownRef = React17__namespace.useRef(null);
|
|
2086
|
+
React17__namespace.useEffect(() => {
|
|
1858
2087
|
if (value) {
|
|
1859
2088
|
setSelectedMonth(value);
|
|
1860
2089
|
}
|
|
@@ -1871,7 +2100,13 @@ function DatePicker({
|
|
|
1871
2100
|
};
|
|
1872
2101
|
const handleToggle = () => {
|
|
1873
2102
|
if (disabled) return;
|
|
1874
|
-
setIsOpen((prev) =>
|
|
2103
|
+
setIsOpen((prev) => {
|
|
2104
|
+
const newIsOpen = !prev;
|
|
2105
|
+
if (newIsOpen && !hasInteracted) {
|
|
2106
|
+
setHasInteracted(true);
|
|
2107
|
+
}
|
|
2108
|
+
return newIsOpen;
|
|
2109
|
+
});
|
|
1875
2110
|
};
|
|
1876
2111
|
const isDisabled = (date) => {
|
|
1877
2112
|
if (minDate && date < minDate) return true;
|
|
@@ -1880,10 +2115,13 @@ function DatePicker({
|
|
|
1880
2115
|
if (isDateDisabled && isDateDisabled(date)) return true;
|
|
1881
2116
|
return false;
|
|
1882
2117
|
};
|
|
1883
|
-
const closeCalendar =
|
|
2118
|
+
const closeCalendar = React17__namespace.useCallback(() => {
|
|
2119
|
+
if (!isOpen) return;
|
|
1884
2120
|
setIsOpen(false);
|
|
1885
|
-
|
|
1886
|
-
|
|
2121
|
+
if (hasInteracted) {
|
|
2122
|
+
onBlur?.();
|
|
2123
|
+
}
|
|
2124
|
+
}, [isOpen, hasInteracted, onBlur]);
|
|
1887
2125
|
useOnClickOutside.useOnClickOutside([inputRef, dropdownRef], closeCalendar, void 0, {
|
|
1888
2126
|
capture: true
|
|
1889
2127
|
});
|
|
@@ -1931,7 +2169,7 @@ function DatePicker({
|
|
|
1931
2169
|
const handleNextMonth = () => {
|
|
1932
2170
|
setSelectedMonth(new Date(year, month + 1, 1));
|
|
1933
2171
|
};
|
|
1934
|
-
return /* @__PURE__ */
|
|
2172
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { role: "grid", "aria-label": "Calendar", className: "w-[248px] max-w-full" }, /* @__PURE__ */ React17__namespace.createElement("div", { className: "flex items-center justify-between pb-3" }, /* @__PURE__ */ React17__namespace.createElement(
|
|
1935
2173
|
"button",
|
|
1936
2174
|
{
|
|
1937
2175
|
type: "button",
|
|
@@ -1940,7 +2178,7 @@ function DatePicker({
|
|
|
1940
2178
|
"aria-label": "Previous month"
|
|
1941
2179
|
},
|
|
1942
2180
|
"\u2039"
|
|
1943
|
-
), /* @__PURE__ */
|
|
2181
|
+
), /* @__PURE__ */ React17__namespace.createElement("div", { className: "font-medium text-sm" }, `${monthNames[month]} ${year}`), /* @__PURE__ */ React17__namespace.createElement(
|
|
1944
2182
|
"button",
|
|
1945
2183
|
{
|
|
1946
2184
|
type: "button",
|
|
@@ -1949,13 +2187,13 @@ function DatePicker({
|
|
|
1949
2187
|
"aria-label": "Next month"
|
|
1950
2188
|
},
|
|
1951
2189
|
"\u203A"
|
|
1952
|
-
)), /* @__PURE__ */
|
|
2190
|
+
)), /* @__PURE__ */ React17__namespace.createElement(
|
|
1953
2191
|
"div",
|
|
1954
2192
|
{
|
|
1955
2193
|
className: "grid gap-1 text-xs text-muted-foreground",
|
|
1956
2194
|
style: dayGridStyle
|
|
1957
2195
|
},
|
|
1958
|
-
["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */
|
|
2196
|
+
["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React17__namespace.createElement(
|
|
1959
2197
|
"div",
|
|
1960
2198
|
{
|
|
1961
2199
|
key: day,
|
|
@@ -1963,14 +2201,14 @@ function DatePicker({
|
|
|
1963
2201
|
},
|
|
1964
2202
|
day
|
|
1965
2203
|
))
|
|
1966
|
-
), /* @__PURE__ */
|
|
2204
|
+
), /* @__PURE__ */ React17__namespace.createElement("div", { className: "grid gap-1", style: dayGridStyle }, days.map((date, index) => {
|
|
1967
2205
|
if (!date) {
|
|
1968
|
-
return /* @__PURE__ */
|
|
2206
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { key: `empty-${index}`, className: "h-8 w-8" });
|
|
1969
2207
|
}
|
|
1970
2208
|
const isSelected = value && date.toDateString() === value.toDateString();
|
|
1971
2209
|
const isToday = date.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
|
|
1972
2210
|
const disabled2 = isDisabled(date);
|
|
1973
|
-
return /* @__PURE__ */
|
|
2211
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
1974
2212
|
"button",
|
|
1975
2213
|
{
|
|
1976
2214
|
key: date.toISOString(),
|
|
@@ -1991,20 +2229,20 @@ function DatePicker({
|
|
|
1991
2229
|
})));
|
|
1992
2230
|
};
|
|
1993
2231
|
const combinedClassName = cn("relative", className);
|
|
1994
|
-
return /* @__PURE__ */
|
|
2232
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { className: combinedClassName, onBlur: handleBlur }, /* @__PURE__ */ React17__namespace.createElement(
|
|
1995
2233
|
"input",
|
|
1996
2234
|
{
|
|
1997
2235
|
type: "hidden",
|
|
1998
2236
|
name,
|
|
1999
2237
|
value: value ? value.toISOString() : ""
|
|
2000
2238
|
}
|
|
2001
|
-
), /* @__PURE__ */
|
|
2239
|
+
), /* @__PURE__ */ React17__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React17__namespace.createElement(
|
|
2002
2240
|
"span",
|
|
2003
2241
|
{
|
|
2004
2242
|
className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
|
|
2005
2243
|
"aria-hidden": "true"
|
|
2006
2244
|
},
|
|
2007
|
-
/* @__PURE__ */
|
|
2245
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
2008
2246
|
"svg",
|
|
2009
2247
|
{
|
|
2010
2248
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -2017,9 +2255,9 @@ function DatePicker({
|
|
|
2017
2255
|
strokeLinejoin: "round",
|
|
2018
2256
|
strokeWidth: "2"
|
|
2019
2257
|
},
|
|
2020
|
-
/* @__PURE__ */
|
|
2258
|
+
/* @__PURE__ */ React17__namespace.createElement("path", { d: "M8 2v4m8-4v4m5 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8M3 10h18m-5 10l2 2l4-4" })
|
|
2021
2259
|
)
|
|
2022
|
-
), /* @__PURE__ */
|
|
2260
|
+
), /* @__PURE__ */ React17__namespace.createElement(
|
|
2023
2261
|
"input",
|
|
2024
2262
|
{
|
|
2025
2263
|
ref: inputRef,
|
|
@@ -2044,7 +2282,7 @@ function DatePicker({
|
|
|
2044
2282
|
"aria-required": required || props["aria-required"],
|
|
2045
2283
|
readOnly: true
|
|
2046
2284
|
}
|
|
2047
|
-
), clearable && value && !disabled && /* @__PURE__ */
|
|
2285
|
+
), clearable && value && !disabled && /* @__PURE__ */ React17__namespace.createElement(
|
|
2048
2286
|
"button",
|
|
2049
2287
|
{
|
|
2050
2288
|
type: "button",
|
|
@@ -2054,7 +2292,7 @@ function DatePicker({
|
|
|
2054
2292
|
tabIndex: -1
|
|
2055
2293
|
},
|
|
2056
2294
|
"\u2715"
|
|
2057
|
-
)), isOpen && !disabled && /* @__PURE__ */
|
|
2295
|
+
)), isOpen && !disabled && /* @__PURE__ */ React17__namespace.createElement(
|
|
2058
2296
|
"div",
|
|
2059
2297
|
{
|
|
2060
2298
|
ref: dropdownRef,
|
|
@@ -2121,11 +2359,11 @@ function TimePicker({
|
|
|
2121
2359
|
showIcon = true,
|
|
2122
2360
|
...props
|
|
2123
2361
|
}) {
|
|
2124
|
-
const inputRef =
|
|
2125
|
-
const [nativeValue, setNativeValue] =
|
|
2362
|
+
const inputRef = React17__namespace.useRef(null);
|
|
2363
|
+
const [nativeValue, setNativeValue] = React17__namespace.useState(
|
|
2126
2364
|
normalizeToNativeTime(value)
|
|
2127
2365
|
);
|
|
2128
|
-
|
|
2366
|
+
React17__namespace.useEffect(() => {
|
|
2129
2367
|
setNativeValue(normalizeToNativeTime(value));
|
|
2130
2368
|
}, [value]);
|
|
2131
2369
|
const handleChange = (e) => {
|
|
@@ -2141,13 +2379,13 @@ function TimePicker({
|
|
|
2141
2379
|
};
|
|
2142
2380
|
const hasValue = Boolean(value);
|
|
2143
2381
|
const stepInSeconds = Math.max(1, minuteStep * 60);
|
|
2144
|
-
return /* @__PURE__ */
|
|
2382
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { className: cn("relative", className) }, /* @__PURE__ */ React17__namespace.createElement("input", { type: "hidden", name, value }), /* @__PURE__ */ React17__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React17__namespace.createElement(
|
|
2145
2383
|
"span",
|
|
2146
2384
|
{
|
|
2147
2385
|
className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
|
|
2148
2386
|
"aria-hidden": "true"
|
|
2149
2387
|
},
|
|
2150
|
-
/* @__PURE__ */
|
|
2388
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
2151
2389
|
"svg",
|
|
2152
2390
|
{
|
|
2153
2391
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -2160,10 +2398,10 @@ function TimePicker({
|
|
|
2160
2398
|
strokeLinejoin: "round",
|
|
2161
2399
|
strokeWidth: "2"
|
|
2162
2400
|
},
|
|
2163
|
-
/* @__PURE__ */
|
|
2164
|
-
/* @__PURE__ */
|
|
2401
|
+
/* @__PURE__ */ React17__namespace.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2402
|
+
/* @__PURE__ */ React17__namespace.createElement("path", { d: "M12 6v6l4 2" })
|
|
2165
2403
|
)
|
|
2166
|
-
), /* @__PURE__ */
|
|
2404
|
+
), /* @__PURE__ */ React17__namespace.createElement(
|
|
2167
2405
|
"input",
|
|
2168
2406
|
{
|
|
2169
2407
|
ref: inputRef,
|
|
@@ -2191,7 +2429,7 @@ function TimePicker({
|
|
|
2191
2429
|
"aria-required": required || props["aria-required"],
|
|
2192
2430
|
...props
|
|
2193
2431
|
}
|
|
2194
|
-
), clearable && value && !disabled && /* @__PURE__ */
|
|
2432
|
+
), clearable && value && !disabled && /* @__PURE__ */ React17__namespace.createElement(
|
|
2195
2433
|
"button",
|
|
2196
2434
|
{
|
|
2197
2435
|
type: "button",
|
|
@@ -2244,16 +2482,17 @@ function DateRangePicker({
|
|
|
2244
2482
|
separator = " - ",
|
|
2245
2483
|
...props
|
|
2246
2484
|
}) {
|
|
2247
|
-
const [isOpen, setIsOpen] =
|
|
2248
|
-
const [
|
|
2485
|
+
const [isOpen, setIsOpen] = React17__namespace.useState(false);
|
|
2486
|
+
const [hasInteracted, setHasInteracted] = React17__namespace.useState(false);
|
|
2487
|
+
const [selectedMonth, setSelectedMonth] = React17__namespace.useState(
|
|
2249
2488
|
value.start || /* @__PURE__ */ new Date()
|
|
2250
2489
|
);
|
|
2251
|
-
const [rangeStart, setRangeStart] =
|
|
2252
|
-
const [rangeEnd, setRangeEnd] =
|
|
2253
|
-
const [hoverDate, setHoverDate] =
|
|
2254
|
-
const triggerRef =
|
|
2255
|
-
const dropdownRef =
|
|
2256
|
-
|
|
2490
|
+
const [rangeStart, setRangeStart] = React17__namespace.useState(value.start);
|
|
2491
|
+
const [rangeEnd, setRangeEnd] = React17__namespace.useState(value.end);
|
|
2492
|
+
const [hoverDate, setHoverDate] = React17__namespace.useState(null);
|
|
2493
|
+
const triggerRef = React17__namespace.useRef(null);
|
|
2494
|
+
const dropdownRef = React17__namespace.useRef(null);
|
|
2495
|
+
React17__namespace.useEffect(() => {
|
|
2257
2496
|
setRangeStart(value.start);
|
|
2258
2497
|
setRangeEnd(value.end);
|
|
2259
2498
|
if (value.start) {
|
|
@@ -2287,7 +2526,13 @@ function DateRangePicker({
|
|
|
2287
2526
|
};
|
|
2288
2527
|
const handleToggle = () => {
|
|
2289
2528
|
if (disabled) return;
|
|
2290
|
-
setIsOpen((prev) =>
|
|
2529
|
+
setIsOpen((prev) => {
|
|
2530
|
+
const newIsOpen = !prev;
|
|
2531
|
+
if (newIsOpen && !hasInteracted) {
|
|
2532
|
+
setHasInteracted(true);
|
|
2533
|
+
}
|
|
2534
|
+
return newIsOpen;
|
|
2535
|
+
});
|
|
2291
2536
|
};
|
|
2292
2537
|
const isDisabled = (date) => {
|
|
2293
2538
|
if (minDate && date < minDate) return true;
|
|
@@ -2296,10 +2541,13 @@ function DateRangePicker({
|
|
|
2296
2541
|
if (isDateDisabled && isDateDisabled(date)) return true;
|
|
2297
2542
|
return false;
|
|
2298
2543
|
};
|
|
2299
|
-
const closeCalendar =
|
|
2544
|
+
const closeCalendar = React17__namespace.useCallback(() => {
|
|
2545
|
+
if (!isOpen) return;
|
|
2300
2546
|
setIsOpen(false);
|
|
2301
|
-
|
|
2302
|
-
|
|
2547
|
+
if (hasInteracted) {
|
|
2548
|
+
onBlur?.();
|
|
2549
|
+
}
|
|
2550
|
+
}, [isOpen, hasInteracted, onBlur]);
|
|
2303
2551
|
useOnClickOutside.useOnClickOutside([triggerRef, dropdownRef], closeCalendar, void 0, {
|
|
2304
2552
|
capture: true
|
|
2305
2553
|
});
|
|
@@ -2343,7 +2591,7 @@ function DateRangePicker({
|
|
|
2343
2591
|
for (let day = 1; day <= daysInMonth; day++) {
|
|
2344
2592
|
days.push(new Date(year, month, day));
|
|
2345
2593
|
}
|
|
2346
|
-
return /* @__PURE__ */
|
|
2594
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { className: "w-[240px] max-w-full" }, /* @__PURE__ */ React17__namespace.createElement("div", { className: "flex items-center justify-between pb-3" }, controls?.prev ? /* @__PURE__ */ React17__namespace.createElement(
|
|
2347
2595
|
"button",
|
|
2348
2596
|
{
|
|
2349
2597
|
type: "button",
|
|
@@ -2352,7 +2600,7 @@ function DateRangePicker({
|
|
|
2352
2600
|
"aria-label": "Previous month"
|
|
2353
2601
|
},
|
|
2354
2602
|
"\u2039"
|
|
2355
|
-
) : /* @__PURE__ */
|
|
2603
|
+
) : /* @__PURE__ */ React17__namespace.createElement("div", { className: "h-8 w-8", "aria-hidden": "true" }), /* @__PURE__ */ React17__namespace.createElement("div", { className: "font-medium text-sm" }, `${monthNames[month]} ${year}`), controls?.next ? /* @__PURE__ */ React17__namespace.createElement(
|
|
2356
2604
|
"button",
|
|
2357
2605
|
{
|
|
2358
2606
|
type: "button",
|
|
@@ -2361,13 +2609,13 @@ function DateRangePicker({
|
|
|
2361
2609
|
"aria-label": "Next month"
|
|
2362
2610
|
},
|
|
2363
2611
|
"\u203A"
|
|
2364
|
-
) : /* @__PURE__ */
|
|
2612
|
+
) : /* @__PURE__ */ React17__namespace.createElement("div", { className: "h-8 w-8", "aria-hidden": "true" })), /* @__PURE__ */ React17__namespace.createElement(
|
|
2365
2613
|
"div",
|
|
2366
2614
|
{
|
|
2367
2615
|
className: "grid gap-1 text-xs text-muted-foreground",
|
|
2368
2616
|
style: dayGridStyle
|
|
2369
2617
|
},
|
|
2370
|
-
["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */
|
|
2618
|
+
["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React17__namespace.createElement(
|
|
2371
2619
|
"div",
|
|
2372
2620
|
{
|
|
2373
2621
|
key: `${month}-${day}`,
|
|
@@ -2375,9 +2623,9 @@ function DateRangePicker({
|
|
|
2375
2623
|
},
|
|
2376
2624
|
day
|
|
2377
2625
|
))
|
|
2378
|
-
), /* @__PURE__ */
|
|
2626
|
+
), /* @__PURE__ */ React17__namespace.createElement("div", { className: "grid gap-1", style: dayGridStyle }, days.map((date, index) => {
|
|
2379
2627
|
if (!date) {
|
|
2380
|
-
return /* @__PURE__ */
|
|
2628
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { key: `empty-${month}-${index}`, className: "h-8 w-8" });
|
|
2381
2629
|
}
|
|
2382
2630
|
const isStart = rangeStart && date.toDateString() === rangeStart.toDateString();
|
|
2383
2631
|
const isEnd = rangeEnd && date.toDateString() === rangeEnd.toDateString();
|
|
@@ -2389,7 +2637,7 @@ function DateRangePicker({
|
|
|
2389
2637
|
);
|
|
2390
2638
|
const isToday = date.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
|
|
2391
2639
|
const disabled2 = isDisabled(date);
|
|
2392
|
-
return /* @__PURE__ */
|
|
2640
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
2393
2641
|
"button",
|
|
2394
2642
|
{
|
|
2395
2643
|
key: date.toISOString(),
|
|
@@ -2414,27 +2662,27 @@ function DateRangePicker({
|
|
|
2414
2662
|
};
|
|
2415
2663
|
const combinedClassName = cn("relative", className);
|
|
2416
2664
|
const displayValue = rangeStart && rangeEnd ? `${formatDate2(rangeStart, format)}${separator}${formatDate2(rangeEnd, format)}` : rangeStart ? formatDate2(rangeStart, format) : "";
|
|
2417
|
-
return /* @__PURE__ */
|
|
2665
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { className: combinedClassName, onBlur: handleBlur }, /* @__PURE__ */ React17__namespace.createElement(
|
|
2418
2666
|
"input",
|
|
2419
2667
|
{
|
|
2420
2668
|
type: "hidden",
|
|
2421
2669
|
name: `${name}[start]`,
|
|
2422
2670
|
value: rangeStart ? rangeStart.toISOString() : ""
|
|
2423
2671
|
}
|
|
2424
|
-
), /* @__PURE__ */
|
|
2672
|
+
), /* @__PURE__ */ React17__namespace.createElement(
|
|
2425
2673
|
"input",
|
|
2426
2674
|
{
|
|
2427
2675
|
type: "hidden",
|
|
2428
2676
|
name: `${name}[end]`,
|
|
2429
2677
|
value: rangeEnd ? rangeEnd.toISOString() : ""
|
|
2430
2678
|
}
|
|
2431
|
-
), /* @__PURE__ */
|
|
2679
|
+
), /* @__PURE__ */ React17__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React17__namespace.createElement(
|
|
2432
2680
|
"span",
|
|
2433
2681
|
{
|
|
2434
2682
|
className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
|
|
2435
2683
|
"aria-hidden": "true"
|
|
2436
2684
|
},
|
|
2437
|
-
/* @__PURE__ */
|
|
2685
|
+
/* @__PURE__ */ React17__namespace.createElement(
|
|
2438
2686
|
"svg",
|
|
2439
2687
|
{
|
|
2440
2688
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -2447,9 +2695,9 @@ function DateRangePicker({
|
|
|
2447
2695
|
strokeLinejoin: "round",
|
|
2448
2696
|
strokeWidth: "2"
|
|
2449
2697
|
},
|
|
2450
|
-
/* @__PURE__ */
|
|
2698
|
+
/* @__PURE__ */ React17__namespace.createElement("path", { d: "M8 2v4m8-4v4m5 8V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8M3 10h18m-5 10l2 2l4-4" })
|
|
2451
2699
|
)
|
|
2452
|
-
), /* @__PURE__ */
|
|
2700
|
+
), /* @__PURE__ */ React17__namespace.createElement(
|
|
2453
2701
|
"input",
|
|
2454
2702
|
{
|
|
2455
2703
|
ref: triggerRef,
|
|
@@ -2474,7 +2722,7 @@ function DateRangePicker({
|
|
|
2474
2722
|
"aria-required": required || props["aria-required"],
|
|
2475
2723
|
readOnly: true
|
|
2476
2724
|
}
|
|
2477
|
-
), clearable && (rangeStart || rangeEnd) && !disabled && /* @__PURE__ */
|
|
2725
|
+
), clearable && (rangeStart || rangeEnd) && !disabled && /* @__PURE__ */ React17__namespace.createElement(
|
|
2478
2726
|
"button",
|
|
2479
2727
|
{
|
|
2480
2728
|
type: "button",
|
|
@@ -2484,14 +2732,14 @@ function DateRangePicker({
|
|
|
2484
2732
|
tabIndex: -1
|
|
2485
2733
|
},
|
|
2486
2734
|
"\u2715"
|
|
2487
|
-
)), isOpen && !disabled && /* @__PURE__ */
|
|
2735
|
+
)), isOpen && !disabled && /* @__PURE__ */ React17__namespace.createElement(
|
|
2488
2736
|
"div",
|
|
2489
2737
|
{
|
|
2490
2738
|
ref: dropdownRef,
|
|
2491
2739
|
className: "absolute z-50 top-full mt-1 w-fit rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3"
|
|
2492
2740
|
},
|
|
2493
|
-
/* @__PURE__ */
|
|
2494
|
-
rangeStart && !rangeEnd && /* @__PURE__ */
|
|
2741
|
+
/* @__PURE__ */ React17__namespace.createElement("div", { role: "grid", "aria-label": "Calendar" }, /* @__PURE__ */ React17__namespace.createElement("div", { className: "grid gap-4", style: monthsGridStyle }, renderMonth(selectedMonth, { prev: true }), renderMonth(addMonths(selectedMonth, 1), { next: true }))),
|
|
2742
|
+
rangeStart && !rangeEnd && /* @__PURE__ */ React17__namespace.createElement("div", { className: "text-xs text-center pt-2 border-t border-border mt-2" }, "Select end date")
|
|
2495
2743
|
));
|
|
2496
2744
|
}
|
|
2497
2745
|
DateRangePicker.displayName = "DateRangePicker";
|
|
@@ -2563,11 +2811,11 @@ function RichTextEditor({
|
|
|
2563
2811
|
],
|
|
2564
2812
|
...props
|
|
2565
2813
|
}) {
|
|
2566
|
-
const [currentMode, setCurrentMode] =
|
|
2567
|
-
const [content, setContent] =
|
|
2568
|
-
const editorRef =
|
|
2569
|
-
const textareaRef =
|
|
2570
|
-
|
|
2814
|
+
const [currentMode, setCurrentMode] = React17__namespace.useState(mode);
|
|
2815
|
+
const [content, setContent] = React17__namespace.useState(value);
|
|
2816
|
+
const editorRef = React17__namespace.useRef(null);
|
|
2817
|
+
const textareaRef = React17__namespace.useRef(null);
|
|
2818
|
+
React17__namespace.useEffect(() => {
|
|
2571
2819
|
setContent(value);
|
|
2572
2820
|
if (currentMode === "wysiwyg" && editorRef.current) {
|
|
2573
2821
|
editorRef.current.innerHTML = value;
|
|
@@ -2655,7 +2903,7 @@ function RichTextEditor({
|
|
|
2655
2903
|
}
|
|
2656
2904
|
}
|
|
2657
2905
|
};
|
|
2658
|
-
const hasValue =
|
|
2906
|
+
const hasValue = React17__namespace.useMemo(() => {
|
|
2659
2907
|
if (!content) return false;
|
|
2660
2908
|
const stripped = content.replace(/<[^>]+>/g, "").trim();
|
|
2661
2909
|
return stripped.length > 0;
|
|
@@ -2672,10 +2920,10 @@ function RichTextEditor({
|
|
|
2672
2920
|
maxHeight,
|
|
2673
2921
|
overflowY: maxHeight ? "auto" : void 0
|
|
2674
2922
|
};
|
|
2675
|
-
return /* @__PURE__ */
|
|
2923
|
+
return /* @__PURE__ */ React17__namespace.createElement("div", { className: combinedClassName }, /* @__PURE__ */ React17__namespace.createElement("input", { type: "hidden", name, value: content }), showToolbar && /* @__PURE__ */ React17__namespace.createElement("div", { className: "flex items-center justify-between p-2 border-b border-border bg-muted/50" }, /* @__PURE__ */ React17__namespace.createElement("div", { className: "flex items-center gap-1" }, toolbarButtons.map((buttonName) => {
|
|
2676
2924
|
const button = toolbarConfig[buttonName];
|
|
2677
2925
|
if (!button) return null;
|
|
2678
|
-
return /* @__PURE__ */
|
|
2926
|
+
return /* @__PURE__ */ React17__namespace.createElement(
|
|
2679
2927
|
"button",
|
|
2680
2928
|
{
|
|
2681
2929
|
key: buttonName,
|
|
@@ -2688,7 +2936,7 @@ function RichTextEditor({
|
|
|
2688
2936
|
},
|
|
2689
2937
|
button.icon
|
|
2690
2938
|
);
|
|
2691
|
-
})), allowModeSwitch && /* @__PURE__ */
|
|
2939
|
+
})), allowModeSwitch && /* @__PURE__ */ React17__namespace.createElement(
|
|
2692
2940
|
"button",
|
|
2693
2941
|
{
|
|
2694
2942
|
type: "button",
|
|
@@ -2699,7 +2947,7 @@ function RichTextEditor({
|
|
|
2699
2947
|
"aria-label": `Switch to ${currentMode === "wysiwyg" ? "Markdown" : "WYSIWYG"}`
|
|
2700
2948
|
},
|
|
2701
2949
|
currentMode === "wysiwyg" ? "MD" : "WYSIWYG"
|
|
2702
|
-
)), /* @__PURE__ */
|
|
2950
|
+
)), /* @__PURE__ */ React17__namespace.createElement("div", { style: editorStyle }, currentMode === "wysiwyg" ? /* @__PURE__ */ React17__namespace.createElement(
|
|
2703
2951
|
"div",
|
|
2704
2952
|
{
|
|
2705
2953
|
ref: editorRef,
|
|
@@ -2714,7 +2962,7 @@ function RichTextEditor({
|
|
|
2714
2962
|
"aria-required": required || props["aria-required"],
|
|
2715
2963
|
suppressContentEditableWarning: true
|
|
2716
2964
|
}
|
|
2717
|
-
) : /* @__PURE__ */
|
|
2965
|
+
) : /* @__PURE__ */ React17__namespace.createElement(
|
|
2718
2966
|
"textarea",
|
|
2719
2967
|
{
|
|
2720
2968
|
ref: textareaRef,
|
|
@@ -2737,7 +2985,7 @@ function RichTextEditor({
|
|
|
2737
2985
|
}
|
|
2738
2986
|
RichTextEditor.displayName = "RichTextEditor";
|
|
2739
2987
|
|
|
2740
|
-
exports.Checkbox =
|
|
2988
|
+
exports.Checkbox = Checkbox2;
|
|
2741
2989
|
exports.CheckboxGroup = CheckboxGroup;
|
|
2742
2990
|
exports.DatePicker = DatePicker;
|
|
2743
2991
|
exports.DateRangePicker = DateRangePicker;
|
|
@@ -2745,7 +2993,8 @@ exports.FileInput = FileInput;
|
|
|
2745
2993
|
exports.MultiSelect = MultiSelect;
|
|
2746
2994
|
exports.Radio = Radio;
|
|
2747
2995
|
exports.RichTextEditor = RichTextEditor;
|
|
2748
|
-
exports.Select =
|
|
2996
|
+
exports.Select = Select2;
|
|
2997
|
+
exports.Switch = Switch2;
|
|
2749
2998
|
exports.TextArea = TextArea;
|
|
2750
2999
|
exports.TextInput = TextInput;
|
|
2751
3000
|
exports.TimePicker = TimePicker;
|