@campminder/ds 0.2.0 → 0.3.0

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
@@ -18,6 +18,7 @@ var zod = require('zod');
18
18
  var input = require('@base-ui/react/input');
19
19
  var select = require('@base-ui/react/select');
20
20
  var checkbox = require('@base-ui/react/checkbox');
21
+ var popover = require('@base-ui/react/popover');
21
22
  var cmdk = require('cmdk');
22
23
  var dialog = require('@base-ui/react/dialog');
23
24
  var menu = require('@base-ui/react/menu');
@@ -25,7 +26,6 @@ var separator = require('@base-ui/react/separator');
25
26
  var RPNInput = require('react-phone-number-input');
26
27
  var flags = require('react-phone-number-input/flags');
27
28
  var en = require('react-phone-number-input/locale/en.json');
28
- var popover = require('@base-ui/react/popover');
29
29
  var scrollArea = require('@base-ui/react/scroll-area');
30
30
  var progress = require('@base-ui/react/progress');
31
31
  var radioGroup = require('@base-ui/react/radio-group');
@@ -1202,6 +1202,397 @@ function Checkbox({ className, ...props }) {
1202
1202
  }
1203
1203
  );
1204
1204
  }
1205
+ function Popover({ ...props }) {
1206
+ return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Root, { "data-slot": "popover", ...props });
1207
+ }
1208
+ function PopoverTrigger({ ...props }) {
1209
+ return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Trigger, { "data-slot": "popover-trigger", ...props });
1210
+ }
1211
+ function PopoverContent({
1212
+ className,
1213
+ align = "center",
1214
+ alignOffset = 0,
1215
+ side = "bottom",
1216
+ sideOffset = 4,
1217
+ ...props
1218
+ }) {
1219
+ return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
1220
+ popover.Popover.Positioner,
1221
+ {
1222
+ align,
1223
+ alignOffset,
1224
+ side,
1225
+ sideOffset,
1226
+ className: "isolate z-50",
1227
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1228
+ popover.Popover.Popup,
1229
+ {
1230
+ "data-slot": "popover-content",
1231
+ className: cn(
1232
+ "z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
1233
+ className
1234
+ ),
1235
+ ...props
1236
+ }
1237
+ )
1238
+ }
1239
+ ) });
1240
+ }
1241
+ function PopoverHeader({ className, ...props }) {
1242
+ return /* @__PURE__ */ jsxRuntime.jsx(
1243
+ "div",
1244
+ {
1245
+ "data-slot": "popover-header",
1246
+ className: cn("flex flex-col gap-0.5 text-sm", className),
1247
+ ...props
1248
+ }
1249
+ );
1250
+ }
1251
+ function PopoverTitle({ className, ...props }) {
1252
+ return /* @__PURE__ */ jsxRuntime.jsx(
1253
+ popover.Popover.Title,
1254
+ {
1255
+ "data-slot": "popover-title",
1256
+ className: cn("font-medium", className),
1257
+ ...props
1258
+ }
1259
+ );
1260
+ }
1261
+ function PopoverDescription({
1262
+ className,
1263
+ ...props
1264
+ }) {
1265
+ return /* @__PURE__ */ jsxRuntime.jsx(
1266
+ popover.Popover.Description,
1267
+ {
1268
+ "data-slot": "popover-description",
1269
+ className: cn("text-muted-foreground", className),
1270
+ ...props
1271
+ }
1272
+ );
1273
+ }
1274
+ var ALL_GROUPS = "__all__";
1275
+ function ColumnCustomizer({
1276
+ columns,
1277
+ value,
1278
+ onApply,
1279
+ groupOrder,
1280
+ title = "Customize columns",
1281
+ searchPlaceholder = "Search for a column",
1282
+ allGroupsLabel = "All columns",
1283
+ align = "end",
1284
+ trigger
1285
+ }) {
1286
+ const [open, setOpen] = React3.useState(false);
1287
+ const [draft, setDraft] = React3.useState(value);
1288
+ const [query, setQuery] = React3.useState("");
1289
+ const [group, setGroup] = React3.useState(ALL_GROUPS);
1290
+ const [dragIndex, setDragIndex] = React3.useState(null);
1291
+ const q = query.trim().toLowerCase();
1292
+ const searching = q !== "";
1293
+ const labelFor = React3.useMemo(() => {
1294
+ const m = /* @__PURE__ */ new Map();
1295
+ for (const c of columns) m.set(c.key, c.label);
1296
+ return m;
1297
+ }, [columns]);
1298
+ const groupKeys = React3.useMemo(() => {
1299
+ if (groupOrder?.length) return groupOrder;
1300
+ const seen = [];
1301
+ for (const c of columns) if (!seen.includes(c.group)) seen.push(c.group);
1302
+ return seen;
1303
+ }, [columns, groupOrder]);
1304
+ const groups = React3.useMemo(
1305
+ () => [
1306
+ { key: ALL_GROUPS, label: allGroupsLabel, count: columns.length },
1307
+ ...groupKeys.map((g) => ({
1308
+ key: g,
1309
+ label: g,
1310
+ count: columns.filter((c) => c.group === g).length
1311
+ }))
1312
+ ],
1313
+ [columns, groupKeys, allGroupsLabel]
1314
+ );
1315
+ const handleOpenChange = (next) => {
1316
+ if (next) {
1317
+ setDraft(value);
1318
+ setQuery("");
1319
+ setGroup(ALL_GROUPS);
1320
+ }
1321
+ setOpen(next);
1322
+ };
1323
+ const toggle = (k) => setDraft(
1324
+ (cur) => cur.includes(k) ? cur.filter((c) => c !== k) : [...cur, k]
1325
+ );
1326
+ const remove = (k) => setDraft((cur) => cur.filter((c) => c !== k));
1327
+ const reorder = (from, to) => setDraft((cur) => {
1328
+ const next = [...cur];
1329
+ const [moved] = next.splice(from, 1);
1330
+ next.splice(to, 0, moved);
1331
+ return next;
1332
+ });
1333
+ const visibleCols = React3.useMemo(() => {
1334
+ const base = searching || group === ALL_GROUPS ? columns : columns.filter((c) => c.group === group);
1335
+ return searching ? base.filter((c) => c.label.toLowerCase().includes(q)) : base;
1336
+ }, [columns, q, group, searching]);
1337
+ const showSource = searching || group === ALL_GROUPS;
1338
+ const allChecked = visibleCols.length > 0 && visibleCols.every((c) => draft.includes(c.key));
1339
+ const toggleAll = () => setDraft(
1340
+ (cur) => allChecked ? cur.filter((k) => !visibleCols.some((c) => c.key === k)) : [
1341
+ ...cur,
1342
+ ...visibleCols.map((c) => c.key).filter((k) => !cur.includes(k))
1343
+ ]
1344
+ );
1345
+ const activeGroupLabel = groups.find((g) => g.key === group)?.label;
1346
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
1347
+ trigger ? /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { render: trigger }) : /* @__PURE__ */ jsxRuntime.jsxs(
1348
+ PopoverTrigger,
1349
+ {
1350
+ type: "button",
1351
+ className: cn(
1352
+ buttonVariants({ variant: "outline" }),
1353
+ "h-9 gap-1.5 text-muted-foreground"
1354
+ ),
1355
+ children: [
1356
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Columns3, { className: "size-4" }),
1357
+ "Columns"
1358
+ ]
1359
+ }
1360
+ ),
1361
+ /* @__PURE__ */ jsxRuntime.jsxs(
1362
+ PopoverContent,
1363
+ {
1364
+ align,
1365
+ className: "w-[720px] max-w-[calc(100vw-2rem)] gap-0 p-0",
1366
+ children: [
1367
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTitle, { className: "px-4 pt-4 pb-3 text-sm font-semibold", children: title }),
1368
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 pb-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
1369
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" }),
1370
+ /* @__PURE__ */ jsxRuntime.jsx(
1371
+ Input,
1372
+ {
1373
+ value: query,
1374
+ onChange: (e) => setQuery(e.target.value),
1375
+ placeholder: searchPlaceholder,
1376
+ "aria-label": searchPlaceholder,
1377
+ className: "h-10 pl-9"
1378
+ }
1379
+ )
1380
+ ] }) }),
1381
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid h-[380px] grid-cols-[12rem_1fr_16rem] border-y", children: [
1382
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-y-auto border-r p-2", children: groups.map((gr) => /* @__PURE__ */ jsxRuntime.jsxs(
1383
+ "button",
1384
+ {
1385
+ type: "button",
1386
+ disabled: searching,
1387
+ onClick: () => setGroup(gr.key),
1388
+ className: cn(
1389
+ "flex w-full items-center justify-between gap-2 rounded-md px-3 py-2 text-left text-sm hover:bg-muted/60",
1390
+ !searching && group === gr.key && "bg-muted font-medium",
1391
+ searching && "opacity-40"
1392
+ ),
1393
+ children: [
1394
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: gr.label }),
1395
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 rounded-md bg-muted px-1.5 text-xs tabular-nums text-muted-foreground", children: gr.count })
1396
+ ]
1397
+ },
1398
+ gr.key
1399
+ )) }),
1400
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 overflow-y-auto p-3", children: [
1401
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1 pb-1 text-sm font-semibold", children: searching ? "Search results" : activeGroupLabel }),
1402
+ !searching && visibleCols.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex cursor-pointer items-center gap-2.5 border-b px-1 py-2 text-sm", children: [
1403
+ /* @__PURE__ */ jsxRuntime.jsx(
1404
+ Checkbox,
1405
+ {
1406
+ checked: allChecked,
1407
+ onCheckedChange: () => toggleAll()
1408
+ }
1409
+ ),
1410
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Select all" })
1411
+ ] }),
1412
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1", children: visibleCols.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-1 py-6 text-center text-sm text-muted-foreground", children: [
1413
+ "No columns match \u201C",
1414
+ query,
1415
+ "\u201D."
1416
+ ] }) : visibleCols.map((c) => /* @__PURE__ */ jsxRuntime.jsxs(
1417
+ "label",
1418
+ {
1419
+ className: "flex cursor-pointer items-center gap-2.5 rounded-md px-1 py-2 text-sm hover:bg-muted/60",
1420
+ children: [
1421
+ /* @__PURE__ */ jsxRuntime.jsx(
1422
+ Checkbox,
1423
+ {
1424
+ checked: draft.includes(c.key),
1425
+ onCheckedChange: () => toggle(c.key)
1426
+ }
1427
+ ),
1428
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: c.label }),
1429
+ showSource && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: c.group })
1430
+ ]
1431
+ },
1432
+ c.key
1433
+ )) })
1434
+ ] }),
1435
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col border-l", children: [
1436
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-3 py-2.5", children: [
1437
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-semibold", children: [
1438
+ draft.length,
1439
+ " selected"
1440
+ ] }),
1441
+ draft.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1442
+ "button",
1443
+ {
1444
+ type: "button",
1445
+ onClick: () => setDraft([]),
1446
+ className: "text-xs font-medium text-primary hover:underline",
1447
+ children: "Clear all"
1448
+ }
1449
+ )
1450
+ ] }),
1451
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 space-y-1.5 overflow-y-auto px-3 pb-3", children: draft.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1 py-6 text-center text-sm text-muted-foreground", children: "No columns selected." }) : draft.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(
1452
+ "div",
1453
+ {
1454
+ draggable: true,
1455
+ onDragStart: () => setDragIndex(i),
1456
+ onDragOver: (e) => e.preventDefault(),
1457
+ onDrop: () => {
1458
+ if (dragIndex !== null && dragIndex !== i)
1459
+ reorder(dragIndex, i);
1460
+ setDragIndex(null);
1461
+ },
1462
+ onDragEnd: () => setDragIndex(null),
1463
+ className: cn(
1464
+ "flex items-center gap-2 rounded-md border bg-background px-2.5 py-2 text-sm",
1465
+ dragIndex === i && "opacity-50"
1466
+ ),
1467
+ children: [
1468
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripVertical, { className: "size-3.5 shrink-0 cursor-grab text-muted-foreground" }),
1469
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: labelFor.get(k) ?? k }),
1470
+ /* @__PURE__ */ jsxRuntime.jsx(
1471
+ "button",
1472
+ {
1473
+ type: "button",
1474
+ onClick: () => remove(k),
1475
+ "aria-label": `Remove ${labelFor.get(k) ?? k}`,
1476
+ className: "shrink-0 rounded-sm p-0.5 text-muted-foreground hover:text-foreground",
1477
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3.5" })
1478
+ }
1479
+ )
1480
+ ]
1481
+ },
1482
+ k
1483
+ )) })
1484
+ ] })
1485
+ ] }),
1486
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 px-4 py-3", children: [
1487
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: () => setOpen(false), children: "Cancel" }),
1488
+ /* @__PURE__ */ jsxRuntime.jsx(
1489
+ Button,
1490
+ {
1491
+ onClick: () => {
1492
+ onApply(draft);
1493
+ setOpen(false);
1494
+ },
1495
+ children: "Apply"
1496
+ }
1497
+ )
1498
+ ] })
1499
+ ]
1500
+ }
1501
+ )
1502
+ ] });
1503
+ }
1504
+ function ColumnPicker({
1505
+ columns,
1506
+ value,
1507
+ onChange,
1508
+ title = "Columns",
1509
+ searchPlaceholder = "Search columns",
1510
+ align = "end",
1511
+ trigger
1512
+ }) {
1513
+ const [query, setQuery] = React3.useState("");
1514
+ const q = query.trim().toLowerCase();
1515
+ const visible = React3.useMemo(() => new Set(value), [value]);
1516
+ const filtered = React3.useMemo(
1517
+ () => q ? columns.filter((c) => c.label.toLowerCase().includes(q)) : columns,
1518
+ [columns, q]
1519
+ );
1520
+ const emit = (next) => onChange(columns.filter((c) => next.has(c.key)).map((c) => c.key));
1521
+ const toggle = (key) => {
1522
+ const next = new Set(visible);
1523
+ if (next.has(key)) next.delete(key);
1524
+ else next.add(key);
1525
+ emit(next);
1526
+ };
1527
+ const allChecked = filtered.length > 0 && filtered.every((c) => visible.has(c.key));
1528
+ const toggleAll = () => {
1529
+ const next = new Set(visible);
1530
+ for (const c of filtered) {
1531
+ if (allChecked) next.delete(c.key);
1532
+ else next.add(c.key);
1533
+ }
1534
+ emit(next);
1535
+ };
1536
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { children: [
1537
+ trigger ? /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { render: trigger }) : /* @__PURE__ */ jsxRuntime.jsxs(
1538
+ PopoverTrigger,
1539
+ {
1540
+ type: "button",
1541
+ className: cn(
1542
+ buttonVariants({ variant: "outline" }),
1543
+ "h-9 gap-1.5 text-muted-foreground"
1544
+ ),
1545
+ children: [
1546
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Columns3, { className: "size-4" }),
1547
+ "Columns"
1548
+ ]
1549
+ }
1550
+ ),
1551
+ /* @__PURE__ */ jsxRuntime.jsxs(PopoverContent, { align, className: "w-72 gap-0 p-0", children: [
1552
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTitle, { className: "px-3 pt-3 pb-2 text-sm font-semibold", children: title }),
1553
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
1554
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" }),
1555
+ /* @__PURE__ */ jsxRuntime.jsx(
1556
+ Input,
1557
+ {
1558
+ value: query,
1559
+ onChange: (e) => setQuery(e.target.value),
1560
+ placeholder: searchPlaceholder,
1561
+ "aria-label": searchPlaceholder,
1562
+ className: "h-9 pl-9"
1563
+ }
1564
+ )
1565
+ ] }) }),
1566
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-[320px] overflow-y-auto border-t px-1.5 py-1.5", children: filtered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-2 py-6 text-center text-sm text-muted-foreground", children: [
1567
+ "No columns match \u201C",
1568
+ query,
1569
+ "\u201D."
1570
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1571
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex cursor-pointer items-center gap-2.5 rounded-md px-2 py-2 text-sm hover:bg-muted/60", children: [
1572
+ /* @__PURE__ */ jsxRuntime.jsx(Checkbox, { checked: allChecked, onCheckedChange: () => toggleAll() }),
1573
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Select all" })
1574
+ ] }),
1575
+ filtered.map((c) => /* @__PURE__ */ jsxRuntime.jsxs(
1576
+ "label",
1577
+ {
1578
+ className: "flex cursor-pointer items-center gap-2.5 rounded-md px-2 py-2 text-sm hover:bg-muted/60",
1579
+ children: [
1580
+ /* @__PURE__ */ jsxRuntime.jsx(
1581
+ Checkbox,
1582
+ {
1583
+ checked: visible.has(c.key),
1584
+ onCheckedChange: () => toggle(c.key)
1585
+ }
1586
+ ),
1587
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: c.label })
1588
+ ]
1589
+ },
1590
+ c.key
1591
+ ))
1592
+ ] }) })
1593
+ ] })
1594
+ ] });
1595
+ }
1205
1596
  function Dialog({ ...props }) {
1206
1597
  return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog.Root, { "data-slot": "dialog", ...props });
1207
1598
  }
@@ -1296,7 +1687,7 @@ function DialogFooter({
1296
1687
  {
1297
1688
  "data-slot": "dialog-footer",
1298
1689
  className: cn(
1299
- "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end",
1690
+ "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t border-border bg-muted/50 p-4 sm:flex-row sm:justify-end",
1300
1691
  className
1301
1692
  ),
1302
1693
  ...props,
@@ -1635,6 +2026,449 @@ function CommandShortcut({
1635
2026
  }
1636
2027
  );
1637
2028
  }
2029
+ function Table({ className, ...props }) {
2030
+ return /* @__PURE__ */ jsxRuntime.jsx(
2031
+ "div",
2032
+ {
2033
+ "data-slot": "table-container",
2034
+ className: "relative w-full overflow-x-auto",
2035
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2036
+ "table",
2037
+ {
2038
+ "data-slot": "table",
2039
+ className: cn("w-full caption-bottom text-sm", className),
2040
+ ...props
2041
+ }
2042
+ )
2043
+ }
2044
+ );
2045
+ }
2046
+ function TableHeader({ className, ...props }) {
2047
+ return /* @__PURE__ */ jsxRuntime.jsx(
2048
+ "thead",
2049
+ {
2050
+ "data-slot": "table-header",
2051
+ className: cn("[&_tr]:border-b", className),
2052
+ ...props
2053
+ }
2054
+ );
2055
+ }
2056
+ function TableBody({ className, ...props }) {
2057
+ return /* @__PURE__ */ jsxRuntime.jsx(
2058
+ "tbody",
2059
+ {
2060
+ "data-slot": "table-body",
2061
+ className: cn("[&_tr:last-child]:border-0", className),
2062
+ ...props
2063
+ }
2064
+ );
2065
+ }
2066
+ function TableFooter({ className, ...props }) {
2067
+ return /* @__PURE__ */ jsxRuntime.jsx(
2068
+ "tfoot",
2069
+ {
2070
+ "data-slot": "table-footer",
2071
+ className: cn(
2072
+ "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
2073
+ className
2074
+ ),
2075
+ ...props
2076
+ }
2077
+ );
2078
+ }
2079
+ function TableRow({ className, ...props }) {
2080
+ return /* @__PURE__ */ jsxRuntime.jsx(
2081
+ "tr",
2082
+ {
2083
+ "data-slot": "table-row",
2084
+ className: cn(
2085
+ "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
2086
+ className
2087
+ ),
2088
+ ...props
2089
+ }
2090
+ );
2091
+ }
2092
+ function TableHead({ className, ...props }) {
2093
+ return /* @__PURE__ */ jsxRuntime.jsx(
2094
+ "th",
2095
+ {
2096
+ "data-slot": "table-head",
2097
+ className: cn(
2098
+ "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
2099
+ className
2100
+ ),
2101
+ ...props
2102
+ }
2103
+ );
2104
+ }
2105
+ function TableCell({ className, ...props }) {
2106
+ return /* @__PURE__ */ jsxRuntime.jsx(
2107
+ "td",
2108
+ {
2109
+ "data-slot": "table-cell",
2110
+ className: cn(
2111
+ "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
2112
+ className
2113
+ ),
2114
+ ...props
2115
+ }
2116
+ );
2117
+ }
2118
+ function TableCaption({
2119
+ className,
2120
+ ...props
2121
+ }) {
2122
+ return /* @__PURE__ */ jsxRuntime.jsx(
2123
+ "caption",
2124
+ {
2125
+ "data-slot": "table-caption",
2126
+ className: cn("mt-4 text-sm text-muted-foreground", className),
2127
+ ...props
2128
+ }
2129
+ );
2130
+ }
2131
+ var SELECT_COL_PX = 48;
2132
+ var STICKY_UNDERLAP_PX = 8;
2133
+ var selectColStyle = {
2134
+ width: SELECT_COL_PX,
2135
+ minWidth: SELECT_COL_PX,
2136
+ maxWidth: SELECT_COL_PX
2137
+ };
2138
+ var DEFAULT_STICKY_PX = 180;
2139
+ var HEADER_CELL_BG = "bg-[color-mix(in_oklab,var(--color-muted)_40%,var(--color-background))]";
2140
+ function alignClass(align) {
2141
+ return align === "right" ? "text-right" : align === "center" ? "text-center" : "text-left";
2142
+ }
2143
+ function DataTable({
2144
+ data,
2145
+ columns,
2146
+ rowKey,
2147
+ selectable = false,
2148
+ selected: selectedProp,
2149
+ onSelectedChange,
2150
+ bulkActions,
2151
+ sort: sortProp,
2152
+ defaultSort = null,
2153
+ onSortChange,
2154
+ paginated = false,
2155
+ pageSize: pageSizeProp,
2156
+ pageSizeOptions = [25, 50, 100],
2157
+ page: pageProp,
2158
+ onPageChange,
2159
+ toolbar,
2160
+ onRowClick,
2161
+ emptyMessage = "No rows to show.",
2162
+ rowClassName,
2163
+ className
2164
+ }) {
2165
+ const [selInner, setSelInner] = React3.useState(/* @__PURE__ */ new Set());
2166
+ const selected = selectedProp ?? selInner;
2167
+ const setSelected = (next) => {
2168
+ onSelectedChange?.(next);
2169
+ if (selectedProp === void 0) setSelInner(next);
2170
+ };
2171
+ const toggleRow = (id) => {
2172
+ const next = new Set(selected);
2173
+ if (next.has(id)) next.delete(id);
2174
+ else next.add(id);
2175
+ setSelected(next);
2176
+ };
2177
+ const clearSelection = () => setSelected(/* @__PURE__ */ new Set());
2178
+ const [sortInner, setSortInner] = React3.useState(defaultSort);
2179
+ const sort = sortProp !== void 0 ? sortProp : sortInner;
2180
+ const colByKey = React3.useMemo(() => {
2181
+ const m = /* @__PURE__ */ new Map();
2182
+ for (const c of columns) m.set(c.key, c);
2183
+ return m;
2184
+ }, [columns]);
2185
+ const toggleSort = (key) => {
2186
+ const next = sort?.key !== key ? { key, dir: "asc" } : sort.dir === "asc" ? { key, dir: "desc" } : null;
2187
+ onSortChange?.(next);
2188
+ if (sortProp === void 0) setSortInner(next);
2189
+ };
2190
+ const sorted = React3.useMemo(() => {
2191
+ if (!sort) return data;
2192
+ const col = colByKey.get(sort.key);
2193
+ if (!col?.sortValue) return data;
2194
+ const { sortValue } = col;
2195
+ const arr = [...data];
2196
+ arr.sort((a, b) => {
2197
+ const av = sortValue(a);
2198
+ const bv = sortValue(b);
2199
+ const cmp = typeof av === "number" && typeof bv === "number" ? av - bv : String(av).localeCompare(String(bv));
2200
+ return sort.dir === "asc" ? cmp : -cmp;
2201
+ });
2202
+ return arr;
2203
+ }, [data, sort, colByKey]);
2204
+ const [pageSizeInner, setPageSizeInner] = React3.useState(pageSizeProp ?? 25);
2205
+ const pageSize = paginated ? pageSizeInner : sorted.length || 1;
2206
+ const [pageInner, setPageInner] = React3.useState(0);
2207
+ const page = pageProp !== void 0 ? pageProp : pageInner;
2208
+ const setPage = (p) => {
2209
+ onPageChange?.(p);
2210
+ if (pageProp === void 0) setPageInner(p);
2211
+ };
2212
+ const total = sorted.length;
2213
+ const pageCount = Math.max(1, Math.ceil(total / pageSize));
2214
+ const safePage = Math.min(page, pageCount - 1);
2215
+ const pageStart = paginated ? safePage * pageSize : 0;
2216
+ const rows = paginated ? sorted.slice(pageStart, pageStart + pageSize) : sorted;
2217
+ const pageIds = rows.map(rowKey);
2218
+ const allChecked = pageIds.length > 0 && pageIds.every((id) => selected.has(id));
2219
+ const toggleAll = () => {
2220
+ const next = new Set(selected);
2221
+ for (const id of pageIds) {
2222
+ if (allChecked) next.delete(id);
2223
+ else next.add(id);
2224
+ }
2225
+ setSelected(next);
2226
+ };
2227
+ const selectedCount = selected.size;
2228
+ const stickyLeft = React3.useMemo(() => {
2229
+ const offsets = /* @__PURE__ */ new Map();
2230
+ let left = selectable ? SELECT_COL_PX - STICKY_UNDERLAP_PX : 0;
2231
+ for (const col of columns) {
2232
+ if (!col.sticky) continue;
2233
+ offsets.set(col.key, left);
2234
+ left += typeof col.width === "number" ? col.width : DEFAULT_STICKY_PX;
2235
+ }
2236
+ return offsets;
2237
+ }, [columns, selectable]);
2238
+ const colCount = (selectable ? 1 : 0) + columns.length + 1;
2239
+ const sortIcon = (key) => {
2240
+ if (sort?.key !== key)
2241
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "size-3.5 text-muted-foreground/50 opacity-0 transition-opacity group-hover/sort:opacity-100" });
2242
+ return sort.dir === "asc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-3.5" });
2243
+ };
2244
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-2", className), children: [
2245
+ toolbar,
2246
+ bulkActions?.length && selectedCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-fit flex-wrap items-center gap-2 rounded-lg border border-primary/40 bg-primary/5 px-3 py-1.5", children: [
2247
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-medium", children: [
2248
+ selectedCount,
2249
+ " selected"
2250
+ ] }),
2251
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "\xB7" }),
2252
+ bulkActions.map(
2253
+ (action, i) => action.options ? /* @__PURE__ */ jsxRuntime.jsxs(
2254
+ Select,
2255
+ {
2256
+ value: "",
2257
+ onValueChange: (v) => v && action.onPick?.(v),
2258
+ children: [
2259
+ /* @__PURE__ */ jsxRuntime.jsx(
2260
+ SelectTrigger,
2261
+ {
2262
+ "aria-label": action.label,
2263
+ className: "h-8 min-w-[130px] bg-background text-sm",
2264
+ children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: action.label })
2265
+ }
2266
+ ),
2267
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { className: "w-auto min-w-(--anchor-width) max-w-[20rem]", children: action.options.map((o) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: o.value, children: o.label }, o.value)) })
2268
+ ]
2269
+ },
2270
+ i
2271
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
2272
+ "button",
2273
+ {
2274
+ type: "button",
2275
+ onClick: action.onClick,
2276
+ className: "inline-flex h-8 items-center rounded-md border bg-background px-2.5 text-sm hover:bg-muted",
2277
+ children: action.label
2278
+ },
2279
+ i
2280
+ )
2281
+ ),
2282
+ /* @__PURE__ */ jsxRuntime.jsxs(
2283
+ "button",
2284
+ {
2285
+ type: "button",
2286
+ onClick: clearSelection,
2287
+ className: "inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground",
2288
+ children: [
2289
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3.5" }),
2290
+ "Clear"
2291
+ ]
2292
+ }
2293
+ )
2294
+ ] }) : null,
2295
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border bg-background overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { className: "border-separate border-spacing-0", children: [
2296
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { className: "text-xs uppercase tracking-wide text-muted-foreground", children: [
2297
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(
2298
+ TableHead,
2299
+ {
2300
+ style: selectColStyle,
2301
+ className: cn(
2302
+ "sticky left-0 z-30 px-0 py-2.5 border-b rounded-tl-xl",
2303
+ HEADER_CELL_BG
2304
+ ),
2305
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
2306
+ Checkbox,
2307
+ {
2308
+ checked: allChecked,
2309
+ onCheckedChange: toggleAll,
2310
+ "aria-label": "Select all"
2311
+ }
2312
+ ) })
2313
+ }
2314
+ ),
2315
+ columns.map((col, colIndex) => {
2316
+ const sortable = col.sortable && col.sortValue;
2317
+ const left = stickyLeft.get(col.key);
2318
+ const isFirstCol = !selectable && colIndex === 0;
2319
+ return /* @__PURE__ */ jsxRuntime.jsx(
2320
+ TableHead,
2321
+ {
2322
+ style: col.sticky ? { left, minWidth: col.width } : { minWidth: col.width },
2323
+ className: cn(
2324
+ "px-4 py-2.5 border-b font-medium text-muted-foreground",
2325
+ HEADER_CELL_BG,
2326
+ alignClass(col.align),
2327
+ col.sticky && "sticky z-20",
2328
+ isFirstCol && "rounded-tl-xl",
2329
+ col.headerClassName
2330
+ ),
2331
+ children: sortable ? /* @__PURE__ */ jsxRuntime.jsxs(
2332
+ "button",
2333
+ {
2334
+ type: "button",
2335
+ onClick: () => toggleSort(col.key),
2336
+ className: "group/sort inline-flex items-center gap-1 hover:text-foreground",
2337
+ children: [
2338
+ col.header,
2339
+ sortIcon(col.key)
2340
+ ]
2341
+ }
2342
+ ) : col.header
2343
+ },
2344
+ col.key
2345
+ );
2346
+ }),
2347
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { "aria-hidden": true, className: cn("w-full border-b", HEADER_CELL_BG) })
2348
+ ] }) }),
2349
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: data.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ jsxRuntime.jsx(
2350
+ TableCell,
2351
+ {
2352
+ colSpan: colCount,
2353
+ className: "py-12 text-center text-sm text-muted-foreground rounded-bl-xl",
2354
+ children: emptyMessage
2355
+ }
2356
+ ) }) : rows.map((row, rowIndex) => {
2357
+ const id = rowKey(row);
2358
+ const isSel = selected.has(id);
2359
+ const rowBg = isSel ? "bg-muted" : "bg-background";
2360
+ const isLastRow = rowIndex === rows.length - 1;
2361
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2362
+ TableRow,
2363
+ {
2364
+ className: cn(
2365
+ "group",
2366
+ rowBg,
2367
+ "hover:bg-muted",
2368
+ rowClassName?.(row)
2369
+ ),
2370
+ children: [
2371
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(
2372
+ TableCell,
2373
+ {
2374
+ style: selectColStyle,
2375
+ className: cn(
2376
+ "sticky left-0 z-20 px-0 py-2.5 border-b group-hover:bg-muted",
2377
+ rowBg,
2378
+ isLastRow && "rounded-bl-xl"
2379
+ ),
2380
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
2381
+ Checkbox,
2382
+ {
2383
+ checked: isSel,
2384
+ onCheckedChange: () => toggleRow(id),
2385
+ "aria-label": "Select row"
2386
+ }
2387
+ ) })
2388
+ }
2389
+ ),
2390
+ columns.map((col, colIndex) => {
2391
+ const left = stickyLeft.get(col.key);
2392
+ const isFirstCol = !selectable && colIndex === 0;
2393
+ return /* @__PURE__ */ jsxRuntime.jsx(
2394
+ TableCell,
2395
+ {
2396
+ style: col.sticky ? { left } : void 0,
2397
+ className: cn(
2398
+ "px-4 py-2.5 border-b align-middle",
2399
+ alignClass(col.align),
2400
+ col.sticky && cn("sticky z-10 group-hover:bg-muted", rowBg),
2401
+ isFirstCol && isLastRow && "rounded-bl-xl",
2402
+ col.className
2403
+ ),
2404
+ onClick: col.sticky && onRowClick ? () => onRowClick(row) : void 0,
2405
+ children: col.render(row)
2406
+ },
2407
+ col.key
2408
+ );
2409
+ }),
2410
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { "aria-hidden": true, className: "border-b" })
2411
+ ]
2412
+ },
2413
+ id
2414
+ );
2415
+ }) })
2416
+ ] }) }),
2417
+ paginated && total > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-4 px-1 text-sm text-muted-foreground", children: [
2418
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2419
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: "Rows per page" }),
2420
+ /* @__PURE__ */ jsxRuntime.jsxs(
2421
+ Select,
2422
+ {
2423
+ value: String(pageSize),
2424
+ onValueChange: (v) => {
2425
+ if (!v) return;
2426
+ setPageSizeInner(Number(v));
2427
+ setPage(0);
2428
+ },
2429
+ children: [
2430
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { "aria-label": "Rows per page", className: "h-8 w-[70px]", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, {}) }),
2431
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: pageSizeOptions.map((n) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: String(n), children: n }, n)) })
2432
+ ]
2433
+ }
2434
+ )
2435
+ ] }),
2436
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
2437
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tabular-nums whitespace-nowrap", children: [
2438
+ pageStart + 1,
2439
+ "\u2013",
2440
+ Math.min(pageStart + pageSize, total),
2441
+ " of ",
2442
+ total
2443
+ ] }),
2444
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
2445
+ /* @__PURE__ */ jsxRuntime.jsx(
2446
+ "button",
2447
+ {
2448
+ type: "button",
2449
+ onClick: () => setPage(safePage - 1),
2450
+ disabled: safePage === 0,
2451
+ "aria-label": "Previous page",
2452
+ className: "inline-flex size-8 items-center justify-center rounded-md border bg-background hover:bg-muted disabled:pointer-events-none disabled:opacity-40",
2453
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "size-4" })
2454
+ }
2455
+ ),
2456
+ /* @__PURE__ */ jsxRuntime.jsx(
2457
+ "button",
2458
+ {
2459
+ type: "button",
2460
+ onClick: () => setPage(safePage + 1),
2461
+ disabled: safePage >= pageCount - 1,
2462
+ "aria-label": "Next page",
2463
+ className: "inline-flex size-8 items-center justify-center rounded-md border bg-background hover:bg-muted disabled:pointer-events-none disabled:opacity-40",
2464
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "size-4" })
2465
+ }
2466
+ )
2467
+ ] })
2468
+ ] })
2469
+ ] })
2470
+ ] });
2471
+ }
1638
2472
  function DropdownMenu(props) {
1639
2473
  return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
1640
2474
  }
@@ -1955,47 +2789,406 @@ function FieldSeparator({
1955
2789
  "data-slot": "field-separator-content",
1956
2790
  children
1957
2791
  }
1958
- )
2792
+ )
2793
+ ]
2794
+ }
2795
+ );
2796
+ }
2797
+ function FieldError({
2798
+ className,
2799
+ children,
2800
+ errors,
2801
+ ...props
2802
+ }) {
2803
+ const content = React3.useMemo(() => {
2804
+ if (children) {
2805
+ return children;
2806
+ }
2807
+ if (!errors?.length) {
2808
+ return null;
2809
+ }
2810
+ const uniqueErrors = [
2811
+ ...new Map(errors.map((error) => [error?.message, error])).values()
2812
+ ];
2813
+ if (uniqueErrors?.length == 1) {
2814
+ return uniqueErrors[0]?.message;
2815
+ }
2816
+ return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "ml-4 flex list-disc flex-col gap-1", children: uniqueErrors.map(
2817
+ (error, index) => error?.message && /* @__PURE__ */ jsxRuntime.jsx("li", { children: error.message }, index)
2818
+ ) });
2819
+ }, [children, errors]);
2820
+ if (!content) {
2821
+ return null;
2822
+ }
2823
+ return /* @__PURE__ */ jsxRuntime.jsx(
2824
+ "div",
2825
+ {
2826
+ role: "alert",
2827
+ "data-slot": "field-error",
2828
+ className: cn("text-sm font-normal text-destructive", className),
2829
+ ...props,
2830
+ children: content
2831
+ }
2832
+ );
2833
+ }
2834
+ function CheckIndicator({ checked }) {
2835
+ return /* @__PURE__ */ jsxRuntime.jsx(
2836
+ "span",
2837
+ {
2838
+ "aria-hidden": true,
2839
+ className: cn(
2840
+ "flex size-4 shrink-0 items-center justify-center rounded-[4px] border transition-colors",
2841
+ checked ? "border-primary bg-primary text-primary-foreground" : "border-input"
2842
+ ),
2843
+ children: checked && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-3.5" })
2844
+ }
2845
+ );
2846
+ }
2847
+ function FilterBar({
2848
+ search,
2849
+ onSearchChange,
2850
+ searchPlaceholder = "Search by name\u2026",
2851
+ showSearch = true,
2852
+ facets = [],
2853
+ values = {},
2854
+ onValuesChange,
2855
+ resultCount,
2856
+ resultNoun = "result",
2857
+ maxVisibleFacets = 3,
2858
+ right,
2859
+ left,
2860
+ filterVariant = "inline",
2861
+ className
2862
+ }) {
2863
+ const visibleFacets = facets.slice(0, maxVisibleFacets);
2864
+ const overflowFacets = facets.slice(maxVisibleFacets);
2865
+ const toggle = (key, value) => {
2866
+ const cur = values[key] ?? [];
2867
+ const next = cur.includes(value) ? cur.filter((v) => v !== value) : [...cur, value];
2868
+ onValuesChange?.({ ...values, [key]: next });
2869
+ };
2870
+ const clearAll = () => onValuesChange?.({});
2871
+ const activeCount = Object.values(values).reduce((n, a) => n + a.length, 0);
2872
+ const searchBox = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-56", children: [
2873
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
2874
+ /* @__PURE__ */ jsxRuntime.jsx(
2875
+ Input,
2876
+ {
2877
+ value: search,
2878
+ onChange: (e) => onSearchChange(e.target.value),
2879
+ placeholder: searchPlaceholder,
2880
+ "aria-label": searchPlaceholder,
2881
+ className: "rounded-full bg-background pl-8 pr-8"
2882
+ }
2883
+ ),
2884
+ search && /* @__PURE__ */ jsxRuntime.jsx(
2885
+ "button",
2886
+ {
2887
+ type: "button",
2888
+ onClick: () => onSearchChange(""),
2889
+ "aria-label": "Clear search",
2890
+ className: "absolute right-2 top-1/2 inline-flex size-5 -translate-y-1/2 items-center justify-center rounded-full text-muted-foreground hover:bg-muted hover:text-foreground",
2891
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3.5" })
2892
+ }
2893
+ )
2894
+ ] });
2895
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
2896
+ left,
2897
+ filterVariant === "inline" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2898
+ showSearch && searchBox,
2899
+ visibleFacets.map((facet) => /* @__PURE__ */ jsxRuntime.jsx(
2900
+ FacetDropdown,
2901
+ {
2902
+ facet,
2903
+ selected: values[facet.key] ?? [],
2904
+ onToggle: (value) => toggle(facet.key, value),
2905
+ onClear: () => onValuesChange?.({ ...values, [facet.key]: [] })
2906
+ },
2907
+ facet.key
2908
+ )),
2909
+ overflowFacets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
2910
+ MoreFilters,
2911
+ {
2912
+ facets: overflowFacets,
2913
+ values,
2914
+ onToggle: toggle
2915
+ }
2916
+ ),
2917
+ activeCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
2918
+ "button",
2919
+ {
2920
+ type: "button",
2921
+ onClick: clearAll,
2922
+ "aria-label": "Clear all filters",
2923
+ className: "inline-flex h-7 items-center gap-1 px-2 text-xs text-muted-foreground hover:text-foreground",
2924
+ children: [
2925
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3.5" }),
2926
+ activeCount
2927
+ ]
2928
+ }
2929
+ )
2930
+ ] }),
2931
+ filterVariant === "funnel" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2932
+ showSearch && searchBox,
2933
+ /* @__PURE__ */ jsxRuntime.jsx(
2934
+ FunnelFilter,
2935
+ {
2936
+ facets,
2937
+ values,
2938
+ onToggle: toggle,
2939
+ onClearAll: clearAll
2940
+ }
2941
+ )
2942
+ ] }),
2943
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
2944
+ typeof resultCount === "number" && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "whitespace-nowrap text-sm text-muted-foreground", children: [
2945
+ resultCount,
2946
+ " ",
2947
+ resultNoun,
2948
+ resultCount === 1 ? "" : "s"
2949
+ ] }),
2950
+ right
2951
+ ] })
2952
+ ] }) });
2953
+ }
2954
+ function FacetDropdown({
2955
+ facet,
2956
+ selected,
2957
+ onToggle,
2958
+ onClear
2959
+ }) {
2960
+ const count = selected.length;
2961
+ const firstLabel = facet.options.find((o) => o.value === selected[0])?.label ?? selected[0];
2962
+ const summary = count === 0 ? facet.label : `${facet.label}: ${firstLabel}${count > 1 ? ` (+${count - 1})` : ""}`;
2963
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { children: [
2964
+ /* @__PURE__ */ jsxRuntime.jsx(
2965
+ PopoverTrigger,
2966
+ {
2967
+ render: /* @__PURE__ */ jsxRuntime.jsxs(
2968
+ "button",
2969
+ {
2970
+ type: "button",
2971
+ className: cn(
2972
+ "inline-flex h-7 max-w-[14rem] items-center gap-1 rounded-full border bg-background px-2.5 text-xs transition-colors",
2973
+ count > 0 ? "border-primary/40 bg-primary/5 text-foreground" : "text-muted-foreground hover:text-foreground"
2974
+ ),
2975
+ children: [
2976
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: summary }),
2977
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-3 shrink-0 opacity-60" })
2978
+ ]
2979
+ }
2980
+ )
2981
+ }
2982
+ ),
2983
+ /* @__PURE__ */ jsxRuntime.jsx(
2984
+ PopoverContent,
2985
+ {
2986
+ className: "w-60 p-0",
2987
+ align: "start",
2988
+ "aria-label": `${facet.label} options`,
2989
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [
2990
+ facet.options.length > 6 && /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: `Search ${facet.label.toLowerCase()}\u2026` }),
2991
+ /* @__PURE__ */ jsxRuntime.jsxs(CommandList, { children: [
2992
+ /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: "No options." }),
2993
+ /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: facet.options.map((opt) => {
2994
+ const checked = selected.includes(opt.value);
2995
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2996
+ CommandItem,
2997
+ {
2998
+ value: opt.label,
2999
+ onSelect: () => onToggle(opt.value),
3000
+ className: "gap-2.5",
3001
+ children: [
3002
+ /* @__PURE__ */ jsxRuntime.jsx(CheckIndicator, { checked }),
3003
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: opt.label }),
3004
+ checked && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "selected" })
3005
+ ]
3006
+ },
3007
+ opt.value
3008
+ );
3009
+ }) })
3010
+ ] }),
3011
+ count > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t p-1", children: /* @__PURE__ */ jsxRuntime.jsx(
3012
+ Button,
3013
+ {
3014
+ variant: "ghost",
3015
+ onClick: onClear,
3016
+ className: "w-full justify-center text-primary",
3017
+ children: "Clear"
3018
+ }
3019
+ ) })
3020
+ ] })
3021
+ }
3022
+ )
3023
+ ] });
3024
+ }
3025
+ function FunnelFilter({
3026
+ facets,
3027
+ values,
3028
+ onToggle,
3029
+ onClearAll
3030
+ }) {
3031
+ const [open, setOpen] = React3.useState(false);
3032
+ const [drill, setDrill] = React3.useState(null);
3033
+ const activeCount = Object.values(values).reduce((n, a) => n + a.length, 0);
3034
+ const facet = facets.find((f) => f.key === drill);
3035
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3036
+ Popover,
3037
+ {
3038
+ open,
3039
+ onOpenChange: (o) => {
3040
+ setOpen(o);
3041
+ if (!o) setDrill(null);
3042
+ },
3043
+ children: [
3044
+ /* @__PURE__ */ jsxRuntime.jsx(
3045
+ PopoverTrigger,
3046
+ {
3047
+ render: /* @__PURE__ */ jsxRuntime.jsxs(
3048
+ "button",
3049
+ {
3050
+ type: "button",
3051
+ className: cn(
3052
+ "inline-flex h-9 items-center gap-1.5 rounded-md border bg-background px-3 text-sm transition-colors",
3053
+ activeCount > 0 ? "text-foreground" : "text-muted-foreground hover:text-foreground"
3054
+ ),
3055
+ children: [
3056
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListFilter, { className: "size-4" }),
3057
+ "Filter",
3058
+ activeCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "ml-0.5 h-5 bg-primary px-1.5 text-primary-foreground", children: activeCount })
3059
+ ]
3060
+ }
3061
+ )
3062
+ }
3063
+ ),
3064
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-64 p-1", align: "end", "aria-label": "Filters", children: !facet ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3065
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Add filter" }),
3066
+ facets.map((f) => {
3067
+ const count = values[f.key]?.length ?? 0;
3068
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3069
+ "button",
3070
+ {
3071
+ type: "button",
3072
+ onClick: () => setDrill(f.key),
3073
+ className: "flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm hover:bg-muted/60",
3074
+ children: [
3075
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: f.label }),
3076
+ count > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-primary", children: count }),
3077
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "size-3.5 opacity-50" })
3078
+ ]
3079
+ },
3080
+ f.key
3081
+ );
3082
+ }),
3083
+ activeCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3084
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-1 border-t" }),
3085
+ /* @__PURE__ */ jsxRuntime.jsx(
3086
+ "button",
3087
+ {
3088
+ type: "button",
3089
+ onClick: onClearAll,
3090
+ className: "w-full rounded-md px-2 py-1.5 text-left text-sm text-muted-foreground hover:bg-muted/60",
3091
+ children: "Clear all filters"
3092
+ }
3093
+ )
3094
+ ] })
3095
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3096
+ /* @__PURE__ */ jsxRuntime.jsxs(
3097
+ "button",
3098
+ {
3099
+ type: "button",
3100
+ onClick: () => setDrill(null),
3101
+ className: "flex w-full items-center gap-1 rounded-md px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground hover:bg-muted/60",
3102
+ children: [
3103
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "size-3.5" }),
3104
+ facet.label
3105
+ ]
3106
+ }
3107
+ ),
3108
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-64 overflow-y-auto", children: facet.options.map((opt) => {
3109
+ const checked = (values[facet.key] ?? []).includes(opt.value);
3110
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3111
+ "button",
3112
+ {
3113
+ type: "button",
3114
+ onClick: () => onToggle(facet.key, opt.value),
3115
+ className: "flex w-full items-center gap-2.5 rounded-md px-2 py-1.5 text-left text-sm hover:bg-muted/60",
3116
+ children: [
3117
+ /* @__PURE__ */ jsxRuntime.jsx(
3118
+ "span",
3119
+ {
3120
+ className: cn(
3121
+ "flex size-4 shrink-0 items-center justify-center rounded border",
3122
+ checked ? "border-primary bg-primary text-primary-foreground" : "border-input"
3123
+ ),
3124
+ children: checked && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-3" })
3125
+ }
3126
+ ),
3127
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: opt.label })
3128
+ ]
3129
+ },
3130
+ opt.value
3131
+ );
3132
+ }) })
3133
+ ] }) })
1959
3134
  ]
1960
3135
  }
1961
3136
  );
1962
3137
  }
1963
- function FieldError({
1964
- className,
1965
- children,
1966
- errors,
1967
- ...props
3138
+ function MoreFilters({
3139
+ facets,
3140
+ values,
3141
+ onToggle
1968
3142
  }) {
1969
- const content = React3.useMemo(() => {
1970
- if (children) {
1971
- return children;
1972
- }
1973
- if (!errors?.length) {
1974
- return null;
1975
- }
1976
- const uniqueErrors = [
1977
- ...new Map(errors.map((error) => [error?.message, error])).values()
1978
- ];
1979
- if (uniqueErrors?.length == 1) {
1980
- return uniqueErrors[0]?.message;
1981
- }
1982
- return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "ml-4 flex list-disc flex-col gap-1", children: uniqueErrors.map(
1983
- (error, index) => error?.message && /* @__PURE__ */ jsxRuntime.jsx("li", { children: error.message }, index)
1984
- ) });
1985
- }, [children, errors]);
1986
- if (!content) {
1987
- return null;
1988
- }
1989
- return /* @__PURE__ */ jsxRuntime.jsx(
1990
- "div",
1991
- {
1992
- role: "alert",
1993
- "data-slot": "field-error",
1994
- className: cn("text-sm font-normal text-destructive", className),
1995
- ...props,
1996
- children: content
1997
- }
3143
+ const activeCount = facets.reduce(
3144
+ (n, f) => n + (values[f.key]?.length ?? 0),
3145
+ 0
1998
3146
  );
3147
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { children: [
3148
+ /* @__PURE__ */ jsxRuntime.jsx(
3149
+ PopoverTrigger,
3150
+ {
3151
+ render: /* @__PURE__ */ jsxRuntime.jsxs(
3152
+ "button",
3153
+ {
3154
+ type: "button",
3155
+ className: cn(
3156
+ "inline-flex h-7 items-center gap-1 rounded-full border bg-background px-2.5 text-xs transition-colors",
3157
+ activeCount > 0 ? "border-primary/40 bg-primary/5 text-foreground" : "text-muted-foreground hover:text-foreground"
3158
+ ),
3159
+ children: [
3160
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListFilter, { className: "size-3.5" }),
3161
+ "More",
3162
+ activeCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "ml-0.5 h-4 bg-primary px-1.5 text-primary-foreground", children: activeCount })
3163
+ ]
3164
+ }
3165
+ )
3166
+ }
3167
+ ),
3168
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-64 p-0", align: "start", "aria-label": "Filters", children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [
3169
+ facets.reduce((n, f) => n + f.options.length, 0) > 8 && /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Search filters\u2026" }),
3170
+ /* @__PURE__ */ jsxRuntime.jsxs(CommandList, { className: "max-h-[60vh]", children: [
3171
+ /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: "No filters." }),
3172
+ facets.map((facet) => /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { heading: facet.label, children: facet.options.map((opt) => {
3173
+ const checked = (values[facet.key] ?? []).includes(opt.value);
3174
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3175
+ CommandItem,
3176
+ {
3177
+ value: `${facet.label} ${opt.label}`,
3178
+ onSelect: () => onToggle(facet.key, opt.value),
3179
+ className: "gap-2.5",
3180
+ children: [
3181
+ /* @__PURE__ */ jsxRuntime.jsx(CheckIndicator, { checked }),
3182
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: opt.label }),
3183
+ checked && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "selected" })
3184
+ ]
3185
+ },
3186
+ opt.value
3187
+ );
3188
+ }) }, facet.key))
3189
+ ] })
3190
+ ] }) })
3191
+ ] });
1999
3192
  }
2000
3193
  function PackagePicker({
2001
3194
  packages,
@@ -2963,75 +4156,6 @@ function PersonDropdown({
2963
4156
  }
2964
4157
  );
2965
4158
  }
2966
- function Popover({ ...props }) {
2967
- return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Root, { "data-slot": "popover", ...props });
2968
- }
2969
- function PopoverTrigger({ ...props }) {
2970
- return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Trigger, { "data-slot": "popover-trigger", ...props });
2971
- }
2972
- function PopoverContent({
2973
- className,
2974
- align = "center",
2975
- alignOffset = 0,
2976
- side = "bottom",
2977
- sideOffset = 4,
2978
- ...props
2979
- }) {
2980
- return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
2981
- popover.Popover.Positioner,
2982
- {
2983
- align,
2984
- alignOffset,
2985
- side,
2986
- sideOffset,
2987
- className: "isolate z-50",
2988
- children: /* @__PURE__ */ jsxRuntime.jsx(
2989
- popover.Popover.Popup,
2990
- {
2991
- "data-slot": "popover-content",
2992
- className: cn(
2993
- "z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
2994
- className
2995
- ),
2996
- ...props
2997
- }
2998
- )
2999
- }
3000
- ) });
3001
- }
3002
- function PopoverHeader({ className, ...props }) {
3003
- return /* @__PURE__ */ jsxRuntime.jsx(
3004
- "div",
3005
- {
3006
- "data-slot": "popover-header",
3007
- className: cn("flex flex-col gap-0.5 text-sm", className),
3008
- ...props
3009
- }
3010
- );
3011
- }
3012
- function PopoverTitle({ className, ...props }) {
3013
- return /* @__PURE__ */ jsxRuntime.jsx(
3014
- popover.Popover.Title,
3015
- {
3016
- "data-slot": "popover-title",
3017
- className: cn("font-medium", className),
3018
- ...props
3019
- }
3020
- );
3021
- }
3022
- function PopoverDescription({
3023
- className,
3024
- ...props
3025
- }) {
3026
- return /* @__PURE__ */ jsxRuntime.jsx(
3027
- popover.Popover.Description,
3028
- {
3029
- "data-slot": "popover-description",
3030
- className: cn("text-muted-foreground", className),
3031
- ...props
3032
- }
3033
- );
3034
- }
3035
4159
  function ScrollArea({
3036
4160
  className,
3037
4161
  children,
@@ -4215,7 +5339,7 @@ function SheetContent({
4215
5339
  "data-slot": "sheet-content",
4216
5340
  "data-side": side,
4217
5341
  className: cn(
4218
- "fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
5342
+ "fixed z-50 flex flex-col gap-4 border-border bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
4219
5343
  className
4220
5344
  ),
4221
5345
  ...props,
@@ -5258,108 +6382,6 @@ function Switch({
5258
6382
  }
5259
6383
  );
5260
6384
  }
5261
- function Table({ className, ...props }) {
5262
- return /* @__PURE__ */ jsxRuntime.jsx(
5263
- "div",
5264
- {
5265
- "data-slot": "table-container",
5266
- className: "relative w-full overflow-x-auto",
5267
- children: /* @__PURE__ */ jsxRuntime.jsx(
5268
- "table",
5269
- {
5270
- "data-slot": "table",
5271
- className: cn("w-full caption-bottom text-sm", className),
5272
- ...props
5273
- }
5274
- )
5275
- }
5276
- );
5277
- }
5278
- function TableHeader({ className, ...props }) {
5279
- return /* @__PURE__ */ jsxRuntime.jsx(
5280
- "thead",
5281
- {
5282
- "data-slot": "table-header",
5283
- className: cn("[&_tr]:border-b", className),
5284
- ...props
5285
- }
5286
- );
5287
- }
5288
- function TableBody({ className, ...props }) {
5289
- return /* @__PURE__ */ jsxRuntime.jsx(
5290
- "tbody",
5291
- {
5292
- "data-slot": "table-body",
5293
- className: cn("[&_tr:last-child]:border-0", className),
5294
- ...props
5295
- }
5296
- );
5297
- }
5298
- function TableFooter({ className, ...props }) {
5299
- return /* @__PURE__ */ jsxRuntime.jsx(
5300
- "tfoot",
5301
- {
5302
- "data-slot": "table-footer",
5303
- className: cn(
5304
- "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
5305
- className
5306
- ),
5307
- ...props
5308
- }
5309
- );
5310
- }
5311
- function TableRow({ className, ...props }) {
5312
- return /* @__PURE__ */ jsxRuntime.jsx(
5313
- "tr",
5314
- {
5315
- "data-slot": "table-row",
5316
- className: cn(
5317
- "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
5318
- className
5319
- ),
5320
- ...props
5321
- }
5322
- );
5323
- }
5324
- function TableHead({ className, ...props }) {
5325
- return /* @__PURE__ */ jsxRuntime.jsx(
5326
- "th",
5327
- {
5328
- "data-slot": "table-head",
5329
- className: cn(
5330
- "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
5331
- className
5332
- ),
5333
- ...props
5334
- }
5335
- );
5336
- }
5337
- function TableCell({ className, ...props }) {
5338
- return /* @__PURE__ */ jsxRuntime.jsx(
5339
- "td",
5340
- {
5341
- "data-slot": "table-cell",
5342
- className: cn(
5343
- "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
5344
- className
5345
- ),
5346
- ...props
5347
- }
5348
- );
5349
- }
5350
- function TableCaption({
5351
- className,
5352
- ...props
5353
- }) {
5354
- return /* @__PURE__ */ jsxRuntime.jsx(
5355
- "caption",
5356
- {
5357
- "data-slot": "table-caption",
5358
- className: cn("mt-4 text-sm text-muted-foreground", className),
5359
- ...props
5360
- }
5361
- );
5362
- }
5363
6385
  function Tabs({
5364
6386
  className,
5365
6387
  orientation = "horizontal",
@@ -5471,6 +6493,8 @@ exports.CardFooter = CardFooter;
5471
6493
  exports.CardHeader = CardHeader;
5472
6494
  exports.CardTitle = CardTitle;
5473
6495
  exports.Checkbox = Checkbox;
6496
+ exports.ColumnCustomizer = ColumnCustomizer;
6497
+ exports.ColumnPicker = ColumnPicker;
5474
6498
  exports.Command = Command;
5475
6499
  exports.CommandDialog = CommandDialog;
5476
6500
  exports.CommandEmpty = CommandEmpty;
@@ -5480,6 +6504,7 @@ exports.CommandItem = CommandItem;
5480
6504
  exports.CommandList = CommandList;
5481
6505
  exports.CommandSeparator = CommandSeparator;
5482
6506
  exports.CommandShortcut = CommandShortcut;
6507
+ exports.DataTable = DataTable;
5483
6508
  exports.Dialog = Dialog;
5484
6509
  exports.DialogClose = DialogClose;
5485
6510
  exports.DialogContent = DialogContent;
@@ -5514,6 +6539,7 @@ exports.FieldLegend = FieldLegend;
5514
6539
  exports.FieldSeparator = FieldSeparator;
5515
6540
  exports.FieldSet = FieldSet;
5516
6541
  exports.FieldTitle = FieldTitle;
6542
+ exports.FilterBar = FilterBar;
5517
6543
  exports.InlineAddonPicker = InlineAddonPicker;
5518
6544
  exports.InlineSessionPicker = InlineSessionPicker;
5519
6545
  exports.Input = Input;