@underverse-ui/underverse 1.0.79 → 1.0.81

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/index.cjs CHANGED
@@ -4051,7 +4051,7 @@ var EmojiPicker = ({
4051
4051
  className
4052
4052
  ),
4053
4053
  children: [
4054
- showSearch && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cn("shrink-0 border-b p-3", isEmbedded ? "bg-transparent" : "bg-muted/30"), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "relative", children: [
4054
+ showSearch && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "shrink-0 border-b p-3 bg-transparent", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "relative", children: [
4055
4055
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
4056
4056
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4057
4057
  "input",
@@ -4061,7 +4061,7 @@ var EmojiPicker = ({
4061
4061
  value: search,
4062
4062
  onChange: (e) => setSearch(e.target.value),
4063
4063
  className: cn(
4064
- "w-full rounded-full border border-border bg-background py-2 pl-9 pr-9 text-sm",
4064
+ "w-full rounded-full border border-border bg-background/90 py-2 pl-9 pr-9 text-sm shadow-sm",
4065
4065
  "placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/20"
4066
4066
  )
4067
4067
  }
@@ -7099,6 +7099,7 @@ var getOptionDisabled = (option) => {
7099
7099
  var findOptionByValue = (options, value) => {
7100
7100
  return options.find((opt) => getOptionValue(opt) === value);
7101
7101
  };
7102
+ var REQUIRED_ERROR_MESSAGE = "This field is required";
7102
7103
  var Combobox = ({
7103
7104
  id,
7104
7105
  options,
@@ -7131,8 +7132,8 @@ var Combobox = ({
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
- "li",
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
- role: "option",
7220
+ type: "button",
7215
7221
  tabIndex: -1,
7216
- "aria-selected": isSelected,
7217
- "aria-disabled": itemDisabled,
7218
- onClick: () => !itemDisabled && handleSelect(item),
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 cursor-pointer items-center rounded-full",
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
- `${itemValue}-${index}`
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-invalid": !!error,
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
- !!error && "border-destructive focus-visible:ring-destructive/30",
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,22 @@ 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
+ readOnly: true,
7482
+ value: hasValue ? "selected" : "",
7483
+ required,
7484
+ disabled,
7485
+ onInvalid: (e) => {
7486
+ e.preventDefault();
7487
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE);
7488
+ },
7489
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
7490
+ }
7491
+ ),
7471
7492
  usePortal ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7472
7493
  Popover,
7473
7494
  {
@@ -7484,17 +7505,26 @@ var Combobox = ({
7484
7505
  triggerButtonInline,
7485
7506
  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
7507
  ] }),
7487
- (helperText || error) && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("p", { className: cn("text-xs transition-colors duration-200 flex items-center gap-1.5", error ? "text-destructive" : "text-muted-foreground"), children: [
7488
- error && /* @__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)(
7489
- "path",
7490
- {
7491
- fillRule: "evenodd",
7492
- 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",
7493
- clipRule: "evenodd"
7494
- }
7495
- ) }),
7496
- error || helperText
7497
- ] })
7508
+ (helperText || effectiveError) && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7509
+ "p",
7510
+ {
7511
+ className: cn(
7512
+ "text-xs transition-colors duration-200 flex items-center gap-1.5",
7513
+ effectiveError ? "text-destructive" : "text-muted-foreground"
7514
+ ),
7515
+ children: [
7516
+ 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)(
7517
+ "path",
7518
+ {
7519
+ fillRule: "evenodd",
7520
+ 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",
7521
+ clipRule: "evenodd"
7522
+ }
7523
+ ) }),
7524
+ effectiveError || helperText
7525
+ ]
7526
+ }
7527
+ )
7498
7528
  ] });
7499
7529
  };
7500
7530
 
@@ -8166,6 +8196,7 @@ var import_lucide_react15 = require("lucide-react");
8166
8196
  var React28 = __toESM(require("react"), 1);
8167
8197
  var import_react19 = require("react");
8168
8198
  var import_jsx_runtime34 = require("react/jsx-runtime");
8199
+ var REQUIRED_ERROR_MESSAGE2 = "This field is required";
8169
8200
  var DatePicker = ({
8170
8201
  id,
8171
8202
  value,
@@ -8189,6 +8220,7 @@ var DatePicker = ({
8189
8220
  const [isOpen, setIsOpen] = React28.useState(false);
8190
8221
  const [viewDate, setViewDate] = React28.useState(value || /* @__PURE__ */ new Date());
8191
8222
  const [viewMode, setViewMode] = React28.useState("calendar");
8223
+ const [localRequiredError, setLocalRequiredError] = React28.useState();
8192
8224
  const triggerRef = React28.useRef(null);
8193
8225
  const wheelContainerRef = React28.useRef(null);
8194
8226
  const wheelDeltaRef = React28.useRef(0);
@@ -8274,6 +8306,11 @@ var DatePicker = ({
8274
8306
  setViewDate(/* @__PURE__ */ new Date());
8275
8307
  }
8276
8308
  }, [value]);
8309
+ React28.useEffect(() => {
8310
+ if (disabled || !required || value) {
8311
+ setLocalRequiredError(void 0);
8312
+ }
8313
+ }, [disabled, required, value]);
8277
8314
  React28.useEffect(() => {
8278
8315
  if (!isOpen) {
8279
8316
  setViewMode("calendar");
@@ -8288,6 +8325,7 @@ var DatePicker = ({
8288
8325
  selectedDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
8289
8326
  }
8290
8327
  onChange(selectedDate);
8328
+ setLocalRequiredError(void 0);
8291
8329
  setIsOpen(false);
8292
8330
  };
8293
8331
  const formatDateDisplay = (date) => {
@@ -8569,6 +8607,7 @@ var DatePicker = ({
8569
8607
  const labelSize = sizeStyles8[size].label;
8570
8608
  const radiusClass = size === "sm" ? "rounded-md" : "rounded-lg";
8571
8609
  const verticalGap = size === "sm" ? "space-y-1.5" : size === "lg" ? "space-y-2.5" : "space-y-2";
8610
+ const effectiveError = localRequiredError;
8572
8611
  return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: cn("w-full group", verticalGap), children: [
8573
8612
  label && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex items-center justify-between mb-2", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
8574
8613
  "label",
@@ -8580,6 +8619,7 @@ var DatePicker = ({
8580
8619
  labelSize,
8581
8620
  "font-semibold transition-colors duration-300 cursor-pointer",
8582
8621
  disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary hover:text-primary",
8622
+ effectiveError && "text-destructive",
8583
8623
  labelClassName
8584
8624
  ),
8585
8625
  children: [
@@ -8588,6 +8628,22 @@ var DatePicker = ({
8588
8628
  ]
8589
8629
  }
8590
8630
  ) }),
8631
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
8632
+ "input",
8633
+ {
8634
+ tabIndex: -1,
8635
+ "aria-hidden": "true",
8636
+ readOnly: true,
8637
+ value: value ? "selected" : "",
8638
+ required,
8639
+ disabled,
8640
+ onInvalid: (e) => {
8641
+ e.preventDefault();
8642
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE2);
8643
+ },
8644
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
8645
+ }
8646
+ ),
8591
8647
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
8592
8648
  Popover,
8593
8649
  {
@@ -8613,6 +8669,8 @@ var DatePicker = ({
8613
8669
  disabled,
8614
8670
  id: resolvedId,
8615
8671
  "aria-labelledby": labelId,
8672
+ "aria-required": required,
8673
+ "aria-invalid": !!effectiveError,
8616
8674
  className: cn(
8617
8675
  "group flex w-full items-center justify-between border bg-background/80 backdrop-blur-sm",
8618
8676
  "rounded-full",
@@ -8623,6 +8681,7 @@ var DatePicker = ({
8623
8681
  "hover:bg-accent/10 hover:shadow-lg hover:shadow-primary/5 hover:-translate-y-0.5",
8624
8682
  "transition-all duration-300 ease-out",
8625
8683
  isOpen && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
8684
+ effectiveError && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
8626
8685
  className
8627
8686
  ),
8628
8687
  children: [
@@ -8663,6 +8722,7 @@ var DatePicker = ({
8663
8722
  e.preventDefault();
8664
8723
  e.stopPropagation();
8665
8724
  onChange(void 0);
8725
+ setLocalRequiredError(void 0);
8666
8726
  setViewDate(/* @__PURE__ */ new Date());
8667
8727
  }
8668
8728
  },
@@ -8687,7 +8747,8 @@ var DatePicker = ({
8687
8747
  ),
8688
8748
  children: datePickerContent
8689
8749
  }
8690
- )
8750
+ ),
8751
+ effectiveError && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "text-xs text-destructive", children: effectiveError })
8691
8752
  ] });
8692
8753
  };
8693
8754
  var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select date range...", className, disablePastDates = false, minDate, maxDate, size = "md" }) => {
@@ -9031,6 +9092,7 @@ var React30 = __toESM(require("react"), 1);
9031
9092
  var React29 = __toESM(require("react"), 1);
9032
9093
  var import_lucide_react16 = require("lucide-react");
9033
9094
  var import_jsx_runtime35 = require("react/jsx-runtime");
9095
+ var REQUIRED_ERROR_MESSAGE3 = "This field is required";
9034
9096
  var DEFAULT_MONTH_NAMES = [
9035
9097
  "January",
9036
9098
  "February",
@@ -9524,6 +9586,7 @@ function MonthYearPicker({
9524
9586
  const [open, setOpen] = React29.useState(false);
9525
9587
  const [parts, setParts] = React29.useState(initial);
9526
9588
  const [focusedColumn, setFocusedColumn] = React29.useState(null);
9589
+ const [localRequiredError, setLocalRequiredError] = React29.useState();
9527
9590
  const monthScrollRef = React29.useRef(null);
9528
9591
  const yearScrollRef = React29.useRef(null);
9529
9592
  React29.useEffect(() => {
@@ -9532,6 +9595,13 @@ function MonthYearPicker({
9532
9595
  if (parsed) setParts(parsed);
9533
9596
  }
9534
9597
  }, [value, isControlled]);
9598
+ const hasValue = isControlled ? !!value : !!defaultValue || parts !== initial;
9599
+ const effectiveError = error ?? localRequiredError;
9600
+ React29.useEffect(() => {
9601
+ if (disabled || !required || hasValue) {
9602
+ setLocalRequiredError(void 0);
9603
+ }
9604
+ }, [disabled, hasValue, required]);
9535
9605
  const years = React29.useMemo(() => {
9536
9606
  return Array.from({ length: resolvedMaxYear - resolvedMinYear + 1 }, (_, i) => resolvedMinYear + i);
9537
9607
  }, [resolvedMinYear, resolvedMaxYear]);
@@ -9555,11 +9625,13 @@ function MonthYearPicker({
9555
9625
  const emit = React29.useCallback(
9556
9626
  (next) => {
9557
9627
  if (!next) {
9628
+ setLocalRequiredError(void 0);
9558
9629
  onChange?.(void 0);
9559
9630
  return;
9560
9631
  }
9561
9632
  if (!isDateInRange(next.month, next.year)) return;
9562
9633
  const date = new Date(next.year, next.month, 1);
9634
+ setLocalRequiredError(void 0);
9563
9635
  onChange?.({ ...next, date });
9564
9636
  },
9565
9637
  [isDateInRange, onChange]
@@ -9634,7 +9706,6 @@ function MonthYearPicker({
9634
9706
  const monthIndex = parts.month;
9635
9707
  const yearIndex = years.indexOf(parts.year);
9636
9708
  const display = `${shortMonthNames[parts.month]} ${parts.year}`;
9637
- const hasValue = isControlled ? !!value : !!defaultValue || parts !== initial;
9638
9709
  const trigger = variant === "inline" ? null : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
9639
9710
  "button",
9640
9711
  {
@@ -9643,6 +9714,8 @@ function MonthYearPicker({
9643
9714
  "aria-label": "Select month and year",
9644
9715
  "aria-haspopup": "dialog",
9645
9716
  "aria-expanded": open,
9717
+ "aria-required": required,
9718
+ "aria-invalid": !!effectiveError,
9646
9719
  className: cn(
9647
9720
  "group flex w-full items-center justify-between rounded-full border bg-background/80 backdrop-blur-sm",
9648
9721
  sz.height,
@@ -9651,9 +9724,9 @@ function MonthYearPicker({
9651
9724
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
9652
9725
  "disabled:opacity-50 disabled:cursor-not-allowed",
9653
9726
  "transition-all duration-300 ease-out",
9654
- error && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
9655
- success && "border-success/60 focus-visible:ring-success/50 bg-success/5",
9656
- !error && !success && "border-border/60 hover:border-primary/40 hover:bg-accent/10",
9727
+ effectiveError && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
9728
+ success && !effectiveError && "border-success/60 focus-visible:ring-success/50 bg-success/5",
9729
+ !effectiveError && !success && "border-border/60 hover:border-primary/40 hover:bg-accent/10",
9657
9730
  animate && !disabled && "hover:shadow-lg hover:shadow-primary/5 hover:-translate-y-0.5",
9658
9731
  open && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
9659
9732
  className
@@ -9665,7 +9738,7 @@ function MonthYearPicker({
9665
9738
  {
9666
9739
  className: cn(
9667
9740
  "flex items-center justify-center transition-colors duration-300",
9668
- error ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
9741
+ effectiveError ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
9669
9742
  ),
9670
9743
  children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react16.Calendar, { className: cn(sz.icon, "transition-transform duration-300", open && "rotate-12") })
9671
9744
  }
@@ -9800,19 +9873,61 @@ function MonthYearPicker({
9800
9873
  ] });
9801
9874
  if (variant === "inline") {
9802
9875
  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: [
9876
+ 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
9877
  label,
9805
9878
  required && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-destructive ml-0.5", children: "*" })
9806
9879
  ] }),
9807
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cn(panelSz.contentPadding, "rounded-2xl border border-border/50 bg-background/80 backdrop-blur-sm"), children: pickerContent }),
9808
- (helperText || error) && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cn("mt-1.5 text-xs", error ? "text-destructive" : "text-muted-foreground"), children: error || helperText })
9880
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
9881
+ "input",
9882
+ {
9883
+ tabIndex: -1,
9884
+ "aria-hidden": "true",
9885
+ readOnly: true,
9886
+ value: hasValue ? "selected" : "",
9887
+ required,
9888
+ disabled,
9889
+ onInvalid: (e) => {
9890
+ e.preventDefault();
9891
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE3);
9892
+ },
9893
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
9894
+ }
9895
+ ),
9896
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
9897
+ "div",
9898
+ {
9899
+ className: cn(
9900
+ panelSz.contentPadding,
9901
+ "rounded-2xl border bg-background/80 backdrop-blur-sm",
9902
+ effectiveError ? "border-destructive/60 bg-destructive/5" : "border-border/50"
9903
+ ),
9904
+ children: pickerContent
9905
+ }
9906
+ ),
9907
+ (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
9908
  ] });
9810
9909
  }
9811
9910
  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: [
9911
+ 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
9912
  label,
9814
9913
  required && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-destructive ml-0.5", children: "*" })
9815
9914
  ] }),
9915
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
9916
+ "input",
9917
+ {
9918
+ tabIndex: -1,
9919
+ "aria-hidden": "true",
9920
+ readOnly: true,
9921
+ value: hasValue ? "selected" : "",
9922
+ required,
9923
+ disabled,
9924
+ onInvalid: (e) => {
9925
+ e.preventDefault();
9926
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE3);
9927
+ },
9928
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
9929
+ }
9930
+ ),
9816
9931
  /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
9817
9932
  Popover,
9818
9933
  {
@@ -9827,7 +9942,7 @@ function MonthYearPicker({
9827
9942
  children: pickerContent
9828
9943
  }
9829
9944
  ),
9830
- (helperText || error) && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cn("mt-1.5 text-xs", error ? "text-destructive" : "text-muted-foreground"), children: error || helperText })
9945
+ (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
9946
  ] });
9832
9947
  }
9833
9948
 
@@ -10484,6 +10599,7 @@ function Calendar3({
10484
10599
  var React31 = __toESM(require("react"), 1);
10485
10600
  var import_lucide_react18 = require("lucide-react");
10486
10601
  var import_jsx_runtime37 = require("react/jsx-runtime");
10602
+ var REQUIRED_ERROR_MESSAGE4 = "This field is required";
10487
10603
  var pad = (n) => n.toString().padStart(2, "0");
10488
10604
  var clamp4 = (n, min, max) => Math.min(max, Math.max(min, n));
10489
10605
  var WHEEL_ITEM_HEIGHT2 = {
@@ -10974,6 +11090,8 @@ function TimePicker({
10974
11090
  const [parts, setParts] = React31.useState(initial);
10975
11091
  const [manualInput, setManualInput] = React31.useState("");
10976
11092
  const [focusedColumn, setFocusedColumn] = React31.useState(null);
11093
+ const [localRequiredError, setLocalRequiredError] = React31.useState();
11094
+ const [hasCommittedValue, setHasCommittedValue] = React31.useState(Boolean(isControlled ? value : defaultValue));
10977
11095
  const hourScrollRef = React31.useRef(null);
10978
11096
  const minuteScrollRef = React31.useRef(null);
10979
11097
  const secondScrollRef = React31.useRef(null);
@@ -10983,6 +11101,11 @@ function TimePicker({
10983
11101
  if (parsed) setParts(parsed);
10984
11102
  }
10985
11103
  }, [value, isControlled, format, includeSeconds]);
11104
+ React31.useEffect(() => {
11105
+ if (isControlled) {
11106
+ setHasCommittedValue(Boolean(value));
11107
+ }
11108
+ }, [isControlled, value]);
10986
11109
  const isTimeDisabled = React31.useCallback(
10987
11110
  (timeStr) => {
10988
11111
  if (!disabledTimes) return false;
@@ -11037,9 +11160,13 @@ function TimePicker({
11037
11160
  (next) => {
11038
11161
  const timeStr = next ? formatTime2(next, format, includeSeconds) : void 0;
11039
11162
  if (!canEmit(next)) return;
11163
+ setLocalRequiredError(void 0);
11164
+ if (!isControlled) {
11165
+ setHasCommittedValue(Boolean(next));
11166
+ }
11040
11167
  onChange?.(timeStr);
11041
11168
  },
11042
- [canEmit, format, includeSeconds, onChange]
11169
+ [canEmit, format, includeSeconds, isControlled, onChange]
11043
11170
  );
11044
11171
  const tryUpdate = React31.useCallback(
11045
11172
  (next) => {
@@ -11059,6 +11186,11 @@ function TimePicker({
11059
11186
  setFocusedColumn(null);
11060
11187
  }
11061
11188
  };
11189
+ React31.useEffect(() => {
11190
+ if (disabled || !required || hasCommittedValue) {
11191
+ setLocalRequiredError(void 0);
11192
+ }
11193
+ }, [disabled, hasCommittedValue, required]);
11062
11194
  const handleKeyDown2 = (e, column) => {
11063
11195
  if (!["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End", "PageUp", "PageDown"].includes(e.key)) return;
11064
11196
  e.preventDefault();
@@ -11201,6 +11333,7 @@ function TimePicker({
11201
11333
  const panelSz = panelSizeClasses[effectivePanelSize];
11202
11334
  const shouldMatchTriggerWidth = matchTriggerWidth ?? variant !== "compact";
11203
11335
  const compactPanel = variant === "compact";
11336
+ const effectiveError = error ?? localRequiredError;
11204
11337
  const display = formatTime2(parts, format, includeSeconds);
11205
11338
  const trigger = variant === "inline" ? null : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
11206
11339
  "button",
@@ -11210,6 +11343,8 @@ function TimePicker({
11210
11343
  "aria-label": "Select time",
11211
11344
  "aria-haspopup": "dialog",
11212
11345
  "aria-expanded": open,
11346
+ "aria-required": required,
11347
+ "aria-invalid": !!effectiveError,
11213
11348
  className: cn(
11214
11349
  "group flex w-full items-center justify-between rounded-full border bg-background/80 backdrop-blur-sm",
11215
11350
  sz.height,
@@ -11218,9 +11353,9 @@ function TimePicker({
11218
11353
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
11219
11354
  "disabled:opacity-50 disabled:cursor-not-allowed",
11220
11355
  "transition-all duration-300 ease-out",
11221
- error && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
11222
- success && "border-success/60 focus-visible:ring-success/50 bg-success/5",
11223
- !error && !success && "border-border/60 hover:border-primary/40 hover:bg-accent/10",
11356
+ effectiveError && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
11357
+ success && !effectiveError && "border-success/60 focus-visible:ring-success/50 bg-success/5",
11358
+ !effectiveError && !success && "border-border/60 hover:border-primary/40 hover:bg-accent/10",
11224
11359
  animate && !disabled && "hover:shadow-lg hover:shadow-primary/5 hover:-translate-y-0.5",
11225
11360
  open && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
11226
11361
  className
@@ -11232,7 +11367,7 @@ function TimePicker({
11232
11367
  {
11233
11368
  className: cn(
11234
11369
  "flex items-center justify-center transition-colors duration-300",
11235
- error ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
11370
+ effectiveError ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
11236
11371
  ),
11237
11372
  children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react18.Clock, { className: cn(sz.icon, "transition-transform duration-300", open && "rotate-12") })
11238
11373
  }
@@ -11519,17 +11654,39 @@ function TimePicker({
11519
11654
  ] });
11520
11655
  if (variant === "inline") {
11521
11656
  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: [
11657
+ 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
11658
  label,
11524
11659
  required && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-destructive ml-1", children: "*" })
11525
11660
  ] }) }),
11661
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
11662
+ "input",
11663
+ {
11664
+ tabIndex: -1,
11665
+ "aria-hidden": "true",
11666
+ readOnly: true,
11667
+ value: hasCommittedValue ? "selected" : "",
11668
+ required,
11669
+ disabled,
11670
+ onInvalid: (e) => {
11671
+ e.preventDefault();
11672
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE4);
11673
+ },
11674
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
11675
+ }
11676
+ ),
11526
11677
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
11527
11678
  "div",
11528
11679
  {
11529
- className: cn(panelSz.contentPadding, "rounded-2xl md:rounded-3xl border border-border/60 bg-card/95 backdrop-blur-sm shadow-xl", className),
11680
+ className: cn(
11681
+ panelSz.contentPadding,
11682
+ "rounded-2xl md:rounded-3xl border bg-card/95 backdrop-blur-sm shadow-xl",
11683
+ effectiveError ? "border-destructive/60 bg-destructive/5" : "border-border/60",
11684
+ className
11685
+ ),
11530
11686
  children: timePickerContent
11531
11687
  }
11532
- )
11688
+ ),
11689
+ effectiveError && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cn("mt-2", sz.label, "text-destructive"), children: effectiveError })
11533
11690
  ] });
11534
11691
  }
11535
11692
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "w-full", ...rest, children: [
@@ -11540,6 +11697,7 @@ function TimePicker({
11540
11697
  sz.label,
11541
11698
  "font-semibold",
11542
11699
  disabled ? "text-muted-foreground" : "text-foreground",
11700
+ effectiveError && "text-destructive",
11543
11701
  "cursor-pointer transition-colors hover:text-primary"
11544
11702
  ),
11545
11703
  onClick: () => !disabled && handleOpenChange(true),
@@ -11549,6 +11707,22 @@ function TimePicker({
11549
11707
  ]
11550
11708
  }
11551
11709
  ) }),
11710
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
11711
+ "input",
11712
+ {
11713
+ tabIndex: -1,
11714
+ "aria-hidden": "true",
11715
+ readOnly: true,
11716
+ value: hasCommittedValue ? "selected" : "",
11717
+ required,
11718
+ disabled,
11719
+ onInvalid: (e) => {
11720
+ e.preventDefault();
11721
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE4);
11722
+ },
11723
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
11724
+ }
11725
+ ),
11552
11726
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
11553
11727
  Popover,
11554
11728
  {
@@ -11562,30 +11736,31 @@ function TimePicker({
11562
11736
  panelSz.contentPadding,
11563
11737
  compactPanel && "max-w-[calc(100vw-2rem)] p-4 rounded-2xl",
11564
11738
  "rounded-2xl md:rounded-3xl border bg-popover/98 backdrop-blur-md shadow-2xl",
11565
- error && "border-destructive/40",
11566
- success && "border-success/40",
11567
- !error && !success && "border-border/60",
11739
+ effectiveError && "border-destructive/40",
11740
+ success && !effectiveError && "border-success/40",
11741
+ !effectiveError && !success && "border-border/60",
11568
11742
  animate && "animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-300"
11569
11743
  ),
11570
11744
  children: timePickerContent
11571
11745
  }
11572
11746
  ),
11573
- (error || success || helperText) && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cn("mt-2 flex items-start gap-2", sz.label), children: [
11574
- error && /* @__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: [
11747
+ (effectiveError || success || helperText) && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cn("mt-2 flex items-start gap-2", sz.label), children: [
11748
+ 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
11749
  /* @__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: error })
11750
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "font-medium", children: effectiveError })
11577
11751
  ] }),
11578
- success && !error && /* @__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: [
11752
+ 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
11753
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react18.Check, { className: "w-3.5 h-3.5 shrink-0" }),
11580
11754
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "font-medium", children: "Valid time selected" })
11581
11755
  ] }),
11582
- helperText && !error && !success && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-muted-foreground/80 italic", children: helperText })
11756
+ helperText && !effectiveError && !success && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-muted-foreground/80 italic", children: helperText })
11583
11757
  ] })
11584
11758
  ] });
11585
11759
  }
11586
11760
 
11587
11761
  // src/components/DateTimePicker.tsx
11588
11762
  var import_jsx_runtime38 = require("react/jsx-runtime");
11763
+ var REQUIRED_ERROR_MESSAGE5 = "This field is required";
11589
11764
  var DateTimePicker = ({
11590
11765
  value,
11591
11766
  onChange,
@@ -11606,6 +11781,7 @@ var DateTimePicker = ({
11606
11781
  const t = useSmartTranslations("DateTimePicker");
11607
11782
  const locale = useSmartLocale();
11608
11783
  const [open, setOpen] = React32.useState(false);
11784
+ const [localRequiredError, setLocalRequiredError] = React32.useState();
11609
11785
  const sizeStyles8 = {
11610
11786
  sm: {
11611
11787
  trigger: "h-8 px-2.5 py-1.5 text-sm md:h-7 md:text-xs",
@@ -11644,6 +11820,11 @@ var DateTimePicker = ({
11644
11820
  setTempDate(value);
11645
11821
  setCalendarMonth(value ?? /* @__PURE__ */ new Date());
11646
11822
  }, [value, open]);
11823
+ React32.useEffect(() => {
11824
+ if (disabled || !required || value) {
11825
+ setLocalRequiredError(void 0);
11826
+ }
11827
+ }, [disabled, required, value]);
11647
11828
  const getTimeString = (date) => {
11648
11829
  if (!date) return "";
11649
11830
  const h = date.getHours();
@@ -11700,11 +11881,13 @@ var DateTimePicker = ({
11700
11881
  };
11701
11882
  const handleApply = () => {
11702
11883
  onChange(tempDate);
11884
+ setLocalRequiredError(void 0);
11703
11885
  setOpen(false);
11704
11886
  };
11705
11887
  const handleClear = () => {
11706
11888
  onChange(void 0);
11707
11889
  setTempDate(void 0);
11890
+ setLocalRequiredError(void 0);
11708
11891
  setOpen(false);
11709
11892
  };
11710
11893
  const displayValue = value ? value.toLocaleString(locale === "vi" ? "vi-VN" : "en-US", {
@@ -11735,12 +11918,29 @@ var DateTimePicker = ({
11735
11918
  }
11736
11919
  };
11737
11920
  const weekdays = getWeekdays(locale);
11921
+ const effectiveError = localRequiredError;
11738
11922
  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: [
11923
+ 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
11924
  label,
11741
11925
  " ",
11742
11926
  required && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-destructive", children: "*" })
11743
11927
  ] }),
11928
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
11929
+ "input",
11930
+ {
11931
+ tabIndex: -1,
11932
+ "aria-hidden": "true",
11933
+ readOnly: true,
11934
+ value: value ? "selected" : "",
11935
+ required,
11936
+ disabled,
11937
+ onInvalid: (e) => {
11938
+ e.preventDefault();
11939
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE5);
11940
+ },
11941
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
11942
+ }
11943
+ ),
11744
11944
  /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
11745
11945
  Popover,
11746
11946
  {
@@ -11751,12 +11951,15 @@ var DateTimePicker = ({
11751
11951
  {
11752
11952
  type: "button",
11753
11953
  disabled,
11954
+ "aria-required": required,
11955
+ "aria-invalid": !!effectiveError,
11754
11956
  className: cn(
11755
11957
  "flex w-full items-center justify-between rounded-full border border-input bg-background",
11756
11958
  sizeStyles8[size].trigger,
11757
11959
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
11758
11960
  disabled && "opacity-50 cursor-not-allowed",
11759
- !displayValue && "text-muted-foreground"
11961
+ !displayValue && "text-muted-foreground",
11962
+ effectiveError && "border-destructive/60 bg-destructive/5"
11760
11963
  ),
11761
11964
  children: [
11762
11965
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "truncate", children: displayValue || placeholder || "Select date & time" }),
@@ -11769,6 +11972,7 @@ var DateTimePicker = ({
11769
11972
  onClick: (e) => {
11770
11973
  e.stopPropagation();
11771
11974
  onChange(void 0);
11975
+ setLocalRequiredError(void 0);
11772
11976
  },
11773
11977
  className: "hover:text-foreground p-0.5 rounded-md hover:bg-accent",
11774
11978
  children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react19.X, { className: sizeStyles8[size].icon })
@@ -11828,7 +12032,8 @@ var DateTimePicker = ({
11828
12032
  ] })
11829
12033
  ]
11830
12034
  }
11831
- )
12035
+ ),
12036
+ effectiveError && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "text-xs text-destructive", children: effectiveError })
11832
12037
  ] });
11833
12038
  };
11834
12039
 
@@ -14752,6 +14957,7 @@ var React39 = __toESM(require("react"), 1);
14752
14957
  var import_react20 = require("react");
14753
14958
  var import_lucide_react24 = require("lucide-react");
14754
14959
  var import_jsx_runtime45 = require("react/jsx-runtime");
14960
+ var REQUIRED_ERROR_MESSAGE6 = "This field is required";
14755
14961
  var MultiCombobox = ({
14756
14962
  id,
14757
14963
  options,
@@ -14788,6 +14994,7 @@ var MultiCombobox = ({
14788
14994
  const [query, setQuery] = React39.useState("");
14789
14995
  const [open, setOpen] = React39.useState(false);
14790
14996
  const [activeIndex, setActiveIndex] = React39.useState(null);
14997
+ const [localRequiredError, setLocalRequiredError] = React39.useState();
14791
14998
  const inputRef = React39.useRef(null);
14792
14999
  const listRef = React39.useRef([]);
14793
15000
  const optionsListRef = React39.useRef(null);
@@ -14824,6 +15031,7 @@ var MultiCombobox = ({
14824
15031
  onChange(value.filter((v) => v !== optionValue));
14825
15032
  } else {
14826
15033
  if (!maxSelected || value.length < maxSelected) {
15034
+ setLocalRequiredError(void 0);
14827
15035
  onChange([...value, optionValue]);
14828
15036
  }
14829
15037
  }
@@ -14843,6 +15051,12 @@ var MultiCombobox = ({
14843
15051
  const handleClearAll = () => {
14844
15052
  onChange([]);
14845
15053
  };
15054
+ const effectiveError = error ?? localRequiredError;
15055
+ React39.useEffect(() => {
15056
+ if (disabled || !required || value.length > 0) {
15057
+ setLocalRequiredError(void 0);
15058
+ }
15059
+ }, [disabled, required, value.length]);
14846
15060
  React39.useEffect(() => {
14847
15061
  if (open && enableSearch) {
14848
15062
  setTimeout(() => {
@@ -15053,7 +15267,8 @@ var MultiCombobox = ({
15053
15267
  "aria-haspopup": "listbox",
15054
15268
  "aria-expanded": open,
15055
15269
  "aria-controls": listboxId,
15056
- "aria-invalid": !!error,
15270
+ "aria-required": required,
15271
+ "aria-invalid": !!effectiveError,
15057
15272
  className: cn(
15058
15273
  "group flex w-full items-center gap-2 rounded-full transition-all duration-200",
15059
15274
  sizeStyles8[size].trigger,
@@ -15061,7 +15276,7 @@ var MultiCombobox = ({
15061
15276
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:border-primary",
15062
15277
  "disabled:cursor-not-allowed disabled:opacity-50",
15063
15278
  open && "ring-2 ring-primary/20 border-primary",
15064
- !!error && "border-destructive focus-visible:ring-destructive/30"
15279
+ !!effectiveError && "border-destructive focus-visible:ring-destructive/30"
15065
15280
  ),
15066
15281
  children: [
15067
15282
  /* @__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 +15372,7 @@ var MultiCombobox = ({
15157
15372
  size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm",
15158
15373
  "font-medium transition-colors duration-200",
15159
15374
  disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary",
15375
+ effectiveError && "text-destructive",
15160
15376
  labelClassName
15161
15377
  ),
15162
15378
  children: [
@@ -15174,6 +15390,7 @@ var MultiCombobox = ({
15174
15390
  labelSize,
15175
15391
  "font-medium transition-colors duration-200",
15176
15392
  disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary",
15393
+ effectiveError && "text-destructive",
15177
15394
  labelClassName
15178
15395
  ),
15179
15396
  children: [
@@ -15182,6 +15399,22 @@ var MultiCombobox = ({
15182
15399
  ]
15183
15400
  }
15184
15401
  ),
15402
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
15403
+ "input",
15404
+ {
15405
+ tabIndex: -1,
15406
+ "aria-hidden": "true",
15407
+ readOnly: true,
15408
+ value: value.length > 0 ? "selected" : "",
15409
+ required,
15410
+ disabled,
15411
+ onInvalid: (e) => {
15412
+ e.preventDefault();
15413
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE6);
15414
+ },
15415
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
15416
+ }
15417
+ ),
15185
15418
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
15186
15419
  Popover,
15187
15420
  {
@@ -15195,17 +15428,26 @@ var MultiCombobox = ({
15195
15428
  children: dropdownBody
15196
15429
  }
15197
15430
  ),
15198
- (helperText || error) && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: cn("text-xs transition-colors duration-200 flex items-center gap-1.5", error ? "text-destructive" : "text-muted-foreground"), children: [
15199
- error && /* @__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)(
15200
- "path",
15201
- {
15202
- fillRule: "evenodd",
15203
- 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",
15204
- clipRule: "evenodd"
15205
- }
15206
- ) }),
15207
- error || helperText
15208
- ] })
15431
+ (helperText || effectiveError) && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
15432
+ "p",
15433
+ {
15434
+ className: cn(
15435
+ "text-xs transition-colors duration-200 flex items-center gap-1.5",
15436
+ effectiveError ? "text-destructive" : "text-muted-foreground"
15437
+ ),
15438
+ children: [
15439
+ 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)(
15440
+ "path",
15441
+ {
15442
+ fillRule: "evenodd",
15443
+ 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",
15444
+ clipRule: "evenodd"
15445
+ }
15446
+ ) }),
15447
+ effectiveError || helperText
15448
+ ]
15449
+ }
15450
+ )
15209
15451
  ] });
15210
15452
  };
15211
15453
 
@@ -16343,6 +16585,7 @@ var defaultLabels = {
16343
16585
  searchPlaceholder: "Search...",
16344
16586
  noResultsText: "No results found"
16345
16587
  };
16588
+ var REQUIRED_ERROR_MESSAGE7 = "This field is required";
16346
16589
  function getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline) {
16347
16590
  if (!(viewOnly || inline) || !defaultExpanded) return /* @__PURE__ */ new Set();
16348
16591
  const parentIds = /* @__PURE__ */ new Set();
@@ -16381,14 +16624,16 @@ function CategoryTreeSelect(props) {
16381
16624
  const [isOpen, setIsOpen] = (0, import_react22.useState)(false);
16382
16625
  const [expandedNodes, setExpandedNodes] = (0, import_react22.useState)(() => getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline));
16383
16626
  const [query, setQuery] = (0, import_react22.useState)("");
16627
+ const [localRequiredError, setLocalRequiredError] = (0, import_react22.useState)();
16384
16628
  const searchInputRef = (0, import_react22.useRef)(null);
16385
16629
  const dropdownViewportRef = (0, import_react22.useRef)(null);
16386
16630
  useOverlayScrollbarTarget(dropdownViewportRef, { enabled: useOverlayScrollbar });
16387
16631
  const autoId = (0, import_react22.useId)();
16388
16632
  const resolvedId = id ? String(id) : `category-tree-select-${autoId}`;
16389
16633
  const labelId = label ? `${resolvedId}-label` : void 0;
16390
- const helperId = helperText && !error ? `${resolvedId}-helper` : void 0;
16391
- const errorId = error ? `${resolvedId}-error` : void 0;
16634
+ const effectiveError = error ?? localRequiredError;
16635
+ const helperId = helperText && !effectiveError ? `${resolvedId}-helper` : void 0;
16636
+ const errorId = effectiveError ? `${resolvedId}-error` : void 0;
16392
16637
  const describedBy = errorId || helperId;
16393
16638
  const mergedLabels = { ...defaultLabels, ...labels };
16394
16639
  const valueArray = (0, import_react22.useMemo)(
@@ -16459,6 +16704,11 @@ function CategoryTreeSelect(props) {
16459
16704
  const t = setTimeout(() => searchInputRef.current?.focus(), 50);
16460
16705
  return () => clearTimeout(t);
16461
16706
  }, [isOpen, isSearchEnabled]);
16707
+ (0, import_react22.useEffect)(() => {
16708
+ if (disabled || !required || valueArray.length > 0) {
16709
+ setLocalRequiredError(void 0);
16710
+ }
16711
+ }, [disabled, required, valueArray.length]);
16462
16712
  const toggleExpand = (id2) => {
16463
16713
  if (isSearchMode) return;
16464
16714
  const newExpanded = new Set(expandedNodes);
@@ -16477,6 +16727,7 @@ function CategoryTreeSelect(props) {
16477
16727
  toggleExpand(categoryId);
16478
16728
  return;
16479
16729
  }
16730
+ setLocalRequiredError(void 0);
16480
16731
  if (!props.onChange) return;
16481
16732
  if (singleSelect) {
16482
16733
  const onChange = props.onChange;
@@ -16584,7 +16835,7 @@ function CategoryTreeSelect(props) {
16584
16835
  };
16585
16836
  const renderSearch = ({ sticky = true, className: className2 } = {}) => {
16586
16837
  if (!isSearchEnabled) return null;
16587
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: cn(sticky && "sticky top-0 z-10 bg-popover/85 pb-2 backdrop-blur-xl", className2), children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "relative", children: [
16838
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: cn(sticky && "sticky top-0 z-10 pb-2", className2), children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "relative", children: [
16588
16839
  /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react26.Search, { className: "absolute left-3.5 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground/60 transition-colors peer-focus:text-primary" }),
16589
16840
  /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16590
16841
  "input",
@@ -16594,7 +16845,7 @@ function CategoryTreeSelect(props) {
16594
16845
  onChange: (e) => setQuery(e.target.value),
16595
16846
  placeholder: mergedLabels.searchPlaceholder,
16596
16847
  className: cn(
16597
- "peer w-full rounded-full bg-muted/40 py-2.5 pl-10 pr-10 text-sm",
16848
+ "peer w-full rounded-full bg-background/90 py-2.5 pl-10 pr-10 text-sm shadow-sm",
16598
16849
  "border border-border/30",
16599
16850
  "focus:outline-none focus:bg-background focus:border-primary/30 focus:ring-2 focus:ring-primary/10",
16600
16851
  "transition-all duration-200",
@@ -16648,7 +16899,7 @@ function CategoryTreeSelect(props) {
16648
16899
  className: cn(
16649
16900
  size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm",
16650
16901
  disabled ? "text-muted-foreground" : "text-foreground",
16651
- error && "text-destructive",
16902
+ effectiveError && "text-destructive",
16652
16903
  labelClassName
16653
16904
  ),
16654
16905
  children: [
@@ -16657,10 +16908,26 @@ function CategoryTreeSelect(props) {
16657
16908
  ]
16658
16909
  }
16659
16910
  ) }) : null;
16660
- const renderAssistiveText = () => error ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { id: errorId, className: "text-sm text-destructive", children: error }) : helperText ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { id: helperId, className: "text-sm text-muted-foreground", children: helperText }) : null;
16911
+ 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
16912
  if (viewOnly) {
16662
16913
  return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("w-full space-y-2", className), children: [
16663
16914
  renderLabel(),
16915
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16916
+ "input",
16917
+ {
16918
+ tabIndex: -1,
16919
+ "aria-hidden": "true",
16920
+ readOnly: true,
16921
+ value: valueArray.length > 0 ? "selected" : "",
16922
+ required,
16923
+ disabled,
16924
+ onInvalid: (e) => {
16925
+ e.preventDefault();
16926
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE7);
16927
+ },
16928
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
16929
+ }
16930
+ ),
16664
16931
  /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
16665
16932
  "div",
16666
16933
  {
@@ -16680,6 +16947,22 @@ function CategoryTreeSelect(props) {
16680
16947
  if (inline) {
16681
16948
  return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("w-full space-y-2", className), children: [
16682
16949
  renderLabel(),
16950
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16951
+ "input",
16952
+ {
16953
+ tabIndex: -1,
16954
+ "aria-hidden": "true",
16955
+ readOnly: true,
16956
+ value: valueArray.length > 0 ? "selected" : "",
16957
+ required,
16958
+ disabled,
16959
+ onInvalid: (e) => {
16960
+ e.preventDefault();
16961
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE7);
16962
+ },
16963
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
16964
+ }
16965
+ ),
16683
16966
  /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
16684
16967
  "div",
16685
16968
  {
@@ -16779,6 +17062,22 @@ function CategoryTreeSelect(props) {
16779
17062
  ] });
16780
17063
  return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("w-full space-y-2", className), children: [
16781
17064
  renderLabel(),
17065
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
17066
+ "input",
17067
+ {
17068
+ tabIndex: -1,
17069
+ "aria-hidden": "true",
17070
+ readOnly: true,
17071
+ value: valueArray.length > 0 ? "selected" : "",
17072
+ required,
17073
+ disabled,
17074
+ onInvalid: (e) => {
17075
+ e.preventDefault();
17076
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE7);
17077
+ },
17078
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
17079
+ }
17080
+ ),
16782
17081
  /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16783
17082
  Popover,
16784
17083
  {
@@ -16805,7 +17104,8 @@ function CategoryTreeSelect(props) {
16805
17104
  "aria-controls": `${resolvedId}-tree`,
16806
17105
  "aria-labelledby": labelId,
16807
17106
  "aria-describedby": describedBy,
16808
- "aria-invalid": !!error,
17107
+ "aria-required": required,
17108
+ "aria-invalid": !!effectiveError,
16809
17109
  className: cn(
16810
17110
  "group flex w-full items-center justify-between rounded-full transition-all duration-200",
16811
17111
  "backdrop-blur-sm",
@@ -16814,7 +17114,7 @@ function CategoryTreeSelect(props) {
16814
17114
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
16815
17115
  disabled && "opacity-50 cursor-not-allowed hover:transform-none hover:shadow-none",
16816
17116
  isOpen && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
16817
- error && "border-destructive focus-visible:ring-destructive/30"
17117
+ effectiveError && "border-destructive focus-visible:ring-destructive/30"
16818
17118
  ),
16819
17119
  children: [
16820
17120
  /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2.5 text-left", children: [
@@ -20793,7 +21093,7 @@ function DataTableHeader({
20793
21093
  className: cn(
20794
21094
  "absolute inset-y-0 right-0 z-10 w-3 -mr-1",
20795
21095
  "cursor-col-resize select-none bg-transparent",
20796
- "after:absolute after:inset-y-2 after:right-[3px] after:w-px after:bg-border/0 after:transition-colors",
21096
+ "after:absolute after:inset-y-2 after:right-0.8 after:w-px after:bg-border/0 after:transition-colors",
20797
21097
  "hover:after:bg-primary/50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary"
20798
21098
  )
20799
21099
  }
@@ -24023,7 +24323,7 @@ var TableInsertGrid = ({
24023
24323
  onFocus: () => setSelection({ rows, cols }),
24024
24324
  onClick: () => onInsert(rows, cols),
24025
24325
  className: cn(
24026
- "h-5 w-5 rounded-[4px] border transition-colors",
24326
+ "h-5 w-5 rounded-sm border transition-colors",
24027
24327
  active ? "border-primary bg-primary/20" : "border-border/70 bg-background hover:border-primary/60 hover:bg-primary/10"
24028
24328
  )
24029
24329
  },