@tensor_1/react 2.49.1 → 2.51.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/components/DataWorkspace.d.ts +216 -9
- package/dist/components/DataWorkspace.js +849 -93
- package/dist/components/FilterEditor.d.ts +3 -1
- package/dist/components/FilterEditor.js +22 -6
- package/dist/components/SearchBar.d.ts +3 -1
- package/dist/components/SearchBar.js +2 -0
- package/dist/components/Table.d.ts +10 -1
- package/dist/components/Table.js +12 -4
- package/dist/filter-model.d.ts +15 -1
- package/dist/filter-model.js +8 -2
- package/dist/index.cjs +911 -118
- package/dist/index.d.cts +263 -14
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -0
- package/dist/labels-context.d.ts +6 -1
- package/dist/table-engine.d.ts +14 -3
- package/dist/table-engine.js +7 -2
- package/package.json +1 -1
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useEffect, useId, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { memo, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { cx } from "../cx.js";
|
|
5
|
+
import { toggleSort } from "../table-engine.js";
|
|
5
6
|
import { fillLabel } from "../fill-label.js";
|
|
6
7
|
import { useUixLabels } from "../labels-context.js";
|
|
7
8
|
import { renderUixLink } from "../link.js";
|
|
8
9
|
import { isFilterEmpty, summarizeFilter } from "../filter-model.js";
|
|
9
10
|
import { useResolvedFilterLabels } from "../hooks/useResolvedFilterLabels.js";
|
|
11
|
+
import { useVirtualRows } from "../hooks/useVirtualRows.js";
|
|
10
12
|
import { BusyRegion } from "./BusyRegion.js";
|
|
11
13
|
import { Button } from "./Button.js";
|
|
12
14
|
import { Checkbox } from "./Checkbox.js";
|
|
@@ -45,25 +47,60 @@ const DEFAULT_DATA_WORKSPACE_LABELS = {
|
|
|
45
47
|
filteredEmpty: "Nothing matches",
|
|
46
48
|
filteredEmptyDetail: "Change the search or clear a filter.",
|
|
47
49
|
error: "The list could not be loaded",
|
|
48
|
-
retry: "Try again"
|
|
50
|
+
retry: "Try again",
|
|
51
|
+
sortPriority: "Sort priority {n}",
|
|
52
|
+
groupCount: "{count} rows",
|
|
53
|
+
groupCountOne: "{count} row",
|
|
54
|
+
collapseGroup: "Collapse group {name}",
|
|
55
|
+
expandGroup: "Expand group {name}",
|
|
56
|
+
selectGroup: "Select group {name}"
|
|
49
57
|
};
|
|
58
|
+
const useIsomorphicLayoutEffect = typeof document !== "undefined" ? useLayoutEffect : useEffect;
|
|
50
59
|
const ArrowUpRight = () => /* @__PURE__ */ 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__ */ jsx("path", { d: "M7 17 17 7M8 7h9v9" }) });
|
|
51
60
|
const PlusIcon = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx("path", { d: "M12 5v14M5 12h14" }) });
|
|
52
61
|
const MaximizeIcon = ({ restore }) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx("path", { d: restore ? "M4 14h6v6M20 10h-6V4M14 10l7-7M3 21l7-7" : "M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" }) });
|
|
62
|
+
const ChevronIcon = () => /* @__PURE__ */ 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__ */ jsx("path", { d: "M6 4l4 4-4 4" }) });
|
|
63
|
+
const LADDER_CARDS = 768;
|
|
64
|
+
const LADDER_LOW = 900;
|
|
65
|
+
const LADDER_MID = 600;
|
|
66
|
+
const ladderFor = (mobile, width) => {
|
|
67
|
+
if (!mobile || !(width > 0)) return null;
|
|
68
|
+
if (mobile === "cards" && width < LADDER_CARDS) return "cards";
|
|
69
|
+
if (width < LADDER_MID) return "priority-mid";
|
|
70
|
+
if (width < LADDER_LOW) return "priority";
|
|
71
|
+
return null;
|
|
72
|
+
};
|
|
73
|
+
const hiddenBy = (ladder, priority) => ladder === "priority" && priority === "low" || ladder === "priority-mid" && (priority === "low" || priority === "mid");
|
|
74
|
+
const ROW_HEIGHT = { compact: 44, standard: 56, comfortable: 68 };
|
|
75
|
+
const CONTROLS = 'a, button, input, select, textarea, label, summary, dialog, [role="button"], [role="menuitem"], [contenteditable="true"], [popover], td.uix-table__selcell, td.uix-table__actions';
|
|
76
|
+
const RESERVED_COLS = /* @__PURE__ */ new Set(["select", "id", "actions", "expand"]);
|
|
77
|
+
const textOf = (node) => typeof node === "string" ? node : void 0;
|
|
78
|
+
const columnLabel = (column) => column.label ?? textOf(column.header);
|
|
79
|
+
const ladderAttrs = (on, column, body) => on ? {
|
|
80
|
+
"data-col": RESERVED_COLS.has(column.id) ? void 0 : column.id,
|
|
81
|
+
"data-priority": column.priority && column.priority !== "high" ? column.priority : void 0,
|
|
82
|
+
"data-label": body ? columnLabel(column) : void 0
|
|
83
|
+
} : {};
|
|
53
84
|
function DataWorkspace({
|
|
54
85
|
label,
|
|
55
86
|
rows,
|
|
56
87
|
getRowId,
|
|
88
|
+
rowLabel,
|
|
57
89
|
columns,
|
|
58
90
|
idColumn,
|
|
59
91
|
sort,
|
|
60
92
|
onSortChange,
|
|
61
93
|
selection,
|
|
62
94
|
onSelectionChange,
|
|
95
|
+
maxSelection,
|
|
63
96
|
bulkActions,
|
|
64
97
|
rowActions,
|
|
65
98
|
getRowProps,
|
|
66
99
|
density,
|
|
100
|
+
zebra,
|
|
101
|
+
freezeFirstColumn = false,
|
|
102
|
+
fixed,
|
|
103
|
+
mobile,
|
|
67
104
|
search,
|
|
68
105
|
filters,
|
|
69
106
|
savedViews,
|
|
@@ -71,13 +108,32 @@ function DataWorkspace({
|
|
|
71
108
|
viewChanged = false,
|
|
72
109
|
onSaveView,
|
|
73
110
|
onSaveViewAs,
|
|
111
|
+
saveViewAs = "changed",
|
|
74
112
|
maximized = false,
|
|
75
113
|
onMaximizedChange,
|
|
76
114
|
toolbarEnd,
|
|
115
|
+
beforeBody,
|
|
77
116
|
pagination,
|
|
78
117
|
status = "ready",
|
|
79
118
|
refreshing = false,
|
|
80
119
|
onRetry,
|
|
120
|
+
loadingRows = 6,
|
|
121
|
+
empty,
|
|
122
|
+
emptyAction,
|
|
123
|
+
filteredEmpty,
|
|
124
|
+
filteredEmptyAction,
|
|
125
|
+
error,
|
|
126
|
+
stateOverride,
|
|
127
|
+
groups,
|
|
128
|
+
collapsedGroups,
|
|
129
|
+
onCollapsedGroupsChange,
|
|
130
|
+
virtualize,
|
|
131
|
+
rowNavigation,
|
|
132
|
+
onRowActivate,
|
|
133
|
+
activateOnClick = true,
|
|
134
|
+
activeRowId,
|
|
135
|
+
onActiveRowChange,
|
|
136
|
+
multiSort = false,
|
|
81
137
|
labels: labelOverrides,
|
|
82
138
|
className,
|
|
83
139
|
...props
|
|
@@ -111,68 +167,128 @@ function DataWorkspace({
|
|
|
111
167
|
const root = rootRef.current;
|
|
112
168
|
const target = event.target;
|
|
113
169
|
const owner = target?.closest?.('[popover], [role="dialog"], [role="menu"], [role="listbox"], [aria-expanded="true"]');
|
|
114
|
-
if (owner && root?.contains(owner)) return;
|
|
170
|
+
if (owner && root?.contains(owner) && (owner.getAttribute("aria-expanded") !== "true" || stillExpanded(owner))) return;
|
|
115
171
|
if (root && openInside(root)) return;
|
|
116
172
|
onMaximizedChange(false);
|
|
117
173
|
};
|
|
118
174
|
window.addEventListener("keydown", onKey);
|
|
119
175
|
return () => window.removeEventListener("keydown", onKey);
|
|
120
176
|
}, [maximized, onMaximizedChange]);
|
|
177
|
+
const [ladder, setLadder] = useState(null);
|
|
178
|
+
useIsomorphicLayoutEffect(() => {
|
|
179
|
+
const root = rootRef.current;
|
|
180
|
+
if (!mobile || !root) {
|
|
181
|
+
setLadder(null);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const read = () => {
|
|
185
|
+
const style = getComputedStyle(root);
|
|
186
|
+
const padding = (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0);
|
|
187
|
+
setLadder(ladderFor(mobile, root.getBoundingClientRect().width - padding));
|
|
188
|
+
};
|
|
189
|
+
read();
|
|
190
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
191
|
+
const observer = new ResizeObserver(read);
|
|
192
|
+
observer.observe(root);
|
|
193
|
+
return () => observer.disconnect();
|
|
194
|
+
}, [mobile]);
|
|
195
|
+
const cards = ladder === "cards";
|
|
121
196
|
const filtered = (filters ? filters.fields.some((field) => !isFilterEmpty(filters.values[field.id])) : false) || (search?.value.trim() ?? "") !== "";
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
const
|
|
197
|
+
const source = groups ?? rows;
|
|
198
|
+
const flat = useMemo(() => groups ? groups.flatMap((group) => group.rows) : rows, [groups, rows]);
|
|
199
|
+
const current = { source, flat, groups, filtered };
|
|
200
|
+
const [settled, setSettled] = useState(current);
|
|
201
|
+
if (!refreshing && source !== settled.source) setSettled(current);
|
|
202
|
+
const view = flat.length > 0 ? current : refreshing || source === settled.source ? settled : current;
|
|
203
|
+
const shownRows = view.flat;
|
|
204
|
+
const shownGroups = view.groups;
|
|
205
|
+
const [ownCollapsed, setOwnCollapsed] = useState(() => /* @__PURE__ */ new Set());
|
|
206
|
+
const collapsed = collapsedGroups ?? ownCollapsed;
|
|
207
|
+
const toggleGroupOpen = (groupId) => {
|
|
208
|
+
const next = new Set(collapsed);
|
|
209
|
+
if (next.has(groupId)) next.delete(groupId);
|
|
210
|
+
else next.add(groupId);
|
|
211
|
+
if (!collapsedGroups) setOwnCollapsed(next);
|
|
212
|
+
onCollapsedGroupsChange?.(next);
|
|
213
|
+
};
|
|
126
214
|
const ids = useMemo(() => shownRows.map(getRowId), [shownRows, getRowId]);
|
|
127
|
-
const
|
|
215
|
+
const visibleIds = useMemo(() => {
|
|
216
|
+
if (!shownGroups) return ids;
|
|
217
|
+
const out = [];
|
|
218
|
+
for (const group of shownGroups) if (!collapsed.has(group.id)) for (const row of group.rows) out.push(getRowId(row));
|
|
219
|
+
return out;
|
|
220
|
+
}, [shownGroups, collapsed, ids, getRowId]);
|
|
221
|
+
const selected = selection ?? EMPTY_SET;
|
|
128
222
|
const selectable = onSelectionChange != null;
|
|
223
|
+
const cap = maxSelection ?? Infinity;
|
|
129
224
|
const onPage = ids.filter((rowId) => selected.has(rowId)).length;
|
|
225
|
+
const apply = (next, rowIds, on) => {
|
|
226
|
+
for (const rowId of rowIds) {
|
|
227
|
+
if (!on) next.delete(rowId);
|
|
228
|
+
else if (next.has(rowId) || next.size < cap) next.add(rowId);
|
|
229
|
+
}
|
|
230
|
+
return next;
|
|
231
|
+
};
|
|
130
232
|
const toggleRow = (rowId, on, event) => {
|
|
131
233
|
if (!onSelectionChange) return;
|
|
132
234
|
const next = new Set(selected);
|
|
133
|
-
const from = anchor.current ?
|
|
134
|
-
const to =
|
|
235
|
+
const from = anchor.current ? visibleIds.indexOf(anchor.current) : -1;
|
|
236
|
+
const to = visibleIds.indexOf(rowId);
|
|
135
237
|
if (event?.shiftKey && from >= 0 && to >= 0) {
|
|
136
|
-
|
|
137
|
-
if (on) next.add(ids[i]);
|
|
138
|
-
else next.delete(ids[i]);
|
|
139
|
-
}
|
|
238
|
+
apply(next, visibleIds.slice(Math.min(from, to), Math.max(from, to) + 1), on);
|
|
140
239
|
} else {
|
|
141
|
-
|
|
142
|
-
else next.delete(rowId);
|
|
240
|
+
apply(next, [rowId], on);
|
|
143
241
|
anchor.current = rowId;
|
|
144
242
|
}
|
|
145
243
|
onSelectionChange(next);
|
|
146
244
|
};
|
|
147
|
-
const
|
|
245
|
+
const toggleMany = (rowIds, on) => {
|
|
148
246
|
if (!onSelectionChange) return;
|
|
149
|
-
|
|
150
|
-
for (const rowId of ids) {
|
|
151
|
-
if (on) next.add(rowId);
|
|
152
|
-
else next.delete(rowId);
|
|
153
|
-
}
|
|
154
|
-
onSelectionChange(next);
|
|
247
|
+
onSelectionChange(apply(new Set(selected), rowIds, on));
|
|
155
248
|
};
|
|
156
|
-
const
|
|
249
|
+
const atCap = selected.size >= cap;
|
|
250
|
+
const actionsByRow = useMemo(() => {
|
|
251
|
+
if (!rowActions) return [];
|
|
252
|
+
const context = { ladder, compact: ladder === "priority-mid" };
|
|
253
|
+
return shownRows.map((row) => rowActions(row, context));
|
|
254
|
+
}, [shownRows, rowActions, ladder]);
|
|
157
255
|
const hasActions = actionsByRow.some((node) => node != null && node !== false);
|
|
158
256
|
const activeFilters = filters ? filters.fields.filter((field) => !isFilterEmpty(filters.values[field.id])) : [];
|
|
159
257
|
const searching = (search?.value.trim() ?? "") !== "";
|
|
160
258
|
const clearAll = () => {
|
|
259
|
+
if (filters?.onClearAll) {
|
|
260
|
+
filters.onClearAll({ search: searching });
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
161
263
|
for (const field of activeFilters) filters?.onChange(field.id, void 0);
|
|
162
264
|
if (searching) search?.onChange("");
|
|
163
265
|
};
|
|
164
|
-
const
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
266
|
+
const multi = multiSort || Array.isArray(sort);
|
|
267
|
+
const keys = Array.isArray(sort) ? sort : sort ? [sort] : [];
|
|
268
|
+
const sortFor = (column) => keys.find((key) => key.columnId === column.id)?.direction ?? "none";
|
|
269
|
+
const cycleSort = (column, additive) => {
|
|
270
|
+
if (!onSortChange) return;
|
|
271
|
+
const current2 = sortFor(column);
|
|
272
|
+
const turned = current2 === "none" ? "ascending" : current2 === "ascending" ? "descending" : null;
|
|
273
|
+
if (!multi) {
|
|
274
|
+
onSortChange(turned ? { columnId: column.id, direction: turned } : null);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
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" }));
|
|
278
|
+
onSortChange(next);
|
|
168
279
|
};
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
280
|
+
const showSaveAs = onSaveViewAs != null && (viewChanged || saveViewAs === "always");
|
|
281
|
+
const hasToolbar = savedViews != null || viewChanged && onSaveView != null || showSaveAs || filters != null || search != null || viewMenu != null || onMaximizedChange != null || toolbarEnd != null && toolbarEnd !== false;
|
|
282
|
+
const toolbar = hasToolbar && /* @__PURE__ */ jsxs("div", { className: "uix-toolbar uix-data-workspace__toolbar", role: "toolbar", "aria-label": label, children: [
|
|
283
|
+
savedViews && /* @__PURE__ */ 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__ */ jsxs(Fragment, { children: [
|
|
284
|
+
savedViews.note != null && /* @__PURE__ */ jsx("div", { className: "uix-data-workspace__views-note", children: savedViews.note }),
|
|
285
|
+
/* @__PURE__ */ jsx(SavedViewMenu, { ...savedViews.menu, onSelect: (viewId) => {
|
|
286
|
+
savedViews.menu.onSelect(viewId);
|
|
287
|
+
close();
|
|
288
|
+
} })
|
|
289
|
+
] }) }),
|
|
174
290
|
viewChanged && onSaveView && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "secondary", onClick: onSaveView, children: labels.saveView }),
|
|
175
|
-
|
|
291
|
+
showSaveAs && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", onClick: onSaveViewAs, children: labels.saveViewAs }),
|
|
176
292
|
filters && /* @__PURE__ */ jsx(FilterChips, { filters, labels, baseId: id }),
|
|
177
293
|
/* @__PURE__ */ jsx("span", { className: "uix-toolbar__spacer" }),
|
|
178
294
|
search && /* @__PURE__ */ jsx(
|
|
@@ -184,67 +300,78 @@ function DataWorkspace({
|
|
|
184
300
|
placeholder: search.placeholder ?? labels.searchPlaceholder,
|
|
185
301
|
value: search.value,
|
|
186
302
|
onValueChange: search.onChange,
|
|
187
|
-
inputRef: searchRef
|
|
303
|
+
inputRef: searchRef,
|
|
304
|
+
onSubmit: search.onSubmit,
|
|
305
|
+
onClear: search.onClear,
|
|
306
|
+
maxLength: search.maxLength
|
|
188
307
|
}
|
|
189
308
|
),
|
|
190
309
|
viewMenu && /* @__PURE__ */ jsx(PopoverButton, { id: `${id}-view`, label: labels.view, variant: "ghost", children: () => /* @__PURE__ */ jsx(ViewMenu, { ...viewMenu }) }),
|
|
191
310
|
onMaximizedChange && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", icon: true, "aria-label": maximized ? labels.restore : labels.maximize, "aria-pressed": maximized, onClick: () => onMaximizedChange(!maximized), children: /* @__PURE__ */ jsx(MaximizeIcon, { restore: maximized }) }),
|
|
192
311
|
toolbarEnd
|
|
193
312
|
] });
|
|
313
|
+
const busy = (node) => /* @__PURE__ */ jsx(BusyRegion, { busy: refreshing, className: "uix-data-workspace__state", children: node });
|
|
194
314
|
let body;
|
|
195
|
-
if (
|
|
196
|
-
else if (status === "
|
|
315
|
+
if (stateOverride != null) body = busy(stateOverride);
|
|
316
|
+
else if (status === "loading") body = /* @__PURE__ */ jsx(LoadingState, { rows: loadingRows, label: labels.loading, className: "uix-data-workspace__loading" });
|
|
317
|
+
else if (status === "error") body = error != null ? busy(error) : /* @__PURE__ */ jsx(ErrorState, { title: labels.error, action: onRetry && /* @__PURE__ */ jsx(Button, { size: "sm", onClick: onRetry, children: labels.retry }) });
|
|
197
318
|
else if (shownRows.length === 0) {
|
|
198
|
-
|
|
319
|
+
const clear = /* @__PURE__ */ jsx(Button, { size: "sm", onClick: clearAll, children: labels.clearFilters });
|
|
320
|
+
body = busy(view.filtered ? filteredEmpty ?? /* @__PURE__ */ jsx(
|
|
321
|
+
FilteredEmptyState,
|
|
322
|
+
{
|
|
323
|
+
title: labels.filteredEmpty,
|
|
324
|
+
action: filteredEmptyAction != null ? /* @__PURE__ */ jsxs("div", { className: "uix-data-workspace__state-actions", children: [
|
|
325
|
+
clear,
|
|
326
|
+
filteredEmptyAction
|
|
327
|
+
] }) : clear,
|
|
328
|
+
children: labels.filteredEmptyDetail
|
|
329
|
+
}
|
|
330
|
+
) : empty ?? /* @__PURE__ */ jsx(EmptyState, { title: labels.empty, action: emptyAction, children: labels.emptyDetail }));
|
|
199
331
|
} else {
|
|
200
|
-
body = /* @__PURE__ */ jsx(
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
columns.map((column) => /* @__PURE__ */ jsx(Td, { className: column.align === "end" ? "uix-col--num" : void 0, children: column.cell(row) }, column.id)),
|
|
244
|
-
hasActions && /* @__PURE__ */ jsx(RowActions, { children: actionsByRow[index] })
|
|
245
|
-
] }, rowId);
|
|
246
|
-
}) })
|
|
247
|
-
] }) });
|
|
332
|
+
body = /* @__PURE__ */ jsx(
|
|
333
|
+
WorkspaceGrid,
|
|
334
|
+
{
|
|
335
|
+
label,
|
|
336
|
+
rows: shownRows,
|
|
337
|
+
ids,
|
|
338
|
+
groups: shownGroups,
|
|
339
|
+
collapsed,
|
|
340
|
+
onToggleGroup: toggleGroupOpen,
|
|
341
|
+
getRowId,
|
|
342
|
+
rowLabel,
|
|
343
|
+
columns,
|
|
344
|
+
idColumn,
|
|
345
|
+
getRowProps,
|
|
346
|
+
density,
|
|
347
|
+
zebra,
|
|
348
|
+
freezeFirstColumn,
|
|
349
|
+
fixed: fixed ?? columns.some((column) => column.className != null || column.minWidth != null),
|
|
350
|
+
ladderOn: mobile != null,
|
|
351
|
+
ladder,
|
|
352
|
+
refreshing,
|
|
353
|
+
selectable,
|
|
354
|
+
selected,
|
|
355
|
+
onPage,
|
|
356
|
+
atCap,
|
|
357
|
+
toggleRow,
|
|
358
|
+
toggleMany,
|
|
359
|
+
actionsByRow,
|
|
360
|
+
hasActions,
|
|
361
|
+
keys,
|
|
362
|
+
sortable: onSortChange != null,
|
|
363
|
+
multi,
|
|
364
|
+
sortFor,
|
|
365
|
+
cycleSort,
|
|
366
|
+
virtualize: pagination || shownGroups ? void 0 : virtualize,
|
|
367
|
+
rowNavigation: rowNavigation ?? onRowActivate != null,
|
|
368
|
+
onRowActivate,
|
|
369
|
+
activateOnClick,
|
|
370
|
+
activeRowId,
|
|
371
|
+
onActiveRowChange,
|
|
372
|
+
labels
|
|
373
|
+
}
|
|
374
|
+
);
|
|
248
375
|
}
|
|
249
376
|
const selectedIds = [...selected];
|
|
250
377
|
return /* @__PURE__ */ jsxs(
|
|
@@ -257,13 +384,627 @@ function DataWorkspace({
|
|
|
257
384
|
children: [
|
|
258
385
|
toolbar,
|
|
259
386
|
bulkActions && selectedIds.length > 0 && /* @__PURE__ */ jsx(BulkBar, { count: selectedIds.length, label: labels.bulkActions, selectedLabel: (n) => fillLabel(labels.selected, { count: n }), children: bulkActions(selectedIds) }),
|
|
387
|
+
beforeBody != null && /* @__PURE__ */ jsx("div", { className: "uix-data-workspace__before", children: beforeBody }),
|
|
260
388
|
body,
|
|
261
|
-
pagination && status === "ready" && shownRows.length > 0 && /* @__PURE__ */ jsx(Footer, { pagination, labels, rowCount: shownRows.length })
|
|
389
|
+
pagination && status === "ready" && stateOverride == null && shownRows.length > 0 && /* @__PURE__ */ jsx(Footer, { pagination, labels, rowCount: shownRows.length })
|
|
262
390
|
]
|
|
263
391
|
}
|
|
264
392
|
);
|
|
265
393
|
}
|
|
394
|
+
const EMPTY_SET = /* @__PURE__ */ new Set();
|
|
395
|
+
function WorkspaceGrid(props) {
|
|
396
|
+
return props.virtualize ? /* @__PURE__ */ jsx(WindowedGrid, { ...props }) : /* @__PURE__ */ jsx(WorkspaceTable, { ...props, windowing: null, virtual: null });
|
|
397
|
+
}
|
|
398
|
+
function WindowedGrid(props) {
|
|
399
|
+
const windowing = props.virtualize === true || !props.virtualize ? {} : props.virtualize;
|
|
400
|
+
const threshold = windowing.threshold ?? 100;
|
|
401
|
+
const virtual = useVirtualRows(props.rows, {
|
|
402
|
+
rowHeight: windowing.estimatedRowHeight ?? ROW_HEIGHT[props.density ?? "standard"],
|
|
403
|
+
overscan: windowing.overscan ?? 8,
|
|
404
|
+
// windowed at `threshold` rows or more (the hook windows above its own threshold)
|
|
405
|
+
threshold: Math.max(0, threshold - 1),
|
|
406
|
+
estimatedViewportHeight: windowing.maxHeight ?? 640,
|
|
407
|
+
measureRows: "tbody > tr[data-uix-row-id]",
|
|
408
|
+
// cards are not windowed: a card's height is its content's
|
|
409
|
+
enabled: props.rows.length >= threshold && props.ladder !== "cards"
|
|
410
|
+
});
|
|
411
|
+
return /* @__PURE__ */ jsx(WorkspaceTable, { ...props, windowing, virtual });
|
|
412
|
+
}
|
|
413
|
+
const columnFloor = (width, minWidth, className) => {
|
|
414
|
+
if (minWidth) return minWidth;
|
|
415
|
+
if (width && !width.trim().endsWith("%")) return width;
|
|
416
|
+
const classes = className?.split(/\s+/) ?? [];
|
|
417
|
+
for (const cls of classes) {
|
|
418
|
+
const tier = /^uix-col--w-(xs|sm|md|lg|xl)$/.exec(cls)?.[1];
|
|
419
|
+
if (tier) return `var(--uix-col-w-${tier})`;
|
|
420
|
+
}
|
|
421
|
+
if (classes.includes("uix-col--flex") || classes.includes("uix-col--primary")) return "var(--uix-col-title-min)";
|
|
422
|
+
return "var(--uix-col-w-sm)";
|
|
423
|
+
};
|
|
424
|
+
const isFlex = (className) => /(^|\s)uix-col--(flex|primary)(\s|$)/.test(className ?? "");
|
|
425
|
+
const colClasses = (className) => className?.split(/\s+/).filter((cls) => /^uix-col--(w-(xs|sm|md|lg|xl)|flex|primary)$/.test(cls)).join(" ") || void 0;
|
|
426
|
+
function WorkspaceTable({
|
|
427
|
+
label,
|
|
428
|
+
rows,
|
|
429
|
+
ids,
|
|
430
|
+
groups,
|
|
431
|
+
collapsed,
|
|
432
|
+
onToggleGroup,
|
|
433
|
+
getRowId,
|
|
434
|
+
rowLabel,
|
|
435
|
+
columns,
|
|
436
|
+
idColumn,
|
|
437
|
+
getRowProps,
|
|
438
|
+
density,
|
|
439
|
+
zebra,
|
|
440
|
+
freezeFirstColumn,
|
|
441
|
+
fixed,
|
|
442
|
+
ladderOn,
|
|
443
|
+
ladder,
|
|
444
|
+
refreshing,
|
|
445
|
+
selectable,
|
|
446
|
+
selected,
|
|
447
|
+
onPage,
|
|
448
|
+
atCap,
|
|
449
|
+
toggleRow,
|
|
450
|
+
toggleMany,
|
|
451
|
+
actionsByRow,
|
|
452
|
+
hasActions,
|
|
453
|
+
keys,
|
|
454
|
+
sortable,
|
|
455
|
+
multi,
|
|
456
|
+
sortFor,
|
|
457
|
+
cycleSort,
|
|
458
|
+
rowNavigation,
|
|
459
|
+
onRowActivate,
|
|
460
|
+
activateOnClick,
|
|
461
|
+
activeRowId,
|
|
462
|
+
onActiveRowChange,
|
|
463
|
+
labels,
|
|
464
|
+
windowing,
|
|
465
|
+
virtual
|
|
466
|
+
}) {
|
|
467
|
+
const cards = ladder === "cards";
|
|
468
|
+
const wrapRef = useRef(null);
|
|
469
|
+
const baseId = useId();
|
|
470
|
+
const maxHeight = windowing?.maxHeight ?? 640;
|
|
471
|
+
const long = windowing != null && !cards && rows.length >= (windowing.threshold ?? 100);
|
|
472
|
+
const containerRef = virtual?.containerRef;
|
|
473
|
+
const setWrap = useCallback((node) => {
|
|
474
|
+
wrapRef.current = node;
|
|
475
|
+
if (containerRef) containerRef.current = node;
|
|
476
|
+
}, [containerRef]);
|
|
477
|
+
const windowed = virtual?.virtualized ?? false;
|
|
478
|
+
const start = virtual && windowed ? virtual.startIndex : 0;
|
|
479
|
+
const mountedRows = virtual && windowed ? virtual.rows : rows;
|
|
480
|
+
const nav = rowNavigation;
|
|
481
|
+
const clickActivates = onRowActivate != null && activateOnClick;
|
|
482
|
+
const [ownActive, setOwnActive] = useState(null);
|
|
483
|
+
const active = activeRowId !== void 0 ? activeRowId : ownActive;
|
|
484
|
+
const navIds = useMemo(() => {
|
|
485
|
+
if (!groups) return ids;
|
|
486
|
+
const out = [];
|
|
487
|
+
for (const group of groups) if (!collapsed.has(group.id)) for (const row of group.rows) out.push(getRowId(row));
|
|
488
|
+
return out;
|
|
489
|
+
}, [groups, collapsed, ids, getRowId]);
|
|
490
|
+
const mountedIds = useMemo(() => new Set(windowed ? ids.slice(start, start + mountedRows.length) : navIds), [windowed, ids, start, mountedRows.length, navIds]);
|
|
491
|
+
const tabStop = active != null && mountedIds.has(active) ? active : navIds.find((rowId) => mountedIds.has(rowId)) ?? null;
|
|
492
|
+
const pendingFocus = useRef(null);
|
|
493
|
+
const focusedRow = useRef(null);
|
|
494
|
+
const rowElement = (rowId) => {
|
|
495
|
+
for (const el of Array.from(wrapRef.current?.querySelectorAll("tbody > tr[data-uix-row-id]") ?? [])) {
|
|
496
|
+
if (el.getAttribute("data-uix-row-id") === rowId) return el;
|
|
497
|
+
}
|
|
498
|
+
return null;
|
|
499
|
+
};
|
|
500
|
+
const reveal = (el) => {
|
|
501
|
+
el.scrollIntoView?.({ block: "nearest", inline: "nearest" });
|
|
502
|
+
const wrap = wrapRef.current;
|
|
503
|
+
const head = wrap?.querySelector("thead");
|
|
504
|
+
if (wrap && head && windowed) {
|
|
505
|
+
const under = head.getBoundingClientRect().bottom - el.getBoundingClientRect().top;
|
|
506
|
+
if (under > 0) wrap.scrollTop -= under;
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
const setActive = (rowId) => {
|
|
510
|
+
if (rowId === active) return;
|
|
511
|
+
if (activeRowId === void 0) setOwnActive(rowId);
|
|
512
|
+
onActiveRowChange?.(rowId);
|
|
513
|
+
};
|
|
514
|
+
const focusRow = (rowId, { take = true } = {}) => {
|
|
515
|
+
if (!navIds.includes(rowId)) return;
|
|
516
|
+
setActive(rowId);
|
|
517
|
+
if (!take) return;
|
|
518
|
+
const el = rowElement(rowId);
|
|
519
|
+
if (el) {
|
|
520
|
+
el.focus({ preventScroll: true });
|
|
521
|
+
reveal(el);
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
const index = ids.indexOf(rowId);
|
|
525
|
+
if (index >= 0 && wrapRef.current && virtual && windowed) {
|
|
526
|
+
pendingFocus.current = rowId;
|
|
527
|
+
wrapRef.current.scrollTop = index * virtual.rowHeight;
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
useIsomorphicLayoutEffect(() => {
|
|
531
|
+
if (!nav) return;
|
|
532
|
+
const pending = pendingFocus.current;
|
|
533
|
+
if (pending != null) {
|
|
534
|
+
if (!ids.includes(pending)) {
|
|
535
|
+
pendingFocus.current = null;
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
const el2 = rowElement(pending);
|
|
539
|
+
if (el2) {
|
|
540
|
+
pendingFocus.current = null;
|
|
541
|
+
el2.focus({ preventScroll: true });
|
|
542
|
+
reveal(el2);
|
|
543
|
+
}
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
const had = focusedRow.current;
|
|
547
|
+
if (had == null) return;
|
|
548
|
+
const wrap = wrapRef.current;
|
|
549
|
+
const focused = typeof document !== "undefined" ? document.activeElement : null;
|
|
550
|
+
const el = rowElement(had);
|
|
551
|
+
if (el && wrap && focused === wrap) {
|
|
552
|
+
el.focus({ preventScroll: true });
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
if (el || !(focused == null || focused === document.body)) return;
|
|
556
|
+
if (windowed && ids.includes(had) && wrap) {
|
|
557
|
+
wrap.focus({ preventScroll: true });
|
|
558
|
+
} else if (tabStop != null) {
|
|
559
|
+
rowElement(tabStop)?.focus({ preventScroll: true });
|
|
560
|
+
}
|
|
561
|
+
});
|
|
562
|
+
const lastActiveProp = useRef(activeRowId);
|
|
563
|
+
useEffect(() => {
|
|
564
|
+
if (!nav || activeRowId === lastActiveProp.current) return;
|
|
565
|
+
lastActiveProp.current = activeRowId;
|
|
566
|
+
if (activeRowId == null) return;
|
|
567
|
+
const focused = document.activeElement;
|
|
568
|
+
const el = rowElement(activeRowId);
|
|
569
|
+
if (el && el.contains(focused)) return;
|
|
570
|
+
const mayTake = focused == null || focused === document.body || (wrapRef.current?.contains(focused) ?? false);
|
|
571
|
+
focusRow(activeRowId, { take: mayTake });
|
|
572
|
+
});
|
|
573
|
+
const latest = {
|
|
574
|
+
toggle: (rowId, on, event) => toggleRow(rowId, on, event),
|
|
575
|
+
key: (rowId, event) => {
|
|
576
|
+
if (event.target !== event.currentTarget || event.altKey || event.ctrlKey || event.metaKey) return;
|
|
577
|
+
const at = navIds.indexOf(rowId);
|
|
578
|
+
const to = event.key === "ArrowDown" ? at + 1 : event.key === "ArrowUp" ? at - 1 : event.key === "Home" ? 0 : event.key === "End" ? navIds.length - 1 : null;
|
|
579
|
+
if (to != null) {
|
|
580
|
+
event.preventDefault();
|
|
581
|
+
const target = navIds[Math.max(0, Math.min(navIds.length - 1, to))];
|
|
582
|
+
if (target != null) focusRow(target);
|
|
583
|
+
} else if (event.key === "Enter") {
|
|
584
|
+
event.preventDefault();
|
|
585
|
+
const row = rows[ids.indexOf(rowId)];
|
|
586
|
+
if (onRowActivate) {
|
|
587
|
+
if (row !== void 0) onRowActivate(row);
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
const el = event.currentTarget;
|
|
591
|
+
(el.querySelector(".uix-id-cell__btn") ?? el.querySelector("a[href]"))?.click();
|
|
592
|
+
} else if (event.key === " ") {
|
|
593
|
+
event.preventDefault();
|
|
594
|
+
}
|
|
595
|
+
},
|
|
596
|
+
click: (rowId, event) => {
|
|
597
|
+
if (!clickActivates) return;
|
|
598
|
+
if (!event.currentTarget.contains(event.target)) return;
|
|
599
|
+
const control = event.target.closest?.(CONTROLS);
|
|
600
|
+
if (control && control !== event.currentTarget && event.currentTarget.contains(control)) return;
|
|
601
|
+
if (typeof window !== "undefined" && (window.getSelection?.()?.toString() ?? "") !== "") return;
|
|
602
|
+
const row = rows[ids.indexOf(rowId)];
|
|
603
|
+
if (row !== void 0) onRowActivate?.(row);
|
|
604
|
+
},
|
|
605
|
+
focus: (rowId) => {
|
|
606
|
+
focusedRow.current = rowId;
|
|
607
|
+
setActive(rowId);
|
|
608
|
+
},
|
|
609
|
+
blur: (rowId, event) => {
|
|
610
|
+
const next = event.relatedTarget;
|
|
611
|
+
if (next && wrapRef.current?.contains(next)) return;
|
|
612
|
+
if (next) {
|
|
613
|
+
focusedRow.current = null;
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
const el = event.currentTarget;
|
|
617
|
+
setTimeout(() => {
|
|
618
|
+
if (el.isConnected && focusedRow.current === rowId) focusedRow.current = null;
|
|
619
|
+
}, 0);
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
const latestRef = useRef(latest);
|
|
623
|
+
latestRef.current = latest;
|
|
624
|
+
const handlers = useMemo(() => ({
|
|
625
|
+
toggle: (...args) => latestRef.current.toggle(...args),
|
|
626
|
+
key: (...args) => latestRef.current.key(...args),
|
|
627
|
+
click: (...args) => latestRef.current.click(...args),
|
|
628
|
+
focus: (...args) => latestRef.current.focus(...args),
|
|
629
|
+
blur: (...args) => latestRef.current.blur(...args)
|
|
630
|
+
}), []);
|
|
631
|
+
const groupAnchor = useRef(null);
|
|
632
|
+
const toggleGroup = (groupId, header) => {
|
|
633
|
+
groupAnchor.current = header ? { id: groupId, top: header.getBoundingClientRect().top } : null;
|
|
634
|
+
onToggleGroup(groupId);
|
|
635
|
+
};
|
|
636
|
+
useIsomorphicLayoutEffect(() => {
|
|
637
|
+
const was = groupAnchor.current;
|
|
638
|
+
if (!was) return;
|
|
639
|
+
groupAnchor.current = null;
|
|
640
|
+
const header = wrapRef.current?.querySelector(`tr[data-group-id="${cssEscape(was.id)}"]`);
|
|
641
|
+
if (!header) return;
|
|
642
|
+
const moved = header.getBoundingClientRect().top - was.top;
|
|
643
|
+
if (Math.abs(moved) < 1) return;
|
|
644
|
+
const wrap = wrapRef.current;
|
|
645
|
+
if (wrap && wrap.scrollHeight > wrap.clientHeight + 1 && getComputedStyle(wrap).overflowY !== "visible") wrap.scrollTop += moved;
|
|
646
|
+
else window.scrollBy?.(0, moved);
|
|
647
|
+
});
|
|
648
|
+
const shiftKey = useRef(false);
|
|
649
|
+
const additive = useRef(false);
|
|
650
|
+
const frozen = !cards && ladder !== "priority-mid" && (idColumn != null || freezeFirstColumn);
|
|
651
|
+
const shown = columns.filter((column) => !hiddenBy(ladder, column.priority));
|
|
652
|
+
const colCount = (selectable ? 1 : 0) + (idColumn ? 1 : 0) + shown.length + (hasActions ? 1 : 0);
|
|
653
|
+
const selectRowLabel = labels.selectRow;
|
|
654
|
+
const openLabel = labels.open;
|
|
655
|
+
const fixedOn = fixed && !cards;
|
|
656
|
+
const [actionsTooWide, setActionsTooWide] = useState(false);
|
|
657
|
+
const [actionsWidth, setActionsWidth] = useState(null);
|
|
658
|
+
const measureActions = !cards && hasActions;
|
|
659
|
+
const measureConfig = useRef({ measureActions, fixedOn, hasActions });
|
|
660
|
+
measureConfig.current = { measureActions, fixedOn, hasActions };
|
|
661
|
+
const measureActionsNow = useRef(() => {
|
|
662
|
+
});
|
|
663
|
+
measureActionsNow.current = () => {
|
|
664
|
+
const wrap = wrapRef.current;
|
|
665
|
+
const { measureActions: on, fixedOn: fixedNow, hasActions: any } = measureConfig.current;
|
|
666
|
+
if (!wrap) return;
|
|
667
|
+
const cells = Array.from(wrap.querySelectorAll("tbody td.uix-table__actions"));
|
|
668
|
+
if (!on) setActionsTooWide(false);
|
|
669
|
+
else {
|
|
670
|
+
let widest = 0;
|
|
671
|
+
for (const td of cells) if (typeof td.getBoundingClientRect === "function") widest = Math.max(widest, td.getBoundingClientRect().width, td.scrollWidth);
|
|
672
|
+
if (wrap.clientWidth > 0 && widest > 0) setActionsTooWide(widest > wrap.clientWidth / 4);
|
|
673
|
+
}
|
|
674
|
+
if (!fixedNow || !any || typeof document.createRange !== "function" || typeof getComputedStyle !== "function") return;
|
|
675
|
+
if (typeof document.createRange().getBoundingClientRect !== "function") return;
|
|
676
|
+
let content = 0;
|
|
677
|
+
for (const td of cells) {
|
|
678
|
+
const range = document.createRange();
|
|
679
|
+
range.selectNodeContents(td);
|
|
680
|
+
const style = getComputedStyle(td);
|
|
681
|
+
content = Math.max(content, range.getBoundingClientRect().width + parseFloat(style.paddingLeft || "0") + parseFloat(style.paddingRight || "0"));
|
|
682
|
+
}
|
|
683
|
+
const next = content > 0 ? Math.ceil(content) : null;
|
|
684
|
+
setActionsWidth((current) => current === next ? current : next);
|
|
685
|
+
};
|
|
686
|
+
useIsomorphicLayoutEffect(() => {
|
|
687
|
+
const wrap = wrapRef.current;
|
|
688
|
+
if (!wrap) return;
|
|
689
|
+
let frame = 0;
|
|
690
|
+
const schedule = () => {
|
|
691
|
+
if (frame || typeof requestAnimationFrame !== "function") return;
|
|
692
|
+
frame = requestAnimationFrame(() => {
|
|
693
|
+
frame = 0;
|
|
694
|
+
measureActionsNow.current();
|
|
695
|
+
});
|
|
696
|
+
};
|
|
697
|
+
const resize = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(schedule);
|
|
698
|
+
const collect = () => {
|
|
699
|
+
if (!resize) return;
|
|
700
|
+
resize.disconnect();
|
|
701
|
+
resize.observe(wrap);
|
|
702
|
+
const table = wrap.querySelector("table");
|
|
703
|
+
if (table) resize.observe(table);
|
|
704
|
+
for (const td of Array.from(wrap.querySelectorAll("tbody td.uix-table__actions"))) {
|
|
705
|
+
resize.observe(td);
|
|
706
|
+
for (const child of Array.from(td.children)) resize.observe(child);
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
collect();
|
|
710
|
+
const mutation = typeof MutationObserver === "undefined" ? null : new MutationObserver(() => {
|
|
711
|
+
collect();
|
|
712
|
+
schedule();
|
|
713
|
+
});
|
|
714
|
+
mutation?.observe(wrap, { childList: true, subtree: true });
|
|
715
|
+
return () => {
|
|
716
|
+
resize?.disconnect();
|
|
717
|
+
mutation?.disconnect();
|
|
718
|
+
if (frame && typeof cancelAnimationFrame === "function") cancelAnimationFrame(frame);
|
|
719
|
+
};
|
|
720
|
+
}, []);
|
|
721
|
+
const rowSet = ids.join("\0");
|
|
722
|
+
useIsomorphicLayoutEffect(() => {
|
|
723
|
+
measureActionsNow.current();
|
|
724
|
+
}, [measureActions, fixedOn, ladder, rowSet]);
|
|
725
|
+
const actionsCol = actionsWidth != null ? `${actionsWidth}px` : "5.25rem";
|
|
726
|
+
const floors = fixedOn ? [
|
|
727
|
+
...selectable ? ["var(--uix-selcol-w)"] : [],
|
|
728
|
+
...idColumn ? [columnFloor(idColumn.width, idColumn.minWidth, void 0)] : [],
|
|
729
|
+
...shown.map((column) => columnFloor(column.width, column.minWidth, column.className)),
|
|
730
|
+
...hasActions ? [actionsCol] : []
|
|
731
|
+
] : [];
|
|
732
|
+
const tableStyle = fixedOn && floors.length ? { minWidth: floors.length === 1 ? floors[0] : `calc(${floors.join(" + ")})` } : void 0;
|
|
733
|
+
const sortProps = (column, columnSortable) => {
|
|
734
|
+
const order = keys.findIndex((key) => key.columnId === column.id);
|
|
735
|
+
const canSort = columnSortable && sortable;
|
|
736
|
+
const ordinal = keys.length > 1 && order >= 0 ? order + 1 : void 0;
|
|
737
|
+
return {
|
|
738
|
+
sortable: canSort,
|
|
739
|
+
sortDirection: sortFor(column),
|
|
740
|
+
sortOrder: ordinal,
|
|
741
|
+
sortOrderLabel: ordinal != null ? fillLabel(labels.sortPriority, { n: ordinal }) : void 0,
|
|
742
|
+
onSort: () => {
|
|
743
|
+
cycleSort(column, multi && additive.current);
|
|
744
|
+
additive.current = false;
|
|
745
|
+
},
|
|
746
|
+
...canSort && multi ? {
|
|
747
|
+
onKeyDownCapture: (event) => {
|
|
748
|
+
if (event.key === "Enter" || event.key === " ") shiftKey.current = event.shiftKey;
|
|
749
|
+
},
|
|
750
|
+
// A click made by Enter or Space has no pointer (detail 0) and may not carry Shift itself.
|
|
751
|
+
onClickCapture: (event) => {
|
|
752
|
+
additive.current = event.shiftKey || event.detail === 0 && shiftKey.current;
|
|
753
|
+
shiftKey.current = false;
|
|
754
|
+
}
|
|
755
|
+
} : {}
|
|
756
|
+
};
|
|
757
|
+
};
|
|
758
|
+
const idSortColumn = idColumn ? { id: idColumn.id ?? "id", header: idColumn.header, cell: () => null } : null;
|
|
759
|
+
const renderRow = (row, index) => {
|
|
760
|
+
const rowId = ids[index];
|
|
761
|
+
const isSelected = selected.has(rowId);
|
|
762
|
+
return /* @__PURE__ */ jsx(
|
|
763
|
+
WorkspaceRow,
|
|
764
|
+
{
|
|
765
|
+
row,
|
|
766
|
+
rowId,
|
|
767
|
+
rowLabel,
|
|
768
|
+
columns,
|
|
769
|
+
idColumn,
|
|
770
|
+
getRowProps,
|
|
771
|
+
selectable,
|
|
772
|
+
selected: isSelected,
|
|
773
|
+
selectDisabled: !isSelected && atCap,
|
|
774
|
+
hasActions,
|
|
775
|
+
actions: actionsByRow[index],
|
|
776
|
+
ladderOn,
|
|
777
|
+
selectRowLabel,
|
|
778
|
+
openLabel,
|
|
779
|
+
marked: nav || windowing != null,
|
|
780
|
+
ariaRowIndex: windowed ? index + 2 : void 0,
|
|
781
|
+
nav,
|
|
782
|
+
tabStop: tabStop === rowId,
|
|
783
|
+
handlers
|
|
784
|
+
},
|
|
785
|
+
rowId
|
|
786
|
+
);
|
|
787
|
+
};
|
|
788
|
+
let tbody;
|
|
789
|
+
if (groups) {
|
|
790
|
+
let offset = 0;
|
|
791
|
+
tbody = groups.map((group, groupIndex) => {
|
|
792
|
+
const first = offset;
|
|
793
|
+
offset += group.rows.length;
|
|
794
|
+
const open = !collapsed.has(group.id);
|
|
795
|
+
const name = group.name ?? textOf(group.label) ?? group.id;
|
|
796
|
+
const groupIds = ids.slice(first, first + group.rows.length);
|
|
797
|
+
const on = groupIds.filter((rowId) => selected.has(rowId)).length;
|
|
798
|
+
const count = group.count ?? group.rows.length;
|
|
799
|
+
const nameId = `${baseId}-g${groupIndex}-name`;
|
|
800
|
+
const countId = `${baseId}-g${groupIndex}-count`;
|
|
801
|
+
const firstAgg = shown.findIndex((column) => group.aggregates?.[column.id] != null);
|
|
802
|
+
const lead = (idColumn ? 1 : 0) + (firstAgg < 0 ? shown.length + (hasActions ? 1 : 0) : firstAgg);
|
|
803
|
+
const leadAgg = lead === 0 && firstAgg === 0 ? group.aggregates?.[shown[0].id] : null;
|
|
804
|
+
return /* @__PURE__ */ jsxs("tbody", { className: "uix-data-workspace__group", "data-collapsed": open ? void 0 : "", children: [
|
|
805
|
+
/* @__PURE__ */ jsxs("tr", { className: "uix-data-workspace__group-head", "data-group-id": group.id, children: [
|
|
806
|
+
selectable && /* @__PURE__ */ jsx("td", { className: "uix-table__selcell", "data-col": ladderOn ? "select" : void 0, children: /* @__PURE__ */ jsx(
|
|
807
|
+
Checkbox,
|
|
808
|
+
{
|
|
809
|
+
"aria-label": fillLabel(labels.selectGroup, { name }),
|
|
810
|
+
disabled: group.rows.length === 0 || atCap && on === 0,
|
|
811
|
+
checked: on > 0 && on === groupIds.length,
|
|
812
|
+
indeterminate: on > 0 && on < groupIds.length,
|
|
813
|
+
onChange: () => toggleMany(groupIds, on < groupIds.length && !atCap)
|
|
814
|
+
}
|
|
815
|
+
) }),
|
|
816
|
+
/* @__PURE__ */ jsx("th", { scope: "rowgroup", colSpan: Math.max(1, lead), className: "uix-data-workspace__group-label", "aria-labelledby": `${nameId} ${countId}`, children: /* @__PURE__ */ jsxs("span", { className: "uix-data-workspace__group-title", children: [
|
|
817
|
+
/* @__PURE__ */ jsx(
|
|
818
|
+
"button",
|
|
819
|
+
{
|
|
820
|
+
type: "button",
|
|
821
|
+
className: "uix-data-workspace__group-toggle",
|
|
822
|
+
"aria-expanded": open,
|
|
823
|
+
"aria-label": fillLabel(open ? labels.collapseGroup : labels.expandGroup, { name }),
|
|
824
|
+
onClick: (event) => toggleGroup(group.id, event.currentTarget.closest("tr")),
|
|
825
|
+
children: /* @__PURE__ */ jsx(ChevronIcon, {})
|
|
826
|
+
}
|
|
827
|
+
),
|
|
828
|
+
/* @__PURE__ */ jsx("span", { className: "uix-data-workspace__group-name", id: nameId, children: group.label }),
|
|
829
|
+
/* @__PURE__ */ jsx("span", { className: "uix-data-workspace__group-count", id: countId, children: fillLabel(count === 1 ? labels.groupCountOne : labels.groupCount, { count }) }),
|
|
830
|
+
leadAgg
|
|
831
|
+
] }) }),
|
|
832
|
+
firstAgg >= 0 && shown.slice(lead === 0 ? 1 : firstAgg).map((column) => /* @__PURE__ */ jsx("td", { className: cx("uix-data-workspace__group-agg", column.align === "end" && "uix-col--num", column.className), children: group.aggregates?.[column.id] }, column.id)),
|
|
833
|
+
firstAgg >= 0 && hasActions && /* @__PURE__ */ jsx("td", { className: "uix-table__actions" })
|
|
834
|
+
] }),
|
|
835
|
+
open && group.rows.map((row, at) => renderRow(row, first + at))
|
|
836
|
+
] }, group.id);
|
|
837
|
+
});
|
|
838
|
+
} else {
|
|
839
|
+
const spacer = (height, key) => /* @__PURE__ */ jsx("tr", { "aria-hidden": "true", className: "uix-data-workspace__spacer", children: /* @__PURE__ */ jsx("td", { colSpan: colCount, style: { height } }) }, key);
|
|
840
|
+
tbody = /* @__PURE__ */ jsxs("tbody", { children: [
|
|
841
|
+
virtual && windowed && start > 0 && spacer(virtual.padTop, "pad-top"),
|
|
842
|
+
windowed && start > 0 && start % 2 === 0 && spacer(0, "pad-zebra"),
|
|
843
|
+
mountedRows.map((row, at) => renderRow(row, start + at)),
|
|
844
|
+
virtual && windowed && virtual.padBottom > 0 && spacer(virtual.padBottom, "pad-bottom")
|
|
845
|
+
] });
|
|
846
|
+
}
|
|
847
|
+
const wrapStyle = long ? { "--uix-table-max-height": `${maxHeight}px` } : void 0;
|
|
848
|
+
return /* @__PURE__ */ jsx(
|
|
849
|
+
TableWrap,
|
|
850
|
+
{
|
|
851
|
+
ref: setWrap,
|
|
852
|
+
refreshing,
|
|
853
|
+
style: wrapStyle,
|
|
854
|
+
tabIndex: windowing != null && nav ? -1 : void 0,
|
|
855
|
+
className: cx("uix-data-workspace__table", long && "uix-table-wrap--scroll", cards && "uix-data-workspace__table--cards"),
|
|
856
|
+
children: /* @__PURE__ */ jsxs(
|
|
857
|
+
Table,
|
|
858
|
+
{
|
|
859
|
+
density,
|
|
860
|
+
zebra,
|
|
861
|
+
pinnedCol: frozen,
|
|
862
|
+
pinnedActions: hasActions && !cards && !actionsTooWide,
|
|
863
|
+
fixed: fixedOn || void 0,
|
|
864
|
+
style: tableStyle,
|
|
865
|
+
className: cx(
|
|
866
|
+
selectable && frozen && "uix-data-workspace__grid--pin-id",
|
|
867
|
+
ladder && `uix-table--${ladder}`,
|
|
868
|
+
groups && zebra !== false && "uix-data-workspace__grid--grouped",
|
|
869
|
+
nav && "uix-data-workspace__grid--rows",
|
|
870
|
+
clickActivates && "uix-data-workspace__grid--click"
|
|
871
|
+
),
|
|
872
|
+
"aria-label": label,
|
|
873
|
+
"aria-rowcount": windowed ? ids.length + 1 : void 0,
|
|
874
|
+
children: [
|
|
875
|
+
fixedOn && /* @__PURE__ */ jsxs("colgroup", { children: [
|
|
876
|
+
selectable && /* @__PURE__ */ jsx("col", { style: { width: "var(--uix-selcol-w)" } }),
|
|
877
|
+
idColumn && /* @__PURE__ */ jsx("col", { style: idColumn.width ? { width: idColumn.width } : void 0 }),
|
|
878
|
+
shown.map((column) => {
|
|
879
|
+
const width = column.width ?? (isFlex(column.className) ? void 0 : columnFloor(void 0, column.minWidth, column.className));
|
|
880
|
+
return /* @__PURE__ */ jsx("col", { className: colClasses(column.className), style: width ? { width } : void 0 }, column.id);
|
|
881
|
+
}),
|
|
882
|
+
hasActions && /* @__PURE__ */ jsx("col", { style: { width: actionsCol } })
|
|
883
|
+
] }),
|
|
884
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { "aria-rowindex": windowed ? 1 : void 0, children: [
|
|
885
|
+
selectable && /* @__PURE__ */ jsx("th", { className: "uix-table__selcol", scope: "col", "data-col": ladderOn ? "select" : void 0, children: /* @__PURE__ */ jsx(
|
|
886
|
+
Checkbox,
|
|
887
|
+
{
|
|
888
|
+
"aria-label": labels.selectAll,
|
|
889
|
+
checked: onPage > 0 && onPage === ids.length,
|
|
890
|
+
indeterminate: onPage > 0 && onPage < ids.length,
|
|
891
|
+
disabled: atCap && onPage === 0,
|
|
892
|
+
onChange: () => toggleMany(ids, onPage < ids.length && !atCap)
|
|
893
|
+
}
|
|
894
|
+
) }),
|
|
895
|
+
idColumn && (idColumn.sortable && idSortColumn ? /* @__PURE__ */ jsx(Th, { scope: "col", "data-col": ladderOn ? "id" : void 0, ...sortProps(idSortColumn, true), children: idColumn.header }) : /* @__PURE__ */ jsx(Th, { scope: "col", "data-col": ladderOn ? "id" : void 0, children: idColumn.header })),
|
|
896
|
+
columns.map((column) => {
|
|
897
|
+
const style = !fixedOn && (column.width || column.minWidth) ? { width: column.width, minWidth: column.minWidth } : void 0;
|
|
898
|
+
return /* @__PURE__ */ jsx(
|
|
899
|
+
Th,
|
|
900
|
+
{
|
|
901
|
+
scope: "col",
|
|
902
|
+
className: cx(column.align === "end" && "uix-col--num", column.className) || void 0,
|
|
903
|
+
style,
|
|
904
|
+
...sortProps(column, column.sortable === true),
|
|
905
|
+
...ladderAttrs(ladderOn, column, false),
|
|
906
|
+
children: column.header
|
|
907
|
+
},
|
|
908
|
+
column.id
|
|
909
|
+
);
|
|
910
|
+
}),
|
|
911
|
+
hasActions && /* @__PURE__ */ jsx("th", { scope: "col", className: "uix-table__actions", "data-col": ladderOn ? "actions" : void 0, children: /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: labels.rowActions }) })
|
|
912
|
+
] }) }),
|
|
913
|
+
tbody
|
|
914
|
+
]
|
|
915
|
+
}
|
|
916
|
+
)
|
|
917
|
+
}
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
function WorkspaceRowInner({
|
|
921
|
+
row,
|
|
922
|
+
rowId,
|
|
923
|
+
rowLabel,
|
|
924
|
+
columns,
|
|
925
|
+
idColumn,
|
|
926
|
+
getRowProps,
|
|
927
|
+
selectable,
|
|
928
|
+
selected,
|
|
929
|
+
selectDisabled,
|
|
930
|
+
hasActions,
|
|
931
|
+
actions,
|
|
932
|
+
ladderOn,
|
|
933
|
+
selectRowLabel,
|
|
934
|
+
openLabel,
|
|
935
|
+
marked,
|
|
936
|
+
ariaRowIndex,
|
|
937
|
+
nav,
|
|
938
|
+
tabStop,
|
|
939
|
+
handlers
|
|
940
|
+
}) {
|
|
941
|
+
const text = idColumn?.text(row) ?? rowLabel?.(row) ?? rowId;
|
|
942
|
+
const extra = getRowProps?.(row);
|
|
943
|
+
const navProps = nav ? {
|
|
944
|
+
tabIndex: tabStop ? 0 : -1,
|
|
945
|
+
onKeyDown: (event) => {
|
|
946
|
+
extra?.onKeyDown?.(event);
|
|
947
|
+
if (!event.defaultPrevented) handlers.key(rowId, event);
|
|
948
|
+
},
|
|
949
|
+
onClick: (event) => {
|
|
950
|
+
extra?.onClick?.(event);
|
|
951
|
+
if (!event.defaultPrevented) handlers.click(rowId, event);
|
|
952
|
+
},
|
|
953
|
+
onFocus: (event) => {
|
|
954
|
+
extra?.onFocus?.(event);
|
|
955
|
+
handlers.focus(rowId);
|
|
956
|
+
},
|
|
957
|
+
onBlur: (event) => {
|
|
958
|
+
extra?.onBlur?.(event);
|
|
959
|
+
handlers.blur(rowId, event);
|
|
960
|
+
}
|
|
961
|
+
} : {};
|
|
962
|
+
return /* @__PURE__ */ jsxs(Tr, { selected, "data-uix-row-id": marked ? rowId : void 0, "aria-rowindex": ariaRowIndex, ...extra, ...navProps, children: [
|
|
963
|
+
selectable && /* @__PURE__ */ jsx("td", { className: "uix-table__selcell", "data-col": ladderOn ? "select" : void 0, children: /* @__PURE__ */ jsx(
|
|
964
|
+
Checkbox,
|
|
965
|
+
{
|
|
966
|
+
"aria-label": fillLabel(selectRowLabel, { label: text }),
|
|
967
|
+
checked: selected,
|
|
968
|
+
disabled: selectDisabled,
|
|
969
|
+
onClick: (event) => handlers.toggle(rowId, event.currentTarget.checked, event),
|
|
970
|
+
onChange: () => {
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
) }),
|
|
974
|
+
idColumn && /* @__PURE__ */ jsx(Td, { className: "uix-id-cell", "data-col": ladderOn ? "id" : void 0, children: /* @__PURE__ */ jsx(IdCell, { row, text, idColumn, openLabel }) }),
|
|
975
|
+
columns.map((column) => /* @__PURE__ */ jsx(Td, { className: cx(column.align === "end" && "uix-col--num", column.className) || void 0, ...ladderAttrs(ladderOn, column, true), children: column.cell(row) }, column.id)),
|
|
976
|
+
hasActions && /* @__PURE__ */ jsx(RowActions, { "data-col": ladderOn ? "actions" : void 0, children: actions })
|
|
977
|
+
] });
|
|
978
|
+
}
|
|
979
|
+
const WorkspaceRow = memo(WorkspaceRowInner);
|
|
980
|
+
function IdCell({ row, text, idColumn, openLabel }) {
|
|
981
|
+
const rich = idColumn.render ? /* @__PURE__ */ jsx("span", { className: "uix-data-workspace__id-text", children: idColumn.render(row) }) : null;
|
|
982
|
+
const label = /* @__PURE__ */ jsx("span", { className: "uix-data-workspace__id-label", children: text });
|
|
983
|
+
const arrow = idColumn.href && renderUixLink(idColumn.renderLink, {
|
|
984
|
+
href: idColumn.href(row),
|
|
985
|
+
className: "uix-data-workspace__open",
|
|
986
|
+
"aria-label": fillLabel(openLabel, { label: text }),
|
|
987
|
+
children: /* @__PURE__ */ jsx(ArrowUpRight, {})
|
|
988
|
+
});
|
|
989
|
+
if (!idColumn.onPeek && idColumn.href && idColumn.linkId) {
|
|
990
|
+
return /* @__PURE__ */ jsx("span", { className: "uix-data-workspace__id", children: renderUixLink(idColumn.renderLink, {
|
|
991
|
+
href: idColumn.href(row),
|
|
992
|
+
className: "uix-id-cell__btn uix-data-workspace__id-link",
|
|
993
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
994
|
+
rich ?? label,
|
|
995
|
+
/* @__PURE__ */ jsx(ArrowUpRight, {})
|
|
996
|
+
] })
|
|
997
|
+
}) });
|
|
998
|
+
}
|
|
999
|
+
return /* @__PURE__ */ jsxs("span", { className: "uix-data-workspace__id", children: [
|
|
1000
|
+
idColumn.onPeek ? /* @__PURE__ */ jsx("button", { type: "button", className: "uix-id-cell__btn", "aria-haspopup": "dialog", onClick: () => idColumn.onPeek?.(row), children: rich ?? label }) : rich ?? /* @__PURE__ */ jsx("span", { className: "uix-cell-strong uix-data-workspace__id-label", children: text }),
|
|
1001
|
+
arrow
|
|
1002
|
+
] });
|
|
1003
|
+
}
|
|
1004
|
+
const cssEscape = (value) => typeof CSS !== "undefined" && CSS.escape ? CSS.escape(value) : value.replace(/["\\]/g, "\\$&");
|
|
266
1005
|
function Footer({ pagination, labels, rowCount }) {
|
|
1006
|
+
const provided = useUixLabels().pagination;
|
|
1007
|
+
const pagerLabels = provided || pagination.labels ? { ...provided, ...pagination.labels } : void 0;
|
|
267
1008
|
const sizes = pagination.pageSizes;
|
|
268
1009
|
const size = pagination.mode === "offset" ? pagination.pageSize : pagination.pageSize;
|
|
269
1010
|
const rangeText = pagination.mode === "offset" ? fillLabel(labels.range, {
|
|
@@ -278,7 +1019,7 @@ function Footer({ pagination, labels, rowCount }) {
|
|
|
278
1019
|
/* @__PURE__ */ jsx(Select, { size: "sm", value: String(size), onValueChange: (v) => pagination.onPageSizeChange?.(Number(v)), options: sizes.map((s) => ({ value: String(s), label: String(s) })) })
|
|
279
1020
|
] }),
|
|
280
1021
|
/* @__PURE__ */ jsx("span", { className: "uix-toolbar__spacer" }),
|
|
281
|
-
pagination.mode === "offset" ? /* @__PURE__ */ jsx(Pagination, { mode: "offset", page: pagination.page, pageCount: Math.max(1, Math.ceil(pagination.total / pagination.pageSize)), onChange: pagination.onPageChange }) : /* @__PURE__ */ jsx(Pagination, { mode: "cursor", hasPrevious: pagination.hasPrevious, hasNext: pagination.hasNext, onFirst: pagination.onFirst, onPrevious: pagination.onPrevious, onNext: pagination.onNext, summary: pagination.summary })
|
|
1022
|
+
pagination.mode === "offset" ? /* @__PURE__ */ jsx(Pagination, { mode: "offset", page: pagination.page, pageCount: Math.max(1, Math.ceil(pagination.total / pagination.pageSize)), onChange: pagination.onPageChange, labels: pagerLabels }) : /* @__PURE__ */ jsx(Pagination, { mode: "cursor", hasPrevious: pagination.hasPrevious, hasNext: pagination.hasNext, onFirst: pagination.onFirst, onPrevious: pagination.onPrevious, onNext: pagination.onNext, summary: pagination.summary, labels: pagerLabels })
|
|
282
1023
|
] });
|
|
283
1024
|
}
|
|
284
1025
|
function PopoverButton({ id, label, title, variant, children }) {
|
|
@@ -303,14 +1044,27 @@ function PopoverButton({ id, label, title, variant, children }) {
|
|
|
303
1044
|
}
|
|
304
1045
|
function ChipSummary({ field, value, options }) {
|
|
305
1046
|
const resolved = useResolvedFilterLabels(field, value);
|
|
306
|
-
|
|
1047
|
+
const provided = useUixLabels().filterSummary;
|
|
1048
|
+
const merged = provided ? { ...options, labels: { ...provided, ...options?.labels, operators: { ...provided.operators, ...options?.labels?.operators } } } : options;
|
|
1049
|
+
return /* @__PURE__ */ jsx(Fragment, { children: summarizeFilter(resolved.field, resolved.value, merged) });
|
|
307
1050
|
}
|
|
308
1051
|
function openInside(root) {
|
|
309
1052
|
try {
|
|
310
1053
|
if (root.querySelector(":popover-open")) return true;
|
|
311
1054
|
} catch {
|
|
312
1055
|
}
|
|
313
|
-
|
|
1056
|
+
if (root.querySelector("dialog[open]")) return true;
|
|
1057
|
+
return Array.from(root.querySelectorAll('[aria-expanded="true"]')).some(stillExpanded);
|
|
1058
|
+
}
|
|
1059
|
+
function stillExpanded(el) {
|
|
1060
|
+
const controls = el.getAttribute("aria-controls");
|
|
1061
|
+
const target = controls ? document.getElementById(controls) : null;
|
|
1062
|
+
if (!target?.hasAttribute("popover")) return true;
|
|
1063
|
+
try {
|
|
1064
|
+
return target.matches(":popover-open");
|
|
1065
|
+
} catch {
|
|
1066
|
+
return true;
|
|
1067
|
+
}
|
|
314
1068
|
}
|
|
315
1069
|
function FilterChips({ filters, labels, baseId }) {
|
|
316
1070
|
const [editing, setEditing] = useState(null);
|
|
@@ -353,6 +1107,10 @@ function FilterChips({ filters, labels, baseId }) {
|
|
|
353
1107
|
setFocusChip(null);
|
|
354
1108
|
}
|
|
355
1109
|
});
|
|
1110
|
+
const clearSet = () => {
|
|
1111
|
+
if (filters.onClearAll) filters.onClearAll({ search: false });
|
|
1112
|
+
else for (const f of set) filters.onChange(f.id, void 0);
|
|
1113
|
+
};
|
|
356
1114
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
357
1115
|
set.map((field) => /* @__PURE__ */ jsx("span", { ref: (el) => {
|
|
358
1116
|
if (el) anchors.current.set(field.id, el);
|
|
@@ -368,9 +1126,7 @@ function FilterChips({ filters, labels, baseId }) {
|
|
|
368
1126
|
}
|
|
369
1127
|
) }, field.id)),
|
|
370
1128
|
unset.length > 0 && /* @__PURE__ */ jsx("span", { ref: addRef, children: /* @__PURE__ */ jsx(Menu, { trigger: /* @__PURE__ */ jsx(Chip, { variant: "add", icon: /* @__PURE__ */ jsx(PlusIcon, {}), children: labels.addFilter }), children: unset.map((field) => /* @__PURE__ */ jsx(MenuItem, { onSelect: () => edit(field, addRef.current), children: field.label }, field.id)) }) }),
|
|
371
|
-
set.length > 0 && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "link", onClick:
|
|
372
|
-
for (const f of set) filters.onChange(f.id, void 0);
|
|
373
|
-
}, children: labels.clearFilters }),
|
|
1129
|
+
set.length > 0 && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "link", onClick: clearSet, children: labels.clearFilters }),
|
|
374
1130
|
/* @__PURE__ */ jsx(Popover, { id: popId, anchor: editing?.anchor ?? null, role: "dialog", "aria-label": editing?.field.label, children: editing && /* @__PURE__ */ jsx(FilterEditor, { field: editing.field, value: draft, onValueChange: setDraft, onApply: (v) => finish(v), onClear: () => finish(void 0) }) })
|
|
375
1131
|
] });
|
|
376
1132
|
}
|