@andreagiugni/tailwind-dashboard-ui 1.0.4 → 1.0.6
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 +3 -3
- package/dist/index.cjs +272 -130
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +272 -130
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -199,11 +199,11 @@ 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
|
-
| `Switch` | `label
|
|
206
|
+
| `Switch` | `label?`, `checked` / `defaultChecked`, `onChange(checked)`, `color` (blue/gray), `disabled` |
|
|
207
207
|
| `TextArea` | `value`, `onChange`, `rows`, `success`, `error`, `hint`, `disabled` |
|
|
208
208
|
| `FileInput` | `onChange`, `accept`, `multiple`, (+native input) |
|
|
209
209
|
| `PasswordInput` | password field with a show/hide eye toggle, (+native input attrs) |
|
package/dist/index.cjs
CHANGED
|
@@ -632,6 +632,8 @@ var Input = ({
|
|
|
632
632
|
style,
|
|
633
633
|
...rest
|
|
634
634
|
}) => {
|
|
635
|
+
const placeholder = typeof rest.placeholder === "string" ? rest.placeholder.trim() : "";
|
|
636
|
+
const placeholderMinWidth = placeholder ? `${Math.min(Math.max(placeholder.length + 6, 18), 40)}ch` : void 0;
|
|
635
637
|
const stateClass = disabled ? "text-gray-500 border-gray-300 cursor-not-allowed dark:bg-gray-800 dark:text-gray-400 dark:border-gray-700" : error ? "text-error-800 border-error-500 focus:ring-3 focus:ring-error-500/10 dark:text-error-400 dark:border-error-500" : success ? "text-success-500 border-success-400 focus:ring-success-500/10 focus:border-success-300 dark:text-success-400 dark:border-success-500" : "text-gray-800 border-gray-300 focus:border-brand-300 focus:ring-3 focus:ring-brand-500/10 dark:border-gray-700 dark:text-white/90 dark:focus:border-brand-800";
|
|
636
638
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
637
639
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -643,7 +645,11 @@ var Input = ({
|
|
|
643
645
|
stateClass,
|
|
644
646
|
className
|
|
645
647
|
),
|
|
646
|
-
style: {
|
|
648
|
+
style: {
|
|
649
|
+
minWidth: placeholderMinWidth,
|
|
650
|
+
...styleOverride({ bgColor, textColor, borderColor }),
|
|
651
|
+
...style
|
|
652
|
+
},
|
|
647
653
|
...rest
|
|
648
654
|
}
|
|
649
655
|
),
|
|
@@ -807,7 +813,7 @@ function DataDrivenTable({
|
|
|
807
813
|
setSearch(e.target.value);
|
|
808
814
|
setPage(1);
|
|
809
815
|
},
|
|
810
|
-
className: "
|
|
816
|
+
className: "sm:w-auto"
|
|
811
817
|
}
|
|
812
818
|
)
|
|
813
819
|
] }),
|
|
@@ -2220,7 +2226,12 @@ var Switch = ({
|
|
|
2220
2226
|
defaultChecked = false,
|
|
2221
2227
|
disabled = false,
|
|
2222
2228
|
onChange,
|
|
2223
|
-
color = "blue"
|
|
2229
|
+
color = "blue",
|
|
2230
|
+
className,
|
|
2231
|
+
onClick,
|
|
2232
|
+
onKeyDown,
|
|
2233
|
+
"aria-label": ariaLabel,
|
|
2234
|
+
...rest
|
|
2224
2235
|
}) => {
|
|
2225
2236
|
const isControlled = checked !== void 0;
|
|
2226
2237
|
const [internalChecked, setInternalChecked] = React5.useState(defaultChecked);
|
|
@@ -2235,6 +2246,20 @@ var Switch = ({
|
|
|
2235
2246
|
onChange(newCheckedState);
|
|
2236
2247
|
}
|
|
2237
2248
|
};
|
|
2249
|
+
const handleClick = (event) => {
|
|
2250
|
+
onClick?.(event);
|
|
2251
|
+
if (!event.defaultPrevented) {
|
|
2252
|
+
handleToggle();
|
|
2253
|
+
}
|
|
2254
|
+
};
|
|
2255
|
+
const handleKeyDown = (event) => {
|
|
2256
|
+
onKeyDown?.(event);
|
|
2257
|
+
if (event.defaultPrevented) return;
|
|
2258
|
+
if (event.key === " " || event.key === "Enter") {
|
|
2259
|
+
event.preventDefault();
|
|
2260
|
+
handleToggle();
|
|
2261
|
+
}
|
|
2262
|
+
};
|
|
2238
2263
|
const offTrack = "bg-gray-200 ring-1 ring-inset ring-gray-300 dark:bg-white/10 dark:ring-gray-700";
|
|
2239
2264
|
const switchColors = color === "blue" ? {
|
|
2240
2265
|
background: isChecked ? "bg-brand-500 " : offTrack,
|
|
@@ -2245,14 +2270,23 @@ var Switch = ({
|
|
|
2245
2270
|
// Gray version
|
|
2246
2271
|
knob: isChecked ? "translate-x-full bg-white" : "translate-x-0 bg-white"
|
|
2247
2272
|
};
|
|
2273
|
+
const hasLabel = label !== void 0 && label !== null && label !== "";
|
|
2248
2274
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2249
2275
|
"label",
|
|
2250
2276
|
{
|
|
2277
|
+
role: "switch",
|
|
2278
|
+
"aria-checked": isChecked,
|
|
2279
|
+
"aria-disabled": disabled || void 0,
|
|
2280
|
+
"aria-label": ariaLabel ?? (!hasLabel ? "Toggle switch" : void 0),
|
|
2281
|
+
tabIndex: disabled ? -1 : 0,
|
|
2251
2282
|
className: chunkYERNSNT4_cjs.cn(
|
|
2252
2283
|
"flex cursor-pointer select-none items-center gap-3 text-sm font-medium",
|
|
2253
|
-
disabled ? "text-gray-400" : "text-gray-700 dark:text-gray-400"
|
|
2284
|
+
disabled ? "text-gray-400" : "text-gray-700 dark:text-gray-400",
|
|
2285
|
+
className
|
|
2254
2286
|
),
|
|
2255
|
-
onClick:
|
|
2287
|
+
onClick: handleClick,
|
|
2288
|
+
onKeyDown: handleKeyDown,
|
|
2289
|
+
...rest,
|
|
2256
2290
|
children: [
|
|
2257
2291
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
2258
2292
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2274,7 +2308,7 @@ var Switch = ({
|
|
|
2274
2308
|
}
|
|
2275
2309
|
)
|
|
2276
2310
|
] }),
|
|
2277
|
-
label
|
|
2311
|
+
hasLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: label })
|
|
2278
2312
|
]
|
|
2279
2313
|
}
|
|
2280
2314
|
);
|
|
@@ -2285,15 +2319,20 @@ var Select = ({
|
|
|
2285
2319
|
onChange,
|
|
2286
2320
|
className,
|
|
2287
2321
|
defaultValue = "",
|
|
2288
|
-
disabled = false
|
|
2322
|
+
disabled = false,
|
|
2323
|
+
portal = true
|
|
2289
2324
|
}) => {
|
|
2290
2325
|
const [selectedValue, setSelectedValue] = React5.useState(defaultValue);
|
|
2291
2326
|
const [isOpen, setIsOpen] = React5.useState(false);
|
|
2292
2327
|
const rootRef = React5.useRef(null);
|
|
2328
|
+
const triggerRef = React5.useRef(null);
|
|
2329
|
+
const menuRef = React5.useRef(null);
|
|
2330
|
+
const [menuPosition, setMenuPosition] = React5.useState();
|
|
2293
2331
|
React5.useEffect(() => {
|
|
2294
2332
|
if (!isOpen) return;
|
|
2295
2333
|
const onPointerDown = (e) => {
|
|
2296
|
-
|
|
2334
|
+
const target = e.target;
|
|
2335
|
+
if (rootRef.current && !rootRef.current.contains(target) && !menuRef.current?.contains(target)) {
|
|
2297
2336
|
setIsOpen(false);
|
|
2298
2337
|
}
|
|
2299
2338
|
};
|
|
@@ -2307,6 +2346,33 @@ var Select = ({
|
|
|
2307
2346
|
document.removeEventListener("keydown", onKeyDown);
|
|
2308
2347
|
};
|
|
2309
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]);
|
|
2310
2376
|
const toggleOpen = () => {
|
|
2311
2377
|
if (!disabled) setIsOpen((prev) => !prev);
|
|
2312
2378
|
};
|
|
@@ -2320,6 +2386,7 @@ var Select = ({
|
|
|
2320
2386
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2321
2387
|
"button",
|
|
2322
2388
|
{
|
|
2389
|
+
ref: triggerRef,
|
|
2323
2390
|
type: "button",
|
|
2324
2391
|
onClick: toggleOpen,
|
|
2325
2392
|
disabled,
|
|
@@ -2355,52 +2422,61 @@ var Select = ({
|
|
|
2355
2422
|
]
|
|
2356
2423
|
}
|
|
2357
2424
|
),
|
|
2358
|
-
isOpen &&
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
"
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
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,
|
|
2382
2465
|
{
|
|
2383
|
-
"
|
|
2384
|
-
|
|
2385
|
-
children: option.icon
|
|
2466
|
+
className: "ml-2 size-4 shrink-0 stroke-current",
|
|
2467
|
+
"aria-hidden": "true"
|
|
2386
2468
|
}
|
|
2387
|
-
)
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
},
|
|
2399
|
-
option.value
|
|
2400
|
-
);
|
|
2401
|
-
})
|
|
2402
|
-
}
|
|
2403
|
-
)
|
|
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
|
+
})()
|
|
2404
2480
|
] });
|
|
2405
2481
|
};
|
|
2406
2482
|
var MultiSelect = ({
|
|
@@ -2408,10 +2484,60 @@ var MultiSelect = ({
|
|
|
2408
2484
|
options,
|
|
2409
2485
|
defaultSelected = [],
|
|
2410
2486
|
onChange,
|
|
2411
|
-
disabled = false
|
|
2487
|
+
disabled = false,
|
|
2488
|
+
portal = true
|
|
2412
2489
|
}) => {
|
|
2413
2490
|
const [selectedOptions, setSelectedOptions] = React5.useState(defaultSelected);
|
|
2414
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]);
|
|
2415
2541
|
const toggleDropdown = () => {
|
|
2416
2542
|
if (disabled) return;
|
|
2417
2543
|
setIsOpen((prev) => !prev);
|
|
@@ -2429,94 +2555,110 @@ var MultiSelect = ({
|
|
|
2429
2555
|
const selectedValuesText = selectedOptions.map(
|
|
2430
2556
|
(value) => options.find((option) => option.value === value)?.text || ""
|
|
2431
2557
|
);
|
|
2432
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
2558
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: rootRef, className: "w-full", children: [
|
|
2433
2559
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-400", children: label }),
|
|
2434
2560
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative inline-block w-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col items-center", children: [
|
|
2435
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { onClick: toggleDropdown, className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2436
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap flex-auto gap-2", children: selectedValuesText.length > 0 ? selectedValuesText.map((text, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2437
|
-
"div",
|
|
2438
|
-
{
|
|
2439
|
-
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",
|
|
2440
|
-
children: [
|
|
2441
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-initial max-w-full", children: text }),
|
|
2442
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row-reverse flex-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2443
|
-
"div",
|
|
2444
|
-
{
|
|
2445
|
-
onClick: () => removeOption(index, selectedOptions[index]),
|
|
2446
|
-
className: "pl-2 text-gray-500 cursor-pointer group-hover:text-gray-400 dark:text-gray-400",
|
|
2447
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4", role: "button", "aria-hidden": "true" })
|
|
2448
|
-
}
|
|
2449
|
-
) })
|
|
2450
|
-
]
|
|
2451
|
-
},
|
|
2452
|
-
index
|
|
2453
|
-
)) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2454
|
-
"input",
|
|
2455
|
-
{
|
|
2456
|
-
placeholder: "Select option",
|
|
2457
|
-
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",
|
|
2458
|
-
readOnly: true,
|
|
2459
|
-
value: "Select option"
|
|
2460
|
-
}
|
|
2461
|
-
) }),
|
|
2462
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center py-1 pl-1 pr-1 w-7", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2463
|
-
"button",
|
|
2464
|
-
{
|
|
2465
|
-
type: "button",
|
|
2466
|
-
onClick: toggleDropdown,
|
|
2467
|
-
className: "w-5 h-5 text-gray-700 outline-hidden cursor-pointer focus:outline-hidden dark:text-gray-400",
|
|
2468
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2469
|
-
lucideReact.ChevronDown,
|
|
2470
|
-
{
|
|
2471
|
-
className: `size-4 stroke-current ${isOpen ? "rotate-180" : ""}`,
|
|
2472
|
-
"aria-hidden": "true"
|
|
2473
|
-
}
|
|
2474
|
-
)
|
|
2475
|
-
}
|
|
2476
|
-
) })
|
|
2477
|
-
] }) }),
|
|
2478
|
-
isOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2561
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { onClick: toggleDropdown, className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2479
2562
|
"div",
|
|
2480
2563
|
{
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
onClick: (e) => e.stopPropagation(),
|
|
2486
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col", children: options.map((option, index) => {
|
|
2487
|
-
const isSelected = selectedOptions.includes(option.value);
|
|
2488
|
-
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(
|
|
2489
2568
|
"div",
|
|
2490
2569
|
{
|
|
2491
|
-
className:
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
"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,
|
|
2495
2601
|
{
|
|
2496
|
-
className: `
|
|
2497
|
-
|
|
2498
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2499
|
-
"div",
|
|
2500
|
-
{
|
|
2501
|
-
className: `mx-2 leading-6 ${isSelected ? "font-medium text-brand-600 dark:text-brand-400" : "text-gray-800 dark:text-white/90"}`,
|
|
2502
|
-
children: option.text
|
|
2503
|
-
}
|
|
2504
|
-
),
|
|
2505
|
-
isSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2506
|
-
lucideReact.Check,
|
|
2507
|
-
{
|
|
2508
|
-
className: "mr-2 size-4 shrink-0 stroke-current text-brand-500",
|
|
2509
|
-
"aria-hidden": "true"
|
|
2510
|
-
}
|
|
2511
|
-
)
|
|
2512
|
-
]
|
|
2602
|
+
className: `size-4 stroke-current ${isOpen ? "rotate-180" : ""}`,
|
|
2603
|
+
"aria-hidden": "true"
|
|
2513
2604
|
}
|
|
2514
2605
|
)
|
|
2515
2606
|
}
|
|
2516
|
-
) }
|
|
2517
|
-
|
|
2607
|
+
) })
|
|
2608
|
+
]
|
|
2518
2609
|
}
|
|
2519
|
-
)
|
|
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
|
+
})()
|
|
2520
2662
|
] }) })
|
|
2521
2663
|
] });
|
|
2522
2664
|
};
|