@page-speed/forms 0.4.3 → 0.4.4
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 +119 -27
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +104 -12
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +119 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +104 -12
- package/dist/index.js.map +1 -1
- package/dist/inputs.cjs +519 -523
- package/dist/inputs.cjs.map +1 -1
- package/dist/inputs.d.cts +21 -54
- package/dist/inputs.d.ts +21 -54
- package/dist/inputs.js +518 -522
- package/dist/inputs.js.map +1 -1
- package/dist/integration.cjs +11 -3
- package/dist/integration.cjs.map +1 -1
- package/dist/integration.js +11 -3
- package/dist/integration.js.map +1 -1
- package/package.json +1 -1
package/dist/inputs.cjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React8 = require('react');
|
|
4
4
|
var clsx = require('clsx');
|
|
5
5
|
var tailwindMerge = require('tailwind-merge');
|
|
6
|
+
var useOnClickOutside = require('@opensite/hooks/useOnClickOutside');
|
|
6
7
|
|
|
7
8
|
function _interopNamespace(e) {
|
|
8
9
|
if (e && e.__esModule) return e;
|
|
@@ -22,7 +23,13 @@ function _interopNamespace(e) {
|
|
|
22
23
|
return Object.freeze(n);
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
var
|
|
26
|
+
var React8__namespace = /*#__PURE__*/_interopNamespace(React8);
|
|
27
|
+
|
|
28
|
+
// src/inputs/TextInput.tsx
|
|
29
|
+
function cn(...inputs) {
|
|
30
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
31
|
+
}
|
|
32
|
+
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]";
|
|
26
33
|
|
|
27
34
|
// src/inputs/TextInput.tsx
|
|
28
35
|
function TextInput({
|
|
@@ -45,10 +52,17 @@ function TextInput({
|
|
|
45
52
|
const handleBlur = () => {
|
|
46
53
|
onBlur?.();
|
|
47
54
|
};
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
const hasValue = String(value ?? "").trim().length > 0;
|
|
56
|
+
const combinedClassName = cn(
|
|
57
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors",
|
|
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__ */ React8__namespace.createElement(
|
|
52
66
|
"input",
|
|
53
67
|
{
|
|
54
68
|
type,
|
|
@@ -92,10 +106,17 @@ function TextArea({
|
|
|
92
106
|
const handleBlur = () => {
|
|
93
107
|
onBlur?.();
|
|
94
108
|
};
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
109
|
+
const hasValue = String(value ?? "").trim().length > 0;
|
|
110
|
+
const combinedClassName = cn(
|
|
111
|
+
"flex min-h-20 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm transition-colors",
|
|
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__ */ React8__namespace.createElement(
|
|
99
120
|
"textarea",
|
|
100
121
|
{
|
|
101
122
|
name,
|
|
@@ -119,9 +140,53 @@ function TextArea({
|
|
|
119
140
|
);
|
|
120
141
|
}
|
|
121
142
|
TextArea.displayName = "TextArea";
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
143
|
+
var LabelGroup = ({
|
|
144
|
+
labelHtmlFor,
|
|
145
|
+
required = false,
|
|
146
|
+
variant = "label",
|
|
147
|
+
secondaryId,
|
|
148
|
+
secondary,
|
|
149
|
+
primary,
|
|
150
|
+
primaryClassName,
|
|
151
|
+
secondaryClassName
|
|
152
|
+
}) => {
|
|
153
|
+
const primaryClasses = cn(
|
|
154
|
+
"text-sm font-medium leading-snug",
|
|
155
|
+
variant === "legend" ? "mb-1.5" : "mb-1 block",
|
|
156
|
+
primaryClassName
|
|
157
|
+
);
|
|
158
|
+
const requiredIndicator = required ? /* @__PURE__ */ React8__namespace.createElement("span", { className: "text-destructive pl-0.5", "aria-label": "required" }, "*") : null;
|
|
159
|
+
let primaryElement = null;
|
|
160
|
+
if (primary) {
|
|
161
|
+
if (variant === "label") {
|
|
162
|
+
primaryElement = /* @__PURE__ */ React8__namespace.createElement(
|
|
163
|
+
"label",
|
|
164
|
+
{
|
|
165
|
+
htmlFor: labelHtmlFor,
|
|
166
|
+
"data-slot": "field-label",
|
|
167
|
+
className: primaryClasses
|
|
168
|
+
},
|
|
169
|
+
primary,
|
|
170
|
+
requiredIndicator
|
|
171
|
+
);
|
|
172
|
+
} else if (variant === "legend") {
|
|
173
|
+
primaryElement = /* @__PURE__ */ React8__namespace.createElement("legend", { "data-slot": "field-legend", className: primaryClasses }, primary, requiredIndicator);
|
|
174
|
+
} else {
|
|
175
|
+
primaryElement = /* @__PURE__ */ React8__namespace.createElement("div", { "data-slot": "field-label", className: primaryClasses }, primary, requiredIndicator);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const secondaryElement = secondary ? /* @__PURE__ */ React8__namespace.createElement(
|
|
179
|
+
"p",
|
|
180
|
+
{
|
|
181
|
+
"data-slot": "field-description",
|
|
182
|
+
id: secondaryId,
|
|
183
|
+
className: cn("text-sm leading-normal font-normal", secondaryClassName)
|
|
184
|
+
},
|
|
185
|
+
secondary
|
|
186
|
+
) : null;
|
|
187
|
+
if (!primaryElement && !secondaryElement) return null;
|
|
188
|
+
return /* @__PURE__ */ React8__namespace.createElement(React8__namespace.Fragment, null, primaryElement, secondaryElement);
|
|
189
|
+
};
|
|
125
190
|
|
|
126
191
|
// src/inputs/Checkbox.tsx
|
|
127
192
|
function Checkbox({
|
|
@@ -136,12 +201,12 @@ function Checkbox({
|
|
|
136
201
|
indeterminate = false,
|
|
137
202
|
label,
|
|
138
203
|
description,
|
|
139
|
-
|
|
204
|
+
useChoiceCard = false,
|
|
140
205
|
...props
|
|
141
206
|
}) {
|
|
142
|
-
const inputRef =
|
|
207
|
+
const inputRef = React8__namespace.useRef(null);
|
|
143
208
|
const checkboxId = props.id || `checkbox-${name}`;
|
|
144
|
-
|
|
209
|
+
React8__namespace.useEffect(() => {
|
|
145
210
|
if (inputRef.current) {
|
|
146
211
|
inputRef.current.indeterminate = indeterminate;
|
|
147
212
|
}
|
|
@@ -153,7 +218,7 @@ function Checkbox({
|
|
|
153
218
|
onBlur?.();
|
|
154
219
|
};
|
|
155
220
|
const isActive = value || indeterminate && !value;
|
|
156
|
-
const checkbox = /* @__PURE__ */
|
|
221
|
+
const checkbox = /* @__PURE__ */ React8__namespace.createElement(
|
|
157
222
|
"div",
|
|
158
223
|
{
|
|
159
224
|
className: cn(
|
|
@@ -161,7 +226,7 @@ function Checkbox({
|
|
|
161
226
|
!label && className
|
|
162
227
|
)
|
|
163
228
|
},
|
|
164
|
-
/* @__PURE__ */
|
|
229
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
165
230
|
"input",
|
|
166
231
|
{
|
|
167
232
|
ref: inputRef,
|
|
@@ -180,7 +245,7 @@ function Checkbox({
|
|
|
180
245
|
...props
|
|
181
246
|
}
|
|
182
247
|
),
|
|
183
|
-
/* @__PURE__ */
|
|
248
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
184
249
|
"div",
|
|
185
250
|
{
|
|
186
251
|
className: cn(
|
|
@@ -193,7 +258,7 @@ function Checkbox({
|
|
|
193
258
|
"peer-focus-visible:ring-2 peer-focus-visible:ring-ring/50 peer-focus-visible:ring-offset-1"
|
|
194
259
|
)
|
|
195
260
|
},
|
|
196
|
-
value && /* @__PURE__ */
|
|
261
|
+
value && /* @__PURE__ */ React8__namespace.createElement(
|
|
197
262
|
"svg",
|
|
198
263
|
{
|
|
199
264
|
className: "size-3.5",
|
|
@@ -204,9 +269,9 @@ function Checkbox({
|
|
|
204
269
|
strokeLinecap: "round",
|
|
205
270
|
strokeLinejoin: "round"
|
|
206
271
|
},
|
|
207
|
-
/* @__PURE__ */
|
|
272
|
+
/* @__PURE__ */ React8__namespace.createElement("polyline", { points: "20 6 9 17 4 12" })
|
|
208
273
|
),
|
|
209
|
-
indeterminate && !value && /* @__PURE__ */
|
|
274
|
+
indeterminate && !value && /* @__PURE__ */ React8__namespace.createElement(
|
|
210
275
|
"svg",
|
|
211
276
|
{
|
|
212
277
|
className: "size-3.5",
|
|
@@ -217,31 +282,44 @@ function Checkbox({
|
|
|
217
282
|
strokeLinecap: "round",
|
|
218
283
|
strokeLinejoin: "round"
|
|
219
284
|
},
|
|
220
|
-
/* @__PURE__ */
|
|
285
|
+
/* @__PURE__ */ React8__namespace.createElement("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
|
|
221
286
|
)
|
|
222
287
|
)
|
|
223
288
|
);
|
|
224
289
|
if (label) {
|
|
225
|
-
return /* @__PURE__ */
|
|
290
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
226
291
|
"label",
|
|
227
292
|
{
|
|
228
293
|
className: cn(
|
|
229
294
|
"w-full h-full flex gap-3 p-3 duration-200",
|
|
230
|
-
|
|
231
|
-
|
|
295
|
+
useChoiceCard && "border rounded-lg hover:ring-2",
|
|
296
|
+
useChoiceCard && value && "ring-2",
|
|
232
297
|
disabled ? "opacity-50 cursor-not-allowed hover:ring-0" : "cursor-pointer",
|
|
233
298
|
className
|
|
234
299
|
),
|
|
235
300
|
htmlFor: checkboxId
|
|
236
301
|
},
|
|
237
|
-
/* @__PURE__ */
|
|
238
|
-
"
|
|
302
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
303
|
+
"div",
|
|
239
304
|
{
|
|
240
|
-
className:
|
|
241
|
-
|
|
305
|
+
className: cn(
|
|
306
|
+
"flex w-full flex-row gap-2",
|
|
307
|
+
useChoiceCard ? "items-start" : "items-center"
|
|
308
|
+
)
|
|
242
309
|
},
|
|
243
|
-
|
|
244
|
-
|
|
310
|
+
checkbox,
|
|
311
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
312
|
+
LabelGroup,
|
|
313
|
+
{
|
|
314
|
+
variant: "text",
|
|
315
|
+
primary: label,
|
|
316
|
+
secondary: description,
|
|
317
|
+
secondaryId: description ? `${checkboxId}-description` : void 0,
|
|
318
|
+
primaryClassName: "mb-0",
|
|
319
|
+
secondaryClassName: "text-xs opacity-75"
|
|
320
|
+
}
|
|
321
|
+
)
|
|
322
|
+
)
|
|
245
323
|
);
|
|
246
324
|
}
|
|
247
325
|
return checkbox;
|
|
@@ -275,13 +353,11 @@ function CheckboxGroup({
|
|
|
275
353
|
).length;
|
|
276
354
|
const allSelected = selectedEnabledCount === enabledOptions.length;
|
|
277
355
|
const someSelected = selectedEnabledCount > 0 && !allSelected;
|
|
278
|
-
const
|
|
279
|
-
if (options
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
return "inline";
|
|
356
|
+
const useChoiceCard = React8__namespace.useMemo(() => {
|
|
357
|
+
if (!options) return false;
|
|
358
|
+
return options?.some((opt) => opt.description);
|
|
283
359
|
}, [options]);
|
|
284
|
-
const countableValue =
|
|
360
|
+
const countableValue = React8__namespace.useMemo(() => {
|
|
285
361
|
if (value?.length > 0) {
|
|
286
362
|
return value.length;
|
|
287
363
|
}
|
|
@@ -306,29 +382,37 @@ function CheckboxGroup({
|
|
|
306
382
|
onBlur?.();
|
|
307
383
|
};
|
|
308
384
|
const maxReached = Boolean(maxSelections && countableValue >= maxSelections);
|
|
309
|
-
const containerClass =
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
|
|
385
|
+
const containerClass = React8__namespace.useMemo(() => {
|
|
386
|
+
return cn(
|
|
387
|
+
"w-full gap-3 grid grid-cols-1 border-0 m-0 p-0 min-w-0",
|
|
388
|
+
(layout === "grid" || layout === "inline") && "md:grid-cols-2",
|
|
389
|
+
className
|
|
390
|
+
);
|
|
391
|
+
}, [layout, className]);
|
|
392
|
+
const groupDescriptionId = description ? `${name}-description` : void 0;
|
|
393
|
+
const groupAriaDescribedBy = [props["aria-describedby"], groupDescriptionId].filter(Boolean).join(" ") || void 0;
|
|
394
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
395
|
+
"fieldset",
|
|
318
396
|
{
|
|
319
397
|
className: containerClass,
|
|
320
398
|
role: "group",
|
|
321
399
|
"aria-invalid": error || props["aria-invalid"],
|
|
322
|
-
"aria-describedby":
|
|
400
|
+
"aria-describedby": groupAriaDescribedBy,
|
|
323
401
|
"aria-required": required || props["aria-required"],
|
|
324
|
-
"aria-label": typeof label === "string" ? label : props["aria-label"]
|
|
325
|
-
style: layout === "grid" ? {
|
|
326
|
-
gridTemplateColumns: `repeat(${gridColumns}, 1fr)`
|
|
327
|
-
} : void 0
|
|
402
|
+
"aria-label": typeof label === "string" ? label : props["aria-label"]
|
|
328
403
|
},
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
404
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
405
|
+
LabelGroup,
|
|
406
|
+
{
|
|
407
|
+
labelHtmlFor: name,
|
|
408
|
+
required,
|
|
409
|
+
variant: "legend",
|
|
410
|
+
secondaryId: groupDescriptionId,
|
|
411
|
+
secondary: description,
|
|
412
|
+
primary: label
|
|
413
|
+
}
|
|
414
|
+
),
|
|
415
|
+
showSelectAll && enabledOptions.length > 0 && /* @__PURE__ */ React8__namespace.createElement(
|
|
332
416
|
Checkbox,
|
|
333
417
|
{
|
|
334
418
|
name: `${name}-select-all`,
|
|
@@ -338,7 +422,7 @@ function CheckboxGroup({
|
|
|
338
422
|
onBlur: handleBlur,
|
|
339
423
|
indeterminate: someSelected,
|
|
340
424
|
label: selectAllLabel,
|
|
341
|
-
|
|
425
|
+
useChoiceCard,
|
|
342
426
|
disabled,
|
|
343
427
|
"aria-label": selectAllLabel
|
|
344
428
|
}
|
|
@@ -346,7 +430,7 @@ function CheckboxGroup({
|
|
|
346
430
|
options.map((option) => {
|
|
347
431
|
const isChecked = value.includes(option.value);
|
|
348
432
|
const isDisabled = disabled || option.disabled || maxReached && !isChecked;
|
|
349
|
-
return /* @__PURE__ */
|
|
433
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
350
434
|
Checkbox,
|
|
351
435
|
{
|
|
352
436
|
key: option.value,
|
|
@@ -360,11 +444,11 @@ function CheckboxGroup({
|
|
|
360
444
|
error,
|
|
361
445
|
label: renderOption ? renderOption(option) : option.label,
|
|
362
446
|
description: renderOption ? void 0 : option.description,
|
|
363
|
-
|
|
447
|
+
useChoiceCard
|
|
364
448
|
}
|
|
365
449
|
);
|
|
366
450
|
}),
|
|
367
|
-
(minSelections || maxSelections) && /* @__PURE__ */
|
|
451
|
+
(minSelections || maxSelections) && /* @__PURE__ */ React8__namespace.createElement(
|
|
368
452
|
"div",
|
|
369
453
|
{
|
|
370
454
|
className: cn(
|
|
@@ -373,8 +457,8 @@ function CheckboxGroup({
|
|
|
373
457
|
),
|
|
374
458
|
"aria-live": "polite"
|
|
375
459
|
},
|
|
376
|
-
minSelections && countableValue < minSelections && /* @__PURE__ */
|
|
377
|
-
maxSelections && /* @__PURE__ */
|
|
460
|
+
minSelections && countableValue < minSelections && /* @__PURE__ */ React8__namespace.createElement("span", null, "Select at least ", minSelections, " option", minSelections !== 1 ? "s" : ""),
|
|
461
|
+
maxSelections && /* @__PURE__ */ React8__namespace.createElement("span", null, countableValue, "/", maxSelections, " selected")
|
|
378
462
|
)
|
|
379
463
|
);
|
|
380
464
|
}
|
|
@@ -390,6 +474,7 @@ function Radio({
|
|
|
390
474
|
className = "",
|
|
391
475
|
layout = "stacked",
|
|
392
476
|
label,
|
|
477
|
+
description,
|
|
393
478
|
options,
|
|
394
479
|
...props
|
|
395
480
|
}) {
|
|
@@ -424,33 +509,43 @@ function Radio({
|
|
|
424
509
|
const handleBlur = () => {
|
|
425
510
|
onBlur?.();
|
|
426
511
|
};
|
|
427
|
-
const useChoiceCard =
|
|
512
|
+
const useChoiceCard = React8__namespace.useMemo(() => {
|
|
428
513
|
return options.some((option) => option.description);
|
|
429
514
|
}, [options]);
|
|
430
|
-
const containerClass =
|
|
515
|
+
const containerClass = React8__namespace.useMemo(() => {
|
|
431
516
|
return cn(
|
|
432
|
-
"w-full gap-3 grid grid-cols-1",
|
|
433
|
-
layout === "inline" && "md:grid-cols-2",
|
|
517
|
+
"w-full gap-3 grid grid-cols-1 border-0 m-0 p-0 min-w-0",
|
|
518
|
+
(layout === "grid" || layout === "inline") && "md:grid-cols-2",
|
|
434
519
|
className
|
|
435
520
|
);
|
|
436
521
|
}, [layout, className]);
|
|
437
|
-
|
|
438
|
-
|
|
522
|
+
const groupDescriptionId = description ? `${name}-description` : void 0;
|
|
523
|
+
const groupAriaDescribedBy = [props["aria-describedby"], groupDescriptionId].filter(Boolean).join(" ") || void 0;
|
|
524
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
525
|
+
"fieldset",
|
|
439
526
|
{
|
|
440
527
|
className: containerClass,
|
|
441
528
|
role: "radiogroup",
|
|
442
529
|
"aria-invalid": error || props["aria-invalid"],
|
|
443
|
-
"aria-describedby":
|
|
530
|
+
"aria-describedby": groupAriaDescribedBy,
|
|
444
531
|
"aria-required": required || props["aria-required"],
|
|
445
532
|
"aria-label": typeof label === "string" ? label : props["aria-label"]
|
|
446
533
|
},
|
|
447
|
-
|
|
534
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
535
|
+
LabelGroup,
|
|
536
|
+
{
|
|
537
|
+
variant: "legend",
|
|
538
|
+
primary: label,
|
|
539
|
+
secondary: description,
|
|
540
|
+
secondaryId: groupDescriptionId
|
|
541
|
+
}
|
|
542
|
+
),
|
|
448
543
|
options.map((option, index) => {
|
|
449
544
|
const isChecked = value === option.value;
|
|
450
545
|
const isDisabled = disabled || option.disabled;
|
|
451
546
|
const radioId = `${name}-${option.value}`;
|
|
452
547
|
const hasDescription = option.description != null && option.description !== "";
|
|
453
|
-
const radioIndicator = /* @__PURE__ */
|
|
548
|
+
const radioIndicator = /* @__PURE__ */ React8__namespace.createElement("div", { className: "relative inline-flex items-center justify-center" }, /* @__PURE__ */ React8__namespace.createElement(
|
|
454
549
|
"input",
|
|
455
550
|
{
|
|
456
551
|
type: "radio",
|
|
@@ -465,7 +560,7 @@ function Radio({
|
|
|
465
560
|
className: "peer sr-only",
|
|
466
561
|
"aria-describedby": hasDescription ? `${radioId}-description` : props["aria-describedby"]
|
|
467
562
|
}
|
|
468
|
-
), /* @__PURE__ */
|
|
563
|
+
), /* @__PURE__ */ React8__namespace.createElement(
|
|
469
564
|
"div",
|
|
470
565
|
{
|
|
471
566
|
className: cn(
|
|
@@ -478,10 +573,20 @@ function Radio({
|
|
|
478
573
|
"peer-focus-visible:ring-2 peer-focus-visible:ring-ring/50 peer-focus-visible:ring-offset-1"
|
|
479
574
|
)
|
|
480
575
|
},
|
|
481
|
-
isChecked && /* @__PURE__ */
|
|
576
|
+
isChecked && /* @__PURE__ */ React8__namespace.createElement("div", { className: "size-3 rounded-full bg-primary" })
|
|
482
577
|
));
|
|
483
|
-
const labelContent = /* @__PURE__ */
|
|
484
|
-
|
|
578
|
+
const labelContent = /* @__PURE__ */ React8__namespace.createElement(
|
|
579
|
+
LabelGroup,
|
|
580
|
+
{
|
|
581
|
+
variant: "text",
|
|
582
|
+
primary: option.label,
|
|
583
|
+
secondary: hasDescription ? option.description : void 0,
|
|
584
|
+
secondaryId: hasDescription ? `${radioId}-description` : void 0,
|
|
585
|
+
primaryClassName: "mb-0",
|
|
586
|
+
secondaryClassName: "text-xs opacity-75"
|
|
587
|
+
}
|
|
588
|
+
);
|
|
589
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
485
590
|
"label",
|
|
486
591
|
{
|
|
487
592
|
key: option.value,
|
|
@@ -495,7 +600,18 @@ function Radio({
|
|
|
495
600
|
onKeyDown: (e) => handleKeyDown(e, index),
|
|
496
601
|
tabIndex: isDisabled ? -1 : 0
|
|
497
602
|
},
|
|
498
|
-
/* @__PURE__ */
|
|
603
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
604
|
+
"div",
|
|
605
|
+
{
|
|
606
|
+
className: cn(
|
|
607
|
+
"flex w-full flex-row gap-2",
|
|
608
|
+
useChoiceCard ? "items-start" : "items-center"
|
|
609
|
+
)
|
|
610
|
+
},
|
|
611
|
+
!useChoiceCard && radioIndicator,
|
|
612
|
+
/* @__PURE__ */ React8__namespace.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, labelContent),
|
|
613
|
+
useChoiceCard && radioIndicator
|
|
614
|
+
)
|
|
499
615
|
);
|
|
500
616
|
})
|
|
501
617
|
);
|
|
@@ -520,19 +636,19 @@ function Select({
|
|
|
520
636
|
renderOption,
|
|
521
637
|
...props
|
|
522
638
|
}) {
|
|
523
|
-
const [isOpen, setIsOpen] =
|
|
524
|
-
const [searchQuery, setSearchQuery] =
|
|
525
|
-
const [focusedIndex, setFocusedIndex] =
|
|
526
|
-
const selectRef =
|
|
527
|
-
const searchInputRef =
|
|
639
|
+
const [isOpen, setIsOpen] = React8__namespace.useState(false);
|
|
640
|
+
const [searchQuery, setSearchQuery] = React8__namespace.useState("");
|
|
641
|
+
const [focusedIndex, setFocusedIndex] = React8__namespace.useState(-1);
|
|
642
|
+
const selectRef = React8__namespace.useRef(null);
|
|
643
|
+
const searchInputRef = React8__namespace.useRef(null);
|
|
528
644
|
const dropdownId = `${name}-dropdown`;
|
|
529
|
-
const allOptions =
|
|
645
|
+
const allOptions = React8__namespace.useMemo(() => {
|
|
530
646
|
if (optionGroups.length > 0) {
|
|
531
647
|
return optionGroups.flatMap((group) => group.options);
|
|
532
648
|
}
|
|
533
649
|
return options;
|
|
534
650
|
}, [options, optionGroups]);
|
|
535
|
-
const filteredOptions =
|
|
651
|
+
const filteredOptions = React8__namespace.useMemo(() => {
|
|
536
652
|
if (!searchQuery.trim()) {
|
|
537
653
|
return allOptions;
|
|
538
654
|
}
|
|
@@ -542,9 +658,10 @@ function Select({
|
|
|
542
658
|
return label.toLowerCase().includes(query);
|
|
543
659
|
});
|
|
544
660
|
}, [allOptions, searchQuery]);
|
|
545
|
-
const selectedOption =
|
|
661
|
+
const selectedOption = React8__namespace.useMemo(() => {
|
|
546
662
|
return allOptions.find((opt) => opt.value === value);
|
|
547
663
|
}, [allOptions, value]);
|
|
664
|
+
const hasValue = Boolean(value);
|
|
548
665
|
const handleSelect = (optionValue) => {
|
|
549
666
|
onChange(optionValue);
|
|
550
667
|
setIsOpen(false);
|
|
@@ -639,27 +756,22 @@ function Select({
|
|
|
639
756
|
break;
|
|
640
757
|
}
|
|
641
758
|
};
|
|
642
|
-
const handleBlur = () => {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
const handleClickOutside = (event) => {
|
|
647
|
-
if (selectRef.current && !selectRef.current.contains(event.target)) {
|
|
648
|
-
setIsOpen(false);
|
|
649
|
-
setSearchQuery("");
|
|
650
|
-
setFocusedIndex(-1);
|
|
651
|
-
handleBlur();
|
|
652
|
-
}
|
|
653
|
-
};
|
|
654
|
-
if (isOpen) {
|
|
655
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
656
|
-
return () => {
|
|
657
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
|
658
|
-
};
|
|
759
|
+
const handleBlur = (event) => {
|
|
760
|
+
const nextTarget = event?.relatedTarget;
|
|
761
|
+
if (!nextTarget || !selectRef.current?.contains(nextTarget)) {
|
|
762
|
+
onBlur?.();
|
|
659
763
|
}
|
|
660
|
-
}
|
|
661
|
-
const
|
|
662
|
-
|
|
764
|
+
};
|
|
765
|
+
const closeDropdown = React8__namespace.useCallback(() => {
|
|
766
|
+
if (!isOpen) return;
|
|
767
|
+
setIsOpen(false);
|
|
768
|
+
setSearchQuery("");
|
|
769
|
+
setFocusedIndex(-1);
|
|
770
|
+
onBlur?.();
|
|
771
|
+
}, [isOpen, onBlur]);
|
|
772
|
+
useOnClickOutside.useOnClickOutside(selectRef, closeDropdown, "pointerdown", true);
|
|
773
|
+
const combinedClassName = cn("relative w-full", className);
|
|
774
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
663
775
|
"div",
|
|
664
776
|
{
|
|
665
777
|
ref: selectRef,
|
|
@@ -667,7 +779,7 @@ function Select({
|
|
|
667
779
|
onKeyDown: handleKeyDown,
|
|
668
780
|
onBlur: handleBlur
|
|
669
781
|
},
|
|
670
|
-
/* @__PURE__ */
|
|
782
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
671
783
|
"select",
|
|
672
784
|
{
|
|
673
785
|
name,
|
|
@@ -680,13 +792,19 @@ function Select({
|
|
|
680
792
|
tabIndex: -1,
|
|
681
793
|
style: { display: "none" }
|
|
682
794
|
},
|
|
683
|
-
/* @__PURE__ */
|
|
684
|
-
allOptions.map((option) => /* @__PURE__ */
|
|
795
|
+
/* @__PURE__ */ React8__namespace.createElement("option", { value: "" }, "Select..."),
|
|
796
|
+
allOptions.map((option) => /* @__PURE__ */ React8__namespace.createElement("option", { key: option.value, value: option.value }, typeof option.label === "string" ? option.label : option.value))
|
|
685
797
|
),
|
|
686
|
-
/* @__PURE__ */
|
|
798
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
687
799
|
"div",
|
|
688
800
|
{
|
|
689
|
-
className:
|
|
801
|
+
className: cn(
|
|
802
|
+
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm",
|
|
803
|
+
"cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
804
|
+
!error && hasValue && "ring-2 ring-ring",
|
|
805
|
+
disabled && "cursor-not-allowed opacity-50 pointer-events-none",
|
|
806
|
+
error && "border-destructive ring-1 ring-destructive"
|
|
807
|
+
),
|
|
690
808
|
onClick: handleToggle,
|
|
691
809
|
role: "combobox",
|
|
692
810
|
"aria-expanded": isOpen,
|
|
@@ -697,8 +815,8 @@ function Select({
|
|
|
697
815
|
"aria-disabled": disabled,
|
|
698
816
|
tabIndex: disabled ? -1 : 0
|
|
699
817
|
},
|
|
700
|
-
/* @__PURE__ */
|
|
701
|
-
/* @__PURE__ */
|
|
818
|
+
/* @__PURE__ */ React8__namespace.createElement("span", { className: "flex items-center flex-1 overflow-hidden text-ellipsis" }, selectedOption ? renderOption ? renderOption(selectedOption) : selectedOption.label : /* @__PURE__ */ React8__namespace.createElement("span", { className: "relative" }, placeholder)),
|
|
819
|
+
/* @__PURE__ */ React8__namespace.createElement("div", { className: "flex items-center gap-1 ml-2" }, loading && /* @__PURE__ */ React8__namespace.createElement("span", { className: "text-xs" }, "\u23F3"), clearable && value && !disabled && !loading && /* @__PURE__ */ React8__namespace.createElement(
|
|
702
820
|
"button",
|
|
703
821
|
{
|
|
704
822
|
type: "button",
|
|
@@ -708,21 +826,24 @@ function Select({
|
|
|
708
826
|
tabIndex: -1
|
|
709
827
|
},
|
|
710
828
|
"\u2715"
|
|
711
|
-
), /* @__PURE__ */
|
|
829
|
+
), /* @__PURE__ */ React8__namespace.createElement("span", { className: "text-xs leading-none", "aria-hidden": "true" }, isOpen ? "\u25B2" : "\u25BC"))
|
|
712
830
|
),
|
|
713
|
-
isOpen && /* @__PURE__ */
|
|
831
|
+
isOpen && /* @__PURE__ */ React8__namespace.createElement(
|
|
714
832
|
"div",
|
|
715
833
|
{
|
|
716
834
|
id: dropdownId,
|
|
717
835
|
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",
|
|
718
836
|
role: "listbox"
|
|
719
837
|
},
|
|
720
|
-
searchable && /* @__PURE__ */
|
|
838
|
+
searchable && /* @__PURE__ */ React8__namespace.createElement("div", { className: "p-2 border-b border-border" }, /* @__PURE__ */ React8__namespace.createElement(
|
|
721
839
|
"input",
|
|
722
840
|
{
|
|
723
841
|
ref: searchInputRef,
|
|
724
842
|
type: "text",
|
|
725
|
-
className:
|
|
843
|
+
className: cn(
|
|
844
|
+
"w-full border border-input rounded px-2 py-1 text-sm bg-transparent outline-none focus:ring-1 focus:ring-ring",
|
|
845
|
+
INPUT_AUTOFILL_RESET_CLASSES
|
|
846
|
+
),
|
|
726
847
|
placeholder: "Search...",
|
|
727
848
|
value: searchQuery,
|
|
728
849
|
onChange: handleSearchChange,
|
|
@@ -730,19 +851,19 @@ function Select({
|
|
|
730
851
|
"aria-label": "Search options"
|
|
731
852
|
}
|
|
732
853
|
)),
|
|
733
|
-
/* @__PURE__ */
|
|
854
|
+
/* @__PURE__ */ React8__namespace.createElement("div", { className: "max-h-64 overflow-y-auto p-1" }, filteredOptions.length === 0 ? /* @__PURE__ */ React8__namespace.createElement("div", { className: "py-2 px-3 text-center text-sm " }, "No options found") : optionGroups.length > 0 ? (
|
|
734
855
|
// Render grouped options
|
|
735
856
|
optionGroups.map((group, groupIndex) => {
|
|
736
857
|
const groupOptions = group.options.filter(
|
|
737
858
|
(opt) => filteredOptions.includes(opt)
|
|
738
859
|
);
|
|
739
860
|
if (groupOptions.length === 0) return null;
|
|
740
|
-
return /* @__PURE__ */
|
|
861
|
+
return /* @__PURE__ */ React8__namespace.createElement("div", { key: groupIndex, className: "py-1" }, /* @__PURE__ */ React8__namespace.createElement("div", { className: "py-1.5 px-2 text-xs font-semibold " }, group.label), groupOptions.map((option) => {
|
|
741
862
|
const globalIndex = filteredOptions.indexOf(option);
|
|
742
863
|
const isSelected = value === option.value;
|
|
743
864
|
const isFocused = globalIndex === focusedIndex;
|
|
744
865
|
const isDisabled = option.disabled;
|
|
745
|
-
return /* @__PURE__ */
|
|
866
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
746
867
|
"div",
|
|
747
868
|
{
|
|
748
869
|
key: option.value,
|
|
@@ -762,7 +883,7 @@ function Select({
|
|
|
762
883
|
const isSelected = value === option.value;
|
|
763
884
|
const isFocused = index === focusedIndex;
|
|
764
885
|
const isDisabled = option.disabled;
|
|
765
|
-
return /* @__PURE__ */
|
|
886
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
766
887
|
"div",
|
|
767
888
|
{
|
|
768
889
|
key: option.value,
|
|
@@ -805,14 +926,14 @@ function FileInput({
|
|
|
805
926
|
onFileRemove,
|
|
806
927
|
...props
|
|
807
928
|
}) {
|
|
808
|
-
const inputRef =
|
|
809
|
-
const [dragActive, setDragActive] =
|
|
810
|
-
const [cropperOpen, setCropperOpen] =
|
|
811
|
-
const [imageToCrop, setImageToCrop] =
|
|
812
|
-
const [crop, setCrop] =
|
|
813
|
-
const [zoom, setZoom] =
|
|
814
|
-
const [croppedAreaPixels, setCroppedAreaPixels] =
|
|
815
|
-
const validateFile =
|
|
929
|
+
const inputRef = React8__namespace.useRef(null);
|
|
930
|
+
const [dragActive, setDragActive] = React8__namespace.useState(false);
|
|
931
|
+
const [cropperOpen, setCropperOpen] = React8__namespace.useState(false);
|
|
932
|
+
const [imageToCrop, setImageToCrop] = React8__namespace.useState(null);
|
|
933
|
+
const [crop, setCrop] = React8__namespace.useState({ x: 0, y: 0 });
|
|
934
|
+
const [zoom, setZoom] = React8__namespace.useState(1);
|
|
935
|
+
const [croppedAreaPixels, setCroppedAreaPixels] = React8__namespace.useState(null);
|
|
936
|
+
const validateFile = React8__namespace.useCallback(
|
|
816
937
|
(file) => {
|
|
817
938
|
if (accept) {
|
|
818
939
|
const acceptedTypes = accept.split(",").map((t) => t.trim());
|
|
@@ -847,7 +968,7 @@ function FileInput({
|
|
|
847
968
|
},
|
|
848
969
|
[accept, maxSize]
|
|
849
970
|
);
|
|
850
|
-
const handleFiles =
|
|
971
|
+
const handleFiles = React8__namespace.useCallback(
|
|
851
972
|
(fileList) => {
|
|
852
973
|
if (!fileList || fileList.length === 0) return;
|
|
853
974
|
const newFiles = Array.from(fileList);
|
|
@@ -898,7 +1019,7 @@ function FileInput({
|
|
|
898
1019
|
onValidationError
|
|
899
1020
|
]
|
|
900
1021
|
);
|
|
901
|
-
const createCroppedImage =
|
|
1022
|
+
const createCroppedImage = React8__namespace.useCallback(
|
|
902
1023
|
async (imageUrl, cropArea) => {
|
|
903
1024
|
return new Promise((resolve, reject) => {
|
|
904
1025
|
const image = new Image();
|
|
@@ -942,7 +1063,7 @@ function FileInput({
|
|
|
942
1063
|
},
|
|
943
1064
|
[]
|
|
944
1065
|
);
|
|
945
|
-
const handleCropSave =
|
|
1066
|
+
const handleCropSave = React8__namespace.useCallback(async () => {
|
|
946
1067
|
if (!imageToCrop || !croppedAreaPixels) return;
|
|
947
1068
|
try {
|
|
948
1069
|
const croppedBlob = await createCroppedImage(
|
|
@@ -975,7 +1096,7 @@ function FileInput({
|
|
|
975
1096
|
onChange,
|
|
976
1097
|
multiple
|
|
977
1098
|
]);
|
|
978
|
-
const handleCropCancel =
|
|
1099
|
+
const handleCropCancel = React8__namespace.useCallback(() => {
|
|
979
1100
|
if (imageToCrop) {
|
|
980
1101
|
URL.revokeObjectURL(imageToCrop.url);
|
|
981
1102
|
}
|
|
@@ -985,13 +1106,13 @@ function FileInput({
|
|
|
985
1106
|
setZoom(1);
|
|
986
1107
|
setCroppedAreaPixels(null);
|
|
987
1108
|
}, [imageToCrop]);
|
|
988
|
-
const onCropChange =
|
|
1109
|
+
const onCropChange = React8__namespace.useCallback((crop2) => {
|
|
989
1110
|
setCrop(crop2);
|
|
990
1111
|
}, []);
|
|
991
|
-
const onZoomChange =
|
|
1112
|
+
const onZoomChange = React8__namespace.useCallback((zoom2) => {
|
|
992
1113
|
setZoom(zoom2);
|
|
993
1114
|
}, []);
|
|
994
|
-
const onCropCompleteInternal =
|
|
1115
|
+
const onCropCompleteInternal = React8__namespace.useCallback(
|
|
995
1116
|
(_, croppedAreaPixels2) => {
|
|
996
1117
|
setCroppedAreaPixels(croppedAreaPixels2);
|
|
997
1118
|
},
|
|
@@ -1052,7 +1173,7 @@ function FileInput({
|
|
|
1052
1173
|
}
|
|
1053
1174
|
return null;
|
|
1054
1175
|
};
|
|
1055
|
-
|
|
1176
|
+
React8__namespace.useEffect(() => {
|
|
1056
1177
|
return () => {
|
|
1057
1178
|
value.forEach((file) => {
|
|
1058
1179
|
const previewUrl = getPreviewUrl(file);
|
|
@@ -1066,7 +1187,7 @@ function FileInput({
|
|
|
1066
1187
|
};
|
|
1067
1188
|
}, [value, imageToCrop]);
|
|
1068
1189
|
const combinedClassName = `${className}`.trim();
|
|
1069
|
-
return /* @__PURE__ */
|
|
1190
|
+
return /* @__PURE__ */ React8__namespace.createElement("div", { className: combinedClassName }, /* @__PURE__ */ React8__namespace.createElement(
|
|
1070
1191
|
"input",
|
|
1071
1192
|
{
|
|
1072
1193
|
ref: inputRef,
|
|
@@ -1083,10 +1204,10 @@ function FileInput({
|
|
|
1083
1204
|
"aria-required": required || props["aria-required"],
|
|
1084
1205
|
style: { display: "none" }
|
|
1085
1206
|
}
|
|
1086
|
-
), /* @__PURE__ */
|
|
1207
|
+
), /* @__PURE__ */ React8__namespace.createElement(
|
|
1087
1208
|
"div",
|
|
1088
1209
|
{
|
|
1089
|
-
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-
|
|
1210
|
+
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" : ""}`,
|
|
1090
1211
|
onDragEnter: handleDrag,
|
|
1091
1212
|
onDragLeave: handleDrag,
|
|
1092
1213
|
onDragOver: handleDrag,
|
|
@@ -1098,7 +1219,7 @@ function FileInput({
|
|
|
1098
1219
|
"aria-label": placeholder,
|
|
1099
1220
|
"aria-disabled": disabled
|
|
1100
1221
|
},
|
|
1101
|
-
/* @__PURE__ */
|
|
1222
|
+
/* @__PURE__ */ React8__namespace.createElement("div", { className: "flex flex-col items-center gap-2 text-center" }, /* @__PURE__ */ React8__namespace.createElement(
|
|
1102
1223
|
"svg",
|
|
1103
1224
|
{
|
|
1104
1225
|
width: "48",
|
|
@@ -1111,19 +1232,19 @@ function FileInput({
|
|
|
1111
1232
|
strokeLinejoin: "round",
|
|
1112
1233
|
"aria-hidden": "true"
|
|
1113
1234
|
},
|
|
1114
|
-
/* @__PURE__ */
|
|
1115
|
-
/* @__PURE__ */
|
|
1116
|
-
/* @__PURE__ */
|
|
1117
|
-
), /* @__PURE__ */
|
|
1118
|
-
), value.length > 0 && /* @__PURE__ */
|
|
1235
|
+
/* @__PURE__ */ React8__namespace.createElement("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
1236
|
+
/* @__PURE__ */ React8__namespace.createElement("polyline", { points: "17 8 12 3 7 8" }),
|
|
1237
|
+
/* @__PURE__ */ React8__namespace.createElement("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
|
|
1238
|
+
), /* @__PURE__ */ React8__namespace.createElement("p", { className: "text-sm font-medium" }, value.length > 0 ? `${value.length} file(s) selected` : placeholder), accept && /* @__PURE__ */ React8__namespace.createElement("p", { className: "text-xs" }, "Accepted: ", accept), maxSize && /* @__PURE__ */ React8__namespace.createElement("p", { className: "text-xs " }, "Max size: ", formatFileSize(maxSize)))
|
|
1239
|
+
), value.length > 0 && /* @__PURE__ */ React8__namespace.createElement("ul", { className: "flex flex-col gap-2 mt-4", role: "list" }, value.map((file, index) => {
|
|
1119
1240
|
const previewUrl = showPreview ? getPreviewUrl(file) : null;
|
|
1120
|
-
return /* @__PURE__ */
|
|
1241
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
1121
1242
|
"li",
|
|
1122
1243
|
{
|
|
1123
1244
|
key: `${file.name}-${index}`,
|
|
1124
1245
|
className: "flex items-center gap-3 p-3 rounded-md border border-border bg-card text-card-foreground hover:bg-primary/50 transition-colors"
|
|
1125
1246
|
},
|
|
1126
|
-
previewUrl && /* @__PURE__ */
|
|
1247
|
+
previewUrl && /* @__PURE__ */ React8__namespace.createElement(
|
|
1127
1248
|
"img",
|
|
1128
1249
|
{
|
|
1129
1250
|
src: previewUrl,
|
|
@@ -1133,7 +1254,7 @@ function FileInput({
|
|
|
1133
1254
|
height: "48"
|
|
1134
1255
|
}
|
|
1135
1256
|
),
|
|
1136
|
-
/* @__PURE__ */
|
|
1257
|
+
/* @__PURE__ */ React8__namespace.createElement("div", { className: "flex flex-col flex-1 min-w-0" }, /* @__PURE__ */ React8__namespace.createElement("span", { className: "text-sm font-medium truncate" }, file.name), /* @__PURE__ */ React8__namespace.createElement("span", { className: "text-xs" }, formatFileSize(file.size)), showProgress && uploadProgress[file.name] !== void 0 && /* @__PURE__ */ React8__namespace.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ React8__namespace.createElement(
|
|
1137
1258
|
"div",
|
|
1138
1259
|
{
|
|
1139
1260
|
className: "h-1.5 bg-muted rounded-full overflow-hidden flex-1",
|
|
@@ -1143,15 +1264,15 @@ function FileInput({
|
|
|
1143
1264
|
"aria-valuemax": 100,
|
|
1144
1265
|
"aria-label": `Upload progress: ${uploadProgress[file.name]}%`
|
|
1145
1266
|
},
|
|
1146
|
-
/* @__PURE__ */
|
|
1267
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
1147
1268
|
"div",
|
|
1148
1269
|
{
|
|
1149
1270
|
className: "h-full bg-primary transition-all",
|
|
1150
1271
|
style: { width: `${uploadProgress[file.name]}%` }
|
|
1151
1272
|
}
|
|
1152
1273
|
)
|
|
1153
|
-
), /* @__PURE__ */
|
|
1154
|
-
enableCropping && file.type.startsWith("image/") && /* @__PURE__ */
|
|
1274
|
+
), /* @__PURE__ */ React8__namespace.createElement("span", { className: "text-xs " }, uploadProgress[file.name], "%"))),
|
|
1275
|
+
enableCropping && file.type.startsWith("image/") && /* @__PURE__ */ React8__namespace.createElement(
|
|
1155
1276
|
"button",
|
|
1156
1277
|
{
|
|
1157
1278
|
type: "button",
|
|
@@ -1163,7 +1284,7 @@ function FileInput({
|
|
|
1163
1284
|
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
1164
1285
|
"aria-label": `Crop ${file.name}`
|
|
1165
1286
|
},
|
|
1166
|
-
/* @__PURE__ */
|
|
1287
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
1167
1288
|
"svg",
|
|
1168
1289
|
{
|
|
1169
1290
|
width: "20",
|
|
@@ -1176,11 +1297,11 @@ function FileInput({
|
|
|
1176
1297
|
strokeLinejoin: "round",
|
|
1177
1298
|
"aria-hidden": "true"
|
|
1178
1299
|
},
|
|
1179
|
-
/* @__PURE__ */
|
|
1180
|
-
/* @__PURE__ */
|
|
1300
|
+
/* @__PURE__ */ React8__namespace.createElement("path", { d: "M6.13 1L6 16a2 2 0 0 0 2 2h15" }),
|
|
1301
|
+
/* @__PURE__ */ React8__namespace.createElement("path", { d: "M1 6.13L16 6a2 2 0 0 1 2 2v15" })
|
|
1181
1302
|
)
|
|
1182
1303
|
),
|
|
1183
|
-
/* @__PURE__ */
|
|
1304
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
1184
1305
|
"button",
|
|
1185
1306
|
{
|
|
1186
1307
|
type: "button",
|
|
@@ -1192,7 +1313,7 @@ function FileInput({
|
|
|
1192
1313
|
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
1193
1314
|
"aria-label": `Remove ${file.name}`
|
|
1194
1315
|
},
|
|
1195
|
-
/* @__PURE__ */
|
|
1316
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
1196
1317
|
"svg",
|
|
1197
1318
|
{
|
|
1198
1319
|
width: "20",
|
|
@@ -1205,19 +1326,19 @@ function FileInput({
|
|
|
1205
1326
|
strokeLinejoin: "round",
|
|
1206
1327
|
"aria-hidden": "true"
|
|
1207
1328
|
},
|
|
1208
|
-
/* @__PURE__ */
|
|
1209
|
-
/* @__PURE__ */
|
|
1329
|
+
/* @__PURE__ */ React8__namespace.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
1330
|
+
/* @__PURE__ */ React8__namespace.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
1210
1331
|
)
|
|
1211
1332
|
)
|
|
1212
1333
|
);
|
|
1213
|
-
})), cropperOpen && imageToCrop && /* @__PURE__ */
|
|
1334
|
+
})), cropperOpen && imageToCrop && /* @__PURE__ */ React8__namespace.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center" }, /* @__PURE__ */ React8__namespace.createElement(
|
|
1214
1335
|
"div",
|
|
1215
1336
|
{
|
|
1216
1337
|
className: "absolute inset-0 bg-black/50",
|
|
1217
1338
|
onClick: handleCropCancel,
|
|
1218
1339
|
"aria-label": "Close cropper"
|
|
1219
1340
|
}
|
|
1220
|
-
), /* @__PURE__ */
|
|
1341
|
+
), /* @__PURE__ */ React8__namespace.createElement("div", { className: "relative bg-popover border border-border rounded-lg shadow-lg max-w-3xl w-full mx-4" }, /* @__PURE__ */ React8__namespace.createElement("div", { className: "flex items-center justify-between p-4 border-b border-border" }, /* @__PURE__ */ React8__namespace.createElement("h3", { className: "text-lg font-semibold" }, "Crop Image"), /* @__PURE__ */ React8__namespace.createElement(
|
|
1221
1342
|
"button",
|
|
1222
1343
|
{
|
|
1223
1344
|
type: "button",
|
|
@@ -1226,7 +1347,7 @@ function FileInput({
|
|
|
1226
1347
|
"aria-label": "Close"
|
|
1227
1348
|
},
|
|
1228
1349
|
"\u2715"
|
|
1229
|
-
)), /* @__PURE__ */
|
|
1350
|
+
)), /* @__PURE__ */ React8__namespace.createElement("div", { className: "p-4" }, /* @__PURE__ */ React8__namespace.createElement(
|
|
1230
1351
|
"div",
|
|
1231
1352
|
{
|
|
1232
1353
|
className: "relative w-full h-96 bg-muted rounded-md overflow-hidden",
|
|
@@ -1248,7 +1369,7 @@ function FileInput({
|
|
|
1248
1369
|
document.addEventListener("mouseup", handleMouseUp);
|
|
1249
1370
|
}
|
|
1250
1371
|
},
|
|
1251
|
-
/* @__PURE__ */
|
|
1372
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
1252
1373
|
"img",
|
|
1253
1374
|
{
|
|
1254
1375
|
src: imageToCrop.url,
|
|
@@ -1283,7 +1404,7 @@ function FileInput({
|
|
|
1283
1404
|
}
|
|
1284
1405
|
}
|
|
1285
1406
|
),
|
|
1286
|
-
/* @__PURE__ */
|
|
1407
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
1287
1408
|
"div",
|
|
1288
1409
|
{
|
|
1289
1410
|
className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 border-2 border-primary rounded pointer-events-none",
|
|
@@ -1292,9 +1413,9 @@ function FileInput({
|
|
|
1292
1413
|
aspectRatio: cropAspectRatio ? String(cropAspectRatio) : void 0
|
|
1293
1414
|
}
|
|
1294
1415
|
},
|
|
1295
|
-
/* @__PURE__ */
|
|
1416
|
+
/* @__PURE__ */ React8__namespace.createElement("div", { className: "absolute inset-0 grid grid-cols-3 grid-rows-3" }, /* @__PURE__ */ React8__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React8__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React8__namespace.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React8__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React8__namespace.createElement("div", { className: "border-r border-b border-primary/30" }), /* @__PURE__ */ React8__namespace.createElement("div", { className: "border-b border-primary/30" }), /* @__PURE__ */ React8__namespace.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React8__namespace.createElement("div", { className: "border-r border-primary/30" }), /* @__PURE__ */ React8__namespace.createElement("div", null))
|
|
1296
1417
|
)
|
|
1297
|
-
), /* @__PURE__ */
|
|
1418
|
+
), /* @__PURE__ */ React8__namespace.createElement("div", { className: "flex items-center gap-3 mt-4" }, /* @__PURE__ */ React8__namespace.createElement(
|
|
1298
1419
|
"label",
|
|
1299
1420
|
{
|
|
1300
1421
|
htmlFor: "zoom-slider",
|
|
@@ -1303,7 +1424,7 @@ function FileInput({
|
|
|
1303
1424
|
"Zoom: ",
|
|
1304
1425
|
zoom.toFixed(1),
|
|
1305
1426
|
"x"
|
|
1306
|
-
), /* @__PURE__ */
|
|
1427
|
+
), /* @__PURE__ */ React8__namespace.createElement(
|
|
1307
1428
|
"input",
|
|
1308
1429
|
{
|
|
1309
1430
|
id: "zoom-slider",
|
|
@@ -1316,7 +1437,7 @@ function FileInput({
|
|
|
1316
1437
|
className: "flex-1 h-2 bg-muted rounded-lg appearance-none cursor-pointer",
|
|
1317
1438
|
"aria-label": "Zoom level"
|
|
1318
1439
|
}
|
|
1319
|
-
))), /* @__PURE__ */
|
|
1440
|
+
))), /* @__PURE__ */ React8__namespace.createElement("div", { className: "flex items-center justify-end gap-2 p-4 border-t border-border" }, /* @__PURE__ */ React8__namespace.createElement(
|
|
1320
1441
|
"button",
|
|
1321
1442
|
{
|
|
1322
1443
|
type: "button",
|
|
@@ -1324,7 +1445,7 @@ function FileInput({
|
|
|
1324
1445
|
onClick: handleCropCancel
|
|
1325
1446
|
},
|
|
1326
1447
|
"Cancel"
|
|
1327
|
-
), /* @__PURE__ */
|
|
1448
|
+
), /* @__PURE__ */ React8__namespace.createElement(
|
|
1328
1449
|
"button",
|
|
1329
1450
|
{
|
|
1330
1451
|
type: "button",
|
|
@@ -1343,27 +1464,6 @@ function formatDate(date, format) {
|
|
|
1343
1464
|
const year = d.getFullYear();
|
|
1344
1465
|
return format.replace("MM", month).replace("dd", day).replace("yyyy", String(year)).replace("yy", String(year).slice(2));
|
|
1345
1466
|
}
|
|
1346
|
-
function parseDate(dateString, format) {
|
|
1347
|
-
if (!dateString) return null;
|
|
1348
|
-
try {
|
|
1349
|
-
if (format === "MM/dd/yyyy" || format === "MM-dd-yyyy") {
|
|
1350
|
-
const parts = dateString.split(/[/-]/);
|
|
1351
|
-
if (parts.length === 3) {
|
|
1352
|
-
const month = parseInt(parts[0], 10) - 1;
|
|
1353
|
-
const day = parseInt(parts[1], 10);
|
|
1354
|
-
const year = parseInt(parts[2], 10);
|
|
1355
|
-
const date2 = new Date(year, month, day);
|
|
1356
|
-
if (!isNaN(date2.getTime())) {
|
|
1357
|
-
return date2;
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
const date = new Date(dateString);
|
|
1362
|
-
return isNaN(date.getTime()) ? null : date;
|
|
1363
|
-
} catch {
|
|
1364
|
-
return null;
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
1467
|
function isDateInArray(date, dates) {
|
|
1368
1468
|
const dateStr = date.toDateString();
|
|
1369
1469
|
return dates.some((d) => d.toDateString() === dateStr);
|
|
@@ -1387,43 +1487,30 @@ function DatePicker({
|
|
|
1387
1487
|
showIcon = true,
|
|
1388
1488
|
...props
|
|
1389
1489
|
}) {
|
|
1390
|
-
const [isOpen, setIsOpen] =
|
|
1391
|
-
const [
|
|
1392
|
-
const [selectedMonth, setSelectedMonth] = React7__namespace.useState(
|
|
1490
|
+
const [isOpen, setIsOpen] = React8__namespace.useState(false);
|
|
1491
|
+
const [selectedMonth, setSelectedMonth] = React8__namespace.useState(
|
|
1393
1492
|
value || /* @__PURE__ */ new Date()
|
|
1394
1493
|
);
|
|
1395
|
-
const containerRef =
|
|
1396
|
-
const inputRef =
|
|
1397
|
-
|
|
1398
|
-
setInputValue(formatDate(value, format));
|
|
1494
|
+
const containerRef = React8__namespace.useRef(null);
|
|
1495
|
+
const inputRef = React8__namespace.useRef(null);
|
|
1496
|
+
React8__namespace.useEffect(() => {
|
|
1399
1497
|
if (value) {
|
|
1400
1498
|
setSelectedMonth(value);
|
|
1401
1499
|
}
|
|
1402
|
-
}, [value
|
|
1500
|
+
}, [value]);
|
|
1403
1501
|
const handleDateSelect = (date) => {
|
|
1404
1502
|
onChange(date);
|
|
1405
1503
|
setIsOpen(false);
|
|
1406
1504
|
onBlur?.();
|
|
1407
1505
|
};
|
|
1408
|
-
const handleInputChange = (e) => {
|
|
1409
|
-
const newValue = e.target.value;
|
|
1410
|
-
setInputValue(newValue);
|
|
1411
|
-
const parsedDate = parseDate(newValue, format);
|
|
1412
|
-
if (parsedDate && !isNaN(parsedDate.getTime())) {
|
|
1413
|
-
onChange(parsedDate);
|
|
1414
|
-
} else if (newValue === "") {
|
|
1415
|
-
onChange(null);
|
|
1416
|
-
}
|
|
1417
|
-
};
|
|
1418
1506
|
const handleClear = (e) => {
|
|
1419
1507
|
e.stopPropagation();
|
|
1420
1508
|
onChange(null);
|
|
1421
|
-
setInputValue("");
|
|
1422
1509
|
inputRef.current?.focus();
|
|
1423
1510
|
};
|
|
1424
1511
|
const handleToggle = () => {
|
|
1425
1512
|
if (disabled) return;
|
|
1426
|
-
setIsOpen(!
|
|
1513
|
+
setIsOpen((prev) => !prev);
|
|
1427
1514
|
};
|
|
1428
1515
|
const isDisabled = (date) => {
|
|
1429
1516
|
if (minDate && date < minDate) return true;
|
|
@@ -1432,20 +1519,17 @@ function DatePicker({
|
|
|
1432
1519
|
if (isDateDisabled && isDateDisabled(date)) return true;
|
|
1433
1520
|
return false;
|
|
1434
1521
|
};
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
onBlur?.();
|
|
1440
|
-
}
|
|
1441
|
-
};
|
|
1442
|
-
if (isOpen) {
|
|
1443
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
1444
|
-
return () => {
|
|
1445
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
|
1446
|
-
};
|
|
1447
|
-
}
|
|
1522
|
+
const closeCalendar = React8__namespace.useCallback(() => {
|
|
1523
|
+
if (!isOpen) return;
|
|
1524
|
+
setIsOpen(false);
|
|
1525
|
+
onBlur?.();
|
|
1448
1526
|
}, [isOpen, onBlur]);
|
|
1527
|
+
useOnClickOutside.useOnClickOutside(containerRef, closeCalendar, "pointerdown", true);
|
|
1528
|
+
const dayGridStyle = {
|
|
1529
|
+
gridTemplateColumns: "repeat(7, minmax(0, 1fr))"
|
|
1530
|
+
};
|
|
1531
|
+
const hasValue = Boolean(value);
|
|
1532
|
+
const displayValue = formatDate(value, format);
|
|
1449
1533
|
const renderCalendar = () => {
|
|
1450
1534
|
const year = selectedMonth.getFullYear();
|
|
1451
1535
|
const month = selectedMonth.getMonth();
|
|
@@ -1478,44 +1562,57 @@ function DatePicker({
|
|
|
1478
1562
|
const handleNextMonth = () => {
|
|
1479
1563
|
setSelectedMonth(new Date(year, month + 1, 1));
|
|
1480
1564
|
};
|
|
1481
|
-
return /* @__PURE__ */
|
|
1565
|
+
return /* @__PURE__ */ React8__namespace.createElement("div", { role: "grid", "aria-label": "Calendar", className: "w-[248px] max-w-full" }, /* @__PURE__ */ React8__namespace.createElement("div", { className: "flex items-center justify-between pb-3" }, /* @__PURE__ */ React8__namespace.createElement(
|
|
1482
1566
|
"button",
|
|
1483
1567
|
{
|
|
1484
1568
|
type: "button",
|
|
1485
|
-
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-
|
|
1569
|
+
className: "flex items-center justify-center h-8 w-8 rounded-md border-none bg-transparent hover:bg-muted cursor-pointer transition-colors",
|
|
1486
1570
|
onClick: handlePrevMonth,
|
|
1487
1571
|
"aria-label": "Previous month"
|
|
1488
1572
|
},
|
|
1489
|
-
"\
|
|
1490
|
-
), /* @__PURE__ */
|
|
1573
|
+
"\u2039"
|
|
1574
|
+
), /* @__PURE__ */ React8__namespace.createElement("div", { className: "font-medium text-sm" }, `${monthNames[month]} ${year}`), /* @__PURE__ */ React8__namespace.createElement(
|
|
1491
1575
|
"button",
|
|
1492
1576
|
{
|
|
1493
1577
|
type: "button",
|
|
1494
|
-
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-
|
|
1578
|
+
className: "flex items-center justify-center h-8 w-8 rounded-md border-none bg-transparent hover:bg-muted cursor-pointer transition-colors",
|
|
1495
1579
|
onClick: handleNextMonth,
|
|
1496
1580
|
"aria-label": "Next month"
|
|
1497
1581
|
},
|
|
1498
|
-
"\
|
|
1499
|
-
)), /* @__PURE__ */
|
|
1582
|
+
"\u203A"
|
|
1583
|
+
)), /* @__PURE__ */ React8__namespace.createElement(
|
|
1500
1584
|
"div",
|
|
1501
1585
|
{
|
|
1502
|
-
|
|
1503
|
-
|
|
1586
|
+
className: "grid gap-1 text-xs text-muted-foreground",
|
|
1587
|
+
style: dayGridStyle
|
|
1504
1588
|
},
|
|
1505
|
-
day
|
|
1506
|
-
|
|
1589
|
+
["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React8__namespace.createElement(
|
|
1590
|
+
"div",
|
|
1591
|
+
{
|
|
1592
|
+
key: day,
|
|
1593
|
+
className: "flex items-center justify-center h-8 w-8 font-medium"
|
|
1594
|
+
},
|
|
1595
|
+
day
|
|
1596
|
+
))
|
|
1597
|
+
), /* @__PURE__ */ React8__namespace.createElement("div", { className: "grid gap-1", style: dayGridStyle }, days.map((date, index) => {
|
|
1507
1598
|
if (!date) {
|
|
1508
|
-
return /* @__PURE__ */
|
|
1599
|
+
return /* @__PURE__ */ React8__namespace.createElement("div", { key: `empty-${index}`, className: "h-8 w-8" });
|
|
1509
1600
|
}
|
|
1510
1601
|
const isSelected = value && date.toDateString() === value.toDateString();
|
|
1511
1602
|
const isToday = date.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
|
|
1512
1603
|
const disabled2 = isDisabled(date);
|
|
1513
|
-
return /* @__PURE__ */
|
|
1604
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
1514
1605
|
"button",
|
|
1515
1606
|
{
|
|
1516
1607
|
key: date.toISOString(),
|
|
1517
1608
|
type: "button",
|
|
1518
|
-
className:
|
|
1609
|
+
className: cn(
|
|
1610
|
+
"flex items-center justify-center h-8 w-8 rounded-md border-none bg-transparent cursor-pointer text-sm transition-colors",
|
|
1611
|
+
"hover:bg-muted",
|
|
1612
|
+
isSelected && "bg-primary text-primary-foreground font-semibold",
|
|
1613
|
+
!isSelected && isToday && "border border-primary",
|
|
1614
|
+
disabled2 && "cursor-not-allowed opacity-50 pointer-events-none"
|
|
1615
|
+
),
|
|
1519
1616
|
onClick: () => !disabled2 && handleDateSelect(date),
|
|
1520
1617
|
disabled: disabled2,
|
|
1521
1618
|
"aria-label": formatDate(date, format)
|
|
@@ -1524,21 +1621,21 @@ function DatePicker({
|
|
|
1524
1621
|
);
|
|
1525
1622
|
})));
|
|
1526
1623
|
};
|
|
1527
|
-
const combinedClassName =
|
|
1528
|
-
return /* @__PURE__ */
|
|
1624
|
+
const combinedClassName = cn("relative", className);
|
|
1625
|
+
return /* @__PURE__ */ React8__namespace.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React8__namespace.createElement(
|
|
1529
1626
|
"input",
|
|
1530
1627
|
{
|
|
1531
1628
|
type: "hidden",
|
|
1532
1629
|
name,
|
|
1533
1630
|
value: value ? value.toISOString() : ""
|
|
1534
1631
|
}
|
|
1535
|
-
), /* @__PURE__ */
|
|
1632
|
+
), /* @__PURE__ */ React8__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React8__namespace.createElement(
|
|
1536
1633
|
"span",
|
|
1537
1634
|
{
|
|
1538
1635
|
className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
|
|
1539
1636
|
"aria-hidden": "true"
|
|
1540
1637
|
},
|
|
1541
|
-
/* @__PURE__ */
|
|
1638
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
1542
1639
|
"svg",
|
|
1543
1640
|
{
|
|
1544
1641
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -1551,16 +1648,24 @@ function DatePicker({
|
|
|
1551
1648
|
strokeLinejoin: "round",
|
|
1552
1649
|
strokeWidth: "2"
|
|
1553
1650
|
},
|
|
1554
|
-
/* @__PURE__ */
|
|
1651
|
+
/* @__PURE__ */ React8__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" })
|
|
1555
1652
|
)
|
|
1556
|
-
), /* @__PURE__ */
|
|
1653
|
+
), /* @__PURE__ */ React8__namespace.createElement(
|
|
1557
1654
|
"input",
|
|
1558
1655
|
{
|
|
1559
1656
|
ref: inputRef,
|
|
1560
1657
|
type: "text",
|
|
1561
|
-
className:
|
|
1562
|
-
|
|
1563
|
-
|
|
1658
|
+
className: cn(
|
|
1659
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent py-1 text-base shadow-sm transition-colors",
|
|
1660
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
1661
|
+
"disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
1662
|
+
INPUT_AUTOFILL_RESET_CLASSES,
|
|
1663
|
+
showIcon ? "pl-10" : "pl-3",
|
|
1664
|
+
clearable && value ? "pr-10" : "pr-3",
|
|
1665
|
+
!error && hasValue && "ring-2 ring-ring",
|
|
1666
|
+
error && "border-destructive ring-1 ring-destructive"
|
|
1667
|
+
),
|
|
1668
|
+
value: displayValue,
|
|
1564
1669
|
onClick: handleToggle,
|
|
1565
1670
|
onBlur,
|
|
1566
1671
|
disabled,
|
|
@@ -1571,7 +1676,7 @@ function DatePicker({
|
|
|
1571
1676
|
"aria-required": required || props["aria-required"],
|
|
1572
1677
|
readOnly: true
|
|
1573
1678
|
}
|
|
1574
|
-
), clearable && value && !disabled && /* @__PURE__ */
|
|
1679
|
+
), clearable && value && !disabled && /* @__PURE__ */ React8__namespace.createElement(
|
|
1575
1680
|
"button",
|
|
1576
1681
|
{
|
|
1577
1682
|
type: "button",
|
|
@@ -1581,49 +1686,49 @@ function DatePicker({
|
|
|
1581
1686
|
tabIndex: -1
|
|
1582
1687
|
},
|
|
1583
1688
|
"\u2715"
|
|
1584
|
-
)), isOpen && !disabled && /* @__PURE__ */
|
|
1689
|
+
)), isOpen && !disabled && /* @__PURE__ */ React8__namespace.createElement("div", { className: "absolute z-50 top-full mt-1 w-fit rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3" }, renderCalendar()));
|
|
1585
1690
|
}
|
|
1586
1691
|
DatePicker.displayName = "DatePicker";
|
|
1587
|
-
function
|
|
1588
|
-
if (!
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
const hour = hour24 === 0 ? 12 : hour24 > 12 ? hour24 - 12 : hour24;
|
|
1599
|
-
return { hour, minute, period };
|
|
1600
|
-
} else {
|
|
1601
|
-
const match = timeStr.match(/^(\d{1,2}):(\d{2})\s*(AM|PM)$/i);
|
|
1602
|
-
if (!match) return null;
|
|
1603
|
-
const hour = parseInt(match[1], 10);
|
|
1604
|
-
const minute = parseInt(match[2], 10);
|
|
1605
|
-
const period = match[3].toUpperCase();
|
|
1606
|
-
if (hour < 1 || hour > 12) return null;
|
|
1607
|
-
if (minute < 0 || minute > 59) return null;
|
|
1608
|
-
return { hour, minute, period };
|
|
1692
|
+
function normalizeToNativeTime(value) {
|
|
1693
|
+
if (!value) return "";
|
|
1694
|
+
const twelveHourMatch = value.match(
|
|
1695
|
+
/^(\d{1,2}):(\d{2})(?::(\d{2}))?\s*(AM|PM)$/i
|
|
1696
|
+
);
|
|
1697
|
+
if (twelveHourMatch) {
|
|
1698
|
+
const rawHour = parseInt(twelveHourMatch[1], 10);
|
|
1699
|
+
const minute = parseInt(twelveHourMatch[2], 10);
|
|
1700
|
+
const period = twelveHourMatch[4].toUpperCase();
|
|
1701
|
+
if (Number.isNaN(rawHour) || Number.isNaN(minute) || rawHour < 1 || rawHour > 12 || minute < 0 || minute > 59) {
|
|
1702
|
+
return "";
|
|
1609
1703
|
}
|
|
1610
|
-
|
|
1611
|
-
return
|
|
1704
|
+
const normalizedHour = period === "PM" ? rawHour === 12 ? 12 : rawHour + 12 : rawHour === 12 ? 0 : rawHour;
|
|
1705
|
+
return `${String(normalizedHour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
|
|
1612
1706
|
}
|
|
1707
|
+
const twentyFourHourMatch = value.match(/^(\d{1,2}):(\d{2})(?::(\d{2}))?$/);
|
|
1708
|
+
if (twentyFourHourMatch) {
|
|
1709
|
+
const hour = parseInt(twentyFourHourMatch[1], 10);
|
|
1710
|
+
const minute = parseInt(twentyFourHourMatch[2], 10);
|
|
1711
|
+
if (Number.isNaN(hour) || Number.isNaN(minute) || hour < 0 || hour > 23 || minute < 0 || minute > 59) {
|
|
1712
|
+
return "";
|
|
1713
|
+
}
|
|
1714
|
+
return `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
|
|
1715
|
+
}
|
|
1716
|
+
return "";
|
|
1613
1717
|
}
|
|
1614
|
-
function
|
|
1615
|
-
if (!
|
|
1718
|
+
function formatFromNativeTime(nativeValue, use24Hour) {
|
|
1719
|
+
if (!nativeValue) return "";
|
|
1720
|
+
const [hourValue, minuteValue] = nativeValue.split(":");
|
|
1721
|
+
const hour = parseInt(hourValue, 10);
|
|
1722
|
+
const minute = parseInt(minuteValue, 10);
|
|
1723
|
+
if (Number.isNaN(hour) || Number.isNaN(minute)) {
|
|
1724
|
+
return "";
|
|
1725
|
+
}
|
|
1616
1726
|
if (use24Hour) {
|
|
1617
|
-
|
|
1618
|
-
if (time.period === "PM" && time.hour !== 12) {
|
|
1619
|
-
hour24 = time.hour + 12;
|
|
1620
|
-
} else if (time.period === "AM" && time.hour === 12) {
|
|
1621
|
-
hour24 = 0;
|
|
1622
|
-
}
|
|
1623
|
-
return `${String(hour24).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}`;
|
|
1624
|
-
} else {
|
|
1625
|
-
return `${time.hour}:${String(time.minute).padStart(2, "0")} ${time.period}`;
|
|
1727
|
+
return `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
|
|
1626
1728
|
}
|
|
1729
|
+
const period = hour >= 12 ? "PM" : "AM";
|
|
1730
|
+
const hour12 = hour % 12 || 12;
|
|
1731
|
+
return `${hour12}:${String(minute).padStart(2, "0")} ${period}`;
|
|
1627
1732
|
}
|
|
1628
1733
|
function TimePicker({
|
|
1629
1734
|
name,
|
|
@@ -1641,88 +1746,33 @@ function TimePicker({
|
|
|
1641
1746
|
showIcon = true,
|
|
1642
1747
|
...props
|
|
1643
1748
|
}) {
|
|
1644
|
-
const
|
|
1645
|
-
const [
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
minute: timeValue?.minute || 0,
|
|
1656
|
-
period: timeValue?.period || "AM"
|
|
1657
|
-
};
|
|
1658
|
-
setTimeValue(newTime);
|
|
1659
|
-
onChange(formatTimeValue(newTime, use24Hour));
|
|
1660
|
-
};
|
|
1661
|
-
const handleMinuteChange = (minute) => {
|
|
1662
|
-
const newTime = {
|
|
1663
|
-
hour: timeValue?.hour || 12,
|
|
1664
|
-
minute,
|
|
1665
|
-
period: timeValue?.period || "AM"
|
|
1666
|
-
};
|
|
1667
|
-
setTimeValue(newTime);
|
|
1668
|
-
onChange(formatTimeValue(newTime, use24Hour));
|
|
1669
|
-
};
|
|
1670
|
-
const handlePeriodChange = (period) => {
|
|
1671
|
-
const newTime = {
|
|
1672
|
-
hour: timeValue?.hour || 12,
|
|
1673
|
-
minute: timeValue?.minute || 0,
|
|
1674
|
-
period
|
|
1675
|
-
};
|
|
1676
|
-
setTimeValue(newTime);
|
|
1677
|
-
onChange(formatTimeValue(newTime, use24Hour));
|
|
1749
|
+
const inputRef = React8__namespace.useRef(null);
|
|
1750
|
+
const [nativeValue, setNativeValue] = React8__namespace.useState(
|
|
1751
|
+
normalizeToNativeTime(value)
|
|
1752
|
+
);
|
|
1753
|
+
React8__namespace.useEffect(() => {
|
|
1754
|
+
setNativeValue(normalizeToNativeTime(value));
|
|
1755
|
+
}, [value]);
|
|
1756
|
+
const handleChange = (e) => {
|
|
1757
|
+
const nextNativeValue = e.target.value;
|
|
1758
|
+
setNativeValue(nextNativeValue);
|
|
1759
|
+
onChange(formatFromNativeTime(nextNativeValue, use24Hour));
|
|
1678
1760
|
};
|
|
1679
1761
|
const handleClear = (e) => {
|
|
1680
1762
|
e.stopPropagation();
|
|
1763
|
+
setNativeValue("");
|
|
1681
1764
|
onChange("");
|
|
1682
|
-
setTimeValue(null);
|
|
1683
1765
|
inputRef.current?.focus();
|
|
1684
1766
|
};
|
|
1685
|
-
const
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
};
|
|
1689
|
-
React7__namespace.useEffect(() => {
|
|
1690
|
-
const handleClickOutside = (event) => {
|
|
1691
|
-
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
1692
|
-
setIsOpen(false);
|
|
1693
|
-
onBlur?.();
|
|
1694
|
-
}
|
|
1695
|
-
};
|
|
1696
|
-
if (isOpen) {
|
|
1697
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
1698
|
-
return () => {
|
|
1699
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
|
1700
|
-
};
|
|
1701
|
-
}
|
|
1702
|
-
}, [isOpen, onBlur]);
|
|
1703
|
-
const hours = React7__namespace.useMemo(() => {
|
|
1704
|
-
if (use24Hour) {
|
|
1705
|
-
return Array.from({ length: 24 }, (_, i) => i);
|
|
1706
|
-
} else {
|
|
1707
|
-
return Array.from({ length: 12 }, (_, i) => i + 1);
|
|
1708
|
-
}
|
|
1709
|
-
}, [use24Hour]);
|
|
1710
|
-
const minutes = React7__namespace.useMemo(() => {
|
|
1711
|
-
const mins = [];
|
|
1712
|
-
for (let i = 0; i < 60; i += minuteStep) {
|
|
1713
|
-
mins.push(i);
|
|
1714
|
-
}
|
|
1715
|
-
return mins;
|
|
1716
|
-
}, [minuteStep]);
|
|
1717
|
-
const combinedClassName = cn("relative", className);
|
|
1718
|
-
const displayValue = formatTimeValue(timeValue, use24Hour);
|
|
1719
|
-
return /* @__PURE__ */ React7__namespace.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React7__namespace.createElement("input", { type: "hidden", name, value }), /* @__PURE__ */ React7__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React7__namespace.createElement(
|
|
1767
|
+
const hasValue = Boolean(value);
|
|
1768
|
+
const stepInSeconds = Math.max(1, minuteStep * 60);
|
|
1769
|
+
return /* @__PURE__ */ React8__namespace.createElement("div", { className: cn("relative", className) }, /* @__PURE__ */ React8__namespace.createElement("input", { type: "hidden", name, value }), /* @__PURE__ */ React8__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React8__namespace.createElement(
|
|
1720
1770
|
"span",
|
|
1721
1771
|
{
|
|
1722
1772
|
className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
|
|
1723
1773
|
"aria-hidden": "true"
|
|
1724
1774
|
},
|
|
1725
|
-
/* @__PURE__ */
|
|
1775
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
1726
1776
|
"svg",
|
|
1727
1777
|
{
|
|
1728
1778
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -1735,34 +1785,38 @@ function TimePicker({
|
|
|
1735
1785
|
strokeLinejoin: "round",
|
|
1736
1786
|
strokeWidth: "2"
|
|
1737
1787
|
},
|
|
1738
|
-
/* @__PURE__ */
|
|
1739
|
-
/* @__PURE__ */
|
|
1788
|
+
/* @__PURE__ */ React8__namespace.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1789
|
+
/* @__PURE__ */ React8__namespace.createElement("path", { d: "M12 6v6l4 2" })
|
|
1740
1790
|
)
|
|
1741
|
-
), /* @__PURE__ */
|
|
1791
|
+
), /* @__PURE__ */ React8__namespace.createElement(
|
|
1742
1792
|
"input",
|
|
1743
1793
|
{
|
|
1744
1794
|
ref: inputRef,
|
|
1745
|
-
type: "
|
|
1795
|
+
type: "time",
|
|
1746
1796
|
className: cn(
|
|
1747
1797
|
"flex h-9 w-full rounded-md border border-input bg-transparent py-1 text-base shadow-sm transition-colors",
|
|
1748
1798
|
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
1749
1799
|
"disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
1800
|
+
"appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none",
|
|
1801
|
+
INPUT_AUTOFILL_RESET_CLASSES,
|
|
1750
1802
|
showIcon ? "pl-10" : "pl-3",
|
|
1751
1803
|
clearable && value ? "pr-10" : "pr-3",
|
|
1752
|
-
error && "
|
|
1804
|
+
!error && hasValue && "ring-2 ring-ring",
|
|
1805
|
+
error && "border-destructive ring-1 ring-destructive"
|
|
1753
1806
|
),
|
|
1754
|
-
value:
|
|
1755
|
-
|
|
1807
|
+
value: nativeValue,
|
|
1808
|
+
onChange: handleChange,
|
|
1756
1809
|
onBlur,
|
|
1757
1810
|
disabled,
|
|
1758
1811
|
required,
|
|
1812
|
+
step: stepInSeconds,
|
|
1759
1813
|
placeholder,
|
|
1760
1814
|
"aria-invalid": error || props["aria-invalid"] ? "true" : "false",
|
|
1761
1815
|
"aria-describedby": props["aria-describedby"],
|
|
1762
1816
|
"aria-required": required || props["aria-required"],
|
|
1763
|
-
|
|
1817
|
+
...props
|
|
1764
1818
|
}
|
|
1765
|
-
), clearable && value && !disabled && /* @__PURE__ */
|
|
1819
|
+
), clearable && value && !disabled && /* @__PURE__ */ React8__namespace.createElement(
|
|
1766
1820
|
"button",
|
|
1767
1821
|
{
|
|
1768
1822
|
type: "button",
|
|
@@ -1772,84 +1826,7 @@ function TimePicker({
|
|
|
1772
1826
|
tabIndex: -1
|
|
1773
1827
|
},
|
|
1774
1828
|
"\u2715"
|
|
1775
|
-
))
|
|
1776
|
-
const displayHour = use24Hour ? hour : hour;
|
|
1777
|
-
const isSelected = use24Hour ? timeValue?.hour === (hour === 0 ? 12 : hour > 12 ? hour - 12 : hour) && timeValue?.period === (hour >= 12 ? "PM" : "AM") : timeValue?.hour === hour;
|
|
1778
|
-
return /* @__PURE__ */ React7__namespace.createElement(
|
|
1779
|
-
"button",
|
|
1780
|
-
{
|
|
1781
|
-
key: hour,
|
|
1782
|
-
type: "button",
|
|
1783
|
-
className: cn(
|
|
1784
|
-
"flex items-center justify-center h-8 w-full rounded",
|
|
1785
|
-
"border-none bg-transparent cursor-pointer text-sm transition-colors",
|
|
1786
|
-
"hover:bg-primary hover:text-primary-foreground",
|
|
1787
|
-
isSelected ? "bg-primary text-primary-foreground font-semibold" : ""
|
|
1788
|
-
),
|
|
1789
|
-
onClick: () => {
|
|
1790
|
-
if (use24Hour) {
|
|
1791
|
-
const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
|
|
1792
|
-
const period = hour >= 12 ? "PM" : "AM";
|
|
1793
|
-
const newTime = {
|
|
1794
|
-
hour: hour12,
|
|
1795
|
-
minute: timeValue?.minute || 0,
|
|
1796
|
-
period
|
|
1797
|
-
};
|
|
1798
|
-
setTimeValue(newTime);
|
|
1799
|
-
onChange(formatTimeValue(newTime, use24Hour));
|
|
1800
|
-
} else {
|
|
1801
|
-
handleHourChange(hour);
|
|
1802
|
-
}
|
|
1803
|
-
},
|
|
1804
|
-
"aria-label": `${String(displayHour).padStart(2, "0")} hours`
|
|
1805
|
-
},
|
|
1806
|
-
String(displayHour).padStart(2, "0")
|
|
1807
|
-
);
|
|
1808
|
-
}))), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium mb-2 text-center" }, "Minute"), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-1 max-h-48 overflow-y-auto" }, minutes.map((minute) => {
|
|
1809
|
-
const isSelected = timeValue?.minute === minute;
|
|
1810
|
-
return /* @__PURE__ */ React7__namespace.createElement(
|
|
1811
|
-
"button",
|
|
1812
|
-
{
|
|
1813
|
-
key: minute,
|
|
1814
|
-
type: "button",
|
|
1815
|
-
className: cn(
|
|
1816
|
-
"flex items-center justify-center h-8 w-full",
|
|
1817
|
-
"rounded border-none bg-transparent cursor-pointer text-sm transition-colors",
|
|
1818
|
-
"hover:bg-primary hover:text-primary-foreground",
|
|
1819
|
-
isSelected ? "bg-primary text-primary-foreground font-semibold" : ""
|
|
1820
|
-
),
|
|
1821
|
-
onClick: () => handleMinuteChange(minute),
|
|
1822
|
-
"aria-label": `${String(minute).padStart(2, "0")} minutes`
|
|
1823
|
-
},
|
|
1824
|
-
String(minute).padStart(2, "0")
|
|
1825
|
-
);
|
|
1826
|
-
}))), !use24Hour && /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col w-20" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "text-xs font-medium mb-2 text-center" }, "Period"), /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
1827
|
-
"button",
|
|
1828
|
-
{
|
|
1829
|
-
type: "button",
|
|
1830
|
-
className: cn(
|
|
1831
|
-
"flex items-center justify-center h-8 w-full",
|
|
1832
|
-
"rounded border-none bg-transparent cursor-pointer text-sm",
|
|
1833
|
-
"transition-colors hover:bg-primary hover:text-primary-foreground",
|
|
1834
|
-
timeValue?.period === "AM" ? "bg-muted font-semibold" : ""
|
|
1835
|
-
),
|
|
1836
|
-
onClick: () => handlePeriodChange("AM")
|
|
1837
|
-
},
|
|
1838
|
-
"AM"
|
|
1839
|
-
), /* @__PURE__ */ React7__namespace.createElement(
|
|
1840
|
-
"button",
|
|
1841
|
-
{
|
|
1842
|
-
type: "button",
|
|
1843
|
-
className: cn(
|
|
1844
|
-
"flex items-center justify-center h-8 w-full",
|
|
1845
|
-
"rounded border-none bg-transparent cursor-pointer text-sm",
|
|
1846
|
-
"transition-colors hover:bg-primary hover:text-primary-foreground",
|
|
1847
|
-
timeValue?.period === "PM" ? "bg-muted font-semibold" : ""
|
|
1848
|
-
),
|
|
1849
|
-
onClick: () => handlePeriodChange("PM")
|
|
1850
|
-
},
|
|
1851
|
-
"PM"
|
|
1852
|
-
))))));
|
|
1829
|
+
)));
|
|
1853
1830
|
}
|
|
1854
1831
|
TimePicker.displayName = "TimePicker";
|
|
1855
1832
|
function formatDate2(date, format) {
|
|
@@ -1869,6 +1846,9 @@ function isDateInRange(date, start, end) {
|
|
|
1869
1846
|
const time = date.getTime();
|
|
1870
1847
|
return time >= start.getTime() && time <= end.getTime();
|
|
1871
1848
|
}
|
|
1849
|
+
function addMonths(date, delta) {
|
|
1850
|
+
return new Date(date.getFullYear(), date.getMonth() + delta, 1);
|
|
1851
|
+
}
|
|
1872
1852
|
function DateRangePicker({
|
|
1873
1853
|
name,
|
|
1874
1854
|
value = { start: null, end: null },
|
|
@@ -1889,15 +1869,15 @@ function DateRangePicker({
|
|
|
1889
1869
|
separator = " - ",
|
|
1890
1870
|
...props
|
|
1891
1871
|
}) {
|
|
1892
|
-
const [isOpen, setIsOpen] =
|
|
1893
|
-
const [selectedMonth, setSelectedMonth] =
|
|
1872
|
+
const [isOpen, setIsOpen] = React8__namespace.useState(false);
|
|
1873
|
+
const [selectedMonth, setSelectedMonth] = React8__namespace.useState(
|
|
1894
1874
|
value.start || /* @__PURE__ */ new Date()
|
|
1895
1875
|
);
|
|
1896
|
-
const [rangeStart, setRangeStart] =
|
|
1897
|
-
const [rangeEnd, setRangeEnd] =
|
|
1898
|
-
const [hoverDate, setHoverDate] =
|
|
1899
|
-
const containerRef =
|
|
1900
|
-
|
|
1876
|
+
const [rangeStart, setRangeStart] = React8__namespace.useState(value.start);
|
|
1877
|
+
const [rangeEnd, setRangeEnd] = React8__namespace.useState(value.end);
|
|
1878
|
+
const [hoverDate, setHoverDate] = React8__namespace.useState(null);
|
|
1879
|
+
const containerRef = React8__namespace.useRef(null);
|
|
1880
|
+
React8__namespace.useEffect(() => {
|
|
1901
1881
|
setRangeStart(value.start);
|
|
1902
1882
|
setRangeEnd(value.end);
|
|
1903
1883
|
if (value.start) {
|
|
@@ -1931,7 +1911,7 @@ function DateRangePicker({
|
|
|
1931
1911
|
};
|
|
1932
1912
|
const handleToggle = () => {
|
|
1933
1913
|
if (disabled) return;
|
|
1934
|
-
setIsOpen(!
|
|
1914
|
+
setIsOpen((prev) => !prev);
|
|
1935
1915
|
};
|
|
1936
1916
|
const isDisabled = (date) => {
|
|
1937
1917
|
if (minDate && date < minDate) return true;
|
|
@@ -1940,23 +1920,36 @@ function DateRangePicker({
|
|
|
1940
1920
|
if (isDateDisabled && isDateDisabled(date)) return true;
|
|
1941
1921
|
return false;
|
|
1942
1922
|
};
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
onBlur?.();
|
|
1948
|
-
}
|
|
1949
|
-
};
|
|
1950
|
-
if (isOpen) {
|
|
1951
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
1952
|
-
return () => {
|
|
1953
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
|
1954
|
-
};
|
|
1955
|
-
}
|
|
1923
|
+
const closeCalendar = React8__namespace.useCallback(() => {
|
|
1924
|
+
if (!isOpen) return;
|
|
1925
|
+
setIsOpen(false);
|
|
1926
|
+
onBlur?.();
|
|
1956
1927
|
}, [isOpen, onBlur]);
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1928
|
+
useOnClickOutside.useOnClickOutside(containerRef, closeCalendar, "pointerdown", true);
|
|
1929
|
+
const dayGridStyle = {
|
|
1930
|
+
gridTemplateColumns: "repeat(7, minmax(0, 1fr))"
|
|
1931
|
+
};
|
|
1932
|
+
const monthsGridStyle = {
|
|
1933
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(240px, 1fr))"
|
|
1934
|
+
};
|
|
1935
|
+
const monthNames = [
|
|
1936
|
+
"January",
|
|
1937
|
+
"February",
|
|
1938
|
+
"March",
|
|
1939
|
+
"April",
|
|
1940
|
+
"May",
|
|
1941
|
+
"June",
|
|
1942
|
+
"July",
|
|
1943
|
+
"August",
|
|
1944
|
+
"September",
|
|
1945
|
+
"October",
|
|
1946
|
+
"November",
|
|
1947
|
+
"December"
|
|
1948
|
+
];
|
|
1949
|
+
const hasValue = Boolean(rangeStart || rangeEnd);
|
|
1950
|
+
const renderMonth = (monthDate, controls) => {
|
|
1951
|
+
const year = monthDate.getFullYear();
|
|
1952
|
+
const month = monthDate.getMonth();
|
|
1960
1953
|
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
1961
1954
|
const firstDayOfMonth = new Date(year, month, 1).getDay();
|
|
1962
1955
|
const days = [];
|
|
@@ -1966,54 +1959,41 @@ function DateRangePicker({
|
|
|
1966
1959
|
for (let day = 1; day <= daysInMonth; day++) {
|
|
1967
1960
|
days.push(new Date(year, month, day));
|
|
1968
1961
|
}
|
|
1969
|
-
|
|
1970
|
-
"January",
|
|
1971
|
-
"February",
|
|
1972
|
-
"March",
|
|
1973
|
-
"April",
|
|
1974
|
-
"May",
|
|
1975
|
-
"June",
|
|
1976
|
-
"July",
|
|
1977
|
-
"August",
|
|
1978
|
-
"September",
|
|
1979
|
-
"October",
|
|
1980
|
-
"November",
|
|
1981
|
-
"December"
|
|
1982
|
-
];
|
|
1983
|
-
const handlePrevMonth = () => {
|
|
1984
|
-
setSelectedMonth(new Date(year, month - 1, 1));
|
|
1985
|
-
};
|
|
1986
|
-
const handleNextMonth = () => {
|
|
1987
|
-
setSelectedMonth(new Date(year, month + 1, 1));
|
|
1988
|
-
};
|
|
1989
|
-
return /* @__PURE__ */ React7__namespace.createElement("div", { role: "grid", "aria-label": "Calendar" }, /* @__PURE__ */ React7__namespace.createElement("div", { className: "flex items-center justify-between pb-2 border-b border-border" }, /* @__PURE__ */ React7__namespace.createElement(
|
|
1962
|
+
return /* @__PURE__ */ React8__namespace.createElement("div", { className: "w-[240px] max-w-full" }, /* @__PURE__ */ React8__namespace.createElement("div", { className: "flex items-center justify-between pb-3" }, controls?.prev ? /* @__PURE__ */ React8__namespace.createElement(
|
|
1990
1963
|
"button",
|
|
1991
1964
|
{
|
|
1992
1965
|
type: "button",
|
|
1993
|
-
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-
|
|
1994
|
-
onClick:
|
|
1966
|
+
className: "flex items-center justify-center h-8 w-8 rounded-md border-none bg-transparent hover:bg-muted cursor-pointer transition-colors",
|
|
1967
|
+
onClick: () => setSelectedMonth((prev) => addMonths(prev, -1)),
|
|
1995
1968
|
"aria-label": "Previous month"
|
|
1996
1969
|
},
|
|
1997
|
-
"\
|
|
1998
|
-
), /* @__PURE__ */
|
|
1970
|
+
"\u2039"
|
|
1971
|
+
) : /* @__PURE__ */ React8__namespace.createElement("div", { className: "h-8 w-8", "aria-hidden": "true" }), /* @__PURE__ */ React8__namespace.createElement("div", { className: "font-medium text-sm" }, `${monthNames[month]} ${year}`), controls?.next ? /* @__PURE__ */ React8__namespace.createElement(
|
|
1999
1972
|
"button",
|
|
2000
1973
|
{
|
|
2001
1974
|
type: "button",
|
|
2002
|
-
className: "flex items-center justify-center h-8 w-8 rounded border-none bg-transparent hover:bg-
|
|
2003
|
-
onClick:
|
|
1975
|
+
className: "flex items-center justify-center h-8 w-8 rounded-md border-none bg-transparent hover:bg-muted cursor-pointer transition-colors",
|
|
1976
|
+
onClick: () => setSelectedMonth((prev) => addMonths(prev, 1)),
|
|
2004
1977
|
"aria-label": "Next month"
|
|
2005
1978
|
},
|
|
2006
|
-
"\
|
|
2007
|
-
)
|
|
1979
|
+
"\u203A"
|
|
1980
|
+
) : /* @__PURE__ */ React8__namespace.createElement("div", { className: "h-8 w-8", "aria-hidden": "true" })), /* @__PURE__ */ React8__namespace.createElement(
|
|
2008
1981
|
"div",
|
|
2009
1982
|
{
|
|
2010
|
-
|
|
2011
|
-
|
|
1983
|
+
className: "grid gap-1 text-xs text-muted-foreground",
|
|
1984
|
+
style: dayGridStyle
|
|
2012
1985
|
},
|
|
2013
|
-
day
|
|
2014
|
-
|
|
1986
|
+
["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => /* @__PURE__ */ React8__namespace.createElement(
|
|
1987
|
+
"div",
|
|
1988
|
+
{
|
|
1989
|
+
key: `${month}-${day}`,
|
|
1990
|
+
className: "flex items-center justify-center h-8 w-8 font-medium"
|
|
1991
|
+
},
|
|
1992
|
+
day
|
|
1993
|
+
))
|
|
1994
|
+
), /* @__PURE__ */ React8__namespace.createElement("div", { className: "grid gap-1", style: dayGridStyle }, days.map((date, index) => {
|
|
2015
1995
|
if (!date) {
|
|
2016
|
-
return /* @__PURE__ */
|
|
1996
|
+
return /* @__PURE__ */ React8__namespace.createElement("div", { key: `empty-${month}-${index}`, className: "h-8 w-8" });
|
|
2017
1997
|
}
|
|
2018
1998
|
const isStart = rangeStart && date.toDateString() === rangeStart.toDateString();
|
|
2019
1999
|
const isEnd = rangeEnd && date.toDateString() === rangeEnd.toDateString();
|
|
@@ -2025,17 +2005,17 @@ function DateRangePicker({
|
|
|
2025
2005
|
);
|
|
2026
2006
|
const isToday = date.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
|
|
2027
2007
|
const disabled2 = isDisabled(date);
|
|
2028
|
-
return /* @__PURE__ */
|
|
2008
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
2029
2009
|
"button",
|
|
2030
2010
|
{
|
|
2031
2011
|
key: date.toISOString(),
|
|
2032
2012
|
type: "button",
|
|
2033
2013
|
className: cn(
|
|
2034
|
-
"flex items-center justify-center h-8 w-
|
|
2035
|
-
"
|
|
2036
|
-
isRangeEndpoint && "bg-
|
|
2037
|
-
isRangeHighlight && "bg-muted
|
|
2038
|
-
isToday && "border border-primary",
|
|
2014
|
+
"flex items-center justify-center h-8 w-8 rounded-md border-none bg-transparent cursor-pointer text-sm transition-colors",
|
|
2015
|
+
"hover:bg-muted",
|
|
2016
|
+
isRangeEndpoint && "bg-primary text-primary-foreground font-semibold",
|
|
2017
|
+
isRangeHighlight && "bg-muted",
|
|
2018
|
+
!isRangeEndpoint && !isRangeHighlight && isToday && "border border-primary",
|
|
2039
2019
|
disabled2 && "cursor-not-allowed opacity-50 pointer-events-none"
|
|
2040
2020
|
),
|
|
2041
2021
|
onClick: () => !disabled2 && handleDateSelect(date),
|
|
@@ -2050,27 +2030,27 @@ function DateRangePicker({
|
|
|
2050
2030
|
};
|
|
2051
2031
|
const combinedClassName = cn("relative", className);
|
|
2052
2032
|
const displayValue = rangeStart && rangeEnd ? `${formatDate2(rangeStart, format)}${separator}${formatDate2(rangeEnd, format)}` : rangeStart ? formatDate2(rangeStart, format) : "";
|
|
2053
|
-
return /* @__PURE__ */
|
|
2033
|
+
return /* @__PURE__ */ React8__namespace.createElement("div", { ref: containerRef, className: combinedClassName }, /* @__PURE__ */ React8__namespace.createElement(
|
|
2054
2034
|
"input",
|
|
2055
2035
|
{
|
|
2056
2036
|
type: "hidden",
|
|
2057
2037
|
name: `${name}[start]`,
|
|
2058
2038
|
value: rangeStart ? rangeStart.toISOString() : ""
|
|
2059
2039
|
}
|
|
2060
|
-
), /* @__PURE__ */
|
|
2040
|
+
), /* @__PURE__ */ React8__namespace.createElement(
|
|
2061
2041
|
"input",
|
|
2062
2042
|
{
|
|
2063
2043
|
type: "hidden",
|
|
2064
2044
|
name: `${name}[end]`,
|
|
2065
2045
|
value: rangeEnd ? rangeEnd.toISOString() : ""
|
|
2066
2046
|
}
|
|
2067
|
-
), /* @__PURE__ */
|
|
2047
|
+
), /* @__PURE__ */ React8__namespace.createElement("div", { className: "relative" }, showIcon && /* @__PURE__ */ React8__namespace.createElement(
|
|
2068
2048
|
"span",
|
|
2069
2049
|
{
|
|
2070
2050
|
className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none",
|
|
2071
2051
|
"aria-hidden": "true"
|
|
2072
2052
|
},
|
|
2073
|
-
/* @__PURE__ */
|
|
2053
|
+
/* @__PURE__ */ React8__namespace.createElement(
|
|
2074
2054
|
"svg",
|
|
2075
2055
|
{
|
|
2076
2056
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -2083,9 +2063,9 @@ function DateRangePicker({
|
|
|
2083
2063
|
strokeLinejoin: "round",
|
|
2084
2064
|
strokeWidth: "2"
|
|
2085
2065
|
},
|
|
2086
|
-
/* @__PURE__ */
|
|
2066
|
+
/* @__PURE__ */ React8__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" })
|
|
2087
2067
|
)
|
|
2088
|
-
), /* @__PURE__ */
|
|
2068
|
+
), /* @__PURE__ */ React8__namespace.createElement(
|
|
2089
2069
|
"input",
|
|
2090
2070
|
{
|
|
2091
2071
|
type: "text",
|
|
@@ -2093,9 +2073,11 @@ function DateRangePicker({
|
|
|
2093
2073
|
"flex h-9 w-full rounded-md border border-input bg-transparent py-1 text-base shadow-sm transition-colors",
|
|
2094
2074
|
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
2095
2075
|
"disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
2076
|
+
INPUT_AUTOFILL_RESET_CLASSES,
|
|
2096
2077
|
showIcon ? "pl-10" : "pl-3",
|
|
2097
2078
|
clearable && (rangeStart || rangeEnd) ? "pr-10" : "pr-3",
|
|
2098
|
-
error && "
|
|
2079
|
+
!error && hasValue && "ring-2 ring-ring",
|
|
2080
|
+
error && "border-destructive ring-1 ring-destructive"
|
|
2099
2081
|
),
|
|
2100
2082
|
value: displayValue,
|
|
2101
2083
|
onClick: handleToggle,
|
|
@@ -2108,7 +2090,7 @@ function DateRangePicker({
|
|
|
2108
2090
|
"aria-required": required || props["aria-required"],
|
|
2109
2091
|
readOnly: true
|
|
2110
2092
|
}
|
|
2111
|
-
), clearable && (rangeStart || rangeEnd) && !disabled && /* @__PURE__ */
|
|
2093
|
+
), clearable && (rangeStart || rangeEnd) && !disabled && /* @__PURE__ */ React8__namespace.createElement(
|
|
2112
2094
|
"button",
|
|
2113
2095
|
{
|
|
2114
2096
|
type: "button",
|
|
@@ -2118,7 +2100,7 @@ function DateRangePicker({
|
|
|
2118
2100
|
tabIndex: -1
|
|
2119
2101
|
},
|
|
2120
2102
|
"\u2715"
|
|
2121
|
-
)), isOpen && !disabled && /* @__PURE__ */
|
|
2103
|
+
)), isOpen && !disabled && /* @__PURE__ */ React8__namespace.createElement("div", { className: "absolute z-50 top-full mt-1 w-fit rounded-md border border-border bg-popover text-popover-foreground shadow-md p-3" }, /* @__PURE__ */ React8__namespace.createElement("div", { role: "grid", "aria-label": "Calendar" }, /* @__PURE__ */ React8__namespace.createElement("div", { className: "grid gap-4", style: monthsGridStyle }, renderMonth(selectedMonth, { prev: true }), renderMonth(addMonths(selectedMonth, 1), { next: true }))), rangeStart && !rangeEnd && /* @__PURE__ */ React8__namespace.createElement("div", { className: "text-xs text-center pt-2 border-t border-border mt-2" }, "Select end date")));
|
|
2122
2104
|
}
|
|
2123
2105
|
DateRangePicker.displayName = "DateRangePicker";
|
|
2124
2106
|
function htmlToMarkdown(html) {
|
|
@@ -2189,11 +2171,11 @@ function RichTextEditor({
|
|
|
2189
2171
|
],
|
|
2190
2172
|
...props
|
|
2191
2173
|
}) {
|
|
2192
|
-
const [currentMode, setCurrentMode] =
|
|
2193
|
-
const [content, setContent] =
|
|
2194
|
-
const editorRef =
|
|
2195
|
-
const textareaRef =
|
|
2196
|
-
|
|
2174
|
+
const [currentMode, setCurrentMode] = React8__namespace.useState(mode);
|
|
2175
|
+
const [content, setContent] = React8__namespace.useState(value);
|
|
2176
|
+
const editorRef = React8__namespace.useRef(null);
|
|
2177
|
+
const textareaRef = React8__namespace.useRef(null);
|
|
2178
|
+
React8__namespace.useEffect(() => {
|
|
2197
2179
|
setContent(value);
|
|
2198
2180
|
if (currentMode === "wysiwyg" && editorRef.current) {
|
|
2199
2181
|
editorRef.current.innerHTML = value;
|
|
@@ -2281,16 +2263,27 @@ function RichTextEditor({
|
|
|
2281
2263
|
}
|
|
2282
2264
|
}
|
|
2283
2265
|
};
|
|
2284
|
-
const
|
|
2266
|
+
const hasValue = React8__namespace.useMemo(() => {
|
|
2267
|
+
if (!content) return false;
|
|
2268
|
+
const stripped = content.replace(/<[^>]+>/g, "").trim();
|
|
2269
|
+
return stripped.length > 0;
|
|
2270
|
+
}, [content]);
|
|
2271
|
+
const combinedClassName = cn(
|
|
2272
|
+
"rounded-md border border-input",
|
|
2273
|
+
!error && hasValue && "ring-2 ring-ring",
|
|
2274
|
+
error && "border-destructive ring-1 ring-destructive",
|
|
2275
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
2276
|
+
className
|
|
2277
|
+
);
|
|
2285
2278
|
const editorStyle = {
|
|
2286
2279
|
minHeight,
|
|
2287
2280
|
maxHeight,
|
|
2288
2281
|
overflowY: maxHeight ? "auto" : void 0
|
|
2289
2282
|
};
|
|
2290
|
-
return /* @__PURE__ */
|
|
2283
|
+
return /* @__PURE__ */ React8__namespace.createElement("div", { className: combinedClassName }, /* @__PURE__ */ React8__namespace.createElement("input", { type: "hidden", name, value: content }), showToolbar && /* @__PURE__ */ React8__namespace.createElement("div", { className: "flex items-center justify-between p-2 border-b border-border bg-muted/50" }, /* @__PURE__ */ React8__namespace.createElement("div", { className: "flex items-center gap-1" }, toolbarButtons.map((buttonName) => {
|
|
2291
2284
|
const button = toolbarConfig[buttonName];
|
|
2292
2285
|
if (!button) return null;
|
|
2293
|
-
return /* @__PURE__ */
|
|
2286
|
+
return /* @__PURE__ */ React8__namespace.createElement(
|
|
2294
2287
|
"button",
|
|
2295
2288
|
{
|
|
2296
2289
|
key: buttonName,
|
|
@@ -2303,7 +2296,7 @@ function RichTextEditor({
|
|
|
2303
2296
|
},
|
|
2304
2297
|
button.icon
|
|
2305
2298
|
);
|
|
2306
|
-
})), allowModeSwitch && /* @__PURE__ */
|
|
2299
|
+
})), allowModeSwitch && /* @__PURE__ */ React8__namespace.createElement(
|
|
2307
2300
|
"button",
|
|
2308
2301
|
{
|
|
2309
2302
|
type: "button",
|
|
@@ -2314,7 +2307,7 @@ function RichTextEditor({
|
|
|
2314
2307
|
"aria-label": `Switch to ${currentMode === "wysiwyg" ? "Markdown" : "WYSIWYG"}`
|
|
2315
2308
|
},
|
|
2316
2309
|
currentMode === "wysiwyg" ? "MD" : "WYSIWYG"
|
|
2317
|
-
)), /* @__PURE__ */
|
|
2310
|
+
)), /* @__PURE__ */ React8__namespace.createElement("div", { style: editorStyle }, currentMode === "wysiwyg" ? /* @__PURE__ */ React8__namespace.createElement(
|
|
2318
2311
|
"div",
|
|
2319
2312
|
{
|
|
2320
2313
|
ref: editorRef,
|
|
@@ -2329,11 +2322,14 @@ function RichTextEditor({
|
|
|
2329
2322
|
"aria-required": required || props["aria-required"],
|
|
2330
2323
|
suppressContentEditableWarning: true
|
|
2331
2324
|
}
|
|
2332
|
-
) : /* @__PURE__ */
|
|
2325
|
+
) : /* @__PURE__ */ React8__namespace.createElement(
|
|
2333
2326
|
"textarea",
|
|
2334
2327
|
{
|
|
2335
2328
|
ref: textareaRef,
|
|
2336
|
-
className:
|
|
2329
|
+
className: cn(
|
|
2330
|
+
"w-full p-3 text-base md:text-sm outline-none bg-transparent resize-none focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
2331
|
+
INPUT_AUTOFILL_RESET_CLASSES
|
|
2332
|
+
),
|
|
2337
2333
|
value: content,
|
|
2338
2334
|
onChange: handleMarkdownChange,
|
|
2339
2335
|
onBlur,
|