@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 +251 -160
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +252 -161
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
4193
|
+
"flex w-full items-center justify-between border border-input bg-background px-3",
|
|
4190
4194
|
radiusClass,
|
|
4191
4195
|
sizeStyles8[size],
|
|
4192
|
-
"
|
|
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
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
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,
|
|
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.
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
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
|
-
|
|
5361
|
-
|
|
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
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
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
|
-
"
|
|
5378
|
-
|
|
5379
|
-
"
|
|
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
|
-
|
|
5384
|
-
|
|
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
|
-
|
|
5389
|
-
|
|
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
|
|