@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.js CHANGED
@@ -3866,7 +3866,7 @@ var EmojiPicker = ({
3866
3866
  className
3867
3867
  ),
3868
3868
  children: [
3869
- showSearch && /* @__PURE__ */ jsx12("div", { className: cn("shrink-0 border-b p-3", isEmbedded ? "bg-transparent" : "bg-muted/30"), children: /* @__PURE__ */ jsxs7("div", { className: "relative", children: [
3869
+ showSearch && /* @__PURE__ */ jsx12("div", { className: "shrink-0 border-b p-3 bg-transparent", children: /* @__PURE__ */ jsxs7("div", { className: "relative", children: [
3870
3870
  /* @__PURE__ */ jsx12(Search2, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
3871
3871
  /* @__PURE__ */ jsx12(
3872
3872
  "input",
@@ -3876,7 +3876,7 @@ var EmojiPicker = ({
3876
3876
  value: search,
3877
3877
  onChange: (e) => setSearch(e.target.value),
3878
3878
  className: cn(
3879
- "w-full rounded-full border border-border bg-background py-2 pl-9 pr-9 text-sm",
3879
+ "w-full rounded-full border border-border bg-background/90 py-2 pl-9 pr-9 text-sm shadow-sm",
3880
3880
  "placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/20"
3881
3881
  )
3882
3882
  }
@@ -6914,6 +6914,7 @@ var getOptionDisabled = (option) => {
6914
6914
  var findOptionByValue = (options, value) => {
6915
6915
  return options.find((opt) => getOptionValue(opt) === value);
6916
6916
  };
6917
+ var REQUIRED_ERROR_MESSAGE = "This field is required";
6917
6918
  var Combobox = ({
6918
6919
  id,
6919
6920
  options,
@@ -6946,8 +6947,8 @@ var Combobox = ({
6946
6947
  const [open, setOpen] = React24.useState(false);
6947
6948
  const [query, setQuery] = React24.useState("");
6948
6949
  const [activeIndex, setActiveIndex] = React24.useState(null);
6950
+ const [localRequiredError, setLocalRequiredError] = React24.useState();
6949
6951
  useShadCNAnimations();
6950
- const listRef = React24.useRef([]);
6951
6952
  const inputRef = React24.useRef(null);
6952
6953
  const optionsViewportRef = React24.useRef(null);
6953
6954
  useOverlayScrollbarTarget(optionsViewportRef, { enabled: useOverlayScrollbar });
@@ -6964,6 +6965,7 @@ var Combobox = ({
6964
6965
  if (getOptionDisabled(option)) return;
6965
6966
  const val = getOptionValue(option);
6966
6967
  if (val !== void 0 && val !== null) {
6968
+ setLocalRequiredError(void 0);
6967
6969
  onChange(val);
6968
6970
  setOpen(false);
6969
6971
  triggerRef.current?.focus();
@@ -6987,6 +6989,13 @@ var Combobox = ({
6987
6989
  const selectedOption = findOptionByValue(options, value);
6988
6990
  const displayValue = selectedOption ? getOptionLabel(selectedOption) : "";
6989
6991
  const selectedIcon = selectedOption ? getOptionIcon(selectedOption) : void 0;
6992
+ const hasValue = value !== void 0 && value !== null && value !== "";
6993
+ const effectiveError = error ?? localRequiredError;
6994
+ React24.useEffect(() => {
6995
+ if (disabled || !required || hasValue) {
6996
+ setLocalRequiredError(void 0);
6997
+ }
6998
+ }, [disabled, hasValue, required]);
6990
6999
  const groupedOptions = React24.useMemo(() => {
6991
7000
  if (!groupBy) return null;
6992
7001
  const groups = {};
@@ -7019,27 +7028,24 @@ var Combobox = ({
7019
7028
  const itemDescription = getOptionDescription(item);
7020
7029
  const itemDisabled = getOptionDisabled(item);
7021
7030
  const isSelected = itemValue === value;
7022
- return /* @__PURE__ */ jsxs22(
7023
- "li",
7031
+ return /* @__PURE__ */ jsx29("li", { className: "list-none", children: /* @__PURE__ */ jsxs22(
7032
+ "button",
7024
7033
  {
7025
- ref: (node) => {
7026
- listRef.current[index] = node;
7027
- },
7028
7034
  id: `combobox-item-${index}`,
7029
- role: "option",
7035
+ type: "button",
7030
7036
  tabIndex: -1,
7031
- "aria-selected": isSelected,
7032
- "aria-disabled": itemDisabled,
7033
- onClick: () => !itemDisabled && handleSelect(item),
7037
+ disabled: itemDisabled,
7038
+ "aria-pressed": isSelected,
7039
+ onClick: () => handleSelect(item),
7034
7040
  style: {
7035
7041
  animationDelay: open ? `${Math.min(index * 15, 150)}ms` : "0ms"
7036
7042
  },
7037
7043
  className: cn(
7038
- "dropdown-item group flex cursor-pointer items-center rounded-full",
7044
+ "dropdown-item group flex w-full items-center rounded-full text-left",
7039
7045
  itemSizeStyles[size],
7040
7046
  "outline-none focus:outline-none focus-visible:outline-none",
7041
7047
  "transition-all duration-150",
7042
- !itemDisabled && "hover:bg-accent/70 hover:shadow-sm",
7048
+ !itemDisabled && "cursor-pointer hover:bg-accent/70 hover:shadow-sm",
7043
7049
  !itemDisabled && "focus:bg-accent/80 focus:text-accent-foreground",
7044
7050
  index === activeIndex && !itemDisabled && "bg-accent/60",
7045
7051
  isSelected && "bg-primary/10 text-primary font-medium",
@@ -7059,16 +7065,14 @@ var Combobox = ({
7059
7065
  ] }),
7060
7066
  isSelected && showSelectedIcon && /* @__PURE__ */ jsx29("span", { className: "shrink-0 ml-auto", children: /* @__PURE__ */ jsx29(Check3, { className: cn(checkIconSizeStyles[size], "text-primary") }) })
7061
7067
  ]
7062
- },
7063
- `${itemValue}-${index}`
7064
- );
7068
+ }
7069
+ ) }, `${itemValue}-${index}`);
7065
7070
  };
7066
7071
  const dropdownBody = /* @__PURE__ */ jsxs22(
7067
7072
  "div",
7068
7073
  {
7069
7074
  "data-combobox-dropdown": true,
7070
7075
  "data-state": open ? "open" : "closed",
7071
- role: "listbox",
7072
7076
  id: `${resolvedId}-listbox`,
7073
7077
  className: "w-full rounded-2xl md:rounded-3xl overflow-hidden",
7074
7078
  children: [
@@ -7123,8 +7127,7 @@ var Combobox = ({
7123
7127
  "transition-all duration-200",
7124
7128
  "placeholder:text-muted-foreground/50"
7125
7129
  ),
7126
- "aria-autocomplete": "list",
7127
- "aria-activedescendant": activeIndex != null ? `combobox-item-${activeIndex}` : void 0
7130
+ "aria-autocomplete": "list"
7128
7131
  }
7129
7132
  ),
7130
7133
  query && /* @__PURE__ */ jsx29(
@@ -7196,7 +7199,8 @@ var Combobox = ({
7196
7199
  "aria-haspopup": "listbox",
7197
7200
  "aria-expanded": open,
7198
7201
  "aria-controls": `${resolvedId}-listbox`,
7199
- "aria-invalid": !!error,
7202
+ "aria-required": required,
7203
+ "aria-invalid": !!effectiveError,
7200
7204
  id: resolvedId,
7201
7205
  "aria-labelledby": labelId,
7202
7206
  onKeyDown: (e) => {
@@ -7217,7 +7221,7 @@ var Combobox = ({
7217
7221
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:border-primary",
7218
7222
  "disabled:cursor-not-allowed disabled:opacity-50",
7219
7223
  open && "ring-2 ring-primary/20 border-primary",
7220
- !!error && "border-destructive focus-visible:ring-destructive/30",
7224
+ !!effectiveError && "border-destructive focus-visible:ring-destructive/30",
7221
7225
  className
7222
7226
  )
7223
7227
  };
@@ -7275,6 +7279,7 @@ var Combobox = ({
7275
7279
  labelSize,
7276
7280
  "font-medium transition-colors duration-200",
7277
7281
  disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary",
7282
+ effectiveError && "text-destructive",
7278
7283
  labelClassName
7279
7284
  ),
7280
7285
  children: [
@@ -7283,6 +7288,22 @@ var Combobox = ({
7283
7288
  ]
7284
7289
  }
7285
7290
  ) }),
7291
+ /* @__PURE__ */ jsx29(
7292
+ "input",
7293
+ {
7294
+ tabIndex: -1,
7295
+ "aria-hidden": "true",
7296
+ readOnly: true,
7297
+ value: hasValue ? "selected" : "",
7298
+ required,
7299
+ disabled,
7300
+ onInvalid: (e) => {
7301
+ e.preventDefault();
7302
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE);
7303
+ },
7304
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
7305
+ }
7306
+ ),
7286
7307
  usePortal ? /* @__PURE__ */ jsx29(
7287
7308
  Popover,
7288
7309
  {
@@ -7299,17 +7320,26 @@ var Combobox = ({
7299
7320
  triggerButtonInline,
7300
7321
  open && /* @__PURE__ */ jsx29("div", { className: "absolute left-0 top-full mt-1 z-50 w-full", children: /* @__PURE__ */ jsx29("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 }) })
7301
7322
  ] }),
7302
- (helperText || error) && /* @__PURE__ */ jsxs22("p", { className: cn("text-xs transition-colors duration-200 flex items-center gap-1.5", error ? "text-destructive" : "text-muted-foreground"), children: [
7303
- error && /* @__PURE__ */ jsx29("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__ */ jsx29(
7304
- "path",
7305
- {
7306
- fillRule: "evenodd",
7307
- 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",
7308
- clipRule: "evenodd"
7309
- }
7310
- ) }),
7311
- error || helperText
7312
- ] })
7323
+ (helperText || effectiveError) && /* @__PURE__ */ jsxs22(
7324
+ "p",
7325
+ {
7326
+ className: cn(
7327
+ "text-xs transition-colors duration-200 flex items-center gap-1.5",
7328
+ effectiveError ? "text-destructive" : "text-muted-foreground"
7329
+ ),
7330
+ children: [
7331
+ effectiveError && /* @__PURE__ */ jsx29("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__ */ jsx29(
7332
+ "path",
7333
+ {
7334
+ fillRule: "evenodd",
7335
+ 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",
7336
+ clipRule: "evenodd"
7337
+ }
7338
+ ) }),
7339
+ effectiveError || helperText
7340
+ ]
7341
+ }
7342
+ )
7313
7343
  ] });
7314
7344
  };
7315
7345
 
@@ -7981,6 +8011,7 @@ import { Calendar, ChevronLeft as ChevronLeft2, ChevronRight as ChevronRight3, S
7981
8011
  import * as React28 from "react";
7982
8012
  import { useId as useId6 } from "react";
7983
8013
  import { Fragment as Fragment6, jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
8014
+ var REQUIRED_ERROR_MESSAGE2 = "This field is required";
7984
8015
  var DatePicker = ({
7985
8016
  id,
7986
8017
  value,
@@ -8004,6 +8035,7 @@ var DatePicker = ({
8004
8035
  const [isOpen, setIsOpen] = React28.useState(false);
8005
8036
  const [viewDate, setViewDate] = React28.useState(value || /* @__PURE__ */ new Date());
8006
8037
  const [viewMode, setViewMode] = React28.useState("calendar");
8038
+ const [localRequiredError, setLocalRequiredError] = React28.useState();
8007
8039
  const triggerRef = React28.useRef(null);
8008
8040
  const wheelContainerRef = React28.useRef(null);
8009
8041
  const wheelDeltaRef = React28.useRef(0);
@@ -8089,6 +8121,11 @@ var DatePicker = ({
8089
8121
  setViewDate(/* @__PURE__ */ new Date());
8090
8122
  }
8091
8123
  }, [value]);
8124
+ React28.useEffect(() => {
8125
+ if (disabled || !required || value) {
8126
+ setLocalRequiredError(void 0);
8127
+ }
8128
+ }, [disabled, required, value]);
8092
8129
  React28.useEffect(() => {
8093
8130
  if (!isOpen) {
8094
8131
  setViewMode("calendar");
@@ -8103,6 +8140,7 @@ var DatePicker = ({
8103
8140
  selectedDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
8104
8141
  }
8105
8142
  onChange(selectedDate);
8143
+ setLocalRequiredError(void 0);
8106
8144
  setIsOpen(false);
8107
8145
  };
8108
8146
  const formatDateDisplay = (date) => {
@@ -8384,6 +8422,7 @@ var DatePicker = ({
8384
8422
  const labelSize = sizeStyles8[size].label;
8385
8423
  const radiusClass = size === "sm" ? "rounded-md" : "rounded-lg";
8386
8424
  const verticalGap = size === "sm" ? "space-y-1.5" : size === "lg" ? "space-y-2.5" : "space-y-2";
8425
+ const effectiveError = localRequiredError;
8387
8426
  return /* @__PURE__ */ jsxs24("div", { className: cn("w-full group", verticalGap), children: [
8388
8427
  label && /* @__PURE__ */ jsx34("div", { className: "flex items-center justify-between mb-2", children: /* @__PURE__ */ jsxs24(
8389
8428
  "label",
@@ -8395,6 +8434,7 @@ var DatePicker = ({
8395
8434
  labelSize,
8396
8435
  "font-semibold transition-colors duration-300 cursor-pointer",
8397
8436
  disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary hover:text-primary",
8437
+ effectiveError && "text-destructive",
8398
8438
  labelClassName
8399
8439
  ),
8400
8440
  children: [
@@ -8403,6 +8443,22 @@ var DatePicker = ({
8403
8443
  ]
8404
8444
  }
8405
8445
  ) }),
8446
+ /* @__PURE__ */ jsx34(
8447
+ "input",
8448
+ {
8449
+ tabIndex: -1,
8450
+ "aria-hidden": "true",
8451
+ readOnly: true,
8452
+ value: value ? "selected" : "",
8453
+ required,
8454
+ disabled,
8455
+ onInvalid: (e) => {
8456
+ e.preventDefault();
8457
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE2);
8458
+ },
8459
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
8460
+ }
8461
+ ),
8406
8462
  /* @__PURE__ */ jsx34(
8407
8463
  Popover,
8408
8464
  {
@@ -8428,6 +8484,8 @@ var DatePicker = ({
8428
8484
  disabled,
8429
8485
  id: resolvedId,
8430
8486
  "aria-labelledby": labelId,
8487
+ "aria-required": required,
8488
+ "aria-invalid": !!effectiveError,
8431
8489
  className: cn(
8432
8490
  "group flex w-full items-center justify-between border bg-background/80 backdrop-blur-sm",
8433
8491
  "rounded-full",
@@ -8438,6 +8496,7 @@ var DatePicker = ({
8438
8496
  "hover:bg-accent/10 hover:shadow-lg hover:shadow-primary/5 hover:-translate-y-0.5",
8439
8497
  "transition-all duration-300 ease-out",
8440
8498
  isOpen && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
8499
+ effectiveError && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
8441
8500
  className
8442
8501
  ),
8443
8502
  children: [
@@ -8478,6 +8537,7 @@ var DatePicker = ({
8478
8537
  e.preventDefault();
8479
8538
  e.stopPropagation();
8480
8539
  onChange(void 0);
8540
+ setLocalRequiredError(void 0);
8481
8541
  setViewDate(/* @__PURE__ */ new Date());
8482
8542
  }
8483
8543
  },
@@ -8502,7 +8562,8 @@ var DatePicker = ({
8502
8562
  ),
8503
8563
  children: datePickerContent
8504
8564
  }
8505
- )
8565
+ ),
8566
+ effectiveError && /* @__PURE__ */ jsx34("div", { className: "text-xs text-destructive", children: effectiveError })
8506
8567
  ] });
8507
8568
  };
8508
8569
  var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select date range...", className, disablePastDates = false, minDate, maxDate, size = "md" }) => {
@@ -8846,6 +8907,7 @@ import * as React30 from "react";
8846
8907
  import * as React29 from "react";
8847
8908
  import { Calendar as Calendar2, X as X10, Check as Check4, ChevronDown as ChevronDown2 } from "lucide-react";
8848
8909
  import { jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
8910
+ var REQUIRED_ERROR_MESSAGE3 = "This field is required";
8849
8911
  var DEFAULT_MONTH_NAMES = [
8850
8912
  "January",
8851
8913
  "February",
@@ -9339,6 +9401,7 @@ function MonthYearPicker({
9339
9401
  const [open, setOpen] = React29.useState(false);
9340
9402
  const [parts, setParts] = React29.useState(initial);
9341
9403
  const [focusedColumn, setFocusedColumn] = React29.useState(null);
9404
+ const [localRequiredError, setLocalRequiredError] = React29.useState();
9342
9405
  const monthScrollRef = React29.useRef(null);
9343
9406
  const yearScrollRef = React29.useRef(null);
9344
9407
  React29.useEffect(() => {
@@ -9347,6 +9410,13 @@ function MonthYearPicker({
9347
9410
  if (parsed) setParts(parsed);
9348
9411
  }
9349
9412
  }, [value, isControlled]);
9413
+ const hasValue = isControlled ? !!value : !!defaultValue || parts !== initial;
9414
+ const effectiveError = error ?? localRequiredError;
9415
+ React29.useEffect(() => {
9416
+ if (disabled || !required || hasValue) {
9417
+ setLocalRequiredError(void 0);
9418
+ }
9419
+ }, [disabled, hasValue, required]);
9350
9420
  const years = React29.useMemo(() => {
9351
9421
  return Array.from({ length: resolvedMaxYear - resolvedMinYear + 1 }, (_, i) => resolvedMinYear + i);
9352
9422
  }, [resolvedMinYear, resolvedMaxYear]);
@@ -9370,11 +9440,13 @@ function MonthYearPicker({
9370
9440
  const emit = React29.useCallback(
9371
9441
  (next) => {
9372
9442
  if (!next) {
9443
+ setLocalRequiredError(void 0);
9373
9444
  onChange?.(void 0);
9374
9445
  return;
9375
9446
  }
9376
9447
  if (!isDateInRange(next.month, next.year)) return;
9377
9448
  const date = new Date(next.year, next.month, 1);
9449
+ setLocalRequiredError(void 0);
9378
9450
  onChange?.({ ...next, date });
9379
9451
  },
9380
9452
  [isDateInRange, onChange]
@@ -9449,7 +9521,6 @@ function MonthYearPicker({
9449
9521
  const monthIndex = parts.month;
9450
9522
  const yearIndex = years.indexOf(parts.year);
9451
9523
  const display = `${shortMonthNames[parts.month]} ${parts.year}`;
9452
- const hasValue = isControlled ? !!value : !!defaultValue || parts !== initial;
9453
9524
  const trigger = variant === "inline" ? null : /* @__PURE__ */ jsxs25(
9454
9525
  "button",
9455
9526
  {
@@ -9458,6 +9529,8 @@ function MonthYearPicker({
9458
9529
  "aria-label": "Select month and year",
9459
9530
  "aria-haspopup": "dialog",
9460
9531
  "aria-expanded": open,
9532
+ "aria-required": required,
9533
+ "aria-invalid": !!effectiveError,
9461
9534
  className: cn(
9462
9535
  "group flex w-full items-center justify-between rounded-full border bg-background/80 backdrop-blur-sm",
9463
9536
  sz.height,
@@ -9466,9 +9539,9 @@ function MonthYearPicker({
9466
9539
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
9467
9540
  "disabled:opacity-50 disabled:cursor-not-allowed",
9468
9541
  "transition-all duration-300 ease-out",
9469
- error && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
9470
- success && "border-success/60 focus-visible:ring-success/50 bg-success/5",
9471
- !error && !success && "border-border/60 hover:border-primary/40 hover:bg-accent/10",
9542
+ effectiveError && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
9543
+ success && !effectiveError && "border-success/60 focus-visible:ring-success/50 bg-success/5",
9544
+ !effectiveError && !success && "border-border/60 hover:border-primary/40 hover:bg-accent/10",
9472
9545
  animate && !disabled && "hover:shadow-lg hover:shadow-primary/5 hover:-translate-y-0.5",
9473
9546
  open && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
9474
9547
  className
@@ -9480,7 +9553,7 @@ function MonthYearPicker({
9480
9553
  {
9481
9554
  className: cn(
9482
9555
  "flex items-center justify-center transition-colors duration-300",
9483
- error ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
9556
+ effectiveError ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
9484
9557
  ),
9485
9558
  children: /* @__PURE__ */ jsx35(Calendar2, { className: cn(sz.icon, "transition-transform duration-300", open && "rotate-12") })
9486
9559
  }
@@ -9615,19 +9688,61 @@ function MonthYearPicker({
9615
9688
  ] });
9616
9689
  if (variant === "inline") {
9617
9690
  return /* @__PURE__ */ jsxs25("div", { className: cn("w-full", className), ...rest, children: [
9618
- label && /* @__PURE__ */ jsxs25("label", { className: cn(sz.label, "block mb-1.5 font-medium text-foreground/80", labelClassName), children: [
9691
+ label && /* @__PURE__ */ jsxs25("label", { className: cn(sz.label, "block mb-1.5 font-medium text-foreground/80", effectiveError && "text-destructive", labelClassName), children: [
9619
9692
  label,
9620
9693
  required && /* @__PURE__ */ jsx35("span", { className: "text-destructive ml-0.5", children: "*" })
9621
9694
  ] }),
9622
- /* @__PURE__ */ jsx35("div", { className: cn(panelSz.contentPadding, "rounded-2xl border border-border/50 bg-background/80 backdrop-blur-sm"), children: pickerContent }),
9623
- (helperText || error) && /* @__PURE__ */ jsx35("div", { className: cn("mt-1.5 text-xs", error ? "text-destructive" : "text-muted-foreground"), children: error || helperText })
9695
+ /* @__PURE__ */ jsx35(
9696
+ "input",
9697
+ {
9698
+ tabIndex: -1,
9699
+ "aria-hidden": "true",
9700
+ readOnly: true,
9701
+ value: hasValue ? "selected" : "",
9702
+ required,
9703
+ disabled,
9704
+ onInvalid: (e) => {
9705
+ e.preventDefault();
9706
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE3);
9707
+ },
9708
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
9709
+ }
9710
+ ),
9711
+ /* @__PURE__ */ jsx35(
9712
+ "div",
9713
+ {
9714
+ className: cn(
9715
+ panelSz.contentPadding,
9716
+ "rounded-2xl border bg-background/80 backdrop-blur-sm",
9717
+ effectiveError ? "border-destructive/60 bg-destructive/5" : "border-border/50"
9718
+ ),
9719
+ children: pickerContent
9720
+ }
9721
+ ),
9722
+ (helperText || effectiveError) && /* @__PURE__ */ jsx35("div", { className: cn("mt-1.5 text-xs", effectiveError ? "text-destructive" : "text-muted-foreground"), children: effectiveError || helperText })
9624
9723
  ] });
9625
9724
  }
9626
9725
  return /* @__PURE__ */ jsxs25("div", { className: cn("w-full", className), ...rest, children: [
9627
- label && /* @__PURE__ */ jsxs25("label", { className: cn(sz.label, "block mb-1.5 font-medium text-foreground/80", labelClassName), children: [
9726
+ label && /* @__PURE__ */ jsxs25("label", { className: cn(sz.label, "block mb-1.5 font-medium text-foreground/80", effectiveError && "text-destructive", labelClassName), children: [
9628
9727
  label,
9629
9728
  required && /* @__PURE__ */ jsx35("span", { className: "text-destructive ml-0.5", children: "*" })
9630
9729
  ] }),
9730
+ /* @__PURE__ */ jsx35(
9731
+ "input",
9732
+ {
9733
+ tabIndex: -1,
9734
+ "aria-hidden": "true",
9735
+ readOnly: true,
9736
+ value: hasValue ? "selected" : "",
9737
+ required,
9738
+ disabled,
9739
+ onInvalid: (e) => {
9740
+ e.preventDefault();
9741
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE3);
9742
+ },
9743
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
9744
+ }
9745
+ ),
9631
9746
  /* @__PURE__ */ jsx35(
9632
9747
  Popover,
9633
9748
  {
@@ -9642,7 +9757,7 @@ function MonthYearPicker({
9642
9757
  children: pickerContent
9643
9758
  }
9644
9759
  ),
9645
- (helperText || error) && /* @__PURE__ */ jsx35("div", { className: cn("mt-1.5 text-xs", error ? "text-destructive" : "text-muted-foreground"), children: error || helperText })
9760
+ (helperText || effectiveError) && /* @__PURE__ */ jsx35("div", { className: cn("mt-1.5 text-xs", effectiveError ? "text-destructive" : "text-muted-foreground"), children: effectiveError || helperText })
9646
9761
  ] });
9647
9762
  }
9648
9763
 
@@ -10299,6 +10414,7 @@ function Calendar3({
10299
10414
  import * as React31 from "react";
10300
10415
  import { Clock as Clock2, X as X11, Check as Check5, Sun, Moon, Sunset, Coffee } from "lucide-react";
10301
10416
  import { Fragment as Fragment9, jsx as jsx37, jsxs as jsxs27 } from "react/jsx-runtime";
10417
+ var REQUIRED_ERROR_MESSAGE4 = "This field is required";
10302
10418
  var pad = (n) => n.toString().padStart(2, "0");
10303
10419
  var clamp4 = (n, min, max) => Math.min(max, Math.max(min, n));
10304
10420
  var WHEEL_ITEM_HEIGHT2 = {
@@ -10789,6 +10905,8 @@ function TimePicker({
10789
10905
  const [parts, setParts] = React31.useState(initial);
10790
10906
  const [manualInput, setManualInput] = React31.useState("");
10791
10907
  const [focusedColumn, setFocusedColumn] = React31.useState(null);
10908
+ const [localRequiredError, setLocalRequiredError] = React31.useState();
10909
+ const [hasCommittedValue, setHasCommittedValue] = React31.useState(Boolean(isControlled ? value : defaultValue));
10792
10910
  const hourScrollRef = React31.useRef(null);
10793
10911
  const minuteScrollRef = React31.useRef(null);
10794
10912
  const secondScrollRef = React31.useRef(null);
@@ -10798,6 +10916,11 @@ function TimePicker({
10798
10916
  if (parsed) setParts(parsed);
10799
10917
  }
10800
10918
  }, [value, isControlled, format, includeSeconds]);
10919
+ React31.useEffect(() => {
10920
+ if (isControlled) {
10921
+ setHasCommittedValue(Boolean(value));
10922
+ }
10923
+ }, [isControlled, value]);
10801
10924
  const isTimeDisabled = React31.useCallback(
10802
10925
  (timeStr) => {
10803
10926
  if (!disabledTimes) return false;
@@ -10852,9 +10975,13 @@ function TimePicker({
10852
10975
  (next) => {
10853
10976
  const timeStr = next ? formatTime2(next, format, includeSeconds) : void 0;
10854
10977
  if (!canEmit(next)) return;
10978
+ setLocalRequiredError(void 0);
10979
+ if (!isControlled) {
10980
+ setHasCommittedValue(Boolean(next));
10981
+ }
10855
10982
  onChange?.(timeStr);
10856
10983
  },
10857
- [canEmit, format, includeSeconds, onChange]
10984
+ [canEmit, format, includeSeconds, isControlled, onChange]
10858
10985
  );
10859
10986
  const tryUpdate = React31.useCallback(
10860
10987
  (next) => {
@@ -10874,6 +11001,11 @@ function TimePicker({
10874
11001
  setFocusedColumn(null);
10875
11002
  }
10876
11003
  };
11004
+ React31.useEffect(() => {
11005
+ if (disabled || !required || hasCommittedValue) {
11006
+ setLocalRequiredError(void 0);
11007
+ }
11008
+ }, [disabled, hasCommittedValue, required]);
10877
11009
  const handleKeyDown2 = (e, column) => {
10878
11010
  if (!["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End", "PageUp", "PageDown"].includes(e.key)) return;
10879
11011
  e.preventDefault();
@@ -11016,6 +11148,7 @@ function TimePicker({
11016
11148
  const panelSz = panelSizeClasses[effectivePanelSize];
11017
11149
  const shouldMatchTriggerWidth = matchTriggerWidth ?? variant !== "compact";
11018
11150
  const compactPanel = variant === "compact";
11151
+ const effectiveError = error ?? localRequiredError;
11019
11152
  const display = formatTime2(parts, format, includeSeconds);
11020
11153
  const trigger = variant === "inline" ? null : /* @__PURE__ */ jsxs27(
11021
11154
  "button",
@@ -11025,6 +11158,8 @@ function TimePicker({
11025
11158
  "aria-label": "Select time",
11026
11159
  "aria-haspopup": "dialog",
11027
11160
  "aria-expanded": open,
11161
+ "aria-required": required,
11162
+ "aria-invalid": !!effectiveError,
11028
11163
  className: cn(
11029
11164
  "group flex w-full items-center justify-between rounded-full border bg-background/80 backdrop-blur-sm",
11030
11165
  sz.height,
@@ -11033,9 +11168,9 @@ function TimePicker({
11033
11168
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
11034
11169
  "disabled:opacity-50 disabled:cursor-not-allowed",
11035
11170
  "transition-all duration-300 ease-out",
11036
- error && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
11037
- success && "border-success/60 focus-visible:ring-success/50 bg-success/5",
11038
- !error && !success && "border-border/60 hover:border-primary/40 hover:bg-accent/10",
11171
+ effectiveError && "border-destructive/60 focus-visible:ring-destructive/50 bg-destructive/5",
11172
+ success && !effectiveError && "border-success/60 focus-visible:ring-success/50 bg-success/5",
11173
+ !effectiveError && !success && "border-border/60 hover:border-primary/40 hover:bg-accent/10",
11039
11174
  animate && !disabled && "hover:shadow-lg hover:shadow-primary/5 hover:-translate-y-0.5",
11040
11175
  open && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
11041
11176
  className
@@ -11047,7 +11182,7 @@ function TimePicker({
11047
11182
  {
11048
11183
  className: cn(
11049
11184
  "flex items-center justify-center transition-colors duration-300",
11050
- error ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
11185
+ effectiveError ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
11051
11186
  ),
11052
11187
  children: /* @__PURE__ */ jsx37(Clock2, { className: cn(sz.icon, "transition-transform duration-300", open && "rotate-12") })
11053
11188
  }
@@ -11334,17 +11469,39 @@ function TimePicker({
11334
11469
  ] });
11335
11470
  if (variant === "inline") {
11336
11471
  return /* @__PURE__ */ jsxs27("div", { className: "w-fit max-w-full", ...rest, children: [
11337
- label && /* @__PURE__ */ jsx37("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ jsxs27("label", { className: cn(sz.label, "font-semibold", disabled ? "text-muted-foreground" : "text-foreground"), children: [
11472
+ label && /* @__PURE__ */ jsx37("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ jsxs27("label", { className: cn(sz.label, "font-semibold", disabled ? "text-muted-foreground" : "text-foreground", effectiveError && "text-destructive"), children: [
11338
11473
  label,
11339
11474
  required && /* @__PURE__ */ jsx37("span", { className: "text-destructive ml-1", children: "*" })
11340
11475
  ] }) }),
11476
+ /* @__PURE__ */ jsx37(
11477
+ "input",
11478
+ {
11479
+ tabIndex: -1,
11480
+ "aria-hidden": "true",
11481
+ readOnly: true,
11482
+ value: hasCommittedValue ? "selected" : "",
11483
+ required,
11484
+ disabled,
11485
+ onInvalid: (e) => {
11486
+ e.preventDefault();
11487
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE4);
11488
+ },
11489
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
11490
+ }
11491
+ ),
11341
11492
  /* @__PURE__ */ jsx37(
11342
11493
  "div",
11343
11494
  {
11344
- className: cn(panelSz.contentPadding, "rounded-2xl md:rounded-3xl border border-border/60 bg-card/95 backdrop-blur-sm shadow-xl", className),
11495
+ className: cn(
11496
+ panelSz.contentPadding,
11497
+ "rounded-2xl md:rounded-3xl border bg-card/95 backdrop-blur-sm shadow-xl",
11498
+ effectiveError ? "border-destructive/60 bg-destructive/5" : "border-border/60",
11499
+ className
11500
+ ),
11345
11501
  children: timePickerContent
11346
11502
  }
11347
- )
11503
+ ),
11504
+ effectiveError && /* @__PURE__ */ jsx37("div", { className: cn("mt-2", sz.label, "text-destructive"), children: effectiveError })
11348
11505
  ] });
11349
11506
  }
11350
11507
  return /* @__PURE__ */ jsxs27("div", { className: "w-full", ...rest, children: [
@@ -11355,6 +11512,7 @@ function TimePicker({
11355
11512
  sz.label,
11356
11513
  "font-semibold",
11357
11514
  disabled ? "text-muted-foreground" : "text-foreground",
11515
+ effectiveError && "text-destructive",
11358
11516
  "cursor-pointer transition-colors hover:text-primary"
11359
11517
  ),
11360
11518
  onClick: () => !disabled && handleOpenChange(true),
@@ -11364,6 +11522,22 @@ function TimePicker({
11364
11522
  ]
11365
11523
  }
11366
11524
  ) }),
11525
+ /* @__PURE__ */ jsx37(
11526
+ "input",
11527
+ {
11528
+ tabIndex: -1,
11529
+ "aria-hidden": "true",
11530
+ readOnly: true,
11531
+ value: hasCommittedValue ? "selected" : "",
11532
+ required,
11533
+ disabled,
11534
+ onInvalid: (e) => {
11535
+ e.preventDefault();
11536
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE4);
11537
+ },
11538
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
11539
+ }
11540
+ ),
11367
11541
  /* @__PURE__ */ jsx37(
11368
11542
  Popover,
11369
11543
  {
@@ -11377,30 +11551,31 @@ function TimePicker({
11377
11551
  panelSz.contentPadding,
11378
11552
  compactPanel && "max-w-[calc(100vw-2rem)] p-4 rounded-2xl",
11379
11553
  "rounded-2xl md:rounded-3xl border bg-popover/98 backdrop-blur-md shadow-2xl",
11380
- error && "border-destructive/40",
11381
- success && "border-success/40",
11382
- !error && !success && "border-border/60",
11554
+ effectiveError && "border-destructive/40",
11555
+ success && !effectiveError && "border-success/40",
11556
+ !effectiveError && !success && "border-border/60",
11383
11557
  animate && "animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-300"
11384
11558
  ),
11385
11559
  children: timePickerContent
11386
11560
  }
11387
11561
  ),
11388
- (error || success || helperText) && /* @__PURE__ */ jsxs27("div", { className: cn("mt-2 flex items-start gap-2", sz.label), children: [
11389
- error && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-2 text-destructive bg-destructive/10 px-3 py-1.5 rounded-lg", children: [
11562
+ (effectiveError || success || helperText) && /* @__PURE__ */ jsxs27("div", { className: cn("mt-2 flex items-start gap-2", sz.label), children: [
11563
+ effectiveError && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-2 text-destructive bg-destructive/10 px-3 py-1.5 rounded-lg", children: [
11390
11564
  /* @__PURE__ */ jsx37(X11, { className: "w-3.5 h-3.5 shrink-0" }),
11391
- /* @__PURE__ */ jsx37("span", { className: "font-medium", children: error })
11565
+ /* @__PURE__ */ jsx37("span", { className: "font-medium", children: effectiveError })
11392
11566
  ] }),
11393
- success && !error && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-2 text-success bg-success/10 px-3 py-1.5 rounded-lg", children: [
11567
+ success && !effectiveError && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-2 text-success bg-success/10 px-3 py-1.5 rounded-lg", children: [
11394
11568
  /* @__PURE__ */ jsx37(Check5, { className: "w-3.5 h-3.5 shrink-0" }),
11395
11569
  /* @__PURE__ */ jsx37("span", { className: "font-medium", children: "Valid time selected" })
11396
11570
  ] }),
11397
- helperText && !error && !success && /* @__PURE__ */ jsx37("span", { className: "text-muted-foreground/80 italic", children: helperText })
11571
+ helperText && !effectiveError && !success && /* @__PURE__ */ jsx37("span", { className: "text-muted-foreground/80 italic", children: helperText })
11398
11572
  ] })
11399
11573
  ] });
11400
11574
  }
11401
11575
 
11402
11576
  // src/components/DateTimePicker.tsx
11403
11577
  import { jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
11578
+ var REQUIRED_ERROR_MESSAGE5 = "This field is required";
11404
11579
  var DateTimePicker = ({
11405
11580
  value,
11406
11581
  onChange,
@@ -11421,6 +11596,7 @@ var DateTimePicker = ({
11421
11596
  const t = useSmartTranslations("DateTimePicker");
11422
11597
  const locale = useSmartLocale();
11423
11598
  const [open, setOpen] = React32.useState(false);
11599
+ const [localRequiredError, setLocalRequiredError] = React32.useState();
11424
11600
  const sizeStyles8 = {
11425
11601
  sm: {
11426
11602
  trigger: "h-8 px-2.5 py-1.5 text-sm md:h-7 md:text-xs",
@@ -11459,6 +11635,11 @@ var DateTimePicker = ({
11459
11635
  setTempDate(value);
11460
11636
  setCalendarMonth(value ?? /* @__PURE__ */ new Date());
11461
11637
  }, [value, open]);
11638
+ React32.useEffect(() => {
11639
+ if (disabled || !required || value) {
11640
+ setLocalRequiredError(void 0);
11641
+ }
11642
+ }, [disabled, required, value]);
11462
11643
  const getTimeString = (date) => {
11463
11644
  if (!date) return "";
11464
11645
  const h = date.getHours();
@@ -11515,11 +11696,13 @@ var DateTimePicker = ({
11515
11696
  };
11516
11697
  const handleApply = () => {
11517
11698
  onChange(tempDate);
11699
+ setLocalRequiredError(void 0);
11518
11700
  setOpen(false);
11519
11701
  };
11520
11702
  const handleClear = () => {
11521
11703
  onChange(void 0);
11522
11704
  setTempDate(void 0);
11705
+ setLocalRequiredError(void 0);
11523
11706
  setOpen(false);
11524
11707
  };
11525
11708
  const displayValue = value ? value.toLocaleString(locale === "vi" ? "vi-VN" : "en-US", {
@@ -11550,12 +11733,29 @@ var DateTimePicker = ({
11550
11733
  }
11551
11734
  };
11552
11735
  const weekdays = getWeekdays(locale);
11736
+ const effectiveError = localRequiredError;
11553
11737
  return /* @__PURE__ */ jsxs28("div", { className: cn("space-y-1.5", className), children: [
11554
- label && /* @__PURE__ */ jsxs28("label", { className: cn(sizeStyles8[size].label, "font-medium text-foreground flex items-center gap-1", labelClassName), children: [
11738
+ label && /* @__PURE__ */ jsxs28("label", { className: cn(sizeStyles8[size].label, "font-medium text-foreground flex items-center gap-1", effectiveError && "text-destructive", labelClassName), children: [
11555
11739
  label,
11556
11740
  " ",
11557
11741
  required && /* @__PURE__ */ jsx38("span", { className: "text-destructive", children: "*" })
11558
11742
  ] }),
11743
+ /* @__PURE__ */ jsx38(
11744
+ "input",
11745
+ {
11746
+ tabIndex: -1,
11747
+ "aria-hidden": "true",
11748
+ readOnly: true,
11749
+ value: value ? "selected" : "",
11750
+ required,
11751
+ disabled,
11752
+ onInvalid: (e) => {
11753
+ e.preventDefault();
11754
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE5);
11755
+ },
11756
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
11757
+ }
11758
+ ),
11559
11759
  /* @__PURE__ */ jsxs28(
11560
11760
  Popover,
11561
11761
  {
@@ -11566,12 +11766,15 @@ var DateTimePicker = ({
11566
11766
  {
11567
11767
  type: "button",
11568
11768
  disabled,
11769
+ "aria-required": required,
11770
+ "aria-invalid": !!effectiveError,
11569
11771
  className: cn(
11570
11772
  "flex w-full items-center justify-between rounded-full border border-input bg-background",
11571
11773
  sizeStyles8[size].trigger,
11572
11774
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
11573
11775
  disabled && "opacity-50 cursor-not-allowed",
11574
- !displayValue && "text-muted-foreground"
11776
+ !displayValue && "text-muted-foreground",
11777
+ effectiveError && "border-destructive/60 bg-destructive/5"
11575
11778
  ),
11576
11779
  children: [
11577
11780
  /* @__PURE__ */ jsx38("span", { className: "truncate", children: displayValue || placeholder || "Select date & time" }),
@@ -11584,6 +11787,7 @@ var DateTimePicker = ({
11584
11787
  onClick: (e) => {
11585
11788
  e.stopPropagation();
11586
11789
  onChange(void 0);
11790
+ setLocalRequiredError(void 0);
11587
11791
  },
11588
11792
  className: "hover:text-foreground p-0.5 rounded-md hover:bg-accent",
11589
11793
  children: /* @__PURE__ */ jsx38(X12, { className: sizeStyles8[size].icon })
@@ -11643,7 +11847,8 @@ var DateTimePicker = ({
11643
11847
  ] })
11644
11848
  ]
11645
11849
  }
11646
- )
11850
+ ),
11851
+ effectiveError && /* @__PURE__ */ jsx38("div", { className: "text-xs text-destructive", children: effectiveError })
11647
11852
  ] });
11648
11853
  };
11649
11854
 
@@ -14567,6 +14772,7 @@ import * as React39 from "react";
14567
14772
  import { useId as useId7 } from "react";
14568
14773
  import { ChevronDown as ChevronDown4, Search as Search5, Check as Check6, SearchX as SearchX2, Loader2 as Loader24, X as X13, Sparkles as Sparkles3 } from "lucide-react";
14569
14774
  import { Fragment as Fragment13, jsx as jsx45, jsxs as jsxs35 } from "react/jsx-runtime";
14775
+ var REQUIRED_ERROR_MESSAGE6 = "This field is required";
14570
14776
  var MultiCombobox = ({
14571
14777
  id,
14572
14778
  options,
@@ -14603,6 +14809,7 @@ var MultiCombobox = ({
14603
14809
  const [query, setQuery] = React39.useState("");
14604
14810
  const [open, setOpen] = React39.useState(false);
14605
14811
  const [activeIndex, setActiveIndex] = React39.useState(null);
14812
+ const [localRequiredError, setLocalRequiredError] = React39.useState();
14606
14813
  const inputRef = React39.useRef(null);
14607
14814
  const listRef = React39.useRef([]);
14608
14815
  const optionsListRef = React39.useRef(null);
@@ -14639,6 +14846,7 @@ var MultiCombobox = ({
14639
14846
  onChange(value.filter((v) => v !== optionValue));
14640
14847
  } else {
14641
14848
  if (!maxSelected || value.length < maxSelected) {
14849
+ setLocalRequiredError(void 0);
14642
14850
  onChange([...value, optionValue]);
14643
14851
  }
14644
14852
  }
@@ -14658,6 +14866,12 @@ var MultiCombobox = ({
14658
14866
  const handleClearAll = () => {
14659
14867
  onChange([]);
14660
14868
  };
14869
+ const effectiveError = error ?? localRequiredError;
14870
+ React39.useEffect(() => {
14871
+ if (disabled || !required || value.length > 0) {
14872
+ setLocalRequiredError(void 0);
14873
+ }
14874
+ }, [disabled, required, value.length]);
14661
14875
  React39.useEffect(() => {
14662
14876
  if (open && enableSearch) {
14663
14877
  setTimeout(() => {
@@ -14868,7 +15082,8 @@ var MultiCombobox = ({
14868
15082
  "aria-haspopup": "listbox",
14869
15083
  "aria-expanded": open,
14870
15084
  "aria-controls": listboxId,
14871
- "aria-invalid": !!error,
15085
+ "aria-required": required,
15086
+ "aria-invalid": !!effectiveError,
14872
15087
  className: cn(
14873
15088
  "group flex w-full items-center gap-2 rounded-full transition-all duration-200",
14874
15089
  sizeStyles8[size].trigger,
@@ -14876,7 +15091,7 @@ var MultiCombobox = ({
14876
15091
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:border-primary",
14877
15092
  "disabled:cursor-not-allowed disabled:opacity-50",
14878
15093
  open && "ring-2 ring-primary/20 border-primary",
14879
- !!error && "border-destructive focus-visible:ring-destructive/30"
15094
+ !!effectiveError && "border-destructive focus-visible:ring-destructive/30"
14880
15095
  ),
14881
15096
  children: [
14882
15097
  /* @__PURE__ */ jsx45("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__ */ jsxs35(Fragment13, { children: [
@@ -14972,6 +15187,7 @@ var MultiCombobox = ({
14972
15187
  size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm",
14973
15188
  "font-medium transition-colors duration-200",
14974
15189
  disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary",
15190
+ effectiveError && "text-destructive",
14975
15191
  labelClassName
14976
15192
  ),
14977
15193
  children: [
@@ -14989,6 +15205,7 @@ var MultiCombobox = ({
14989
15205
  labelSize,
14990
15206
  "font-medium transition-colors duration-200",
14991
15207
  disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary",
15208
+ effectiveError && "text-destructive",
14992
15209
  labelClassName
14993
15210
  ),
14994
15211
  children: [
@@ -14997,6 +15214,22 @@ var MultiCombobox = ({
14997
15214
  ]
14998
15215
  }
14999
15216
  ),
15217
+ /* @__PURE__ */ jsx45(
15218
+ "input",
15219
+ {
15220
+ tabIndex: -1,
15221
+ "aria-hidden": "true",
15222
+ readOnly: true,
15223
+ value: value.length > 0 ? "selected" : "",
15224
+ required,
15225
+ disabled,
15226
+ onInvalid: (e) => {
15227
+ e.preventDefault();
15228
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE6);
15229
+ },
15230
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
15231
+ }
15232
+ ),
15000
15233
  /* @__PURE__ */ jsx45(
15001
15234
  Popover,
15002
15235
  {
@@ -15010,17 +15243,26 @@ var MultiCombobox = ({
15010
15243
  children: dropdownBody
15011
15244
  }
15012
15245
  ),
15013
- (helperText || error) && /* @__PURE__ */ jsxs35("p", { className: cn("text-xs transition-colors duration-200 flex items-center gap-1.5", error ? "text-destructive" : "text-muted-foreground"), children: [
15014
- error && /* @__PURE__ */ jsx45("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__ */ jsx45(
15015
- "path",
15016
- {
15017
- fillRule: "evenodd",
15018
- 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",
15019
- clipRule: "evenodd"
15020
- }
15021
- ) }),
15022
- error || helperText
15023
- ] })
15246
+ (helperText || effectiveError) && /* @__PURE__ */ jsxs35(
15247
+ "p",
15248
+ {
15249
+ className: cn(
15250
+ "text-xs transition-colors duration-200 flex items-center gap-1.5",
15251
+ effectiveError ? "text-destructive" : "text-muted-foreground"
15252
+ ),
15253
+ children: [
15254
+ effectiveError && /* @__PURE__ */ jsx45("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__ */ jsx45(
15255
+ "path",
15256
+ {
15257
+ fillRule: "evenodd",
15258
+ 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",
15259
+ clipRule: "evenodd"
15260
+ }
15261
+ ) }),
15262
+ effectiveError || helperText
15263
+ ]
15264
+ }
15265
+ )
15024
15266
  ] });
15025
15267
  };
15026
15268
 
@@ -16158,6 +16400,7 @@ var defaultLabels = {
16158
16400
  searchPlaceholder: "Search...",
16159
16401
  noResultsText: "No results found"
16160
16402
  };
16403
+ var REQUIRED_ERROR_MESSAGE7 = "This field is required";
16161
16404
  function getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline) {
16162
16405
  if (!(viewOnly || inline) || !defaultExpanded) return /* @__PURE__ */ new Set();
16163
16406
  const parentIds = /* @__PURE__ */ new Set();
@@ -16196,14 +16439,16 @@ function CategoryTreeSelect(props) {
16196
16439
  const [isOpen, setIsOpen] = useState30(false);
16197
16440
  const [expandedNodes, setExpandedNodes] = useState30(() => getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline));
16198
16441
  const [query, setQuery] = useState30("");
16442
+ const [localRequiredError, setLocalRequiredError] = useState30();
16199
16443
  const searchInputRef = useRef19(null);
16200
16444
  const dropdownViewportRef = useRef19(null);
16201
16445
  useOverlayScrollbarTarget(dropdownViewportRef, { enabled: useOverlayScrollbar });
16202
16446
  const autoId = useId9();
16203
16447
  const resolvedId = id ? String(id) : `category-tree-select-${autoId}`;
16204
16448
  const labelId = label ? `${resolvedId}-label` : void 0;
16205
- const helperId = helperText && !error ? `${resolvedId}-helper` : void 0;
16206
- const errorId = error ? `${resolvedId}-error` : void 0;
16449
+ const effectiveError = error ?? localRequiredError;
16450
+ const helperId = helperText && !effectiveError ? `${resolvedId}-helper` : void 0;
16451
+ const errorId = effectiveError ? `${resolvedId}-error` : void 0;
16207
16452
  const describedBy = errorId || helperId;
16208
16453
  const mergedLabels = { ...defaultLabels, ...labels };
16209
16454
  const valueArray = useMemo19(
@@ -16274,6 +16519,11 @@ function CategoryTreeSelect(props) {
16274
16519
  const t = setTimeout(() => searchInputRef.current?.focus(), 50);
16275
16520
  return () => clearTimeout(t);
16276
16521
  }, [isOpen, isSearchEnabled]);
16522
+ useEffect24(() => {
16523
+ if (disabled || !required || valueArray.length > 0) {
16524
+ setLocalRequiredError(void 0);
16525
+ }
16526
+ }, [disabled, required, valueArray.length]);
16277
16527
  const toggleExpand = (id2) => {
16278
16528
  if (isSearchMode) return;
16279
16529
  const newExpanded = new Set(expandedNodes);
@@ -16292,6 +16542,7 @@ function CategoryTreeSelect(props) {
16292
16542
  toggleExpand(categoryId);
16293
16543
  return;
16294
16544
  }
16545
+ setLocalRequiredError(void 0);
16295
16546
  if (!props.onChange) return;
16296
16547
  if (singleSelect) {
16297
16548
  const onChange = props.onChange;
@@ -16399,7 +16650,7 @@ function CategoryTreeSelect(props) {
16399
16650
  };
16400
16651
  const renderSearch = ({ sticky = true, className: className2 } = {}) => {
16401
16652
  if (!isSearchEnabled) return null;
16402
- return /* @__PURE__ */ jsx49("div", { className: cn(sticky && "sticky top-0 z-10 bg-popover/85 pb-2 backdrop-blur-xl", className2), children: /* @__PURE__ */ jsxs39("div", { className: "relative", children: [
16653
+ return /* @__PURE__ */ jsx49("div", { className: cn(sticky && "sticky top-0 z-10 pb-2", className2), children: /* @__PURE__ */ jsxs39("div", { className: "relative", children: [
16403
16654
  /* @__PURE__ */ jsx49(Search6, { 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" }),
16404
16655
  /* @__PURE__ */ jsx49(
16405
16656
  "input",
@@ -16409,7 +16660,7 @@ function CategoryTreeSelect(props) {
16409
16660
  onChange: (e) => setQuery(e.target.value),
16410
16661
  placeholder: mergedLabels.searchPlaceholder,
16411
16662
  className: cn(
16412
- "peer w-full rounded-full bg-muted/40 py-2.5 pl-10 pr-10 text-sm",
16663
+ "peer w-full rounded-full bg-background/90 py-2.5 pl-10 pr-10 text-sm shadow-sm",
16413
16664
  "border border-border/30",
16414
16665
  "focus:outline-none focus:bg-background focus:border-primary/30 focus:ring-2 focus:ring-primary/10",
16415
16666
  "transition-all duration-200",
@@ -16463,7 +16714,7 @@ function CategoryTreeSelect(props) {
16463
16714
  className: cn(
16464
16715
  size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm",
16465
16716
  disabled ? "text-muted-foreground" : "text-foreground",
16466
- error && "text-destructive",
16717
+ effectiveError && "text-destructive",
16467
16718
  labelClassName
16468
16719
  ),
16469
16720
  children: [
@@ -16472,10 +16723,26 @@ function CategoryTreeSelect(props) {
16472
16723
  ]
16473
16724
  }
16474
16725
  ) }) : null;
16475
- const renderAssistiveText = () => error ? /* @__PURE__ */ jsx49("p", { id: errorId, className: "text-sm text-destructive", children: error }) : helperText ? /* @__PURE__ */ jsx49("p", { id: helperId, className: "text-sm text-muted-foreground", children: helperText }) : null;
16726
+ const renderAssistiveText = () => effectiveError ? /* @__PURE__ */ jsx49("p", { id: errorId, className: "text-sm text-destructive", children: effectiveError }) : helperText ? /* @__PURE__ */ jsx49("p", { id: helperId, className: "text-sm text-muted-foreground", children: helperText }) : null;
16476
16727
  if (viewOnly) {
16477
16728
  return /* @__PURE__ */ jsxs39("div", { className: cn("w-full space-y-2", className), children: [
16478
16729
  renderLabel(),
16730
+ /* @__PURE__ */ jsx49(
16731
+ "input",
16732
+ {
16733
+ tabIndex: -1,
16734
+ "aria-hidden": "true",
16735
+ readOnly: true,
16736
+ value: valueArray.length > 0 ? "selected" : "",
16737
+ required,
16738
+ disabled,
16739
+ onInvalid: (e) => {
16740
+ e.preventDefault();
16741
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE7);
16742
+ },
16743
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
16744
+ }
16745
+ ),
16479
16746
  /* @__PURE__ */ jsxs39(
16480
16747
  "div",
16481
16748
  {
@@ -16495,6 +16762,22 @@ function CategoryTreeSelect(props) {
16495
16762
  if (inline) {
16496
16763
  return /* @__PURE__ */ jsxs39("div", { className: cn("w-full space-y-2", className), children: [
16497
16764
  renderLabel(),
16765
+ /* @__PURE__ */ jsx49(
16766
+ "input",
16767
+ {
16768
+ tabIndex: -1,
16769
+ "aria-hidden": "true",
16770
+ readOnly: true,
16771
+ value: valueArray.length > 0 ? "selected" : "",
16772
+ required,
16773
+ disabled,
16774
+ onInvalid: (e) => {
16775
+ e.preventDefault();
16776
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE7);
16777
+ },
16778
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
16779
+ }
16780
+ ),
16498
16781
  /* @__PURE__ */ jsxs39(
16499
16782
  "div",
16500
16783
  {
@@ -16594,6 +16877,22 @@ function CategoryTreeSelect(props) {
16594
16877
  ] });
16595
16878
  return /* @__PURE__ */ jsxs39("div", { className: cn("w-full space-y-2", className), children: [
16596
16879
  renderLabel(),
16880
+ /* @__PURE__ */ jsx49(
16881
+ "input",
16882
+ {
16883
+ tabIndex: -1,
16884
+ "aria-hidden": "true",
16885
+ readOnly: true,
16886
+ value: valueArray.length > 0 ? "selected" : "",
16887
+ required,
16888
+ disabled,
16889
+ onInvalid: (e) => {
16890
+ e.preventDefault();
16891
+ setLocalRequiredError(REQUIRED_ERROR_MESSAGE7);
16892
+ },
16893
+ className: "pointer-events-none absolute h-0 w-0 opacity-0"
16894
+ }
16895
+ ),
16597
16896
  /* @__PURE__ */ jsx49(
16598
16897
  Popover,
16599
16898
  {
@@ -16620,7 +16919,8 @@ function CategoryTreeSelect(props) {
16620
16919
  "aria-controls": `${resolvedId}-tree`,
16621
16920
  "aria-labelledby": labelId,
16622
16921
  "aria-describedby": describedBy,
16623
- "aria-invalid": !!error,
16922
+ "aria-required": required,
16923
+ "aria-invalid": !!effectiveError,
16624
16924
  className: cn(
16625
16925
  "group flex w-full items-center justify-between rounded-full transition-all duration-200",
16626
16926
  "backdrop-blur-sm",
@@ -16629,7 +16929,7 @@ function CategoryTreeSelect(props) {
16629
16929
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
16630
16930
  disabled && "opacity-50 cursor-not-allowed hover:transform-none hover:shadow-none",
16631
16931
  isOpen && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
16632
- error && "border-destructive focus-visible:ring-destructive/30"
16932
+ effectiveError && "border-destructive focus-visible:ring-destructive/30"
16633
16933
  ),
16634
16934
  children: [
16635
16935
  /* @__PURE__ */ jsxs39("div", { className: "flex min-w-0 flex-1 items-center gap-2.5 text-left", children: [
@@ -20624,7 +20924,7 @@ function DataTableHeader({
20624
20924
  className: cn(
20625
20925
  "absolute inset-y-0 right-0 z-10 w-3 -mr-1",
20626
20926
  "cursor-col-resize select-none bg-transparent",
20627
- "after:absolute after:inset-y-2 after:right-[3px] after:w-px after:bg-border/0 after:transition-colors",
20927
+ "after:absolute after:inset-y-2 after:right-0.8 after:w-px after:bg-border/0 after:transition-colors",
20628
20928
  "hover:after:bg-primary/50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary"
20629
20929
  )
20630
20930
  }
@@ -23903,7 +24203,7 @@ var TableInsertGrid = ({
23903
24203
  onFocus: () => setSelection({ rows, cols }),
23904
24204
  onClick: () => onInsert(rows, cols),
23905
24205
  className: cn(
23906
- "h-5 w-5 rounded-[4px] border transition-colors",
24206
+ "h-5 w-5 rounded-sm border transition-colors",
23907
24207
  active ? "border-primary bg-primary/20" : "border-border/70 bg-background hover:border-primary/60 hover:bg-primary/10"
23908
24208
  )
23909
24209
  },