@underverse-ui/underverse 1.0.80 → 1.0.82
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/api-reference.json +1 -1
- package/dist/index.cjs +402 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +402 -83
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -7128,11 +7128,12 @@ var Combobox = ({
|
|
|
7128
7128
|
helperText,
|
|
7129
7129
|
useOverlayScrollbar = false
|
|
7130
7130
|
}) => {
|
|
7131
|
+
const tv = useSmartTranslations("ValidationInput");
|
|
7131
7132
|
const [open, setOpen] = React24.useState(false);
|
|
7132
7133
|
const [query, setQuery] = React24.useState("");
|
|
7133
7134
|
const [activeIndex, setActiveIndex] = React24.useState(null);
|
|
7135
|
+
const [localRequiredError, setLocalRequiredError] = React24.useState();
|
|
7134
7136
|
useShadCNAnimations();
|
|
7135
|
-
const listRef = React24.useRef([]);
|
|
7136
7137
|
const inputRef = React24.useRef(null);
|
|
7137
7138
|
const optionsViewportRef = React24.useRef(null);
|
|
7138
7139
|
useOverlayScrollbarTarget(optionsViewportRef, { enabled: useOverlayScrollbar });
|
|
@@ -7149,6 +7150,7 @@ var Combobox = ({
|
|
|
7149
7150
|
if (getOptionDisabled(option)) return;
|
|
7150
7151
|
const val = getOptionValue(option);
|
|
7151
7152
|
if (val !== void 0 && val !== null) {
|
|
7153
|
+
setLocalRequiredError(void 0);
|
|
7152
7154
|
onChange(val);
|
|
7153
7155
|
setOpen(false);
|
|
7154
7156
|
triggerRef.current?.focus();
|
|
@@ -7172,6 +7174,13 @@ var Combobox = ({
|
|
|
7172
7174
|
const selectedOption = findOptionByValue(options, value);
|
|
7173
7175
|
const displayValue = selectedOption ? getOptionLabel(selectedOption) : "";
|
|
7174
7176
|
const selectedIcon = selectedOption ? getOptionIcon(selectedOption) : void 0;
|
|
7177
|
+
const hasValue = value !== void 0 && value !== null && value !== "";
|
|
7178
|
+
const effectiveError = error ?? localRequiredError;
|
|
7179
|
+
React24.useEffect(() => {
|
|
7180
|
+
if (disabled || !required || hasValue) {
|
|
7181
|
+
setLocalRequiredError(void 0);
|
|
7182
|
+
}
|
|
7183
|
+
}, [disabled, hasValue, required]);
|
|
7175
7184
|
const groupedOptions = React24.useMemo(() => {
|
|
7176
7185
|
if (!groupBy) return null;
|
|
7177
7186
|
const groups = {};
|
|
@@ -7204,27 +7213,24 @@ var Combobox = ({
|
|
|
7204
7213
|
const itemDescription = getOptionDescription(item);
|
|
7205
7214
|
const itemDisabled = getOptionDisabled(item);
|
|
7206
7215
|
const isSelected = itemValue === value;
|
|
7207
|
-
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
7208
|
-
"
|
|
7216
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("li", { className: "list-none", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
7217
|
+
"button",
|
|
7209
7218
|
{
|
|
7210
|
-
ref: (node) => {
|
|
7211
|
-
listRef.current[index] = node;
|
|
7212
|
-
},
|
|
7213
7219
|
id: `combobox-item-${index}`,
|
|
7214
|
-
|
|
7220
|
+
type: "button",
|
|
7215
7221
|
tabIndex: -1,
|
|
7216
|
-
|
|
7217
|
-
"aria-
|
|
7218
|
-
onClick: () =>
|
|
7222
|
+
disabled: itemDisabled,
|
|
7223
|
+
"aria-pressed": isSelected,
|
|
7224
|
+
onClick: () => handleSelect(item),
|
|
7219
7225
|
style: {
|
|
7220
7226
|
animationDelay: open ? `${Math.min(index * 15, 150)}ms` : "0ms"
|
|
7221
7227
|
},
|
|
7222
7228
|
className: cn(
|
|
7223
|
-
"dropdown-item group flex
|
|
7229
|
+
"dropdown-item group flex w-full items-center rounded-full text-left",
|
|
7224
7230
|
itemSizeStyles[size],
|
|
7225
7231
|
"outline-none focus:outline-none focus-visible:outline-none",
|
|
7226
7232
|
"transition-all duration-150",
|
|
7227
|
-
!itemDisabled && "hover:bg-accent/70 hover:shadow-sm",
|
|
7233
|
+
!itemDisabled && "cursor-pointer hover:bg-accent/70 hover:shadow-sm",
|
|
7228
7234
|
!itemDisabled && "focus:bg-accent/80 focus:text-accent-foreground",
|
|
7229
7235
|
index === activeIndex && !itemDisabled && "bg-accent/60",
|
|
7230
7236
|
isSelected && "bg-primary/10 text-primary font-medium",
|
|
@@ -7244,16 +7250,14 @@ var Combobox = ({
|
|
|
7244
7250
|
] }),
|
|
7245
7251
|
isSelected && showSelectedIcon && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "shrink-0 ml-auto", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react13.Check, { className: cn(checkIconSizeStyles[size], "text-primary") }) })
|
|
7246
7252
|
]
|
|
7247
|
-
}
|
|
7248
|
-
|
|
7249
|
-
);
|
|
7253
|
+
}
|
|
7254
|
+
) }, `${itemValue}-${index}`);
|
|
7250
7255
|
};
|
|
7251
7256
|
const dropdownBody = /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
7252
7257
|
"div",
|
|
7253
7258
|
{
|
|
7254
7259
|
"data-combobox-dropdown": true,
|
|
7255
7260
|
"data-state": open ? "open" : "closed",
|
|
7256
|
-
role: "listbox",
|
|
7257
7261
|
id: `${resolvedId}-listbox`,
|
|
7258
7262
|
className: "w-full rounded-2xl md:rounded-3xl overflow-hidden",
|
|
7259
7263
|
children: [
|
|
@@ -7308,8 +7312,7 @@ var Combobox = ({
|
|
|
7308
7312
|
"transition-all duration-200",
|
|
7309
7313
|
"placeholder:text-muted-foreground/50"
|
|
7310
7314
|
),
|
|
7311
|
-
"aria-autocomplete": "list"
|
|
7312
|
-
"aria-activedescendant": activeIndex != null ? `combobox-item-${activeIndex}` : void 0
|
|
7315
|
+
"aria-autocomplete": "list"
|
|
7313
7316
|
}
|
|
7314
7317
|
),
|
|
7315
7318
|
query && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
@@ -7381,7 +7384,8 @@ var Combobox = ({
|
|
|
7381
7384
|
"aria-haspopup": "listbox",
|
|
7382
7385
|
"aria-expanded": open,
|
|
7383
7386
|
"aria-controls": `${resolvedId}-listbox`,
|
|
7384
|
-
"aria-
|
|
7387
|
+
"aria-required": required,
|
|
7388
|
+
"aria-invalid": !!effectiveError,
|
|
7385
7389
|
id: resolvedId,
|
|
7386
7390
|
"aria-labelledby": labelId,
|
|
7387
7391
|
onKeyDown: (e) => {
|
|
@@ -7402,7 +7406,7 @@ var Combobox = ({
|
|
|
7402
7406
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:border-primary",
|
|
7403
7407
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
7404
7408
|
open && "ring-2 ring-primary/20 border-primary",
|
|
7405
|
-
!!
|
|
7409
|
+
!!effectiveError && "border-destructive focus-visible:ring-destructive/30",
|
|
7406
7410
|
className
|
|
7407
7411
|
)
|
|
7408
7412
|
};
|
|
@@ -7460,6 +7464,7 @@ var Combobox = ({
|
|
|
7460
7464
|
labelSize,
|
|
7461
7465
|
"font-medium transition-colors duration-200",
|
|
7462
7466
|
disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary",
|
|
7467
|
+
effectiveError && "text-destructive",
|
|
7463
7468
|
labelClassName
|
|
7464
7469
|
),
|
|
7465
7470
|
children: [
|
|
@@ -7468,6 +7473,23 @@ var Combobox = ({
|
|
|
7468
7473
|
]
|
|
7469
7474
|
}
|
|
7470
7475
|
) }),
|
|
7476
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
7477
|
+
"input",
|
|
7478
|
+
{
|
|
7479
|
+
tabIndex: -1,
|
|
7480
|
+
"aria-hidden": "true",
|
|
7481
|
+
value: hasValue ? "selected" : "",
|
|
7482
|
+
onChange: () => {
|
|
7483
|
+
},
|
|
7484
|
+
required,
|
|
7485
|
+
disabled,
|
|
7486
|
+
onInvalid: (e) => {
|
|
7487
|
+
e.preventDefault();
|
|
7488
|
+
setLocalRequiredError(tv("required"));
|
|
7489
|
+
},
|
|
7490
|
+
className: "pointer-events-none absolute h-0 w-0 opacity-0"
|
|
7491
|
+
}
|
|
7492
|
+
),
|
|
7471
7493
|
usePortal ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
7472
7494
|
Popover,
|
|
7473
7495
|
{
|
|
@@ -7484,17 +7506,26 @@ var Combobox = ({
|
|
|
7484
7506
|
triggerButtonInline,
|
|
7485
7507
|
open && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "absolute left-0 top-full mt-1 z-50 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "rounded-2xl md:rounded-3xl overflow-hidden border text-popover-foreground shadow-md backdrop-blur-sm bg-popover/95 border-border/60", children: dropdownBody }) })
|
|
7486
7508
|
] }),
|
|
7487
|
-
(helperText ||
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7509
|
+
(helperText || effectiveError) && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
7510
|
+
"p",
|
|
7511
|
+
{
|
|
7512
|
+
className: cn(
|
|
7513
|
+
"text-xs transition-colors duration-200 flex items-center gap-1.5",
|
|
7514
|
+
effectiveError ? "text-destructive" : "text-muted-foreground"
|
|
7515
|
+
),
|
|
7516
|
+
children: [
|
|
7517
|
+
effectiveError && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", className: "w-3.5 h-3.5 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
7518
|
+
"path",
|
|
7519
|
+
{
|
|
7520
|
+
fillRule: "evenodd",
|
|
7521
|
+
d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z",
|
|
7522
|
+
clipRule: "evenodd"
|
|
7523
|
+
}
|
|
7524
|
+
) }),
|
|
7525
|
+
effectiveError || helperText
|
|
7526
|
+
]
|
|
7527
|
+
}
|
|
7528
|
+
)
|
|
7498
7529
|
] });
|
|
7499
7530
|
};
|
|
7500
7531
|
|
|
@@ -8185,10 +8216,12 @@ var DatePicker = ({
|
|
|
8185
8216
|
maxDate
|
|
8186
8217
|
}) => {
|
|
8187
8218
|
const t = useSmartTranslations("DatePicker");
|
|
8219
|
+
const tv = useSmartTranslations("ValidationInput");
|
|
8188
8220
|
const locale = useSmartLocale();
|
|
8189
8221
|
const [isOpen, setIsOpen] = React28.useState(false);
|
|
8190
8222
|
const [viewDate, setViewDate] = React28.useState(value || /* @__PURE__ */ new Date());
|
|
8191
8223
|
const [viewMode, setViewMode] = React28.useState("calendar");
|
|
8224
|
+
const [localRequiredError, setLocalRequiredError] = React28.useState();
|
|
8192
8225
|
const triggerRef = React28.useRef(null);
|
|
8193
8226
|
const wheelContainerRef = React28.useRef(null);
|
|
8194
8227
|
const wheelDeltaRef = React28.useRef(0);
|
|
@@ -8274,6 +8307,11 @@ var DatePicker = ({
|
|
|
8274
8307
|
setViewDate(/* @__PURE__ */ new Date());
|
|
8275
8308
|
}
|
|
8276
8309
|
}, [value]);
|
|
8310
|
+
React28.useEffect(() => {
|
|
8311
|
+
if (disabled || !required || value) {
|
|
8312
|
+
setLocalRequiredError(void 0);
|
|
8313
|
+
}
|
|
8314
|
+
}, [disabled, required, value]);
|
|
8277
8315
|
React28.useEffect(() => {
|
|
8278
8316
|
if (!isOpen) {
|
|
8279
8317
|
setViewMode("calendar");
|
|
@@ -8288,6 +8326,7 @@ var DatePicker = ({
|
|
|
8288
8326
|
selectedDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
|
|
8289
8327
|
}
|
|
8290
8328
|
onChange(selectedDate);
|
|
8329
|
+
setLocalRequiredError(void 0);
|
|
8291
8330
|
setIsOpen(false);
|
|
8292
8331
|
};
|
|
8293
8332
|
const formatDateDisplay = (date) => {
|
|
@@ -8569,6 +8608,7 @@ var DatePicker = ({
|
|
|
8569
8608
|
const labelSize = sizeStyles8[size].label;
|
|
8570
8609
|
const radiusClass = size === "sm" ? "rounded-md" : "rounded-lg";
|
|
8571
8610
|
const verticalGap = size === "sm" ? "space-y-1.5" : size === "lg" ? "space-y-2.5" : "space-y-2";
|
|
8611
|
+
const effectiveError = localRequiredError;
|
|
8572
8612
|
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: cn("w-full group", verticalGap), children: [
|
|
8573
8613
|
label && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex items-center justify-between mb-2", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
8574
8614
|
"label",
|
|
@@ -8580,6 +8620,7 @@ var DatePicker = ({
|
|
|
8580
8620
|
labelSize,
|
|
8581
8621
|
"font-semibold transition-colors duration-300 cursor-pointer",
|
|
8582
8622
|
disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary hover:text-primary",
|
|
8623
|
+
effectiveError && "text-destructive",
|
|
8583
8624
|
labelClassName
|
|
8584
8625
|
),
|
|
8585
8626
|
children: [
|
|
@@ -8588,6 +8629,23 @@ var DatePicker = ({
|
|
|
8588
8629
|
]
|
|
8589
8630
|
}
|
|
8590
8631
|
) }),
|
|
8632
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
8633
|
+
"input",
|
|
8634
|
+
{
|
|
8635
|
+
tabIndex: -1,
|
|
8636
|
+
"aria-hidden": "true",
|
|
8637
|
+
value: value ? "selected" : "",
|
|
8638
|
+
onChange: () => {
|
|
8639
|
+
},
|
|
8640
|
+
required,
|
|
8641
|
+
disabled,
|
|
8642
|
+
onInvalid: (e) => {
|
|
8643
|
+
e.preventDefault();
|
|
8644
|
+
setLocalRequiredError(tv("required"));
|
|
8645
|
+
},
|
|
8646
|
+
className: "pointer-events-none absolute h-0 w-0 opacity-0"
|
|
8647
|
+
}
|
|
8648
|
+
),
|
|
8591
8649
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
8592
8650
|
Popover,
|
|
8593
8651
|
{
|
|
@@ -8613,6 +8671,8 @@ var DatePicker = ({
|
|
|
8613
8671
|
disabled,
|
|
8614
8672
|
id: resolvedId,
|
|
8615
8673
|
"aria-labelledby": labelId,
|
|
8674
|
+
"aria-required": required,
|
|
8675
|
+
"aria-invalid": !!effectiveError,
|
|
8616
8676
|
className: cn(
|
|
8617
8677
|
"group flex w-full items-center justify-between border bg-background/80 backdrop-blur-sm",
|
|
8618
8678
|
"rounded-full",
|
|
@@ -8623,6 +8683,7 @@ var DatePicker = ({
|
|
|
8623
8683
|
"hover:bg-accent/10 hover:shadow-lg hover:shadow-primary/5 hover:-translate-y-0.5",
|
|
8624
8684
|
"transition-all duration-300 ease-out",
|
|
8625
8685
|
isOpen && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
|
|
8686
|
+
effectiveError && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
|
|
8626
8687
|
className
|
|
8627
8688
|
),
|
|
8628
8689
|
children: [
|
|
@@ -8663,6 +8724,7 @@ var DatePicker = ({
|
|
|
8663
8724
|
e.preventDefault();
|
|
8664
8725
|
e.stopPropagation();
|
|
8665
8726
|
onChange(void 0);
|
|
8727
|
+
setLocalRequiredError(void 0);
|
|
8666
8728
|
setViewDate(/* @__PURE__ */ new Date());
|
|
8667
8729
|
}
|
|
8668
8730
|
},
|
|
@@ -8687,7 +8749,8 @@ var DatePicker = ({
|
|
|
8687
8749
|
),
|
|
8688
8750
|
children: datePickerContent
|
|
8689
8751
|
}
|
|
8690
|
-
)
|
|
8752
|
+
),
|
|
8753
|
+
effectiveError && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "text-xs text-destructive", children: effectiveError })
|
|
8691
8754
|
] });
|
|
8692
8755
|
};
|
|
8693
8756
|
var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select date range...", className, disablePastDates = false, minDate, maxDate, size = "md" }) => {
|
|
@@ -9508,6 +9571,7 @@ function MonthYearPicker({
|
|
|
9508
9571
|
className,
|
|
9509
9572
|
...rest
|
|
9510
9573
|
}) {
|
|
9574
|
+
const tv = useSmartTranslations("ValidationInput");
|
|
9511
9575
|
const now = /* @__PURE__ */ new Date();
|
|
9512
9576
|
const currentYear = now.getFullYear();
|
|
9513
9577
|
const resolvedMinYear = minYear ?? minDate?.getFullYear() ?? currentYear - 50;
|
|
@@ -9524,6 +9588,8 @@ function MonthYearPicker({
|
|
|
9524
9588
|
const [open, setOpen] = React29.useState(false);
|
|
9525
9589
|
const [parts, setParts] = React29.useState(initial);
|
|
9526
9590
|
const [focusedColumn, setFocusedColumn] = React29.useState(null);
|
|
9591
|
+
const [localRequiredError, setLocalRequiredError] = React29.useState();
|
|
9592
|
+
const [hasCommittedValue, setHasCommittedValue] = React29.useState(Boolean(parseValue(isControlled ? value : defaultValue)));
|
|
9527
9593
|
const monthScrollRef = React29.useRef(null);
|
|
9528
9594
|
const yearScrollRef = React29.useRef(null);
|
|
9529
9595
|
React29.useEffect(() => {
|
|
@@ -9532,6 +9598,18 @@ function MonthYearPicker({
|
|
|
9532
9598
|
if (parsed) setParts(parsed);
|
|
9533
9599
|
}
|
|
9534
9600
|
}, [value, isControlled]);
|
|
9601
|
+
React29.useEffect(() => {
|
|
9602
|
+
if (isControlled) {
|
|
9603
|
+
setHasCommittedValue(Boolean(parseValue(value)));
|
|
9604
|
+
}
|
|
9605
|
+
}, [isControlled, value]);
|
|
9606
|
+
const hasValue = hasCommittedValue;
|
|
9607
|
+
const effectiveError = error ?? localRequiredError;
|
|
9608
|
+
React29.useEffect(() => {
|
|
9609
|
+
if (disabled || !required || hasValue) {
|
|
9610
|
+
setLocalRequiredError(void 0);
|
|
9611
|
+
}
|
|
9612
|
+
}, [disabled, hasValue, required]);
|
|
9535
9613
|
const years = React29.useMemo(() => {
|
|
9536
9614
|
return Array.from({ length: resolvedMaxYear - resolvedMinYear + 1 }, (_, i) => resolvedMinYear + i);
|
|
9537
9615
|
}, [resolvedMinYear, resolvedMaxYear]);
|
|
@@ -9555,14 +9633,18 @@ function MonthYearPicker({
|
|
|
9555
9633
|
const emit = React29.useCallback(
|
|
9556
9634
|
(next) => {
|
|
9557
9635
|
if (!next) {
|
|
9636
|
+
setLocalRequiredError(void 0);
|
|
9637
|
+
if (!isControlled) setHasCommittedValue(false);
|
|
9558
9638
|
onChange?.(void 0);
|
|
9559
9639
|
return;
|
|
9560
9640
|
}
|
|
9561
9641
|
if (!isDateInRange(next.month, next.year)) return;
|
|
9562
9642
|
const date = new Date(next.year, next.month, 1);
|
|
9643
|
+
setLocalRequiredError(void 0);
|
|
9644
|
+
if (!isControlled) setHasCommittedValue(true);
|
|
9563
9645
|
onChange?.({ ...next, date });
|
|
9564
9646
|
},
|
|
9565
|
-
[isDateInRange, onChange]
|
|
9647
|
+
[isControlled, isDateInRange, onChange]
|
|
9566
9648
|
);
|
|
9567
9649
|
const tryUpdate = React29.useCallback(
|
|
9568
9650
|
(next) => {
|
|
@@ -9634,7 +9716,6 @@ function MonthYearPicker({
|
|
|
9634
9716
|
const monthIndex = parts.month;
|
|
9635
9717
|
const yearIndex = years.indexOf(parts.year);
|
|
9636
9718
|
const display = `${shortMonthNames[parts.month]} ${parts.year}`;
|
|
9637
|
-
const hasValue = isControlled ? !!value : !!defaultValue || parts !== initial;
|
|
9638
9719
|
const trigger = variant === "inline" ? null : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
9639
9720
|
"button",
|
|
9640
9721
|
{
|
|
@@ -9643,6 +9724,8 @@ function MonthYearPicker({
|
|
|
9643
9724
|
"aria-label": "Select month and year",
|
|
9644
9725
|
"aria-haspopup": "dialog",
|
|
9645
9726
|
"aria-expanded": open,
|
|
9727
|
+
"aria-required": required,
|
|
9728
|
+
"aria-invalid": !!effectiveError,
|
|
9646
9729
|
className: cn(
|
|
9647
9730
|
"group flex w-full items-center justify-between rounded-full border bg-background/80 backdrop-blur-sm",
|
|
9648
9731
|
sz.height,
|
|
@@ -9651,9 +9734,9 @@ function MonthYearPicker({
|
|
|
9651
9734
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
9652
9735
|
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
9653
9736
|
"transition-all duration-300 ease-out",
|
|
9654
|
-
|
|
9655
|
-
success && "border-success/60 focus-visible:ring-success/50 bg-success/5",
|
|
9656
|
-
!
|
|
9737
|
+
effectiveError && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
|
|
9738
|
+
success && !effectiveError && "border-success/60 focus-visible:ring-success/50 bg-success/5",
|
|
9739
|
+
!effectiveError && !success && "border-border/60 hover:border-primary/40 hover:bg-accent/10",
|
|
9657
9740
|
animate && !disabled && "hover:shadow-lg hover:shadow-primary/5 hover:-translate-y-0.5",
|
|
9658
9741
|
open && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
|
|
9659
9742
|
className
|
|
@@ -9665,7 +9748,7 @@ function MonthYearPicker({
|
|
|
9665
9748
|
{
|
|
9666
9749
|
className: cn(
|
|
9667
9750
|
"flex items-center justify-center transition-colors duration-300",
|
|
9668
|
-
|
|
9751
|
+
effectiveError ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
|
|
9669
9752
|
),
|
|
9670
9753
|
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react16.Calendar, { className: cn(sz.icon, "transition-transform duration-300", open && "rotate-12") })
|
|
9671
9754
|
}
|
|
@@ -9800,19 +9883,63 @@ function MonthYearPicker({
|
|
|
9800
9883
|
] });
|
|
9801
9884
|
if (variant === "inline") {
|
|
9802
9885
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: cn("w-full", className), ...rest, children: [
|
|
9803
|
-
label && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: cn(sz.label, "block mb-1.5 font-medium text-foreground/80", labelClassName), children: [
|
|
9886
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: cn(sz.label, "block mb-1.5 font-medium text-foreground/80", effectiveError && "text-destructive", labelClassName), children: [
|
|
9804
9887
|
label,
|
|
9805
9888
|
required && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
9806
9889
|
] }),
|
|
9807
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
9808
|
-
|
|
9890
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
9891
|
+
"input",
|
|
9892
|
+
{
|
|
9893
|
+
tabIndex: -1,
|
|
9894
|
+
"aria-hidden": "true",
|
|
9895
|
+
value: hasValue ? "selected" : "",
|
|
9896
|
+
onChange: () => {
|
|
9897
|
+
},
|
|
9898
|
+
required,
|
|
9899
|
+
disabled,
|
|
9900
|
+
onInvalid: (e) => {
|
|
9901
|
+
e.preventDefault();
|
|
9902
|
+
setLocalRequiredError(tv("required"));
|
|
9903
|
+
},
|
|
9904
|
+
className: "pointer-events-none absolute h-0 w-0 opacity-0"
|
|
9905
|
+
}
|
|
9906
|
+
),
|
|
9907
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
9908
|
+
"div",
|
|
9909
|
+
{
|
|
9910
|
+
className: cn(
|
|
9911
|
+
panelSz.contentPadding,
|
|
9912
|
+
"rounded-2xl border bg-background/80 backdrop-blur-sm",
|
|
9913
|
+
effectiveError ? "border-destructive/60 bg-destructive/5" : "border-border/50"
|
|
9914
|
+
),
|
|
9915
|
+
children: pickerContent
|
|
9916
|
+
}
|
|
9917
|
+
),
|
|
9918
|
+
(helperText || effectiveError) && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cn("mt-1.5 text-xs", effectiveError ? "text-destructive" : "text-muted-foreground"), children: effectiveError || helperText })
|
|
9809
9919
|
] });
|
|
9810
9920
|
}
|
|
9811
9921
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: cn("w-full", className), ...rest, children: [
|
|
9812
|
-
label && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: cn(sz.label, "block mb-1.5 font-medium text-foreground/80", labelClassName), children: [
|
|
9922
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: cn(sz.label, "block mb-1.5 font-medium text-foreground/80", effectiveError && "text-destructive", labelClassName), children: [
|
|
9813
9923
|
label,
|
|
9814
9924
|
required && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
9815
9925
|
] }),
|
|
9926
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
9927
|
+
"input",
|
|
9928
|
+
{
|
|
9929
|
+
tabIndex: -1,
|
|
9930
|
+
"aria-hidden": "true",
|
|
9931
|
+
value: hasValue ? "selected" : "",
|
|
9932
|
+
onChange: () => {
|
|
9933
|
+
},
|
|
9934
|
+
required,
|
|
9935
|
+
disabled,
|
|
9936
|
+
onInvalid: (e) => {
|
|
9937
|
+
e.preventDefault();
|
|
9938
|
+
setLocalRequiredError(tv("required"));
|
|
9939
|
+
},
|
|
9940
|
+
className: "pointer-events-none absolute h-0 w-0 opacity-0"
|
|
9941
|
+
}
|
|
9942
|
+
),
|
|
9816
9943
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
9817
9944
|
Popover,
|
|
9818
9945
|
{
|
|
@@ -9827,7 +9954,7 @@ function MonthYearPicker({
|
|
|
9827
9954
|
children: pickerContent
|
|
9828
9955
|
}
|
|
9829
9956
|
),
|
|
9830
|
-
(helperText ||
|
|
9957
|
+
(helperText || effectiveError) && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cn("mt-1.5 text-xs", effectiveError ? "text-destructive" : "text-muted-foreground"), children: effectiveError || helperText })
|
|
9831
9958
|
] });
|
|
9832
9959
|
}
|
|
9833
9960
|
|
|
@@ -10967,6 +11094,7 @@ function TimePicker({
|
|
|
10967
11094
|
className,
|
|
10968
11095
|
...rest
|
|
10969
11096
|
}) {
|
|
11097
|
+
const tv = useSmartTranslations("ValidationInput");
|
|
10970
11098
|
const isControlled = value !== void 0;
|
|
10971
11099
|
const now = /* @__PURE__ */ new Date();
|
|
10972
11100
|
const initial = parseTime(isControlled ? value : defaultValue, format, includeSeconds) || (format === "12" ? { h: now.getHours() % 12 || 12, m: now.getMinutes(), s: now.getSeconds(), p: now.getHours() >= 12 ? "PM" : "AM" } : { h: now.getHours(), m: now.getMinutes(), s: now.getSeconds() });
|
|
@@ -10974,6 +11102,8 @@ function TimePicker({
|
|
|
10974
11102
|
const [parts, setParts] = React31.useState(initial);
|
|
10975
11103
|
const [manualInput, setManualInput] = React31.useState("");
|
|
10976
11104
|
const [focusedColumn, setFocusedColumn] = React31.useState(null);
|
|
11105
|
+
const [localRequiredError, setLocalRequiredError] = React31.useState();
|
|
11106
|
+
const [hasCommittedValue, setHasCommittedValue] = React31.useState(Boolean(isControlled ? value : defaultValue));
|
|
10977
11107
|
const hourScrollRef = React31.useRef(null);
|
|
10978
11108
|
const minuteScrollRef = React31.useRef(null);
|
|
10979
11109
|
const secondScrollRef = React31.useRef(null);
|
|
@@ -10983,6 +11113,11 @@ function TimePicker({
|
|
|
10983
11113
|
if (parsed) setParts(parsed);
|
|
10984
11114
|
}
|
|
10985
11115
|
}, [value, isControlled, format, includeSeconds]);
|
|
11116
|
+
React31.useEffect(() => {
|
|
11117
|
+
if (isControlled) {
|
|
11118
|
+
setHasCommittedValue(Boolean(value));
|
|
11119
|
+
}
|
|
11120
|
+
}, [isControlled, value]);
|
|
10986
11121
|
const isTimeDisabled = React31.useCallback(
|
|
10987
11122
|
(timeStr) => {
|
|
10988
11123
|
if (!disabledTimes) return false;
|
|
@@ -11037,9 +11172,13 @@ function TimePicker({
|
|
|
11037
11172
|
(next) => {
|
|
11038
11173
|
const timeStr = next ? formatTime2(next, format, includeSeconds) : void 0;
|
|
11039
11174
|
if (!canEmit(next)) return;
|
|
11175
|
+
setLocalRequiredError(void 0);
|
|
11176
|
+
if (!isControlled) {
|
|
11177
|
+
setHasCommittedValue(Boolean(next));
|
|
11178
|
+
}
|
|
11040
11179
|
onChange?.(timeStr);
|
|
11041
11180
|
},
|
|
11042
|
-
[canEmit, format, includeSeconds, onChange]
|
|
11181
|
+
[canEmit, format, includeSeconds, isControlled, onChange]
|
|
11043
11182
|
);
|
|
11044
11183
|
const tryUpdate = React31.useCallback(
|
|
11045
11184
|
(next) => {
|
|
@@ -11059,6 +11198,11 @@ function TimePicker({
|
|
|
11059
11198
|
setFocusedColumn(null);
|
|
11060
11199
|
}
|
|
11061
11200
|
};
|
|
11201
|
+
React31.useEffect(() => {
|
|
11202
|
+
if (disabled || !required || hasCommittedValue) {
|
|
11203
|
+
setLocalRequiredError(void 0);
|
|
11204
|
+
}
|
|
11205
|
+
}, [disabled, hasCommittedValue, required]);
|
|
11062
11206
|
const handleKeyDown2 = (e, column) => {
|
|
11063
11207
|
if (!["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End", "PageUp", "PageDown"].includes(e.key)) return;
|
|
11064
11208
|
e.preventDefault();
|
|
@@ -11201,6 +11345,7 @@ function TimePicker({
|
|
|
11201
11345
|
const panelSz = panelSizeClasses[effectivePanelSize];
|
|
11202
11346
|
const shouldMatchTriggerWidth = matchTriggerWidth ?? variant !== "compact";
|
|
11203
11347
|
const compactPanel = variant === "compact";
|
|
11348
|
+
const effectiveError = error ?? localRequiredError;
|
|
11204
11349
|
const display = formatTime2(parts, format, includeSeconds);
|
|
11205
11350
|
const trigger = variant === "inline" ? null : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
11206
11351
|
"button",
|
|
@@ -11210,6 +11355,8 @@ function TimePicker({
|
|
|
11210
11355
|
"aria-label": "Select time",
|
|
11211
11356
|
"aria-haspopup": "dialog",
|
|
11212
11357
|
"aria-expanded": open,
|
|
11358
|
+
"aria-required": required,
|
|
11359
|
+
"aria-invalid": !!effectiveError,
|
|
11213
11360
|
className: cn(
|
|
11214
11361
|
"group flex w-full items-center justify-between rounded-full border bg-background/80 backdrop-blur-sm",
|
|
11215
11362
|
sz.height,
|
|
@@ -11218,9 +11365,9 @@ function TimePicker({
|
|
|
11218
11365
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
11219
11366
|
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
11220
11367
|
"transition-all duration-300 ease-out",
|
|
11221
|
-
|
|
11222
|
-
success && "border-success/60 focus-visible:ring-success/50 bg-success/5",
|
|
11223
|
-
!
|
|
11368
|
+
effectiveError && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
|
|
11369
|
+
success && !effectiveError && "border-success/60 focus-visible:ring-success/50 bg-success/5",
|
|
11370
|
+
!effectiveError && !success && "border-border/60 hover:border-primary/40 hover:bg-accent/10",
|
|
11224
11371
|
animate && !disabled && "hover:shadow-lg hover:shadow-primary/5 hover:-translate-y-0.5",
|
|
11225
11372
|
open && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
|
|
11226
11373
|
className
|
|
@@ -11232,7 +11379,7 @@ function TimePicker({
|
|
|
11232
11379
|
{
|
|
11233
11380
|
className: cn(
|
|
11234
11381
|
"flex items-center justify-center transition-colors duration-300",
|
|
11235
|
-
|
|
11382
|
+
effectiveError ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
|
|
11236
11383
|
),
|
|
11237
11384
|
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react18.Clock, { className: cn(sz.icon, "transition-transform duration-300", open && "rotate-12") })
|
|
11238
11385
|
}
|
|
@@ -11519,17 +11666,40 @@ function TimePicker({
|
|
|
11519
11666
|
] });
|
|
11520
11667
|
if (variant === "inline") {
|
|
11521
11668
|
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "w-fit max-w-full", ...rest, children: [
|
|
11522
|
-
label && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("label", { className: cn(sz.label, "font-semibold", disabled ? "text-muted-foreground" : "text-foreground"), children: [
|
|
11669
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("label", { className: cn(sz.label, "font-semibold", disabled ? "text-muted-foreground" : "text-foreground", effectiveError && "text-destructive"), children: [
|
|
11523
11670
|
label,
|
|
11524
11671
|
required && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-destructive ml-1", children: "*" })
|
|
11525
11672
|
] }) }),
|
|
11673
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
11674
|
+
"input",
|
|
11675
|
+
{
|
|
11676
|
+
tabIndex: -1,
|
|
11677
|
+
"aria-hidden": "true",
|
|
11678
|
+
value: hasCommittedValue ? "selected" : "",
|
|
11679
|
+
onChange: () => {
|
|
11680
|
+
},
|
|
11681
|
+
required,
|
|
11682
|
+
disabled,
|
|
11683
|
+
onInvalid: (e) => {
|
|
11684
|
+
e.preventDefault();
|
|
11685
|
+
setLocalRequiredError(tv("required"));
|
|
11686
|
+
},
|
|
11687
|
+
className: "pointer-events-none absolute h-0 w-0 opacity-0"
|
|
11688
|
+
}
|
|
11689
|
+
),
|
|
11526
11690
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
11527
11691
|
"div",
|
|
11528
11692
|
{
|
|
11529
|
-
className: cn(
|
|
11693
|
+
className: cn(
|
|
11694
|
+
panelSz.contentPadding,
|
|
11695
|
+
"rounded-2xl md:rounded-3xl border bg-card/95 backdrop-blur-sm shadow-xl",
|
|
11696
|
+
effectiveError ? "border-destructive/60 bg-destructive/5" : "border-border/60",
|
|
11697
|
+
className
|
|
11698
|
+
),
|
|
11530
11699
|
children: timePickerContent
|
|
11531
11700
|
}
|
|
11532
|
-
)
|
|
11701
|
+
),
|
|
11702
|
+
effectiveError && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cn("mt-2", sz.label, "text-destructive"), children: effectiveError })
|
|
11533
11703
|
] });
|
|
11534
11704
|
}
|
|
11535
11705
|
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "w-full", ...rest, children: [
|
|
@@ -11540,6 +11710,7 @@ function TimePicker({
|
|
|
11540
11710
|
sz.label,
|
|
11541
11711
|
"font-semibold",
|
|
11542
11712
|
disabled ? "text-muted-foreground" : "text-foreground",
|
|
11713
|
+
effectiveError && "text-destructive",
|
|
11543
11714
|
"cursor-pointer transition-colors hover:text-primary"
|
|
11544
11715
|
),
|
|
11545
11716
|
onClick: () => !disabled && handleOpenChange(true),
|
|
@@ -11549,6 +11720,23 @@ function TimePicker({
|
|
|
11549
11720
|
]
|
|
11550
11721
|
}
|
|
11551
11722
|
) }),
|
|
11723
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
11724
|
+
"input",
|
|
11725
|
+
{
|
|
11726
|
+
tabIndex: -1,
|
|
11727
|
+
"aria-hidden": "true",
|
|
11728
|
+
value: hasCommittedValue ? "selected" : "",
|
|
11729
|
+
onChange: () => {
|
|
11730
|
+
},
|
|
11731
|
+
required,
|
|
11732
|
+
disabled,
|
|
11733
|
+
onInvalid: (e) => {
|
|
11734
|
+
e.preventDefault();
|
|
11735
|
+
setLocalRequiredError(tv("required"));
|
|
11736
|
+
},
|
|
11737
|
+
className: "pointer-events-none absolute h-0 w-0 opacity-0"
|
|
11738
|
+
}
|
|
11739
|
+
),
|
|
11552
11740
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
11553
11741
|
Popover,
|
|
11554
11742
|
{
|
|
@@ -11562,24 +11750,24 @@ function TimePicker({
|
|
|
11562
11750
|
panelSz.contentPadding,
|
|
11563
11751
|
compactPanel && "max-w-[calc(100vw-2rem)] p-4 rounded-2xl",
|
|
11564
11752
|
"rounded-2xl md:rounded-3xl border bg-popover/98 backdrop-blur-md shadow-2xl",
|
|
11565
|
-
|
|
11566
|
-
success && "border-success/40",
|
|
11567
|
-
!
|
|
11753
|
+
effectiveError && "border-destructive/40",
|
|
11754
|
+
success && !effectiveError && "border-success/40",
|
|
11755
|
+
!effectiveError && !success && "border-border/60",
|
|
11568
11756
|
animate && "animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-300"
|
|
11569
11757
|
),
|
|
11570
11758
|
children: timePickerContent
|
|
11571
11759
|
}
|
|
11572
11760
|
),
|
|
11573
|
-
(
|
|
11574
|
-
|
|
11761
|
+
(effectiveError || success || helperText) && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cn("mt-2 flex items-start gap-2", sz.label), children: [
|
|
11762
|
+
effectiveError && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center gap-2 text-destructive bg-destructive/10 px-3 py-1.5 rounded-lg", children: [
|
|
11575
11763
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react18.X, { className: "w-3.5 h-3.5 shrink-0" }),
|
|
11576
|
-
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "font-medium", children:
|
|
11764
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "font-medium", children: effectiveError })
|
|
11577
11765
|
] }),
|
|
11578
|
-
success && !
|
|
11766
|
+
success && !effectiveError && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center gap-2 text-success bg-success/10 px-3 py-1.5 rounded-lg", children: [
|
|
11579
11767
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react18.Check, { className: "w-3.5 h-3.5 shrink-0" }),
|
|
11580
11768
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "font-medium", children: "Valid time selected" })
|
|
11581
11769
|
] }),
|
|
11582
|
-
helperText && !
|
|
11770
|
+
helperText && !effectiveError && !success && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-muted-foreground/80 italic", children: helperText })
|
|
11583
11771
|
] })
|
|
11584
11772
|
] });
|
|
11585
11773
|
}
|
|
@@ -11604,8 +11792,10 @@ var DateTimePicker = ({
|
|
|
11604
11792
|
size = "md"
|
|
11605
11793
|
}) => {
|
|
11606
11794
|
const t = useSmartTranslations("DateTimePicker");
|
|
11795
|
+
const tv = useSmartTranslations("ValidationInput");
|
|
11607
11796
|
const locale = useSmartLocale();
|
|
11608
11797
|
const [open, setOpen] = React32.useState(false);
|
|
11798
|
+
const [localRequiredError, setLocalRequiredError] = React32.useState();
|
|
11609
11799
|
const sizeStyles8 = {
|
|
11610
11800
|
sm: {
|
|
11611
11801
|
trigger: "h-8 px-2.5 py-1.5 text-sm md:h-7 md:text-xs",
|
|
@@ -11644,6 +11834,11 @@ var DateTimePicker = ({
|
|
|
11644
11834
|
setTempDate(value);
|
|
11645
11835
|
setCalendarMonth(value ?? /* @__PURE__ */ new Date());
|
|
11646
11836
|
}, [value, open]);
|
|
11837
|
+
React32.useEffect(() => {
|
|
11838
|
+
if (disabled || !required || value) {
|
|
11839
|
+
setLocalRequiredError(void 0);
|
|
11840
|
+
}
|
|
11841
|
+
}, [disabled, required, value]);
|
|
11647
11842
|
const getTimeString = (date) => {
|
|
11648
11843
|
if (!date) return "";
|
|
11649
11844
|
const h = date.getHours();
|
|
@@ -11700,11 +11895,13 @@ var DateTimePicker = ({
|
|
|
11700
11895
|
};
|
|
11701
11896
|
const handleApply = () => {
|
|
11702
11897
|
onChange(tempDate);
|
|
11898
|
+
setLocalRequiredError(void 0);
|
|
11703
11899
|
setOpen(false);
|
|
11704
11900
|
};
|
|
11705
11901
|
const handleClear = () => {
|
|
11706
11902
|
onChange(void 0);
|
|
11707
11903
|
setTempDate(void 0);
|
|
11904
|
+
setLocalRequiredError(void 0);
|
|
11708
11905
|
setOpen(false);
|
|
11709
11906
|
};
|
|
11710
11907
|
const displayValue = value ? value.toLocaleString(locale === "vi" ? "vi-VN" : "en-US", {
|
|
@@ -11735,12 +11932,30 @@ var DateTimePicker = ({
|
|
|
11735
11932
|
}
|
|
11736
11933
|
};
|
|
11737
11934
|
const weekdays = getWeekdays(locale);
|
|
11935
|
+
const effectiveError = localRequiredError;
|
|
11738
11936
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: cn("space-y-1.5", className), children: [
|
|
11739
|
-
label && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("label", { className: cn(sizeStyles8[size].label, "font-medium text-foreground flex items-center gap-1", labelClassName), children: [
|
|
11937
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("label", { className: cn(sizeStyles8[size].label, "font-medium text-foreground flex items-center gap-1", effectiveError && "text-destructive", labelClassName), children: [
|
|
11740
11938
|
label,
|
|
11741
11939
|
" ",
|
|
11742
11940
|
required && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-destructive", children: "*" })
|
|
11743
11941
|
] }),
|
|
11942
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
11943
|
+
"input",
|
|
11944
|
+
{
|
|
11945
|
+
tabIndex: -1,
|
|
11946
|
+
"aria-hidden": "true",
|
|
11947
|
+
value: value ? "selected" : "",
|
|
11948
|
+
onChange: () => {
|
|
11949
|
+
},
|
|
11950
|
+
required,
|
|
11951
|
+
disabled,
|
|
11952
|
+
onInvalid: (e) => {
|
|
11953
|
+
e.preventDefault();
|
|
11954
|
+
setLocalRequiredError(tv("required"));
|
|
11955
|
+
},
|
|
11956
|
+
className: "pointer-events-none absolute h-0 w-0 opacity-0"
|
|
11957
|
+
}
|
|
11958
|
+
),
|
|
11744
11959
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
11745
11960
|
Popover,
|
|
11746
11961
|
{
|
|
@@ -11751,12 +11966,15 @@ var DateTimePicker = ({
|
|
|
11751
11966
|
{
|
|
11752
11967
|
type: "button",
|
|
11753
11968
|
disabled,
|
|
11969
|
+
"aria-required": required,
|
|
11970
|
+
"aria-invalid": !!effectiveError,
|
|
11754
11971
|
className: cn(
|
|
11755
11972
|
"flex w-full items-center justify-between rounded-full border border-input bg-background",
|
|
11756
11973
|
sizeStyles8[size].trigger,
|
|
11757
11974
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
11758
11975
|
disabled && "opacity-50 cursor-not-allowed",
|
|
11759
|
-
!displayValue && "text-muted-foreground"
|
|
11976
|
+
!displayValue && "text-muted-foreground",
|
|
11977
|
+
effectiveError && "border-destructive/60 bg-destructive/5"
|
|
11760
11978
|
),
|
|
11761
11979
|
children: [
|
|
11762
11980
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "truncate", children: displayValue || placeholder || "Select date & time" }),
|
|
@@ -11769,6 +11987,7 @@ var DateTimePicker = ({
|
|
|
11769
11987
|
onClick: (e) => {
|
|
11770
11988
|
e.stopPropagation();
|
|
11771
11989
|
onChange(void 0);
|
|
11990
|
+
setLocalRequiredError(void 0);
|
|
11772
11991
|
},
|
|
11773
11992
|
className: "hover:text-foreground p-0.5 rounded-md hover:bg-accent",
|
|
11774
11993
|
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react19.X, { className: sizeStyles8[size].icon })
|
|
@@ -11828,7 +12047,8 @@ var DateTimePicker = ({
|
|
|
11828
12047
|
] })
|
|
11829
12048
|
]
|
|
11830
12049
|
}
|
|
11831
|
-
)
|
|
12050
|
+
),
|
|
12051
|
+
effectiveError && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "text-xs text-destructive", children: effectiveError })
|
|
11832
12052
|
] });
|
|
11833
12053
|
};
|
|
11834
12054
|
|
|
@@ -14785,9 +15005,11 @@ var MultiCombobox = ({
|
|
|
14785
15005
|
maxTagsVisible = 3,
|
|
14786
15006
|
useOverlayScrollbar = false
|
|
14787
15007
|
}) => {
|
|
15008
|
+
const tv = useSmartTranslations("ValidationInput");
|
|
14788
15009
|
const [query, setQuery] = React39.useState("");
|
|
14789
15010
|
const [open, setOpen] = React39.useState(false);
|
|
14790
15011
|
const [activeIndex, setActiveIndex] = React39.useState(null);
|
|
15012
|
+
const [localRequiredError, setLocalRequiredError] = React39.useState();
|
|
14791
15013
|
const inputRef = React39.useRef(null);
|
|
14792
15014
|
const listRef = React39.useRef([]);
|
|
14793
15015
|
const optionsListRef = React39.useRef(null);
|
|
@@ -14824,6 +15046,7 @@ var MultiCombobox = ({
|
|
|
14824
15046
|
onChange(value.filter((v) => v !== optionValue));
|
|
14825
15047
|
} else {
|
|
14826
15048
|
if (!maxSelected || value.length < maxSelected) {
|
|
15049
|
+
setLocalRequiredError(void 0);
|
|
14827
15050
|
onChange([...value, optionValue]);
|
|
14828
15051
|
}
|
|
14829
15052
|
}
|
|
@@ -14843,6 +15066,12 @@ var MultiCombobox = ({
|
|
|
14843
15066
|
const handleClearAll = () => {
|
|
14844
15067
|
onChange([]);
|
|
14845
15068
|
};
|
|
15069
|
+
const effectiveError = error ?? localRequiredError;
|
|
15070
|
+
React39.useEffect(() => {
|
|
15071
|
+
if (disabled || !required || value.length > 0) {
|
|
15072
|
+
setLocalRequiredError(void 0);
|
|
15073
|
+
}
|
|
15074
|
+
}, [disabled, required, value.length]);
|
|
14846
15075
|
React39.useEffect(() => {
|
|
14847
15076
|
if (open && enableSearch) {
|
|
14848
15077
|
setTimeout(() => {
|
|
@@ -15053,7 +15282,8 @@ var MultiCombobox = ({
|
|
|
15053
15282
|
"aria-haspopup": "listbox",
|
|
15054
15283
|
"aria-expanded": open,
|
|
15055
15284
|
"aria-controls": listboxId,
|
|
15056
|
-
"aria-
|
|
15285
|
+
"aria-required": required,
|
|
15286
|
+
"aria-invalid": !!effectiveError,
|
|
15057
15287
|
className: cn(
|
|
15058
15288
|
"group flex w-full items-center gap-2 rounded-full transition-all duration-200",
|
|
15059
15289
|
sizeStyles8[size].trigger,
|
|
@@ -15061,7 +15291,7 @@ var MultiCombobox = ({
|
|
|
15061
15291
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:border-primary",
|
|
15062
15292
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
15063
15293
|
open && "ring-2 ring-primary/20 border-primary",
|
|
15064
|
-
!!
|
|
15294
|
+
!!effectiveError && "border-destructive focus-visible:ring-destructive/30"
|
|
15065
15295
|
),
|
|
15066
15296
|
children: [
|
|
15067
15297
|
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cn("flex items-center gap-1.5 flex-1 overflow-hidden", size === "sm" ? "min-h-4" : size === "lg" ? "min-h-8" : "min-h-6"), children: value.length > 0 ? showTags ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
@@ -15157,6 +15387,7 @@ var MultiCombobox = ({
|
|
|
15157
15387
|
size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm",
|
|
15158
15388
|
"font-medium transition-colors duration-200",
|
|
15159
15389
|
disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary",
|
|
15390
|
+
effectiveError && "text-destructive",
|
|
15160
15391
|
labelClassName
|
|
15161
15392
|
),
|
|
15162
15393
|
children: [
|
|
@@ -15174,6 +15405,7 @@ var MultiCombobox = ({
|
|
|
15174
15405
|
labelSize,
|
|
15175
15406
|
"font-medium transition-colors duration-200",
|
|
15176
15407
|
disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary",
|
|
15408
|
+
effectiveError && "text-destructive",
|
|
15177
15409
|
labelClassName
|
|
15178
15410
|
),
|
|
15179
15411
|
children: [
|
|
@@ -15182,6 +15414,23 @@ var MultiCombobox = ({
|
|
|
15182
15414
|
]
|
|
15183
15415
|
}
|
|
15184
15416
|
),
|
|
15417
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
15418
|
+
"input",
|
|
15419
|
+
{
|
|
15420
|
+
tabIndex: -1,
|
|
15421
|
+
"aria-hidden": "true",
|
|
15422
|
+
value: value.length > 0 ? "selected" : "",
|
|
15423
|
+
onChange: () => {
|
|
15424
|
+
},
|
|
15425
|
+
required,
|
|
15426
|
+
disabled,
|
|
15427
|
+
onInvalid: (e) => {
|
|
15428
|
+
e.preventDefault();
|
|
15429
|
+
setLocalRequiredError(tv("required"));
|
|
15430
|
+
},
|
|
15431
|
+
className: "pointer-events-none absolute h-0 w-0 opacity-0"
|
|
15432
|
+
}
|
|
15433
|
+
),
|
|
15185
15434
|
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
15186
15435
|
Popover,
|
|
15187
15436
|
{
|
|
@@ -15195,17 +15444,26 @@ var MultiCombobox = ({
|
|
|
15195
15444
|
children: dropdownBody
|
|
15196
15445
|
}
|
|
15197
15446
|
),
|
|
15198
|
-
(helperText ||
|
|
15199
|
-
|
|
15200
|
-
|
|
15201
|
-
|
|
15202
|
-
|
|
15203
|
-
|
|
15204
|
-
|
|
15205
|
-
|
|
15206
|
-
|
|
15207
|
-
|
|
15208
|
-
|
|
15447
|
+
(helperText || effectiveError) && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
15448
|
+
"p",
|
|
15449
|
+
{
|
|
15450
|
+
className: cn(
|
|
15451
|
+
"text-xs transition-colors duration-200 flex items-center gap-1.5",
|
|
15452
|
+
effectiveError ? "text-destructive" : "text-muted-foreground"
|
|
15453
|
+
),
|
|
15454
|
+
children: [
|
|
15455
|
+
effectiveError && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", className: "w-3.5 h-3.5 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
15456
|
+
"path",
|
|
15457
|
+
{
|
|
15458
|
+
fillRule: "evenodd",
|
|
15459
|
+
d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z",
|
|
15460
|
+
clipRule: "evenodd"
|
|
15461
|
+
}
|
|
15462
|
+
) }),
|
|
15463
|
+
effectiveError || helperText
|
|
15464
|
+
]
|
|
15465
|
+
}
|
|
15466
|
+
)
|
|
15209
15467
|
] });
|
|
15210
15468
|
};
|
|
15211
15469
|
|
|
@@ -16354,6 +16612,7 @@ function getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline)
|
|
|
16354
16612
|
return parentIds;
|
|
16355
16613
|
}
|
|
16356
16614
|
function CategoryTreeSelect(props) {
|
|
16615
|
+
const tv = useSmartTranslations("ValidationInput");
|
|
16357
16616
|
const {
|
|
16358
16617
|
id,
|
|
16359
16618
|
label,
|
|
@@ -16381,14 +16640,16 @@ function CategoryTreeSelect(props) {
|
|
|
16381
16640
|
const [isOpen, setIsOpen] = (0, import_react22.useState)(false);
|
|
16382
16641
|
const [expandedNodes, setExpandedNodes] = (0, import_react22.useState)(() => getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline));
|
|
16383
16642
|
const [query, setQuery] = (0, import_react22.useState)("");
|
|
16643
|
+
const [localRequiredError, setLocalRequiredError] = (0, import_react22.useState)();
|
|
16384
16644
|
const searchInputRef = (0, import_react22.useRef)(null);
|
|
16385
16645
|
const dropdownViewportRef = (0, import_react22.useRef)(null);
|
|
16386
16646
|
useOverlayScrollbarTarget(dropdownViewportRef, { enabled: useOverlayScrollbar });
|
|
16387
16647
|
const autoId = (0, import_react22.useId)();
|
|
16388
16648
|
const resolvedId = id ? String(id) : `category-tree-select-${autoId}`;
|
|
16389
16649
|
const labelId = label ? `${resolvedId}-label` : void 0;
|
|
16390
|
-
const
|
|
16391
|
-
const
|
|
16650
|
+
const effectiveError = error ?? localRequiredError;
|
|
16651
|
+
const helperId = helperText && !effectiveError ? `${resolvedId}-helper` : void 0;
|
|
16652
|
+
const errorId = effectiveError ? `${resolvedId}-error` : void 0;
|
|
16392
16653
|
const describedBy = errorId || helperId;
|
|
16393
16654
|
const mergedLabels = { ...defaultLabels, ...labels };
|
|
16394
16655
|
const valueArray = (0, import_react22.useMemo)(
|
|
@@ -16459,6 +16720,11 @@ function CategoryTreeSelect(props) {
|
|
|
16459
16720
|
const t = setTimeout(() => searchInputRef.current?.focus(), 50);
|
|
16460
16721
|
return () => clearTimeout(t);
|
|
16461
16722
|
}, [isOpen, isSearchEnabled]);
|
|
16723
|
+
(0, import_react22.useEffect)(() => {
|
|
16724
|
+
if (disabled || !required || valueArray.length > 0) {
|
|
16725
|
+
setLocalRequiredError(void 0);
|
|
16726
|
+
}
|
|
16727
|
+
}, [disabled, required, valueArray.length]);
|
|
16462
16728
|
const toggleExpand = (id2) => {
|
|
16463
16729
|
if (isSearchMode) return;
|
|
16464
16730
|
const newExpanded = new Set(expandedNodes);
|
|
@@ -16477,6 +16743,7 @@ function CategoryTreeSelect(props) {
|
|
|
16477
16743
|
toggleExpand(categoryId);
|
|
16478
16744
|
return;
|
|
16479
16745
|
}
|
|
16746
|
+
setLocalRequiredError(void 0);
|
|
16480
16747
|
if (!props.onChange) return;
|
|
16481
16748
|
if (singleSelect) {
|
|
16482
16749
|
const onChange = props.onChange;
|
|
@@ -16648,7 +16915,7 @@ function CategoryTreeSelect(props) {
|
|
|
16648
16915
|
className: cn(
|
|
16649
16916
|
size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm",
|
|
16650
16917
|
disabled ? "text-muted-foreground" : "text-foreground",
|
|
16651
|
-
|
|
16918
|
+
effectiveError && "text-destructive",
|
|
16652
16919
|
labelClassName
|
|
16653
16920
|
),
|
|
16654
16921
|
children: [
|
|
@@ -16657,10 +16924,27 @@ function CategoryTreeSelect(props) {
|
|
|
16657
16924
|
]
|
|
16658
16925
|
}
|
|
16659
16926
|
) }) : null;
|
|
16660
|
-
const renderAssistiveText = () =>
|
|
16927
|
+
const renderAssistiveText = () => effectiveError ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { id: errorId, className: "text-sm text-destructive", children: effectiveError }) : helperText ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { id: helperId, className: "text-sm text-muted-foreground", children: helperText }) : null;
|
|
16661
16928
|
if (viewOnly) {
|
|
16662
16929
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("w-full space-y-2", className), children: [
|
|
16663
16930
|
renderLabel(),
|
|
16931
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
16932
|
+
"input",
|
|
16933
|
+
{
|
|
16934
|
+
tabIndex: -1,
|
|
16935
|
+
"aria-hidden": "true",
|
|
16936
|
+
value: valueArray.length > 0 ? "selected" : "",
|
|
16937
|
+
onChange: () => {
|
|
16938
|
+
},
|
|
16939
|
+
required,
|
|
16940
|
+
disabled,
|
|
16941
|
+
onInvalid: (e) => {
|
|
16942
|
+
e.preventDefault();
|
|
16943
|
+
setLocalRequiredError(tv("required"));
|
|
16944
|
+
},
|
|
16945
|
+
className: "pointer-events-none absolute h-0 w-0 opacity-0"
|
|
16946
|
+
}
|
|
16947
|
+
),
|
|
16664
16948
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
16665
16949
|
"div",
|
|
16666
16950
|
{
|
|
@@ -16680,6 +16964,23 @@ function CategoryTreeSelect(props) {
|
|
|
16680
16964
|
if (inline) {
|
|
16681
16965
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("w-full space-y-2", className), children: [
|
|
16682
16966
|
renderLabel(),
|
|
16967
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
16968
|
+
"input",
|
|
16969
|
+
{
|
|
16970
|
+
tabIndex: -1,
|
|
16971
|
+
"aria-hidden": "true",
|
|
16972
|
+
value: valueArray.length > 0 ? "selected" : "",
|
|
16973
|
+
onChange: () => {
|
|
16974
|
+
},
|
|
16975
|
+
required,
|
|
16976
|
+
disabled,
|
|
16977
|
+
onInvalid: (e) => {
|
|
16978
|
+
e.preventDefault();
|
|
16979
|
+
setLocalRequiredError(tv("required"));
|
|
16980
|
+
},
|
|
16981
|
+
className: "pointer-events-none absolute h-0 w-0 opacity-0"
|
|
16982
|
+
}
|
|
16983
|
+
),
|
|
16683
16984
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
16684
16985
|
"div",
|
|
16685
16986
|
{
|
|
@@ -16779,6 +17080,23 @@ function CategoryTreeSelect(props) {
|
|
|
16779
17080
|
] });
|
|
16780
17081
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("w-full space-y-2", className), children: [
|
|
16781
17082
|
renderLabel(),
|
|
17083
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
17084
|
+
"input",
|
|
17085
|
+
{
|
|
17086
|
+
tabIndex: -1,
|
|
17087
|
+
"aria-hidden": "true",
|
|
17088
|
+
value: valueArray.length > 0 ? "selected" : "",
|
|
17089
|
+
onChange: () => {
|
|
17090
|
+
},
|
|
17091
|
+
required,
|
|
17092
|
+
disabled,
|
|
17093
|
+
onInvalid: (e) => {
|
|
17094
|
+
e.preventDefault();
|
|
17095
|
+
setLocalRequiredError(tv("required"));
|
|
17096
|
+
},
|
|
17097
|
+
className: "pointer-events-none absolute h-0 w-0 opacity-0"
|
|
17098
|
+
}
|
|
17099
|
+
),
|
|
16782
17100
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
16783
17101
|
Popover,
|
|
16784
17102
|
{
|
|
@@ -16805,7 +17123,8 @@ function CategoryTreeSelect(props) {
|
|
|
16805
17123
|
"aria-controls": `${resolvedId}-tree`,
|
|
16806
17124
|
"aria-labelledby": labelId,
|
|
16807
17125
|
"aria-describedby": describedBy,
|
|
16808
|
-
"aria-
|
|
17126
|
+
"aria-required": required,
|
|
17127
|
+
"aria-invalid": !!effectiveError,
|
|
16809
17128
|
className: cn(
|
|
16810
17129
|
"group flex w-full items-center justify-between rounded-full transition-all duration-200",
|
|
16811
17130
|
"backdrop-blur-sm",
|
|
@@ -16814,7 +17133,7 @@ function CategoryTreeSelect(props) {
|
|
|
16814
17133
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
16815
17134
|
disabled && "opacity-50 cursor-not-allowed hover:transform-none hover:shadow-none",
|
|
16816
17135
|
isOpen && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
|
|
16817
|
-
|
|
17136
|
+
effectiveError && "border-destructive focus-visible:ring-destructive/30"
|
|
16818
17137
|
),
|
|
16819
17138
|
children: [
|
|
16820
17139
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2.5 text-left", children: [
|
|
@@ -20793,7 +21112,7 @@ function DataTableHeader({
|
|
|
20793
21112
|
className: cn(
|
|
20794
21113
|
"absolute inset-y-0 right-0 z-10 w-3 -mr-1",
|
|
20795
21114
|
"cursor-col-resize select-none bg-transparent",
|
|
20796
|
-
"after:absolute after:inset-y-2 after:right-
|
|
21115
|
+
"after:absolute after:inset-y-2 after:right-0.8 after:w-px after:bg-border/0 after:transition-colors",
|
|
20797
21116
|
"hover:after:bg-primary/50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary"
|
|
20798
21117
|
)
|
|
20799
21118
|
}
|
|
@@ -24023,7 +24342,7 @@ var TableInsertGrid = ({
|
|
|
24023
24342
|
onFocus: () => setSelection({ rows, cols }),
|
|
24024
24343
|
onClick: () => onInsert(rows, cols),
|
|
24025
24344
|
className: cn(
|
|
24026
|
-
"h-5 w-5 rounded-
|
|
24345
|
+
"h-5 w-5 rounded-sm border transition-colors",
|
|
24027
24346
|
active ? "border-primary bg-primary/20" : "border-border/70 bg-background hover:border-primary/60 hover:bg-primary/10"
|
|
24028
24347
|
)
|
|
24029
24348
|
},
|