@tensor_1/react 2.49.0 → 2.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -633,8 +633,9 @@ function toggleSort(keys, field, additive = false) {
633
633
  const existing = keys.find((k) => k.field === field);
634
634
  const dir = nextSortDir(existing?.dir);
635
635
  if (!additive) return dir === "none" ? [] : [{ field, dir }];
636
- const rest = keys.filter((k) => k.field !== field);
637
- return dir === "none" ? rest : [...rest, { field, dir }];
636
+ if (dir === "none") return keys.filter((k) => k.field !== field);
637
+ if (!existing) return [...keys, { field, dir }];
638
+ return keys.map((k) => k.field === field ? { field, dir } : k);
638
639
  }
639
640
  function asNum(v) {
640
641
  return typeof v === "number" ? v : Number(v);
@@ -4007,6 +4008,7 @@ function SearchBar({
4007
4008
  inputDescribedBy,
4008
4009
  labels: labelsProp,
4009
4010
  name,
4011
+ maxLength,
4010
4012
  inputId,
4011
4013
  inputRef,
4012
4014
  autoFocus,
@@ -4065,6 +4067,7 @@ function SearchBar({
4065
4067
  id: fieldId,
4066
4068
  type: "search",
4067
4069
  name,
4070
+ maxLength,
4068
4071
  className: "uix-input",
4069
4072
  value,
4070
4073
  placeholder,
@@ -6678,9 +6681,9 @@ var ConfirmDialog = (0, import_react42.forwardRef)(function ConfirmDialog2({
6678
6681
  role: "alertdialog",
6679
6682
  "aria-describedby": hasBody ? bodyId : void 0,
6680
6683
  footer: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
6681
- tertiaryLabel != null && onTertiary && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Button, { type: "button", className: "uix-confirm__tertiary", onClick: () => void onTertiary(), disabled: pending, children: tertiaryLabel }),
6682
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Button, { ref: cancelRef, type: "button", onClick: onCancel, disabled: pending, children: cancelLabel }),
6683
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Button, { ref: confirmRef, type: "button", variant: destructive ? "danger" : "primary", loading: pending, ...confirm, children: confirmLabel })
6684
+ tertiaryLabel != null && onTertiary && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Button, { type: "button", wrap: true, className: "uix-confirm__tertiary", onClick: () => void onTertiary(), disabled: pending, children: tertiaryLabel }),
6685
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Button, { ref: cancelRef, type: "button", wrap: true, onClick: onCancel, disabled: pending, children: cancelLabel }),
6686
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Button, { ref: confirmRef, type: "button", wrap: true, variant: destructive ? "danger" : "primary", loading: pending, ...confirm, children: confirmLabel })
6684
6687
  ] }),
6685
6688
  children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "uix-confirm", children: [
6686
6689
  hasBody && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { id: bodyId, className: "uix-confirm__body", children: [
@@ -6949,8 +6952,8 @@ function PromptDialog({
6949
6952
  ) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Input, { ...field, onChange: (event) => setValue(event.currentTarget.value) }),
6950
6953
  error != null && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { id: errorId, className: "uix-field__error", role: "alert", children: error }),
6951
6954
  /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "uix-dialog__footer uix-prompt__actions", children: [
6952
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Button, { type: "button", onClick: onCancel, disabled: pending, children: cancelLabel }),
6953
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Button, { type: "submit", variant: destructive ? "danger" : "primary", loading: pending, children: submitLabel })
6955
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Button, { type: "button", wrap: true, onClick: onCancel, disabled: pending, children: cancelLabel }),
6956
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Button, { type: "submit", wrap: true, variant: destructive ? "danger" : "primary", loading: pending, children: submitLabel })
6954
6957
  ] })
6955
6958
  ] })
6956
6959
  }
@@ -10929,17 +10932,25 @@ function Table({
10929
10932
  }
10930
10933
  );
10931
10934
  }
10932
- function Th({ sortable, sortDirection, sortOrder, onSort, className, children, onClick, ...props }) {
10935
+ function Th({ sortable, sortDirection, sortOrder, sortOrderLabel, onSort, className, children, onClick, ...props }) {
10936
+ const ordinal = sortOrder != null && sortOrder > 0 && sortOrderLabel ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "uix-visually-hidden", children: `, ${sortOrderLabel}` }) : null;
10933
10937
  return /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
10934
10938
  "th",
10935
10939
  {
10936
10940
  className,
10937
10941
  "data-sort": sortable || void 0,
10938
10942
  "data-sort-order": sortOrder != null && sortOrder > 0 ? sortOrder : void 0,
10943
+ "data-sort-labelled": ordinal != null || void 0,
10939
10944
  "aria-sort": sortDirection && sortDirection !== "none" ? sortDirection : void 0,
10940
10945
  onClick: sortable && onSort ? void 0 : onClick,
10941
10946
  ...props,
10942
- children: sortable ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", className: "uix-th__sortbtn", onClick: onSort, children }) : children
10947
+ children: sortable ? /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("button", { type: "button", className: "uix-th__sortbtn", onClick: onSort, children: [
10948
+ children,
10949
+ ordinal
10950
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(import_jsx_runtime76.Fragment, { children: [
10951
+ children,
10952
+ ordinal
10953
+ ] })
10943
10954
  }
10944
10955
  );
10945
10956
  }
@@ -14543,11 +14554,40 @@ var DEFAULT_DATA_WORKSPACE_LABELS = {
14543
14554
  filteredEmpty: "Nothing matches",
14544
14555
  filteredEmptyDetail: "Change the search or clear a filter.",
14545
14556
  error: "The list could not be loaded",
14546
- retry: "Try again"
14557
+ retry: "Try again",
14558
+ sortPriority: "Sort priority {n}",
14559
+ groupCount: "{count} rows",
14560
+ groupCountOne: "{count} row",
14561
+ collapseGroup: "Collapse group {name}",
14562
+ expandGroup: "Expand group {name}",
14563
+ selectGroup: "Select group {name}"
14547
14564
  };
14565
+ var useIsomorphicLayoutEffect22 = typeof document !== "undefined" ? import_react89.useLayoutEffect : import_react89.useEffect;
14548
14566
  var ArrowUpRight = () => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("svg", { className: "uix-id-cell__arrow", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("path", { d: "M7 17 17 7M8 7h9v9" }) });
14549
14567
  var PlusIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("path", { d: "M12 5v14M5 12h14" }) });
14550
14568
  var MaximizeIcon = ({ restore }) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("path", { d: restore ? "M4 14h6v6M20 10h-6V4M14 10l7-7M3 21l7-7" : "M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" }) });
14569
+ var ChevronIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("path", { d: "M6 4l4 4-4 4" }) });
14570
+ var LADDER_CARDS = 768;
14571
+ var LADDER_LOW = 900;
14572
+ var LADDER_MID = 600;
14573
+ var ladderFor = (mobile, width) => {
14574
+ if (!mobile || !(width > 0)) return null;
14575
+ if (mobile === "cards" && width < LADDER_CARDS) return "cards";
14576
+ if (width < LADDER_MID) return "priority-mid";
14577
+ if (width < LADDER_LOW) return "priority";
14578
+ return null;
14579
+ };
14580
+ var hiddenBy = (ladder, priority) => ladder === "priority" && priority === "low" || ladder === "priority-mid" && (priority === "low" || priority === "mid");
14581
+ var ROW_HEIGHT = { compact: 44, standard: 56, comfortable: 68 };
14582
+ var CONTROLS = 'a, button, input, select, textarea, label, summary, dialog, [role="button"], [role="menuitem"], [contenteditable="true"], [popover], td.uix-table__selcell, td.uix-table__actions';
14583
+ var RESERVED_COLS = /* @__PURE__ */ new Set(["select", "id", "actions", "expand"]);
14584
+ var textOf2 = (node) => typeof node === "string" ? node : void 0;
14585
+ var columnLabel = (column) => column.label ?? textOf2(column.header);
14586
+ var ladderAttrs = (on, column, body) => on ? {
14587
+ "data-col": RESERVED_COLS.has(column.id) ? void 0 : column.id,
14588
+ "data-priority": column.priority && column.priority !== "high" ? column.priority : void 0,
14589
+ "data-label": body ? columnLabel(column) : void 0
14590
+ } : {};
14551
14591
  function DataWorkspace({
14552
14592
  label,
14553
14593
  rows,
@@ -14558,10 +14598,15 @@ function DataWorkspace({
14558
14598
  onSortChange,
14559
14599
  selection,
14560
14600
  onSelectionChange,
14601
+ maxSelection,
14561
14602
  bulkActions,
14562
14603
  rowActions,
14563
14604
  getRowProps,
14564
14605
  density,
14606
+ zebra,
14607
+ freezeFirstColumn = false,
14608
+ fixed,
14609
+ mobile,
14565
14610
  search,
14566
14611
  filters,
14567
14612
  savedViews,
@@ -14569,13 +14614,32 @@ function DataWorkspace({
14569
14614
  viewChanged = false,
14570
14615
  onSaveView,
14571
14616
  onSaveViewAs,
14617
+ saveViewAs = "changed",
14572
14618
  maximized = false,
14573
14619
  onMaximizedChange,
14574
14620
  toolbarEnd,
14621
+ beforeBody,
14575
14622
  pagination,
14576
14623
  status = "ready",
14577
14624
  refreshing = false,
14578
14625
  onRetry,
14626
+ loadingRows = 6,
14627
+ empty,
14628
+ emptyAction,
14629
+ filteredEmpty,
14630
+ filteredEmptyAction,
14631
+ error,
14632
+ stateOverride,
14633
+ groups,
14634
+ collapsedGroups,
14635
+ onCollapsedGroupsChange,
14636
+ virtualize,
14637
+ rowNavigation,
14638
+ onRowActivate,
14639
+ activateOnClick = true,
14640
+ activeRowId,
14641
+ onActiveRowChange,
14642
+ multiSort: multiSort2 = false,
14579
14643
  labels: labelOverrides,
14580
14644
  className,
14581
14645
  ...props
@@ -14609,68 +14673,123 @@ function DataWorkspace({
14609
14673
  const root = rootRef.current;
14610
14674
  const target = event.target;
14611
14675
  const owner = target?.closest?.('[popover], [role="dialog"], [role="menu"], [role="listbox"], [aria-expanded="true"]');
14612
- if (owner && root?.contains(owner)) return;
14676
+ if (owner && root?.contains(owner) && (owner.getAttribute("aria-expanded") !== "true" || stillExpanded(owner))) return;
14613
14677
  if (root && openInside(root)) return;
14614
14678
  onMaximizedChange(false);
14615
14679
  };
14616
14680
  window.addEventListener("keydown", onKey);
14617
14681
  return () => window.removeEventListener("keydown", onKey);
14618
14682
  }, [maximized, onMaximizedChange]);
14683
+ const [ladder, setLadder] = (0, import_react89.useState)(null);
14684
+ useIsomorphicLayoutEffect22(() => {
14685
+ const root = rootRef.current;
14686
+ if (!mobile || !root) {
14687
+ setLadder(null);
14688
+ return;
14689
+ }
14690
+ const read = () => {
14691
+ const style = getComputedStyle(root);
14692
+ const padding = (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0);
14693
+ setLadder(ladderFor(mobile, root.getBoundingClientRect().width - padding));
14694
+ };
14695
+ read();
14696
+ if (typeof ResizeObserver === "undefined") return;
14697
+ const observer = new ResizeObserver(read);
14698
+ observer.observe(root);
14699
+ return () => observer.disconnect();
14700
+ }, [mobile]);
14701
+ const cards = ladder === "cards";
14619
14702
  const filtered = (filters ? filters.fields.some((field) => !isFilterEmpty(filters.values[field.id])) : false) || (search?.value.trim() ?? "") !== "";
14620
- const [settled, setSettled] = (0, import_react89.useState)({ rows, filtered });
14621
- if (!refreshing && rows !== settled.rows) setSettled({ rows, filtered });
14622
- const view = rows.length > 0 ? { rows, filtered } : refreshing || rows === settled.rows ? settled : { rows, filtered };
14623
- const shownRows = view.rows;
14703
+ const source = groups ?? rows;
14704
+ const flat = (0, import_react89.useMemo)(() => groups ? groups.flatMap((group2) => group2.rows) : rows, [groups, rows]);
14705
+ const current = { source, flat, groups, filtered };
14706
+ const [settled, setSettled] = (0, import_react89.useState)(current);
14707
+ if (!refreshing && source !== settled.source) setSettled(current);
14708
+ const view = flat.length > 0 ? current : refreshing || source === settled.source ? settled : current;
14709
+ const shownRows = view.flat;
14710
+ const shownGroups = view.groups;
14711
+ const [ownCollapsed, setOwnCollapsed] = (0, import_react89.useState)(() => /* @__PURE__ */ new Set());
14712
+ const collapsed = collapsedGroups ?? ownCollapsed;
14713
+ const toggleGroupOpen = (groupId) => {
14714
+ const next = new Set(collapsed);
14715
+ if (next.has(groupId)) next.delete(groupId);
14716
+ else next.add(groupId);
14717
+ if (!collapsedGroups) setOwnCollapsed(next);
14718
+ onCollapsedGroupsChange?.(next);
14719
+ };
14624
14720
  const ids = (0, import_react89.useMemo)(() => shownRows.map(getRowId), [shownRows, getRowId]);
14625
- const selected = selection ?? /* @__PURE__ */ new Set();
14721
+ const visibleIds = (0, import_react89.useMemo)(() => {
14722
+ if (!shownGroups) return ids;
14723
+ const out = [];
14724
+ for (const group2 of shownGroups) if (!collapsed.has(group2.id)) for (const row of group2.rows) out.push(getRowId(row));
14725
+ return out;
14726
+ }, [shownGroups, collapsed, ids, getRowId]);
14727
+ const selected = selection ?? EMPTY_SET;
14626
14728
  const selectable = onSelectionChange != null;
14729
+ const cap = maxSelection ?? Infinity;
14627
14730
  const onPage = ids.filter((rowId) => selected.has(rowId)).length;
14731
+ const apply = (next, rowIds, on) => {
14732
+ for (const rowId of rowIds) {
14733
+ if (!on) next.delete(rowId);
14734
+ else if (next.has(rowId) || next.size < cap) next.add(rowId);
14735
+ }
14736
+ return next;
14737
+ };
14628
14738
  const toggleRow = (rowId, on, event) => {
14629
14739
  if (!onSelectionChange) return;
14630
14740
  const next = new Set(selected);
14631
- const from = anchor.current ? ids.indexOf(anchor.current) : -1;
14632
- const to = ids.indexOf(rowId);
14741
+ const from = anchor.current ? visibleIds.indexOf(anchor.current) : -1;
14742
+ const to = visibleIds.indexOf(rowId);
14633
14743
  if (event?.shiftKey && from >= 0 && to >= 0) {
14634
- for (let i = Math.min(from, to); i <= Math.max(from, to); i += 1) {
14635
- if (on) next.add(ids[i]);
14636
- else next.delete(ids[i]);
14637
- }
14744
+ apply(next, visibleIds.slice(Math.min(from, to), Math.max(from, to) + 1), on);
14638
14745
  } else {
14639
- if (on) next.add(rowId);
14640
- else next.delete(rowId);
14746
+ apply(next, [rowId], on);
14641
14747
  anchor.current = rowId;
14642
14748
  }
14643
14749
  onSelectionChange(next);
14644
14750
  };
14645
- const toggleAll = (on) => {
14751
+ const toggleMany = (rowIds, on) => {
14646
14752
  if (!onSelectionChange) return;
14647
- const next = new Set(selected);
14648
- for (const rowId of ids) {
14649
- if (on) next.add(rowId);
14650
- else next.delete(rowId);
14651
- }
14652
- onSelectionChange(next);
14753
+ onSelectionChange(apply(new Set(selected), rowIds, on));
14653
14754
  };
14755
+ const atCap = selected.size >= cap;
14654
14756
  const actionsByRow = (0, import_react89.useMemo)(() => rowActions ? shownRows.map((row) => rowActions(row)) : [], [shownRows, rowActions]);
14655
14757
  const hasActions = actionsByRow.some((node) => node != null && node !== false);
14656
14758
  const activeFilters = filters ? filters.fields.filter((field) => !isFilterEmpty(filters.values[field.id])) : [];
14657
14759
  const searching = (search?.value.trim() ?? "") !== "";
14658
14760
  const clearAll = () => {
14761
+ if (filters?.onClearAll) {
14762
+ filters.onClearAll({ search: searching });
14763
+ return;
14764
+ }
14659
14765
  for (const field of activeFilters) filters?.onChange(field.id, void 0);
14660
14766
  if (searching) search?.onChange("");
14661
14767
  };
14662
- const sortFor = (column) => sort?.columnId === column.id ? sort.direction : "none";
14663
- const cycleSort = (column) => {
14664
- const current = sortFor(column);
14665
- onSortChange?.(current === "none" ? { columnId: column.id, direction: "ascending" } : current === "ascending" ? { columnId: column.id, direction: "descending" } : null);
14768
+ const multi = multiSort2 || Array.isArray(sort);
14769
+ const keys = Array.isArray(sort) ? sort : sort ? [sort] : [];
14770
+ const sortFor = (column) => keys.find((key) => key.columnId === column.id)?.direction ?? "none";
14771
+ const cycleSort = (column, additive) => {
14772
+ if (!onSortChange) return;
14773
+ const current2 = sortFor(column);
14774
+ const turned = current2 === "none" ? "ascending" : current2 === "ascending" ? "descending" : null;
14775
+ if (!multi) {
14776
+ onSortChange(turned ? { columnId: column.id, direction: turned } : null);
14777
+ return;
14778
+ }
14779
+ const next = toggleSort(keys.map((key) => ({ field: key.columnId, dir: key.direction })), column.id, additive).map((key) => ({ columnId: key.field, direction: key.dir === "descending" ? "descending" : "ascending" }));
14780
+ onSortChange(next);
14666
14781
  };
14782
+ const showSaveAs = onSaveViewAs != null && (viewChanged || saveViewAs === "always");
14667
14783
  const toolbar = /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("div", { className: "uix-toolbar uix-data-workspace__toolbar", role: "toolbar", "aria-label": label, children: [
14668
- savedViews && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(PopoverButton, { id: `${id}-views`, label: savedViews.current, title: typeof savedViews.current === "string" ? fillLabel(labels.savedView, { name: savedViews.current }) : void 0, variant: "secondary", children: (close) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(SavedViewMenu, { ...savedViews.menu, onSelect: (viewId) => {
14669
- savedViews.menu.onSelect(viewId);
14670
- close();
14671
- } }) }),
14784
+ savedViews && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(PopoverButton, { id: `${id}-views`, label: savedViews.current, title: typeof savedViews.current === "string" ? fillLabel(labels.savedView, { name: savedViews.current }) : void 0, variant: "secondary", children: (close) => /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_jsx_runtime100.Fragment, { children: [
14785
+ savedViews.note != null && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("div", { className: "uix-data-workspace__views-note", children: savedViews.note }),
14786
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(SavedViewMenu, { ...savedViews.menu, onSelect: (viewId) => {
14787
+ savedViews.menu.onSelect(viewId);
14788
+ close();
14789
+ } })
14790
+ ] }) }),
14672
14791
  viewChanged && onSaveView && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Button, { size: "sm", variant: "secondary", onClick: onSaveView, children: labels.saveView }),
14673
- viewChanged && onSaveViewAs && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Button, { size: "sm", variant: "ghost", onClick: onSaveViewAs, children: labels.saveViewAs }),
14792
+ showSaveAs && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Button, { size: "sm", variant: "ghost", onClick: onSaveViewAs, children: labels.saveViewAs }),
14674
14793
  filters && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(FilterChips, { filters, labels, baseId: id }),
14675
14794
  /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-toolbar__spacer" }),
14676
14795
  search && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
@@ -14682,67 +14801,77 @@ function DataWorkspace({
14682
14801
  placeholder: search.placeholder ?? labels.searchPlaceholder,
14683
14802
  value: search.value,
14684
14803
  onValueChange: search.onChange,
14685
- inputRef: searchRef
14804
+ inputRef: searchRef,
14805
+ onSubmit: search.onSubmit,
14806
+ onClear: search.onClear,
14807
+ maxLength: search.maxLength
14686
14808
  }
14687
14809
  ),
14688
14810
  viewMenu && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(PopoverButton, { id: `${id}-view`, label: labels.view, variant: "ghost", children: () => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(ViewMenu, { ...viewMenu }) }),
14689
14811
  onMaximizedChange && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Button, { size: "sm", variant: "ghost", icon: true, "aria-label": maximized ? labels.restore : labels.maximize, "aria-pressed": maximized, onClick: () => onMaximizedChange(!maximized), children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(MaximizeIcon, { restore: maximized }) }),
14690
14812
  toolbarEnd
14691
14813
  ] });
14814
+ const busy = (node) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(BusyRegion, { busy: refreshing, className: "uix-data-workspace__state", children: node });
14692
14815
  let body;
14693
- if (status === "loading") body = /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(LoadingState, { rows: 6, label: labels.loading, className: "uix-data-workspace__loading" });
14694
- else if (status === "error") body = /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(ErrorState, { title: labels.error, action: onRetry && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Button, { size: "sm", onClick: onRetry, children: labels.retry }) });
14816
+ if (stateOverride != null) body = busy(stateOverride);
14817
+ else if (status === "loading") body = /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(LoadingState, { rows: loadingRows, label: labels.loading, className: "uix-data-workspace__loading" });
14818
+ else if (status === "error") body = error != null ? busy(error) : /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(ErrorState, { title: labels.error, action: onRetry && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Button, { size: "sm", onClick: onRetry, children: labels.retry }) });
14695
14819
  else if (shownRows.length === 0) {
14696
- body = /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(BusyRegion, { busy: refreshing, className: "uix-data-workspace__state", children: view.filtered ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(FilteredEmptyState, { title: labels.filteredEmpty, action: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Button, { size: "sm", onClick: clearAll, children: labels.clearFilters }), children: labels.filteredEmptyDetail }) : /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(EmptyState, { title: labels.empty, children: labels.emptyDetail }) });
14820
+ const clear = /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Button, { size: "sm", onClick: clearAll, children: labels.clearFilters });
14821
+ body = busy(view.filtered ? filteredEmpty ?? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
14822
+ FilteredEmptyState,
14823
+ {
14824
+ title: labels.filteredEmpty,
14825
+ action: filteredEmptyAction != null ? /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("div", { className: "uix-data-workspace__state-actions", children: [
14826
+ clear,
14827
+ filteredEmptyAction
14828
+ ] }) : clear,
14829
+ children: labels.filteredEmptyDetail
14830
+ }
14831
+ ) : empty ?? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(EmptyState, { title: labels.empty, action: emptyAction, children: labels.emptyDetail }));
14697
14832
  } else {
14698
- body = /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(TableWrap, { refreshing, className: "uix-data-workspace__table", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(Table, { density, pinnedCol: idColumn != null, pinnedActions: hasActions, className: cx(selectable && idColumn && "uix-data-workspace__grid--pin-id"), "aria-label": label, children: [
14699
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("tr", { children: [
14700
- selectable && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("th", { className: "uix-table__selcol", scope: "col", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Checkbox, { "aria-label": labels.selectAll, checked: onPage > 0 && onPage === ids.length, indeterminate: onPage > 0 && onPage < ids.length, onChange: (event) => toggleAll(event.currentTarget.checked) }) }),
14701
- idColumn && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Th, { scope: "col", children: idColumn.header }),
14702
- columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
14703
- Th,
14704
- {
14705
- scope: "col",
14706
- className: column.align === "end" ? "uix-col--num" : void 0,
14707
- style: column.width ? { width: column.width } : void 0,
14708
- sortable: column.sortable && onSortChange != null,
14709
- sortDirection: sortFor(column),
14710
- onSort: () => cycleSort(column),
14711
- children: column.header
14712
- },
14713
- column.id
14714
- )),
14715
- hasActions && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("th", { scope: "col", className: "uix-table__actions", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-visually-hidden", children: labels.rowActions }) })
14716
- ] }) }),
14717
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("tbody", { children: shownRows.map((row, index) => {
14718
- const rowId = ids[index];
14719
- const text = idColumn?.text(row) ?? rowId;
14720
- const isSelected = selected.has(rowId);
14721
- return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(Tr, { selected: isSelected, ...getRowProps?.(row), children: [
14722
- selectable && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("td", { className: "uix-table__selcell", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
14723
- Checkbox,
14724
- {
14725
- "aria-label": fillLabel(labels.selectRow, { label: text }),
14726
- checked: isSelected,
14727
- onClick: (event) => toggleRow(rowId, event.currentTarget.checked, event),
14728
- onChange: () => {
14729
- }
14730
- }
14731
- ) }),
14732
- idColumn && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Td, { className: "uix-id-cell", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("span", { className: "uix-data-workspace__id", children: [
14733
- idColumn.onPeek ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("button", { type: "button", className: "uix-id-cell__btn", "aria-haspopup": "dialog", onClick: () => idColumn.onPeek?.(row), children: text }) : /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-cell-strong", children: text }),
14734
- idColumn.href && renderUixLink(idColumn.renderLink, {
14735
- href: idColumn.href(row),
14736
- className: "uix-data-workspace__open",
14737
- "aria-label": fillLabel(labels.open, { label: text }),
14738
- children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(ArrowUpRight, {})
14739
- })
14740
- ] }) }),
14741
- columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Td, { className: column.align === "end" ? "uix-col--num" : void 0, children: column.cell(row) }, column.id)),
14742
- hasActions && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(RowActions, { children: actionsByRow[index] })
14743
- ] }, rowId);
14744
- }) })
14745
- ] }) });
14833
+ body = /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
14834
+ WorkspaceGrid,
14835
+ {
14836
+ label,
14837
+ rows: shownRows,
14838
+ ids,
14839
+ groups: shownGroups,
14840
+ collapsed,
14841
+ onToggleGroup: toggleGroupOpen,
14842
+ getRowId,
14843
+ columns,
14844
+ idColumn,
14845
+ getRowProps,
14846
+ density,
14847
+ zebra,
14848
+ freezeFirstColumn,
14849
+ fixed: fixed ?? columns.some((column) => column.className != null || column.minWidth != null),
14850
+ ladderOn: mobile != null,
14851
+ ladder,
14852
+ refreshing,
14853
+ selectable,
14854
+ selected,
14855
+ onPage,
14856
+ atCap,
14857
+ toggleRow,
14858
+ toggleMany,
14859
+ actionsByRow,
14860
+ hasActions,
14861
+ keys,
14862
+ sortable: onSortChange != null,
14863
+ multi,
14864
+ sortFor,
14865
+ cycleSort,
14866
+ virtualize: pagination || shownGroups ? void 0 : virtualize,
14867
+ rowNavigation: rowNavigation ?? onRowActivate != null,
14868
+ onRowActivate,
14869
+ activateOnClick,
14870
+ activeRowId,
14871
+ onActiveRowChange,
14872
+ labels
14873
+ }
14874
+ );
14746
14875
  }
14747
14876
  const selectedIds = [...selected];
14748
14877
  return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(
@@ -14755,12 +14884,559 @@ function DataWorkspace({
14755
14884
  children: [
14756
14885
  toolbar,
14757
14886
  bulkActions && selectedIds.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(BulkBar, { count: selectedIds.length, label: labels.bulkActions, selectedLabel: (n) => fillLabel(labels.selected, { count: n }), children: bulkActions(selectedIds) }),
14887
+ beforeBody != null && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("div", { className: "uix-data-workspace__before", children: beforeBody }),
14758
14888
  body,
14759
- pagination && status === "ready" && shownRows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Footer, { pagination, labels, rowCount: shownRows.length })
14889
+ pagination && status === "ready" && stateOverride == null && shownRows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Footer, { pagination, labels, rowCount: shownRows.length })
14760
14890
  ]
14761
14891
  }
14762
14892
  );
14763
14893
  }
14894
+ var EMPTY_SET = /* @__PURE__ */ new Set();
14895
+ function WorkspaceGrid(props) {
14896
+ return props.virtualize ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(WindowedGrid, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(WorkspaceTable, { ...props, windowing: null, virtual: null });
14897
+ }
14898
+ function WindowedGrid(props) {
14899
+ const windowing = props.virtualize === true || !props.virtualize ? {} : props.virtualize;
14900
+ const threshold = windowing.threshold ?? 100;
14901
+ const virtual = useVirtualRows(props.rows, {
14902
+ rowHeight: windowing.estimatedRowHeight ?? ROW_HEIGHT[props.density ?? "standard"],
14903
+ overscan: windowing.overscan ?? 8,
14904
+ // windowed at `threshold` rows or more (the hook windows above its own threshold)
14905
+ threshold: Math.max(0, threshold - 1),
14906
+ estimatedViewportHeight: windowing.maxHeight ?? 640,
14907
+ measureRows: "tbody > tr[data-uix-row-id]",
14908
+ // cards are not windowed: a card's height is its content's
14909
+ enabled: props.rows.length >= threshold && props.ladder !== "cards"
14910
+ });
14911
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(WorkspaceTable, { ...props, windowing, virtual });
14912
+ }
14913
+ var columnFloor = (width, minWidth, className) => {
14914
+ if (minWidth) return minWidth;
14915
+ if (width && !width.trim().endsWith("%")) return width;
14916
+ const classes = className?.split(/\s+/) ?? [];
14917
+ for (const cls of classes) {
14918
+ const tier = /^uix-col--w-(xs|sm|md|lg|xl)$/.exec(cls)?.[1];
14919
+ if (tier) return `var(--uix-col-w-${tier})`;
14920
+ }
14921
+ if (classes.includes("uix-col--flex") || classes.includes("uix-col--primary")) return "var(--uix-col-title-min)";
14922
+ return "var(--uix-col-w-sm)";
14923
+ };
14924
+ var isFlex = (className) => /(^|\s)uix-col--(flex|primary)(\s|$)/.test(className ?? "");
14925
+ var colClasses = (className) => className?.split(/\s+/).filter((cls) => /^uix-col--(w-(xs|sm|md|lg|xl)|flex|primary)$/.test(cls)).join(" ") || void 0;
14926
+ function WorkspaceTable({
14927
+ label,
14928
+ rows,
14929
+ ids,
14930
+ groups,
14931
+ collapsed,
14932
+ onToggleGroup,
14933
+ getRowId,
14934
+ columns,
14935
+ idColumn,
14936
+ getRowProps,
14937
+ density,
14938
+ zebra,
14939
+ freezeFirstColumn,
14940
+ fixed,
14941
+ ladderOn,
14942
+ ladder,
14943
+ refreshing,
14944
+ selectable,
14945
+ selected,
14946
+ onPage,
14947
+ atCap,
14948
+ toggleRow,
14949
+ toggleMany,
14950
+ actionsByRow,
14951
+ hasActions,
14952
+ keys,
14953
+ sortable,
14954
+ multi,
14955
+ sortFor,
14956
+ cycleSort,
14957
+ rowNavigation,
14958
+ onRowActivate,
14959
+ activateOnClick,
14960
+ activeRowId,
14961
+ onActiveRowChange,
14962
+ labels,
14963
+ windowing,
14964
+ virtual
14965
+ }) {
14966
+ const cards = ladder === "cards";
14967
+ const wrapRef = (0, import_react89.useRef)(null);
14968
+ const baseId = (0, import_react89.useId)();
14969
+ const maxHeight = windowing?.maxHeight ?? 640;
14970
+ const long = windowing != null && !cards && rows.length >= (windowing.threshold ?? 100);
14971
+ const containerRef = virtual?.containerRef;
14972
+ const setWrap = (0, import_react89.useCallback)((node) => {
14973
+ wrapRef.current = node;
14974
+ if (containerRef) containerRef.current = node;
14975
+ }, [containerRef]);
14976
+ const windowed = virtual?.virtualized ?? false;
14977
+ const start = virtual && windowed ? virtual.startIndex : 0;
14978
+ const mountedRows = virtual && windowed ? virtual.rows : rows;
14979
+ const nav = rowNavigation;
14980
+ const clickActivates = onRowActivate != null && activateOnClick;
14981
+ const [ownActive, setOwnActive] = (0, import_react89.useState)(null);
14982
+ const active = activeRowId !== void 0 ? activeRowId : ownActive;
14983
+ const navIds = (0, import_react89.useMemo)(() => {
14984
+ if (!groups) return ids;
14985
+ const out = [];
14986
+ for (const group2 of groups) if (!collapsed.has(group2.id)) for (const row of group2.rows) out.push(getRowId(row));
14987
+ return out;
14988
+ }, [groups, collapsed, ids, getRowId]);
14989
+ const mountedIds = (0, import_react89.useMemo)(() => new Set(windowed ? ids.slice(start, start + mountedRows.length) : navIds), [windowed, ids, start, mountedRows.length, navIds]);
14990
+ const tabStop = active != null && mountedIds.has(active) ? active : navIds.find((rowId) => mountedIds.has(rowId)) ?? null;
14991
+ const pendingFocus = (0, import_react89.useRef)(null);
14992
+ const focusedRow = (0, import_react89.useRef)(null);
14993
+ const rowElement = (rowId) => {
14994
+ for (const el of Array.from(wrapRef.current?.querySelectorAll("tbody > tr[data-uix-row-id]") ?? [])) {
14995
+ if (el.getAttribute("data-uix-row-id") === rowId) return el;
14996
+ }
14997
+ return null;
14998
+ };
14999
+ const reveal = (el) => {
15000
+ el.scrollIntoView?.({ block: "nearest", inline: "nearest" });
15001
+ const wrap = wrapRef.current;
15002
+ const head = wrap?.querySelector("thead");
15003
+ if (wrap && head && windowed) {
15004
+ const under = head.getBoundingClientRect().bottom - el.getBoundingClientRect().top;
15005
+ if (under > 0) wrap.scrollTop -= under;
15006
+ }
15007
+ };
15008
+ const setActive = (rowId) => {
15009
+ if (rowId === active) return;
15010
+ if (activeRowId === void 0) setOwnActive(rowId);
15011
+ onActiveRowChange?.(rowId);
15012
+ };
15013
+ const focusRow = (rowId, { take = true } = {}) => {
15014
+ if (!navIds.includes(rowId)) return;
15015
+ setActive(rowId);
15016
+ if (!take) return;
15017
+ const el = rowElement(rowId);
15018
+ if (el) {
15019
+ el.focus({ preventScroll: true });
15020
+ reveal(el);
15021
+ return;
15022
+ }
15023
+ const index = ids.indexOf(rowId);
15024
+ if (index >= 0 && wrapRef.current && virtual && windowed) {
15025
+ pendingFocus.current = rowId;
15026
+ wrapRef.current.scrollTop = index * virtual.rowHeight;
15027
+ }
15028
+ };
15029
+ useIsomorphicLayoutEffect22(() => {
15030
+ if (!nav) return;
15031
+ const pending = pendingFocus.current;
15032
+ if (pending != null) {
15033
+ if (!ids.includes(pending)) {
15034
+ pendingFocus.current = null;
15035
+ return;
15036
+ }
15037
+ const el2 = rowElement(pending);
15038
+ if (el2) {
15039
+ pendingFocus.current = null;
15040
+ el2.focus({ preventScroll: true });
15041
+ reveal(el2);
15042
+ }
15043
+ return;
15044
+ }
15045
+ const had = focusedRow.current;
15046
+ if (had == null) return;
15047
+ const wrap = wrapRef.current;
15048
+ const focused = typeof document !== "undefined" ? document.activeElement : null;
15049
+ const el = rowElement(had);
15050
+ if (el && wrap && focused === wrap) {
15051
+ el.focus({ preventScroll: true });
15052
+ return;
15053
+ }
15054
+ if (el || !(focused == null || focused === document.body)) return;
15055
+ if (windowed && ids.includes(had) && wrap) {
15056
+ wrap.focus({ preventScroll: true });
15057
+ } else if (tabStop != null) {
15058
+ rowElement(tabStop)?.focus({ preventScroll: true });
15059
+ }
15060
+ });
15061
+ const lastActiveProp = (0, import_react89.useRef)(activeRowId);
15062
+ (0, import_react89.useEffect)(() => {
15063
+ if (!nav || activeRowId === lastActiveProp.current) return;
15064
+ lastActiveProp.current = activeRowId;
15065
+ if (activeRowId == null) return;
15066
+ const focused = document.activeElement;
15067
+ const el = rowElement(activeRowId);
15068
+ if (el && el.contains(focused)) return;
15069
+ const mayTake = focused == null || focused === document.body || (wrapRef.current?.contains(focused) ?? false);
15070
+ focusRow(activeRowId, { take: mayTake });
15071
+ });
15072
+ const latest = {
15073
+ toggle: (rowId, on, event) => toggleRow(rowId, on, event),
15074
+ key: (rowId, event) => {
15075
+ if (event.target !== event.currentTarget || event.altKey || event.ctrlKey || event.metaKey) return;
15076
+ const at2 = navIds.indexOf(rowId);
15077
+ const to = event.key === "ArrowDown" ? at2 + 1 : event.key === "ArrowUp" ? at2 - 1 : event.key === "Home" ? 0 : event.key === "End" ? navIds.length - 1 : null;
15078
+ if (to != null) {
15079
+ event.preventDefault();
15080
+ const target = navIds[Math.max(0, Math.min(navIds.length - 1, to))];
15081
+ if (target != null) focusRow(target);
15082
+ } else if (event.key === "Enter") {
15083
+ event.preventDefault();
15084
+ const row = rows[ids.indexOf(rowId)];
15085
+ if (onRowActivate) {
15086
+ if (row !== void 0) onRowActivate(row);
15087
+ return;
15088
+ }
15089
+ const el = event.currentTarget;
15090
+ (el.querySelector(".uix-id-cell__btn") ?? el.querySelector("a[href]"))?.click();
15091
+ } else if (event.key === " ") {
15092
+ event.preventDefault();
15093
+ }
15094
+ },
15095
+ click: (rowId, event) => {
15096
+ if (!clickActivates) return;
15097
+ if (!event.currentTarget.contains(event.target)) return;
15098
+ const control = event.target.closest?.(CONTROLS);
15099
+ if (control && control !== event.currentTarget && event.currentTarget.contains(control)) return;
15100
+ if (typeof window !== "undefined" && (window.getSelection?.()?.toString() ?? "") !== "") return;
15101
+ const row = rows[ids.indexOf(rowId)];
15102
+ if (row !== void 0) onRowActivate?.(row);
15103
+ },
15104
+ focus: (rowId) => {
15105
+ focusedRow.current = rowId;
15106
+ setActive(rowId);
15107
+ },
15108
+ blur: (rowId, event) => {
15109
+ const next = event.relatedTarget;
15110
+ if (next && wrapRef.current?.contains(next)) return;
15111
+ if (next) {
15112
+ focusedRow.current = null;
15113
+ return;
15114
+ }
15115
+ const el = event.currentTarget;
15116
+ setTimeout(() => {
15117
+ if (el.isConnected && focusedRow.current === rowId) focusedRow.current = null;
15118
+ }, 0);
15119
+ }
15120
+ };
15121
+ const latestRef = (0, import_react89.useRef)(latest);
15122
+ latestRef.current = latest;
15123
+ const handlers2 = (0, import_react89.useMemo)(() => ({
15124
+ toggle: (...args) => latestRef.current.toggle(...args),
15125
+ key: (...args) => latestRef.current.key(...args),
15126
+ click: (...args) => latestRef.current.click(...args),
15127
+ focus: (...args) => latestRef.current.focus(...args),
15128
+ blur: (...args) => latestRef.current.blur(...args)
15129
+ }), []);
15130
+ const groupAnchor = (0, import_react89.useRef)(null);
15131
+ const toggleGroup = (groupId, header) => {
15132
+ groupAnchor.current = header ? { id: groupId, top: header.getBoundingClientRect().top } : null;
15133
+ onToggleGroup(groupId);
15134
+ };
15135
+ useIsomorphicLayoutEffect22(() => {
15136
+ const was = groupAnchor.current;
15137
+ if (!was) return;
15138
+ groupAnchor.current = null;
15139
+ const header = wrapRef.current?.querySelector(`tr[data-group-id="${cssEscape(was.id)}"]`);
15140
+ if (!header) return;
15141
+ const moved = header.getBoundingClientRect().top - was.top;
15142
+ if (Math.abs(moved) < 1) return;
15143
+ const wrap = wrapRef.current;
15144
+ if (wrap && wrap.scrollHeight > wrap.clientHeight + 1 && getComputedStyle(wrap).overflowY !== "visible") wrap.scrollTop += moved;
15145
+ else window.scrollBy?.(0, moved);
15146
+ });
15147
+ const shiftKey = (0, import_react89.useRef)(false);
15148
+ const additive = (0, import_react89.useRef)(false);
15149
+ const frozen = !cards && ladder !== "priority-mid" && (idColumn != null || freezeFirstColumn);
15150
+ const shown = columns.filter((column) => !hiddenBy(ladder, column.priority));
15151
+ const colCount = (selectable ? 1 : 0) + (idColumn ? 1 : 0) + shown.length + (hasActions ? 1 : 0);
15152
+ const selectRowLabel = labels.selectRow;
15153
+ const openLabel = labels.open;
15154
+ const fixedOn = fixed && !cards;
15155
+ const [actionsWidth, setActionsWidth] = (0, import_react89.useState)(null);
15156
+ useIsomorphicLayoutEffect22(() => {
15157
+ if (!fixedOn || !hasActions) return;
15158
+ let widest = 0;
15159
+ for (const td of Array.from(wrapRef.current?.querySelectorAll("tbody td.uix-table__actions") ?? [])) {
15160
+ const range = document.createRange();
15161
+ range.selectNodeContents(td);
15162
+ const content = range.getBoundingClientRect().width;
15163
+ const style = getComputedStyle(td);
15164
+ widest = Math.max(widest, content + parseFloat(style.paddingLeft || "0") + parseFloat(style.paddingRight || "0"));
15165
+ }
15166
+ const next = widest > 0 ? Math.ceil(widest) : null;
15167
+ if (next !== actionsWidth) setActionsWidth(next);
15168
+ });
15169
+ const actionsCol = actionsWidth != null ? `${actionsWidth}px` : "5.25rem";
15170
+ const floors = fixedOn ? [
15171
+ ...selectable ? ["var(--uix-selcol-w)"] : [],
15172
+ ...idColumn ? [columnFloor(idColumn.width, idColumn.minWidth, void 0)] : [],
15173
+ ...shown.map((column) => columnFloor(column.width, column.minWidth, column.className)),
15174
+ ...hasActions ? [actionsCol] : []
15175
+ ] : [];
15176
+ const tableStyle = fixedOn && floors.length ? { minWidth: floors.length === 1 ? floors[0] : `calc(${floors.join(" + ")})` } : void 0;
15177
+ const renderRow = (row, index) => {
15178
+ const rowId = ids[index];
15179
+ const isSelected = selected.has(rowId);
15180
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
15181
+ WorkspaceRow,
15182
+ {
15183
+ row,
15184
+ rowId,
15185
+ columns,
15186
+ idColumn,
15187
+ getRowProps,
15188
+ selectable,
15189
+ selected: isSelected,
15190
+ selectDisabled: !isSelected && atCap,
15191
+ hasActions,
15192
+ actions: actionsByRow[index],
15193
+ ladderOn,
15194
+ selectRowLabel,
15195
+ openLabel,
15196
+ marked: nav || windowing != null,
15197
+ ariaRowIndex: windowed ? index + 2 : void 0,
15198
+ nav,
15199
+ tabStop: tabStop === rowId,
15200
+ handlers: handlers2
15201
+ },
15202
+ rowId
15203
+ );
15204
+ };
15205
+ let tbody;
15206
+ if (groups) {
15207
+ let offset = 0;
15208
+ tbody = groups.map((group2, groupIndex) => {
15209
+ const first = offset;
15210
+ offset += group2.rows.length;
15211
+ const open = !collapsed.has(group2.id);
15212
+ const name = group2.name ?? textOf2(group2.label) ?? group2.id;
15213
+ const groupIds = ids.slice(first, first + group2.rows.length);
15214
+ const on = groupIds.filter((rowId) => selected.has(rowId)).length;
15215
+ const count2 = group2.count ?? group2.rows.length;
15216
+ const nameId = `${baseId}-g${groupIndex}-name`;
15217
+ const countId = `${baseId}-g${groupIndex}-count`;
15218
+ const firstAgg = shown.findIndex((column) => group2.aggregates?.[column.id] != null);
15219
+ const lead = (idColumn ? 1 : 0) + (firstAgg < 0 ? shown.length + (hasActions ? 1 : 0) : firstAgg);
15220
+ const leadAgg = lead === 0 && firstAgg === 0 ? group2.aggregates?.[shown[0].id] : null;
15221
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("tbody", { className: "uix-data-workspace__group", "data-collapsed": open ? void 0 : "", children: [
15222
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("tr", { className: "uix-data-workspace__group-head", "data-group-id": group2.id, children: [
15223
+ selectable && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("td", { className: "uix-table__selcell", "data-col": ladderOn ? "select" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
15224
+ Checkbox,
15225
+ {
15226
+ "aria-label": fillLabel(labels.selectGroup, { name }),
15227
+ disabled: group2.rows.length === 0 || atCap && on === 0,
15228
+ checked: on > 0 && on === groupIds.length,
15229
+ indeterminate: on > 0 && on < groupIds.length,
15230
+ onChange: () => toggleMany(groupIds, on < groupIds.length && !atCap)
15231
+ }
15232
+ ) }),
15233
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("th", { scope: "rowgroup", colSpan: Math.max(1, lead), className: "uix-data-workspace__group-label", "aria-labelledby": `${nameId} ${countId}`, children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("span", { className: "uix-data-workspace__group-title", children: [
15234
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
15235
+ "button",
15236
+ {
15237
+ type: "button",
15238
+ className: "uix-data-workspace__group-toggle",
15239
+ "aria-expanded": open,
15240
+ "aria-label": fillLabel(open ? labels.collapseGroup : labels.expandGroup, { name }),
15241
+ onClick: (event) => toggleGroup(group2.id, event.currentTarget.closest("tr")),
15242
+ children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(ChevronIcon2, {})
15243
+ }
15244
+ ),
15245
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-data-workspace__group-name", id: nameId, children: group2.label }),
15246
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-data-workspace__group-count", id: countId, children: fillLabel(count2 === 1 ? labels.groupCountOne : labels.groupCount, { count: count2 }) }),
15247
+ leadAgg
15248
+ ] }) }),
15249
+ firstAgg >= 0 && shown.slice(lead === 0 ? 1 : firstAgg).map((column) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("td", { className: cx("uix-data-workspace__group-agg", column.align === "end" && "uix-col--num", column.className), children: group2.aggregates?.[column.id] }, column.id)),
15250
+ firstAgg >= 0 && hasActions && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("td", { className: "uix-table__actions" })
15251
+ ] }),
15252
+ open && group2.rows.map((row, at2) => renderRow(row, first + at2))
15253
+ ] }, group2.id);
15254
+ });
15255
+ } else {
15256
+ const spacer = (height, key) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("tr", { "aria-hidden": "true", className: "uix-data-workspace__spacer", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("td", { colSpan: colCount, style: { height } }) }, key);
15257
+ tbody = /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("tbody", { children: [
15258
+ virtual && windowed && start > 0 && spacer(virtual.padTop, "pad-top"),
15259
+ windowed && start > 0 && start % 2 === 0 && spacer(0, "pad-zebra"),
15260
+ mountedRows.map((row, at2) => renderRow(row, start + at2)),
15261
+ virtual && windowed && virtual.padBottom > 0 && spacer(virtual.padBottom, "pad-bottom")
15262
+ ] });
15263
+ }
15264
+ const wrapStyle = long ? { "--uix-table-max-height": `${maxHeight}px` } : void 0;
15265
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
15266
+ TableWrap,
15267
+ {
15268
+ ref: setWrap,
15269
+ refreshing,
15270
+ style: wrapStyle,
15271
+ tabIndex: windowing != null && nav ? -1 : void 0,
15272
+ className: cx("uix-data-workspace__table", long && "uix-table-wrap--scroll", cards && "uix-data-workspace__table--cards"),
15273
+ children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(
15274
+ Table,
15275
+ {
15276
+ density,
15277
+ zebra,
15278
+ pinnedCol: frozen,
15279
+ pinnedActions: hasActions && !cards,
15280
+ fixed: fixedOn || void 0,
15281
+ style: tableStyle,
15282
+ className: cx(
15283
+ selectable && frozen && "uix-data-workspace__grid--pin-id",
15284
+ ladder && `uix-table--${ladder}`,
15285
+ groups && zebra !== false && "uix-data-workspace__grid--grouped",
15286
+ nav && "uix-data-workspace__grid--rows",
15287
+ clickActivates && "uix-data-workspace__grid--click"
15288
+ ),
15289
+ "aria-label": label,
15290
+ "aria-rowcount": windowed ? ids.length + 1 : void 0,
15291
+ children: [
15292
+ fixedOn && /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("colgroup", { children: [
15293
+ selectable && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("col", { style: { width: "var(--uix-selcol-w)" } }),
15294
+ idColumn && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("col", { style: idColumn.width ? { width: idColumn.width } : void 0 }),
15295
+ shown.map((column) => {
15296
+ const width = column.width ?? (isFlex(column.className) ? void 0 : columnFloor(void 0, column.minWidth, column.className));
15297
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("col", { className: colClasses(column.className), style: width ? { width } : void 0 }, column.id);
15298
+ }),
15299
+ hasActions && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("col", { style: { width: actionsCol } })
15300
+ ] }),
15301
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("tr", { "aria-rowindex": windowed ? 1 : void 0, children: [
15302
+ selectable && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("th", { className: "uix-table__selcol", scope: "col", "data-col": ladderOn ? "select" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
15303
+ Checkbox,
15304
+ {
15305
+ "aria-label": labels.selectAll,
15306
+ checked: onPage > 0 && onPage === ids.length,
15307
+ indeterminate: onPage > 0 && onPage < ids.length,
15308
+ disabled: atCap && onPage === 0,
15309
+ onChange: () => toggleMany(ids, onPage < ids.length && !atCap)
15310
+ }
15311
+ ) }),
15312
+ idColumn && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Th, { scope: "col", "data-col": ladderOn ? "id" : void 0, children: idColumn.header }),
15313
+ columns.map((column) => {
15314
+ const order = keys.findIndex((key) => key.columnId === column.id);
15315
+ const canSort = column.sortable && sortable;
15316
+ const style = !fixedOn && (column.width || column.minWidth) ? { width: column.width, minWidth: column.minWidth } : void 0;
15317
+ const ordinal = keys.length > 1 && order >= 0 ? order + 1 : void 0;
15318
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
15319
+ Th,
15320
+ {
15321
+ scope: "col",
15322
+ className: cx(column.align === "end" && "uix-col--num", column.className) || void 0,
15323
+ style,
15324
+ sortable: canSort,
15325
+ sortDirection: sortFor(column),
15326
+ sortOrder: ordinal,
15327
+ sortOrderLabel: ordinal != null ? fillLabel(labels.sortPriority, { n: ordinal }) : void 0,
15328
+ onSort: () => {
15329
+ cycleSort(column, multi && additive.current);
15330
+ additive.current = false;
15331
+ },
15332
+ ...canSort && multi ? {
15333
+ onKeyDownCapture: (event) => {
15334
+ if (event.key === "Enter" || event.key === " ") shiftKey.current = event.shiftKey;
15335
+ },
15336
+ // A click made by Enter or Space has no pointer (detail 0) and may not carry Shift itself.
15337
+ onClickCapture: (event) => {
15338
+ additive.current = event.shiftKey || event.detail === 0 && shiftKey.current;
15339
+ shiftKey.current = false;
15340
+ }
15341
+ } : {},
15342
+ ...ladderAttrs(ladderOn, column, false),
15343
+ children: column.header
15344
+ },
15345
+ column.id
15346
+ );
15347
+ }),
15348
+ hasActions && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("th", { scope: "col", className: "uix-table__actions", "data-col": ladderOn ? "actions" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-visually-hidden", children: labels.rowActions }) })
15349
+ ] }) }),
15350
+ tbody
15351
+ ]
15352
+ }
15353
+ )
15354
+ }
15355
+ );
15356
+ }
15357
+ function WorkspaceRowInner({
15358
+ row,
15359
+ rowId,
15360
+ columns,
15361
+ idColumn,
15362
+ getRowProps,
15363
+ selectable,
15364
+ selected,
15365
+ selectDisabled,
15366
+ hasActions,
15367
+ actions,
15368
+ ladderOn,
15369
+ selectRowLabel,
15370
+ openLabel,
15371
+ marked,
15372
+ ariaRowIndex,
15373
+ nav,
15374
+ tabStop,
15375
+ handlers: handlers2
15376
+ }) {
15377
+ const text = idColumn?.text(row) ?? rowId;
15378
+ const extra = getRowProps?.(row);
15379
+ const navProps = nav ? {
15380
+ tabIndex: tabStop ? 0 : -1,
15381
+ onKeyDown: (event) => {
15382
+ extra?.onKeyDown?.(event);
15383
+ if (!event.defaultPrevented) handlers2.key(rowId, event);
15384
+ },
15385
+ onClick: (event) => {
15386
+ extra?.onClick?.(event);
15387
+ if (!event.defaultPrevented) handlers2.click(rowId, event);
15388
+ },
15389
+ onFocus: (event) => {
15390
+ extra?.onFocus?.(event);
15391
+ handlers2.focus(rowId);
15392
+ },
15393
+ onBlur: (event) => {
15394
+ extra?.onBlur?.(event);
15395
+ handlers2.blur(rowId, event);
15396
+ }
15397
+ } : {};
15398
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(Tr, { selected, "data-uix-row-id": marked ? rowId : void 0, "aria-rowindex": ariaRowIndex, ...extra, ...navProps, children: [
15399
+ selectable && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("td", { className: "uix-table__selcell", "data-col": ladderOn ? "select" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
15400
+ Checkbox,
15401
+ {
15402
+ "aria-label": fillLabel(selectRowLabel, { label: text }),
15403
+ checked: selected,
15404
+ disabled: selectDisabled,
15405
+ onClick: (event) => handlers2.toggle(rowId, event.currentTarget.checked, event),
15406
+ onChange: () => {
15407
+ }
15408
+ }
15409
+ ) }),
15410
+ idColumn && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Td, { className: "uix-id-cell", "data-col": ladderOn ? "id" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(IdCell, { row, text, idColumn, openLabel }) }),
15411
+ columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Td, { className: cx(column.align === "end" && "uix-col--num", column.className) || void 0, ...ladderAttrs(ladderOn, column, true), children: column.cell(row) }, column.id)),
15412
+ hasActions && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(RowActions, { "data-col": ladderOn ? "actions" : void 0, children: actions })
15413
+ ] });
15414
+ }
15415
+ var WorkspaceRow = (0, import_react89.memo)(WorkspaceRowInner);
15416
+ function IdCell({ row, text, idColumn, openLabel }) {
15417
+ const rich = idColumn.render ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-data-workspace__id-text", children: idColumn.render(row) }) : null;
15418
+ const arrow = idColumn.href && renderUixLink(idColumn.renderLink, {
15419
+ href: idColumn.href(row),
15420
+ className: "uix-data-workspace__open",
15421
+ "aria-label": fillLabel(openLabel, { label: text }),
15422
+ children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(ArrowUpRight, {})
15423
+ });
15424
+ if (!idColumn.onPeek && idColumn.href && idColumn.linkId) {
15425
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-data-workspace__id", children: renderUixLink(idColumn.renderLink, {
15426
+ href: idColumn.href(row),
15427
+ className: "uix-id-cell__btn uix-data-workspace__id-link",
15428
+ children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_jsx_runtime100.Fragment, { children: [
15429
+ rich ?? text,
15430
+ /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(ArrowUpRight, {})
15431
+ ] })
15432
+ }) });
15433
+ }
15434
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("span", { className: "uix-data-workspace__id", children: [
15435
+ idColumn.onPeek ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("button", { type: "button", className: "uix-id-cell__btn", "aria-haspopup": "dialog", onClick: () => idColumn.onPeek?.(row), children: rich ?? text }) : rich ?? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-cell-strong", children: text }),
15436
+ arrow
15437
+ ] });
15438
+ }
15439
+ var cssEscape = (value) => typeof CSS !== "undefined" && CSS.escape ? CSS.escape(value) : value.replace(/["\\]/g, "\\$&");
14764
15440
  function Footer({ pagination, labels, rowCount }) {
14765
15441
  const sizes = pagination.pageSizes;
14766
15442
  const size = pagination.mode === "offset" ? pagination.pageSize : pagination.pageSize;
@@ -14808,7 +15484,18 @@ function openInside(root) {
14808
15484
  if (root.querySelector(":popover-open")) return true;
14809
15485
  } catch {
14810
15486
  }
14811
- return root.querySelector('dialog[open], [aria-expanded="true"]') != null;
15487
+ if (root.querySelector("dialog[open]")) return true;
15488
+ return Array.from(root.querySelectorAll('[aria-expanded="true"]')).some(stillExpanded);
15489
+ }
15490
+ function stillExpanded(el) {
15491
+ const controls = el.getAttribute("aria-controls");
15492
+ const target = controls ? document.getElementById(controls) : null;
15493
+ if (!target?.hasAttribute("popover")) return true;
15494
+ try {
15495
+ return target.matches(":popover-open");
15496
+ } catch {
15497
+ return true;
15498
+ }
14812
15499
  }
14813
15500
  function FilterChips({ filters, labels, baseId }) {
14814
15501
  const [editing, setEditing] = (0, import_react89.useState)(null);
@@ -14851,6 +15538,10 @@ function FilterChips({ filters, labels, baseId }) {
14851
15538
  setFocusChip(null);
14852
15539
  }
14853
15540
  });
15541
+ const clearSet = () => {
15542
+ if (filters.onClearAll) filters.onClearAll({ search: false });
15543
+ else for (const f of set) filters.onChange(f.id, void 0);
15544
+ };
14854
15545
  return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_jsx_runtime100.Fragment, { children: [
14855
15546
  set.map((field) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { ref: (el) => {
14856
15547
  if (el) anchors.current.set(field.id, el);
@@ -14866,9 +15557,7 @@ function FilterChips({ filters, labels, baseId }) {
14866
15557
  }
14867
15558
  ) }, field.id)),
14868
15559
  unset.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { ref: addRef, children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Menu, { trigger: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Chip, { variant: "add", icon: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(PlusIcon2, {}), children: labels.addFilter }), children: unset.map((field) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(MenuItem, { onSelect: () => edit(field, addRef.current), children: field.label }, field.id)) }) }),
14869
- set.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Button, { size: "sm", variant: "link", onClick: () => {
14870
- for (const f of set) filters.onChange(f.id, void 0);
14871
- }, children: labels.clearFilters }),
15560
+ set.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Button, { size: "sm", variant: "link", onClick: clearSet, children: labels.clearFilters }),
14872
15561
  /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Popover, { id: popId, anchor: editing?.anchor ?? null, role: "dialog", "aria-label": editing?.field.label, children: editing && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(FilterEditor, { field: editing.field, value: draft, onValueChange: setDraft, onApply: (v) => finish(v), onClear: () => finish(void 0) }) })
14873
15562
  ] });
14874
15563
  }
@@ -15049,7 +15738,7 @@ function groupCommandItems(items) {
15049
15738
  // src/components/CommandPalette.tsx
15050
15739
  var import_jsx_runtime105 = require("react/jsx-runtime");
15051
15740
  var CmdkContext = (0, import_react91.createContext)(null);
15052
- var useIsomorphicLayoutEffect22 = typeof document !== "undefined" ? import_react91.useLayoutEffect : import_react91.useEffect;
15741
+ var useIsomorphicLayoutEffect23 = typeof document !== "undefined" ? import_react91.useLayoutEffect : import_react91.useEffect;
15053
15742
  function CommandPalette(props) {
15054
15743
  if (props.items) return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(CommandPaletteItems, { ...props, items: props.items });
15055
15744
  return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(CommandPaletteChildren, { ...props });
@@ -15084,7 +15773,7 @@ function CommandPaletteChildren({
15084
15773
  resultsTextRef.current = resultsText;
15085
15774
  const listId = (0, import_react91.useId)();
15086
15775
  const rootRef = (0, import_react91.useRef)(null);
15087
- useIsomorphicLayoutEffect22(() => {
15776
+ useIsomorphicLayoutEffect23(() => {
15088
15777
  const overlay = rootRef.current?.closest("dialog, [popover]");
15089
15778
  if (!overlay || overlay.hasAttribute("data-uix-instant")) return;
15090
15779
  overlay.setAttribute("data-uix-instant", "");
@@ -15596,7 +16285,7 @@ function treeNav(flat, currentId, key) {
15596
16285
 
15597
16286
  // src/components/Tree.tsx
15598
16287
  var import_jsx_runtime108 = require("react/jsx-runtime");
15599
- var ChevronIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("svg", { viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("path", { d: "M2 4l4 4 4-4" }) });
16288
+ var ChevronIcon3 = () => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("svg", { viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("path", { d: "M2 4l4 4 4-4" }) });
15600
16289
  var DEFAULT_TREE_LABELS = {
15601
16290
  loading: "Loading\u2026",
15602
16291
  error: "Could not load.",
@@ -15650,7 +16339,7 @@ function TreeNode({ node, expanded, selected, selectable, tabbableId, onToggle,
15650
16339
  onToggle(node.id);
15651
16340
  onFocusNode(node.id);
15652
16341
  },
15653
- children: /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(ChevronIcon2, {})
16342
+ children: /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(ChevronIcon3, {})
15654
16343
  }
15655
16344
  )
15656
16345
  ) : /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("span", { className: "uix-tree__toggle" }),
@@ -16050,7 +16739,7 @@ function VirtualTreeView({
16050
16739
  onToggle(f.node.id);
16051
16740
  setFocusedId(f.node.id);
16052
16741
  },
16053
- children: /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(ChevronIcon2, {})
16742
+ children: /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(ChevronIcon3, {})
16054
16743
  }
16055
16744
  )
16056
16745
  ) : /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("span", { className: "uix-tree__toggle" }),
@@ -16113,7 +16802,7 @@ var idRef = (chartId, nodeId, part) => {
16113
16802
  return `${chartId}-${nodeId.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 40)}-${hash.toString(36)}-${part}`;
16114
16803
  };
16115
16804
  var isExpandable = (node, known, lazy) => known ? known.length > 0 : lazy && (node.reportCount ?? 0) > 0;
16116
- var ChevronIcon3 = () => /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("svg", { viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("path", { d: "M2 4l4 4 4-4" }) });
16805
+ var ChevronIcon4 = () => /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("svg", { viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("path", { d: "M2 4l4 4 4-4" }) });
16117
16806
  var PlusIcon3 = () => /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("path", { d: "M8 3v10M3 8h10" }) });
16118
16807
  var MinusIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("path", { d: "M3 8h10" }) });
16119
16808
  var FitIcon = () => /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("path", { d: "M2 6V2h4M14 6V2h-4M2 10v4h4M14 10v4h-4" }) });
@@ -16208,7 +16897,7 @@ function OrgChartItem({ node, level, size, pos, ctx }) {
16208
16897
  ctx.onToggle(node.id);
16209
16898
  },
16210
16899
  children: [
16211
- /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(ChevronIcon3, {}),
16900
+ /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(ChevronIcon4, {}),
16212
16901
  count2 > 0 ? count2 : null
16213
16902
  ]
16214
16903
  }
@@ -19691,7 +20380,7 @@ var DEFAULT_UNITS = { row: 36, pad: 16, head: 40 };
19691
20380
  var ESTIMATED_VIEWPORT = 720;
19692
20381
  var OVERSCAN_ROWS = 4;
19693
20382
  var BAR_MIN_FALLBACK = 1.5 * 16;
19694
- var useIsomorphicLayoutEffect23 = typeof document !== "undefined" ? import_react102.useLayoutEffect : import_react102.useEffect;
20383
+ var useIsomorphicLayoutEffect24 = typeof document !== "undefined" ? import_react102.useLayoutEffect : import_react102.useEffect;
19695
20384
  var sameExtent = (a, b) => a.subRows === b.subRows && a.lanes === b.lanes && a.heads === b.heads;
19696
20385
  var IN_LANE = { scope: "lane", labelTops: ["0%"] };
19697
20386
  var vars3 = (values) => values;
@@ -19801,7 +20490,7 @@ function SchedulingTimeline({
19801
20490
  // eslint-disable-line react-hooks/exhaustive-deps
19802
20491
  );
19803
20492
  const tickCount = ticks.length;
19804
- useIsomorphicLayoutEffect23(() => {
20493
+ useIsomorphicLayoutEffect24(() => {
19805
20494
  if (!layerTrack) return void 0;
19806
20495
  const measure3 = () => {
19807
20496
  const width = layerTrack.getBoundingClientRect().width;
@@ -19955,7 +20644,7 @@ function SchedulingTimeline({
19955
20644
  list.sort((a, b) => a - b);
19956
20645
  return { mounted: list, windowStart: window_.start };
19957
20646
  }, [virtual, rows, offsets, view, overscan, pinned, focusedRow, anchorRow]);
19958
- useIsomorphicLayoutEffect23(() => {
20647
+ useIsomorphicLayoutEffect24(() => {
19959
20648
  const anchor = anchorRef.current;
19960
20649
  if (anchorKey === null || !anchor || anchor.key !== anchorKey) return;
19961
20650
  anchorRef.current = null;
@@ -21413,7 +22102,7 @@ function EquivalentRelationshipList({
21413
22102
  // src/components/RelationshipGraphLayered.tsx
21414
22103
  var import_jsx_runtime120 = require("react/jsx-runtime");
21415
22104
  var EMPTY_IDS2 = /* @__PURE__ */ new Set();
21416
- var useIsomorphicLayoutEffect24 = typeof document !== "undefined" ? import_react105.useLayoutEffect : import_react105.useEffect;
22105
+ var useIsomorphicLayoutEffect25 = typeof document !== "undefined" ? import_react105.useLayoutEffect : import_react105.useEffect;
21417
22106
  var MIN_ZOOM2 = 0.4;
21418
22107
  var MAX_ZOOM2 = 1.5;
21419
22108
  var READABLE_ZOOM = 0.75;
@@ -21873,7 +22562,7 @@ function LayeredRelationshipGraph({
21873
22562
  }) })
21874
22563
  ] });
21875
22564
  }, [layout, activeIds, highlightedEdgeIds, conflictedEdgeIds, dimmedNodeIds, labelPlacement, labels]);
21876
- useIsomorphicLayoutEffect24(() => {
22565
+ useIsomorphicLayoutEffect25(() => {
21877
22566
  const svg2 = edgesRef.current;
21878
22567
  if (!svg2) return;
21879
22568
  for (const group2 of Array.from(svg2.querySelectorAll(".uix-relationship-graph__edge-label"))) {