@underverse-ui/underverse 0.1.20 → 0.1.22

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
@@ -3962,7 +3962,11 @@ var Combobox = ({
3962
3962
  const autoId = (0, import_react10.useId)();
3963
3963
  const resolvedId = id ? String(id) : `combobox-${autoId}`;
3964
3964
  const labelId = label ? `${resolvedId}-label` : void 0;
3965
- const filteredOptions = React18.useMemo(() => options.filter((o) => getOptionLabel(o).toLowerCase().includes(query.toLowerCase())), [options, query]);
3965
+ const enableSearch = options.length > 10;
3966
+ const filteredOptions = React18.useMemo(
3967
+ () => enableSearch ? options.filter((o) => getOptionLabel(o).toLowerCase().includes(query.toLowerCase())) : options,
3968
+ [options, query, enableSearch]
3969
+ );
3966
3970
  const [dropdownPosition, setDropdownPosition] = React18.useState(null);
3967
3971
  const triggerRef = React18.useRef(null);
3968
3972
  const calculatePosition = React18.useCallback(() => {
@@ -4029,12 +4033,12 @@ var Combobox = ({
4029
4033
  if (!open) {
4030
4034
  setQuery("");
4031
4035
  setActiveIndex(null);
4032
- } else {
4036
+ } else if (enableSearch) {
4033
4037
  setTimeout(() => {
4034
4038
  inputRef.current?.focus();
4035
4039
  }, 100);
4036
4040
  }
4037
- }, [open]);
4041
+ }, [open, enableSearch]);
4038
4042
  const selectedOption = findOptionByValue(options, value);
4039
4043
  const displayValue = selectedOption ? getOptionLabel(selectedOption) : "";
4040
4044
  const dropdownContent = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
@@ -4057,7 +4061,7 @@ var Combobox = ({
4057
4061
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
4058
4062
  ),
4059
4063
  children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cn("rounded-md border bg-popover text-popover-foreground shadow-md", "backdrop-blur-sm bg-popover/95 border-border/60"), children: [
4060
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "relative p-3 border-b border-border/50 bg-muted/20", children: [
4064
+ enableSearch && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "relative p-3 border-b border-border/50 bg-muted/20", children: [
4061
4065
  /* @__PURE__ */ (0, import_jsx_runtime23.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" }),
4062
4066
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4063
4067
  "input",
@@ -4186,11 +4190,12 @@ var Combobox = ({
4186
4190
  setOpen(next);
4187
4191
  },
4188
4192
  className: cn(
4189
- "flex w-full items-center justify-between border border-input bg-background px-3 vanh",
4193
+ "flex w-full items-center justify-between border border-input bg-background px-3",
4190
4194
  radiusClass,
4191
4195
  sizeStyles8[size],
4192
- "ring-offset-background placeholder:text-muted-foreground outline-none focus:outline-none focus-visible:outline-none focus:ring-0 focus-visible:ring-0 focus:ring-offset-0",
4196
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
4193
4197
  "disabled:cursor-not-allowed disabled:opacity-50",
4198
+ "hover:bg-accent/5 transition-colors hover:border-primary/40 focus:border-primary",
4194
4199
  className
4195
4200
  ),
4196
4201
  children: [
@@ -4759,6 +4764,7 @@ var DatePicker = ({
4759
4764
  const [dropdownPosition, setDropdownPosition] = React21.useState(null);
4760
4765
  const [viewDate, setViewDate] = React21.useState(value || /* @__PURE__ */ new Date());
4761
4766
  const triggerRef = React21.useRef(null);
4767
+ const dropdownRef = React21.useRef(null);
4762
4768
  useShadCNAnimations();
4763
4769
  const calculatePosition = React21.useCallback(() => {
4764
4770
  if (!triggerRef.current) return null;
@@ -4784,15 +4790,24 @@ var DatePicker = ({
4784
4790
  window.removeEventListener("scroll", handler, true);
4785
4791
  };
4786
4792
  }, [isOpen, calculatePosition]);
4793
+ React21.useEffect(() => {
4794
+ if (value) {
4795
+ setViewDate(value);
4796
+ } else {
4797
+ setViewDate(/* @__PURE__ */ new Date());
4798
+ }
4799
+ }, [value]);
4787
4800
  React21.useEffect(() => {
4788
4801
  if (!isOpen) return;
4789
4802
  const handleClickOutside = (event) => {
4790
4803
  const target = event.target;
4791
- if (triggerRef.current && !triggerRef.current.contains(target)) {
4792
- const dropdown = document.querySelector("[data-datepicker]");
4793
- if (dropdown && !dropdown.contains(target)) {
4794
- setIsOpen(false);
4795
- }
4804
+ const trigger = triggerRef.current;
4805
+ const dropdown = dropdownRef.current;
4806
+ if (!trigger || !dropdown) return;
4807
+ const clickedOutsideTrigger = !trigger.contains(target);
4808
+ const clickedOutsideDropdown = !dropdown.contains(target);
4809
+ if (clickedOutsideTrigger && clickedOutsideDropdown) {
4810
+ setIsOpen(false);
4796
4811
  }
4797
4812
  };
4798
4813
  const handleEscape = (event) => {
@@ -4808,11 +4823,18 @@ var DatePicker = ({
4808
4823
  };
4809
4824
  }, [isOpen]);
4810
4825
  const handleDateSelect = (date) => {
4811
- onChange(date);
4826
+ let selectedDate;
4827
+ if (value && (value.getHours() !== 0 || value.getMinutes() !== 0 || value.getSeconds() !== 0)) {
4828
+ selectedDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), value.getHours(), value.getMinutes(), value.getSeconds());
4829
+ } else {
4830
+ const now = /* @__PURE__ */ new Date();
4831
+ selectedDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
4832
+ }
4833
+ onChange(selectedDate);
4812
4834
  setIsOpen(false);
4813
4835
  };
4814
4836
  const formatDateDisplay = (date) => {
4815
- return locale === "vi" /* VI */ ? formatDate(date) : formatDateShort(date);
4837
+ return formatDate(date);
4816
4838
  };
4817
4839
  const getDaysInMonth = (date) => {
4818
4840
  return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
@@ -4873,7 +4895,8 @@ var DatePicker = ({
4873
4895
  top: dropdownPosition?.top || 0,
4874
4896
  left: dropdownPosition?.left || 0,
4875
4897
  width: size === "sm" ? dropdownPosition?.width || 224 : dropdownPosition?.width || 256,
4876
- zIndex: 9999
4898
+ zIndex: 9999,
4899
+ pointerEvents: "none"
4877
4900
  },
4878
4901
  "data-state": isOpen ? "open" : "closed",
4879
4902
  className: cn(
@@ -4884,11 +4907,13 @@ var DatePicker = ({
4884
4907
  children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4885
4908
  "div",
4886
4909
  {
4910
+ ref: dropdownRef,
4887
4911
  className: cn(
4888
4912
  "rounded-md border bg-popover text-popover-foreground shadow-md",
4889
4913
  "backdrop-blur-sm bg-popover/95 border-border/60",
4890
4914
  size === "sm" ? "p-3 w-56" : "p-4 w-64"
4891
4915
  ),
4916
+ style: { pointerEvents: "auto" },
4892
4917
  children: [
4893
4918
  /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
4894
4919
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Button_default, { variant: "ghost", size: "sm", onClick: () => navigateMonth("prev"), className: "p-1 h-auto", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.ChevronLeft, { className: "h-4 w-4" }) }),
@@ -4896,7 +4921,20 @@ var DatePicker = ({
4896
4921
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Button_default, { variant: "ghost", size: "sm", onClick: () => navigateMonth("next"), className: "p-1 h-auto", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.ChevronRight, { className: "h-4 w-4" }) })
4897
4922
  ] }),
4898
4923
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("grid grid-cols-7 gap-1", size === "sm" ? "mb-1" : "mb-2"), children: (weekdayLabels || ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]).map((day) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("text-muted-foreground text-center font-medium", size === "sm" ? "text-[10px] py-0.5" : "text-xs py-1"), children: day }, day)) }),
4899
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "grid grid-cols-7 gap-1", children: renderCalendar() })
4924
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "grid grid-cols-7 gap-1", children: renderCalendar() }),
4925
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex items-center justify-end mt-2", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4926
+ Button_default,
4927
+ {
4928
+ variant: "outline",
4929
+ size: "sm",
4930
+ onClick: () => {
4931
+ onChange(void 0);
4932
+ setIsOpen(false);
4933
+ setViewDate(/* @__PURE__ */ new Date());
4934
+ },
4935
+ children: clearLabel || t("clear")
4936
+ }
4937
+ ) })
4900
4938
  ]
4901
4939
  }
4902
4940
  )
@@ -4954,6 +4992,31 @@ var DatePicker = ({
4954
4992
  ),
4955
4993
  children: [
4956
4994
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: cn("truncate", !value && "text-muted-foreground"), children: value ? formatDateDisplay(value) : placeholder || t("placeholder") }),
4995
+ value && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4996
+ "span",
4997
+ {
4998
+ role: "button",
4999
+ "aria-label": clearLabel || t("clear"),
5000
+ tabIndex: 0,
5001
+ onClick: (e) => {
5002
+ e.preventDefault();
5003
+ e.stopPropagation();
5004
+ onChange(void 0);
5005
+ setViewDate(/* @__PURE__ */ new Date());
5006
+ },
5007
+ onKeyDown: (e) => {
5008
+ if (e.key === "Enter" || e.key === " ") {
5009
+ e.preventDefault();
5010
+ e.stopPropagation();
5011
+ onChange(void 0);
5012
+ setViewDate(/* @__PURE__ */ new Date());
5013
+ }
5014
+ },
5015
+ className: "absolute right-8 inline-flex items-center justify-center rounded-sm text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors cursor-pointer",
5016
+ style: { width: 20, height: 20 },
5017
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.X, { className: "h-3.5 w-3.5" })
5018
+ }
5019
+ ),
4957
5020
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Calendar, { className: "h-4 w-4 text-muted-foreground ml-2" })
4958
5021
  ]
4959
5022
  }
@@ -5191,7 +5254,9 @@ var MultiCombobox = ({
5191
5254
  disabled = false,
5192
5255
  size = "md",
5193
5256
  label,
5194
- required
5257
+ title,
5258
+ required,
5259
+ displayFormat = (option) => option.label
5195
5260
  }) => {
5196
5261
  const [query, setQuery] = React22.useState("");
5197
5262
  const [open, setOpen] = React22.useState(false);
@@ -5248,14 +5313,22 @@ var MultiCombobox = ({
5248
5313
  document.removeEventListener("keydown", handleEscape);
5249
5314
  };
5250
5315
  }, [open]);
5251
- const filtered = options.filter((o) => o.toLowerCase().includes(query.toLowerCase()));
5252
- const toggleSelect = (val) => {
5253
- if (disabledOptions.includes(val)) return;
5254
- if (value.includes(val)) {
5255
- onChange(value.filter((v) => v !== val));
5316
+ const normalizedOptions = React22.useMemo(
5317
+ () => options.map((o) => typeof o === "string" ? { value: o, label: o } : { value: o.value, label: o.label }),
5318
+ [options]
5319
+ );
5320
+ const enableSearch = normalizedOptions.length > 10;
5321
+ const filtered = React22.useMemo(
5322
+ () => enableSearch ? normalizedOptions.filter((opt) => opt.label.toLowerCase().includes(query.toLowerCase())) : normalizedOptions,
5323
+ [normalizedOptions, query, enableSearch]
5324
+ );
5325
+ const toggleSelect = (optionValue) => {
5326
+ if (disabledOptions.includes(optionValue)) return;
5327
+ if (value.includes(optionValue)) {
5328
+ onChange(value.filter((v) => v !== optionValue));
5256
5329
  } else {
5257
5330
  if (!maxSelected || value.length < maxSelected) {
5258
- onChange([...value, val]);
5331
+ onChange([...value, optionValue]);
5259
5332
  }
5260
5333
  }
5261
5334
  };
@@ -5267,7 +5340,7 @@ var MultiCombobox = ({
5267
5340
  if (e.key === "Enter") {
5268
5341
  e.preventDefault();
5269
5342
  if (activeIndex !== null && filtered[activeIndex]) {
5270
- toggleSelect(filtered[activeIndex]);
5343
+ toggleSelect(filtered[activeIndex].value);
5271
5344
  }
5272
5345
  }
5273
5346
  };
@@ -5275,12 +5348,12 @@ var MultiCombobox = ({
5275
5348
  onChange([]);
5276
5349
  };
5277
5350
  React22.useEffect(() => {
5278
- if (open) {
5351
+ if (open && enableSearch) {
5279
5352
  setTimeout(() => {
5280
5353
  inputRef.current?.focus();
5281
5354
  }, 100);
5282
5355
  }
5283
- }, [open]);
5356
+ }, [open, enableSearch]);
5284
5357
  const sizeStyles8 = {
5285
5358
  sm: {
5286
5359
  trigger: "h-8 px-3 py-1.5 text-sm md:h-7 md:text-xs",
@@ -5309,6 +5382,20 @@ var MultiCombobox = ({
5309
5382
  const labelId = label ? `${resolvedId}-label` : void 0;
5310
5383
  const labelSize = size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm";
5311
5384
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn("w-full space-y-2 group", className), children: [
5385
+ title && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5386
+ "label",
5387
+ {
5388
+ className: cn(
5389
+ size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm",
5390
+ "font-medium transition-colors duration-200",
5391
+ disabled ? "text-muted-foreground" : "text-foreground group-focus-within:text-primary"
5392
+ ),
5393
+ children: [
5394
+ title,
5395
+ required && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-destructive ml-1", children: "*" })
5396
+ ]
5397
+ }
5398
+ ) }),
5312
5399
  label && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5313
5400
  "label",
5314
5401
  {
@@ -5325,148 +5412,152 @@ var MultiCombobox = ({
5325
5412
  ]
5326
5413
  }
5327
5414
  ),
5328
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative w-full", children: [
5329
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
5330
- showTags && value.map((item) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: cn("flex items-center gap-1 rounded bg-accent text-accent-foreground", sizeStyles8[size].tag), children: [
5331
- item,
5332
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5333
- "button",
5334
- {
5335
- type: "button",
5336
- onClick: (e) => {
5337
- e.preventDefault();
5338
- e.stopPropagation();
5339
- handleRemove(item);
5340
- },
5341
- className: "text-xs hover:text-destructive",
5342
- children: "\xD7"
5343
- }
5344
- )
5345
- ] }, item)),
5346
- showClear && value.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5347
- "button",
5348
- {
5349
- type: "button",
5350
- onClick: (e) => {
5351
- e.preventDefault();
5352
- e.stopPropagation();
5353
- handleClearAll();
5354
- },
5355
- className: "ml-auto text-xs text-muted-foreground hover:underline",
5356
- children: "Clear all"
5415
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "relative w-full" }),
5416
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5417
+ "button",
5418
+ {
5419
+ ref: triggerRef,
5420
+ type: "button",
5421
+ disabled,
5422
+ id: resolvedId,
5423
+ "aria-labelledby": labelId,
5424
+ onClick: () => {
5425
+ const next = !open;
5426
+ if (next) {
5427
+ const pos = calculatePosition();
5428
+ if (pos) setDropdownPosition(pos);
5357
5429
  }
5358
- )
5359
- ] }),
5360
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5361
- "button",
5430
+ setOpen(next);
5431
+ },
5432
+ className: cn(
5433
+ "flex w-full items-center gap-2 rounded-lg border border-input bg-background shadow-sm min-h-[2.5rem]",
5434
+ "px-3 py-2",
5435
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
5436
+ "disabled:cursor-not-allowed disabled:opacity-50"
5437
+ ),
5438
+ children: [
5439
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex items-center gap-1 flex-wrap min-h-[1.5rem] flex-1", children: value.length > 0 ? showTags ? value.map((itemValue) => {
5440
+ const option = normalizedOptions.find((o) => o.value === itemValue);
5441
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "inline-flex items-center gap-1 bg-accent text-accent-foreground rounded px-2 py-1 text-xs", children: [
5442
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "truncate max-w-[120px]", children: option ? displayFormat(option) : itemValue }),
5443
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5444
+ "button",
5445
+ {
5446
+ type: "button",
5447
+ onClick: (e) => {
5448
+ e.preventDefault();
5449
+ e.stopPropagation();
5450
+ handleRemove(itemValue);
5451
+ },
5452
+ className: "hover:text-destructive transition-colors cursor-pointer",
5453
+ children: "\xD7"
5454
+ }
5455
+ )
5456
+ ] }, itemValue);
5457
+ }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "truncate text-sm", children: [
5458
+ value.length,
5459
+ " selected"
5460
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-muted-foreground", children: placeholder || "Select..." }) }),
5461
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.ChevronDown, { className: cn("opacity-50 transition-transform", sizeStyles8[size].icon, open && "rotate-180") })
5462
+ ]
5463
+ }
5464
+ ),
5465
+ open && dropdownPosition && typeof window !== "undefined" ? (0, import_react_dom8.createPortal)(
5466
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5467
+ "div",
5362
5468
  {
5363
- ref: triggerRef,
5364
- type: "button",
5365
- disabled,
5366
- id: resolvedId,
5367
- "aria-labelledby": labelId,
5368
- onClick: () => {
5369
- const next = !open;
5370
- if (next) {
5371
- const pos = calculatePosition();
5372
- if (pos) setDropdownPosition(pos);
5373
- }
5374
- setOpen(next);
5469
+ "data-dropdown": "multicombobox",
5470
+ style: {
5471
+ position: "absolute",
5472
+ top: dropdownPosition?.top || 0,
5473
+ left: dropdownPosition?.left || 0,
5474
+ width: dropdownPosition?.width || 200,
5475
+ zIndex: 9999
5375
5476
  },
5477
+ "data-state": open ? "open" : "closed",
5376
5478
  className: cn(
5377
- "flex w-full items-center justify-between rounded-lg border border-input bg-background shadow-sm",
5378
- sizeStyles8[size].trigger,
5379
- "outline-none focus:outline-none focus-visible:outline-none focus:ring-0 focus-visible:ring-0 focus:ring-offset-0",
5380
- "disabled:cursor-not-allowed disabled:opacity-50"
5479
+ "z-[9999]",
5480
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
5481
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
5381
5482
  ),
5382
- children: [
5383
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "truncate", children: value.length ? `${value.length} selected` : placeholder || "Select..." }),
5384
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.ChevronDown, { className: cn("opacity-50 transition-transform", sizeStyles8[size].icon, open && "rotate-180") })
5385
- ]
5483
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5484
+ "div",
5485
+ {
5486
+ className: cn(
5487
+ "rounded-md border bg-popover text-popover-foreground shadow-md",
5488
+ "backdrop-blur-sm bg-popover/95 border-border/60"
5489
+ ),
5490
+ children: [
5491
+ showClear && value.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "px-3 py-2 border-b border-border/60 flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5492
+ "button",
5493
+ {
5494
+ type: "button",
5495
+ onClick: (e) => {
5496
+ e.preventDefault();
5497
+ e.stopPropagation();
5498
+ handleClearAll();
5499
+ },
5500
+ className: "text-xs text-muted-foreground hover:underline cursor-pointer",
5501
+ children: "Clear all"
5502
+ }
5503
+ ) }),
5504
+ enableSearch && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative border-b border-border/60", children: [
5505
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.Search, { className: cn("absolute left-2 top-2.5 text-muted-foreground", sizeStyles8[size].icon) }),
5506
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5507
+ "input",
5508
+ {
5509
+ ref: inputRef,
5510
+ value: query,
5511
+ onChange: (e) => {
5512
+ setQuery(e.target.value);
5513
+ setActiveIndex(null);
5514
+ },
5515
+ onKeyDown: handleKeyDown,
5516
+ placeholder,
5517
+ className: cn("w-full rounded-t-md bg-transparent focus:outline-none cursor-text", sizeStyles8[size].search)
5518
+ }
5519
+ )
5520
+ ] }),
5521
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("ul", { className: cn("max-h-60 overflow-y-auto p-1", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"), children: filtered.length ? filtered.map((item, index) => {
5522
+ const isSelected = value.includes(item.value);
5523
+ const isDisabled = disabledOptions.includes(item.value);
5524
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5525
+ "li",
5526
+ {
5527
+ ref: (node) => {
5528
+ listRef.current[index] = node;
5529
+ },
5530
+ onClick: (e) => {
5531
+ e.preventDefault();
5532
+ e.stopPropagation();
5533
+ toggleSelect(item.value);
5534
+ inputRef.current?.focus();
5535
+ },
5536
+ style: {
5537
+ animationDelay: open ? `${index * 25}ms` : "0ms"
5538
+ },
5539
+ className: cn(
5540
+ "dropdown-item flex cursor-pointer items-center justify-between rounded-sm transition-colors",
5541
+ sizeStyles8[size].item,
5542
+ "hover:bg-accent hover:text-accent-foreground",
5543
+ index === activeIndex && "bg-accent text-accent-foreground",
5544
+ isDisabled && "opacity-50 cursor-not-allowed pointer-events-none"
5545
+ ),
5546
+ children: [
5547
+ item.label,
5548
+ isSelected && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.Check, { className: sizeStyles8[size].icon })
5549
+ ]
5550
+ },
5551
+ item.value
5552
+ );
5553
+ }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("li", { className: cn("px-3 py-2 text-muted-foreground", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"), children: "No result." }) })
5554
+ ]
5555
+ }
5556
+ )
5386
5557
  }
5387
5558
  ),
5388
- open && dropdownPosition && typeof window !== "undefined" && (0, import_react_dom8.createPortal)(
5389
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5390
- "div",
5391
- {
5392
- "data-dropdown": "multicombobox",
5393
- style: {
5394
- position: "absolute",
5395
- top: dropdownPosition?.top || 0,
5396
- left: dropdownPosition?.left || 0,
5397
- width: dropdownPosition?.width || 200,
5398
- zIndex: 9999
5399
- },
5400
- "data-state": open ? "open" : "closed",
5401
- className: cn(
5402
- "z-[9999]",
5403
- "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
5404
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
5405
- ),
5406
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5407
- "div",
5408
- {
5409
- className: cn(
5410
- "rounded-md border bg-popover text-popover-foreground shadow-md",
5411
- "backdrop-blur-sm bg-popover/95 border-border/60"
5412
- ),
5413
- children: [
5414
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative border-b border-border/60", children: [
5415
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.Search, { className: cn("absolute left-2 top-2.5 text-muted-foreground", sizeStyles8[size].icon) }),
5416
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5417
- "input",
5418
- {
5419
- ref: inputRef,
5420
- value: query,
5421
- onChange: (e) => {
5422
- setQuery(e.target.value);
5423
- setActiveIndex(null);
5424
- },
5425
- onKeyDown: handleKeyDown,
5426
- placeholder,
5427
- className: cn("w-full rounded-t-md bg-transparent focus:outline-none", sizeStyles8[size].search)
5428
- }
5429
- )
5430
- ] }),
5431
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("ul", { className: cn("max-h-60 overflow-y-auto p-1", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"), children: filtered.length ? filtered.map((item, index) => {
5432
- const isSelected = value.includes(item);
5433
- const isDisabled = disabledOptions.includes(item);
5434
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5435
- "li",
5436
- {
5437
- ref: (node) => {
5438
- listRef.current[index] = node;
5439
- },
5440
- onClick: () => {
5441
- toggleSelect(item);
5442
- inputRef.current?.focus();
5443
- },
5444
- style: {
5445
- animationDelay: open ? `${index * 25}ms` : "0ms"
5446
- },
5447
- className: cn(
5448
- "dropdown-item flex cursor-pointer items-center justify-between rounded-sm transition-colors",
5449
- sizeStyles8[size].item,
5450
- "hover:bg-accent hover:text-accent-foreground",
5451
- index === activeIndex && "bg-accent text-accent-foreground",
5452
- isDisabled && "opacity-50 cursor-not-allowed pointer-events-none"
5453
- ),
5454
- children: [
5455
- item,
5456
- isSelected && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.Check, { className: sizeStyles8[size].icon })
5457
- ]
5458
- },
5459
- item
5460
- );
5461
- }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("li", { className: cn("px-3 py-2 text-muted-foreground", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"), children: "No result." }) })
5462
- ]
5463
- }
5464
- )
5465
- }
5466
- ),
5467
- document.body
5468
- )
5469
- ] })
5559
+ document.body
5560
+ ) : null
5470
5561
  ] });
5471
5562
  };
5472
5563