@underverse-ui/underverse 0.2.59 → 0.2.61

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
@@ -440,7 +440,7 @@ var Badge = ({
440
440
  }
441
441
  );
442
442
  }
443
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: cn(baseClasses, "rounded-lg gap-1", sizeStyles[size], className), onClick: handleClick, role: "status", children: [
443
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: cn(baseClasses, "rounded-full gap-1", sizeStyles[size], className), onClick: handleClick, role: "status", children: [
444
444
  Icon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
445
445
  Icon,
446
446
  {
@@ -2130,7 +2130,7 @@ function SmartImage({
2130
2130
  alt,
2131
2131
  className,
2132
2132
  ratioClass,
2133
- roundedClass = "rounded-xl",
2133
+ roundedClass = "rounded-2xl md:rounded-3xl",
2134
2134
  fill = true,
2135
2135
  width,
2136
2136
  height,
@@ -2320,10 +2320,10 @@ var Avatar_default = Avatar;
2320
2320
  var import_jsx_runtime13 = require("react/jsx-runtime");
2321
2321
  var Skeleton = ({ className, width, height, variant = "rectangular", animation = "pulse", lines = 1 }) => {
2322
2322
  const variantClasses2 = {
2323
- rectangular: "rounded-md",
2323
+ rectangular: "rounded-2xl md:rounded-3xl",
2324
2324
  circular: "rounded-full",
2325
- rounded: "rounded-lg",
2326
- text: "rounded"
2325
+ rounded: "rounded-2xl md:rounded-3xl",
2326
+ text: "rounded-xl"
2327
2327
  };
2328
2328
  const animationClasses = {
2329
2329
  pulse: "animate-pulse",
@@ -2372,9 +2372,9 @@ var SkeletonText = ({ lines = 3, className, width = "100%" }) => {
2372
2372
  };
2373
2373
  var SkeletonCard = ({ showAvatar = true, showImage = false, textLines = 3, className, children }) => {
2374
2374
  if (children) {
2375
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("p-4 space-y-4 rounded-lg bg-card outline-none focus:outline-none", className), children });
2375
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("p-4 space-y-4 rounded-2xl md:rounded-3xl bg-card outline-none focus:outline-none", className), children });
2376
2376
  }
2377
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cn("p-4 space-y-4 rounded-2xl bg-card outline-none focus:outline-none", className), children: [
2377
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cn("p-4 space-y-4 rounded-2xl md:rounded-3xl bg-card outline-none focus:outline-none", className), children: [
2378
2378
  showAvatar && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center space-x-3", children: [
2379
2379
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SkeletonAvatar, {}),
2380
2380
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-2", children: [
@@ -2382,7 +2382,7 @@ var SkeletonCard = ({ showAvatar = true, showImage = false, textLines = 3, class
2382
2382
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Skeleton, { className: "h-3 w-16" })
2383
2383
  ] })
2384
2384
  ] }),
2385
- showImage && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Skeleton, { className: "h-48 w-full rounded-xl" }),
2385
+ showImage && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Skeleton, { className: "h-48 w-full rounded-2xl md:rounded-3xl" }),
2386
2386
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SkeletonText, { lines: textLines }),
2387
2387
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex space-x-2", children: [
2388
2388
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SkeletonButton, { size: "sm" }),
@@ -2391,7 +2391,7 @@ var SkeletonCard = ({ showAvatar = true, showImage = false, textLines = 3, class
2391
2391
  ] });
2392
2392
  };
2393
2393
  var SkeletonPost = ({ className }) => {
2394
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cn("p-6 space-y-4 rounded-3xl bg-card outline-none focus:outline-none", className), children: [
2394
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cn("p-6 space-y-4 rounded-2xl md:rounded-3xl bg-card outline-none focus:outline-none", className), children: [
2395
2395
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center space-x-3", children: [
2396
2396
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SkeletonAvatar, { size: "lg" }),
2397
2397
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-2", children: [
@@ -2423,7 +2423,7 @@ var SkeletonMessage = ({ own = false, showAvatar = true, className }) => {
2423
2423
  ] });
2424
2424
  };
2425
2425
  var SkeletonList = ({ items = 5, itemHeight = 60, showAvatar = true, className }) => {
2426
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("space-y-3", className), children: Array.from({ length: items }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center space-x-3 p-3 rounded-xl", children: [
2426
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("space-y-3", className), children: Array.from({ length: items }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center space-x-3 p-3 rounded-2xl md:rounded-3xl", children: [
2427
2427
  showAvatar && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SkeletonAvatar, {}),
2428
2428
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex-1 space-y-2", children: [
2429
2429
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Skeleton, { className: "h-4 w-3/4" }),
@@ -4511,7 +4511,7 @@ var sizeStyles6 = {
4511
4511
  content: "mt-3 p-3"
4512
4512
  },
4513
4513
  md: {
4514
- tab: "py-2 px-4 text-sm",
4514
+ tab: "py-2.5 px-4 text-sm",
4515
4515
  content: "mt-4 p-4"
4516
4516
  },
4517
4517
  lg: {
@@ -4521,33 +4521,33 @@ var sizeStyles6 = {
4521
4521
  };
4522
4522
  var variantStyles5 = {
4523
4523
  default: {
4524
- container: "border-b border-border",
4525
- tab: "border-b-2 border-transparent hover:border-border/60",
4526
- activeTab: "border-primary text-primary",
4524
+ container: "border-b border-border/60 bg-muted/30 p-1 rounded-t-2xl",
4525
+ tab: "rounded-full border-b-2 border-transparent hover:bg-accent/40",
4526
+ activeTab: "border-primary bg-background text-primary shadow-sm",
4527
4527
  inactiveTab: "text-muted-foreground hover:text-foreground"
4528
4528
  },
4529
4529
  pills: {
4530
- container: "bg-muted p-1 rounded-lg",
4531
- tab: "rounded-md transition-all duration-200",
4532
- activeTab: "bg-background text-foreground shadow-sm",
4530
+ container: "bg-muted/50 backdrop-blur-sm p-1.5 rounded-2xl border border-border/40",
4531
+ tab: "rounded-full transition-all duration-200",
4532
+ activeTab: "bg-background text-foreground shadow-md border border-border/50",
4533
4533
  inactiveTab: "text-muted-foreground hover:text-foreground hover:bg-background/50"
4534
4534
  },
4535
4535
  underline: {
4536
- container: "relative border-b border-border",
4537
- tab: "relative transition-colors duration-200 pb-3 border-b-2 border-transparent hover:border-border/60",
4538
- activeTab: "text-primary border-primary font-medium",
4536
+ container: "relative border-b border-border/60",
4537
+ tab: "relative transition-colors duration-200 pb-3 border-b-2 border-transparent hover:border-primary/30",
4538
+ activeTab: "text-primary border-primary font-semibold",
4539
4539
  inactiveTab: "text-muted-foreground hover:text-foreground"
4540
4540
  },
4541
4541
  card: {
4542
- container: "space-y-1",
4542
+ container: "space-y-1.5 bg-muted/20 p-2 rounded-2xl border border-border/30",
4543
4543
  tab: "rounded-xl border border-transparent transition-all duration-200",
4544
- activeTab: "bg-primary text-primary-foreground border-primary",
4545
- inactiveTab: "text-muted-foreground hover:text-foreground hover:bg-accent/50 hover:border-border hover:shadow-sm"
4544
+ activeTab: "bg-primary text-primary-foreground border-primary shadow-md",
4545
+ inactiveTab: "text-muted-foreground hover:text-foreground hover:bg-accent/50 hover:border-border/50"
4546
4546
  },
4547
4547
  "underline-card": {
4548
- container: "border-b border-border bg-card rounded-t-2xl",
4549
- tab: "relative transition-all duration-200 pb-3 px-4 border-b-2 border-transparent hover:border-primary/50 hover:bg-accent/30",
4550
- activeTab: "text-primary border-primary font-medium bg-accent/20",
4548
+ container: "border-b border-border/60 bg-card/80 backdrop-blur-sm rounded-t-2xl p-1",
4549
+ tab: "relative transition-all duration-200 pb-3 px-4 rounded-t-xl border-b-2 border-transparent hover:border-primary/30 hover:bg-accent/30",
4550
+ activeTab: "text-primary border-primary font-semibold bg-accent/30",
4551
4551
  inactiveTab: "text-muted-foreground hover:text-foreground"
4552
4552
  }
4553
4553
  };
@@ -4667,7 +4667,8 @@ var Tabs = ({
4667
4667
  id: `${baseId}-panel-${tabs.findIndex((t) => t.value === active)}`,
4668
4668
  "aria-labelledby": `${baseId}-tab-${tabs.findIndex((t) => t.value === active)}`,
4669
4669
  className: cn(
4670
- "bg-card rounded-xl border border-border shadow-sm text-card-foreground transition-all duration-200",
4670
+ "bg-card rounded-2xl md:rounded-3xl border border-border/60 shadow-sm text-card-foreground transition-all duration-200",
4671
+ "backdrop-blur-sm",
4671
4672
  sizeStyles6[size].content,
4672
4673
  orientation === "vertical" && "flex-1"
4673
4674
  ),
@@ -4830,20 +4831,42 @@ var DropdownMenu = ({
4830
4831
  }
4831
4832
  );
4832
4833
  };
4833
- var DropdownMenuItem = ({ children, onClick, disabled, destructive, className }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4834
+ var DropdownMenuItem = ({
4835
+ children,
4836
+ label,
4837
+ description,
4838
+ icon: Icon,
4839
+ onClick,
4840
+ disabled,
4841
+ destructive,
4842
+ active,
4843
+ shortcut,
4844
+ className
4845
+ }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
4834
4846
  "button",
4835
4847
  {
4836
4848
  onClick,
4837
4849
  disabled,
4850
+ onMouseDown: (e) => e.preventDefault(),
4838
4851
  className: cn(
4839
- "flex w-full items-center gap-2 px-3 py-2 text-sm rounded-lg transition-colors",
4852
+ "flex w-full items-center gap-2 px-3 py-2 text-sm rounded-lg transition-colors group",
4840
4853
  "hover:bg-accent hover:text-accent-foreground",
4841
4854
  "focus:bg-accent focus:text-accent-foreground focus:outline-none",
4842
4855
  "disabled:opacity-50 disabled:cursor-not-allowed",
4843
4856
  destructive && "text-destructive hover:bg-destructive/10 focus:bg-destructive/10",
4857
+ active && "bg-primary/10 text-primary",
4844
4858
  className
4845
4859
  ),
4846
- children
4860
+ children: [
4861
+ Icon && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Icon, { className: cn("w-4 h-4 shrink-0", active ? "text-primary" : "opacity-60 group-hover:opacity-100") }),
4862
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 text-left", children: [
4863
+ label && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cn("font-medium", description && "leading-tight"), children: label }),
4864
+ description && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "text-xs text-muted-foreground", children: description }),
4865
+ children
4866
+ ] }),
4867
+ shortcut && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "ml-2 text-xs text-muted-foreground opacity-60", children: shortcut }),
4868
+ active && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("svg", { className: "w-4 h-4 text-primary shrink-0", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("polyline", { points: "20 6 9 17 4 12" }) })
4869
+ ]
4847
4870
  }
4848
4871
  );
4849
4872
  var DropdownMenuSeparator = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cn("h-px bg-border my-1", className) });
@@ -4888,6 +4911,15 @@ var getOptionLabel = (option) => {
4888
4911
  var getOptionValue = (option) => {
4889
4912
  return typeof option === "string" ? option : option.value;
4890
4913
  };
4914
+ var getOptionIcon = (option) => {
4915
+ return typeof option === "string" ? void 0 : option.icon;
4916
+ };
4917
+ var getOptionDescription = (option) => {
4918
+ return typeof option === "string" ? void 0 : option.description;
4919
+ };
4920
+ var getOptionDisabled = (option) => {
4921
+ return typeof option === "string" ? false : option.disabled ?? false;
4922
+ };
4891
4923
  var findOptionByValue = (options, value) => {
4892
4924
  return options.find((opt) => getOptionValue(opt) === value);
4893
4925
  };
@@ -4902,13 +4934,21 @@ var Combobox = ({
4902
4934
  className,
4903
4935
  disabled = false,
4904
4936
  size = "md",
4937
+ variant = "default",
4905
4938
  allowClear = false,
4906
4939
  usePortal = true,
4907
4940
  label,
4908
4941
  required,
4909
4942
  fontBold = false,
4910
4943
  loading: loading2 = false,
4911
- loadingText = "Loading..."
4944
+ loadingText = "Loading...",
4945
+ showSelectedIcon = true,
4946
+ maxHeight = 280,
4947
+ groupBy,
4948
+ renderOption,
4949
+ renderValue,
4950
+ error,
4951
+ helperText
4912
4952
  }) => {
4913
4953
  const [open, setOpen] = React20.useState(false);
4914
4954
  const [query, setQuery] = React20.useState("");
@@ -4926,6 +4966,7 @@ var Combobox = ({
4926
4966
  );
4927
4967
  const triggerRef = React20.useRef(null);
4928
4968
  const handleSelect = (option) => {
4969
+ if (getOptionDisabled(option)) return;
4929
4970
  const val = getOptionValue(option);
4930
4971
  if (val !== void 0 && val !== null) {
4931
4972
  onChange(val);
@@ -4950,9 +4991,66 @@ var Combobox = ({
4950
4991
  }, [open, enableSearch]);
4951
4992
  const selectedOption = findOptionByValue(options, value);
4952
4993
  const displayValue = selectedOption ? getOptionLabel(selectedOption) : "";
4994
+ const selectedIcon = selectedOption ? getOptionIcon(selectedOption) : void 0;
4995
+ const groupedOptions = React20.useMemo(() => {
4996
+ if (!groupBy) return null;
4997
+ const groups = {};
4998
+ filteredOptions.forEach((opt) => {
4999
+ const group = groupBy(opt);
5000
+ if (!groups[group]) groups[group] = [];
5001
+ groups[group].push(opt);
5002
+ });
5003
+ return groups;
5004
+ }, [filteredOptions, groupBy]);
5005
+ const renderOptionItem = (item, index) => {
5006
+ const itemValue = getOptionValue(item);
5007
+ const itemLabel = getOptionLabel(item);
5008
+ const itemIcon = getOptionIcon(item);
5009
+ const itemDescription = getOptionDescription(item);
5010
+ const itemDisabled = getOptionDisabled(item);
5011
+ const isSelected = itemValue === value;
5012
+ const isEven = index % 2 === 0;
5013
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5014
+ "li",
5015
+ {
5016
+ ref: (node) => {
5017
+ listRef.current[index] = node;
5018
+ },
5019
+ id: `combobox-item-${index}`,
5020
+ role: "option",
5021
+ tabIndex: -1,
5022
+ "aria-selected": isSelected,
5023
+ "aria-disabled": itemDisabled,
5024
+ onClick: () => !itemDisabled && handleSelect(item),
5025
+ style: {
5026
+ animationDelay: open ? `${Math.min(index * 15, 150)}ms` : "0ms"
5027
+ },
5028
+ className: cn(
5029
+ "dropdown-item group flex cursor-pointer items-center gap-3 rounded-lg px-3 py-2.5 text-sm",
5030
+ "outline-none focus:outline-none focus-visible:outline-none",
5031
+ "transition-all duration-150",
5032
+ isEven && "bg-muted/40",
5033
+ !itemDisabled && "hover:bg-accent/70 hover:shadow-sm",
5034
+ !itemDisabled && "focus:bg-accent/80 focus:text-accent-foreground",
5035
+ index === activeIndex && !itemDisabled && "bg-accent/60",
5036
+ isSelected && "bg-primary/10 text-primary font-medium",
5037
+ itemDisabled && "opacity-50 cursor-not-allowed"
5038
+ ),
5039
+ children: [
5040
+ itemIcon && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: cn("shrink-0 w-5 h-5 flex items-center justify-center", isSelected ? "text-primary" : "text-muted-foreground"), children: itemIcon }),
5041
+ renderOption ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex-1 min-w-0", children: renderOption(item, isSelected) }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex-1 min-w-0", children: [
5042
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "block truncate", children: itemLabel }),
5043
+ itemDescription && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "block text-xs text-muted-foreground truncate mt-0.5", children: itemDescription })
5044
+ ] }),
5045
+ isSelected && showSelectedIcon && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "shrink-0 ml-auto", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Check, { className: "h-4 w-4 text-primary" }) })
5046
+ ]
5047
+ },
5048
+ `${itemValue}-${index}`
5049
+ );
5050
+ };
4953
5051
  const dropdownBody = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-combobox-dropdown": true, "data-state": open ? "open" : "closed", role: "listbox", id: `${resolvedId}-listbox`, className: "w-full", children: [
4954
- enableSearch && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative p-3 border-b border-border/50 bg-muted/20", children: [
4955
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Search, { className: "absolute left-6 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground transition-colors" }),
5052
+ enableSearch && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "relative p-2.5 border-b border-border/30", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", children: [
5053
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground/60 transition-colors peer-focus:text-primary" }),
4956
5054
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4957
5055
  "input",
4958
5056
  {
@@ -4977,7 +5075,7 @@ var Combobox = ({
4977
5075
  });
4978
5076
  } else if (e.key === "Enter") {
4979
5077
  e.preventDefault();
4980
- if (activeIndex !== null && filteredOptions[activeIndex]) {
5078
+ if (activeIndex !== null && filteredOptions[activeIndex] && !getOptionDisabled(filteredOptions[activeIndex])) {
4981
5079
  handleSelect(filteredOptions[activeIndex]);
4982
5080
  }
4983
5081
  } else if (e.key === "Escape") {
@@ -4986,63 +5084,75 @@ var Combobox = ({
4986
5084
  }
4987
5085
  },
4988
5086
  placeholder: searchPlaceholder,
4989
- className: "w-full rounded-full bg-background/50 py-2 pl-8 pr-3 text-sm border-0 focus:outline-none focus:bg-background/80 transition-colors placeholder:text-muted-foreground/60",
5087
+ className: cn(
5088
+ "peer w-full rounded-xl bg-muted/40 py-2.5 pl-9 pr-3 text-sm",
5089
+ "border border-transparent",
5090
+ "focus:outline-none focus:bg-background focus:border-primary/30 focus:ring-2 focus:ring-primary/10",
5091
+ "transition-all duration-200",
5092
+ "placeholder:text-muted-foreground/50"
5093
+ ),
4990
5094
  "aria-autocomplete": "list",
4991
5095
  "aria-activedescendant": activeIndex != null ? `combobox-item-${activeIndex}` : void 0
4992
5096
  }
5097
+ ),
5098
+ query && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5099
+ "button",
5100
+ {
5101
+ type: "button",
5102
+ onClick: () => setQuery(""),
5103
+ className: "absolute right-3 top-1/2 -translate-y-1/2 p-0.5 rounded-md hover:bg-muted text-muted-foreground hover:text-foreground transition-colors",
5104
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.X, { className: "h-3.5 w-3.5" })
5105
+ }
4993
5106
  )
4994
- ] }),
4995
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "max-h-64 overflow-y-auto overscroll-contain", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ul", { className: "p-1 space-y-1", children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("li", { className: "px-3 py-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center gap-2 animate-in fade-in-0 zoom-in-95 duration-300", children: [
4996
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Loader2, { className: "h-6 w-6 animate-spin text-primary" }),
4997
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-sm text-muted-foreground", children: loadingText || "Loading\u2026" })
4998
- ] }) }) : filteredOptions.length > 0 ? filteredOptions.map((item, index) => {
4999
- const itemValue = getOptionValue(item);
5000
- const itemLabel = getOptionLabel(item);
5001
- const isSelected = itemValue === value;
5002
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5003
- "li",
5107
+ ] }) }),
5108
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "overflow-y-auto overscroll-contain", style: { maxHeight }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "p-1.5", children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-3 py-10 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center gap-3 animate-in fade-in-0 zoom-in-95 duration-300", children: [
5109
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "w-10 h-10 rounded-full border-2 border-primary/20 border-t-primary animate-spin" }) }),
5110
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-sm text-muted-foreground", children: loadingText })
5111
+ ] }) }) : filteredOptions.length > 0 ? groupedOptions ? (
5112
+ // Render grouped options with global index tracking
5113
+ (() => {
5114
+ let globalIndex = 0;
5115
+ return Object.entries(groupedOptions).map(([group, items]) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn(globalIndex > 0 && "mt-2 pt-2 border-t border-border/30"), children: [
5116
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-3 py-1.5 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: group }),
5117
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ul", { className: "space-y-0.5", children: items.map((item) => {
5118
+ const index = globalIndex++;
5119
+ return renderOptionItem(item, index);
5120
+ }) })
5121
+ ] }, group));
5122
+ })()
5123
+ ) : (
5124
+ // Render flat options
5125
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ul", { className: "space-y-0.5", children: filteredOptions.map((item, index) => renderOptionItem(item, index)) })
5126
+ ) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-3 py-10 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center gap-3 animate-in fade-in-0 zoom-in-95 duration-300", children: [
5127
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "w-12 h-12 rounded-full bg-muted/50 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.SearchX, { className: "h-6 w-6 text-muted-foreground/60" }) }),
5128
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-1", children: [
5129
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "block text-sm font-medium text-foreground", children: emptyText }),
5130
+ query && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "block text-xs text-muted-foreground", children: "Try a different search term" })
5131
+ ] }),
5132
+ query && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5133
+ "button",
5004
5134
  {
5005
- ref: (node) => {
5006
- listRef.current[index] = node;
5007
- },
5008
- id: `combobox-item-${index}`,
5009
- role: "option",
5010
- tabIndex: -1,
5011
- "aria-selected": isSelected,
5012
- onClick: () => handleSelect(item),
5013
- style: {
5014
- animationDelay: open ? `${Math.min(index * 20, 200)}ms` : "0ms"
5015
- },
5016
- className: cn(
5017
- "dropdown-item group flex cursor-pointer items-center justify-between rounded-lg px-2.5 py-1.5 text-sm",
5018
- "outline-none focus:outline-none focus-visible:outline-none",
5019
- "hover:bg-accent hover:text-accent-foreground",
5020
- "focus:bg-accent focus:text-accent-foreground",
5021
- "data-disabled:pointer-events-none data-disabled:opacity-50",
5022
- index === activeIndex && "bg-accent text-accent-foreground",
5023
- isSelected && "bg-accent text-accent-foreground"
5024
- ),
5025
- children: [
5026
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "truncate", children: itemLabel }),
5027
- isSelected && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Check, { className: "h-4 w-4 text-primary" })
5028
- ]
5029
- },
5030
- `${itemValue}-${index}`
5031
- );
5032
- }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("li", { className: "px-3 py-8 text-center text-muted-foreground text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center gap-2 animate-in fade-in-0 zoom-in-95 duration-300", children: [
5033
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.SearchX, { className: "h-8 w-8 opacity-40 text-muted-foreground" }),
5034
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-sm", children: emptyText }),
5035
- query && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", onClick: () => setQuery(""), className: "text-xs text-primary hover:underline", children: "Clear" })
5135
+ type: "button",
5136
+ onClick: () => setQuery(""),
5137
+ className: "px-3 py-1.5 text-xs font-medium text-primary bg-primary/10 rounded-full hover:bg-primary/20 transition-colors",
5138
+ children: "Clear search"
5139
+ }
5140
+ )
5036
5141
  ] }) }) }) })
5037
5142
  ] });
5038
5143
  const sizeStyles8 = {
5039
- // Keep consistent with Input size heights
5040
5144
  sm: "h-8 py-1.5 text-sm md:h-7 md:text-xs",
5041
5145
  md: "h-10 py-2 text-sm",
5042
5146
  lg: "h-12 py-3 text-base"
5043
5147
  };
5148
+ const variantStyles6 = {
5149
+ default: "border border-input bg-background hover:bg-accent/5 hover:border-primary/40",
5150
+ outline: "border-2 border-input bg-transparent hover:border-primary/60",
5151
+ ghost: "border-0 bg-transparent hover:bg-accent/50",
5152
+ filled: "border-0 bg-muted/50 hover:bg-muted/80"
5153
+ };
5044
5154
  const labelSize = size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm";
5045
- const radiusClass = size === "sm" ? "rounded-full" : "rounded-full";
5155
+ const radiusClass = size === "sm" ? "rounded-lg" : "rounded-xl";
5046
5156
  const verticalGap = size === "sm" ? "space-y-1.5" : "space-y-2";
5047
5157
  const triggerButtonBaseProps = {
5048
5158
  ref: triggerRef,
@@ -5052,6 +5162,7 @@ var Combobox = ({
5052
5162
  "aria-haspopup": "listbox",
5053
5163
  "aria-expanded": open,
5054
5164
  "aria-controls": `${resolvedId}-listbox`,
5165
+ "aria-invalid": !!error,
5055
5166
  id: resolvedId,
5056
5167
  "aria-labelledby": labelId,
5057
5168
  onKeyDown: (e) => {
@@ -5065,18 +5176,21 @@ var Combobox = ({
5065
5176
  }
5066
5177
  },
5067
5178
  className: cn(
5068
- "flex w-full items-center justify-between border border-input bg-background px-3",
5179
+ "group flex w-full items-center justify-between px-3 transition-all duration-200",
5069
5180
  radiusClass,
5070
5181
  sizeStyles8[size],
5071
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
5182
+ variantStyles6[variant],
5183
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:border-primary",
5072
5184
  "disabled:cursor-not-allowed disabled:opacity-50",
5073
- "hover:bg-accent/5 transition-colors hover:border-primary/40 focus:border-primary",
5185
+ open && "ring-2 ring-primary/20 border-primary",
5186
+ !!error && "border-destructive focus-visible:ring-destructive/30",
5074
5187
  className
5075
5188
  )
5076
5189
  };
5077
5190
  const triggerContents = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
5078
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: cn("truncate", !displayValue && "text-muted-foreground", fontBold && "font-bold"), children: displayValue || placeholder }),
5079
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-1 ml-2", children: [
5191
+ selectedIcon && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "shrink-0 w-5 h-5 mr-2 flex items-center justify-center text-primary", children: selectedIcon }),
5192
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: cn("flex-1 truncate text-left", !displayValue && "text-muted-foreground", fontBold && "font-semibold"), children: renderValue && selectedOption ? renderValue(selectedOption) : displayValue || placeholder }),
5193
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-1.5 ml-2 shrink-0", children: [
5080
5194
  allowClear && value && !disabled && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5081
5195
  "div",
5082
5196
  {
@@ -5085,11 +5199,23 @@ var Combobox = ({
5085
5199
  "aria-label": "Clear selection",
5086
5200
  onClick: handleClear,
5087
5201
  onKeyDown: (e) => (e.key === "Enter" || e.key === " ") && handleClear(e),
5088
- className: "opacity-0 group-hover:opacity-100 transition-opacity p-0.5 rounded-md hover:bg-destructive/10 text-muted-foreground hover:text-destructive",
5089
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.X, { className: "h-3 w-3" })
5202
+ className: cn(
5203
+ "opacity-0 group-hover:opacity-100 transition-all duration-200",
5204
+ "p-1 rounded-lg hover:bg-destructive/10 text-muted-foreground hover:text-destructive"
5205
+ ),
5206
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.X, { className: "h-3.5 w-3.5" })
5090
5207
  }
5091
5208
  ),
5092
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.ChevronDown, { className: cn("h-4 w-4 text-muted-foreground transition-all duration-200", open && "rotate-180 scale-110 text-primary") })
5209
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5210
+ import_lucide_react12.ChevronDown,
5211
+ {
5212
+ className: cn(
5213
+ "h-4 w-4 text-muted-foreground transition-all duration-300 ease-out",
5214
+ open && "rotate-180 text-primary",
5215
+ !open && "group-hover:text-foreground"
5216
+ )
5217
+ }
5218
+ )
5093
5219
  ] })
5094
5220
  ] });
5095
5221
  const triggerButtonForPopover = /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { ...triggerButtonBaseProps, children: triggerContents });
@@ -5136,7 +5262,18 @@ var Combobox = ({
5136
5262
  }
5137
5263
  ) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", children: [
5138
5264
  triggerButtonInline,
5139
- open && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "absolute left-0 top-full mt-1 z-50 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "rounded-2xl border bg-popover text-popover-foreground shadow-md backdrop-blur-sm bg-popover/95 border-border/60", children: dropdownBody }) })
5265
+ open && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "absolute left-0 top-full mt-1 z-50 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "rounded-2xl border text-popover-foreground shadow-md backdrop-blur-sm bg-popover/95 border-border/60", children: dropdownBody }) })
5266
+ ] }),
5267
+ (helperText || error) && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("p", { className: cn("text-xs transition-colors duration-200 flex items-center gap-1.5", error ? "text-destructive" : "text-muted-foreground"), children: [
5268
+ error && /* @__PURE__ */ (0, import_jsx_runtime25.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_runtime25.jsx)(
5269
+ "path",
5270
+ {
5271
+ fillRule: "evenodd",
5272
+ 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",
5273
+ clipRule: "evenodd"
5274
+ }
5275
+ ) }),
5276
+ error || helperText
5140
5277
  ] })
5141
5278
  ] });
5142
5279
  };
@@ -5309,17 +5446,23 @@ var Pagination = ({
5309
5446
  }
5310
5447
  )
5311
5448
  ] }),
5312
- pageSizeOptions && onPageSizeChange ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5313
- Combobox,
5314
- {
5315
- options: pageSizeOptionsStrings,
5316
- value: pageSize?.toString() || "10",
5317
- onChange: handlePageSizeChange,
5318
- size: "sm",
5319
- className: "w-14",
5320
- disabled
5321
- }
5322
- ) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", {})
5449
+ pageSizeOptions && onPageSizeChange ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2", children: [
5450
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "text-xs text-muted-foreground/70 hidden sm:inline", children: [
5451
+ t("itemsPerPage"),
5452
+ ":"
5453
+ ] }),
5454
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5455
+ Combobox,
5456
+ {
5457
+ options: pageSizeOptionsStrings,
5458
+ value: pageSize?.toString() || "10",
5459
+ onChange: handlePageSizeChange,
5460
+ size: "sm",
5461
+ className: "w-20 sm:w-24",
5462
+ disabled
5463
+ }
5464
+ )
5465
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", {})
5323
5466
  ]
5324
5467
  }
5325
5468
  );
@@ -5545,7 +5688,12 @@ var ScrollArea = (0, import_react14.forwardRef)(
5545
5688
  "div",
5546
5689
  {
5547
5690
  ref,
5548
- className: cn("relative overflow-hidden", variantClasses[variant], outlined && "rounded-xl border border-border/60", className),
5691
+ className: cn(
5692
+ "relative overflow-hidden rounded-2xl md:rounded-3xl",
5693
+ variantClasses[variant],
5694
+ outlined && "border border-border/60",
5695
+ className
5696
+ ),
5549
5697
  ...props,
5550
5698
  children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: cn("h-full w-full overflow-y-auto scroll-area-viewport", contentClassName), children })
5551
5699
  }
@@ -7472,7 +7620,8 @@ var MultiCombobox = ({
7472
7620
  options,
7473
7621
  value,
7474
7622
  onChange,
7475
- placeholder = "Search...",
7623
+ placeholder = "Select...",
7624
+ searchPlaceholder = "Search...",
7476
7625
  maxSelected,
7477
7626
  disabledOptions = [],
7478
7627
  showTags = true,
@@ -7480,13 +7629,22 @@ var MultiCombobox = ({
7480
7629
  className,
7481
7630
  disabled = false,
7482
7631
  size = "md",
7632
+ variant = "default",
7483
7633
  label,
7484
7634
  title,
7485
7635
  required,
7486
7636
  displayFormat = (option) => option.label,
7487
7637
  loading: loading2 = false,
7488
7638
  loadingText = "Loading...",
7489
- emptyText = "No results found"
7639
+ emptyText = "No results found",
7640
+ showSelectedIcons = true,
7641
+ maxHeight = 280,
7642
+ groupBy,
7643
+ renderOption,
7644
+ renderTag,
7645
+ error,
7646
+ helperText,
7647
+ maxTagsVisible = 3
7490
7648
  }) => {
7491
7649
  const [query, setQuery] = React27.useState("");
7492
7650
  const [open, setOpen] = React27.useState(false);
@@ -7496,16 +7654,31 @@ var MultiCombobox = ({
7496
7654
  const triggerRef = React27.useRef(null);
7497
7655
  useShadCNAnimations();
7498
7656
  const normalizedOptions = React27.useMemo(
7499
- () => options.map((o) => typeof o === "string" ? { value: o, label: o } : { value: o.value, label: o.label }),
7657
+ () => options.map(
7658
+ (o) => typeof o === "string" ? { value: o, label: o } : { value: o.value, label: o.label, icon: o.icon, description: o.description, disabled: o.disabled, group: o.group }
7659
+ ),
7500
7660
  [options]
7501
7661
  );
7502
7662
  const enableSearch = normalizedOptions.length > 10;
7503
7663
  const filtered = React27.useMemo(
7504
- () => enableSearch ? normalizedOptions.filter((opt) => opt.label.toLowerCase().includes(query.toLowerCase())) : normalizedOptions,
7664
+ () => enableSearch ? normalizedOptions.filter(
7665
+ (opt) => opt.label.toLowerCase().includes(query.toLowerCase()) || opt.description?.toLowerCase().includes(query.toLowerCase())
7666
+ ) : normalizedOptions,
7505
7667
  [normalizedOptions, query, enableSearch]
7506
7668
  );
7669
+ const groupedOptions = React27.useMemo(() => {
7670
+ if (!groupBy) return null;
7671
+ const groups = /* @__PURE__ */ new Map();
7672
+ filtered.forEach((opt) => {
7673
+ const group = groupBy(opt);
7674
+ if (!groups.has(group)) groups.set(group, []);
7675
+ groups.get(group).push(opt);
7676
+ });
7677
+ return groups;
7678
+ }, [filtered, groupBy]);
7507
7679
  const toggleSelect = (optionValue) => {
7508
- if (disabledOptions.includes(optionValue)) return;
7680
+ const option = normalizedOptions.find((o) => o.value === optionValue);
7681
+ if (option?.disabled || disabledOptions.includes(optionValue)) return;
7509
7682
  if (value.includes(optionValue)) {
7510
7683
  onChange(value.filter((v) => v !== optionValue));
7511
7684
  } else {
@@ -7547,39 +7720,123 @@ var MultiCombobox = ({
7547
7720
  md: {
7548
7721
  trigger: "h-10 px-4 py-2 text-sm",
7549
7722
  icon: "h-4 w-4",
7550
- search: "px-8 py-2 text-sm",
7723
+ search: "px-10 py-2 text-sm",
7551
7724
  item: "text-sm px-3 py-2",
7552
7725
  tag: "px-2 py-1 text-xs"
7553
7726
  },
7554
7727
  lg: {
7555
7728
  trigger: "h-12 px-5 py-3 text-base",
7556
7729
  icon: "h-5 w-5",
7557
- search: "px-8 py-3 text-base",
7730
+ search: "px-10 py-3 text-base",
7558
7731
  item: "text-base px-3 py-3",
7559
7732
  tag: "px-2.5 py-1 text-sm"
7560
7733
  }
7561
7734
  };
7735
+ const variantStyles6 = {
7736
+ default: "border border-input bg-background shadow-sm hover:border-primary/50",
7737
+ outline: "border-2 border-input bg-transparent hover:border-primary",
7738
+ ghost: "border border-transparent bg-muted/50 hover:bg-muted"
7739
+ };
7562
7740
  const autoId = (0, import_react16.useId)();
7563
7741
  const resolvedId = id ? String(id) : `multicombobox-${autoId}`;
7564
7742
  const labelId = label ? `${resolvedId}-label` : void 0;
7565
7743
  const labelSize = size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm";
7566
7744
  const listboxId = `${resolvedId}-listbox`;
7567
- const dropdownBody = /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { "data-combobox-dropdown": true, "data-state": open ? "open" : "closed", className: "w-full", children: [
7568
- showClear && value.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "px-3 py-2 border-b border-border/60 flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7569
- "button",
7745
+ const renderOptionItem = (item, index) => {
7746
+ const isSelected = value.includes(item.value);
7747
+ const isDisabled = item.disabled || disabledOptions.includes(item.value);
7748
+ const optionIcon = item.icon;
7749
+ const optionDesc = item.description;
7750
+ const isEven = index % 2 === 0;
7751
+ if (renderOption) {
7752
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7753
+ "li",
7754
+ {
7755
+ ref: (node) => {
7756
+ listRef.current[index] = node;
7757
+ },
7758
+ onClick: (e) => {
7759
+ e.preventDefault();
7760
+ e.stopPropagation();
7761
+ if (!isDisabled) toggleSelect(item.value);
7762
+ inputRef.current?.focus();
7763
+ },
7764
+ style: { animationDelay: open ? `${Math.min(index * 20, 200)}ms` : "0ms" },
7765
+ className: cn("dropdown-item", isEven && "bg-muted/25", isDisabled && "opacity-50 cursor-not-allowed pointer-events-none"),
7766
+ children: renderOption(item, isSelected)
7767
+ },
7768
+ item.value
7769
+ );
7770
+ }
7771
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
7772
+ "li",
7570
7773
  {
7571
- type: "button",
7774
+ ref: (node) => {
7775
+ listRef.current[index] = node;
7776
+ },
7572
7777
  onClick: (e) => {
7573
7778
  e.preventDefault();
7574
7779
  e.stopPropagation();
7575
- handleClearAll();
7780
+ if (!isDisabled) toggleSelect(item.value);
7781
+ inputRef.current?.focus();
7576
7782
  },
7577
- className: "text-xs text-muted-foreground hover:underline cursor-pointer",
7578
- children: "Clear all"
7579
- }
7580
- ) }),
7581
- enableSearch && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "relative border-b border-border/60", children: [
7582
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.Search, { className: cn("absolute left-2 top-2.5 text-muted-foreground", sizeStyles8[size].icon) }),
7783
+ style: { animationDelay: open ? `${Math.min(index * 20, 200)}ms` : "0ms" },
7784
+ className: cn(
7785
+ "dropdown-item flex cursor-pointer items-center gap-3 rounded-lg transition-all duration-200",
7786
+ sizeStyles8[size].item,
7787
+ isEven && "bg-muted/25",
7788
+ "hover:bg-accent/70 hover:shadow-sm",
7789
+ index === activeIndex && "bg-accent/60",
7790
+ isSelected && "bg-primary/10 text-primary font-medium",
7791
+ isDisabled && "opacity-40 cursor-not-allowed pointer-events-none"
7792
+ ),
7793
+ children: [
7794
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7795
+ "span",
7796
+ {
7797
+ className: cn(
7798
+ "shrink-0 w-5 h-5 flex items-center justify-center rounded-md border-2 transition-all duration-200",
7799
+ isSelected ? "bg-primary border-primary text-primary-foreground" : "border-muted-foreground/30 bg-transparent"
7800
+ ),
7801
+ children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.Check, { className: "w-3 h-3" })
7802
+ }
7803
+ ),
7804
+ optionIcon && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "shrink-0 w-5 h-5 flex items-center justify-center text-muted-foreground", children: optionIcon }),
7805
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex-1 min-w-0", children: [
7806
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cn("truncate", isSelected && "font-medium text-primary"), children: item.label }),
7807
+ optionDesc && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "text-xs text-muted-foreground truncate mt-0.5", children: optionDesc })
7808
+ ] })
7809
+ ]
7810
+ },
7811
+ item.value
7812
+ );
7813
+ };
7814
+ const dropdownBody = /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { "data-combobox-dropdown": true, "data-state": open ? "open" : "closed", className: "w-full", children: [
7815
+ value.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "px-3 py-2 border-b border-border/40 flex items-center justify-between bg-muted/30", children: [
7816
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "text-xs font-medium text-muted-foreground", children: [
7817
+ value.length,
7818
+ " selected",
7819
+ maxSelected && ` / ${maxSelected} max`
7820
+ ] }),
7821
+ showClear && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
7822
+ "button",
7823
+ {
7824
+ type: "button",
7825
+ onClick: (e) => {
7826
+ e.preventDefault();
7827
+ e.stopPropagation();
7828
+ handleClearAll();
7829
+ },
7830
+ className: "text-xs text-muted-foreground hover:text-destructive transition-colors cursor-pointer flex items-center gap-1",
7831
+ children: [
7832
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.X, { className: "w-3 h-3" }),
7833
+ "Clear all"
7834
+ ]
7835
+ }
7836
+ )
7837
+ ] }),
7838
+ enableSearch && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "relative border-b border-border/40", children: [
7839
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.Search, { className: cn("absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground", sizeStyles8[size].icon) }),
7583
7840
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7584
7841
  "input",
7585
7842
  {
@@ -7590,8 +7847,17 @@ var MultiCombobox = ({
7590
7847
  setActiveIndex(null);
7591
7848
  },
7592
7849
  onKeyDown: handleKeyDown,
7593
- placeholder,
7594
- className: cn("w-full rounded-t-xl bg-transparent focus:outline-none cursor-text", sizeStyles8[size].search)
7850
+ placeholder: searchPlaceholder,
7851
+ className: cn("w-full bg-transparent focus:outline-none cursor-text placeholder:text-muted-foreground/60", sizeStyles8[size].search)
7852
+ }
7853
+ ),
7854
+ query && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7855
+ "button",
7856
+ {
7857
+ type: "button",
7858
+ onClick: () => setQuery(""),
7859
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
7860
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.X, { className: "w-4 h-4" })
7595
7861
  }
7596
7862
  )
7597
7863
  ] }),
@@ -7600,50 +7866,41 @@ var MultiCombobox = ({
7600
7866
  {
7601
7867
  id: listboxId,
7602
7868
  role: "listbox",
7603
- className: cn("max-h-60 overflow-y-auto p-1", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"),
7604
- children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("li", { className: "px-3 py-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col items-center gap-2 animate-in fade-in-0 zoom-in-95 duration-300", children: [
7605
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.Loader2, { className: "h-6 w-6 animate-spin text-primary" }),
7606
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-muted-foreground", children: loadingText })
7607
- ] }) }) : filtered.length ? filtered.map((item, index) => {
7608
- const isSelected = value.includes(item.value);
7609
- const isDisabled = disabledOptions.includes(item.value);
7610
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
7611
- "li",
7612
- {
7613
- ref: (node) => {
7614
- listRef.current[index] = node;
7615
- },
7616
- onClick: (e) => {
7617
- e.preventDefault();
7618
- e.stopPropagation();
7619
- toggleSelect(item.value);
7620
- inputRef.current?.focus();
7621
- },
7622
- style: {
7623
- animationDelay: open ? `${Math.min(index * 20, 200)}ms` : "0ms"
7624
- },
7625
- className: cn(
7626
- "dropdown-item flex cursor-pointer items-center justify-between rounded-lg transition-colors",
7627
- sizeStyles8[size].item,
7628
- "hover:bg-accent hover:text-accent-foreground",
7629
- index === activeIndex && "bg-accent text-accent-foreground",
7630
- isDisabled && "opacity-50 cursor-not-allowed pointer-events-none"
7631
- ),
7632
- children: [
7633
- item.label,
7634
- isSelected && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.Check, { className: sizeStyles8[size].icon })
7635
- ]
7636
- },
7637
- item.value
7638
- );
7639
- }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("li", { className: cn("px-3 py-8 text-center text-muted-foreground", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col items-center gap-2 animate-in fade-in-0 zoom-in-95 duration-300", children: [
7640
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.SearchX, { className: "h-8 w-8 opacity-40 text-muted-foreground" }),
7641
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { children: emptyText }),
7642
- query && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", onClick: () => setQuery(""), className: "text-xs text-primary hover:underline", children: "Clear search" })
7869
+ "aria-multiselectable": "true",
7870
+ style: { maxHeight },
7871
+ className: cn("overflow-y-auto p-1.5", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"),
7872
+ children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("li", { className: "px-3 py-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col items-center gap-3 animate-in fade-in-0 zoom-in-95 duration-300", children: [
7873
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "relative", children: [
7874
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.Loader2, { className: "h-8 w-8 animate-spin text-primary" }),
7875
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.Sparkles, { className: "h-4 w-4 text-primary/60 absolute -top-1 -right-1 animate-pulse" })
7876
+ ] }),
7877
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-muted-foreground font-medium", children: loadingText })
7878
+ ] }) }) : filtered.length ? groupedOptions ? (
7879
+ // Render grouped options
7880
+ Array.from(groupedOptions.entries()).map(([group, items]) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("li", { className: "mb-2", children: [
7881
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "px-3 py-1.5 text-xs font-semibold text-muted-foreground uppercase tracking-wider sticky top-0 bg-popover/95 backdrop-blur-sm", children: group }),
7882
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("ul", { children: items.map((item) => renderOptionItem(item, filtered.indexOf(item))) })
7883
+ ] }, group))
7884
+ ) : (
7885
+ // Render flat options
7886
+ filtered.map((item, index) => renderOptionItem(item, index))
7887
+ ) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("li", { className: cn("px-3 py-8 text-center text-muted-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col items-center gap-3 animate-in fade-in-0 zoom-in-95 duration-300", children: [
7888
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.SearchX, { className: "h-10 w-10 opacity-30 text-muted-foreground" }),
7889
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "space-y-1", children: [
7890
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "font-medium block", children: emptyText }),
7891
+ query && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-xs opacity-60", children: "Try a different search term" })
7892
+ ] }),
7893
+ query && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("button", { type: "button", onClick: () => setQuery(""), className: "text-xs text-primary hover:underline flex items-center gap-1", children: [
7894
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.X, { className: "w-3 h-3" }),
7895
+ "Clear search"
7896
+ ] })
7643
7897
  ] }) })
7644
7898
  }
7645
7899
  )
7646
7900
  ] });
7901
+ const selectedOptions = value.map((v) => normalizedOptions.find((o) => o.value === v)).filter(Boolean);
7902
+ const visibleTags = maxTagsVisible ? selectedOptions.slice(0, maxTagsVisible) : selectedOptions;
7903
+ const hiddenCount = maxTagsVisible ? Math.max(0, selectedOptions.length - maxTagsVisible) : 0;
7647
7904
  const triggerButton = /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
7648
7905
  "button",
7649
7906
  {
@@ -7656,50 +7913,99 @@ var MultiCombobox = ({
7656
7913
  "aria-haspopup": "listbox",
7657
7914
  "aria-expanded": open,
7658
7915
  "aria-controls": listboxId,
7916
+ "aria-invalid": !!error,
7659
7917
  className: cn(
7660
- "flex w-full items-center gap-2 rounded-2xl border border-input bg-background shadow-sm min-h-10",
7918
+ "group flex w-full items-center gap-2 rounded-2xl min-h-10 transition-all duration-200",
7661
7919
  "px-3 py-2",
7662
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
7663
- "disabled:cursor-not-allowed disabled:opacity-50"
7920
+ variantStyles6[variant],
7921
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:border-primary",
7922
+ "disabled:cursor-not-allowed disabled:opacity-50",
7923
+ open && "ring-2 ring-primary/20 border-primary",
7924
+ !!error && "border-destructive focus-visible:ring-destructive/30"
7664
7925
  ),
7665
7926
  children: [
7666
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex items-center gap-1 flex-wrap min-h-6 flex-1", children: value.length > 0 ? showTags ? value.map((itemValue) => {
7667
- const option = normalizedOptions.find((o) => o.value === itemValue);
7668
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "inline-flex items-center gap-1 bg-accent text-accent-foreground rounded-lg px-2 py-1 text-xs", children: [
7669
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "truncate max-w-30", children: option ? displayFormat(option) : itemValue }),
7670
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7927
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex items-center gap-1.5 flex-wrap min-h-6 flex-1", children: value.length > 0 ? showTags ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
7928
+ visibleTags.map((option) => {
7929
+ if (renderTag) {
7930
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(React27.Fragment, { children: renderTag(option, () => handleRemove(option.value)) }, option.value);
7931
+ }
7932
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
7671
7933
  "span",
7672
7934
  {
7673
- role: "button",
7674
- tabIndex: 0,
7675
- "aria-label": `Remove ${option ? displayFormat(option) : itemValue}`,
7676
- onClick: (e) => {
7677
- e.preventDefault();
7678
- e.stopPropagation();
7679
- handleRemove(itemValue);
7680
- },
7681
- onKeyDown: (e) => {
7682
- if (e.key === "Enter" || e.key === " ") {
7683
- e.preventDefault();
7684
- e.stopPropagation();
7685
- handleRemove(itemValue);
7686
- }
7687
- },
7688
- className: "hover:text-destructive transition-colors cursor-pointer select-none",
7689
- children: "\xD7"
7690
- }
7691
- )
7692
- ] }, itemValue);
7693
- }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "truncate text-sm", children: [
7935
+ className: cn(
7936
+ "inline-flex items-center gap-1.5 bg-primary/10 text-primary rounded-lg transition-all duration-200",
7937
+ "hover:bg-primary/20",
7938
+ sizeStyles8[size].tag
7939
+ ),
7940
+ children: [
7941
+ showSelectedIcons && option.icon && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "shrink-0 w-3.5 h-3.5 flex items-center justify-center", children: option.icon }),
7942
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "truncate max-w-24", children: displayFormat(option) }),
7943
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7944
+ "span",
7945
+ {
7946
+ role: "button",
7947
+ tabIndex: 0,
7948
+ "aria-label": `Remove ${displayFormat(option)}`,
7949
+ onClick: (e) => {
7950
+ e.preventDefault();
7951
+ e.stopPropagation();
7952
+ handleRemove(option.value);
7953
+ },
7954
+ onKeyDown: (e) => {
7955
+ if (e.key === "Enter" || e.key === " ") {
7956
+ e.preventDefault();
7957
+ e.stopPropagation();
7958
+ handleRemove(option.value);
7959
+ }
7960
+ },
7961
+ className: "hover:text-destructive transition-colors cursor-pointer select-none hover:bg-destructive/10 rounded-full p-0.5",
7962
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.X, { className: "w-3 h-3" })
7963
+ }
7964
+ )
7965
+ ]
7966
+ },
7967
+ option.value
7968
+ );
7969
+ }),
7970
+ hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: cn("inline-flex items-center bg-muted text-muted-foreground rounded-lg", sizeStyles8[size].tag), children: [
7971
+ "+",
7972
+ hiddenCount,
7973
+ " more"
7974
+ ] })
7975
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "truncate text-sm font-medium", children: [
7694
7976
  value.length,
7977
+ " item",
7978
+ value.length > 1 ? "s" : "",
7695
7979
  " selected"
7696
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-muted-foreground", children: placeholder || "Select..." }) }),
7697
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7698
- import_lucide_react18.ChevronDown,
7699
- {
7700
- className: cn("opacity-50 transition-all duration-200", sizeStyles8[size].icon, open && "rotate-180 scale-110 text-primary opacity-100")
7701
- }
7702
- )
7980
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-muted-foreground", children: placeholder }) }),
7981
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center gap-1.5 shrink-0", children: [
7982
+ showClear && value.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7983
+ "div",
7984
+ {
7985
+ role: "button",
7986
+ tabIndex: 0,
7987
+ "aria-label": "Clear all",
7988
+ onClick: (e) => {
7989
+ e.preventDefault();
7990
+ e.stopPropagation();
7991
+ handleClearAll();
7992
+ },
7993
+ onKeyDown: (e) => (e.key === "Enter" || e.key === " ") && handleClearAll(),
7994
+ className: "opacity-0 group-hover:opacity-100 transition-all duration-200 p-1 rounded-lg hover:bg-destructive/10 text-muted-foreground hover:text-destructive",
7995
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react18.X, { className: "h-3.5 w-3.5" })
7996
+ }
7997
+ ),
7998
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7999
+ import_lucide_react18.ChevronDown,
8000
+ {
8001
+ className: cn(
8002
+ "h-4 w-4 text-muted-foreground transition-all duration-300 ease-out",
8003
+ open && "rotate-180 text-primary",
8004
+ !open && "group-hover:text-foreground"
8005
+ )
8006
+ }
8007
+ )
8008
+ ] })
7703
8009
  ]
7704
8010
  }
7705
8011
  );
@@ -7746,7 +8052,18 @@ var MultiCombobox = ({
7746
8052
  contentClassName: "p-0",
7747
8053
  children: dropdownBody
7748
8054
  }
7749
- )
8055
+ ),
8056
+ (helperText || error) && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("p", { className: cn("text-xs transition-colors duration-200 flex items-center gap-1.5", error ? "text-destructive" : "text-muted-foreground"), children: [
8057
+ error && /* @__PURE__ */ (0, import_jsx_runtime33.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_runtime33.jsx)(
8058
+ "path",
8059
+ {
8060
+ fillRule: "evenodd",
8061
+ 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",
8062
+ clipRule: "evenodd"
8063
+ }
8064
+ ) }),
8065
+ error || helperText
8066
+ ] })
7750
8067
  ] });
7751
8068
  };
7752
8069
 
@@ -8673,26 +8990,23 @@ function CategoryTreeSelect(props) {
8673
8990
  const hasChildren = children.length > 0;
8674
8991
  const isExpanded = expandedNodes.has(category.id);
8675
8992
  const isSelected = valueArray.includes(category.id);
8993
+ const isParent = level === 0;
8676
8994
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "animate-in fade-in-50 duration-200", style: { animationDelay: `${level * 30}ms` }, children: [
8677
8995
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
8678
8996
  "div",
8679
8997
  {
8680
8998
  className: cn(
8681
- "relative flex items-center gap-2.5 px-3 py-2.5 rounded-xl transition-all duration-200",
8999
+ "relative flex items-center gap-2.5 px-3 py-2.5 transition-all duration-200",
9000
+ "border-l-4 border-l-transparent",
9001
+ // Parent level styling
9002
+ isParent && "bg-muted/25 font-medium",
8682
9003
  !viewOnly && "cursor-pointer",
8683
9004
  !viewOnly && !isSelected && "hover:bg-accent/60 hover:shadow-sm",
8684
9005
  // Selected state
8685
- !viewOnly && isSelected && "bg-linear-to-r from-primary/15 via-primary/10 to-primary/5 shadow-sm"
9006
+ !viewOnly && isSelected && "bg-accent/30 border-l-primary shadow-sm"
8686
9007
  ),
8687
9008
  style: { paddingLeft: `${level * 1.25 + 0.75}rem` },
8688
9009
  children: [
8689
- !viewOnly && isSelected && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8690
- "span",
8691
- {
8692
- "aria-hidden": true,
8693
- className: "absolute left-0 top-2 bottom-2 w-1 rounded-full bg-linear-to-b from-primary to-primary/70 shadow-sm shadow-primary/30"
8694
- }
8695
- ),
8696
9010
  hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8697
9011
  "button",
8698
9012
  {
@@ -8993,7 +9307,7 @@ function ImageUpload({
8993
9307
  "div",
8994
9308
  {
8995
9309
  className: cn(
8996
- "relative border-2 border-dashed rounded-xl p-8 text-center transition-all duration-200",
9310
+ "relative border-2 border-dashed rounded-2xl md:rounded-3xl p-8 text-center transition-all duration-200",
8997
9311
  isDragging && !disabled ? "border-primary bg-primary/5 scale-[1.02]" : "border-border hover:border-primary/50",
8998
9312
  disabled && "opacity-50 cursor-not-allowed",
8999
9313
  uploading && "pointer-events-none"
@@ -9002,7 +9316,7 @@ function ImageUpload({
9002
9316
  onDragLeave: handleDragLeave,
9003
9317
  onDrop: handleDrop,
9004
9318
  children: [
9005
- uploading && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "absolute inset-0 bg-background/80 flex items-center justify-center rounded-xl", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-3", children: [
9319
+ uploading && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "absolute inset-0 bg-background/80 flex items-center justify-center rounded-2xl md:rounded-3xl", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-3", children: [
9006
9320
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react21.Loader2, { className: "w-6 h-6 animate-spin text-primary" }),
9007
9321
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-sm font-medium", children: "Uploading..." })
9008
9322
  ] }) }),
@@ -9031,7 +9345,7 @@ function ImageUpload({
9031
9345
  ),
9032
9346
  showPreview && uploadedImages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "space-y-3", children: [
9033
9347
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("h4", { className: "text-sm font-medium", children: "Uploaded Images" }),
9034
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4", children: uploadedImages.map((image) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "relative group bg-card border border-border rounded-xl p-3", children: [
9348
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4", children: uploadedImages.map((image) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "relative group bg-card border border-border rounded-2xl md:rounded-3xl p-3", children: [
9035
9349
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
9036
9350
  Button_default,
9037
9351
  {
@@ -9238,7 +9552,10 @@ function Carousel({
9238
9552
  "div",
9239
9553
  {
9240
9554
  ref: carouselRef,
9241
- className: cn("relative w-full overflow-hidden focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 rounded-2xl", className),
9555
+ className: cn(
9556
+ "relative w-full overflow-hidden focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 rounded-2xl md:rounded-3xl",
9557
+ className
9558
+ ),
9242
9559
  onMouseEnter: () => setIsPaused(true),
9243
9560
  onMouseLeave: () => setIsPaused(false),
9244
9561
  role: "region",
@@ -9695,12 +10012,12 @@ var ListRoot = React34.forwardRef(
9695
10012
  const hasChildren = childCount > 0;
9696
10013
  const variantClasses2 = {
9697
10014
  plain: "",
9698
- outlined: "rounded-xl md:rounded-2xl bg-card text-card-foreground border border-border shadow-sm",
9699
- soft: "rounded-xl bg-muted/40 border border-border/60",
9700
- bordered: "border border-border rounded-xl",
9701
- card: "rounded-xl bg-card shadow-md border border-border",
10015
+ outlined: "rounded-2xl md:rounded-3xl bg-card text-card-foreground border border-border shadow-sm",
10016
+ soft: "rounded-2xl md:rounded-3xl bg-muted/40 border border-border/60",
10017
+ bordered: "border border-border rounded-2xl md:rounded-3xl",
10018
+ card: "rounded-2xl md:rounded-3xl bg-card shadow-md border border-border",
9702
10019
  flush: "",
9703
- striped: "rounded-xl border border-border overflow-hidden"
10020
+ striped: "rounded-2xl md:rounded-3xl border border-border overflow-hidden"
9704
10021
  };
9705
10022
  if (loading2) {
9706
10023
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
@@ -10963,14 +11280,14 @@ function joinAreas(areas) {
10963
11280
  }
10964
11281
  function getVariantClasses(variant = "default", outlined) {
10965
11282
  if (outlined) {
10966
- return "rounded-xl md:rounded-2xl bg-card text-card-foreground border border-border shadow-sm";
11283
+ return "rounded-2xl md:rounded-3xl bg-card text-card-foreground border border-border shadow-sm";
10967
11284
  }
10968
11285
  const variants = {
10969
11286
  default: "",
10970
- bordered: "border border-border rounded-xl",
10971
- card: "rounded-xl md:rounded-2xl bg-card text-card-foreground border border-border shadow-sm",
10972
- flat: "bg-muted/30 rounded-xl",
10973
- glass: "bg-background/80 backdrop-blur-sm border border-border/50 rounded-xl shadow-lg"
11287
+ bordered: "border border-border rounded-2xl md:rounded-3xl",
11288
+ card: "rounded-2xl md:rounded-3xl bg-card text-card-foreground border border-border shadow-sm",
11289
+ flat: "bg-muted/30 rounded-2xl md:rounded-3xl",
11290
+ glass: "bg-background/80 backdrop-blur-sm border border-border/50 rounded-2xl md:rounded-3xl shadow-lg"
10974
11291
  };
10975
11292
  return variants[variant] || "";
10976
11293
  }
@@ -11105,7 +11422,11 @@ var GridItem = import_react21.default.forwardRef(
11105
11422
  "div",
11106
11423
  {
11107
11424
  ref,
11108
- className: cn(hoverable && "transition-all duration-200 hover:scale-[1.02] hover:shadow-md cursor-pointer", className),
11425
+ className: cn(
11426
+ "rounded-2xl md:rounded-3xl",
11427
+ hoverable && "transition-all duration-200 hover:scale-[1.02] hover:shadow-md cursor-pointer",
11428
+ className
11429
+ ),
11109
11430
  style: st,
11110
11431
  ...rest
11111
11432
  }
@@ -13081,7 +13402,17 @@ function DataTable({
13081
13402
  totalItems
13082
13403
  ] }),
13083
13404
  /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-center gap-0.5", children: [
13084
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Button_default, { variant: "ghost", size: "sm", className: "h-7 w-7 p-0", onClick: () => setCurPage(Math.max(1, curPage - 1)), disabled: curPage === 1, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("svg", { className: "h-4 w-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) }) }),
13405
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
13406
+ Button_default,
13407
+ {
13408
+ variant: "ghost",
13409
+ size: "sm",
13410
+ className: "h-7 w-7 p-0 rounded-full",
13411
+ onClick: () => setCurPage(Math.max(1, curPage - 1)),
13412
+ disabled: curPage === 1,
13413
+ children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("svg", { className: "h-4 w-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
13414
+ }
13415
+ ),
13085
13416
  (() => {
13086
13417
  const totalPages = Math.ceil(totalItems / curPageSize);
13087
13418
  const pages = [];
@@ -13102,7 +13433,7 @@ function DataTable({
13102
13433
  {
13103
13434
  onClick: () => setCurPage(p),
13104
13435
  className: cn(
13105
- "h-7 min-w-7 px-1.5 rounded-lg text-xs font-medium transition-colors",
13436
+ "h-7 min-w-7 px-2 rounded-full text-xs font-medium transition-colors",
13106
13437
  curPage === p ? "bg-primary text-primary-foreground" : "hover:bg-accent hover:text-accent-foreground"
13107
13438
  ),
13108
13439
  children: p
@@ -13116,7 +13447,7 @@ function DataTable({
13116
13447
  {
13117
13448
  variant: "ghost",
13118
13449
  size: "sm",
13119
- className: "h-7 w-7 p-0",
13450
+ className: "h-7 w-7 p-0 rounded-full",
13120
13451
  onClick: () => setCurPage(Math.min(Math.ceil(totalItems / curPageSize), curPage + 1)),
13121
13452
  disabled: curPage === Math.ceil(totalItems / curPageSize),
13122
13453
  children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("svg", { className: "h-4 w-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
@@ -13133,7 +13464,7 @@ function DataTable({
13133
13464
  setCurPageSize(Number(v));
13134
13465
  },
13135
13466
  size: "sm",
13136
- className: "w-14 h-7"
13467
+ className: "w-20"
13137
13468
  }
13138
13469
  )
13139
13470
  ] })