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