@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.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use client";
2
+ import '../styles.css';
2
3
  import { Accordion as Accordion$1 } from '@base-ui/react/accordion';
3
- import { ChevronDown, CheckIcon, ChevronRightIcon, MoreHorizontalIcon, Loader2, ChevronDownIcon, ChevronUpIcon, XIcon, PlusIcon, SearchIcon, Check, Circle, ChevronRight, PencilIcon, TrashIcon, ArrowLeftIcon, ArrowRightIcon, ChevronLeftIcon, ChevronsUpDown, CameraIcon, PanelLeftIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon, InfoIcon, CircleCheckIcon, BadgeCheck, AlertTriangleIcon } from 'lucide-react';
4
+ import { ChevronDown, CheckIcon, ChevronRightIcon, MoreHorizontalIcon, Loader2, ChevronDownIcon, ChevronUpIcon, XIcon, PlusIcon, Columns3, Search, GripVertical, X, SearchIcon, ChevronLeft, ChevronRight, Check, Circle, ListFilter, PencilIcon, TrashIcon, ArrowLeftIcon, ArrowRightIcon, ChevronLeftIcon, ChevronsUpDown, CameraIcon, PanelLeftIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon, InfoIcon, CircleCheckIcon, BadgeCheck, ChevronUp, AlertTriangleIcon } from 'lucide-react';
4
5
  import { clsx } from 'clsx';
5
6
  import { twMerge } from 'tailwind-merge';
6
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -10,13 +11,14 @@ import { useRender } from '@base-ui/react/use-render';
10
11
  import { cva } from 'class-variance-authority';
11
12
  import { Button as Button$1 } from '@base-ui/react/button';
12
13
  import * as React3 from 'react';
13
- import { useEffect, useMemo, useState, useRef, useLayoutEffect } from 'react';
14
+ import { useEffect, useState, useMemo, useRef, useLayoutEffect } from 'react';
14
15
  import { useForm, Controller } from 'react-hook-form';
15
16
  import { zodResolver } from '@hookform/resolvers/zod';
16
17
  import { z } from 'zod';
17
18
  import { Input as Input$1 } from '@base-ui/react/input';
18
19
  import { Select as Select$1 } from '@base-ui/react/select';
19
20
  import { Checkbox as Checkbox$1 } from '@base-ui/react/checkbox';
21
+ import { Popover as Popover$1 } from '@base-ui/react/popover';
20
22
  import { Command as Command$1 } from 'cmdk';
21
23
  import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
22
24
  import { Menu } from '@base-ui/react/menu';
@@ -25,7 +27,6 @@ import RPNInput, { getCountryCallingCode } from 'react-phone-number-input';
25
27
  export { getCountries, isValidPhoneNumber } from 'react-phone-number-input';
26
28
  import flags from 'react-phone-number-input/flags';
27
29
  import en from 'react-phone-number-input/locale/en.json';
28
- import { Popover as Popover$1 } from '@base-ui/react/popover';
29
30
  import { ScrollArea as ScrollArea$1 } from '@base-ui/react/scroll-area';
30
31
  import { Progress as Progress$1 } from '@base-ui/react/progress';
31
32
  import { RadioGroup as RadioGroup$1 } from '@base-ui/react/radio-group';
@@ -35,7 +36,7 @@ import { Toaster as Toaster$1 } from 'sonner';
35
36
  import { Switch as Switch$1 } from '@base-ui/react/switch';
36
37
  import { Tabs as Tabs$1 } from '@base-ui/react/tabs';
37
38
 
38
- // src/accordion.tsx
39
+ // src/index.ts
39
40
  function cn(...inputs) {
40
41
  return twMerge(clsx(inputs));
41
42
  }
@@ -1177,6 +1178,397 @@ function Checkbox({ className, ...props }) {
1177
1178
  }
1178
1179
  );
1179
1180
  }
1181
+ function Popover({ ...props }) {
1182
+ return /* @__PURE__ */ jsx(Popover$1.Root, { "data-slot": "popover", ...props });
1183
+ }
1184
+ function PopoverTrigger({ ...props }) {
1185
+ return /* @__PURE__ */ jsx(Popover$1.Trigger, { "data-slot": "popover-trigger", ...props });
1186
+ }
1187
+ function PopoverContent({
1188
+ className,
1189
+ align = "center",
1190
+ alignOffset = 0,
1191
+ side = "bottom",
1192
+ sideOffset = 4,
1193
+ ...props
1194
+ }) {
1195
+ return /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(
1196
+ Popover$1.Positioner,
1197
+ {
1198
+ align,
1199
+ alignOffset,
1200
+ side,
1201
+ sideOffset,
1202
+ className: "isolate z-50",
1203
+ children: /* @__PURE__ */ jsx(
1204
+ Popover$1.Popup,
1205
+ {
1206
+ "data-slot": "popover-content",
1207
+ className: cn(
1208
+ "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",
1209
+ className
1210
+ ),
1211
+ ...props
1212
+ }
1213
+ )
1214
+ }
1215
+ ) });
1216
+ }
1217
+ function PopoverHeader({ className, ...props }) {
1218
+ return /* @__PURE__ */ jsx(
1219
+ "div",
1220
+ {
1221
+ "data-slot": "popover-header",
1222
+ className: cn("flex flex-col gap-0.5 text-sm", className),
1223
+ ...props
1224
+ }
1225
+ );
1226
+ }
1227
+ function PopoverTitle({ className, ...props }) {
1228
+ return /* @__PURE__ */ jsx(
1229
+ Popover$1.Title,
1230
+ {
1231
+ "data-slot": "popover-title",
1232
+ className: cn("font-medium", className),
1233
+ ...props
1234
+ }
1235
+ );
1236
+ }
1237
+ function PopoverDescription({
1238
+ className,
1239
+ ...props
1240
+ }) {
1241
+ return /* @__PURE__ */ jsx(
1242
+ Popover$1.Description,
1243
+ {
1244
+ "data-slot": "popover-description",
1245
+ className: cn("text-muted-foreground", className),
1246
+ ...props
1247
+ }
1248
+ );
1249
+ }
1250
+ var ALL_GROUPS = "__all__";
1251
+ function ColumnCustomizer({
1252
+ columns,
1253
+ value,
1254
+ onApply,
1255
+ groupOrder,
1256
+ title = "Customize columns",
1257
+ searchPlaceholder = "Search for a column",
1258
+ allGroupsLabel = "All columns",
1259
+ align = "end",
1260
+ trigger
1261
+ }) {
1262
+ const [open, setOpen] = useState(false);
1263
+ const [draft, setDraft] = useState(value);
1264
+ const [query, setQuery] = useState("");
1265
+ const [group, setGroup] = useState(ALL_GROUPS);
1266
+ const [dragIndex, setDragIndex] = useState(null);
1267
+ const q = query.trim().toLowerCase();
1268
+ const searching = q !== "";
1269
+ const labelFor = useMemo(() => {
1270
+ const m = /* @__PURE__ */ new Map();
1271
+ for (const c of columns) m.set(c.key, c.label);
1272
+ return m;
1273
+ }, [columns]);
1274
+ const groupKeys = useMemo(() => {
1275
+ if (groupOrder?.length) return groupOrder;
1276
+ const seen = [];
1277
+ for (const c of columns) if (!seen.includes(c.group)) seen.push(c.group);
1278
+ return seen;
1279
+ }, [columns, groupOrder]);
1280
+ const groups = useMemo(
1281
+ () => [
1282
+ { key: ALL_GROUPS, label: allGroupsLabel, count: columns.length },
1283
+ ...groupKeys.map((g) => ({
1284
+ key: g,
1285
+ label: g,
1286
+ count: columns.filter((c) => c.group === g).length
1287
+ }))
1288
+ ],
1289
+ [columns, groupKeys, allGroupsLabel]
1290
+ );
1291
+ const handleOpenChange = (next) => {
1292
+ if (next) {
1293
+ setDraft(value);
1294
+ setQuery("");
1295
+ setGroup(ALL_GROUPS);
1296
+ }
1297
+ setOpen(next);
1298
+ };
1299
+ const toggle = (k) => setDraft(
1300
+ (cur) => cur.includes(k) ? cur.filter((c) => c !== k) : [...cur, k]
1301
+ );
1302
+ const remove = (k) => setDraft((cur) => cur.filter((c) => c !== k));
1303
+ const reorder = (from, to) => setDraft((cur) => {
1304
+ const next = [...cur];
1305
+ const [moved] = next.splice(from, 1);
1306
+ next.splice(to, 0, moved);
1307
+ return next;
1308
+ });
1309
+ const visibleCols = useMemo(() => {
1310
+ const base = searching || group === ALL_GROUPS ? columns : columns.filter((c) => c.group === group);
1311
+ return searching ? base.filter((c) => c.label.toLowerCase().includes(q)) : base;
1312
+ }, [columns, q, group, searching]);
1313
+ const showSource = searching || group === ALL_GROUPS;
1314
+ const allChecked = visibleCols.length > 0 && visibleCols.every((c) => draft.includes(c.key));
1315
+ const toggleAll = () => setDraft(
1316
+ (cur) => allChecked ? cur.filter((k) => !visibleCols.some((c) => c.key === k)) : [
1317
+ ...cur,
1318
+ ...visibleCols.map((c) => c.key).filter((k) => !cur.includes(k))
1319
+ ]
1320
+ );
1321
+ const activeGroupLabel = groups.find((g) => g.key === group)?.label;
1322
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
1323
+ trigger ? /* @__PURE__ */ jsx(PopoverTrigger, { render: trigger }) : /* @__PURE__ */ jsxs(
1324
+ PopoverTrigger,
1325
+ {
1326
+ type: "button",
1327
+ className: cn(
1328
+ buttonVariants({ variant: "outline" }),
1329
+ "h-9 gap-1.5 text-muted-foreground"
1330
+ ),
1331
+ children: [
1332
+ /* @__PURE__ */ jsx(Columns3, { className: "size-4" }),
1333
+ "Columns"
1334
+ ]
1335
+ }
1336
+ ),
1337
+ /* @__PURE__ */ jsxs(
1338
+ PopoverContent,
1339
+ {
1340
+ align,
1341
+ className: "w-[720px] max-w-[calc(100vw-2rem)] gap-0 p-0",
1342
+ children: [
1343
+ /* @__PURE__ */ jsx(PopoverTitle, { className: "px-4 pt-4 pb-3 text-sm font-semibold", children: title }),
1344
+ /* @__PURE__ */ jsx("div", { className: "px-4 pb-3", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1345
+ /* @__PURE__ */ jsx(Search, { className: "absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" }),
1346
+ /* @__PURE__ */ jsx(
1347
+ Input,
1348
+ {
1349
+ value: query,
1350
+ onChange: (e) => setQuery(e.target.value),
1351
+ placeholder: searchPlaceholder,
1352
+ "aria-label": searchPlaceholder,
1353
+ className: "h-10 pl-9"
1354
+ }
1355
+ )
1356
+ ] }) }),
1357
+ /* @__PURE__ */ jsxs("div", { className: "grid h-[380px] grid-cols-[12rem_1fr_16rem] border-y", children: [
1358
+ /* @__PURE__ */ jsx("div", { className: "overflow-y-auto border-r p-2", children: groups.map((gr) => /* @__PURE__ */ jsxs(
1359
+ "button",
1360
+ {
1361
+ type: "button",
1362
+ disabled: searching,
1363
+ onClick: () => setGroup(gr.key),
1364
+ className: cn(
1365
+ "flex w-full items-center justify-between gap-2 rounded-md px-3 py-2 text-left text-sm hover:bg-muted/60",
1366
+ !searching && group === gr.key && "bg-muted font-medium",
1367
+ searching && "opacity-40"
1368
+ ),
1369
+ children: [
1370
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: gr.label }),
1371
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded-md bg-muted px-1.5 text-xs tabular-nums text-muted-foreground", children: gr.count })
1372
+ ]
1373
+ },
1374
+ gr.key
1375
+ )) }),
1376
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 overflow-y-auto p-3", children: [
1377
+ /* @__PURE__ */ jsx("div", { className: "px-1 pb-1 text-sm font-semibold", children: searching ? "Search results" : activeGroupLabel }),
1378
+ !searching && visibleCols.length > 0 && /* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center gap-2.5 border-b px-1 py-2 text-sm", children: [
1379
+ /* @__PURE__ */ jsx(
1380
+ Checkbox,
1381
+ {
1382
+ checked: allChecked,
1383
+ onCheckedChange: () => toggleAll()
1384
+ }
1385
+ ),
1386
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Select all" })
1387
+ ] }),
1388
+ /* @__PURE__ */ jsx("div", { className: "pt-1", children: visibleCols.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "px-1 py-6 text-center text-sm text-muted-foreground", children: [
1389
+ "No columns match \u201C",
1390
+ query,
1391
+ "\u201D."
1392
+ ] }) : visibleCols.map((c) => /* @__PURE__ */ jsxs(
1393
+ "label",
1394
+ {
1395
+ className: "flex cursor-pointer items-center gap-2.5 rounded-md px-1 py-2 text-sm hover:bg-muted/60",
1396
+ children: [
1397
+ /* @__PURE__ */ jsx(
1398
+ Checkbox,
1399
+ {
1400
+ checked: draft.includes(c.key),
1401
+ onCheckedChange: () => toggle(c.key)
1402
+ }
1403
+ ),
1404
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: c.label }),
1405
+ showSource && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: c.group })
1406
+ ]
1407
+ },
1408
+ c.key
1409
+ )) })
1410
+ ] }),
1411
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 min-w-0 flex-col overflow-hidden border-l", children: [
1412
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-3 py-2.5", children: [
1413
+ /* @__PURE__ */ jsxs("span", { className: "text-sm font-semibold", children: [
1414
+ draft.length,
1415
+ " selected"
1416
+ ] }),
1417
+ draft.length > 0 && /* @__PURE__ */ jsx(
1418
+ "button",
1419
+ {
1420
+ type: "button",
1421
+ onClick: () => setDraft([]),
1422
+ className: "text-xs font-medium text-primary hover:underline",
1423
+ children: "Clear all"
1424
+ }
1425
+ )
1426
+ ] }),
1427
+ /* @__PURE__ */ jsx("div", { className: "flex-1 space-y-1.5 overflow-y-auto px-3 pb-3", children: draft.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-1 py-6 text-center text-sm text-muted-foreground", children: "No columns selected." }) : draft.map((k, i) => /* @__PURE__ */ jsxs(
1428
+ "div",
1429
+ {
1430
+ draggable: true,
1431
+ onDragStart: () => setDragIndex(i),
1432
+ onDragOver: (e) => e.preventDefault(),
1433
+ onDrop: () => {
1434
+ if (dragIndex !== null && dragIndex !== i)
1435
+ reorder(dragIndex, i);
1436
+ setDragIndex(null);
1437
+ },
1438
+ onDragEnd: () => setDragIndex(null),
1439
+ className: cn(
1440
+ "flex items-center gap-2 rounded-md border bg-background px-2.5 py-2 text-sm",
1441
+ dragIndex === i && "opacity-50"
1442
+ ),
1443
+ children: [
1444
+ /* @__PURE__ */ jsx(GripVertical, { className: "size-3.5 shrink-0 cursor-grab text-muted-foreground" }),
1445
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: labelFor.get(k) ?? k }),
1446
+ /* @__PURE__ */ jsx(
1447
+ "button",
1448
+ {
1449
+ type: "button",
1450
+ onClick: () => remove(k),
1451
+ "aria-label": `Remove ${labelFor.get(k) ?? k}`,
1452
+ className: "shrink-0 rounded-sm p-0.5 text-muted-foreground hover:text-foreground",
1453
+ children: /* @__PURE__ */ jsx(X, { className: "size-3.5" })
1454
+ }
1455
+ )
1456
+ ]
1457
+ },
1458
+ k
1459
+ )) })
1460
+ ] })
1461
+ ] }),
1462
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2 px-4 py-3", children: [
1463
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => setOpen(false), children: "Cancel" }),
1464
+ /* @__PURE__ */ jsx(
1465
+ Button,
1466
+ {
1467
+ onClick: () => {
1468
+ onApply(draft);
1469
+ setOpen(false);
1470
+ },
1471
+ children: "Apply"
1472
+ }
1473
+ )
1474
+ ] })
1475
+ ]
1476
+ }
1477
+ )
1478
+ ] });
1479
+ }
1480
+ function ColumnPicker({
1481
+ columns,
1482
+ value,
1483
+ onChange,
1484
+ title = "Columns",
1485
+ searchPlaceholder = "Search columns",
1486
+ align = "end",
1487
+ trigger
1488
+ }) {
1489
+ const [query, setQuery] = useState("");
1490
+ const q = query.trim().toLowerCase();
1491
+ const visible = useMemo(() => new Set(value), [value]);
1492
+ const filtered = useMemo(
1493
+ () => q ? columns.filter((c) => c.label.toLowerCase().includes(q)) : columns,
1494
+ [columns, q]
1495
+ );
1496
+ const emit = (next) => onChange(columns.filter((c) => next.has(c.key)).map((c) => c.key));
1497
+ const toggle = (key) => {
1498
+ const next = new Set(visible);
1499
+ if (next.has(key)) next.delete(key);
1500
+ else next.add(key);
1501
+ emit(next);
1502
+ };
1503
+ const allChecked = filtered.length > 0 && filtered.every((c) => visible.has(c.key));
1504
+ const toggleAll = () => {
1505
+ const next = new Set(visible);
1506
+ for (const c of filtered) {
1507
+ if (allChecked) next.delete(c.key);
1508
+ else next.add(c.key);
1509
+ }
1510
+ emit(next);
1511
+ };
1512
+ return /* @__PURE__ */ jsxs(Popover, { children: [
1513
+ trigger ? /* @__PURE__ */ jsx(PopoverTrigger, { render: trigger }) : /* @__PURE__ */ jsxs(
1514
+ PopoverTrigger,
1515
+ {
1516
+ type: "button",
1517
+ className: cn(
1518
+ buttonVariants({ variant: "outline" }),
1519
+ "h-9 gap-1.5 text-muted-foreground"
1520
+ ),
1521
+ children: [
1522
+ /* @__PURE__ */ jsx(Columns3, { className: "size-4" }),
1523
+ "Columns"
1524
+ ]
1525
+ }
1526
+ ),
1527
+ /* @__PURE__ */ jsxs(PopoverContent, { align, className: "w-72 gap-0 p-0", children: [
1528
+ /* @__PURE__ */ jsx(PopoverTitle, { className: "px-3 pt-3 pb-2 text-sm font-semibold", children: title }),
1529
+ /* @__PURE__ */ jsx("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1530
+ /* @__PURE__ */ jsx(Search, { className: "absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" }),
1531
+ /* @__PURE__ */ jsx(
1532
+ Input,
1533
+ {
1534
+ value: query,
1535
+ onChange: (e) => setQuery(e.target.value),
1536
+ placeholder: searchPlaceholder,
1537
+ "aria-label": searchPlaceholder,
1538
+ className: "h-9 pl-9"
1539
+ }
1540
+ )
1541
+ ] }) }),
1542
+ /* @__PURE__ */ jsx("div", { className: "max-h-[320px] overflow-y-auto border-t px-1.5 py-1.5", children: filtered.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "px-2 py-6 text-center text-sm text-muted-foreground", children: [
1543
+ "No columns match \u201C",
1544
+ query,
1545
+ "\u201D."
1546
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1547
+ /* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center gap-2.5 rounded-md px-2 py-2 text-sm hover:bg-muted/60", children: [
1548
+ /* @__PURE__ */ jsx(Checkbox, { checked: allChecked, onCheckedChange: () => toggleAll() }),
1549
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Select all" })
1550
+ ] }),
1551
+ filtered.map((c) => /* @__PURE__ */ jsxs(
1552
+ "label",
1553
+ {
1554
+ className: "flex cursor-pointer items-center gap-2.5 rounded-md px-2 py-2 text-sm hover:bg-muted/60",
1555
+ children: [
1556
+ /* @__PURE__ */ jsx(
1557
+ Checkbox,
1558
+ {
1559
+ checked: visible.has(c.key),
1560
+ onCheckedChange: () => toggle(c.key)
1561
+ }
1562
+ ),
1563
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: c.label })
1564
+ ]
1565
+ },
1566
+ c.key
1567
+ ))
1568
+ ] }) })
1569
+ ] })
1570
+ ] });
1571
+ }
1180
1572
  function Dialog({ ...props }) {
1181
1573
  return /* @__PURE__ */ jsx(Dialog$1.Root, { "data-slot": "dialog", ...props });
1182
1574
  }
@@ -1271,7 +1663,7 @@ function DialogFooter({
1271
1663
  {
1272
1664
  "data-slot": "dialog-footer",
1273
1665
  className: cn(
1274
- "-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",
1666
+ "-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",
1275
1667
  className
1276
1668
  ),
1277
1669
  ...props,
@@ -1610,6 +2002,459 @@ function CommandShortcut({
1610
2002
  }
1611
2003
  );
1612
2004
  }
2005
+ function Table({ className, ...props }) {
2006
+ return /* @__PURE__ */ jsx(
2007
+ "div",
2008
+ {
2009
+ "data-slot": "table-container",
2010
+ className: "relative w-full overflow-x-auto",
2011
+ children: /* @__PURE__ */ jsx(
2012
+ "table",
2013
+ {
2014
+ "data-slot": "table",
2015
+ className: cn("w-full caption-bottom text-sm", className),
2016
+ ...props
2017
+ }
2018
+ )
2019
+ }
2020
+ );
2021
+ }
2022
+ function TableHeader({ className, ...props }) {
2023
+ return /* @__PURE__ */ jsx(
2024
+ "thead",
2025
+ {
2026
+ "data-slot": "table-header",
2027
+ className: cn("[&_tr]:border-b", className),
2028
+ ...props
2029
+ }
2030
+ );
2031
+ }
2032
+ function TableBody({ className, ...props }) {
2033
+ return /* @__PURE__ */ jsx(
2034
+ "tbody",
2035
+ {
2036
+ "data-slot": "table-body",
2037
+ className: cn("[&_tr:last-child]:border-0", className),
2038
+ ...props
2039
+ }
2040
+ );
2041
+ }
2042
+ function TableFooter({ className, ...props }) {
2043
+ return /* @__PURE__ */ jsx(
2044
+ "tfoot",
2045
+ {
2046
+ "data-slot": "table-footer",
2047
+ className: cn(
2048
+ "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
2049
+ className
2050
+ ),
2051
+ ...props
2052
+ }
2053
+ );
2054
+ }
2055
+ function TableRow({ className, ...props }) {
2056
+ return /* @__PURE__ */ jsx(
2057
+ "tr",
2058
+ {
2059
+ "data-slot": "table-row",
2060
+ className: cn(
2061
+ "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
2062
+ className
2063
+ ),
2064
+ ...props
2065
+ }
2066
+ );
2067
+ }
2068
+ function TableHead({ className, ...props }) {
2069
+ return /* @__PURE__ */ jsx(
2070
+ "th",
2071
+ {
2072
+ "data-slot": "table-head",
2073
+ className: cn(
2074
+ "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
2075
+ className
2076
+ ),
2077
+ ...props
2078
+ }
2079
+ );
2080
+ }
2081
+ function TableCell({ className, ...props }) {
2082
+ return /* @__PURE__ */ jsx(
2083
+ "td",
2084
+ {
2085
+ "data-slot": "table-cell",
2086
+ className: cn(
2087
+ "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
2088
+ className
2089
+ ),
2090
+ ...props
2091
+ }
2092
+ );
2093
+ }
2094
+ function TableCaption({
2095
+ className,
2096
+ ...props
2097
+ }) {
2098
+ return /* @__PURE__ */ jsx(
2099
+ "caption",
2100
+ {
2101
+ "data-slot": "table-caption",
2102
+ className: cn("mt-4 text-sm text-muted-foreground", className),
2103
+ ...props
2104
+ }
2105
+ );
2106
+ }
2107
+ var SELECT_COL_PX = 48;
2108
+ var STICKY_UNDERLAP_PX = 8;
2109
+ var selectColStyle = {
2110
+ width: SELECT_COL_PX,
2111
+ minWidth: SELECT_COL_PX,
2112
+ maxWidth: SELECT_COL_PX
2113
+ };
2114
+ var DEFAULT_STICKY_PX = 180;
2115
+ var HEADER_CELL_BG = "bg-[color-mix(in_oklab,var(--color-muted)_40%,var(--color-background))]";
2116
+ function alignClass(align) {
2117
+ return align === "right" ? "text-right" : align === "center" ? "text-center" : "text-left";
2118
+ }
2119
+ function DataTable({
2120
+ data,
2121
+ columns,
2122
+ rowKey,
2123
+ selectable = false,
2124
+ selected: selectedProp,
2125
+ onSelectedChange,
2126
+ bulkActions,
2127
+ sort: sortProp,
2128
+ defaultSort = null,
2129
+ onSortChange,
2130
+ paginated = false,
2131
+ pageSize: pageSizeProp,
2132
+ pageSizeOptions = [25, 50, 100],
2133
+ stickyPagination = false,
2134
+ page: pageProp,
2135
+ onPageChange,
2136
+ toolbar,
2137
+ onRowClick,
2138
+ emptyMessage = "No rows to show.",
2139
+ rowClassName,
2140
+ className
2141
+ }) {
2142
+ const [selInner, setSelInner] = useState(/* @__PURE__ */ new Set());
2143
+ const selected = selectedProp ?? selInner;
2144
+ const setSelected = (next) => {
2145
+ onSelectedChange?.(next);
2146
+ if (selectedProp === void 0) setSelInner(next);
2147
+ };
2148
+ const toggleRow = (id) => {
2149
+ const next = new Set(selected);
2150
+ if (next.has(id)) next.delete(id);
2151
+ else next.add(id);
2152
+ setSelected(next);
2153
+ };
2154
+ const clearSelection = () => setSelected(/* @__PURE__ */ new Set());
2155
+ const [sortInner, setSortInner] = useState(defaultSort);
2156
+ const sort = sortProp !== void 0 ? sortProp : sortInner;
2157
+ const colByKey = useMemo(() => {
2158
+ const m = /* @__PURE__ */ new Map();
2159
+ for (const c of columns) m.set(c.key, c);
2160
+ return m;
2161
+ }, [columns]);
2162
+ const toggleSort = (key) => {
2163
+ const next = sort?.key !== key ? { key, dir: "asc" } : sort.dir === "asc" ? { key, dir: "desc" } : null;
2164
+ onSortChange?.(next);
2165
+ if (sortProp === void 0) setSortInner(next);
2166
+ };
2167
+ const sorted = useMemo(() => {
2168
+ if (!sort) return data;
2169
+ const col = colByKey.get(sort.key);
2170
+ if (!col?.sortValue) return data;
2171
+ const { sortValue } = col;
2172
+ const arr = [...data];
2173
+ arr.sort((a, b) => {
2174
+ const av = sortValue(a);
2175
+ const bv = sortValue(b);
2176
+ const cmp = typeof av === "number" && typeof bv === "number" ? av - bv : String(av).localeCompare(String(bv));
2177
+ return sort.dir === "asc" ? cmp : -cmp;
2178
+ });
2179
+ return arr;
2180
+ }, [data, sort, colByKey]);
2181
+ const [pageSizeInner, setPageSizeInner] = useState(pageSizeProp ?? 25);
2182
+ const pageSize = paginated ? pageSizeInner : sorted.length || 1;
2183
+ const [pageInner, setPageInner] = useState(0);
2184
+ const page = pageProp !== void 0 ? pageProp : pageInner;
2185
+ const setPage = (p) => {
2186
+ onPageChange?.(p);
2187
+ if (pageProp === void 0) setPageInner(p);
2188
+ };
2189
+ const total = sorted.length;
2190
+ const pageCount = Math.max(1, Math.ceil(total / pageSize));
2191
+ const safePage = Math.min(page, pageCount - 1);
2192
+ const pageStart = paginated ? safePage * pageSize : 0;
2193
+ const rows = paginated ? sorted.slice(pageStart, pageStart + pageSize) : sorted;
2194
+ const pageIds = rows.map(rowKey);
2195
+ const allChecked = pageIds.length > 0 && pageIds.every((id) => selected.has(id));
2196
+ const toggleAll = () => {
2197
+ const next = new Set(selected);
2198
+ for (const id of pageIds) {
2199
+ if (allChecked) next.delete(id);
2200
+ else next.add(id);
2201
+ }
2202
+ setSelected(next);
2203
+ };
2204
+ const selectedCount = selected.size;
2205
+ const stickyLeft = useMemo(() => {
2206
+ const offsets = /* @__PURE__ */ new Map();
2207
+ let left = selectable ? SELECT_COL_PX - STICKY_UNDERLAP_PX : 0;
2208
+ for (const col of columns) {
2209
+ if (!col.sticky) continue;
2210
+ offsets.set(col.key, left);
2211
+ left += typeof col.width === "number" ? col.width : DEFAULT_STICKY_PX;
2212
+ }
2213
+ return offsets;
2214
+ }, [columns, selectable]);
2215
+ const colCount = (selectable ? 1 : 0) + columns.length + 1;
2216
+ const sortIcon = (key) => {
2217
+ if (sort?.key !== key)
2218
+ return /* @__PURE__ */ jsx(ChevronsUpDown, { className: "size-3.5 text-muted-foreground/50 opacity-0 transition-opacity group-hover/sort:opacity-100" });
2219
+ return sort.dir === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { className: "size-3.5" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "size-3.5" });
2220
+ };
2221
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", className), children: [
2222
+ toolbar,
2223
+ bulkActions?.length && selectedCount > 0 ? /* @__PURE__ */ 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: [
2224
+ /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium", children: [
2225
+ selectedCount,
2226
+ " selected"
2227
+ ] }),
2228
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "\xB7" }),
2229
+ bulkActions.map(
2230
+ (action, i) => action.options ? /* @__PURE__ */ jsxs(
2231
+ Select,
2232
+ {
2233
+ value: "",
2234
+ onValueChange: (v) => v && action.onPick?.(v),
2235
+ children: [
2236
+ /* @__PURE__ */ jsx(
2237
+ SelectTrigger,
2238
+ {
2239
+ "aria-label": action.label,
2240
+ className: "h-8 min-w-[130px] bg-background text-sm",
2241
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: action.label })
2242
+ }
2243
+ ),
2244
+ /* @__PURE__ */ jsx(SelectContent, { className: "w-auto min-w-(--anchor-width) max-w-[20rem]", children: action.options.map((o) => /* @__PURE__ */ jsx(SelectItem, { value: o.value, children: o.label }, o.value)) })
2245
+ ]
2246
+ },
2247
+ i
2248
+ ) : /* @__PURE__ */ jsx(
2249
+ "button",
2250
+ {
2251
+ type: "button",
2252
+ onClick: action.onClick,
2253
+ className: "inline-flex h-8 items-center rounded-md border bg-background px-2.5 text-sm hover:bg-muted",
2254
+ children: action.label
2255
+ },
2256
+ i
2257
+ )
2258
+ ),
2259
+ /* @__PURE__ */ jsxs(
2260
+ "button",
2261
+ {
2262
+ type: "button",
2263
+ onClick: clearSelection,
2264
+ className: "inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground",
2265
+ children: [
2266
+ /* @__PURE__ */ jsx(X, { className: "size-3.5" }),
2267
+ "Clear"
2268
+ ]
2269
+ }
2270
+ )
2271
+ ] }) : null,
2272
+ /* @__PURE__ */ jsx("div", { className: "rounded-xl border bg-background overflow-hidden", children: /* @__PURE__ */ jsxs(Table, { className: "border-separate border-spacing-0", children: [
2273
+ /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { className: "text-xs uppercase tracking-wide text-muted-foreground", children: [
2274
+ selectable && /* @__PURE__ */ jsx(
2275
+ TableHead,
2276
+ {
2277
+ style: selectColStyle,
2278
+ className: cn(
2279
+ "sticky left-0 z-30 px-0 py-2.5 border-b rounded-tl-xl",
2280
+ HEADER_CELL_BG
2281
+ ),
2282
+ children: /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
2283
+ Checkbox,
2284
+ {
2285
+ checked: allChecked,
2286
+ onCheckedChange: toggleAll,
2287
+ "aria-label": "Select all"
2288
+ }
2289
+ ) })
2290
+ }
2291
+ ),
2292
+ columns.map((col, colIndex) => {
2293
+ const sortable = col.sortable && col.sortValue;
2294
+ const left = stickyLeft.get(col.key);
2295
+ const isFirstCol = !selectable && colIndex === 0;
2296
+ return /* @__PURE__ */ jsx(
2297
+ TableHead,
2298
+ {
2299
+ style: col.sticky ? { left, minWidth: col.width } : { minWidth: col.width },
2300
+ className: cn(
2301
+ "px-4 py-2.5 border-b font-medium text-muted-foreground",
2302
+ HEADER_CELL_BG,
2303
+ alignClass(col.align),
2304
+ col.sticky && "sticky z-20",
2305
+ isFirstCol && "rounded-tl-xl",
2306
+ col.headerClassName
2307
+ ),
2308
+ children: sortable ? /* @__PURE__ */ jsxs(
2309
+ "button",
2310
+ {
2311
+ type: "button",
2312
+ onClick: () => toggleSort(col.key),
2313
+ className: "group/sort inline-flex items-center gap-1 hover:text-foreground",
2314
+ children: [
2315
+ col.header,
2316
+ sortIcon(col.key)
2317
+ ]
2318
+ }
2319
+ ) : col.header
2320
+ },
2321
+ col.key
2322
+ );
2323
+ }),
2324
+ /* @__PURE__ */ jsx(TableHead, { "aria-hidden": true, className: cn("w-full border-b", HEADER_CELL_BG) })
2325
+ ] }) }),
2326
+ /* @__PURE__ */ jsx(TableBody, { children: data.length === 0 ? /* @__PURE__ */ jsx(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ jsx(
2327
+ TableCell,
2328
+ {
2329
+ colSpan: colCount,
2330
+ className: "py-12 text-center text-sm text-muted-foreground rounded-bl-xl",
2331
+ children: emptyMessage
2332
+ }
2333
+ ) }) : rows.map((row, rowIndex) => {
2334
+ const id = rowKey(row);
2335
+ const isSel = selected.has(id);
2336
+ const rowBg = isSel ? "bg-muted" : "bg-background";
2337
+ const isLastRow = rowIndex === rows.length - 1;
2338
+ return /* @__PURE__ */ jsxs(
2339
+ TableRow,
2340
+ {
2341
+ className: cn(
2342
+ "group",
2343
+ rowBg,
2344
+ "hover:bg-muted",
2345
+ rowClassName?.(row)
2346
+ ),
2347
+ children: [
2348
+ selectable && /* @__PURE__ */ jsx(
2349
+ TableCell,
2350
+ {
2351
+ style: selectColStyle,
2352
+ className: cn(
2353
+ "sticky left-0 z-20 px-0 py-2.5 border-b group-hover:bg-muted",
2354
+ rowBg,
2355
+ isLastRow && "rounded-bl-xl"
2356
+ ),
2357
+ children: /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
2358
+ Checkbox,
2359
+ {
2360
+ checked: isSel,
2361
+ onCheckedChange: () => toggleRow(id),
2362
+ "aria-label": "Select row"
2363
+ }
2364
+ ) })
2365
+ }
2366
+ ),
2367
+ columns.map((col, colIndex) => {
2368
+ const left = stickyLeft.get(col.key);
2369
+ const isFirstCol = !selectable && colIndex === 0;
2370
+ return /* @__PURE__ */ jsx(
2371
+ TableCell,
2372
+ {
2373
+ style: col.sticky ? { left } : void 0,
2374
+ className: cn(
2375
+ "px-4 py-2.5 border-b align-middle",
2376
+ alignClass(col.align),
2377
+ col.sticky && cn("sticky z-10 group-hover:bg-muted", rowBg),
2378
+ isFirstCol && isLastRow && "rounded-bl-xl",
2379
+ col.className
2380
+ ),
2381
+ onClick: col.sticky && onRowClick ? () => onRowClick(row) : void 0,
2382
+ children: col.render(row)
2383
+ },
2384
+ col.key
2385
+ );
2386
+ }),
2387
+ /* @__PURE__ */ jsx(TableCell, { "aria-hidden": true, className: "border-b" })
2388
+ ]
2389
+ },
2390
+ id
2391
+ );
2392
+ }) })
2393
+ ] }) }),
2394
+ paginated && total > 0 && /* @__PURE__ */ jsxs(
2395
+ "div",
2396
+ {
2397
+ className: cn(
2398
+ "flex items-center justify-between gap-4 text-sm text-muted-foreground",
2399
+ 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"
2400
+ ),
2401
+ children: [
2402
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2403
+ /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Rows per page" }),
2404
+ /* @__PURE__ */ jsxs(
2405
+ Select,
2406
+ {
2407
+ value: String(pageSize),
2408
+ onValueChange: (v) => {
2409
+ if (!v) return;
2410
+ setPageSizeInner(Number(v));
2411
+ setPage(0);
2412
+ },
2413
+ children: [
2414
+ /* @__PURE__ */ jsx(SelectTrigger, { "aria-label": "Rows per page", className: "h-8 w-[70px]", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
2415
+ /* @__PURE__ */ jsx(SelectContent, { children: pageSizeOptions.map((n) => /* @__PURE__ */ jsx(SelectItem, { value: String(n), children: n }, n)) })
2416
+ ]
2417
+ }
2418
+ )
2419
+ ] }),
2420
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
2421
+ /* @__PURE__ */ jsxs("span", { className: "tabular-nums whitespace-nowrap", children: [
2422
+ pageStart + 1,
2423
+ "\u2013",
2424
+ Math.min(pageStart + pageSize, total),
2425
+ " of ",
2426
+ total
2427
+ ] }),
2428
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
2429
+ /* @__PURE__ */ jsx(
2430
+ "button",
2431
+ {
2432
+ type: "button",
2433
+ onClick: () => setPage(safePage - 1),
2434
+ disabled: safePage === 0,
2435
+ "aria-label": "Previous page",
2436
+ className: "inline-flex size-8 items-center justify-center rounded-md border bg-background hover:bg-muted disabled:pointer-events-none disabled:opacity-40",
2437
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" })
2438
+ }
2439
+ ),
2440
+ /* @__PURE__ */ jsx(
2441
+ "button",
2442
+ {
2443
+ type: "button",
2444
+ onClick: () => setPage(safePage + 1),
2445
+ disabled: safePage >= pageCount - 1,
2446
+ "aria-label": "Next page",
2447
+ className: "inline-flex size-8 items-center justify-center rounded-md border bg-background hover:bg-muted disabled:pointer-events-none disabled:opacity-40",
2448
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" })
2449
+ }
2450
+ )
2451
+ ] })
2452
+ ] })
2453
+ ]
2454
+ }
2455
+ )
2456
+ ] });
2457
+ }
1613
2458
  function DropdownMenu(props) {
1614
2459
  return /* @__PURE__ */ jsx(Menu.Root, { "data-slot": "dropdown-menu", ...props });
1615
2460
  }
@@ -1930,47 +2775,406 @@ function FieldSeparator({
1930
2775
  "data-slot": "field-separator-content",
1931
2776
  children
1932
2777
  }
1933
- )
2778
+ )
2779
+ ]
2780
+ }
2781
+ );
2782
+ }
2783
+ function FieldError({
2784
+ className,
2785
+ children,
2786
+ errors,
2787
+ ...props
2788
+ }) {
2789
+ const content = useMemo(() => {
2790
+ if (children) {
2791
+ return children;
2792
+ }
2793
+ if (!errors?.length) {
2794
+ return null;
2795
+ }
2796
+ const uniqueErrors = [
2797
+ ...new Map(errors.map((error) => [error?.message, error])).values()
2798
+ ];
2799
+ if (uniqueErrors?.length == 1) {
2800
+ return uniqueErrors[0]?.message;
2801
+ }
2802
+ return /* @__PURE__ */ jsx("ul", { className: "ml-4 flex list-disc flex-col gap-1", children: uniqueErrors.map(
2803
+ (error, index) => error?.message && /* @__PURE__ */ jsx("li", { children: error.message }, index)
2804
+ ) });
2805
+ }, [children, errors]);
2806
+ if (!content) {
2807
+ return null;
2808
+ }
2809
+ return /* @__PURE__ */ jsx(
2810
+ "div",
2811
+ {
2812
+ role: "alert",
2813
+ "data-slot": "field-error",
2814
+ className: cn("text-sm font-normal text-destructive", className),
2815
+ ...props,
2816
+ children: content
2817
+ }
2818
+ );
2819
+ }
2820
+ function CheckIndicator({ checked }) {
2821
+ return /* @__PURE__ */ jsx(
2822
+ "span",
2823
+ {
2824
+ "aria-hidden": true,
2825
+ className: cn(
2826
+ "flex size-4 shrink-0 items-center justify-center rounded-[4px] border transition-colors",
2827
+ checked ? "border-primary bg-primary text-primary-foreground" : "border-input"
2828
+ ),
2829
+ children: checked && /* @__PURE__ */ jsx(Check, { className: "size-3.5" })
2830
+ }
2831
+ );
2832
+ }
2833
+ function FilterBar({
2834
+ search,
2835
+ onSearchChange,
2836
+ searchPlaceholder = "Search by name\u2026",
2837
+ showSearch = true,
2838
+ facets = [],
2839
+ values = {},
2840
+ onValuesChange,
2841
+ resultCount,
2842
+ resultNoun = "result",
2843
+ maxVisibleFacets = 3,
2844
+ right,
2845
+ left,
2846
+ filterVariant = "inline",
2847
+ className
2848
+ }) {
2849
+ const visibleFacets = facets.slice(0, maxVisibleFacets);
2850
+ const overflowFacets = facets.slice(maxVisibleFacets);
2851
+ const toggle = (key, value) => {
2852
+ const cur = values[key] ?? [];
2853
+ const next = cur.includes(value) ? cur.filter((v) => v !== value) : [...cur, value];
2854
+ onValuesChange?.({ ...values, [key]: next });
2855
+ };
2856
+ const clearAll = () => onValuesChange?.({});
2857
+ const activeCount = Object.values(values).reduce((n, a) => n + a.length, 0);
2858
+ const searchBox = /* @__PURE__ */ jsxs("div", { className: "relative w-56", children: [
2859
+ /* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
2860
+ /* @__PURE__ */ jsx(
2861
+ Input,
2862
+ {
2863
+ value: search,
2864
+ onChange: (e) => onSearchChange(e.target.value),
2865
+ placeholder: searchPlaceholder,
2866
+ "aria-label": searchPlaceholder,
2867
+ className: "rounded-full bg-background pl-8 pr-8"
2868
+ }
2869
+ ),
2870
+ search && /* @__PURE__ */ jsx(
2871
+ "button",
2872
+ {
2873
+ type: "button",
2874
+ onClick: () => onSearchChange(""),
2875
+ "aria-label": "Clear search",
2876
+ 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",
2877
+ children: /* @__PURE__ */ jsx(X, { className: "size-3.5" })
2878
+ }
2879
+ )
2880
+ ] });
2881
+ return /* @__PURE__ */ jsx("div", { className: cn("space-y-2", className), children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
2882
+ left,
2883
+ filterVariant === "inline" && /* @__PURE__ */ jsxs(Fragment, { children: [
2884
+ showSearch && searchBox,
2885
+ visibleFacets.map((facet) => /* @__PURE__ */ jsx(
2886
+ FacetDropdown,
2887
+ {
2888
+ facet,
2889
+ selected: values[facet.key] ?? [],
2890
+ onToggle: (value) => toggle(facet.key, value),
2891
+ onClear: () => onValuesChange?.({ ...values, [facet.key]: [] })
2892
+ },
2893
+ facet.key
2894
+ )),
2895
+ overflowFacets.length > 0 && /* @__PURE__ */ jsx(
2896
+ MoreFilters,
2897
+ {
2898
+ facets: overflowFacets,
2899
+ values,
2900
+ onToggle: toggle
2901
+ }
2902
+ ),
2903
+ activeCount > 0 && /* @__PURE__ */ jsxs(
2904
+ "button",
2905
+ {
2906
+ type: "button",
2907
+ onClick: clearAll,
2908
+ "aria-label": "Clear all filters",
2909
+ className: "inline-flex h-7 items-center gap-1 px-2 text-xs text-muted-foreground hover:text-foreground",
2910
+ children: [
2911
+ /* @__PURE__ */ jsx(X, { className: "size-3.5" }),
2912
+ activeCount
2913
+ ]
2914
+ }
2915
+ )
2916
+ ] }),
2917
+ filterVariant === "funnel" && /* @__PURE__ */ jsxs(Fragment, { children: [
2918
+ showSearch && searchBox,
2919
+ /* @__PURE__ */ jsx(
2920
+ FunnelFilter,
2921
+ {
2922
+ facets,
2923
+ values,
2924
+ onToggle: toggle,
2925
+ onClearAll: clearAll
2926
+ }
2927
+ )
2928
+ ] }),
2929
+ /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
2930
+ typeof resultCount === "number" && /* @__PURE__ */ jsxs("span", { className: "whitespace-nowrap text-sm text-muted-foreground", children: [
2931
+ resultCount,
2932
+ " ",
2933
+ resultNoun,
2934
+ resultCount === 1 ? "" : "s"
2935
+ ] }),
2936
+ right
2937
+ ] })
2938
+ ] }) });
2939
+ }
2940
+ function FacetDropdown({
2941
+ facet,
2942
+ selected,
2943
+ onToggle,
2944
+ onClear
2945
+ }) {
2946
+ const count = selected.length;
2947
+ const firstLabel = facet.options.find((o) => o.value === selected[0])?.label ?? selected[0];
2948
+ const summary = count === 0 ? facet.label : `${facet.label}: ${firstLabel}${count > 1 ? ` (+${count - 1})` : ""}`;
2949
+ return /* @__PURE__ */ jsxs(Popover, { children: [
2950
+ /* @__PURE__ */ jsx(
2951
+ PopoverTrigger,
2952
+ {
2953
+ render: /* @__PURE__ */ jsxs(
2954
+ "button",
2955
+ {
2956
+ type: "button",
2957
+ className: cn(
2958
+ "inline-flex h-7 max-w-[14rem] items-center gap-1 rounded-full border bg-background px-2.5 text-xs transition-colors",
2959
+ count > 0 ? "border-primary/40 bg-primary/5 text-foreground" : "text-muted-foreground hover:text-foreground"
2960
+ ),
2961
+ children: [
2962
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: summary }),
2963
+ /* @__PURE__ */ jsx(ChevronDown, { className: "size-3 shrink-0 opacity-60" })
2964
+ ]
2965
+ }
2966
+ )
2967
+ }
2968
+ ),
2969
+ /* @__PURE__ */ jsx(
2970
+ PopoverContent,
2971
+ {
2972
+ className: "w-60 p-0",
2973
+ align: "start",
2974
+ "aria-label": `${facet.label} options`,
2975
+ children: /* @__PURE__ */ jsxs(Command, { children: [
2976
+ facet.options.length > 6 && /* @__PURE__ */ jsx(CommandInput, { placeholder: `Search ${facet.label.toLowerCase()}\u2026` }),
2977
+ /* @__PURE__ */ jsxs(CommandList, { children: [
2978
+ /* @__PURE__ */ jsx(CommandEmpty, { children: "No options." }),
2979
+ /* @__PURE__ */ jsx(CommandGroup, { children: facet.options.map((opt) => {
2980
+ const checked = selected.includes(opt.value);
2981
+ return /* @__PURE__ */ jsxs(
2982
+ CommandItem,
2983
+ {
2984
+ value: opt.label,
2985
+ onSelect: () => onToggle(opt.value),
2986
+ className: "gap-2.5",
2987
+ children: [
2988
+ /* @__PURE__ */ jsx(CheckIndicator, { checked }),
2989
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: opt.label }),
2990
+ checked && /* @__PURE__ */ jsx("span", { className: "sr-only", children: "selected" })
2991
+ ]
2992
+ },
2993
+ opt.value
2994
+ );
2995
+ }) })
2996
+ ] }),
2997
+ count > 0 && /* @__PURE__ */ jsx("div", { className: "border-t p-1", children: /* @__PURE__ */ jsx(
2998
+ Button,
2999
+ {
3000
+ variant: "ghost",
3001
+ onClick: onClear,
3002
+ className: "w-full justify-center text-primary",
3003
+ children: "Clear"
3004
+ }
3005
+ ) })
3006
+ ] })
3007
+ }
3008
+ )
3009
+ ] });
3010
+ }
3011
+ function FunnelFilter({
3012
+ facets,
3013
+ values,
3014
+ onToggle,
3015
+ onClearAll
3016
+ }) {
3017
+ const [open, setOpen] = useState(false);
3018
+ const [drill, setDrill] = useState(null);
3019
+ const activeCount = Object.values(values).reduce((n, a) => n + a.length, 0);
3020
+ const facet = facets.find((f) => f.key === drill);
3021
+ return /* @__PURE__ */ jsxs(
3022
+ Popover,
3023
+ {
3024
+ open,
3025
+ onOpenChange: (o) => {
3026
+ setOpen(o);
3027
+ if (!o) setDrill(null);
3028
+ },
3029
+ children: [
3030
+ /* @__PURE__ */ jsx(
3031
+ PopoverTrigger,
3032
+ {
3033
+ render: /* @__PURE__ */ jsxs(
3034
+ "button",
3035
+ {
3036
+ type: "button",
3037
+ className: cn(
3038
+ "inline-flex h-9 items-center gap-1.5 rounded-md border bg-background px-3 text-sm transition-colors",
3039
+ activeCount > 0 ? "text-foreground" : "text-muted-foreground hover:text-foreground"
3040
+ ),
3041
+ children: [
3042
+ /* @__PURE__ */ jsx(ListFilter, { className: "size-4" }),
3043
+ "Filter",
3044
+ activeCount > 0 && /* @__PURE__ */ jsx(Badge, { className: "ml-0.5 h-5 bg-primary px-1.5 text-primary-foreground", children: activeCount })
3045
+ ]
3046
+ }
3047
+ )
3048
+ }
3049
+ ),
3050
+ /* @__PURE__ */ jsx(PopoverContent, { className: "w-64 p-1", align: "end", "aria-label": "Filters", children: !facet ? /* @__PURE__ */ jsxs(Fragment, { children: [
3051
+ /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Add filter" }),
3052
+ facets.map((f) => {
3053
+ const count = values[f.key]?.length ?? 0;
3054
+ return /* @__PURE__ */ jsxs(
3055
+ "button",
3056
+ {
3057
+ type: "button",
3058
+ onClick: () => setDrill(f.key),
3059
+ className: "flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm hover:bg-muted/60",
3060
+ children: [
3061
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: f.label }),
3062
+ count > 0 && /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-primary", children: count }),
3063
+ /* @__PURE__ */ jsx(ChevronRight, { className: "size-3.5 opacity-50" })
3064
+ ]
3065
+ },
3066
+ f.key
3067
+ );
3068
+ }),
3069
+ activeCount > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
3070
+ /* @__PURE__ */ jsx("div", { className: "my-1 border-t" }),
3071
+ /* @__PURE__ */ jsx(
3072
+ "button",
3073
+ {
3074
+ type: "button",
3075
+ onClick: onClearAll,
3076
+ className: "w-full rounded-md px-2 py-1.5 text-left text-sm text-muted-foreground hover:bg-muted/60",
3077
+ children: "Clear all filters"
3078
+ }
3079
+ )
3080
+ ] })
3081
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
3082
+ /* @__PURE__ */ jsxs(
3083
+ "button",
3084
+ {
3085
+ type: "button",
3086
+ onClick: () => setDrill(null),
3087
+ 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",
3088
+ children: [
3089
+ /* @__PURE__ */ jsx(ChevronLeft, { className: "size-3.5" }),
3090
+ facet.label
3091
+ ]
3092
+ }
3093
+ ),
3094
+ /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto", children: facet.options.map((opt) => {
3095
+ const checked = (values[facet.key] ?? []).includes(opt.value);
3096
+ return /* @__PURE__ */ jsxs(
3097
+ "button",
3098
+ {
3099
+ type: "button",
3100
+ onClick: () => onToggle(facet.key, opt.value),
3101
+ className: "flex w-full items-center gap-2.5 rounded-md px-2 py-1.5 text-left text-sm hover:bg-muted/60",
3102
+ children: [
3103
+ /* @__PURE__ */ jsx(
3104
+ "span",
3105
+ {
3106
+ className: cn(
3107
+ "flex size-4 shrink-0 items-center justify-center rounded border",
3108
+ checked ? "border-primary bg-primary text-primary-foreground" : "border-input"
3109
+ ),
3110
+ children: checked && /* @__PURE__ */ jsx(Check, { className: "size-3" })
3111
+ }
3112
+ ),
3113
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: opt.label })
3114
+ ]
3115
+ },
3116
+ opt.value
3117
+ );
3118
+ }) })
3119
+ ] }) })
1934
3120
  ]
1935
3121
  }
1936
3122
  );
1937
3123
  }
1938
- function FieldError({
1939
- className,
1940
- children,
1941
- errors,
1942
- ...props
3124
+ function MoreFilters({
3125
+ facets,
3126
+ values,
3127
+ onToggle
1943
3128
  }) {
1944
- const content = useMemo(() => {
1945
- if (children) {
1946
- return children;
1947
- }
1948
- if (!errors?.length) {
1949
- return null;
1950
- }
1951
- const uniqueErrors = [
1952
- ...new Map(errors.map((error) => [error?.message, error])).values()
1953
- ];
1954
- if (uniqueErrors?.length == 1) {
1955
- return uniqueErrors[0]?.message;
1956
- }
1957
- return /* @__PURE__ */ jsx("ul", { className: "ml-4 flex list-disc flex-col gap-1", children: uniqueErrors.map(
1958
- (error, index) => error?.message && /* @__PURE__ */ jsx("li", { children: error.message }, index)
1959
- ) });
1960
- }, [children, errors]);
1961
- if (!content) {
1962
- return null;
1963
- }
1964
- return /* @__PURE__ */ jsx(
1965
- "div",
1966
- {
1967
- role: "alert",
1968
- "data-slot": "field-error",
1969
- className: cn("text-sm font-normal text-destructive", className),
1970
- ...props,
1971
- children: content
1972
- }
3129
+ const activeCount = facets.reduce(
3130
+ (n, f) => n + (values[f.key]?.length ?? 0),
3131
+ 0
1973
3132
  );
3133
+ return /* @__PURE__ */ jsxs(Popover, { children: [
3134
+ /* @__PURE__ */ jsx(
3135
+ PopoverTrigger,
3136
+ {
3137
+ render: /* @__PURE__ */ jsxs(
3138
+ "button",
3139
+ {
3140
+ type: "button",
3141
+ className: cn(
3142
+ "inline-flex h-7 items-center gap-1 rounded-full border bg-background px-2.5 text-xs transition-colors",
3143
+ activeCount > 0 ? "border-primary/40 bg-primary/5 text-foreground" : "text-muted-foreground hover:text-foreground"
3144
+ ),
3145
+ children: [
3146
+ /* @__PURE__ */ jsx(ListFilter, { className: "size-3.5" }),
3147
+ "More",
3148
+ activeCount > 0 && /* @__PURE__ */ jsx(Badge, { className: "ml-0.5 h-4 bg-primary px-1.5 text-primary-foreground", children: activeCount })
3149
+ ]
3150
+ }
3151
+ )
3152
+ }
3153
+ ),
3154
+ /* @__PURE__ */ jsx(PopoverContent, { className: "w-64 p-0", align: "start", "aria-label": "Filters", children: /* @__PURE__ */ jsxs(Command, { children: [
3155
+ facets.reduce((n, f) => n + f.options.length, 0) > 8 && /* @__PURE__ */ jsx(CommandInput, { placeholder: "Search filters\u2026" }),
3156
+ /* @__PURE__ */ jsxs(CommandList, { className: "max-h-[60vh]", children: [
3157
+ /* @__PURE__ */ jsx(CommandEmpty, { children: "No filters." }),
3158
+ facets.map((facet) => /* @__PURE__ */ jsx(CommandGroup, { heading: facet.label, children: facet.options.map((opt) => {
3159
+ const checked = (values[facet.key] ?? []).includes(opt.value);
3160
+ return /* @__PURE__ */ jsxs(
3161
+ CommandItem,
3162
+ {
3163
+ value: `${facet.label} ${opt.label}`,
3164
+ onSelect: () => onToggle(facet.key, opt.value),
3165
+ className: "gap-2.5",
3166
+ children: [
3167
+ /* @__PURE__ */ jsx(CheckIndicator, { checked }),
3168
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: opt.label }),
3169
+ checked && /* @__PURE__ */ jsx("span", { className: "sr-only", children: "selected" })
3170
+ ]
3171
+ },
3172
+ opt.value
3173
+ );
3174
+ }) }, facet.key))
3175
+ ] })
3176
+ ] }) })
3177
+ ] });
1974
3178
  }
1975
3179
  function PackagePicker({
1976
3180
  packages,
@@ -2938,75 +4142,6 @@ function PersonDropdown({
2938
4142
  }
2939
4143
  );
2940
4144
  }
2941
- function Popover({ ...props }) {
2942
- return /* @__PURE__ */ jsx(Popover$1.Root, { "data-slot": "popover", ...props });
2943
- }
2944
- function PopoverTrigger({ ...props }) {
2945
- return /* @__PURE__ */ jsx(Popover$1.Trigger, { "data-slot": "popover-trigger", ...props });
2946
- }
2947
- function PopoverContent({
2948
- className,
2949
- align = "center",
2950
- alignOffset = 0,
2951
- side = "bottom",
2952
- sideOffset = 4,
2953
- ...props
2954
- }) {
2955
- return /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(
2956
- Popover$1.Positioner,
2957
- {
2958
- align,
2959
- alignOffset,
2960
- side,
2961
- sideOffset,
2962
- className: "isolate z-50",
2963
- children: /* @__PURE__ */ jsx(
2964
- Popover$1.Popup,
2965
- {
2966
- "data-slot": "popover-content",
2967
- className: cn(
2968
- "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",
2969
- className
2970
- ),
2971
- ...props
2972
- }
2973
- )
2974
- }
2975
- ) });
2976
- }
2977
- function PopoverHeader({ className, ...props }) {
2978
- return /* @__PURE__ */ jsx(
2979
- "div",
2980
- {
2981
- "data-slot": "popover-header",
2982
- className: cn("flex flex-col gap-0.5 text-sm", className),
2983
- ...props
2984
- }
2985
- );
2986
- }
2987
- function PopoverTitle({ className, ...props }) {
2988
- return /* @__PURE__ */ jsx(
2989
- Popover$1.Title,
2990
- {
2991
- "data-slot": "popover-title",
2992
- className: cn("font-medium", className),
2993
- ...props
2994
- }
2995
- );
2996
- }
2997
- function PopoverDescription({
2998
- className,
2999
- ...props
3000
- }) {
3001
- return /* @__PURE__ */ jsx(
3002
- Popover$1.Description,
3003
- {
3004
- "data-slot": "popover-description",
3005
- className: cn("text-muted-foreground", className),
3006
- ...props
3007
- }
3008
- );
3009
- }
3010
4145
  function ScrollArea({
3011
4146
  className,
3012
4147
  children,
@@ -4190,7 +5325,7 @@ function SheetContent({
4190
5325
  "data-slot": "sheet-content",
4191
5326
  "data-side": side,
4192
5327
  className: cn(
4193
- "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",
5328
+ "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",
4194
5329
  className
4195
5330
  ),
4196
5331
  ...props,
@@ -5233,108 +6368,6 @@ function Switch({
5233
6368
  }
5234
6369
  );
5235
6370
  }
5236
- function Table({ className, ...props }) {
5237
- return /* @__PURE__ */ jsx(
5238
- "div",
5239
- {
5240
- "data-slot": "table-container",
5241
- className: "relative w-full overflow-x-auto",
5242
- children: /* @__PURE__ */ jsx(
5243
- "table",
5244
- {
5245
- "data-slot": "table",
5246
- className: cn("w-full caption-bottom text-sm", className),
5247
- ...props
5248
- }
5249
- )
5250
- }
5251
- );
5252
- }
5253
- function TableHeader({ className, ...props }) {
5254
- return /* @__PURE__ */ jsx(
5255
- "thead",
5256
- {
5257
- "data-slot": "table-header",
5258
- className: cn("[&_tr]:border-b", className),
5259
- ...props
5260
- }
5261
- );
5262
- }
5263
- function TableBody({ className, ...props }) {
5264
- return /* @__PURE__ */ jsx(
5265
- "tbody",
5266
- {
5267
- "data-slot": "table-body",
5268
- className: cn("[&_tr:last-child]:border-0", className),
5269
- ...props
5270
- }
5271
- );
5272
- }
5273
- function TableFooter({ className, ...props }) {
5274
- return /* @__PURE__ */ jsx(
5275
- "tfoot",
5276
- {
5277
- "data-slot": "table-footer",
5278
- className: cn(
5279
- "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
5280
- className
5281
- ),
5282
- ...props
5283
- }
5284
- );
5285
- }
5286
- function TableRow({ className, ...props }) {
5287
- return /* @__PURE__ */ jsx(
5288
- "tr",
5289
- {
5290
- "data-slot": "table-row",
5291
- className: cn(
5292
- "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
5293
- className
5294
- ),
5295
- ...props
5296
- }
5297
- );
5298
- }
5299
- function TableHead({ className, ...props }) {
5300
- return /* @__PURE__ */ jsx(
5301
- "th",
5302
- {
5303
- "data-slot": "table-head",
5304
- className: cn(
5305
- "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
5306
- className
5307
- ),
5308
- ...props
5309
- }
5310
- );
5311
- }
5312
- function TableCell({ className, ...props }) {
5313
- return /* @__PURE__ */ jsx(
5314
- "td",
5315
- {
5316
- "data-slot": "table-cell",
5317
- className: cn(
5318
- "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
5319
- className
5320
- ),
5321
- ...props
5322
- }
5323
- );
5324
- }
5325
- function TableCaption({
5326
- className,
5327
- ...props
5328
- }) {
5329
- return /* @__PURE__ */ jsx(
5330
- "caption",
5331
- {
5332
- "data-slot": "table-caption",
5333
- className: cn("mt-4 text-sm text-muted-foreground", className),
5334
- ...props
5335
- }
5336
- );
5337
- }
5338
6371
  function Tabs({
5339
6372
  className,
5340
6373
  orientation = "horizontal",
@@ -5409,4 +6442,4 @@ function TabsContent({ className, ...props }) {
5409
6442
  );
5410
6443
  }
5411
6444
 
5412
- export { Accordion, AccordionItem, AccordionPanel, AccordionTrigger, AddonCard, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, CamperForm, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuGroupLabel, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSubmenu, DropdownMenuSubmenuTrigger, DropdownMenuTrigger, ExpandDesc, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, InlineAddonPicker, InlineSessionPicker, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Label, NextStepPeek, PackagePicker, PersonList, PersonSelect, PersonTabs, PhoneInput, PhotoUpload, Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, STATUS_LABEL, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SessionCard, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, StatusPill, StepBadge, StepCard, StepNotices, Switch, TSHIRT_SIZES, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, __internal, badgeVariants, buttonVariants, calcAge, cn, computeSessionDeposit, computeSessionPrice, effectivePrice, eligibilityReason, fakeSpotsLeft, formatDOB, makeCamperFormSchema, mandatoryTotal, parseDOB, statusPillVariants, tabsListVariants, useIsMobile, useLocale, useSidebar };
6445
+ export { Accordion, AccordionItem, AccordionPanel, AccordionTrigger, AddonCard, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, CamperForm, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColumnCustomizer, ColumnPicker, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuGroupLabel, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSubmenu, DropdownMenuSubmenuTrigger, DropdownMenuTrigger, ExpandDesc, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, FilterBar, InlineAddonPicker, InlineSessionPicker, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Label, NextStepPeek, PackagePicker, PersonList, PersonSelect, PersonTabs, PhoneInput, PhotoUpload, Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, STATUS_LABEL, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SessionCard, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, StatusPill, StepBadge, StepCard, StepNotices, Switch, TSHIRT_SIZES, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, __internal, badgeVariants, buttonVariants, calcAge, cn, computeSessionDeposit, computeSessionPrice, effectivePrice, eligibilityReason, fakeSpotsLeft, formatDOB, makeCamperFormSchema, mandatoryTotal, parseDOB, statusPillVariants, tabsListVariants, useIsMobile, useLocale, useSidebar };