@andreagiugni/tailwind-dashboard-ui 1.0.5 → 1.0.7
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/README.md +2 -2
- package/dist/index.cjs +233 -125
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +233 -125
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -199,8 +199,8 @@ Legend: **(+native)** = also extends the element's native HTML attributes.
|
|
|
199
199
|
|---|---|
|
|
200
200
|
| `Input` | `type`, `value` / `defaultValue`, `onChange`, `success`, `error`, `hint`, `disabled`, (+native input) (+override) |
|
|
201
201
|
| `Label` | `htmlFor`, `children`, (+native label) |
|
|
202
|
-
| `Select` | `options` (`{ value, label, icon? }[]`), `placeholder`, `defaultValue`, `onChange(value)`, `disabled` |
|
|
203
|
-
| `MultiSelect` | `options`, `selected` / `defaultSelected`, `onChange`, `placeholder`, `disabled` |
|
|
202
|
+
| `Select` | `options` (`{ value, label, icon? }[]`), `placeholder`, `defaultValue`, `onChange(value)`, `disabled`, `portal?` (default `true`, prevents clipping inside tables/cards) |
|
|
203
|
+
| `MultiSelect` | `options`, `selected` / `defaultSelected`, `onChange`, `placeholder`, `disabled`, `portal?` (default `true`, prevents clipping inside tables/cards) |
|
|
204
204
|
| `Checkbox` | `label`, `checked`, `onChange(checked)`, `disabled`, `checkedColor?` |
|
|
205
205
|
| `Radio` / `RadioSm` | `id`, `name`, `value`, `checked`, `label`, `onChange(value)`, `disabled` |
|
|
206
206
|
| `Switch` | `label?`, `checked` / `defaultChecked`, `onChange(checked)`, `color` (blue/gray), `disabled` |
|
package/dist/index.cjs
CHANGED
|
@@ -817,7 +817,7 @@ function DataDrivenTable({
|
|
|
817
817
|
}
|
|
818
818
|
)
|
|
819
819
|
] }),
|
|
820
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
820
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-y border-gray-100 dark:border-white/[0.05]", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full", children: [
|
|
821
821
|
/* @__PURE__ */ jsxRuntime.jsx(TableHeader, { className: "border-b border-gray-100 bg-gray-50 dark:border-white/[0.05] dark:bg-white/[0.06]", children: /* @__PURE__ */ jsxRuntime.jsx(TableRow, { children: columns.map((col) => {
|
|
822
822
|
const isActive = sortKey === col.key;
|
|
823
823
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2319,15 +2319,20 @@ var Select = ({
|
|
|
2319
2319
|
onChange,
|
|
2320
2320
|
className,
|
|
2321
2321
|
defaultValue = "",
|
|
2322
|
-
disabled = false
|
|
2322
|
+
disabled = false,
|
|
2323
|
+
portal = true
|
|
2323
2324
|
}) => {
|
|
2324
2325
|
const [selectedValue, setSelectedValue] = React5.useState(defaultValue);
|
|
2325
2326
|
const [isOpen, setIsOpen] = React5.useState(false);
|
|
2326
2327
|
const rootRef = React5.useRef(null);
|
|
2328
|
+
const triggerRef = React5.useRef(null);
|
|
2329
|
+
const menuRef = React5.useRef(null);
|
|
2330
|
+
const [menuPosition, setMenuPosition] = React5.useState();
|
|
2327
2331
|
React5.useEffect(() => {
|
|
2328
2332
|
if (!isOpen) return;
|
|
2329
2333
|
const onPointerDown = (e) => {
|
|
2330
|
-
|
|
2334
|
+
const target = e.target;
|
|
2335
|
+
if (rootRef.current && !rootRef.current.contains(target) && !menuRef.current?.contains(target)) {
|
|
2331
2336
|
setIsOpen(false);
|
|
2332
2337
|
}
|
|
2333
2338
|
};
|
|
@@ -2341,6 +2346,33 @@ var Select = ({
|
|
|
2341
2346
|
document.removeEventListener("keydown", onKeyDown);
|
|
2342
2347
|
};
|
|
2343
2348
|
}, [isOpen]);
|
|
2349
|
+
React5.useLayoutEffect(() => {
|
|
2350
|
+
if (!isOpen || !portal) return;
|
|
2351
|
+
const updatePosition = () => {
|
|
2352
|
+
const trigger = triggerRef.current;
|
|
2353
|
+
const menu = menuRef.current;
|
|
2354
|
+
if (!trigger || !menu) return;
|
|
2355
|
+
const rect = trigger.getBoundingClientRect();
|
|
2356
|
+
const menuHeight = menu.offsetHeight;
|
|
2357
|
+
const viewportPadding = 8;
|
|
2358
|
+
const gap = 6;
|
|
2359
|
+
const width = rect.width;
|
|
2360
|
+
const fitsBelow = window.innerHeight - rect.bottom - gap >= menuHeight + viewportPadding;
|
|
2361
|
+
const top = fitsBelow ? rect.bottom + gap : Math.max(viewportPadding, rect.top - gap - menuHeight);
|
|
2362
|
+
const left = Math.min(
|
|
2363
|
+
Math.max(viewportPadding, rect.left),
|
|
2364
|
+
window.innerWidth - width - viewportPadding
|
|
2365
|
+
);
|
|
2366
|
+
setMenuPosition({ top, left, width });
|
|
2367
|
+
};
|
|
2368
|
+
updatePosition();
|
|
2369
|
+
window.addEventListener("resize", updatePosition);
|
|
2370
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
2371
|
+
return () => {
|
|
2372
|
+
window.removeEventListener("resize", updatePosition);
|
|
2373
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
2374
|
+
};
|
|
2375
|
+
}, [isOpen, portal]);
|
|
2344
2376
|
const toggleOpen = () => {
|
|
2345
2377
|
if (!disabled) setIsOpen((prev) => !prev);
|
|
2346
2378
|
};
|
|
@@ -2354,6 +2386,7 @@ var Select = ({
|
|
|
2354
2386
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2355
2387
|
"button",
|
|
2356
2388
|
{
|
|
2389
|
+
ref: triggerRef,
|
|
2357
2390
|
type: "button",
|
|
2358
2391
|
onClick: toggleOpen,
|
|
2359
2392
|
disabled,
|
|
@@ -2389,52 +2422,61 @@ var Select = ({
|
|
|
2389
2422
|
]
|
|
2390
2423
|
}
|
|
2391
2424
|
),
|
|
2392
|
-
isOpen &&
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
"
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2425
|
+
isOpen && (() => {
|
|
2426
|
+
const menu = /* @__PURE__ */ jsxRuntime.jsx(
|
|
2427
|
+
"ul",
|
|
2428
|
+
{
|
|
2429
|
+
ref: menuRef,
|
|
2430
|
+
role: "listbox",
|
|
2431
|
+
className: chunkYERNSNT4_cjs.cn(
|
|
2432
|
+
"max-h-60 overflow-y-auto rounded-lg border border-gray-200 bg-white py-1 shadow-theme-lg dark:border-gray-800 dark:bg-gray-900",
|
|
2433
|
+
portal ? chunkYERNSNT4_cjs.cn("fixed", chunkTF3G3E72_cjs.layers.portal) : chunkYERNSNT4_cjs.cn("absolute left-0 top-full mt-1.5 w-full", chunkTF3G3E72_cjs.layers.menu)
|
|
2434
|
+
),
|
|
2435
|
+
style: {
|
|
2436
|
+
...portal && !menuPosition ? { visibility: "hidden" } : void 0,
|
|
2437
|
+
...portal ? menuPosition : void 0
|
|
2438
|
+
},
|
|
2439
|
+
children: options.map((option) => {
|
|
2440
|
+
const isSelected = option.value === selectedValue;
|
|
2441
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2442
|
+
"li",
|
|
2443
|
+
{
|
|
2444
|
+
role: "option",
|
|
2445
|
+
"aria-selected": isSelected,
|
|
2446
|
+
onClick: () => handleSelect(option.value),
|
|
2447
|
+
className: chunkYERNSNT4_cjs.cn(
|
|
2448
|
+
"flex cursor-pointer items-center justify-between px-4 py-2 text-sm transition hover:bg-gray-50 dark:hover:bg-white/5",
|
|
2449
|
+
isSelected ? "bg-brand-50 font-medium text-brand-600 dark:bg-brand-500/15 dark:text-brand-400" : "text-gray-700 dark:text-gray-300"
|
|
2450
|
+
),
|
|
2451
|
+
children: [
|
|
2452
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
2453
|
+
option.icon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2454
|
+
"span",
|
|
2455
|
+
{
|
|
2456
|
+
"aria-hidden": "true",
|
|
2457
|
+
className: "flex h-5 w-5 shrink-0 items-center justify-center [&>svg]:size-4",
|
|
2458
|
+
children: option.icon
|
|
2459
|
+
}
|
|
2460
|
+
),
|
|
2461
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: option.label })
|
|
2462
|
+
] }),
|
|
2463
|
+
isSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2464
|
+
lucideReact.Check,
|
|
2416
2465
|
{
|
|
2417
|
-
"
|
|
2418
|
-
|
|
2419
|
-
children: option.icon
|
|
2466
|
+
className: "ml-2 size-4 shrink-0 stroke-current",
|
|
2467
|
+
"aria-hidden": "true"
|
|
2420
2468
|
}
|
|
2421
|
-
)
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
},
|
|
2433
|
-
option.value
|
|
2434
|
-
);
|
|
2435
|
-
})
|
|
2436
|
-
}
|
|
2437
|
-
)
|
|
2469
|
+
)
|
|
2470
|
+
]
|
|
2471
|
+
},
|
|
2472
|
+
option.value
|
|
2473
|
+
);
|
|
2474
|
+
})
|
|
2475
|
+
}
|
|
2476
|
+
);
|
|
2477
|
+
if (!portal || typeof document === "undefined") return menu;
|
|
2478
|
+
return reactDom.createPortal(menu, document.body);
|
|
2479
|
+
})()
|
|
2438
2480
|
] });
|
|
2439
2481
|
};
|
|
2440
2482
|
var MultiSelect = ({
|
|
@@ -2442,10 +2484,60 @@ var MultiSelect = ({
|
|
|
2442
2484
|
options,
|
|
2443
2485
|
defaultSelected = [],
|
|
2444
2486
|
onChange,
|
|
2445
|
-
disabled = false
|
|
2487
|
+
disabled = false,
|
|
2488
|
+
portal = true
|
|
2446
2489
|
}) => {
|
|
2447
2490
|
const [selectedOptions, setSelectedOptions] = React5.useState(defaultSelected);
|
|
2448
2491
|
const [isOpen, setIsOpen] = React5.useState(false);
|
|
2492
|
+
const rootRef = React5.useRef(null);
|
|
2493
|
+
const triggerRef = React5.useRef(null);
|
|
2494
|
+
const menuRef = React5.useRef(null);
|
|
2495
|
+
const [menuPosition, setMenuPosition] = React5.useState();
|
|
2496
|
+
React5.useEffect(() => {
|
|
2497
|
+
if (!isOpen) return;
|
|
2498
|
+
const onPointerDown = (event) => {
|
|
2499
|
+
const target = event.target;
|
|
2500
|
+
if (rootRef.current && !rootRef.current.contains(target) && !menuRef.current?.contains(target)) {
|
|
2501
|
+
setIsOpen(false);
|
|
2502
|
+
}
|
|
2503
|
+
};
|
|
2504
|
+
const onKeyDown = (event) => {
|
|
2505
|
+
if (event.key === "Escape") setIsOpen(false);
|
|
2506
|
+
};
|
|
2507
|
+
document.addEventListener("mousedown", onPointerDown);
|
|
2508
|
+
document.addEventListener("keydown", onKeyDown);
|
|
2509
|
+
return () => {
|
|
2510
|
+
document.removeEventListener("mousedown", onPointerDown);
|
|
2511
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
2512
|
+
};
|
|
2513
|
+
}, [isOpen]);
|
|
2514
|
+
React5.useLayoutEffect(() => {
|
|
2515
|
+
if (!isOpen || !portal) return;
|
|
2516
|
+
const updatePosition = () => {
|
|
2517
|
+
const trigger = triggerRef.current;
|
|
2518
|
+
const menu = menuRef.current;
|
|
2519
|
+
if (!trigger || !menu) return;
|
|
2520
|
+
const rect = trigger.getBoundingClientRect();
|
|
2521
|
+
const menuHeight = menu.offsetHeight;
|
|
2522
|
+
const viewportPadding = 8;
|
|
2523
|
+
const gap = 6;
|
|
2524
|
+
const width = rect.width;
|
|
2525
|
+
const fitsBelow = window.innerHeight - rect.bottom - gap >= menuHeight + viewportPadding;
|
|
2526
|
+
const top = fitsBelow ? rect.bottom + gap : Math.max(viewportPadding, rect.top - gap - menuHeight);
|
|
2527
|
+
const left = Math.min(
|
|
2528
|
+
Math.max(viewportPadding, rect.left),
|
|
2529
|
+
window.innerWidth - width - viewportPadding
|
|
2530
|
+
);
|
|
2531
|
+
setMenuPosition({ top, left, width });
|
|
2532
|
+
};
|
|
2533
|
+
updatePosition();
|
|
2534
|
+
window.addEventListener("resize", updatePosition);
|
|
2535
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
2536
|
+
return () => {
|
|
2537
|
+
window.removeEventListener("resize", updatePosition);
|
|
2538
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
2539
|
+
};
|
|
2540
|
+
}, [isOpen, portal]);
|
|
2449
2541
|
const toggleDropdown = () => {
|
|
2450
2542
|
if (disabled) return;
|
|
2451
2543
|
setIsOpen((prev) => !prev);
|
|
@@ -2463,94 +2555,110 @@ var MultiSelect = ({
|
|
|
2463
2555
|
const selectedValuesText = selectedOptions.map(
|
|
2464
2556
|
(value) => options.find((option) => option.value === value)?.text || ""
|
|
2465
2557
|
);
|
|
2466
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
2558
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: rootRef, className: "w-full", children: [
|
|
2467
2559
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-400", children: label }),
|
|
2468
2560
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative inline-block w-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col items-center", children: [
|
|
2469
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { onClick: toggleDropdown, className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2470
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap flex-auto gap-2", children: selectedValuesText.length > 0 ? selectedValuesText.map((text, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2471
|
-
"div",
|
|
2472
|
-
{
|
|
2473
|
-
className: "group flex items-center justify-center rounded-full border-[0.7px] border-transparent bg-gray-100 py-1 pl-2.5 pr-2 text-sm text-gray-800 hover:border-gray-200 dark:bg-gray-800 dark:text-white/90 dark:hover:border-gray-800",
|
|
2474
|
-
children: [
|
|
2475
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-initial max-w-full", children: text }),
|
|
2476
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row-reverse flex-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2477
|
-
"div",
|
|
2478
|
-
{
|
|
2479
|
-
onClick: () => removeOption(index, selectedOptions[index]),
|
|
2480
|
-
className: "pl-2 text-gray-500 cursor-pointer group-hover:text-gray-400 dark:text-gray-400",
|
|
2481
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4", role: "button", "aria-hidden": "true" })
|
|
2482
|
-
}
|
|
2483
|
-
) })
|
|
2484
|
-
]
|
|
2485
|
-
},
|
|
2486
|
-
index
|
|
2487
|
-
)) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2488
|
-
"input",
|
|
2489
|
-
{
|
|
2490
|
-
placeholder: "Select option",
|
|
2491
|
-
className: "w-full h-full p-1 pr-2 text-sm bg-transparent border-0 outline-hidden appearance-none placeholder:text-gray-800 focus:border-0 focus:outline-hidden focus:ring-0 dark:placeholder:text-white/90",
|
|
2492
|
-
readOnly: true,
|
|
2493
|
-
value: "Select option"
|
|
2494
|
-
}
|
|
2495
|
-
) }),
|
|
2496
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center py-1 pl-1 pr-1 w-7", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2497
|
-
"button",
|
|
2498
|
-
{
|
|
2499
|
-
type: "button",
|
|
2500
|
-
onClick: toggleDropdown,
|
|
2501
|
-
className: "w-5 h-5 text-gray-700 outline-hidden cursor-pointer focus:outline-hidden dark:text-gray-400",
|
|
2502
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2503
|
-
lucideReact.ChevronDown,
|
|
2504
|
-
{
|
|
2505
|
-
className: `size-4 stroke-current ${isOpen ? "rotate-180" : ""}`,
|
|
2506
|
-
"aria-hidden": "true"
|
|
2507
|
-
}
|
|
2508
|
-
)
|
|
2509
|
-
}
|
|
2510
|
-
) })
|
|
2511
|
-
] }) }),
|
|
2512
|
-
isOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2561
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { onClick: toggleDropdown, className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2513
2562
|
"div",
|
|
2514
2563
|
{
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
onClick: (e) => e.stopPropagation(),
|
|
2520
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col", children: options.map((option, index) => {
|
|
2521
|
-
const isSelected = selectedOptions.includes(option.value);
|
|
2522
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2564
|
+
ref: triggerRef,
|
|
2565
|
+
className: "mb-2 flex h-11 rounded-lg border border-gray-300 bg-white py-1.5 px-4 shadow-theme-xs outline-hidden transition focus:border-brand-300 focus:shadow-focus-ring dark:border-gray-700 dark:bg-gray-900 dark:focus:border-brand-300",
|
|
2566
|
+
children: [
|
|
2567
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap flex-auto gap-2", children: selectedValuesText.length > 0 ? selectedValuesText.map((text, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2523
2568
|
"div",
|
|
2524
2569
|
{
|
|
2525
|
-
className:
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
"div",
|
|
2570
|
+
className: "group flex items-center justify-center rounded-full border-[0.7px] border-transparent bg-gray-100 py-1 pl-2.5 pr-2 text-sm text-gray-800 hover:border-gray-200 dark:bg-gray-800 dark:text-white/90 dark:hover:border-gray-800",
|
|
2571
|
+
children: [
|
|
2572
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-initial max-w-full", children: text }),
|
|
2573
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row-reverse flex-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2574
|
+
"div",
|
|
2575
|
+
{
|
|
2576
|
+
onClick: () => removeOption(index, selectedOptions[index]),
|
|
2577
|
+
className: "pl-2 text-gray-500 cursor-pointer group-hover:text-gray-400 dark:text-gray-400",
|
|
2578
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4", role: "button", "aria-hidden": "true" })
|
|
2579
|
+
}
|
|
2580
|
+
) })
|
|
2581
|
+
]
|
|
2582
|
+
},
|
|
2583
|
+
index
|
|
2584
|
+
)) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2585
|
+
"input",
|
|
2586
|
+
{
|
|
2587
|
+
placeholder: "Select option",
|
|
2588
|
+
className: "w-full h-full p-1 pr-2 text-sm bg-transparent border-0 outline-hidden appearance-none placeholder:text-gray-800 focus:border-0 focus:outline-hidden focus:ring-0 dark:placeholder:text-white/90",
|
|
2589
|
+
readOnly: true,
|
|
2590
|
+
value: "Select option"
|
|
2591
|
+
}
|
|
2592
|
+
) }),
|
|
2593
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center py-1 pl-1 pr-1 w-7", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2594
|
+
"button",
|
|
2595
|
+
{
|
|
2596
|
+
type: "button",
|
|
2597
|
+
onClick: toggleDropdown,
|
|
2598
|
+
className: "w-5 h-5 text-gray-700 outline-hidden cursor-pointer focus:outline-hidden dark:text-gray-400",
|
|
2599
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2600
|
+
lucideReact.ChevronDown,
|
|
2529
2601
|
{
|
|
2530
|
-
className: `
|
|
2531
|
-
|
|
2532
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2533
|
-
"div",
|
|
2534
|
-
{
|
|
2535
|
-
className: `mx-2 leading-6 ${isSelected ? "font-medium text-brand-600 dark:text-brand-400" : "text-gray-800 dark:text-white/90"}`,
|
|
2536
|
-
children: option.text
|
|
2537
|
-
}
|
|
2538
|
-
),
|
|
2539
|
-
isSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2540
|
-
lucideReact.Check,
|
|
2541
|
-
{
|
|
2542
|
-
className: "mr-2 size-4 shrink-0 stroke-current text-brand-500",
|
|
2543
|
-
"aria-hidden": "true"
|
|
2544
|
-
}
|
|
2545
|
-
)
|
|
2546
|
-
]
|
|
2602
|
+
className: `size-4 stroke-current ${isOpen ? "rotate-180" : ""}`,
|
|
2603
|
+
"aria-hidden": "true"
|
|
2547
2604
|
}
|
|
2548
2605
|
)
|
|
2549
2606
|
}
|
|
2550
|
-
) }
|
|
2551
|
-
|
|
2607
|
+
) })
|
|
2608
|
+
]
|
|
2552
2609
|
}
|
|
2553
|
-
)
|
|
2610
|
+
) }),
|
|
2611
|
+
isOpen && (() => {
|
|
2612
|
+
const menu = /* @__PURE__ */ jsxRuntime.jsx(
|
|
2613
|
+
"div",
|
|
2614
|
+
{
|
|
2615
|
+
ref: menuRef,
|
|
2616
|
+
className: chunkYERNSNT4_cjs.cn(
|
|
2617
|
+
"max-h-select overflow-y-auto rounded-lg bg-white shadow-sm dark:bg-gray-900",
|
|
2618
|
+
portal ? chunkYERNSNT4_cjs.cn("fixed", chunkTF3G3E72_cjs.layers.portal) : chunkYERNSNT4_cjs.cn("absolute left-0 top-full w-full", chunkTF3G3E72_cjs.layers.menu)
|
|
2619
|
+
),
|
|
2620
|
+
style: {
|
|
2621
|
+
...portal && !menuPosition ? { visibility: "hidden" } : void 0,
|
|
2622
|
+
...portal ? menuPosition : void 0
|
|
2623
|
+
},
|
|
2624
|
+
onClick: (e) => e.stopPropagation(),
|
|
2625
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col", children: options.map((option, index) => {
|
|
2626
|
+
const isSelected = selectedOptions.includes(option.value);
|
|
2627
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2628
|
+
"div",
|
|
2629
|
+
{
|
|
2630
|
+
className: `w-full cursor-pointer rounded-t border-b border-gray-200 hover:bg-brand-500/5 dark:border-gray-800`,
|
|
2631
|
+
onClick: () => handleSelect(option.value),
|
|
2632
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2633
|
+
"div",
|
|
2634
|
+
{
|
|
2635
|
+
className: `relative flex w-full items-center justify-between p-2 pl-2 ${isSelected ? "bg-brand-500/10" : ""}`,
|
|
2636
|
+
children: [
|
|
2637
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2638
|
+
"div",
|
|
2639
|
+
{
|
|
2640
|
+
className: `mx-2 leading-6 ${isSelected ? "font-medium text-brand-600 dark:text-brand-400" : "text-gray-800 dark:text-white/90"}`,
|
|
2641
|
+
children: option.text
|
|
2642
|
+
}
|
|
2643
|
+
),
|
|
2644
|
+
isSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2645
|
+
lucideReact.Check,
|
|
2646
|
+
{
|
|
2647
|
+
className: "mr-2 size-4 shrink-0 stroke-current text-brand-500",
|
|
2648
|
+
"aria-hidden": "true"
|
|
2649
|
+
}
|
|
2650
|
+
)
|
|
2651
|
+
]
|
|
2652
|
+
}
|
|
2653
|
+
)
|
|
2654
|
+
}
|
|
2655
|
+
) }, index);
|
|
2656
|
+
}) })
|
|
2657
|
+
}
|
|
2658
|
+
);
|
|
2659
|
+
if (!portal || typeof document === "undefined") return menu;
|
|
2660
|
+
return reactDom.createPortal(menu, document.body);
|
|
2661
|
+
})()
|
|
2554
2662
|
] }) })
|
|
2555
2663
|
] });
|
|
2556
2664
|
};
|