@upbound/monarch-blocks 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -67,6 +67,9 @@ var twMerge = extendTailwindMerge({
67
67
  function cn(...inputs) {
68
68
  return twMerge(clsx(inputs));
69
69
  }
70
+ function sortBy(items, getKey) {
71
+ return [...items].sort((a, b) => getKey(a).localeCompare(getKey(b)));
72
+ }
70
73
 
71
74
  // src/hooks/use-mounted.ts
72
75
  import { useSyncExternalStore } from "react";
@@ -1219,6 +1222,7 @@ function CelFilterBar({
1219
1222
  (_a = onCompileResultChangeRef.current) == null ? void 0 : _a.call(onCompileResultChangeRef, __spreadProps(__spreadValues({}, displayResult), { isEmitReady }));
1220
1223
  }, [displayResult, isEmitReady]);
1221
1224
  const conditions = tree.root.children.filter(isCelFilterCondition);
1225
+ const containerRef = React.useRef(null);
1222
1226
  function handleAddFilter(columnId) {
1223
1227
  const condition = createDefaultCondition({ schema, columnId });
1224
1228
  onChange(appendCondition(tree, condition));
@@ -1233,8 +1237,8 @@ function CelFilterBar({
1233
1237
  onChange({ root: __spreadProps(__spreadValues({}, tree.root), { children: [] }) });
1234
1238
  editor.clearSuppress();
1235
1239
  }
1236
- return /* @__PURE__ */ jsxs("div", { "data-slot": "cel-filter-bar", className: cn("flex flex-wrap items-center gap-2", className), children: [
1237
- /* @__PURE__ */ jsx(CelAddFilterButton, { schema, conditions, onSelect: handleAddFilter }),
1240
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "cel-filter-bar", className: cn("flex flex-wrap items-center gap-2", className), ref: containerRef, children: [
1241
+ /* @__PURE__ */ jsx(CelAddFilterButton, { schema, conditions, onSelect: handleAddFilter, container: containerRef }),
1238
1242
  conditions.map((condition) => {
1239
1243
  const columnDef = resolveColumnDefinition(condition, schema);
1240
1244
  if (!columnDef) return null;
@@ -1249,7 +1253,8 @@ function CelFilterBar({
1249
1253
  controller: editor.getController(condition.id),
1250
1254
  issues: displayResult.issues.filter((issue) => issue.nodeId === condition.id),
1251
1255
  onRemove: () => handleRemove(condition.id),
1252
- onRestrictedOptionSelect
1256
+ onRestrictedOptionSelect,
1257
+ container: containerRef
1253
1258
  },
1254
1259
  condition.id
1255
1260
  );
@@ -1260,7 +1265,8 @@ function CelFilterBar({
1260
1265
  function CelAddFilterButton({
1261
1266
  schema,
1262
1267
  conditions,
1263
- onSelect
1268
+ onSelect,
1269
+ container
1264
1270
  }) {
1265
1271
  var _a, _b;
1266
1272
  const usedSingleInstanceColumnIds = new Set(
@@ -1276,7 +1282,10 @@ function CelAddFilterButton({
1276
1282
  list.push(column);
1277
1283
  groupMap.set(key, list);
1278
1284
  }
1279
- const groups = Array.from(groupMap.entries()).map(([value, items]) => ({ value, items }));
1285
+ const groups = sortBy(
1286
+ Array.from(groupMap.entries()).map(([value, items]) => ({ value, items: sortBy(items, (item) => item.title) })),
1287
+ (group) => group.value
1288
+ );
1280
1289
  return /* @__PURE__ */ jsxs(
1281
1290
  Combobox,
1282
1291
  {
@@ -1291,7 +1300,7 @@ function CelAddFilterButton({
1291
1300
  /* @__PURE__ */ jsx(Icon, { name: "plus", "data-icon": "inline-start" }),
1292
1301
  "Add filter"
1293
1302
  ] }),
1294
- /* @__PURE__ */ jsxs(ComboboxContent, { align: "start", className: "w-64", children: [
1303
+ /* @__PURE__ */ jsxs(ComboboxContent, { container, align: "start", className: "w-64", children: [
1295
1304
  /* @__PURE__ */ jsx(ComboboxInput, { showTrigger: false, placeholder: "Search filters\u2026" }),
1296
1305
  /* @__PURE__ */ jsx(ComboboxEmpty, { children: "No filters found." }),
1297
1306
  /* @__PURE__ */ jsx(ComboboxList, { children: (group) => /* @__PURE__ */ jsxs(ComboboxGroup, { items: group.items, children: [
@@ -1355,7 +1364,8 @@ function CelFilterPill({
1355
1364
  controller,
1356
1365
  issues,
1357
1366
  onRemove,
1358
- onRestrictedOptionSelect
1367
+ onRestrictedOptionSelect,
1368
+ container
1359
1369
  }) {
1360
1370
  var _a;
1361
1371
  const shape = (_a = resolveFilterShape(condition, schema)) != null ? _a : columnDef.filterType;
@@ -1372,7 +1382,8 @@ function CelFilterPill({
1372
1382
  controller,
1373
1383
  issues,
1374
1384
  onRemove,
1375
- onRestrictedOptionSelect
1385
+ onRestrictedOptionSelect,
1386
+ container
1376
1387
  }
1377
1388
  );
1378
1389
  }
@@ -1387,7 +1398,8 @@ function CelFilterPill({
1387
1398
  controller,
1388
1399
  issues,
1389
1400
  onRemove,
1390
- onRestrictedOptionSelect
1401
+ onRestrictedOptionSelect,
1402
+ container
1391
1403
  }
1392
1404
  );
1393
1405
  }
@@ -1497,10 +1509,11 @@ function CelCheckboxComboboxPill({
1497
1509
  controller,
1498
1510
  issues,
1499
1511
  onRemove,
1500
- onRestrictedOptionSelect
1512
+ onRestrictedOptionSelect,
1513
+ container
1501
1514
  }) {
1502
1515
  var _a;
1503
- const options = (_a = columnDef.options) != null ? _a : [];
1516
+ const options = sortBy((_a = columnDef.options) != null ? _a : [], (o) => o.label);
1504
1517
  const value = isCheckboxCelValue(condition.value) ? condition.value : [];
1505
1518
  const selected = options.filter((option) => value.includes(option.value));
1506
1519
  const allowedOperators = getAllowedOperators(columnDef);
@@ -1556,7 +1569,7 @@ function CelCheckboxComboboxPill({
1556
1569
  ),
1557
1570
  /* @__PURE__ */ jsx(Button, { variant: "outline", size: "icon", "aria-label": `Remove ${columnDef.title} filter`, onClick: onRemove, children: /* @__PURE__ */ jsx(Icon, { name: "xmark" }) })
1558
1571
  ] }),
1559
- /* @__PURE__ */ jsxs(ComboboxContent, { className: "min-w-64", collisionAvoidance: { side: "none", align: "shift" }, children: [
1572
+ /* @__PURE__ */ jsxs(ComboboxContent, { container, className: "min-w-64", collisionAvoidance: { side: "none", align: "shift" }, children: [
1560
1573
  /* @__PURE__ */ jsx(ComboboxInput, { showTrigger: false, placeholder: `Search ${columnDef.title.toLowerCase()}\u2026` }),
1561
1574
  selected.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
1562
1575
  /* @__PURE__ */ jsxs(ComboboxSelectedChips, { children: [
@@ -1585,10 +1598,11 @@ function CelRadioComboboxPill({
1585
1598
  controller,
1586
1599
  issues,
1587
1600
  onRemove,
1588
- onRestrictedOptionSelect
1601
+ onRestrictedOptionSelect,
1602
+ container
1589
1603
  }) {
1590
1604
  var _a, _b;
1591
- const options = (_a = columnDef.options) != null ? _a : [];
1605
+ const options = sortBy((_a = columnDef.options) != null ? _a : [], (o) => o.label);
1592
1606
  const value = typeof condition.value === "string" ? condition.value : "";
1593
1607
  const selected = (_b = options.find((option) => option.value === value)) != null ? _b : null;
1594
1608
  const allowedOperators = getAllowedOperators(columnDef);
@@ -1640,7 +1654,7 @@ function CelRadioComboboxPill({
1640
1654
  ),
1641
1655
  /* @__PURE__ */ jsx(Button, { variant: "outline", size: "icon", "aria-label": `Remove ${columnDef.title} filter`, onClick: onRemove, children: /* @__PURE__ */ jsx(Icon, { name: "xmark" }) })
1642
1656
  ] }),
1643
- /* @__PURE__ */ jsxs(ComboboxContent, { className: "min-w-64", collisionAvoidance: { side: "none", align: "shift" }, children: [
1657
+ /* @__PURE__ */ jsxs(ComboboxContent, { container, className: "min-w-64", collisionAvoidance: { side: "none", align: "shift" }, children: [
1644
1658
  /* @__PURE__ */ jsx(ComboboxInput, { showTrigger: false, placeholder: `Search ${columnDef.title.toLowerCase()}\u2026` }),
1645
1659
  /* @__PURE__ */ jsxs(ComboboxEmpty, { children: [
1646
1660
  "No ",
@@ -2753,7 +2767,7 @@ function ChatThread({
2753
2767
  ] }, msg.id)),
2754
2768
  isThinking && /* @__PURE__ */ jsx5(ChatThinkingIndicator, {})
2755
2769
  ] }) }),
2756
- /* @__PURE__ */ jsx5(MessageScrollerButton, { direction: "end", children: /* @__PURE__ */ jsx5(Icon2, { name: "arrow-down" }) })
2770
+ /* @__PURE__ */ jsx5(MessageScrollerButton, { direction: "end", variant: "secondary", size: "icon-sm", children: /* @__PURE__ */ jsx5(Icon2, { name: "arrow-down" }) })
2757
2771
  ] }) }),
2758
2772
  /* @__PURE__ */ jsx5(
2759
2773
  ChatInput,
@@ -3135,7 +3149,15 @@ function CellContextualFilter({
3135
3149
  );
3136
3150
  }
3137
3151
  return /* @__PURE__ */ jsxs5(ContextMenuContent, { children: [
3138
- /* @__PURE__ */ jsx7(ContextMenuItem, { disabled, onClick: (event) => event.stopPropagation(), onSelect: handleSelect, children: "Filter by this value" }),
3152
+ /* @__PURE__ */ jsx7(
3153
+ ContextMenuItem,
3154
+ {
3155
+ disabled,
3156
+ onClick: (event) => event.stopPropagation(),
3157
+ onSelect: handleSelect,
3158
+ children: "Filter by this value"
3159
+ }
3160
+ ),
3139
3161
  contextualMenuActions.length > 0 && /* @__PURE__ */ jsxs5(Fragment4, { children: [
3140
3162
  /* @__PURE__ */ jsx7(ContextMenuSeparator, {}),
3141
3163
  contextualMenuActions.map(renderAction)
@@ -3217,6 +3239,14 @@ function isFilterOnlyColumn(column) {
3217
3239
  var _a;
3218
3240
  return ((_a = column.columnDef.meta) == null ? void 0 : _a.filterOnly) === true;
3219
3241
  }
3242
+ function hasFilterableColumns(columns) {
3243
+ return columns.some(
3244
+ (column) => {
3245
+ var _a;
3246
+ return !isFilterOnlyColumn(column) && column.getCanFilter() && !!((_a = column.columnDef.meta) == null ? void 0 : _a.filter);
3247
+ }
3248
+ );
3249
+ }
3220
3250
  function getTableState({
3221
3251
  error,
3222
3252
  loading,
@@ -3450,6 +3480,7 @@ function ColumnOptions({
3450
3480
  import { Button as Button4 } from "@upbound/monarch-core";
3451
3481
  import { DropdownMenu as DropdownMenu3, DropdownMenuContent as DropdownMenuContent3, DropdownMenuItem as DropdownMenuItem3, DropdownMenuTrigger as DropdownMenuTrigger3 } from "@upbound/monarch-core";
3452
3482
  import { Icon as Icon5 } from "@upbound/monarch-core";
3483
+ import { Link } from "@upbound/monarch-core";
3453
3484
  import { Tooltip as Tooltip4, TooltipContent as TooltipContent3, TooltipTrigger as TooltipTrigger3 } from "@upbound/monarch-core";
3454
3485
  import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
3455
3486
  function RowActions({
@@ -3458,8 +3489,25 @@ function RowActions({
3458
3489
  contentClassName
3459
3490
  }) {
3460
3491
  return /* @__PURE__ */ jsxs7(DropdownMenu3, { children: [
3461
- /* @__PURE__ */ jsx9(DropdownMenuTrigger3, { asChild: true, children: /* @__PURE__ */ jsx9(Button4, { variant: "ghost", size: "icon-xs", "aria-label": "Row actions", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx9(Icon5, { name: "ellipsis-vertical", size: "sm" }) }) }),
3462
- /* @__PURE__ */ jsx9(DropdownMenuContent3, { align, className: contentClassName, onClick: (event) => event.stopPropagation(), children })
3492
+ /* @__PURE__ */ jsx9(DropdownMenuTrigger3, { asChild: true, children: /* @__PURE__ */ jsx9(
3493
+ Button4,
3494
+ {
3495
+ variant: "ghost",
3496
+ size: "icon-xs",
3497
+ "aria-label": "Row actions",
3498
+ onClick: (e) => e.stopPropagation(),
3499
+ children: /* @__PURE__ */ jsx9(Icon5, { name: "ellipsis-vertical", size: "sm" })
3500
+ }
3501
+ ) }),
3502
+ /* @__PURE__ */ jsx9(
3503
+ DropdownMenuContent3,
3504
+ {
3505
+ align,
3506
+ className: contentClassName,
3507
+ onClick: (event) => event.stopPropagation(),
3508
+ children
3509
+ }
3510
+ )
3463
3511
  ] });
3464
3512
  }
3465
3513
  function RowActionItem({
@@ -3528,7 +3576,7 @@ function getExpandColumnDefinition(options) {
3528
3576
  function DataTableValueCell({ content, title, className, href, onClick }) {
3529
3577
  const baseClassName = cn("text-body truncate", className);
3530
3578
  if (href) {
3531
- return /* @__PURE__ */ jsx9("p", { className: baseClassName, children: /* @__PURE__ */ jsx9("a", { href, title, className: "underline hover:no-underline", onClick, children: content }) });
3579
+ return /* @__PURE__ */ jsx9("p", { className: baseClassName, children: /* @__PURE__ */ jsx9(Link, { href, title, onClick, children: content }) });
3532
3580
  }
3533
3581
  if (title) {
3534
3582
  return /* @__PURE__ */ jsxs7(Tooltip4, { children: [
@@ -3555,7 +3603,7 @@ function TimestampCell({ timestamp }) {
3555
3603
  }
3556
3604
 
3557
3605
  // src/data-table/data-table.tsx
3558
- import * as React10 from "react";
3606
+ import * as React11 from "react";
3559
3607
  import {
3560
3608
  getCoreRowModel,
3561
3609
  getExpandedRowModel,
@@ -3568,7 +3616,7 @@ import {
3568
3616
  noop,
3569
3617
  useReactTable
3570
3618
  } from "@tanstack/react-table";
3571
- import { Icon as Icon10 } from "@upbound/monarch-core";
3619
+ import { Icon as Icon11 } from "@upbound/monarch-core";
3572
3620
  import { InputGroup as InputGroup3, InputGroupAddon as InputGroupAddon3, InputGroupInput as InputGroupInput2 } from "@upbound/monarch-core";
3573
3621
 
3574
3622
  // src/lib/data-table/contextual-filters.ts
@@ -4166,6 +4214,18 @@ function useGridLayout({
4166
4214
  };
4167
4215
  }
4168
4216
 
4217
+ // src/hooks/use-filter-visibility.ts
4218
+ import * as React7 from "react";
4219
+ function useFilterVisibility(filterVisibility) {
4220
+ var _a, _b, _c;
4221
+ const config = typeof filterVisibility === "object" ? filterVisibility : void 0;
4222
+ const [innerVisible, setInnerVisible] = React7.useState((_a = config == null ? void 0 : config.defaultVisible) != null ? _a : false);
4223
+ const showFilterToggle = filterVisibility !== false;
4224
+ const filterRowVisible = (_b = config == null ? void 0 : config.visible) != null ? _b : innerVisible;
4225
+ const setFilterRowVisible = (_c = config == null ? void 0 : config.onVisibleChange) != null ? _c : setInnerVisible;
4226
+ return { showFilterToggle, filterRowVisible, setFilterRowVisible };
4227
+ }
4228
+
4169
4229
  // src/data-table/empty-view.tsx
4170
4230
  import { Alert, AlertDescription } from "@upbound/monarch-core";
4171
4231
  import { Button as Button5 } from "@upbound/monarch-core";
@@ -4218,9 +4278,34 @@ function DataTableEmptyView({
4218
4278
  ] }) });
4219
4279
  }
4220
4280
 
4281
+ // src/data-table/filter-toggle.tsx
4282
+ import { Icon as Icon7, Toggle } from "@upbound/monarch-core";
4283
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
4284
+ function FilterToggle({ pressed, onPressedChange, count }) {
4285
+ return /* @__PURE__ */ jsxs9(
4286
+ Toggle,
4287
+ {
4288
+ variant: "outline",
4289
+ pressed,
4290
+ onPressedChange,
4291
+ "aria-label": "Toggle filters",
4292
+ className: "shrink-0 gap-1.5",
4293
+ children: [
4294
+ /* @__PURE__ */ jsx11(Icon7, { name: "filter", "data-icon": "inline-start" }),
4295
+ "Filter",
4296
+ !!count && /* @__PURE__ */ jsxs9("span", { className: "tabular-nums", children: [
4297
+ "(",
4298
+ count,
4299
+ ")"
4300
+ ] })
4301
+ ]
4302
+ }
4303
+ );
4304
+ }
4305
+
4221
4306
  // src/data-table/pagination.tsx
4222
4307
  import { Button as Button6 } from "@upbound/monarch-core";
4223
- import { Icon as Icon7 } from "@upbound/monarch-core";
4308
+ import { Icon as Icon8 } from "@upbound/monarch-core";
4224
4309
  import { Label as Label2 } from "@upbound/monarch-core";
4225
4310
  import {
4226
4311
  Pagination,
@@ -4231,7 +4316,7 @@ import {
4231
4316
  } from "@upbound/monarch-core";
4232
4317
  import { Select as Select2, SelectContent as SelectContent2, SelectGroup as SelectGroup2, SelectItem as SelectItem2, SelectTrigger as SelectTrigger2, SelectValue as SelectValue2 } from "@upbound/monarch-core";
4233
4318
  import { Tooltip as Tooltip5, TooltipContent as TooltipContent4, TooltipTrigger as TooltipTrigger4 } from "@upbound/monarch-core";
4234
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
4319
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
4235
4320
  var DEFAULT_PAGINATION_CONFIG = {
4236
4321
  summary: true,
4237
4322
  arrows: true,
@@ -4270,36 +4355,36 @@ function DataTablePagination({
4270
4355
  const currentPage = pageIndex + 1;
4271
4356
  const mounted = useMounted();
4272
4357
  const locale = mounted ? void 0 : "en-US";
4273
- return /* @__PURE__ */ jsxs9("div", { "data-testid": "table-footer", className: "flex items-center justify-between px-2 pt-4", children: [
4274
- resolved.summary ? /* @__PURE__ */ jsxs9("div", { className: "text-body text-muted-foreground", "data-testid": "table-pagination-summary", children: [
4358
+ return /* @__PURE__ */ jsxs10("div", { "data-testid": "table-footer", className: "flex items-center justify-between px-2 pt-4", children: [
4359
+ resolved.summary ? /* @__PURE__ */ jsxs10("div", { className: "text-body text-muted-foreground", "data-testid": "table-pagination-summary", children: [
4275
4360
  "Showing ",
4276
- /* @__PURE__ */ jsx11("span", { className: "text-foreground font-medium", children: itemStart.toLocaleString(locale) }),
4361
+ /* @__PURE__ */ jsx12("span", { className: "text-foreground font-medium", children: itemStart.toLocaleString(locale) }),
4277
4362
  " to",
4278
4363
  " ",
4279
- /* @__PURE__ */ jsx11("span", { className: "text-foreground font-medium", children: itemEnd.toLocaleString(locale) }),
4364
+ /* @__PURE__ */ jsx12("span", { className: "text-foreground font-medium", children: itemEnd.toLocaleString(locale) }),
4280
4365
  " of",
4281
4366
  " ",
4282
- /* @__PURE__ */ jsxs9("span", { className: "text-foreground font-medium", children: [
4367
+ /* @__PURE__ */ jsxs10("span", { className: "text-foreground font-medium", children: [
4283
4368
  rowCount.toLocaleString(locale),
4284
4369
  !isRowCountExact && "+"
4285
4370
  ] }),
4286
4371
  " ",
4287
4372
  "results",
4288
- !isRowCountExact && /* @__PURE__ */ jsxs9(Tooltip5, { children: [
4289
- /* @__PURE__ */ jsx11(TooltipTrigger4, { className: "ml-1 align-middle", children: /* @__PURE__ */ jsx11(Icon7, { name: "circle-info", size: "sm" }) }),
4290
- /* @__PURE__ */ jsx11(TooltipContent4, { children: "Add filters or refine your search to reduce the result set." })
4373
+ !isRowCountExact && /* @__PURE__ */ jsxs10(Tooltip5, { children: [
4374
+ /* @__PURE__ */ jsx12(TooltipTrigger4, { className: "ml-1 align-middle", children: /* @__PURE__ */ jsx12(Icon8, { name: "circle-info", size: "sm" }) }),
4375
+ /* @__PURE__ */ jsx12(TooltipContent4, { children: "Add filters or refine your search to reduce the result set." })
4291
4376
  ] })
4292
- ] }) : /* @__PURE__ */ jsx11("div", {}),
4293
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-4", children: [
4294
- resolved.pageSizeSelector && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
4295
- /* @__PURE__ */ jsx11(Label2, { htmlFor: PAGE_SIZE_SELECT_ID, className: "font-semibold", children: "Rows per page" }),
4296
- /* @__PURE__ */ jsxs9(Select2, { value: String(effectivePageSize), onValueChange: (value) => onPageSizeChange(Number(value)), children: [
4297
- /* @__PURE__ */ jsx11(SelectTrigger2, { id: PAGE_SIZE_SELECT_ID, size: "sm", className: "w-18", "data-testid": "table-page-size-select", children: /* @__PURE__ */ jsx11(SelectValue2, {}) }),
4298
- /* @__PURE__ */ jsx11(SelectContent2, { align: "end", children: /* @__PURE__ */ jsx11(SelectGroup2, { children: normalizedPageSizeOptions.map((option) => /* @__PURE__ */ jsx11(SelectItem2, { value: String(option), children: option }, option)) }) })
4377
+ ] }) : /* @__PURE__ */ jsx12("div", {}),
4378
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-4", children: [
4379
+ resolved.pageSizeSelector && /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
4380
+ /* @__PURE__ */ jsx12(Label2, { htmlFor: PAGE_SIZE_SELECT_ID, className: "font-semibold", children: "Rows per page" }),
4381
+ /* @__PURE__ */ jsxs10(Select2, { value: String(effectivePageSize), onValueChange: (value) => onPageSizeChange(Number(value)), children: [
4382
+ /* @__PURE__ */ jsx12(SelectTrigger2, { id: PAGE_SIZE_SELECT_ID, size: "sm", className: "w-18", "data-testid": "table-page-size-select", children: /* @__PURE__ */ jsx12(SelectValue2, {}) }),
4383
+ /* @__PURE__ */ jsx12(SelectContent2, { align: "end", children: /* @__PURE__ */ jsx12(SelectGroup2, { children: normalizedPageSizeOptions.map((option) => /* @__PURE__ */ jsx12(SelectItem2, { value: String(option), children: option }, option)) }) })
4299
4384
  ] })
4300
4385
  ] }),
4301
- pageCount > 1 && (resolved.arrows || resolved.numbers) && /* @__PURE__ */ jsx11(Pagination, { className: "mx-0 w-auto justify-end", children: /* @__PURE__ */ jsxs9(PaginationContent, { children: [
4302
- resolved.arrows && /* @__PURE__ */ jsx11(PaginationItem, { children: /* @__PURE__ */ jsx11(
4386
+ pageCount > 1 && (resolved.arrows || resolved.numbers) && /* @__PURE__ */ jsx12(Pagination, { className: "mx-0 w-auto justify-end", children: /* @__PURE__ */ jsxs10(PaginationContent, { children: [
4387
+ resolved.arrows && /* @__PURE__ */ jsx12(PaginationItem, { children: /* @__PURE__ */ jsx12(
4303
4388
  Button6,
4304
4389
  {
4305
4390
  variant: "outline",
@@ -4307,10 +4392,10 @@ function DataTablePagination({
4307
4392
  "aria-label": "Go to first page",
4308
4393
  disabled: currentPage <= 1,
4309
4394
  onClick: () => onPageChange(1),
4310
- children: /* @__PURE__ */ jsx11(Icon7, { name: "chevrons-left", className: "cn-rtl-flip" })
4395
+ children: /* @__PURE__ */ jsx12(Icon8, { name: "chevrons-left", className: "cn-rtl-flip" })
4311
4396
  }
4312
4397
  ) }),
4313
- resolved.arrows && /* @__PURE__ */ jsx11(PaginationItem, { children: /* @__PURE__ */ jsx11(
4398
+ resolved.arrows && /* @__PURE__ */ jsx12(PaginationItem, { children: /* @__PURE__ */ jsx12(
4314
4399
  Button6,
4315
4400
  {
4316
4401
  variant: "outline",
@@ -4318,14 +4403,15 @@ function DataTablePagination({
4318
4403
  "aria-label": "Go to previous page",
4319
4404
  disabled: currentPage <= 1,
4320
4405
  onClick: () => onPageChange(currentPage - 1),
4321
- children: /* @__PURE__ */ jsx11(Icon7, { name: "chevron-left", className: "cn-rtl-flip" })
4406
+ children: /* @__PURE__ */ jsx12(Icon8, { name: "chevron-left", className: "cn-rtl-flip" })
4322
4407
  }
4323
4408
  ) }),
4324
4409
  resolved.numbers && visiblePages.map(
4325
- (page, index) => page === void 0 ? /* @__PURE__ */ jsx11(PaginationItem, { children: /* @__PURE__ */ jsx11(PaginationEllipsis, {}) }, `ellipsis-${index}`) : /* @__PURE__ */ jsx11(PaginationItem, { children: /* @__PURE__ */ jsx11(
4410
+ (page, index) => page === void 0 ? /* @__PURE__ */ jsx12(PaginationItem, { children: /* @__PURE__ */ jsx12(PaginationEllipsis, {}) }, `ellipsis-${index}`) : /* @__PURE__ */ jsx12(PaginationItem, { children: /* @__PURE__ */ jsx12(
4326
4411
  PaginationLink,
4327
4412
  {
4328
4413
  href: "#",
4414
+ size: "icon",
4329
4415
  isActive: page === currentPage,
4330
4416
  onClick: (e) => {
4331
4417
  e.preventDefault();
@@ -4335,7 +4421,7 @@ function DataTablePagination({
4335
4421
  }
4336
4422
  ) }, page)
4337
4423
  ),
4338
- resolved.arrows && /* @__PURE__ */ jsx11(PaginationItem, { children: /* @__PURE__ */ jsx11(
4424
+ resolved.arrows && /* @__PURE__ */ jsx12(PaginationItem, { children: /* @__PURE__ */ jsx12(
4339
4425
  Button6,
4340
4426
  {
4341
4427
  variant: "outline",
@@ -4343,10 +4429,10 @@ function DataTablePagination({
4343
4429
  "aria-label": "Go to next page",
4344
4430
  disabled: currentPage >= pageCount,
4345
4431
  onClick: () => onPageChange(currentPage + 1),
4346
- children: /* @__PURE__ */ jsx11(Icon7, { name: "chevron-right", className: "cn-rtl-flip" })
4432
+ children: /* @__PURE__ */ jsx12(Icon8, { name: "chevron-right", className: "cn-rtl-flip" })
4347
4433
  }
4348
4434
  ) }),
4349
- resolved.arrows && /* @__PURE__ */ jsx11(PaginationItem, { children: /* @__PURE__ */ jsx11(
4435
+ resolved.arrows && /* @__PURE__ */ jsx12(PaginationItem, { children: /* @__PURE__ */ jsx12(
4350
4436
  Button6,
4351
4437
  {
4352
4438
  variant: "outline",
@@ -4354,7 +4440,7 @@ function DataTablePagination({
4354
4440
  "aria-label": "Go to last page",
4355
4441
  disabled: currentPage >= pageCount,
4356
4442
  onClick: () => onPageChange(pageCount),
4357
- children: /* @__PURE__ */ jsx11(Icon7, { name: "chevrons-right", className: "cn-rtl-flip" })
4443
+ children: /* @__PURE__ */ jsx12(Icon8, { name: "chevrons-right", className: "cn-rtl-flip" })
4358
4444
  }
4359
4445
  ) })
4360
4446
  ] }) })
@@ -4363,7 +4449,7 @@ function DataTablePagination({
4363
4449
  }
4364
4450
 
4365
4451
  // src/data-table/table-primitives.tsx
4366
- import * as React7 from "react";
4452
+ import * as React8 from "react";
4367
4453
  import {
4368
4454
  flexRender as flexRender2
4369
4455
  } from "@tanstack/react-table";
@@ -4375,7 +4461,7 @@ import {
4375
4461
  DropdownMenuSeparator as DropdownMenuSeparator2,
4376
4462
  DropdownMenuTrigger as DropdownMenuTrigger4
4377
4463
  } from "@upbound/monarch-core";
4378
- import { Icon as Icon8 } from "@upbound/monarch-core";
4464
+ import { Icon as Icon9 } from "@upbound/monarch-core";
4379
4465
  import { Skeleton } from "@upbound/monarch-core";
4380
4466
  import {
4381
4467
  Table as BaseTable,
@@ -4386,7 +4472,7 @@ import {
4386
4472
  TableRow as BaseTableRow
4387
4473
  } from "@upbound/monarch-core";
4388
4474
  import { Tooltip as Tooltip6, TooltipContent as TooltipContent5, TooltipTrigger as TooltipTrigger5 } from "@upbound/monarch-core";
4389
- import { Fragment as Fragment7, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
4475
+ import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
4390
4476
  var HEADER_SURFACE_BG = "bg-[color-mix(in_oklch,var(--muted)_50%,var(--card))]";
4391
4477
  var TABLE_HEAD_CLASSES = "text-body-sm text-muted-foreground h-10 px-4 text-left align-middle font-medium whitespace-nowrap has-[[role=checkbox]]:pr-0";
4392
4478
  var TABLE_CELL_CLASSES = "px-4 py-2 align-middle whitespace-nowrap has-[[role=checkbox]]:pr-0";
@@ -4400,7 +4486,7 @@ function DataTableRoot({
4400
4486
  children
4401
4487
  }) {
4402
4488
  if (layout === "grid") {
4403
- return /* @__PURE__ */ jsx12(
4489
+ return /* @__PURE__ */ jsx13(
4404
4490
  "div",
4405
4491
  {
4406
4492
  ref: gridRootRef,
@@ -4411,7 +4497,7 @@ function DataTableRoot({
4411
4497
  }
4412
4498
  );
4413
4499
  }
4414
- return /* @__PURE__ */ jsx12(BaseTable, { className, style, children });
4500
+ return /* @__PURE__ */ jsx13(BaseTable, { className, style, children });
4415
4501
  }
4416
4502
  function getColumnPinningProps(column, surface = "body") {
4417
4503
  const isPinned = column.getIsPinned();
@@ -4434,8 +4520,8 @@ function getColumnPinningProps(column, surface = "body") {
4434
4520
  }
4435
4521
  function DataTableSortIcon({ sortOrder }) {
4436
4522
  if (!sortOrder) return null;
4437
- return /* @__PURE__ */ jsx12(
4438
- Icon8,
4523
+ return /* @__PURE__ */ jsx13(
4524
+ Icon9,
4439
4525
  {
4440
4526
  name: sortOrder === "asc" ? "arrow-up" : "arrow-down",
4441
4527
  size: "xs",
@@ -4454,57 +4540,57 @@ function ColumnActionsMenuItems({
4454
4540
  const canResize = header.column.getCanResize();
4455
4541
  const canHide = header.column.getCanHide();
4456
4542
  const canPin = !isGrid && header.column.getCanPin();
4457
- return /* @__PURE__ */ jsxs10(DropdownMenuContent4, { align: "start", className: "w-45", children: [
4458
- canSort && /* @__PURE__ */ jsxs10(Fragment7, { children: [
4459
- /* @__PURE__ */ jsxs10(
4543
+ return /* @__PURE__ */ jsxs11(DropdownMenuContent4, { align: "start", className: "w-45", children: [
4544
+ canSort && /* @__PURE__ */ jsxs11(Fragment7, { children: [
4545
+ /* @__PURE__ */ jsxs11(
4460
4546
  DropdownMenuItem4,
4461
4547
  {
4462
4548
  disabled: header.column.getIsSorted() === "asc",
4463
4549
  onClick: () => header.column.toggleSorting(false),
4464
4550
  children: [
4465
- /* @__PURE__ */ jsx12(Icon8, { name: "arrow-up" }),
4551
+ /* @__PURE__ */ jsx13(Icon9, { name: "arrow-up" }),
4466
4552
  "Sort ascending"
4467
4553
  ]
4468
4554
  }
4469
4555
  ),
4470
- /* @__PURE__ */ jsxs10(
4556
+ /* @__PURE__ */ jsxs11(
4471
4557
  DropdownMenuItem4,
4472
4558
  {
4473
4559
  disabled: header.column.getIsSorted() === "desc",
4474
4560
  onClick: () => header.column.toggleSorting(true),
4475
4561
  children: [
4476
- /* @__PURE__ */ jsx12(Icon8, { name: "arrow-down" }),
4562
+ /* @__PURE__ */ jsx13(Icon9, { name: "arrow-down" }),
4477
4563
  "Sort descending"
4478
4564
  ]
4479
4565
  }
4480
4566
  ),
4481
- !!header.column.getIsSorted() && /* @__PURE__ */ jsxs10(DropdownMenuItem4, { onClick: () => header.column.clearSorting(), children: [
4482
- /* @__PURE__ */ jsx12(Icon8, { name: "xmark" }),
4567
+ !!header.column.getIsSorted() && /* @__PURE__ */ jsxs11(DropdownMenuItem4, { onClick: () => header.column.clearSorting(), children: [
4568
+ /* @__PURE__ */ jsx13(Icon9, { name: "xmark" }),
4483
4569
  "Remove sorting"
4484
4570
  ] })
4485
4571
  ] }),
4486
- canResize && /* @__PURE__ */ jsxs10(Fragment7, { children: [
4487
- canSort && /* @__PURE__ */ jsx12(DropdownMenuSeparator2, {}),
4488
- !isGrid && /* @__PURE__ */ jsxs10(DropdownMenuItem4, { onClick: () => onAutosizeColumn(header.column.id), children: [
4489
- /* @__PURE__ */ jsx12(Icon8, { name: "arrows-left-right" }),
4572
+ canResize && /* @__PURE__ */ jsxs11(Fragment7, { children: [
4573
+ canSort && /* @__PURE__ */ jsx13(DropdownMenuSeparator2, {}),
4574
+ !isGrid && /* @__PURE__ */ jsxs11(DropdownMenuItem4, { onClick: () => onAutosizeColumn(header.column.id), children: [
4575
+ /* @__PURE__ */ jsx13(Icon9, { name: "arrows-left-right" }),
4490
4576
  "Autosize column"
4491
4577
  ] }),
4492
- /* @__PURE__ */ jsxs10(DropdownMenuItem4, { onClick: () => onAutosizeAll(), children: [
4493
- /* @__PURE__ */ jsx12(Icon8, { name: "table-columns" }),
4578
+ /* @__PURE__ */ jsxs11(DropdownMenuItem4, { onClick: () => onAutosizeAll(), children: [
4579
+ /* @__PURE__ */ jsx13(Icon9, { name: "table-columns" }),
4494
4580
  isGrid ? "Reset all columns" : "Autosize all columns"
4495
4581
  ] })
4496
4582
  ] }),
4497
- (canHide || canPin) && /* @__PURE__ */ jsxs10(Fragment7, { children: [
4498
- (canSort || canResize) && /* @__PURE__ */ jsx12(DropdownMenuSeparator2, {}),
4499
- canHide && /* @__PURE__ */ jsxs10(DropdownMenuItem4, { onClick: () => header.column.toggleVisibility(), children: [
4500
- /* @__PURE__ */ jsx12(Icon8, { name: "eye-slash" }),
4583
+ (canHide || canPin) && /* @__PURE__ */ jsxs11(Fragment7, { children: [
4584
+ (canSort || canResize) && /* @__PURE__ */ jsx13(DropdownMenuSeparator2, {}),
4585
+ canHide && /* @__PURE__ */ jsxs11(DropdownMenuItem4, { onClick: () => header.column.toggleVisibility(), children: [
4586
+ /* @__PURE__ */ jsx13(Icon9, { name: "eye-slash" }),
4501
4587
  "Hide column"
4502
4588
  ] }),
4503
- canPin && (header.column.getIsPinned() ? /* @__PURE__ */ jsxs10(DropdownMenuItem4, { onClick: () => header.column.pin(false), children: [
4504
- /* @__PURE__ */ jsx12(Icon8, { name: "thumbtack" }),
4589
+ canPin && (header.column.getIsPinned() ? /* @__PURE__ */ jsxs11(DropdownMenuItem4, { onClick: () => header.column.pin(false), children: [
4590
+ /* @__PURE__ */ jsx13(Icon9, { name: "thumbtack" }),
4505
4591
  "Unpin column"
4506
- ] }) : /* @__PURE__ */ jsxs10(DropdownMenuItem4, { onClick: () => header.column.pin("left"), children: [
4507
- /* @__PURE__ */ jsx12(Icon8, { name: "thumbtack" }),
4592
+ ] }) : /* @__PURE__ */ jsxs11(DropdownMenuItem4, { onClick: () => header.column.pin("left"), children: [
4593
+ /* @__PURE__ */ jsx13(Icon9, { name: "thumbtack" }),
4508
4594
  "Pin column"
4509
4595
  ] }))
4510
4596
  ] })
@@ -4524,7 +4610,7 @@ function HeaderCellContent({
4524
4610
  const resizeHandler = header.getResizeHandler();
4525
4611
  const headerTitle = typeof header.column.columnDef.header === "string" ? header.column.columnDef.header : "";
4526
4612
  const sorted = header.column.getIsSorted();
4527
- const labelButton = /* @__PURE__ */ jsxs10(
4613
+ const labelButton = /* @__PURE__ */ jsxs11(
4528
4614
  "button",
4529
4615
  {
4530
4616
  type: "button",
@@ -4535,10 +4621,10 @@ function HeaderCellContent({
4535
4621
  shouldShowActionsMenu ? "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 cursor-pointer" : "cursor-default"
4536
4622
  ),
4537
4623
  children: [
4538
- /* @__PURE__ */ jsx12(DataTableSortIcon, { sortOrder: sorted }),
4539
- /* @__PURE__ */ jsx12("span", { className: "min-w-0 truncate", children: flexRender2(header.column.columnDef.header, header.getContext()) }),
4540
- shouldShowActionsMenu && /* @__PURE__ */ jsx12(
4541
- Icon8,
4624
+ /* @__PURE__ */ jsx13(DataTableSortIcon, { sortOrder: sorted }),
4625
+ /* @__PURE__ */ jsx13("span", { className: "min-w-0 truncate", children: flexRender2(header.column.columnDef.header, header.getContext()) }),
4626
+ shouldShowActionsMenu && /* @__PURE__ */ jsx13(
4627
+ Icon9,
4542
4628
  {
4543
4629
  size: "sm",
4544
4630
  name: "ellipsis",
@@ -4548,9 +4634,9 @@ function HeaderCellContent({
4548
4634
  ]
4549
4635
  }
4550
4636
  );
4551
- const label = shouldShowActionsMenu ? /* @__PURE__ */ jsxs10(DropdownMenu4, { children: [
4552
- /* @__PURE__ */ jsx12(DropdownMenuTrigger4, { asChild: true, children: labelButton }),
4553
- /* @__PURE__ */ jsx12(
4637
+ const label = shouldShowActionsMenu ? /* @__PURE__ */ jsxs11(DropdownMenu4, { children: [
4638
+ /* @__PURE__ */ jsx13(DropdownMenuTrigger4, { asChild: true, children: labelButton }),
4639
+ /* @__PURE__ */ jsx13(
4554
4640
  ColumnActionsMenuItems,
4555
4641
  {
4556
4642
  header,
@@ -4560,12 +4646,12 @@ function HeaderCellContent({
4560
4646
  }
4561
4647
  )
4562
4648
  ] }) : labelButton;
4563
- return /* @__PURE__ */ jsxs10(Fragment7, { children: [
4564
- /* @__PURE__ */ jsx12("div", { className: "flex min-w-0 items-center gap-1", children: /* @__PURE__ */ jsx12("div", { className: "min-w-0 flex-1", children: !isActionColumn && !isGroupedColumn && (headerTitle ? /* @__PURE__ */ jsxs10(Tooltip6, { children: [
4565
- /* @__PURE__ */ jsx12(TooltipTrigger5, { asChild: true, children: label }),
4566
- /* @__PURE__ */ jsx12(TooltipContent5, { children: headerTitle })
4649
+ return /* @__PURE__ */ jsxs11(Fragment7, { children: [
4650
+ /* @__PURE__ */ jsx13("div", { className: "flex min-w-0 flex-1 items-center gap-1", children: /* @__PURE__ */ jsx13("div", { className: "min-w-0 flex-1", children: !isActionColumn && !isGroupedColumn && (headerTitle ? /* @__PURE__ */ jsxs11(Tooltip6, { children: [
4651
+ /* @__PURE__ */ jsx13(TooltipTrigger5, { asChild: true, children: label }),
4652
+ /* @__PURE__ */ jsx13(TooltipContent5, { children: headerTitle })
4567
4653
  ] }) : label) }) }),
4568
- canResize && /* @__PURE__ */ jsx12(
4654
+ canResize && /* @__PURE__ */ jsx13(
4569
4655
  "button",
4570
4656
  {
4571
4657
  type: "button",
@@ -4581,7 +4667,7 @@ function HeaderCellContent({
4581
4667
  ] });
4582
4668
  }
4583
4669
  var DEFAULT_STICKY_HEADER_OFFSET_PX = 0;
4584
- var DEFAULT_STICKY_HEADER_ROW_HEIGHT_PX = 48;
4670
+ var DEFAULT_STICKY_HEADER_ROW_HEIGHT_PX = 40;
4585
4671
  function DataTableHeader({
4586
4672
  headerGroups,
4587
4673
  onAutosizeAll,
@@ -4609,7 +4695,7 @@ function DataTableHeader({
4609
4695
  const stickyTopPx = stickyHeader ? stickyHeaderOffset + headerGroupIndex * stickyHeaderRowHeight : void 0;
4610
4696
  const isPinned = !isGrid && header.column.getIsPinned();
4611
4697
  const pinning = isGrid ? { className: "", style: {} } : getColumnPinningProps(header.column, "header");
4612
- const content = /* @__PURE__ */ jsx12(
4698
+ const content = /* @__PURE__ */ jsx13(
4613
4699
  HeaderCellContent,
4614
4700
  {
4615
4701
  header,
@@ -4630,11 +4716,11 @@ function DataTableHeader({
4630
4716
  isPinned && "z-30"
4631
4717
  );
4632
4718
  if (isGrid) {
4633
- return /* @__PURE__ */ jsx12(
4719
+ return /* @__PURE__ */ jsx13(
4634
4720
  "div",
4635
4721
  {
4636
4722
  role: "columnheader",
4637
- className: cn(TABLE_HEAD_CLASSES, cellClassName, "h-auto py-1.5 whitespace-normal"),
4723
+ className: cn(TABLE_HEAD_CLASSES, cellClassName, "flex items-center whitespace-normal"),
4638
4724
  style: __spreadValues({
4639
4725
  minWidth: header.column.columnDef.minSize
4640
4726
  }, stickyTopPx !== void 0 ? { top: stickyTopPx } : {}),
@@ -4643,10 +4729,10 @@ function DataTableHeader({
4643
4729
  header.id
4644
4730
  );
4645
4731
  }
4646
- return /* @__PURE__ */ jsx12(
4732
+ return /* @__PURE__ */ jsx13(
4647
4733
  BaseTableHead,
4648
4734
  {
4649
- className: cn(cellClassName, "h-auto py-1.5 whitespace-normal"),
4735
+ className: cn(cellClassName, "whitespace-normal"),
4650
4736
  style: __spreadValues(__spreadValues(__spreadProps(__spreadValues({}, pinning.style), {
4651
4737
  minWidth: header.column.columnDef.minSize,
4652
4738
  maxWidth: header.column.columnDef.maxSize
@@ -4658,19 +4744,19 @@ function DataTableHeader({
4658
4744
  });
4659
4745
  };
4660
4746
  if (isGrid) {
4661
- return /* @__PURE__ */ jsx12(
4747
+ return /* @__PURE__ */ jsx13(
4662
4748
  "div",
4663
4749
  {
4664
4750
  role: "rowgroup",
4665
4751
  className: cn("col-span-full grid grid-cols-subgrid", HEADER_SURFACE_BG, !!stickyHeader && "sticky z-20"),
4666
4752
  style: stickyHeader ? { top: stickyHeaderOffset } : void 0,
4667
- children: headerGroups.map((headerGroup, headerGroupIndex) => /* @__PURE__ */ jsx12("div", { role: "row", className: "col-span-full grid grid-cols-subgrid border-b", children: renderHeaders(headerGroup, headerGroupIndex) }, headerGroup.id))
4753
+ children: headerGroups.map((headerGroup, headerGroupIndex) => /* @__PURE__ */ jsx13("div", { role: "row", className: "col-span-full grid grid-cols-subgrid border-b", children: renderHeaders(headerGroup, headerGroupIndex) }, headerGroup.id))
4668
4754
  }
4669
4755
  );
4670
4756
  }
4671
- return /* @__PURE__ */ jsx12(BaseTableHeader, { children: headerGroups.map((headerGroup, headerGroupIndex) => /* @__PURE__ */ jsx12(BaseTableRow, { children: renderHeaders(headerGroup, headerGroupIndex) }, headerGroup.id)) });
4757
+ return /* @__PURE__ */ jsx13(BaseTableHeader, { children: headerGroups.map((headerGroup, headerGroupIndex) => /* @__PURE__ */ jsx13(BaseTableRow, { children: renderHeaders(headerGroup, headerGroupIndex) }, headerGroup.id)) });
4672
4758
  }
4673
- var DataTableRow = React7.forwardRef(
4759
+ var DataTableRow = React8.forwardRef(
4674
4760
  (_a, ref) => {
4675
4761
  var _b = _a, { hoverable, disabled, className, layout = "auto" } = _b, props = __objRest(_b, ["hoverable", "disabled", "className", "layout"]);
4676
4762
  const classes = cn(
@@ -4680,7 +4766,7 @@ var DataTableRow = React7.forwardRef(
4680
4766
  className
4681
4767
  );
4682
4768
  if (layout === "grid") {
4683
- return /* @__PURE__ */ jsx12(
4769
+ return /* @__PURE__ */ jsx13(
4684
4770
  "div",
4685
4771
  __spreadValues({
4686
4772
  ref,
@@ -4689,7 +4775,7 @@ var DataTableRow = React7.forwardRef(
4689
4775
  }, props)
4690
4776
  );
4691
4777
  }
4692
- return /* @__PURE__ */ jsx12(BaseTableRow, __spreadValues({ ref, className: classes }, props));
4778
+ return /* @__PURE__ */ jsx13(BaseTableRow, __spreadValues({ ref, className: classes }, props));
4693
4779
  }
4694
4780
  );
4695
4781
  DataTableRow.displayName = "DataTableRow";
@@ -4720,7 +4806,7 @@ function DataTableCell({
4720
4806
  isPinned && "z-10",
4721
4807
  className
4722
4808
  );
4723
- const cellElement = isGrid ? /* @__PURE__ */ jsx12(
4809
+ const cellElement = isGrid ? /* @__PURE__ */ jsx13(
4724
4810
  "div",
4725
4811
  {
4726
4812
  role: "cell",
@@ -4728,7 +4814,7 @@ function DataTableCell({
4728
4814
  style: { minWidth: cell.column.columnDef.minSize },
4729
4815
  children: content
4730
4816
  }
4731
- ) : /* @__PURE__ */ jsx12(
4817
+ ) : /* @__PURE__ */ jsx13(
4732
4818
  BaseTableCell,
4733
4819
  {
4734
4820
  className: cellClassName,
@@ -4740,9 +4826,9 @@ function DataTableCell({
4740
4826
  }
4741
4827
  );
4742
4828
  if (!shouldShowContextualMenu || !onContextCell) return cellElement;
4743
- return /* @__PURE__ */ jsxs10(ContextMenu, { children: [
4744
- /* @__PURE__ */ jsx12(ContextMenuTrigger, { asChild: true, children: cellElement }),
4745
- /* @__PURE__ */ jsx12(
4829
+ return /* @__PURE__ */ jsxs11(ContextMenu, { children: [
4830
+ /* @__PURE__ */ jsx13(ContextMenuTrigger, { asChild: true, children: cellElement }),
4831
+ /* @__PURE__ */ jsx13(
4746
4832
  CellContextualFilter,
4747
4833
  {
4748
4834
  filter: contextualFilter,
@@ -4761,7 +4847,7 @@ function DataTableGroupRow({
4761
4847
  layout = "auto"
4762
4848
  }) {
4763
4849
  if (layout === "grid") {
4764
- return /* @__PURE__ */ jsx12("div", { role: "row", className: "bg-muted/50 hover:bg-muted/50 col-span-full grid grid-cols-subgrid", children: /* @__PURE__ */ jsx12(
4850
+ return /* @__PURE__ */ jsx13("div", { role: "row", className: "bg-muted/50 hover:bg-muted/50 col-span-full grid grid-cols-subgrid", children: /* @__PURE__ */ jsx13(
4765
4851
  "div",
4766
4852
  {
4767
4853
  role: "cell",
@@ -4771,7 +4857,7 @@ function DataTableGroupRow({
4771
4857
  }
4772
4858
  ) });
4773
4859
  }
4774
- return /* @__PURE__ */ jsx12(BaseTableRow, { className: "bg-muted/50 hover:bg-muted/50", children: /* @__PURE__ */ jsx12(BaseTableCell, { colSpan, className: "text-foreground border-b font-semibold whitespace-nowrap", children: groupLabel }) });
4860
+ return /* @__PURE__ */ jsx13(BaseTableRow, { className: "bg-muted/50 hover:bg-muted/50", children: /* @__PURE__ */ jsx13(BaseTableCell, { colSpan, className: "text-foreground border-b font-semibold whitespace-nowrap", children: groupLabel }) });
4775
4861
  }
4776
4862
  function DataTableSkeletonBody({
4777
4863
  rowCount = 10,
@@ -4780,32 +4866,32 @@ function DataTableSkeletonBody({
4780
4866
  layout = "auto"
4781
4867
  }) {
4782
4868
  const isGrid = layout === "grid";
4783
- const rows = Array.from({ length: rowCount }).map((_, rowIndex) => /* @__PURE__ */ jsx12(DataTableRow, { layout, children: columns.map(
4869
+ const rows = Array.from({ length: rowCount }).map((_, rowIndex) => /* @__PURE__ */ jsx13(DataTableRow, { layout, children: columns.map(
4784
4870
  (col) => {
4785
4871
  var _a, _b;
4786
- return isGrid ? /* @__PURE__ */ jsx12(
4872
+ return isGrid ? /* @__PURE__ */ jsx13(
4787
4873
  "div",
4788
4874
  {
4789
4875
  role: "cell",
4790
4876
  className: cn(TABLE_CELL_CLASSES, "flex items-center overflow-hidden"),
4791
4877
  style: { minWidth: col.minSize },
4792
- children: (_a = renderCell == null ? void 0 : renderCell(col.id)) != null ? _a : /* @__PURE__ */ jsx12(Skeleton, { className: "h-4 w-full" })
4878
+ children: (_a = renderCell == null ? void 0 : renderCell(col.id)) != null ? _a : /* @__PURE__ */ jsx13(Skeleton, { className: "h-4 w-full" })
4793
4879
  },
4794
4880
  `skeleton-col-${col.id}-row-${rowIndex}`
4795
- ) : /* @__PURE__ */ jsx12(
4881
+ ) : /* @__PURE__ */ jsx13(
4796
4882
  BaseTableCell,
4797
4883
  {
4798
4884
  style: { width: col.size, minWidth: col.minSize, maxWidth: col.maxSize },
4799
- children: (_b = renderCell == null ? void 0 : renderCell(col.id)) != null ? _b : /* @__PURE__ */ jsx12(Skeleton, { className: "h-4 w-full" })
4885
+ children: (_b = renderCell == null ? void 0 : renderCell(col.id)) != null ? _b : /* @__PURE__ */ jsx13(Skeleton, { className: "h-4 w-full" })
4800
4886
  },
4801
4887
  `skeleton-col-${col.id}-row-${rowIndex}`
4802
4888
  );
4803
4889
  }
4804
4890
  ) }, `skeleton-row-${rowIndex}`));
4805
4891
  if (isGrid) {
4806
- return /* @__PURE__ */ jsx12("div", { role: "rowgroup", className: "col-span-full grid grid-cols-subgrid", "data-testid": "table-skeleton-loader", children: rows });
4892
+ return /* @__PURE__ */ jsx13("div", { role: "rowgroup", className: "col-span-full grid grid-cols-subgrid", "data-testid": "table-skeleton-loader", children: rows });
4807
4893
  }
4808
- return /* @__PURE__ */ jsx12(BaseTableBody, { "data-testid": "table-skeleton-loader", children: rows });
4894
+ return /* @__PURE__ */ jsx13(BaseTableBody, { "data-testid": "table-skeleton-loader", children: rows });
4809
4895
  }
4810
4896
  function DataTableExpandedRow({
4811
4897
  colSpan,
@@ -4815,9 +4901,9 @@ function DataTableExpandedRow({
4815
4901
  }) {
4816
4902
  if (!show) return null;
4817
4903
  if (layout === "grid") {
4818
- return /* @__PURE__ */ jsx12("div", { role: "row", className: "col-span-full grid grid-cols-subgrid", children: /* @__PURE__ */ jsx12("div", { role: "cell", style: { gridColumn: `span ${colSpan}` }, className: "bg-card p-0 align-top whitespace-normal", children }) });
4904
+ return /* @__PURE__ */ jsx13("div", { role: "row", className: "col-span-full grid grid-cols-subgrid", children: /* @__PURE__ */ jsx13("div", { role: "cell", style: { gridColumn: `span ${colSpan}` }, className: "bg-card p-0 align-top whitespace-normal", children }) });
4819
4905
  }
4820
- return /* @__PURE__ */ jsx12(BaseTableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ jsx12(BaseTableCell, { colSpan, className: "bg-card p-0 align-top whitespace-normal", children }) });
4906
+ return /* @__PURE__ */ jsx13(BaseTableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ jsx13(BaseTableCell, { colSpan, className: "bg-card p-0 align-top whitespace-normal", children }) });
4821
4907
  }
4822
4908
  function DataTableBody({
4823
4909
  tableRows,
@@ -4843,7 +4929,7 @@ function DataTableBody({
4843
4929
  minSize: c.columnDef.minSize,
4844
4930
  maxSize: c.columnDef.maxSize
4845
4931
  }));
4846
- return /* @__PURE__ */ jsx12(
4932
+ return /* @__PURE__ */ jsx13(
4847
4933
  DataTableSkeletonBody,
4848
4934
  {
4849
4935
  columns: skeletonColumns,
@@ -4857,17 +4943,17 @@ function DataTableBody({
4857
4943
  var _a, _b, _c, _d;
4858
4944
  if ((_a = row.getIsGrouped) == null ? void 0 : _a.call(row)) {
4859
4945
  const groupLabel = (_c = row.groupingValue) != null ? _c : row.groupingColumnId ? (_b = row.getGroupingValue) == null ? void 0 : _b.call(row, row.groupingColumnId) : void 0;
4860
- return /* @__PURE__ */ jsx12(DataTableGroupRow, { groupLabel: String(groupLabel != null ? groupLabel : ""), colSpan, layout }, row.id);
4946
+ return /* @__PURE__ */ jsx13(DataTableGroupRow, { groupLabel: String(groupLabel != null ? groupLabel : ""), colSpan, layout }, row.id);
4861
4947
  }
4862
4948
  const isExpanded = !!(renderExpandedRow && ((_d = row.getIsExpanded) == null ? void 0 : _d.call(row)));
4863
4949
  const expandedRow = renderExpandedRow ? renderExpandedRow(row.original) : null;
4864
- return /* @__PURE__ */ jsxs10(React7.Fragment, { children: [
4865
- /* @__PURE__ */ jsx12(
4950
+ return /* @__PURE__ */ jsxs11(React8.Fragment, { children: [
4951
+ /* @__PURE__ */ jsx13(
4866
4952
  DataTableRow,
4867
4953
  __spreadProps(__spreadValues({}, onRowRender ? onRowRender(row.original) : {}), {
4868
4954
  "data-expanded": isExpanded || void 0,
4869
4955
  layout,
4870
- children: row.getVisibleCells().filter((cell) => !isFilterOnlyColumn(cell.column)).map((cell) => /* @__PURE__ */ jsx12(
4956
+ children: row.getVisibleCells().filter((cell) => !isFilterOnlyColumn(cell.column)).map((cell) => /* @__PURE__ */ jsx13(
4871
4957
  DataTableCell,
4872
4958
  {
4873
4959
  cell,
@@ -4881,21 +4967,21 @@ function DataTableBody({
4881
4967
  ))
4882
4968
  })
4883
4969
  ),
4884
- /* @__PURE__ */ jsx12(DataTableExpandedRow, { colSpan, show: isExpanded, layout, children: expandedRow })
4970
+ /* @__PURE__ */ jsx13(DataTableExpandedRow, { colSpan, show: isExpanded, layout, children: expandedRow })
4885
4971
  ] }, row.id);
4886
4972
  });
4887
4973
  if (isGrid) {
4888
- return /* @__PURE__ */ jsx12("div", { role: "rowgroup", className: "col-span-full grid grid-cols-subgrid", children: rows });
4974
+ return /* @__PURE__ */ jsx13("div", { role: "rowgroup", className: "col-span-full grid grid-cols-subgrid", children: rows });
4889
4975
  }
4890
- return /* @__PURE__ */ jsx12(BaseTableBody, { children: rows });
4976
+ return /* @__PURE__ */ jsx13(BaseTableBody, { children: rows });
4891
4977
  }
4892
4978
 
4893
4979
  // src/data-table/view-filter.tsx
4894
- import * as React9 from "react";
4980
+ import * as React10 from "react";
4895
4981
 
4896
4982
  // src/filter-bar/filter-bar.tsx
4897
- import * as React8 from "react";
4898
- import { Icon as Icon9 } from "@upbound/monarch-core";
4983
+ import * as React9 from "react";
4984
+ import { Icon as Icon10 } from "@upbound/monarch-core";
4899
4985
  import { Badge as Badge3 } from "@upbound/monarch-core";
4900
4986
  import { Button as Button7 } from "@upbound/monarch-core";
4901
4987
  import { ButtonGroup as ButtonGroup2, ButtonGroupText as ButtonGroupText2 } from "@upbound/monarch-core";
@@ -4918,7 +5004,6 @@ import {
4918
5004
  DropdownMenu as DropdownMenu5,
4919
5005
  DropdownMenuCheckboxItem as DropdownMenuCheckboxItem2,
4920
5006
  DropdownMenuContent as DropdownMenuContent5,
4921
- DropdownMenuItem as DropdownMenuItem5,
4922
5007
  DropdownMenuRadioGroup,
4923
5008
  DropdownMenuRadioItem,
4924
5009
  DropdownMenuTrigger as DropdownMenuTrigger5
@@ -4926,7 +5011,7 @@ import {
4926
5011
  import { Input as Input2 } from "@upbound/monarch-core";
4927
5012
  import { Label as Label3 } from "@upbound/monarch-core";
4928
5013
  import { Popover as Popover2, PopoverContent as PopoverContent2, PopoverTrigger as PopoverTrigger2 } from "@upbound/monarch-core";
4929
- import { Fragment as Fragment8, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
5014
+ import { Fragment as Fragment8, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
4930
5015
  function asCheckboxValue(value) {
4931
5016
  return Array.isArray(value) ? value : [];
4932
5017
  }
@@ -4960,6 +5045,17 @@ function applyTimeToDate(date, time) {
4960
5045
  function formatDateLabel(date) {
4961
5046
  return date.toLocaleDateString(void 0, { month: "short", day: "numeric" });
4962
5047
  }
5048
+ function composeRefs(...refs) {
5049
+ return (node) => {
5050
+ for (const ref of refs) {
5051
+ if (typeof ref === "function") ref(node);
5052
+ else if (ref) ref.current = node;
5053
+ }
5054
+ };
5055
+ }
5056
+ function hasOrder(filter) {
5057
+ return typeof filter.order === "number";
5058
+ }
4963
5059
  function FilterBar(_a) {
4964
5060
  var _b = _a, {
4965
5061
  filters,
@@ -4968,7 +5064,8 @@ function FilterBar(_a) {
4968
5064
  onRemoveFilter,
4969
5065
  onChangeFilter,
4970
5066
  className,
4971
- children
5067
+ children,
5068
+ ref
4972
5069
  } = _b, props = __objRest(_b, [
4973
5070
  "filters",
4974
5071
  "activeFilters",
@@ -4976,48 +5073,60 @@ function FilterBar(_a) {
4976
5073
  "onRemoveFilter",
4977
5074
  "onChangeFilter",
4978
5075
  "className",
4979
- "children"
5076
+ "children",
5077
+ "ref"
4980
5078
  ]);
4981
5079
  const usedKeys = new Set(activeFilters.map((f) => f.key));
4982
- const availableFilters = filters.filter((f) => !usedKeys.has(f.key));
5080
+ const remainingFilters = filters.filter((f) => !usedKeys.has(f.key));
5081
+ const availableFilters = filters.some(hasOrder) ? remainingFilters : sortBy(remainingFilters, (f) => f.label);
4983
5082
  const shouldShowFilters = availableFilters.length > 0 || activeFilters.length > 0;
4984
- const [pendingOpenKey, setPendingOpenKey] = React8.useState(null);
5083
+ const [pendingOpenKey, setPendingOpenKey] = React9.useState(null);
4985
5084
  function handleAddFilter(key) {
4986
5085
  onAddFilter(key);
4987
5086
  setPendingOpenKey(key);
4988
5087
  }
4989
- return /* @__PURE__ */ jsxs11(
5088
+ const containerRef = React9.useRef(null);
5089
+ return /* @__PURE__ */ jsxs12(
4990
5090
  "div",
4991
5091
  __spreadProps(__spreadValues({
4992
5092
  "data-slot": "filter-bar",
4993
5093
  "data-visible-filters": shouldShowFilters,
4994
- className: cn("flex flex-wrap items-center gap-2", className)
5094
+ className: cn("flex flex-wrap items-center gap-2", className),
5095
+ ref: composeRefs(containerRef, ref)
4995
5096
  }, props), {
4996
5097
  children: [
4997
- availableFilters.length > 0 && /* @__PURE__ */ jsxs11(DropdownMenu5, { children: [
4998
- /* @__PURE__ */ jsx13(DropdownMenuTrigger5, { asChild: true, children: /* @__PURE__ */ jsxs11(Button7, { variant: "outline", children: [
4999
- /* @__PURE__ */ jsx13(Icon9, { name: "plus", "data-icon": "inline-start" }),
5000
- "Add filter"
5001
- ] }) }),
5002
- /* @__PURE__ */ jsx13(
5003
- DropdownMenuContent5,
5004
- {
5005
- align: "start",
5006
- className: "w-48",
5007
- onCloseAutoFocus: (e) => e.preventDefault(),
5008
- children: availableFilters.map((filter) => /* @__PURE__ */ jsx13(DropdownMenuItem5, { onSelect: () => handleAddFilter(filter.key), children: filter.label }, filter.key))
5009
- }
5010
- )
5011
- ] }),
5098
+ availableFilters.length > 0 && /* @__PURE__ */ jsxs12(
5099
+ Combobox2,
5100
+ {
5101
+ items: availableFilters,
5102
+ itemToStringValue: (item) => item.label,
5103
+ itemToStringLabel: (item) => item.label,
5104
+ onValueChange: (filter) => {
5105
+ if (filter) handleAddFilter(filter.key);
5106
+ },
5107
+ children: [
5108
+ /* @__PURE__ */ jsxs12(ComboboxTrigger2, { "aria-label": "Add filter", render: /* @__PURE__ */ jsx14(Button7, { variant: "outline" }), children: [
5109
+ /* @__PURE__ */ jsx14(Icon10, { name: "plus", "data-icon": "inline-start" }),
5110
+ "Add filter"
5111
+ ] }),
5112
+ /* @__PURE__ */ jsxs12(ComboboxContent2, { container: containerRef, align: "start", className: "w-48", children: [
5113
+ /* @__PURE__ */ jsx14(ComboboxInput2, { showTrigger: false, placeholder: "Search filters\u2026" }),
5114
+ /* @__PURE__ */ jsx14(ComboboxEmpty2, { children: "No filters found." }),
5115
+ /* @__PURE__ */ jsx14(ComboboxList2, { children: (filter) => /* @__PURE__ */ jsx14(ComboboxItem2, { value: filter, children: filter.label }, filter.key) })
5116
+ ] })
5117
+ ]
5118
+ }
5119
+ ),
5012
5120
  activeFilters.map((active) => {
5013
5121
  const definition = filters.find((f) => f.key === active.key);
5014
5122
  if (!definition) return null;
5015
- return /* @__PURE__ */ jsx13(
5123
+ return /* @__PURE__ */ jsx14(
5016
5124
  FilterChip,
5017
5125
  {
5018
5126
  definition,
5019
5127
  value: active.value,
5020
5128
  autoOpen: active.key === pendingOpenKey,
5129
+ container: containerRef,
5021
5130
  onChangeValue: (value) => onChangeFilter(active.key, value),
5022
5131
  onRemove: () => onRemoveFilter(active.key)
5023
5132
  },
@@ -5029,34 +5138,36 @@ function FilterBar(_a) {
5029
5138
  })
5030
5139
  );
5031
5140
  }
5032
- function FilterChip({ definition, value, autoOpen, onChangeValue, onRemove }) {
5141
+ function FilterChip({ definition, value, autoOpen, container, onChangeValue, onRemove }) {
5033
5142
  var _a;
5034
5143
  const type = (_a = definition.type) != null ? _a : "checkbox";
5035
5144
  switch (type) {
5036
5145
  case "checkbox":
5037
- return /* @__PURE__ */ jsx13(
5146
+ return /* @__PURE__ */ jsx14(
5038
5147
  CheckboxFilterChip,
5039
5148
  {
5040
5149
  definition,
5041
5150
  value,
5042
5151
  autoOpen,
5152
+ container,
5043
5153
  onChangeValue,
5044
5154
  onRemove
5045
5155
  }
5046
5156
  );
5047
5157
  case "radio":
5048
- return /* @__PURE__ */ jsx13(
5158
+ return /* @__PURE__ */ jsx14(
5049
5159
  RadioFilterChip,
5050
5160
  {
5051
5161
  definition,
5052
5162
  value,
5053
5163
  autoOpen,
5164
+ container,
5054
5165
  onChangeValue,
5055
5166
  onRemove
5056
5167
  }
5057
5168
  );
5058
5169
  case "text":
5059
- return /* @__PURE__ */ jsx13(
5170
+ return /* @__PURE__ */ jsx14(
5060
5171
  TextFilterChip,
5061
5172
  {
5062
5173
  definition,
@@ -5067,7 +5178,7 @@ function FilterChip({ definition, value, autoOpen, onChangeValue, onRemove }) {
5067
5178
  }
5068
5179
  );
5069
5180
  case "multiText":
5070
- return /* @__PURE__ */ jsx13(
5181
+ return /* @__PURE__ */ jsx14(
5071
5182
  MultiTextFilterChip,
5072
5183
  {
5073
5184
  definition,
@@ -5078,7 +5189,7 @@ function FilterChip({ definition, value, autoOpen, onChangeValue, onRemove }) {
5078
5189
  }
5079
5190
  );
5080
5191
  case "date":
5081
- return /* @__PURE__ */ jsx13(
5192
+ return /* @__PURE__ */ jsx14(
5082
5193
  DateFilterChip,
5083
5194
  {
5084
5195
  definition,
@@ -5091,26 +5202,28 @@ function FilterChip({ definition, value, autoOpen, onChangeValue, onRemove }) {
5091
5202
  }
5092
5203
  }
5093
5204
  function FilterChipRemoveButton({ label, onRemove }) {
5094
- return /* @__PURE__ */ jsx13(Button7, { variant: "outline", size: "icon", "aria-label": `Remove ${label} filter`, onClick: onRemove, children: /* @__PURE__ */ jsx13(Icon9, { name: "xmark" }) });
5205
+ return /* @__PURE__ */ jsx14(Button7, { variant: "outline", size: "icon", "aria-label": `Remove ${label} filter`, onClick: onRemove, children: /* @__PURE__ */ jsx14(Icon10, { name: "xmark" }) });
5095
5206
  }
5096
5207
  function CheckboxFilterChip({
5097
5208
  definition,
5098
5209
  value,
5099
5210
  autoOpen,
5211
+ container,
5100
5212
  onChangeValue,
5101
5213
  onRemove
5102
5214
  }) {
5103
5215
  var _a, _b;
5104
- const { label, options, searchable = false } = definition;
5216
+ const { label, searchable = false } = definition;
5217
+ const options = sortBy(definition.options, (o) => o.label);
5105
5218
  const values = asCheckboxValue(value);
5106
5219
  const displayLabel = values.length === 0 ? "Any" : values.length === 1 ? (_b = (_a = options.find((o) => o.value === values[0])) == null ? void 0 : _a.label) != null ? _b : values[0] : `${values.length} selected`;
5107
5220
  function toggle(optionValue) {
5108
5221
  const next = values.includes(optionValue) ? values.filter((v) => v !== optionValue) : [...values, optionValue];
5109
5222
  onChangeValue(next);
5110
5223
  }
5111
- return /* @__PURE__ */ jsxs11(ButtonGroup2, { children: [
5112
- /* @__PURE__ */ jsx13(ButtonGroupText2, { children: label }),
5113
- searchable ? /* @__PURE__ */ jsxs11(
5224
+ return /* @__PURE__ */ jsxs12(ButtonGroup2, { children: [
5225
+ /* @__PURE__ */ jsx14(ButtonGroupText2, { children: label }),
5226
+ searchable ? /* @__PURE__ */ jsxs12(
5114
5227
  Combobox2,
5115
5228
  {
5116
5229
  items: options,
@@ -5120,40 +5233,48 @@ function CheckboxFilterChip({
5120
5233
  value: options.filter((o) => values.includes(o.value)),
5121
5234
  onValueChange: (selected) => onChangeValue(selected.map((s) => s.value)),
5122
5235
  children: [
5123
- /* @__PURE__ */ jsx13(
5236
+ /* @__PURE__ */ jsx14(
5124
5237
  ComboboxTrigger2,
5125
5238
  {
5126
- render: /* @__PURE__ */ jsx13(Button7, { variant: "outline", className: "gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)" }),
5127
- children: /* @__PURE__ */ jsx13("span", { className: values.length === 0 ? "text-muted-foreground" : "", children: displayLabel })
5239
+ render: /* @__PURE__ */ jsx14(Button7, { variant: "outline", className: "gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)" }),
5240
+ children: /* @__PURE__ */ jsx14("span", { className: values.length === 0 ? "text-muted-foreground" : "", children: displayLabel })
5128
5241
  }
5129
5242
  ),
5130
- /* @__PURE__ */ jsxs11(ComboboxContent2, { className: "min-w-64", collisionAvoidance: { side: "none", align: "shift" }, children: [
5131
- /* @__PURE__ */ jsx13(ComboboxInput2, { showTrigger: false, placeholder: `Search ${label.toLowerCase()}\u2026` }),
5132
- values.length > 0 && /* @__PURE__ */ jsxs11(Fragment8, { children: [
5133
- /* @__PURE__ */ jsxs11(ComboboxSelectedChips2, { children: [
5134
- /* @__PURE__ */ jsx13(ComboboxValue2, { children: (selected) => /* @__PURE__ */ jsx13(Fragment8, { children: selected.map((item) => /* @__PURE__ */ jsx13(ComboboxChip2, { children: item.label }, item.value)) }) }),
5135
- /* @__PURE__ */ jsx13(ComboboxClearAll2, { onClick: () => onChangeValue([]) })
5136
- ] }),
5137
- /* @__PURE__ */ jsx13(ComboboxSeparator2, {})
5138
- ] }),
5139
- /* @__PURE__ */ jsxs11(ComboboxEmpty2, { children: [
5140
- "No ",
5141
- label.toLowerCase(),
5142
- " found."
5143
- ] }),
5144
- /* @__PURE__ */ jsx13(ComboboxList2, { children: (item) => /* @__PURE__ */ jsxs11(ComboboxItem2, { value: item, children: [
5145
- item.icon,
5146
- item.label
5147
- ] }, item.value) })
5148
- ] })
5243
+ /* @__PURE__ */ jsxs12(
5244
+ ComboboxContent2,
5245
+ {
5246
+ container,
5247
+ className: "min-w-64",
5248
+ collisionAvoidance: { side: "none", align: "shift" },
5249
+ children: [
5250
+ /* @__PURE__ */ jsx14(ComboboxInput2, { showTrigger: false, placeholder: `Search ${label.toLowerCase()}\u2026` }),
5251
+ values.length > 0 && /* @__PURE__ */ jsxs12(Fragment8, { children: [
5252
+ /* @__PURE__ */ jsxs12(ComboboxSelectedChips2, { children: [
5253
+ /* @__PURE__ */ jsx14(ComboboxValue2, { children: (selected) => /* @__PURE__ */ jsx14(Fragment8, { children: selected.map((item) => /* @__PURE__ */ jsx14(ComboboxChip2, { children: item.label }, item.value)) }) }),
5254
+ /* @__PURE__ */ jsx14(ComboboxClearAll2, { onClick: () => onChangeValue([]) })
5255
+ ] }),
5256
+ /* @__PURE__ */ jsx14(ComboboxSeparator2, {})
5257
+ ] }),
5258
+ /* @__PURE__ */ jsxs12(ComboboxEmpty2, { children: [
5259
+ "No ",
5260
+ label.toLowerCase(),
5261
+ " found."
5262
+ ] }),
5263
+ /* @__PURE__ */ jsx14(ComboboxList2, { children: (item) => /* @__PURE__ */ jsxs12(ComboboxItem2, { value: item, children: [
5264
+ item.icon,
5265
+ item.label
5266
+ ] }, item.value) })
5267
+ ]
5268
+ }
5269
+ )
5149
5270
  ]
5150
5271
  }
5151
- ) : /* @__PURE__ */ jsxs11(DropdownMenu5, { defaultOpen: autoOpen, children: [
5152
- /* @__PURE__ */ jsx13(DropdownMenuTrigger5, { asChild: true, children: /* @__PURE__ */ jsxs11(Button7, { variant: "outline", className: "gap-1 font-normal", children: [
5153
- /* @__PURE__ */ jsx13("span", { className: values.length === 0 ? "text-muted-foreground" : "", children: displayLabel }),
5154
- /* @__PURE__ */ jsx13(Icon9, { name: "chevron-down", size: "sm", className: "text-muted-foreground" })
5272
+ ) : /* @__PURE__ */ jsxs12(DropdownMenu5, { defaultOpen: autoOpen, children: [
5273
+ /* @__PURE__ */ jsx14(DropdownMenuTrigger5, { asChild: true, children: /* @__PURE__ */ jsxs12(Button7, { variant: "outline", className: "gap-1 font-normal", children: [
5274
+ /* @__PURE__ */ jsx14("span", { className: values.length === 0 ? "text-muted-foreground" : "", children: displayLabel }),
5275
+ /* @__PURE__ */ jsx14(Icon10, { name: "chevron-down", size: "sm", className: "text-muted-foreground" })
5155
5276
  ] }) }),
5156
- /* @__PURE__ */ jsx13(DropdownMenuContent5, { align: "start", className: "w-48", children: options.map((opt) => /* @__PURE__ */ jsxs11(
5277
+ /* @__PURE__ */ jsx14(DropdownMenuContent5, { align: "start", className: "w-48", children: options.map((opt) => /* @__PURE__ */ jsxs12(
5157
5278
  DropdownMenuCheckboxItem2,
5158
5279
  {
5159
5280
  checked: values.includes(opt.value),
@@ -5166,24 +5287,26 @@ function CheckboxFilterChip({
5166
5287
  opt.value
5167
5288
  )) })
5168
5289
  ] }),
5169
- /* @__PURE__ */ jsx13(FilterChipRemoveButton, { label, onRemove })
5290
+ /* @__PURE__ */ jsx14(FilterChipRemoveButton, { label, onRemove })
5170
5291
  ] });
5171
5292
  }
5172
5293
  function RadioFilterChip({
5173
5294
  definition,
5174
5295
  value,
5175
5296
  autoOpen,
5297
+ container,
5176
5298
  onChangeValue,
5177
5299
  onRemove
5178
5300
  }) {
5179
5301
  var _a, _b, _c;
5180
- const { label, options, searchable = false } = definition;
5302
+ const { label, searchable = false } = definition;
5303
+ const options = sortBy(definition.options, (o) => o.label);
5181
5304
  const selectedValue = asRadioValue(value);
5182
5305
  const displayLabel = selectedValue ? (_b = (_a = options.find((o) => o.value === selectedValue)) == null ? void 0 : _a.label) != null ? _b : selectedValue : "Any";
5183
5306
  const selected = (_c = options.find((o) => o.value === selectedValue)) != null ? _c : null;
5184
- return /* @__PURE__ */ jsxs11(ButtonGroup2, { children: [
5185
- /* @__PURE__ */ jsx13(ButtonGroupText2, { children: label }),
5186
- searchable ? /* @__PURE__ */ jsxs11(
5307
+ return /* @__PURE__ */ jsxs12(ButtonGroup2, { children: [
5308
+ /* @__PURE__ */ jsx14(ButtonGroupText2, { children: label }),
5309
+ searchable ? /* @__PURE__ */ jsxs12(
5187
5310
  Combobox2,
5188
5311
  {
5189
5312
  items: options,
@@ -5195,38 +5318,46 @@ function RadioFilterChip({
5195
5318
  return onChangeValue((_a2 = next == null ? void 0 : next.value) != null ? _a2 : "");
5196
5319
  },
5197
5320
  children: [
5198
- /* @__PURE__ */ jsx13(
5321
+ /* @__PURE__ */ jsx14(
5199
5322
  ComboboxTrigger2,
5200
5323
  {
5201
- render: /* @__PURE__ */ jsx13(Button7, { variant: "outline", className: "gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)" }),
5202
- children: /* @__PURE__ */ jsx13("span", { className: selectedValue ? "" : "text-muted-foreground", children: displayLabel })
5324
+ render: /* @__PURE__ */ jsx14(Button7, { variant: "outline", className: "gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)" }),
5325
+ children: /* @__PURE__ */ jsx14("span", { className: selectedValue ? "" : "text-muted-foreground", children: displayLabel })
5203
5326
  }
5204
5327
  ),
5205
- /* @__PURE__ */ jsxs11(ComboboxContent2, { className: "min-w-64", collisionAvoidance: { side: "none", align: "shift" }, children: [
5206
- /* @__PURE__ */ jsx13(ComboboxInput2, { showTrigger: false, placeholder: `Search ${label.toLowerCase()}\u2026` }),
5207
- /* @__PURE__ */ jsxs11(ComboboxEmpty2, { children: [
5208
- "No ",
5209
- label.toLowerCase(),
5210
- " found."
5211
- ] }),
5212
- /* @__PURE__ */ jsx13(ComboboxList2, { children: (item) => /* @__PURE__ */ jsxs11(ComboboxItem2, { value: item, children: [
5213
- item.icon,
5214
- item.label
5215
- ] }, item.value) })
5216
- ] })
5328
+ /* @__PURE__ */ jsxs12(
5329
+ ComboboxContent2,
5330
+ {
5331
+ container,
5332
+ className: "min-w-64",
5333
+ collisionAvoidance: { side: "none", align: "shift" },
5334
+ children: [
5335
+ /* @__PURE__ */ jsx14(ComboboxInput2, { showTrigger: false, placeholder: `Search ${label.toLowerCase()}\u2026` }),
5336
+ /* @__PURE__ */ jsxs12(ComboboxEmpty2, { children: [
5337
+ "No ",
5338
+ label.toLowerCase(),
5339
+ " found."
5340
+ ] }),
5341
+ /* @__PURE__ */ jsx14(ComboboxList2, { children: (item) => /* @__PURE__ */ jsxs12(ComboboxItem2, { value: item, children: [
5342
+ item.icon,
5343
+ item.label
5344
+ ] }, item.value) })
5345
+ ]
5346
+ }
5347
+ )
5217
5348
  ]
5218
5349
  }
5219
- ) : /* @__PURE__ */ jsxs11(DropdownMenu5, { defaultOpen: autoOpen, children: [
5220
- /* @__PURE__ */ jsx13(DropdownMenuTrigger5, { asChild: true, children: /* @__PURE__ */ jsxs11(Button7, { variant: "outline", className: "gap-1 font-normal", children: [
5221
- /* @__PURE__ */ jsx13("span", { className: selectedValue ? "" : "text-muted-foreground", children: displayLabel }),
5222
- /* @__PURE__ */ jsx13(Icon9, { name: "chevron-down", size: "sm", className: "text-muted-foreground" })
5350
+ ) : /* @__PURE__ */ jsxs12(DropdownMenu5, { defaultOpen: autoOpen, children: [
5351
+ /* @__PURE__ */ jsx14(DropdownMenuTrigger5, { asChild: true, children: /* @__PURE__ */ jsxs12(Button7, { variant: "outline", className: "gap-1 font-normal", children: [
5352
+ /* @__PURE__ */ jsx14("span", { className: selectedValue ? "" : "text-muted-foreground", children: displayLabel }),
5353
+ /* @__PURE__ */ jsx14(Icon10, { name: "chevron-down", size: "sm", className: "text-muted-foreground" })
5223
5354
  ] }) }),
5224
- /* @__PURE__ */ jsx13(DropdownMenuContent5, { align: "start", className: "w-48", children: /* @__PURE__ */ jsx13(DropdownMenuRadioGroup, { value: selectedValue, onValueChange: onChangeValue, children: options.map((opt) => /* @__PURE__ */ jsxs11(DropdownMenuRadioItem, { value: opt.value, children: [
5355
+ /* @__PURE__ */ jsx14(DropdownMenuContent5, { align: "start", className: "w-48", children: /* @__PURE__ */ jsx14(DropdownMenuRadioGroup, { value: selectedValue, onValueChange: onChangeValue, children: options.map((opt) => /* @__PURE__ */ jsxs12(DropdownMenuRadioItem, { value: opt.value, children: [
5225
5356
  opt.icon,
5226
5357
  opt.label
5227
5358
  ] }, opt.value)) }) })
5228
5359
  ] }),
5229
- /* @__PURE__ */ jsx13(FilterChipRemoveButton, { label, onRemove })
5360
+ /* @__PURE__ */ jsx14(FilterChipRemoveButton, { label, onRemove })
5230
5361
  ] });
5231
5362
  }
5232
5363
  function TextFilterChip({
@@ -5238,12 +5369,12 @@ function TextFilterChip({
5238
5369
  }) {
5239
5370
  const { label, placeholder } = definition;
5240
5371
  const text = asTextValue(value);
5241
- const [open, setOpen] = React8.useState(!!autoOpen);
5242
- return /* @__PURE__ */ jsxs11(ButtonGroup2, { children: [
5243
- /* @__PURE__ */ jsx13(ButtonGroupText2, { children: label }),
5244
- /* @__PURE__ */ jsxs11(Popover2, { open, onOpenChange: setOpen, children: [
5245
- /* @__PURE__ */ jsx13(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx13(Button7, { variant: "outline", className: "gap-1 font-normal", children: /* @__PURE__ */ jsx13("span", { className: text ? "" : "text-muted-foreground", children: text || "Any" }) }) }),
5246
- /* @__PURE__ */ jsx13(PopoverContent2, { align: "start", children: /* @__PURE__ */ jsx13(
5372
+ const [open, setOpen] = React9.useState(!!autoOpen);
5373
+ return /* @__PURE__ */ jsxs12(ButtonGroup2, { children: [
5374
+ /* @__PURE__ */ jsx14(ButtonGroupText2, { children: label }),
5375
+ /* @__PURE__ */ jsxs12(Popover2, { open, onOpenChange: setOpen, children: [
5376
+ /* @__PURE__ */ jsx14(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx14(Button7, { variant: "outline", className: "gap-1 font-normal", children: /* @__PURE__ */ jsx14("span", { className: text ? "" : "text-muted-foreground", children: text || "Any" }) }) }),
5377
+ /* @__PURE__ */ jsx14(PopoverContent2, { align: "start", children: /* @__PURE__ */ jsx14(
5247
5378
  Input2,
5248
5379
  {
5249
5380
  autoFocus: true,
@@ -5256,7 +5387,7 @@ function TextFilterChip({
5256
5387
  }
5257
5388
  ) })
5258
5389
  ] }),
5259
- /* @__PURE__ */ jsx13(FilterChipRemoveButton, { label, onRemove })
5390
+ /* @__PURE__ */ jsx14(FilterChipRemoveButton, { label, onRemove })
5260
5391
  ] });
5261
5392
  }
5262
5393
  function MultiTextFilterChip({
@@ -5268,7 +5399,7 @@ function MultiTextFilterChip({
5268
5399
  }) {
5269
5400
  const { label, placeholder } = definition;
5270
5401
  const tokens = asMultiTextValue(value);
5271
- const [draft, setDraft] = React8.useState("");
5402
+ const [draft, setDraft] = React9.useState("");
5272
5403
  const displayLabel = tokens.length === 0 ? "Any" : tokens.length === 1 ? tokens[0] : `${tokens.length} values`;
5273
5404
  function addToken() {
5274
5405
  const token = draft.trim();
@@ -5282,25 +5413,25 @@ function MultiTextFilterChip({
5282
5413
  function removeToken(token) {
5283
5414
  onChangeValue(tokens.filter((t) => t !== token));
5284
5415
  }
5285
- return /* @__PURE__ */ jsxs11(ButtonGroup2, { children: [
5286
- /* @__PURE__ */ jsx13(ButtonGroupText2, { children: label }),
5287
- /* @__PURE__ */ jsxs11(Popover2, { defaultOpen: autoOpen, children: [
5288
- /* @__PURE__ */ jsx13(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx13(Button7, { variant: "outline", className: "gap-1 font-normal", children: /* @__PURE__ */ jsx13("span", { className: tokens.length === 0 ? "text-muted-foreground" : "", children: displayLabel }) }) }),
5289
- /* @__PURE__ */ jsx13(PopoverContent2, { align: "start", children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-2", children: [
5290
- tokens.length > 0 && /* @__PURE__ */ jsx13("div", { className: "flex flex-wrap gap-1", children: tokens.map((token) => /* @__PURE__ */ jsxs11(Badge3, { variant: "secondary", className: "gap-1", children: [
5416
+ return /* @__PURE__ */ jsxs12(ButtonGroup2, { children: [
5417
+ /* @__PURE__ */ jsx14(ButtonGroupText2, { children: label }),
5418
+ /* @__PURE__ */ jsxs12(Popover2, { defaultOpen: autoOpen, children: [
5419
+ /* @__PURE__ */ jsx14(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx14(Button7, { variant: "outline", className: "gap-1 font-normal", children: /* @__PURE__ */ jsx14("span", { className: tokens.length === 0 ? "text-muted-foreground" : "", children: displayLabel }) }) }),
5420
+ /* @__PURE__ */ jsx14(PopoverContent2, { align: "start", children: /* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-2", children: [
5421
+ tokens.length > 0 && /* @__PURE__ */ jsx14("div", { className: "flex flex-wrap gap-1", children: tokens.map((token) => /* @__PURE__ */ jsxs12(Badge3, { variant: "secondary", className: "gap-1", children: [
5291
5422
  token,
5292
- /* @__PURE__ */ jsx13(
5423
+ /* @__PURE__ */ jsx14(
5293
5424
  "button",
5294
5425
  {
5295
5426
  type: "button",
5296
5427
  "aria-label": `Remove ${token}`,
5297
5428
  onClick: () => removeToken(token),
5298
5429
  className: "cursor-pointer",
5299
- children: /* @__PURE__ */ jsx13(Icon9, { name: "xmark", size: "xs" })
5430
+ children: /* @__PURE__ */ jsx14(Icon10, { name: "xmark", size: "xs" })
5300
5431
  }
5301
5432
  )
5302
5433
  ] }, token)) }),
5303
- /* @__PURE__ */ jsx13(
5434
+ /* @__PURE__ */ jsx14(
5304
5435
  Input2,
5305
5436
  {
5306
5437
  autoFocus: true,
@@ -5319,7 +5450,7 @@ function MultiTextFilterChip({
5319
5450
  )
5320
5451
  ] }) })
5321
5452
  ] }),
5322
- /* @__PURE__ */ jsx13(FilterChipRemoveButton, { label, onRemove })
5453
+ /* @__PURE__ */ jsx14(FilterChipRemoveButton, { label, onRemove })
5323
5454
  ] });
5324
5455
  }
5325
5456
  function DateFilterChip({
@@ -5349,12 +5480,12 @@ function DateFilterChip({
5349
5480
  if (!endDate) return;
5350
5481
  onChangeValue({ startDate, endDate: applyTimeToDate(endDate, time) });
5351
5482
  }
5352
- return /* @__PURE__ */ jsxs11(ButtonGroup2, { children: [
5353
- /* @__PURE__ */ jsx13(ButtonGroupText2, { children: label }),
5354
- /* @__PURE__ */ jsxs11(Popover2, { defaultOpen: autoOpen, children: [
5355
- /* @__PURE__ */ jsx13(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx13(Button7, { variant: "outline", className: "gap-1 font-normal", children: /* @__PURE__ */ jsx13("span", { className: startDate ? "" : "text-muted-foreground", children: displayLabel }) }) }),
5356
- /* @__PURE__ */ jsx13(PopoverContent2, { align: "start", className: "w-fit", children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-2", children: [
5357
- /* @__PURE__ */ jsx13(
5483
+ return /* @__PURE__ */ jsxs12(ButtonGroup2, { children: [
5484
+ /* @__PURE__ */ jsx14(ButtonGroupText2, { children: label }),
5485
+ /* @__PURE__ */ jsxs12(Popover2, { defaultOpen: autoOpen, children: [
5486
+ /* @__PURE__ */ jsx14(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx14(Button7, { variant: "outline", className: "gap-1 font-normal", children: /* @__PURE__ */ jsx14("span", { className: startDate ? "" : "text-muted-foreground", children: displayLabel }) }) }),
5487
+ /* @__PURE__ */ jsx14(PopoverContent2, { align: "start", className: "w-fit", children: /* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-2", children: [
5488
+ /* @__PURE__ */ jsx14(
5358
5489
  Calendar2,
5359
5490
  {
5360
5491
  mode: "range",
@@ -5362,9 +5493,9 @@ function DateFilterChip({
5362
5493
  onSelect: pickRange
5363
5494
  }
5364
5495
  ),
5365
- showTimeInputs && /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-2", children: [
5366
- /* @__PURE__ */ jsxs11("div", { className: "flex w-full items-center gap-2", children: [
5367
- /* @__PURE__ */ jsx13(
5496
+ showTimeInputs && /* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-2", children: [
5497
+ /* @__PURE__ */ jsxs12("div", { className: "flex w-full items-center gap-2", children: [
5498
+ /* @__PURE__ */ jsx14(
5368
5499
  Label3,
5369
5500
  {
5370
5501
  htmlFor: `${definition.key}-start-time`,
@@ -5372,7 +5503,7 @@ function DateFilterChip({
5372
5503
  children: "Start"
5373
5504
  }
5374
5505
  ),
5375
- /* @__PURE__ */ jsx13(
5506
+ /* @__PURE__ */ jsx14(
5376
5507
  Input2,
5377
5508
  {
5378
5509
  id: `${definition.key}-start-time`,
@@ -5384,8 +5515,8 @@ function DateFilterChip({
5384
5515
  }
5385
5516
  )
5386
5517
  ] }),
5387
- /* @__PURE__ */ jsxs11("div", { className: "flex w-full items-center gap-2", children: [
5388
- /* @__PURE__ */ jsx13(
5518
+ /* @__PURE__ */ jsxs12("div", { className: "flex w-full items-center gap-2", children: [
5519
+ /* @__PURE__ */ jsx14(
5389
5520
  Label3,
5390
5521
  {
5391
5522
  htmlFor: `${definition.key}-end-time`,
@@ -5393,7 +5524,7 @@ function DateFilterChip({
5393
5524
  children: "End"
5394
5525
  }
5395
5526
  ),
5396
- /* @__PURE__ */ jsx13(
5527
+ /* @__PURE__ */ jsx14(
5397
5528
  Input2,
5398
5529
  {
5399
5530
  id: `${definition.key}-end-time`,
@@ -5408,7 +5539,7 @@ function DateFilterChip({
5408
5539
  ] })
5409
5540
  ] }) })
5410
5541
  ] }),
5411
- /* @__PURE__ */ jsx13(FilterChipRemoveButton, { label, onRemove })
5542
+ /* @__PURE__ */ jsx14(FilterChipRemoveButton, { label, onRemove })
5412
5543
  ] });
5413
5544
  }
5414
5545
 
@@ -5419,26 +5550,26 @@ var isCheckboxColumnFilter = (definition) => definition.type === "checkbox";
5419
5550
  var isMultiTextColumnFilter = (definition) => definition.type === "multiText";
5420
5551
 
5421
5552
  // src/data-table/view-filter.tsx
5422
- import { jsx as jsx14 } from "react/jsx-runtime";
5553
+ import { jsx as jsx15 } from "react/jsx-runtime";
5423
5554
  function toFilterOption(opt) {
5424
5555
  return typeof opt === "string" ? { value: opt, label: opt } : { value: opt.value, label: opt.label };
5425
5556
  }
5426
5557
  function toFilterBarDefinition(key, filter) {
5427
- var _a, _b, _c;
5428
- const base = { key, label: filter.title, order: (_a = filter.order) != null ? _a : 0 };
5558
+ var _a, _b;
5559
+ const base = { key, label: filter.title, order: filter.order };
5429
5560
  if (isCheckboxColumnFilter(filter)) {
5430
5561
  const options = "options" in filter && filter.options ? filter.options : [];
5431
5562
  return __spreadProps(__spreadValues({}, base), {
5432
5563
  type: "checkbox",
5433
5564
  options: options.map(toFilterOption),
5434
- searchable: (_b = filter.searchable) != null ? _b : true
5565
+ searchable: (_a = filter.searchable) != null ? _a : true
5435
5566
  });
5436
5567
  }
5437
5568
  if (isRadioColumnFilter(filter)) {
5438
5569
  return __spreadProps(__spreadValues({}, base), {
5439
5570
  type: "radio",
5440
5571
  options: filter.options.map(toFilterOption),
5441
- searchable: (_c = filter.searchable) != null ? _c : true
5572
+ searchable: (_b = filter.searchable) != null ? _b : true
5442
5573
  });
5443
5574
  }
5444
5575
  if (isDateRangeColumnFilter(filter)) {
@@ -5462,7 +5593,7 @@ function ViewFilter({
5462
5593
  onColumnFiltersChange,
5463
5594
  className
5464
5595
  }) {
5465
- const filterableColumns = React9.useMemo(
5596
+ const filterableColumns = React10.useMemo(
5466
5597
  () => columns.filter((column) => !isFilterOnlyColumn(column) && column.getCanFilter()).flatMap((column) => {
5467
5598
  var _a;
5468
5599
  const filter = (_a = column.columnDef.meta) == null ? void 0 : _a.filter;
@@ -5470,19 +5601,24 @@ function ViewFilter({
5470
5601
  }),
5471
5602
  [columns]
5472
5603
  );
5473
- const filterDefinitions = React9.useMemo(
5474
- () => filterableColumns.map(({ key, filter }) => toFilterBarDefinition(key, filter)).sort((a, b) => a.order - b.order),
5604
+ const filterDefinitions = React10.useMemo(
5605
+ () => filterableColumns.map(({ key, filter }) => toFilterBarDefinition(key, filter)).sort((a, b) => {
5606
+ if (a.order == null && b.order == null) return 0;
5607
+ if (a.order == null) return 1;
5608
+ if (b.order == null) return -1;
5609
+ return a.order - b.order;
5610
+ }),
5475
5611
  [filterableColumns]
5476
5612
  );
5477
- const emptyValueByKey = React9.useMemo(
5613
+ const emptyValueByKey = React10.useMemo(
5478
5614
  () => new Map(filterableColumns.map(({ key, filter }) => [key, emptyValueFor(filter)])),
5479
5615
  [filterableColumns]
5480
5616
  );
5481
- const activeFilters = React9.useMemo(
5617
+ const activeFilters = React10.useMemo(
5482
5618
  () => columnFilters.map((filter) => ({ key: filter.id, value: filter.value })),
5483
5619
  [columnFilters]
5484
5620
  );
5485
- return /* @__PURE__ */ jsx14(
5621
+ return /* @__PURE__ */ jsx15(
5486
5622
  FilterBar,
5487
5623
  {
5488
5624
  className,
@@ -5496,10 +5632,10 @@ function ViewFilter({
5496
5632
  }
5497
5633
 
5498
5634
  // src/section-header.tsx
5499
- import { jsx as jsx15 } from "react/jsx-runtime";
5635
+ import { jsx as jsx16 } from "react/jsx-runtime";
5500
5636
  function SectionHeader(_a) {
5501
5637
  var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
5502
- return /* @__PURE__ */ jsx15(
5638
+ return /* @__PURE__ */ jsx16(
5503
5639
  "div",
5504
5640
  __spreadProps(__spreadValues({
5505
5641
  "data-slot": "section-header",
@@ -5511,19 +5647,19 @@ function SectionHeader(_a) {
5511
5647
  }
5512
5648
  function SectionHeaderContent(_a) {
5513
5649
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
5514
- return /* @__PURE__ */ jsx15("div", __spreadValues({ "data-slot": "section-header-content", className: cn("flex flex-col gap-1", className) }, props));
5650
+ return /* @__PURE__ */ jsx16("div", __spreadValues({ "data-slot": "section-header-content", className: cn("flex flex-col gap-1", className) }, props));
5515
5651
  }
5516
5652
  function SectionHeaderTitle(_a) {
5517
5653
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
5518
- return /* @__PURE__ */ jsx15("h2", __spreadValues({ "data-slot": "section-header-title", className: cn("text-h3 text-foreground", className) }, props));
5654
+ return /* @__PURE__ */ jsx16("h2", __spreadValues({ "data-slot": "section-header-title", className: cn("text-h3 text-foreground", className) }, props));
5519
5655
  }
5520
5656
  function SectionHeaderDescription(_a) {
5521
5657
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
5522
- return /* @__PURE__ */ jsx15("p", __spreadValues({ "data-slot": "section-header-description", className: cn("text-body text-muted-foreground", className) }, props));
5658
+ return /* @__PURE__ */ jsx16("p", __spreadValues({ "data-slot": "section-header-description", className: cn("text-body text-muted-foreground", className) }, props));
5523
5659
  }
5524
5660
  function SectionHeaderMeta(_a) {
5525
5661
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
5526
- return /* @__PURE__ */ jsx15(
5662
+ return /* @__PURE__ */ jsx16(
5527
5663
  "div",
5528
5664
  __spreadValues({
5529
5665
  "data-slot": "section-header-meta",
@@ -5537,15 +5673,15 @@ function SectionHeaderMeta(_a) {
5537
5673
  }
5538
5674
  function SectionHeaderActions(_a) {
5539
5675
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
5540
- return /* @__PURE__ */ jsx15("div", __spreadValues({ "data-slot": "section-header-actions", className: cn("flex items-center gap-2", className) }, props));
5676
+ return /* @__PURE__ */ jsx16("div", __spreadValues({ "data-slot": "section-header-actions", className: cn("flex items-center gap-2", className) }, props));
5541
5677
  }
5542
5678
  function SectionHeaderTabs(_a) {
5543
5679
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
5544
- return /* @__PURE__ */ jsx15("div", __spreadValues({ "data-slot": "section-header-tabs", className: cn("border-b", className) }, props));
5680
+ return /* @__PURE__ */ jsx16("div", __spreadValues({ "data-slot": "section-header-tabs", className: cn("border-b", className) }, props));
5545
5681
  }
5546
5682
 
5547
5683
  // src/data-table/data-table.tsx
5548
- import { Fragment as Fragment9, jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
5684
+ import { Fragment as Fragment9, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
5549
5685
  var DEFAULT_PAGE_SIZE = 20;
5550
5686
  function DataTable({
5551
5687
  id,
@@ -5596,23 +5732,24 @@ function DataTable({
5596
5732
  initialColumnSizing,
5597
5733
  onColumnSizingPersist,
5598
5734
  stickyHeader = false,
5599
- celFilterConfig
5735
+ celFilterConfig,
5736
+ filterVisibility
5600
5737
  }) {
5601
5738
  var _a, _b, _c, _d, _e, _f;
5602
5739
  const isGrid = layout === "grid";
5603
- const tableBodyScrollRef = React10.useRef(null);
5604
- const [innerGlobalFilter, setInnerGlobalFilter] = React10.useState("");
5605
- const [innerColumnOrdering, setInnerColumnOrdering] = React10.useState([]);
5606
- const [innerColumnFilters, setInnerColumnFilters] = React10.useState([]);
5607
- const [innerSorting, setInnerSorting] = React10.useState(((_a = config.state) == null ? void 0 : _a.sorting) || []);
5608
- const [innerColumnPinning, setInnerColumnPinning] = React10.useState({ left: [], right: [] });
5609
- const [innerPagination, setInnerPagination] = React10.useState({
5740
+ const tableBodyScrollRef = React11.useRef(null);
5741
+ const [innerGlobalFilter, setInnerGlobalFilter] = React11.useState("");
5742
+ const [innerColumnOrdering, setInnerColumnOrdering] = React11.useState([]);
5743
+ const [innerColumnFilters, setInnerColumnFilters] = React11.useState([]);
5744
+ const [innerSorting, setInnerSorting] = React11.useState(((_a = config.state) == null ? void 0 : _a.sorting) || []);
5745
+ const [innerColumnPinning, setInnerColumnPinning] = React11.useState({ left: [], right: [] });
5746
+ const [innerPagination, setInnerPagination] = React11.useState({
5610
5747
  pageIndex: ((_c = (_b = config.state) == null ? void 0 : _b.pagination) == null ? void 0 : _c.pageIndex) || 0,
5611
5748
  pageSize: ((_e = (_d = config.state) == null ? void 0 : _d.pagination) == null ? void 0 : _e.pageSize) || DEFAULT_PAGE_SIZE
5612
5749
  });
5613
- const [innerGrouping, setInnerGrouping] = React10.useState([]);
5614
- const [innerColumnVisibility, setInnerColumnVisibility] = React10.useState({});
5615
- const [innerExpanded, setInnerExpanded] = React10.useState({});
5750
+ const [innerGrouping, setInnerGrouping] = React11.useState([]);
5751
+ const [innerColumnVisibility, setInnerColumnVisibility] = React11.useState({});
5752
+ const [innerExpanded, setInnerExpanded] = React11.useState({});
5616
5753
  const {
5617
5754
  columnSizing,
5618
5755
  handleColumnSizingChange,
@@ -5624,6 +5761,11 @@ function DataTable({
5624
5761
  onColumnSizingPersist,
5625
5762
  maxSize: isGrid ? RESIZE_MAX_UNBOUNDED : void 0
5626
5763
  });
5764
+ const {
5765
+ showFilterToggle: filterToggleRequested,
5766
+ filterRowVisible,
5767
+ setFilterRowVisible
5768
+ } = useFilterVisibility(filterVisibility);
5627
5769
  const globalFilter = parentGlobalFilter != null ? parentGlobalFilter : innerGlobalFilter;
5628
5770
  const applyGlobalFilter = parentSetGlobalFilter != null ? parentSetGlobalFilter : setInnerGlobalFilter;
5629
5771
  const columnFilters = parentColumnFilters || innerColumnFilters;
@@ -5631,25 +5773,25 @@ function DataTable({
5631
5773
  const pagination = parentPagination || innerPagination;
5632
5774
  const setPagination = parentSetPagination != null ? parentSetPagination : setInnerPagination;
5633
5775
  const shouldDisablePagination = paginationConfig === false;
5634
- const resetPageIndexOnFilterChange = React10.useCallback(() => {
5776
+ const resetPageIndexOnFilterChange = React11.useCallback(() => {
5635
5777
  if (!serverSidePagination || pagination.pageIndex === 0) return;
5636
5778
  setPagination((prev) => __spreadProps(__spreadValues({}, prev), { pageIndex: 0 }));
5637
5779
  }, [serverSidePagination, pagination.pageIndex, setPagination]);
5638
- const setGlobalFilter = React10.useCallback(
5780
+ const setGlobalFilter = React11.useCallback(
5639
5781
  (value) => {
5640
5782
  applyGlobalFilter(value);
5641
5783
  resetPageIndexOnFilterChange();
5642
5784
  },
5643
5785
  [applyGlobalFilter, resetPageIndexOnFilterChange]
5644
5786
  );
5645
- const setColumnFilters = React10.useCallback(
5787
+ const setColumnFilters = React11.useCallback(
5646
5788
  (value) => {
5647
5789
  applyColumnFilters(value);
5648
5790
  resetPageIndexOnFilterChange();
5649
5791
  },
5650
5792
  [applyColumnFilters, resetPageIndexOnFilterChange]
5651
5793
  );
5652
- React10.useLayoutEffect(() => {
5794
+ React11.useLayoutEffect(() => {
5653
5795
  var _a2;
5654
5796
  if (shouldDisablePagination) return;
5655
5797
  (_a2 = tableBodyScrollRef.current) == null ? void 0 : _a2.scrollTo({ top: 0 });
@@ -5731,7 +5873,9 @@ function DataTable({
5731
5873
  const flatColumns = table.getAllFlatColumns();
5732
5874
  const displayableColumns = flatColumns.filter((col) => !isFilterOnlyColumn(col));
5733
5875
  const orderedVisibleColumns = table.getVisibleLeafColumns().filter((col) => !isFilterOnlyColumn(col));
5734
- const [gridMeasuredMins, setGridMeasuredMins] = React10.useState({});
5876
+ const hasFilters = !!celFilterConfig || hasFilterableColumns(flatColumns);
5877
+ const showFilterToggle = filterToggleRequested && !disableFilters && hasFilters;
5878
+ const [gridMeasuredMins, setGridMeasuredMins] = React11.useState({});
5735
5879
  const { gridTemplateColumns, gridRootRef, handleAutosizeAll, handleAutosizeColumn, handleResetColumnSize } = useGridLayout({
5736
5880
  layout,
5737
5881
  table,
@@ -5745,7 +5889,7 @@ function DataTable({
5745
5889
  rawHandleAutosizeColumn,
5746
5890
  rawHandleResetColumnSize
5747
5891
  });
5748
- const handleContextCell = React10.useCallback(
5892
+ const handleContextCell = React11.useCallback(
5749
5893
  (filter, cell) => {
5750
5894
  var _a2, _b2;
5751
5895
  if (celFilterConfig == null ? void 0 : celFilterConfig.onContextualFilter) {
@@ -5762,13 +5906,13 @@ function DataTable({
5762
5906
  },
5763
5907
  [celFilterConfig, onContextCell, setColumnFilters, table]
5764
5908
  );
5765
- const handleContextSearch = React10.useCallback(
5909
+ const handleContextSearch = React11.useCallback(
5766
5910
  (searchTerm) => {
5767
5911
  setGlobalFilter(searchTerm);
5768
5912
  },
5769
5913
  [setGlobalFilter]
5770
5914
  );
5771
- const totalTableWidth = React10.useMemo(() => {
5915
+ const totalTableWidth = React11.useMemo(() => {
5772
5916
  if (isGrid) return 0;
5773
5917
  const firstGroup = headerGroups[0];
5774
5918
  if (!firstGroup) return 0;
@@ -5792,12 +5936,12 @@ function DataTable({
5792
5936
  }
5793
5937
  setGlobalFilter("");
5794
5938
  };
5795
- React10.useEffect(() => {
5939
+ React11.useEffect(() => {
5796
5940
  if (parentGlobalFilter !== void 0) {
5797
5941
  setInnerGlobalFilter(parentGlobalFilter);
5798
5942
  }
5799
5943
  }, [parentGlobalFilter]);
5800
- React10.useEffect(() => {
5944
+ React11.useEffect(() => {
5801
5945
  if (disableColumnReordering) return;
5802
5946
  const allColumnIds = flatColumns.map((col) => col.id);
5803
5947
  const normalizedColumnOrdering = normalizeColumnOrdering(columnOrdering, allColumnIds);
@@ -5807,9 +5951,9 @@ function DataTable({
5807
5951
  }, [columnOrdering, disableColumnReordering, flatColumns, setColumnOrdering]);
5808
5952
  const showViewHeader = !!title || !!Actions;
5809
5953
  const showColumnOptions = !disableColumnReordering || !disableColumnVisibility;
5810
- const toolbarSearch = !disableSearch && /* @__PURE__ */ jsxs12(InputGroup3, { className: "w-70", children: [
5811
- /* @__PURE__ */ jsx16(InputGroupAddon3, { align: "inline-start", children: /* @__PURE__ */ jsx16(Icon10, { name: "magnifying-glass" }) }),
5812
- /* @__PURE__ */ jsx16(
5954
+ const toolbarSearch = !disableSearch && /* @__PURE__ */ jsxs13(InputGroup3, { className: "w-70", children: [
5955
+ /* @__PURE__ */ jsx17(InputGroupAddon3, { align: "inline-start", children: /* @__PURE__ */ jsx17(Icon11, { name: "magnifying-glass" }) }),
5956
+ /* @__PURE__ */ jsx17(
5813
5957
  InputGroupInput2,
5814
5958
  {
5815
5959
  "aria-label": "Search",
@@ -5820,7 +5964,7 @@ function DataTable({
5820
5964
  }
5821
5965
  )
5822
5966
  ] });
5823
- const toolbarColumns = !!showColumnOptions && /* @__PURE__ */ jsx16(
5967
+ const toolbarColumns = !!showColumnOptions && /* @__PURE__ */ jsx17(
5824
5968
  ColumnOptions,
5825
5969
  {
5826
5970
  columns: flatColumns,
@@ -5829,7 +5973,7 @@ function DataTable({
5829
5973
  disableColumnOrdering: disableColumnReordering
5830
5974
  }
5831
5975
  );
5832
- return /* @__PURE__ */ jsxs12(
5976
+ return /* @__PURE__ */ jsxs13(
5833
5977
  "div",
5834
5978
  {
5835
5979
  id: `table-${id}`,
@@ -5840,18 +5984,19 @@ function DataTable({
5840
5984
  className
5841
5985
  ),
5842
5986
  children: [
5843
- showViewHeader && /* @__PURE__ */ jsx16(SectionHeader, { className: "mb-4 flex w-full gap-2", children: /* @__PURE__ */ jsxs12(SectionHeaderContent, { children: [
5844
- !!title && /* @__PURE__ */ jsx16(SectionHeaderTitle, { children: title }),
5845
- !!description && /* @__PURE__ */ jsx16(SectionHeaderDescription, { children: description })
5987
+ showViewHeader && /* @__PURE__ */ jsx17(SectionHeader, { className: "mb-4 flex w-full gap-2", children: /* @__PURE__ */ jsxs13(SectionHeaderContent, { children: [
5988
+ !!title && /* @__PURE__ */ jsx17(SectionHeaderTitle, { children: title }),
5989
+ !!description && /* @__PURE__ */ jsx17(SectionHeaderDescription, { children: description })
5846
5990
  ] }) }),
5847
- /* @__PURE__ */ jsxs12("div", { className: "mb-4 flex flex-row gap-2", children: [
5991
+ /* @__PURE__ */ jsxs13("div", { className: "mb-4 flex flex-row gap-2", children: [
5848
5992
  toolbarSearch,
5849
- /* @__PURE__ */ jsxs12("div", { className: "ml-auto flex items-center gap-2", children: [
5850
- !!Actions && /* @__PURE__ */ jsx16(Actions, { state: tableState }),
5993
+ /* @__PURE__ */ jsxs13("div", { className: "ml-auto flex items-center gap-2", children: [
5994
+ showFilterToggle && /* @__PURE__ */ jsx17(FilterToggle, { pressed: filterRowVisible, onPressedChange: setFilterRowVisible, count: filterCount }),
5995
+ !!Actions && /* @__PURE__ */ jsx17(Actions, { state: tableState }),
5851
5996
  toolbarColumns
5852
5997
  ] })
5853
5998
  ] }),
5854
- !disableFilters && /* @__PURE__ */ jsx16("div", { className: "flex w-full", children: celFilterConfig ? /* @__PURE__ */ jsx16("div", { className: cn("mr-2 mb-4 min-w-0 flex-1", celFilterClassName), children: /* @__PURE__ */ jsx16(
5999
+ !disableFilters && (!showFilterToggle || filterRowVisible) && /* @__PURE__ */ jsx17("div", { className: "flex w-full", children: celFilterConfig ? /* @__PURE__ */ jsx17("div", { className: cn("mr-2 mb-4 min-w-0 flex-1", celFilterClassName), children: /* @__PURE__ */ jsx17(
5855
6000
  CelFilterBar,
5856
6001
  {
5857
6002
  schema: celFilterConfig.schema,
@@ -5861,7 +6006,7 @@ function DataTable({
5861
6006
  onRestrictedOptionSelect: celFilterConfig.onRestrictedOptionSelect,
5862
6007
  showClearButton: celFilterConfig.showClearButton
5863
6008
  }
5864
- ) }) : /* @__PURE__ */ jsx16(
6009
+ ) }) : /* @__PURE__ */ jsx17(
5865
6010
  ViewFilter,
5866
6011
  {
5867
6012
  columns: flatColumns,
@@ -5870,8 +6015,8 @@ function DataTable({
5870
6015
  className: "data-[visible-filters=true]:mb-4"
5871
6016
  }
5872
6017
  ) }),
5873
- shouldRenderTableContent ? /* @__PURE__ */ jsxs12(Fragment9, { children: [
5874
- /* @__PURE__ */ jsx16("div", { className: "flex min-h-0 flex-1 flex-col", "data-testid": "table-main", children: /* @__PURE__ */ jsx16(
6018
+ shouldRenderTableContent ? /* @__PURE__ */ jsxs13(Fragment9, { children: [
6019
+ /* @__PURE__ */ jsx17("div", { className: "flex min-h-0 flex-1 flex-col", "data-testid": "table-main", children: /* @__PURE__ */ jsx17(
5875
6020
  "div",
5876
6021
  {
5877
6022
  ref: tableBodyScrollRef,
@@ -5879,7 +6024,7 @@ function DataTable({
5879
6024
  "min-h-0 flex-1 overflow-auto rounded-lg border **:data-[slot=table-container]:overflow-visible",
5880
6025
  !!stickyHeader && "max-h-[calc(100svh-250px)]"
5881
6026
  ),
5882
- children: /* @__PURE__ */ jsxs12(
6027
+ children: /* @__PURE__ */ jsxs13(
5883
6028
  DataTableRoot,
5884
6029
  {
5885
6030
  layout,
@@ -5887,7 +6032,7 @@ function DataTable({
5887
6032
  gridRootRef,
5888
6033
  style: isGrid ? { width: "100%" } : totalTableWidth > 0 ? { width: `max(100%, ${totalTableWidth}px)`, minWidth: "100%" } : { width: "100%" },
5889
6034
  children: [
5890
- /* @__PURE__ */ jsx16(
6035
+ /* @__PURE__ */ jsx17(
5891
6036
  DataTableHeader,
5892
6037
  {
5893
6038
  headerGroups,
@@ -5898,7 +6043,7 @@ function DataTable({
5898
6043
  layout
5899
6044
  }
5900
6045
  ),
5901
- /* @__PURE__ */ jsx16(
6046
+ /* @__PURE__ */ jsx17(
5902
6047
  DataTableBody,
5903
6048
  {
5904
6049
  tableRows,
@@ -5920,7 +6065,7 @@ function DataTable({
5920
6065
  )
5921
6066
  }
5922
6067
  ) }),
5923
- !shouldDisablePagination && !!pagination && /* @__PURE__ */ jsx16(
6068
+ !shouldDisablePagination && !!pagination && /* @__PURE__ */ jsx17(
5924
6069
  DataTablePagination,
5925
6070
  {
5926
6071
  rowCount,
@@ -5932,7 +6077,7 @@ function DataTable({
5932
6077
  onPageSizeChange: (nextPageSize) => setPagination((prev) => __spreadProps(__spreadValues({}, prev || pagination), { pageIndex: 0, pageSize: nextPageSize }))
5933
6078
  }
5934
6079
  )
5935
- ] }) : /* @__PURE__ */ jsx16(
6080
+ ] }) : /* @__PURE__ */ jsx17(
5936
6081
  DataTableEmptyView,
5937
6082
  {
5938
6083
  emptyView,
@@ -5947,19 +6092,19 @@ function DataTable({
5947
6092
  }
5948
6093
 
5949
6094
  // src/floating-widget.tsx
5950
- import * as React11 from "react";
6095
+ import * as React12 from "react";
5951
6096
  import { Button as Button8 } from "@upbound/monarch-core";
5952
6097
  import { DropdownMenu as DropdownMenu6, DropdownMenuContent as DropdownMenuContent6, DropdownMenuTrigger as DropdownMenuTrigger6 } from "@upbound/monarch-core";
5953
- import { Icon as Icon11 } from "@upbound/monarch-core";
6098
+ import { Icon as Icon12 } from "@upbound/monarch-core";
5954
6099
  import { Kbd as Kbd2 } from "@upbound/monarch-core";
5955
6100
  import { Tooltip as Tooltip7, TooltipContent as TooltipContent6, TooltipTrigger as TooltipTrigger6 } from "@upbound/monarch-core";
5956
- import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
5957
- var FloatingWidgetContext = React11.createContext(null);
6101
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
6102
+ var FloatingWidgetContext = React12.createContext(null);
5958
6103
  function FloatingWidgetProvider({ children }) {
5959
- const [isOpen, setIsOpen] = React11.useState(false);
5960
- const [isCollapsed, setIsCollapsed] = React11.useState(false);
5961
- const [isExpanded, setIsExpanded] = React11.useState(false);
5962
- const value = React11.useMemo(
6104
+ const [isOpen, setIsOpen] = React12.useState(false);
6105
+ const [isCollapsed, setIsCollapsed] = React12.useState(false);
6106
+ const [isExpanded, setIsExpanded] = React12.useState(false);
6107
+ const value = React12.useMemo(
5963
6108
  () => ({
5964
6109
  isOpen,
5965
6110
  isCollapsed,
@@ -5991,10 +6136,10 @@ function FloatingWidgetProvider({ children }) {
5991
6136
  }),
5992
6137
  [isOpen, isCollapsed, isExpanded]
5993
6138
  );
5994
- return /* @__PURE__ */ jsx17(FloatingWidgetContext.Provider, { value, children });
6139
+ return /* @__PURE__ */ jsx18(FloatingWidgetContext.Provider, { value, children });
5995
6140
  }
5996
6141
  function useFloatingWidget() {
5997
- const ctx = React11.useContext(FloatingWidgetContext);
6142
+ const ctx = React12.useContext(FloatingWidgetContext);
5998
6143
  if (!ctx) {
5999
6144
  throw new Error("useFloatingWidget must be used inside <FloatingWidgetProvider>.");
6000
6145
  }
@@ -6002,14 +6147,14 @@ function useFloatingWidget() {
6002
6147
  }
6003
6148
  function FloatingWidget({ title = "Ask AI", subtitle, menuItems, children, className }) {
6004
6149
  const { isOpen, isCollapsed, isExpanded, close, collapse, restore, toggleExpand } = useFloatingWidget();
6005
- const [dragWidth, setDragWidth] = React11.useState(null);
6006
- const [isDragging, setIsDragging] = React11.useState(false);
6007
- React11.useEffect(() => {
6150
+ const [dragWidth, setDragWidth] = React12.useState(null);
6151
+ const [isDragging, setIsDragging] = React12.useState(false);
6152
+ React12.useEffect(() => {
6008
6153
  setDragWidth(null);
6009
6154
  }, [isExpanded]);
6010
6155
  const MIN_WIDTH = 420;
6011
- const widgetRef = React11.useRef(null);
6012
- const handleResizeMouseDown = React11.useCallback((e) => {
6156
+ const widgetRef = React12.useRef(null);
6157
+ const handleResizeMouseDown = React12.useCallback((e) => {
6013
6158
  var _a, _b;
6014
6159
  e.preventDefault();
6015
6160
  setIsDragging(true);
@@ -6029,7 +6174,7 @@ function FloatingWidget({ title = "Ask AI", subtitle, menuItems, children, class
6029
6174
  window.addEventListener("mousemove", onMove);
6030
6175
  window.addEventListener("mouseup", onUp);
6031
6176
  }, []);
6032
- React11.useEffect(() => {
6177
+ React12.useEffect(() => {
6033
6178
  if (!isOpen) return;
6034
6179
  function handleKeydown(e) {
6035
6180
  if (e.key === "Escape") {
@@ -6041,7 +6186,7 @@ function FloatingWidget({ title = "Ask AI", subtitle, menuItems, children, class
6041
6186
  }, [isOpen, close]);
6042
6187
  if (!isOpen) return null;
6043
6188
  const dragStyle = dragWidth != null && !isCollapsed ? { width: `${dragWidth}px`, minWidth: `${MIN_WIDTH}px` } : void 0;
6044
- return /* @__PURE__ */ jsxs13(
6189
+ return /* @__PURE__ */ jsxs14(
6045
6190
  "div",
6046
6191
  {
6047
6192
  ref: widgetRef,
@@ -6065,8 +6210,8 @@ function FloatingWidget({ title = "Ask AI", subtitle, menuItems, children, class
6065
6210
  className
6066
6211
  ),
6067
6212
  children: [
6068
- !isCollapsed && /* @__PURE__ */ jsxs13(Tooltip7, { children: [
6069
- /* @__PURE__ */ jsx17(TooltipTrigger6, { asChild: true, children: /* @__PURE__ */ jsx17(
6213
+ !isCollapsed && /* @__PURE__ */ jsxs14(Tooltip7, { children: [
6214
+ /* @__PURE__ */ jsx18(TooltipTrigger6, { asChild: true, children: /* @__PURE__ */ jsx18(
6070
6215
  "div",
6071
6216
  {
6072
6217
  role: "separator",
@@ -6074,79 +6219,993 @@ function FloatingWidget({ title = "Ask AI", subtitle, menuItems, children, class
6074
6219
  "aria-label": "Resize widget",
6075
6220
  onMouseDown: handleResizeMouseDown,
6076
6221
  className: "group absolute inset-y-0 left-0 z-20 hidden w-3 cursor-col-resize touch-none items-center justify-center bg-transparent select-none sm:flex",
6077
- children: /* @__PURE__ */ jsx17("div", { className: "bg-border h-12 w-1 shrink-0 rounded-lg opacity-0 transition-opacity duration-150 group-hover:opacity-100" })
6222
+ children: /* @__PURE__ */ jsx18("div", { className: "bg-border h-12 w-1 shrink-0 rounded-lg opacity-0 transition-opacity duration-150 group-hover:opacity-100" })
6078
6223
  }
6079
6224
  ) }),
6080
- /* @__PURE__ */ jsx17(TooltipContent6, { side: "left", children: "Resize" })
6225
+ /* @__PURE__ */ jsx18(TooltipContent6, { side: "left", children: "Resize" })
6081
6226
  ] }),
6082
- /* @__PURE__ */ jsxs13("header", { className: "flex min-h-12 shrink-0 items-center gap-1 border-b px-3 py-2", children: [
6083
- /* @__PURE__ */ jsxs13("div", { className: "flex min-w-0 flex-1 flex-col justify-center", children: [
6084
- /* @__PURE__ */ jsx17("span", { className: "text-body truncate font-medium", children: title }),
6085
- subtitle && /* @__PURE__ */ jsx17("span", { className: "text-body-sm text-muted-foreground truncate", children: subtitle })
6227
+ /* @__PURE__ */ jsxs14("header", { className: "flex min-h-12 shrink-0 items-center gap-1 border-b px-3 py-2", children: [
6228
+ /* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 flex-1 flex-col justify-center", children: [
6229
+ /* @__PURE__ */ jsx18("span", { className: "text-body truncate font-medium", children: title }),
6230
+ subtitle && /* @__PURE__ */ jsx18("span", { className: "text-body-sm text-muted-foreground truncate", children: subtitle })
6086
6231
  ] }),
6087
- menuItems && !isCollapsed && /* @__PURE__ */ jsxs13(Tooltip7, { children: [
6088
- /* @__PURE__ */ jsxs13(DropdownMenu6, { children: [
6089
- /* @__PURE__ */ jsx17(TooltipTrigger6, { asChild: true, children: /* @__PURE__ */ jsx17(DropdownMenuTrigger6, { asChild: true, children: /* @__PURE__ */ jsx17(Button8, { variant: "ghost", size: "icon-sm", "aria-label": "More options", children: /* @__PURE__ */ jsx17(Icon11, { name: "ellipsis-vertical" }) }) }) }),
6090
- /* @__PURE__ */ jsx17(DropdownMenuContent6, { align: "end", children: menuItems })
6232
+ menuItems && !isCollapsed && /* @__PURE__ */ jsxs14(Tooltip7, { children: [
6233
+ /* @__PURE__ */ jsxs14(DropdownMenu6, { children: [
6234
+ /* @__PURE__ */ jsx18(TooltipTrigger6, { asChild: true, children: /* @__PURE__ */ jsx18(DropdownMenuTrigger6, { asChild: true, children: /* @__PURE__ */ jsx18(Button8, { variant: "ghost", size: "icon-sm", "aria-label": "More options", children: /* @__PURE__ */ jsx18(Icon12, { name: "ellipsis-vertical" }) }) }) }),
6235
+ /* @__PURE__ */ jsx18(DropdownMenuContent6, { align: "end", children: menuItems })
6091
6236
  ] }),
6092
- /* @__PURE__ */ jsx17(TooltipContent6, { children: "More options" })
6237
+ /* @__PURE__ */ jsx18(TooltipContent6, { children: "More options" })
6093
6238
  ] }),
6094
- !isCollapsed && /* @__PURE__ */ jsxs13(Tooltip7, { children: [
6095
- /* @__PURE__ */ jsx17(TooltipTrigger6, { asChild: true, children: /* @__PURE__ */ jsx17(
6239
+ !isCollapsed && /* @__PURE__ */ jsxs14(Tooltip7, { children: [
6240
+ /* @__PURE__ */ jsx18(TooltipTrigger6, { asChild: true, children: /* @__PURE__ */ jsx18(
6096
6241
  Button8,
6097
6242
  {
6098
6243
  variant: "ghost",
6099
6244
  size: "icon-sm",
6100
6245
  onClick: toggleExpand,
6101
6246
  "aria-label": isExpanded ? "Shrink widget" : "Expand widget",
6102
- children: /* @__PURE__ */ jsx17(Icon11, { name: isExpanded ? "shrink" : "arrow-up-right-and-arrow-down-left-from-center" })
6247
+ children: /* @__PURE__ */ jsx18(Icon12, { name: isExpanded ? "shrink" : "arrow-up-right-and-arrow-down-left-from-center" })
6103
6248
  }
6104
6249
  ) }),
6105
- /* @__PURE__ */ jsx17(TooltipContent6, { children: isExpanded ? "Shrink widget" : "Expand widget" })
6250
+ /* @__PURE__ */ jsx18(TooltipContent6, { children: isExpanded ? "Shrink widget" : "Expand widget" })
6106
6251
  ] }),
6107
- /* @__PURE__ */ jsxs13(Tooltip7, { children: [
6108
- /* @__PURE__ */ jsx17(TooltipTrigger6, { asChild: true, children: isCollapsed ? /* @__PURE__ */ jsx17(Button8, { variant: "ghost", size: "icon-sm", onClick: restore, "aria-label": "Restore widget", children: /* @__PURE__ */ jsx17(Icon11, { name: "window-maximize" }) }) : /* @__PURE__ */ jsx17(Button8, { variant: "ghost", size: "icon-sm", onClick: collapse, "aria-label": "Minimize widget", children: /* @__PURE__ */ jsx17(Icon11, { name: "minus" }) }) }),
6109
- /* @__PURE__ */ jsx17(TooltipContent6, { children: isCollapsed ? "Restore widget" : "Minimize widget" })
6252
+ /* @__PURE__ */ jsxs14(Tooltip7, { children: [
6253
+ /* @__PURE__ */ jsx18(TooltipTrigger6, { asChild: true, children: isCollapsed ? /* @__PURE__ */ jsx18(Button8, { variant: "ghost", size: "icon-sm", onClick: restore, "aria-label": "Restore widget", children: /* @__PURE__ */ jsx18(Icon12, { name: "window-maximize" }) }) : /* @__PURE__ */ jsx18(Button8, { variant: "ghost", size: "icon-sm", onClick: collapse, "aria-label": "Minimize widget", children: /* @__PURE__ */ jsx18(Icon12, { name: "minus" }) }) }),
6254
+ /* @__PURE__ */ jsx18(TooltipContent6, { children: isCollapsed ? "Restore widget" : "Minimize widget" })
6110
6255
  ] }),
6111
- /* @__PURE__ */ jsxs13(Tooltip7, { children: [
6112
- /* @__PURE__ */ jsx17(TooltipTrigger6, { asChild: true, children: /* @__PURE__ */ jsx17(Button8, { variant: "ghost", size: "icon-sm", onClick: close, "aria-label": "Close widget", children: /* @__PURE__ */ jsx17(Icon11, { name: "xmark" }) }) }),
6113
- /* @__PURE__ */ jsxs13(TooltipContent6, { children: [
6256
+ /* @__PURE__ */ jsxs14(Tooltip7, { children: [
6257
+ /* @__PURE__ */ jsx18(TooltipTrigger6, { asChild: true, children: /* @__PURE__ */ jsx18(Button8, { variant: "ghost", size: "icon-sm", onClick: close, "aria-label": "Close widget", children: /* @__PURE__ */ jsx18(Icon12, { name: "xmark" }) }) }),
6258
+ /* @__PURE__ */ jsxs14(TooltipContent6, { children: [
6114
6259
  "Close widget",
6115
- /* @__PURE__ */ jsx17(Kbd2, { children: "Esc" })
6260
+ /* @__PURE__ */ jsx18(Kbd2, { children: "Esc" })
6116
6261
  ] })
6117
6262
  ] })
6118
6263
  ] }),
6119
- !isCollapsed && /* @__PURE__ */ jsx17("div", { className: "flex min-h-0 flex-1 flex-col", children })
6264
+ !isCollapsed && /* @__PURE__ */ jsx18("div", { className: "flex min-h-0 flex-1 flex-col", children })
6265
+ ]
6266
+ }
6267
+ );
6268
+ }
6269
+
6270
+ // src/graph/graph-actions-provider.tsx
6271
+ import * as React14 from "react";
6272
+
6273
+ // src/graph/hooks/useGraphActionsContext.ts
6274
+ import { createContext as createContext3, useContext as useContext3 } from "react";
6275
+ var GraphActionsContext = createContext3(null);
6276
+ var useGraphActionsContext = () => {
6277
+ const context = useContext3(GraphActionsContext);
6278
+ if (!context) {
6279
+ throw new Error("useGraphActionsContext must be used within GraphActionsProvider");
6280
+ }
6281
+ return context;
6282
+ };
6283
+
6284
+ // src/graph/hooks/useGraphActions.ts
6285
+ import { useCallback as useCallback9, useState as useState12 } from "react";
6286
+
6287
+ // src/graph/graph-node.tsx
6288
+ import * as React13 from "react";
6289
+ import { getIncomers, getOutgoers, Handle, Position as Position2 } from "reactflow";
6290
+ import { Badge as Badge4, Card as Card2, Icon as Icon13, Spinner, Tooltip as Tooltip8, TooltipContent as TooltipContent7, TooltipTrigger as TooltipTrigger7 } from "@upbound/monarch-core";
6291
+
6292
+ // src/graph/consts.ts
6293
+ var GRAPH_NODE_WIDTH = 260;
6294
+ var GRAPH_NODE_HEIGHT = 106;
6295
+ var GRAPH_NODE_COLLAPSED_HEIGHT = 47;
6296
+ var GRAPH_NODE_SEP = 22;
6297
+ var GRAPH_RANK_SEP = 54;
6298
+
6299
+ // src/graph/graph-edge.tsx
6300
+ import { getSmoothStepPath, getStraightPath, Position } from "reactflow";
6301
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
6302
+ var GraphEdge = ({
6303
+ id,
6304
+ sourceX,
6305
+ sourceY,
6306
+ targetX,
6307
+ targetY,
6308
+ targetPosition
6309
+ }) => {
6310
+ const halfDistanceWidth = (targetX - sourceX) / 2;
6311
+ const [straightEdgePath] = getStraightPath({
6312
+ sourceX: sourceX - 4,
6313
+ sourceY,
6314
+ targetX: Math.max(sourceX + halfDistanceWidth, GRAPH_NODE_WIDTH / 2),
6315
+ targetY: sourceY
6316
+ });
6317
+ const [edgePath] = getSmoothStepPath({
6318
+ sourceX: Math.max(sourceX + halfDistanceWidth, GRAPH_NODE_WIDTH / 2),
6319
+ sourceY,
6320
+ sourcePosition: Position.Bottom,
6321
+ targetX: targetX + 4,
6322
+ targetY,
6323
+ targetPosition,
6324
+ borderRadius: 8,
6325
+ offset: 0
6326
+ });
6327
+ return /* @__PURE__ */ jsxs15("g", { id, className: "react-flow__edge-path", children: [
6328
+ /* @__PURE__ */ jsx19("path", { d: straightEdgePath, className: "stroke-border fill-transparent stroke-2" }),
6329
+ /* @__PURE__ */ jsx19("path", { d: edgePath, className: "stroke-border fill-transparent stroke-2" })
6330
+ ] });
6331
+ };
6332
+
6333
+ // src/graph/graph-node.tsx
6334
+ import { Fragment as Fragment10, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
6335
+ function isDefaultNode(node) {
6336
+ return node.type !== "loading";
6337
+ }
6338
+ function GraphNode(_a) {
6339
+ var _b = _a, { id, data } = _b, props = __objRest(_b, ["id", "data"]);
6340
+ var _a2, _b2;
6341
+ const { nodes: originalNodes, edges: originalEdges } = useGraphActionsContext();
6342
+ const nodes = originalNodes;
6343
+ const edges = originalEdges;
6344
+ const handleClick = React13.useCallback(() => {
6345
+ var _a3;
6346
+ (_a3 = data == null ? void 0 : data.onClick) == null ? void 0 : _a3.call(data, id, data);
6347
+ }, [data, id]);
6348
+ const compact = (_a2 = data == null ? void 0 : data.compact) != null ? _a2 : false;
6349
+ const state = (_b2 = data == null ? void 0 : data.state) != null ? _b2 : "default";
6350
+ const compactBadges = React13.useMemo(() => {
6351
+ const badges = data.badges.compact || [];
6352
+ if (state === "paused") {
6353
+ return [
6354
+ { children: /* @__PURE__ */ jsx20(Icon13, { name: "pause", size: "xs" }), variant: "secondary", tooltipContent: "Resource is paused" },
6355
+ ...badges
6356
+ ];
6357
+ }
6358
+ return badges;
6359
+ }, [data.badges.compact, state]);
6360
+ const defaultBadges = React13.useMemo(() => {
6361
+ const badges = data.badges.default || [];
6362
+ if (state === "paused") {
6363
+ return [
6364
+ {
6365
+ children: /* @__PURE__ */ jsxs16(Fragment10, { children: [
6366
+ /* @__PURE__ */ jsx20(Icon13, { name: "pause", size: "xs", className: "mr-1" }),
6367
+ " Paused"
6368
+ ] }),
6369
+ variant: "secondary",
6370
+ tooltipContent: "Resource is paused"
6371
+ },
6372
+ ...badges
6373
+ ];
6374
+ }
6375
+ return badges;
6376
+ }, [data.badges.default, state]);
6377
+ const currentNode = React13.useMemo(
6378
+ () => ({
6379
+ id,
6380
+ position: { x: 0, y: 0 },
6381
+ // Position not needed for edge calculations
6382
+ data,
6383
+ type: props.type
6384
+ }),
6385
+ [id, data, props.type]
6386
+ );
6387
+ const _hasIncomingEdge = React13.useMemo(() => {
6388
+ return getIncomers(currentNode, nodes, edges).length > 0;
6389
+ }, [currentNode, nodes, edges]);
6390
+ const hasOutgoingEdge = React13.useMemo(() => {
6391
+ return getOutgoers(currentNode, nodes, edges).length > 0;
6392
+ }, [currentNode, nodes, edges]);
6393
+ const targetX = GRAPH_NODE_WIDTH / 2 - 4;
6394
+ const sourceX = 4;
6395
+ return /* @__PURE__ */ jsxs16(
6396
+ Card2,
6397
+ {
6398
+ className: cn(
6399
+ "relative gap-1.5 overflow-visible rounded-lg py-0",
6400
+ `flex h-[106px]! w-[260px]! flex-col pt-2.5! pb-0!`,
6401
+ `hover:shadow-md motion-safe:transition-shadow`,
6402
+ compact && `h-[47px]!`
6403
+ ),
6404
+ style: { height: compact ? GRAPH_NODE_COLLAPSED_HEIGHT : GRAPH_NODE_HEIGHT, width: GRAPH_NODE_WIDTH },
6405
+ children: [
6406
+ /* @__PURE__ */ jsx20(
6407
+ Handle,
6408
+ {
6409
+ type: "target",
6410
+ position: Position2.Left,
6411
+ style: {
6412
+ visibility: "hidden",
6413
+ width: 0
6414
+ },
6415
+ isConnectable: false
6416
+ }
6417
+ ),
6418
+ /* @__PURE__ */ jsxs16("div", { className: "flex w-full flex-1 cursor-pointer flex-col", onClick: handleClick, children: [
6419
+ /* @__PURE__ */ jsxs16("div", { className: cn("flex w-full justify-between gap-1 px-2.5", compact && "flex-row-reverse items-start"), children: [
6420
+ !!compact && /* @__PURE__ */ jsxs16(Fragment10, { children: [
6421
+ compactBadges.length > 0 && /* @__PURE__ */ jsx20("div", { className: "flex shrink-0 flex-row items-center gap-1.5 overflow-hidden", children: compactBadges.map((_c, index) => {
6422
+ var _d = _c, { tooltipContent, variant } = _d, badge = __objRest(_d, ["tooltipContent", "variant"]);
6423
+ return /* @__PURE__ */ jsxs16(Tooltip8, { children: [
6424
+ /* @__PURE__ */ jsx20(TooltipTrigger7, { children: /* @__PURE__ */ jsx20(
6425
+ Badge4,
6426
+ __spreadProps(__spreadValues({
6427
+ variant
6428
+ }, badge), {
6429
+ className: "flex size-[20px]! cursor-default! items-center justify-center p-0!",
6430
+ children: badge.children
6431
+ })
6432
+ ) }),
6433
+ tooltipContent && /* @__PURE__ */ jsx20(TooltipContent7, { children: tooltipContent })
6434
+ ] }, index);
6435
+ }) }),
6436
+ state === "progressing" && /* @__PURE__ */ jsx20("div", { className: "flex shrink-0 flex-row items-center gap-1.5 overflow-hidden", children: /* @__PURE__ */ jsx20("div", { className: "flex size-[20px]! items-center justify-center", children: /* @__PURE__ */ jsx20(Spinner, { size: "sm" }) }) })
6437
+ ] }),
6438
+ /* @__PURE__ */ jsxs16("div", { className: "mr-auto grow-0 overflow-hidden", children: [
6439
+ /* @__PURE__ */ jsx20("h5", { className: "text-body-sm/tight truncate font-bold", children: data.title }),
6440
+ /* @__PURE__ */ jsx20("p", { className: "text-body-sm truncate leading-none", children: data.subtitle }),
6441
+ !compact && /* @__PURE__ */ jsx20("p", { className: "text-body-sm text-muted-foreground mt-1 truncate", children: data.name })
6442
+ ] }),
6443
+ /* @__PURE__ */ jsx20(
6444
+ "span",
6445
+ {
6446
+ className: cn(
6447
+ "bg-foreground text-background inline-flex h-[26px] w-auto shrink-0 items-center justify-center rounded-md px-[7px] text-[10px] font-semibold",
6448
+ ["progressing", "paused"].includes(state) && "opacity-30",
6449
+ data.typeDescriptors.className
6450
+ ),
6451
+ children: data.typeDescriptors.default
6452
+ }
6453
+ )
6454
+ ] }),
6455
+ !compact && /* @__PURE__ */ jsx20(Fragment10, { children: (defaultBadges.length > 0 || state === "progressing") && /* @__PURE__ */ jsxs16("div", { className: "mt-auto flex h-8 items-center border-t px-2.5", children: [
6456
+ /* @__PURE__ */ jsx20("div", { className: "flex gap-1.5 overflow-hidden overflow-x-auto", children: defaultBadges.map((_e, index) => {
6457
+ var _f = _e, { tooltipContent, variant } = _f, badge = __objRest(_f, ["tooltipContent", "variant"]);
6458
+ return /* @__PURE__ */ jsxs16(Tooltip8, { children: [
6459
+ /* @__PURE__ */ jsx20(TooltipTrigger7, { children: /* @__PURE__ */ jsx20(Badge4, __spreadProps(__spreadValues({ variant }, badge), { className: "cursor-default! py-px! whitespace-nowrap", children: badge.children })) }),
6460
+ tooltipContent && /* @__PURE__ */ jsx20(TooltipContent7, { children: tooltipContent })
6461
+ ] }, index);
6462
+ }) }),
6463
+ state === "progressing" && /* @__PURE__ */ jsx20("div", { className: "ml-auto flex size-[20px]! items-center justify-center", children: /* @__PURE__ */ jsx20(Spinner, { size: "sm" }) })
6464
+ ] }) })
6465
+ ] }),
6466
+ !!hasOutgoingEdge && /* @__PURE__ */ jsxs16(
6467
+ "div",
6468
+ {
6469
+ className: "absolute top-0 right-0 h-full w-auto translate-x-full",
6470
+ style: {
6471
+ width: GRAPH_RANK_SEP
6472
+ },
6473
+ children: [
6474
+ /* @__PURE__ */ jsx20("svg", { height: 20, width: GRAPH_NODE_SEP, className: "absolute top-1/2 -translate-y-1/2", children: /* @__PURE__ */ jsx20(
6475
+ GraphEdge,
6476
+ {
6477
+ id: `${id}-expadable`,
6478
+ sourceX,
6479
+ sourceY: 10,
6480
+ targetX,
6481
+ targetY: 10,
6482
+ sourcePosition: Position2.Right,
6483
+ targetPosition: Position2.Left,
6484
+ source: id,
6485
+ target: id,
6486
+ stopOpacity: 0
6487
+ }
6488
+ ) }),
6489
+ /* @__PURE__ */ jsxs16(Tooltip8, { children: [
6490
+ /* @__PURE__ */ jsx20(TooltipTrigger7, { asChild: true, children: /* @__PURE__ */ jsx20(
6491
+ "button",
6492
+ {
6493
+ type: "button",
6494
+ "aria-label": data.expanded ? "Collapse" : "Expand",
6495
+ className: "bg-foreground text-background hover:bg-foreground/90 focus-visible:ring-ring/30 absolute top-[calc(50%)] left-[calc(50%)] inline-flex size-4 -translate-1/2 items-center justify-center rounded-full p-0 text-center text-[10px] leading-none duration-150 outline-none focus-visible:ring-2 motion-safe:transition-colors",
6496
+ onClick: (e) => {
6497
+ var _a3;
6498
+ e.stopPropagation();
6499
+ (_a3 = data.onExpandToggle) == null ? void 0 : _a3.call(data, id);
6500
+ },
6501
+ children: /* @__PURE__ */ jsx20(Icon13, { name: data.expanded ? "minus" : "plus", size: "xs" })
6502
+ }
6503
+ ) }),
6504
+ /* @__PURE__ */ jsx20(TooltipContent7, { children: data.expanded ? "Collapse" : "Expand" })
6505
+ ] })
6506
+ ]
6507
+ }
6508
+ ),
6509
+ /* @__PURE__ */ jsx20(
6510
+ Handle,
6511
+ {
6512
+ type: "source",
6513
+ position: Position2.Right,
6514
+ style: {
6515
+ visibility: "hidden",
6516
+ width: 0
6517
+ },
6518
+ isConnectable: false
6519
+ }
6520
+ )
6521
+ ]
6522
+ }
6523
+ );
6524
+ }
6525
+ function GraphNodeSkeleton(_props) {
6526
+ const compact = false;
6527
+ return /* @__PURE__ */ jsxs16(
6528
+ Card2,
6529
+ {
6530
+ className: cn(
6531
+ `flex h-[106px]! w-[260px]! flex-col gap-1.5 rounded-lg px-0 py-0 pt-2.5! pb-0! hover:shadow-md motion-safe:transition-shadow`,
6532
+ compact && `h-[47px]!`
6533
+ ),
6534
+ children: [
6535
+ /* @__PURE__ */ jsx20(
6536
+ Handle,
6537
+ {
6538
+ type: "target",
6539
+ position: Position2.Left,
6540
+ style: {
6541
+ visibility: "hidden",
6542
+ width: 0
6543
+ },
6544
+ isConnectable: false
6545
+ }
6546
+ ),
6547
+ /* @__PURE__ */ jsxs16("div", { className: cn("flex w-full gap-1 px-2.5", compact && "flex-row-reverse"), children: [
6548
+ /* @__PURE__ */ jsxs16("div", { className: cn("grow-0 overflow-hidden", compact && "mr-auto"), children: [
6549
+ /* @__PURE__ */ jsx20("div", { className: "bg-muted mb-1 h-3 w-16 animate-pulse rounded-sm" }),
6550
+ /* @__PURE__ */ jsx20("div", { className: "bg-muted h-3 w-40 animate-pulse rounded-sm" }),
6551
+ !compact && /* @__PURE__ */ jsx20("div", { className: "bg-muted mt-2 h-3 w-48 animate-pulse rounded-sm" })
6552
+ ] }),
6553
+ /* @__PURE__ */ jsx20("div", { className: cn("bg-muted size-[26px] shrink-0 animate-pulse rounded-md", !compact && "ml-auto") })
6554
+ ] }),
6555
+ !compact && /* @__PURE__ */ jsx20("div", { className: "mt-auto flex h-8 items-center border-t px-2.5", children: /* @__PURE__ */ jsxs16("div", { className: "flex gap-1.5 overflow-hidden overflow-x-auto", children: [
6556
+ /* @__PURE__ */ jsx20("div", { className: "bg-muted h-4 w-12 animate-pulse rounded-sm" }),
6557
+ /* @__PURE__ */ jsx20("div", { className: "bg-muted h-4 w-12 animate-pulse rounded-sm" })
6558
+ ] }) }),
6559
+ /* @__PURE__ */ jsx20(
6560
+ Handle,
6561
+ {
6562
+ type: "source",
6563
+ position: Position2.Right,
6564
+ style: {
6565
+ visibility: "hidden",
6566
+ width: 0
6567
+ },
6568
+ isConnectable: false
6569
+ }
6570
+ )
6571
+ ]
6572
+ }
6573
+ );
6574
+ }
6575
+
6576
+ // src/graph/hooks/useGraphActions.ts
6577
+ var useGraphActions = (initialNodes = [], initialEdges = []) => {
6578
+ const [nodes, setNodes] = useState12(initialNodes);
6579
+ const [edges, setEdges] = useState12(initialEdges);
6580
+ const addNodes = useCallback9((newNodes) => {
6581
+ setNodes((prevNodes) => {
6582
+ const existingIds = new Set(prevNodes.map((node) => node.id));
6583
+ const uniqueNewNodes = newNodes.filter((node) => !existingIds.has(node.id));
6584
+ return [...prevNodes, ...uniqueNewNodes];
6585
+ });
6586
+ }, []);
6587
+ const addEdges = useCallback9((newEdges) => {
6588
+ setEdges((prevEdges) => {
6589
+ const existingIds = new Set(prevEdges.map((edge) => edge.id));
6590
+ const uniqueNewEdges = newEdges.filter((edge) => !existingIds.has(edge.id));
6591
+ return [...prevEdges, ...uniqueNewEdges];
6592
+ });
6593
+ }, []);
6594
+ const removeNodes = useCallback9((nodeIds) => {
6595
+ const nodeIdSet = new Set(nodeIds);
6596
+ setNodes((prevNodes) => prevNodes.filter((node) => !nodeIdSet.has(node.id)));
6597
+ setEdges((prevEdges) => prevEdges.filter((edge) => !nodeIdSet.has(edge.source) && !nodeIdSet.has(edge.target)));
6598
+ }, []);
6599
+ const removeEdges = useCallback9((edgeIds) => {
6600
+ const edgeIdSet = new Set(edgeIds);
6601
+ setEdges((prevEdges) => prevEdges.filter((edge) => !edgeIdSet.has(edge.id)));
6602
+ }, []);
6603
+ const resetGraph = useCallback9(() => {
6604
+ setNodes(initialNodes);
6605
+ setEdges(initialEdges);
6606
+ }, [initialNodes, initialEdges]);
6607
+ const updateNode = useCallback9((nodeId, node) => {
6608
+ setNodes((prevNodes) => prevNodes.map((n) => n.id === nodeId ? node : n));
6609
+ }, []);
6610
+ const toggleNodeExpansion = useCallback9((nodeId) => {
6611
+ setNodes(
6612
+ (prevNodes) => prevNodes.map((node) => {
6613
+ if (node.id === nodeId && isDefaultNode(node)) {
6614
+ return __spreadProps(__spreadValues({}, node), {
6615
+ data: __spreadProps(__spreadValues({}, node.data), {
6616
+ expanded: !node.data.expanded
6617
+ })
6618
+ });
6619
+ }
6620
+ return node;
6621
+ })
6622
+ );
6623
+ }, []);
6624
+ return {
6625
+ nodes,
6626
+ edges,
6627
+ addNodes,
6628
+ addEdges,
6629
+ removeNodes,
6630
+ removeEdges,
6631
+ setNodes,
6632
+ setEdges,
6633
+ resetGraph,
6634
+ updateNode,
6635
+ toggleNodeExpansion
6636
+ };
6637
+ };
6638
+
6639
+ // src/graph/graph-actions-provider.tsx
6640
+ import { jsx as jsx21 } from "react/jsx-runtime";
6641
+ var GraphActionsProvider = React14.forwardRef(
6642
+ ({ initialNodes = [], initialEdges = [], children }, ref) => {
6643
+ const graphActions = useGraphActions(initialNodes, initialEdges);
6644
+ React14.useImperativeHandle(
6645
+ ref,
6646
+ () => ({
6647
+ addNodes: graphActions.addNodes,
6648
+ addEdges: graphActions.addEdges,
6649
+ setNodes: graphActions.setNodes,
6650
+ setEdges: graphActions.setEdges,
6651
+ toggleNodeExpansion: graphActions.toggleNodeExpansion,
6652
+ updateNode: graphActions.updateNode,
6653
+ reset: graphActions.resetGraph
6654
+ }),
6655
+ [graphActions]
6656
+ );
6657
+ return /* @__PURE__ */ jsx21(GraphActionsContext.Provider, { value: graphActions, children });
6658
+ }
6659
+ );
6660
+ GraphActionsProvider.displayName = "GraphActionsProvider";
6661
+
6662
+ // src/graph/graph.tsx
6663
+ import * as React16 from "react";
6664
+ import {
6665
+ getCoreRowModel as getCoreRowModel2,
6666
+ getFacetedRowModel as getFacetedRowModel2,
6667
+ getFacetedUniqueValues as getFacetedUniqueValues2,
6668
+ getFilteredRowModel as getFilteredRowModel2,
6669
+ useReactTable as useReactTable2
6670
+ } from "@tanstack/react-table";
6671
+ import { Icon as Icon14, InputGroup as InputGroup4, InputGroupAddon as InputGroupAddon4, InputGroupInput as InputGroupInput3 } from "@upbound/monarch-core";
6672
+
6673
+ // src/graph/graph-view.tsx
6674
+ import * as React15 from "react";
6675
+ import {
6676
+ Background,
6677
+ Controls,
6678
+ MiniMap,
6679
+ ReactFlow,
6680
+ ReactFlowProvider,
6681
+ useReactFlow
6682
+ } from "reactflow";
6683
+
6684
+ // src/graph/hooks/useAutoLayout.ts
6685
+ import { useMemo as useMemo10 } from "react";
6686
+ import { Position as Position3 } from "reactflow";
6687
+ var TILE_HORIZONTAL_DISTANCE = GRAPH_RANK_SEP;
6688
+ var TILE_VERTICAL_DISTANCE = GRAPH_NODE_SEP;
6689
+ var TILE_HEIGHT = GRAPH_NODE_HEIGHT;
6690
+ var TILE_WIDTH = GRAPH_NODE_WIDTH;
6691
+ var getNodeDepth = (nodeId, edges, visited = /* @__PURE__ */ new Set(), maxDepth = 100) => {
6692
+ if (visited.has(nodeId)) {
6693
+ console.warn(`Cycle detected in graph at node: ${nodeId}. Returning depth 0 to prevent infinite recursion.`);
6694
+ return 0;
6695
+ }
6696
+ if (visited.size >= maxDepth) {
6697
+ console.warn(`Maximum depth limit (${maxDepth}) reached for node: ${nodeId}.`);
6698
+ return visited.size;
6699
+ }
6700
+ const parentEdge = edges.find((edge) => edge.target === nodeId);
6701
+ if (!parentEdge) {
6702
+ return 0;
6703
+ }
6704
+ const newVisited = /* @__PURE__ */ new Set([...visited, nodeId]);
6705
+ return 1 + getNodeDepth(parentEdge.source, edges, newVisited, maxDepth);
6706
+ };
6707
+ var flatNodeTree = (nodeTree) => {
6708
+ const { node, children } = nodeTree;
6709
+ if (!children) {
6710
+ return [node];
6711
+ }
6712
+ return [node, ...children.flatMap(flatNodeTree)];
6713
+ };
6714
+ var getChildren = (nodeId, nodes, edges) => {
6715
+ const nodeEdges = edges.filter((edge) => edge.source === nodeId);
6716
+ return nodeEdges.map((edge) => nodes.find((node) => node.id === edge.target)).filter((node) => node !== void 0).map((node) => ({
6717
+ node,
6718
+ children: getChildren(node.id, nodes, edges)
6719
+ }));
6720
+ };
6721
+ var getTrees = (nodes, edges) => nodes.filter((node) => !edges.some((edge) => edge.target === node.id)).map((node) => ({
6722
+ node,
6723
+ children: getChildren(node.id, nodes, edges)
6724
+ }));
6725
+ var getLowestPositionYInSubtree = (nodeTree) => {
6726
+ const { node, children } = nodeTree;
6727
+ const lowestY = node.position.y;
6728
+ if (!(children == null ? void 0 : children.length)) {
6729
+ return lowestY;
6730
+ }
6731
+ const visibleChildren = children.filter(({ node: { hidden } }) => !hidden);
6732
+ if (visibleChildren.length === 0) {
6733
+ return lowestY;
6734
+ }
6735
+ const childLowestYPositions = visibleChildren.map((child) => getLowestPositionYInSubtree(child));
6736
+ const lowestChildY = Math.max(...childLowestYPositions);
6737
+ return Math.max(lowestY, lowestChildY);
6738
+ };
6739
+ var positionNodes = (treeNodes, rootFlattenTree, allEdges, parentY) => {
6740
+ const flattenTree = rootFlattenTree || treeNodes.flatMap(flatNodeTree);
6741
+ return treeNodes.reduce((actualTreeNodes, nodeTree, treeNodeIndex) => {
6742
+ const { node, children } = nodeTree;
6743
+ const depth = allEdges ? getNodeDepth(node.id, allEdges) : 0;
6744
+ const getPositionY = () => {
6745
+ if (treeNodeIndex > 0) {
6746
+ const previousSibling = actualTreeNodes[treeNodeIndex - 1];
6747
+ const lowestYInPreviousSubtree = getLowestPositionYInSubtree(previousSibling);
6748
+ return lowestYInPreviousSubtree + TILE_HEIGHT + TILE_VERTICAL_DISTANCE;
6749
+ }
6750
+ if (parentY !== void 0) {
6751
+ return parentY;
6752
+ }
6753
+ return (TILE_HEIGHT + TILE_VERTICAL_DISTANCE) * treeNodeIndex;
6754
+ };
6755
+ const position = {
6756
+ x: depth * (TILE_WIDTH + TILE_HORIZONTAL_DISTANCE),
6757
+ y: getPositionY()
6758
+ };
6759
+ const positionedNode = __spreadProps(__spreadValues({}, node), {
6760
+ targetPosition: Position3.Left,
6761
+ sourcePosition: Position3.Right,
6762
+ position
6763
+ });
6764
+ if (!(children == null ? void 0 : children.length)) {
6765
+ return [
6766
+ ...actualTreeNodes,
6767
+ __spreadProps(__spreadValues({}, nodeTree), {
6768
+ node: positionedNode
6769
+ })
6770
+ ];
6771
+ }
6772
+ const nodeWithChildren = __spreadProps(__spreadValues({}, nodeTree), {
6773
+ node: positionedNode,
6774
+ children: positionNodes(
6775
+ children.sort((a, b) => {
6776
+ return a.node.id.localeCompare(b.node.id);
6777
+ }),
6778
+ flattenTree,
6779
+ allEdges,
6780
+ position.y
6781
+ // Pass parent's Y position to children
6782
+ )
6783
+ });
6784
+ return [...actualTreeNodes, nodeWithChildren];
6785
+ }, []);
6786
+ };
6787
+ var getLaidOutElements = (nodes, edges) => {
6788
+ const nodeTrees = getTrees(nodes, edges);
6789
+ const positionedNodes = positionNodes(nodeTrees, void 0, edges).flatMap(flatNodeTree);
6790
+ return { nodes: positionedNodes, edges };
6791
+ };
6792
+ var useAutoLayout = (nodes, edges, { viewportFocusNodeId }) => {
6793
+ const laidOutElements = useMemo10(() => {
6794
+ if (nodes.length === 0) {
6795
+ return { nodes, edges, nodeMap: /* @__PURE__ */ new Map() };
6796
+ }
6797
+ const visibleNodes = nodes.filter((node) => !node.hidden);
6798
+ const visibleNodeIds = new Set(visibleNodes.map((node) => node.id));
6799
+ const visibleEdges = edges.filter((edge) => visibleNodeIds.has(edge.source) && visibleNodeIds.has(edge.target));
6800
+ const { nodes: laidOutNodes, edges: laidOutEdges } = getLaidOutElements(visibleNodes, visibleEdges);
6801
+ const laidOutNodeMap = new Map(laidOutNodes.map((node) => [node.id, node]));
6802
+ if (viewportFocusNodeId) {
6803
+ const highlightedNode = laidOutNodeMap.get(viewportFocusNodeId);
6804
+ if (highlightedNode) {
6805
+ laidOutNodeMap.set(viewportFocusNodeId, __spreadProps(__spreadValues({}, highlightedNode), {
6806
+ data: __spreadProps(__spreadValues({}, highlightedNode.data), { isHighlighted: true })
6807
+ }));
6808
+ }
6809
+ }
6810
+ const finalNodes = nodes.filter((node) => !node.hidden).map((node) => laidOutNodeMap.get(node.id) || node);
6811
+ return {
6812
+ nodes: finalNodes,
6813
+ edges: laidOutEdges,
6814
+ nodeMap: laidOutNodeMap
6815
+ };
6816
+ }, [nodes, edges, viewportFocusNodeId]);
6817
+ return laidOutElements;
6818
+ };
6819
+
6820
+ // src/graph/hooks/useNodeVisibility.ts
6821
+ import { useCallback as useCallback10, useMemo as useMemo11 } from "react";
6822
+ var useNodeVisibility = (nodes, edges) => {
6823
+ const hasRealChildren = useCallback10(
6824
+ (nodeId) => {
6825
+ const childEdges = edges.filter((edge) => edge.source === nodeId);
6826
+ const childNodes = childEdges.map((edge) => nodes.find((node) => node.id === edge.target)).filter(Boolean);
6827
+ return childNodes.some((child) => child && child.type !== "loading");
6828
+ },
6829
+ [nodes, edges]
6830
+ );
6831
+ const areAllAncestorsExpanded = useCallback10(
6832
+ (nodeId) => {
6833
+ const parentEdges = edges.filter((edge) => edge.target === nodeId);
6834
+ if (parentEdges.length === 0) {
6835
+ return true;
6836
+ }
6837
+ for (const parentEdge of parentEdges) {
6838
+ const parentNode = nodes.find((node) => node.id === parentEdge.source);
6839
+ if (!parentNode) {
6840
+ return false;
6841
+ }
6842
+ const isParentExpanded = isDefaultNode(parentNode) ? Boolean(parentNode.data.expanded) : true;
6843
+ if (!isParentExpanded) {
6844
+ return false;
6845
+ }
6846
+ }
6847
+ return parentEdges.every((parentEdge) => areAllAncestorsExpanded(parentEdge.source));
6848
+ },
6849
+ [nodes, edges]
6850
+ );
6851
+ const visibleNodes = useMemo11(() => {
6852
+ return nodes.map((node) => {
6853
+ const shouldBeVisible = areAllAncestorsExpanded(node.id);
6854
+ if (node.type === "loading") {
6855
+ const loadingNode = {
6856
+ id: node.id,
6857
+ position: node.position,
6858
+ type: "loading",
6859
+ hidden: !shouldBeVisible,
6860
+ data: node.data
6861
+ };
6862
+ return loadingNode;
6863
+ }
6864
+ if (isDefaultNode(node)) {
6865
+ const expandedNode = {
6866
+ id: node.id,
6867
+ position: node.position,
6868
+ type: node.type,
6869
+ hidden: !shouldBeVisible,
6870
+ data: __spreadProps(__spreadValues({}, node.data), {
6871
+ expanded: Boolean(node.data.expanded),
6872
+ isExpandable: hasRealChildren(node.id)
6873
+ // onExpandToggle will be added later in GraphView
6874
+ })
6875
+ };
6876
+ return expandedNode;
6877
+ }
6878
+ return node;
6879
+ });
6880
+ }, [nodes, areAllAncestorsExpanded, hasRealChildren]);
6881
+ const visibleEdges = useMemo11(() => {
6882
+ const visibleNodeIds = new Set(visibleNodes.filter((node) => !node.hidden).map((node) => node.id));
6883
+ return edges.filter((edge) => visibleNodeIds.has(edge.source) && visibleNodeIds.has(edge.target));
6884
+ }, [visibleNodes, edges]);
6885
+ return { nodes: visibleNodes, edges: visibleEdges };
6886
+ };
6887
+
6888
+ // src/graph/graph-view.tsx
6889
+ import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
6890
+ var GraphViewInternal = ({ nodeTypes: parentNodeTypes, edgeTypes: parentEdgeTypes, children, viewportFocusNodeId }) => {
6891
+ const { nodes, edges, toggleNodeExpansion } = useGraphActionsContext();
6892
+ const nodeTypes = React15.useMemo(
6893
+ () => __spreadValues({
6894
+ default: GraphNode,
6895
+ loading: GraphNodeSkeleton
6896
+ }, parentNodeTypes),
6897
+ [parentNodeTypes]
6898
+ );
6899
+ const edgeTypes = React15.useMemo(
6900
+ () => __spreadValues({
6901
+ default: GraphEdge
6902
+ }, parentEdgeTypes),
6903
+ [parentEdgeTypes]
6904
+ );
6905
+ const { nodes: visibleNodes, edges: visibleEdges } = useNodeVisibility(nodes, edges);
6906
+ const nodesWithExpansion = React15.useMemo(() => {
6907
+ return visibleNodes.map((node) => {
6908
+ if (isDefaultNode(node) && !node.data.onExpandToggle) {
6909
+ return __spreadProps(__spreadValues({}, node), {
6910
+ data: __spreadProps(__spreadValues({}, node.data), {
6911
+ onExpandToggle: toggleNodeExpansion
6912
+ })
6913
+ });
6914
+ }
6915
+ return node;
6916
+ });
6917
+ }, [visibleNodes, toggleNodeExpansion]);
6918
+ const {
6919
+ nodes: layoutedNodes,
6920
+ edges: layoutedEdges,
6921
+ nodeMap
6922
+ } = useAutoLayout(nodesWithExpansion, visibleEdges, {
6923
+ viewportFocusNodeId
6924
+ });
6925
+ useViewportFocus(nodeMap, viewportFocusNodeId);
6926
+ return /* @__PURE__ */ jsxs17(
6927
+ ReactFlow,
6928
+ {
6929
+ nodeTypes,
6930
+ edgeTypes,
6931
+ nodes: layoutedNodes,
6932
+ edges: layoutedEdges,
6933
+ nodesConnectable: false,
6934
+ nodesDraggable: false,
6935
+ fitView: viewportFocusNodeId ? false : true,
6936
+ fitViewOptions: {
6937
+ maxZoom: 1
6938
+ },
6939
+ proOptions: {
6940
+ hideAttribution: true
6941
+ },
6942
+ panOnScroll: true,
6943
+ selectionOnDrag: true,
6944
+ children: [
6945
+ /* @__PURE__ */ jsx22(Background, { className: "bg-muted text-muted" }),
6946
+ /* @__PURE__ */ jsx22(Controls, { showInteractive: false }),
6947
+ /* @__PURE__ */ jsx22(MiniMap, { zoomable: true, pannable: true }),
6948
+ children
6120
6949
  ]
6121
6950
  }
6122
6951
  );
6952
+ };
6953
+ var GraphView = React15.forwardRef(({ defaultNodes = [], defaultEdges = [], nodeTypes, edgeTypes, children, viewportFocusNodeId }, ref) => {
6954
+ return /* @__PURE__ */ jsx22(ReactFlowProvider, { children: /* @__PURE__ */ jsx22(GraphActionsProvider, { ref, initialNodes: defaultNodes, initialEdges: defaultEdges, children: /* @__PURE__ */ jsx22(GraphViewInternal, { nodeTypes, edgeTypes, viewportFocusNodeId, children }) }) });
6955
+ });
6956
+ GraphView.displayName = "GraphView";
6957
+ function useViewportFocus(nodeMap, viewportFocusNodeId) {
6958
+ const flow = useReactFlow();
6959
+ React15.useEffect(() => {
6960
+ if (viewportFocusNodeId) {
6961
+ const focusNode = nodeMap.get(viewportFocusNodeId);
6962
+ if (focusNode) {
6963
+ flow.setCenter(focusNode.position.x, focusNode.position.y, { zoom: 1 });
6964
+ }
6965
+ }
6966
+ }, [viewportFocusNodeId, flow, nodeMap]);
6123
6967
  }
6124
6968
 
6969
+ // src/graph/graph.tsx
6970
+ import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
6971
+ var defaultGraphErrorConfig = {
6972
+ icon: "triangle-exclamation",
6973
+ header: "An error occurred",
6974
+ subheader: "There was an error fetching the data for this graph. Please refresh the screen."
6975
+ };
6976
+ var defaultGraphEmptyConfig = {
6977
+ icon: "layer-group",
6978
+ header: "No resources found",
6979
+ subheader: "We couldn't find any resources to display in this graph. If you need help getting started you can learn more in the Upbound Documentation."
6980
+ };
6981
+ var defaultGraphNoFilterFoundConfig = {
6982
+ icon: "magnifying-glass",
6983
+ header: "No results found",
6984
+ subheader: "We couldn't find any results that match your search term or filtering criteria. Try using different keywords, checking for typos or adjusting your filters and try again."
6985
+ };
6986
+ function Graph({
6987
+ id,
6988
+ viewportFocusNodeId,
6989
+ config,
6990
+ columnDefinitions = [],
6991
+ title,
6992
+ emptyView,
6993
+ showError,
6994
+ className,
6995
+ loading = false,
6996
+ ActionsComponent: Actions,
6997
+ disableSearch = false,
6998
+ disableFilters = false,
6999
+ searchTerm: parentGlobalFilter,
7000
+ onSearchTermChange: parentSetGlobalFilter,
7001
+ filters: parentColumnFilters,
7002
+ onFiltersChange: parentSetColumnFilters,
7003
+ children
7004
+ }) {
7005
+ var _a, _b, _c;
7006
+ const graphRef = React16.useRef(null);
7007
+ const [innerGlobalFilter, setInnerGlobalFilter] = React16.useState("");
7008
+ const [innerColumnFilters, setInnerColumnFilters] = React16.useState([]);
7009
+ const globalFilter = parentGlobalFilter != null ? parentGlobalFilter : innerGlobalFilter;
7010
+ const setGlobalFilter = parentSetGlobalFilter != null ? parentSetGlobalFilter : setInnerGlobalFilter;
7011
+ React16.useEffect(() => {
7012
+ if (parentGlobalFilter !== void 0) {
7013
+ setInnerGlobalFilter(parentGlobalFilter);
7014
+ }
7015
+ }, [parentGlobalFilter]);
7016
+ const columnFilters = parentColumnFilters != null ? parentColumnFilters : innerColumnFilters;
7017
+ const setColumnFilters = parentSetColumnFilters != null ? parentSetColumnFilters : setInnerColumnFilters;
7018
+ const table = useReactTable2({
7019
+ data: config.data,
7020
+ columns: columnDefinitions,
7021
+ getCoreRowModel: getCoreRowModel2(),
7022
+ getFilteredRowModel: getFilteredRowModel2(),
7023
+ getFacetedRowModel: getFacetedRowModel2(),
7024
+ getFacetedUniqueValues: getFacetedUniqueValues2(),
7025
+ state: { columnFilters, globalFilter },
7026
+ onColumnFiltersChange: setColumnFilters,
7027
+ onGlobalFilterChange: setGlobalFilter,
7028
+ manualFiltering: false
7029
+ });
7030
+ const flatColumns = table.getAllFlatColumns();
7031
+ const filteredRows = table.getFilteredRowModel().rows;
7032
+ const filteredData = React16.useMemo(() => filteredRows.map((row) => row.original), [filteredRows]);
7033
+ const filterCount = columnFilters.map(
7034
+ ({ id: columnFilterId, value }) => {
7035
+ var _a2, _b2;
7036
+ return getColumnFilterCount(value, (_b2 = (_a2 = table.getColumn(columnFilterId)) == null ? void 0 : _a2.columnDef.meta) == null ? void 0 : _b2.filter);
7037
+ }
7038
+ ).reduce((prev, curr) => prev + curr, 0);
7039
+ const graphState = getTableState({ error: !!showError, loading, rowCount: filteredData.length });
7040
+ const shouldDisable = graphState === "error";
7041
+ const shouldRenderGraphContent = graphState !== "error" && graphState !== "empty";
7042
+ const resetFilters = () => {
7043
+ setColumnFilters([]);
7044
+ setGlobalFilter("");
7045
+ };
7046
+ const memoizedNodeTypes = React16.useMemo(() => config.nodeTypes, [config.nodeTypes]);
7047
+ const memoizedEdgeTypes = React16.useMemo(() => config.edgeTypes, [config.edgeTypes]);
7048
+ const memoizedConfig = React16.useMemo(() => config, [config]);
7049
+ React16.useEffect(() => {
7050
+ if (!graphRef.current) {
7051
+ return;
7052
+ }
7053
+ const { setNodes, setEdges } = graphRef.current;
7054
+ const nodes = filteredData.map((item) => memoizedConfig.nodeTransform(item, filteredData)).flat() || [];
7055
+ const nodeIds = new Set(nodes.map((node) => node.id));
7056
+ const edges = (filteredData.map(memoizedConfig.edgeTransform).filter(Boolean).flat() || []).filter(
7057
+ (edge) => Boolean(edge && edge.hasOwnProperty("source") && edge.hasOwnProperty("target")) && nodeIds.has(edge.source) && nodeIds.has(edge.target)
7058
+ );
7059
+ setNodes(nodes);
7060
+ setEdges(edges);
7061
+ }, [memoizedConfig, filteredData]);
7062
+ const showFilters = !disableFilters && hasFilterableColumns(flatColumns);
7063
+ const showToolbar = !disableSearch || !!Actions;
7064
+ const resolvedEmptyView = {
7065
+ error: (_a = emptyView == null ? void 0 : emptyView.error) != null ? _a : defaultGraphErrorConfig,
7066
+ empty: (_b = emptyView == null ? void 0 : emptyView.empty) != null ? _b : defaultGraphEmptyConfig,
7067
+ filter: (_c = emptyView == null ? void 0 : emptyView.filter) != null ? _c : defaultGraphNoFilterFoundConfig
7068
+ };
7069
+ return /* @__PURE__ */ jsxs18("div", { id: `graph-${id}`, className: cn("flex size-full flex-1 flex-col", className), children: [
7070
+ !!title && /* @__PURE__ */ jsx23(SectionHeader, { className: "mb-4", children: /* @__PURE__ */ jsx23(SectionHeaderContent, { children: /* @__PURE__ */ jsx23(SectionHeaderTitle, { children: title }) }) }),
7071
+ showToolbar && /* @__PURE__ */ jsxs18("div", { className: "mb-4 flex flex-row gap-2", children: [
7072
+ !disableSearch && /* @__PURE__ */ jsxs18(InputGroup4, { className: "w-70", children: [
7073
+ /* @__PURE__ */ jsx23(InputGroupAddon4, { align: "inline-start", children: /* @__PURE__ */ jsx23(Icon14, { name: "magnifying-glass" }) }),
7074
+ /* @__PURE__ */ jsx23(
7075
+ InputGroupInput3,
7076
+ {
7077
+ "aria-label": "Search",
7078
+ placeholder: "Search\u2026",
7079
+ disabled: shouldDisable,
7080
+ value: globalFilter,
7081
+ onChange: (e) => setGlobalFilter(e.target.value)
7082
+ }
7083
+ )
7084
+ ] }),
7085
+ !!Actions && /* @__PURE__ */ jsx23("div", { className: "ml-auto flex items-center gap-2", children: /* @__PURE__ */ jsx23(Actions, { state: graphState }) })
7086
+ ] }),
7087
+ showFilters && /* @__PURE__ */ jsx23(
7088
+ ViewFilter,
7089
+ {
7090
+ columns: flatColumns,
7091
+ columnFilters,
7092
+ onColumnFiltersChange: setColumnFilters,
7093
+ className: "mb-4"
7094
+ }
7095
+ ),
7096
+ shouldRenderGraphContent ? /* @__PURE__ */ jsxs18("div", { className: "relative size-full flex-1", children: [
7097
+ graphState === "loading" && /* @__PURE__ */ jsx23(Icon14, { name: "circle-notch", className: "absolute top-4 left-4 z-10 animate-spin" }),
7098
+ /* @__PURE__ */ jsx23(
7099
+ GraphView,
7100
+ {
7101
+ viewportFocusNodeId,
7102
+ ref: graphRef,
7103
+ nodeTypes: memoizedNodeTypes,
7104
+ edgeTypes: memoizedEdgeTypes,
7105
+ children
7106
+ }
7107
+ )
7108
+ ] }) : /* @__PURE__ */ jsx23(
7109
+ DataTableEmptyView,
7110
+ {
7111
+ emptyView: resolvedEmptyView,
7112
+ tableState: graphState,
7113
+ filterCount: filterCount + (!!globalFilter.trim() ? 1 : 0),
7114
+ resetFilters
7115
+ }
7116
+ )
7117
+ ] });
7118
+ }
7119
+
7120
+ // src/graph/hooks/useGetViewportNodeIds.ts
7121
+ import { useEffect as useEffect9, useMemo as useMemo14, useRef as useRef9, useState as useState14 } from "react";
7122
+ import { useStore, useViewport } from "reactflow";
7123
+ var useGetDebouncedViewport = (debounceDelay = 1e3) => {
7124
+ const timerRef = useRef9(null);
7125
+ const [debouncedValues, setDebouncedValues] = useState14({ x: 0, y: 0, zoom: 1, width: 0, height: 0, nodes: [] });
7126
+ const { x, y, zoom } = useViewport();
7127
+ const { width, height, nodes } = useStore((state) => ({
7128
+ width: state.width,
7129
+ height: state.height,
7130
+ nodes: state.getNodes()
7131
+ }));
7132
+ const nodesHash = nodes.map((n) => n.id).sort().join(",");
7133
+ const memoizedNodes = useMemo14(() => nodes, [nodesHash]);
7134
+ useEffect9(() => {
7135
+ if (timerRef.current) {
7136
+ clearTimeout(timerRef.current);
7137
+ }
7138
+ timerRef.current = setTimeout(() => {
7139
+ setDebouncedValues({ x, y, zoom, width, height, nodes: memoizedNodes });
7140
+ timerRef.current = null;
7141
+ }, debounceDelay);
7142
+ return () => {
7143
+ if (timerRef.current) {
7144
+ clearTimeout(timerRef.current);
7145
+ timerRef.current = null;
7146
+ }
7147
+ };
7148
+ }, [x, y, zoom, width, height, memoizedNodes, debounceDelay]);
7149
+ return debouncedValues;
7150
+ };
7151
+ var useGetViewportNodeIds = (debounceDelay = 1e3) => {
7152
+ const { x, y, zoom, width, height, nodes } = useGetDebouncedViewport(debounceDelay);
7153
+ return useMemo14(() => {
7154
+ return nodes.filter((node) => {
7155
+ var _a, _b, _c, _d;
7156
+ if (node.hidden) {
7157
+ return false;
7158
+ }
7159
+ const nodeX = ((_b = (_a = node.positionAbsolute) == null ? void 0 : _a.x) != null ? _b : node.position.x) * zoom + x;
7160
+ const nodeY = ((_d = (_c = node.positionAbsolute) == null ? void 0 : _c.y) != null ? _d : node.position.y) * zoom + y;
7161
+ const nodeW = GRAPH_NODE_WIDTH * zoom;
7162
+ const nodeH = GRAPH_NODE_HEIGHT * zoom;
7163
+ return nodeX + nodeW >= 0 && nodeX <= width && nodeY + nodeH >= 0 && nodeY <= height;
7164
+ }).map((node) => node.id).sort((a, b) => a.localeCompare(b));
7165
+ }, [x, y, zoom, width, height, nodes]);
7166
+ };
7167
+
7168
+ // src/graph/utils.ts
7169
+ import { getOutgoers as getOutgoers2 } from "reactflow";
7170
+ var getGraphDescendants = (node, nodes, edges) => {
7171
+ const outgoers = getOutgoers2(node, nodes, edges);
7172
+ return outgoers.reduce(
7173
+ (acc, outgoer) => {
7174
+ const { nodes: outgoerNodes, edges: outgoerEdges } = getGraphDescendants(outgoer, nodes, edges);
7175
+ return {
7176
+ nodes: [...acc.nodes, ...outgoerNodes],
7177
+ edges: [...acc.edges, ...outgoerEdges.filter((edge) => edge.source === outgoer.id)]
7178
+ };
7179
+ },
7180
+ { nodes: [node], edges: edges.filter((edge) => edge.source === node.id) }
7181
+ );
7182
+ };
7183
+
6125
7184
  // src/page-header.tsx
6126
- import { jsx as jsx18 } from "react/jsx-runtime";
7185
+ import { jsx as jsx24 } from "react/jsx-runtime";
6127
7186
  function PageHeader(_a) {
6128
7187
  var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
6129
- return /* @__PURE__ */ jsx18("div", __spreadProps(__spreadValues({ "data-slot": "page-header", className: cn("flex w-full items-start justify-between gap-4", className) }, props), { children }));
7188
+ return /* @__PURE__ */ jsx24("div", __spreadProps(__spreadValues({ "data-slot": "page-header", className: cn("flex w-full items-start justify-between gap-4", className) }, props), { children }));
6130
7189
  }
6131
7190
  function PageHeaderAvatar(_a) {
6132
7191
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
6133
- return /* @__PURE__ */ jsx18("div", __spreadValues({ "data-slot": "page-header-avatar", className: cn("shrink-0 self-center", className) }, props));
7192
+ return /* @__PURE__ */ jsx24("div", __spreadValues({ "data-slot": "page-header-avatar", className: cn("shrink-0 self-center", className) }, props));
6134
7193
  }
6135
7194
  function PageHeaderContent(_a) {
6136
7195
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
6137
- return /* @__PURE__ */ jsx18("div", __spreadValues({ "data-slot": "page-header-content", className: cn("flex flex-1 flex-col gap-1", className) }, props));
7196
+ return /* @__PURE__ */ jsx24("div", __spreadValues({ "data-slot": "page-header-content", className: cn("flex flex-1 flex-col gap-1", className) }, props));
6138
7197
  }
6139
7198
  function PageHeaderTitle(_a) {
6140
7199
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
6141
- return /* @__PURE__ */ jsx18("h1", __spreadValues({ "data-slot": "page-header-title", className: cn("text-h1 text-foreground", className) }, props));
7200
+ return /* @__PURE__ */ jsx24("h1", __spreadValues({ "data-slot": "page-header-title", className: cn("text-h1 text-foreground", className) }, props));
6142
7201
  }
6143
7202
  function PageHeaderDescription(_a) {
6144
7203
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
6145
- return /* @__PURE__ */ jsx18("p", __spreadValues({ "data-slot": "page-header-description", className: cn("text-body text-muted-foreground", className) }, props));
7204
+ return /* @__PURE__ */ jsx24("p", __spreadValues({ "data-slot": "page-header-description", className: cn("text-body text-muted-foreground", className) }, props));
6146
7205
  }
6147
7206
  function PageHeaderMeta(_a) {
6148
7207
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
6149
- return /* @__PURE__ */ jsx18(
7208
+ return /* @__PURE__ */ jsx24(
6150
7209
  "div",
6151
7210
  __spreadValues({
6152
7211
  "data-slot": "page-header-meta",
@@ -6160,27 +7219,27 @@ function PageHeaderMeta(_a) {
6160
7219
  }
6161
7220
  function PageHeaderActions(_a) {
6162
7221
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
6163
- return /* @__PURE__ */ jsx18("div", __spreadValues({ "data-slot": "page-header-actions", className: cn("flex items-center gap-2", className) }, props));
7222
+ return /* @__PURE__ */ jsx24("div", __spreadValues({ "data-slot": "page-header-actions", className: cn("flex items-center gap-2", className) }, props));
6164
7223
  }
6165
7224
  function PageHeaderTabs(_a) {
6166
7225
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
6167
- return /* @__PURE__ */ jsx18("div", __spreadValues({ "data-slot": "page-header-tabs", className: cn("border-b", className) }, props));
7226
+ return /* @__PURE__ */ jsx24("div", __spreadValues({ "data-slot": "page-header-tabs", className: cn("border-b", className) }, props));
6168
7227
  }
6169
7228
 
6170
7229
  // src/timeline.tsx
6171
- import { Icon as Icon12 } from "@upbound/monarch-core";
7230
+ import { Icon as Icon15 } from "@upbound/monarch-core";
6172
7231
  import { Item as Item2, ItemGroup as ItemGroup2 } from "@upbound/monarch-core";
6173
- import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
7232
+ import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
6174
7233
  function Timeline(_a) {
6175
7234
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
6176
- return /* @__PURE__ */ jsx19(ItemGroup2, __spreadValues({ "data-slot": "timeline", className: cn(className) }, props));
7235
+ return /* @__PURE__ */ jsx25(ItemGroup2, __spreadValues({ "data-slot": "timeline", className: cn(className) }, props));
6177
7236
  }
6178
7237
  function TimelineItem(_a) {
6179
7238
  var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
6180
- return /* @__PURE__ */ jsxs14(Item2, __spreadProps(__spreadValues({ "data-slot": "timeline-item", className: cn("group/timeline-item gap-3 py-4", className) }, props), { children: [
6181
- /* @__PURE__ */ jsxs14("div", { className: "relative flex flex-col items-center self-stretch", children: [
6182
- /* @__PURE__ */ jsx19(Icon12, { name: "circle-dot", size: "sm", className: "text-primary shrink-0" }),
6183
- /* @__PURE__ */ jsx19(
7239
+ return /* @__PURE__ */ jsxs19(Item2, __spreadProps(__spreadValues({ "data-slot": "timeline-item", className: cn("group/timeline-item gap-3 py-4", className) }, props), { children: [
7240
+ /* @__PURE__ */ jsxs19("div", { className: "relative flex flex-col items-center self-stretch", children: [
7241
+ /* @__PURE__ */ jsx25(Icon15, { name: "circle-dot", size: "sm", className: "text-primary shrink-0" }),
7242
+ /* @__PURE__ */ jsx25(
6184
7243
  "span",
6185
7244
  {
6186
7245
  "aria-hidden": "true",
@@ -6236,6 +7295,12 @@ export {
6236
7295
  FilterChip,
6237
7296
  FloatingWidget,
6238
7297
  FloatingWidgetProvider,
7298
+ Graph,
7299
+ GraphActionsProvider,
7300
+ GraphEdge,
7301
+ GraphNode,
7302
+ GraphNodeSkeleton,
7303
+ GraphView,
6239
7304
  PageHeader,
6240
7305
  PageHeaderActions,
6241
7306
  PageHeaderAvatar,
@@ -6281,6 +7346,9 @@ export {
6281
7346
  dateBoundaryForOperator,
6282
7347
  defaultEmptyConfig,
6283
7348
  defaultErrorConfig,
7349
+ defaultGraphEmptyConfig,
7350
+ defaultGraphErrorConfig,
7351
+ defaultGraphNoFilterFoundConfig,
6284
7352
  defaultNoFilterFoundConfig,
6285
7353
  denormalizeColumnIdWithReservedNames,
6286
7354
  denormalizeColumnsWithReservedNames,
@@ -6292,6 +7360,7 @@ export {
6292
7360
  getColumnEmitOn,
6293
7361
  getDefaultOperator,
6294
7362
  getExpandColumnDefinition,
7363
+ getGraphDescendants,
6295
7364
  getOperatorLabel,
6296
7365
  getQuantifierLabel,
6297
7366
  isCelFilterCondition,
@@ -6301,6 +7370,7 @@ export {
6301
7370
  isDateRangeOperator,
6302
7371
  isDateRelativeOperator,
6303
7372
  isDateWindowOperator,
7373
+ isDefaultNode,
6304
7374
  isEndOfDayTimestamp,
6305
7375
  isEndOfMinuteTimestamp,
6306
7376
  isMapKeyCelValue,
@@ -6324,7 +7394,12 @@ export {
6324
7394
  resolveFilterShape,
6325
7395
  startInstantFromEndOfDay,
6326
7396
  startInstantFromEndOfMinute,
7397
+ useAutoLayout,
6327
7398
  useFloatingWidget,
7399
+ useGetViewportNodeIds,
7400
+ useGraphActions,
7401
+ useGraphActionsContext,
7402
+ useNodeVisibility,
6328
7403
  validateCondition,
6329
7404
  withTimeOfDay
6330
7405
  };