@dxos/react-ui-table 0.3.9-main.5167f76 → 0.3.9-main.52d137d
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/lib/browser/index.mjs +229 -162
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/Cell/CellCombobox.d.ts.map +1 -1
- package/dist/types/src/components/ColumnMenu.d.ts.map +1 -1
- package/dist/types/src/components/ColumnMenu.stories.d.ts +1 -0
- package/dist/types/src/components/ColumnMenu.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/TableBody.d.ts.map +1 -1
- package/dist/types/src/components/Table/props.d.ts +6 -2
- package/dist/types/src/components/Table/props.d.ts.map +1 -1
- package/dist/types/src/helpers.d.ts +2 -2
- package/dist/types/src/helpers.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/schema.d.ts +0 -1
- package/dist/types/src/schema.d.ts.map +1 -1
- package/dist/types/src/theme.d.ts +0 -2
- package/dist/types/src/theme.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +11 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/package.json +12 -16
- package/src/components/Cell/CellCombobox.tsx +4 -1
- package/src/components/ColumnMenu.stories.tsx +3 -0
- package/src/components/ColumnMenu.tsx +16 -16
- package/src/components/Table/Table.stories.tsx +23 -12
- package/src/components/Table/Table.tsx +92 -26
- package/src/components/Table/TableBody.tsx +2 -1
- package/src/components/Table/props.ts +26 -14
- package/src/helpers.tsx +105 -84
- package/src/index.ts +1 -0
- package/src/schema.ts +0 -8
- package/src/theme.ts +14 -7
- package/src/translations.ts +11 -0
|
@@ -1,45 +1,42 @@
|
|
|
1
1
|
// packages/ui/react-ui-table/src/components/ColumnMenu.tsx
|
|
2
2
|
import { Check, CaretDown, Trash, X } from "@phosphor-icons/react";
|
|
3
3
|
import React, { useRef, useState } from "react";
|
|
4
|
-
import { Button, DensityProvider, Input, Popover, Select, Separator } from "@dxos/react-ui";
|
|
4
|
+
import { Button, DensityProvider, Input, Popover, Select, Separator, useTranslation } from "@dxos/react-ui";
|
|
5
5
|
import { getSize, mx } from "@dxos/react-ui-theme";
|
|
6
6
|
import { safeParseInt } from "@dxos/util";
|
|
7
7
|
|
|
8
|
-
// packages/ui/react-ui-table/src/
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
]);
|
|
8
|
+
// packages/ui/react-ui-table/src/translations.ts
|
|
9
|
+
var translationKey = "table";
|
|
10
|
+
var translations_default = [
|
|
11
|
+
{
|
|
12
|
+
"en-US": {
|
|
13
|
+
[translationKey]: {
|
|
14
|
+
"no selection label": "\xA0",
|
|
15
|
+
"number column type label": "Number",
|
|
16
|
+
"boolean column type label": "Toggle",
|
|
17
|
+
"date column type label": "Date",
|
|
18
|
+
"string column type label": "Text",
|
|
19
|
+
"ref column type label": "Reference",
|
|
20
|
+
"digits label": "Decimal places",
|
|
21
|
+
"save label": "Save",
|
|
22
|
+
"delete label": "Delete",
|
|
23
|
+
"column label label": "Label",
|
|
24
|
+
"property key label": "Property",
|
|
25
|
+
"column type label": "Type"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
];
|
|
31
30
|
|
|
32
31
|
// packages/ui/react-ui-table/src/components/ColumnMenu.tsx
|
|
33
32
|
var ColumnMenu = ({ column, ...props }) => {
|
|
34
33
|
const title = column.label?.length ? column.label : column.id;
|
|
35
34
|
return /* @__PURE__ */ React.createElement("div", {
|
|
36
|
-
className: "flex
|
|
35
|
+
className: "flex items-center gap-2"
|
|
37
36
|
}, /* @__PURE__ */ React.createElement("div", {
|
|
38
|
-
className: "truncate",
|
|
37
|
+
className: "flex-1 min-is-0 truncate",
|
|
39
38
|
title
|
|
40
39
|
}, title), /* @__PURE__ */ React.createElement("div", {
|
|
41
|
-
className: "grow"
|
|
42
|
-
}), /* @__PURE__ */ React.createElement("div", {
|
|
43
40
|
className: "flex shrink-0"
|
|
44
41
|
}, /* @__PURE__ */ React.createElement(ColumnPanel, {
|
|
45
42
|
...props,
|
|
@@ -59,6 +56,7 @@ var ColumnPanel = ({ context, tableDefs, tableDef, column, onUpdate, onDelete })
|
|
|
59
56
|
const [label, setLabel] = useState(column.label);
|
|
60
57
|
const [digits, setDigits] = useState(String(column.digits ?? "0"));
|
|
61
58
|
const propRef = useRef(null);
|
|
59
|
+
const { t } = useTranslation(translationKey);
|
|
62
60
|
const handleCancel = () => {
|
|
63
61
|
setProp(column.id);
|
|
64
62
|
setOpen(false);
|
|
@@ -93,7 +91,7 @@ var ColumnPanel = ({ context, tableDefs, tableDef, column, onUpdate, onDelete })
|
|
|
93
91
|
asChild: true
|
|
94
92
|
}, /* @__PURE__ */ React.createElement(Button, {
|
|
95
93
|
variant: "ghost",
|
|
96
|
-
classNames: "p-
|
|
94
|
+
classNames: "p-1"
|
|
97
95
|
}, /* @__PURE__ */ React.createElement(CaretDown, {
|
|
98
96
|
className: getSize(4)
|
|
99
97
|
}))), /* @__PURE__ */ React.createElement(Popover.Portal, null, /* @__PURE__ */ React.createElement(Popover.Content, null, /* @__PURE__ */ React.createElement(Popover.Viewport, {
|
|
@@ -104,14 +102,14 @@ var ColumnPanel = ({ context, tableDefs, tableDef, column, onUpdate, onDelete })
|
|
|
104
102
|
className: "flex flex-col gap-1"
|
|
105
103
|
}, /* @__PURE__ */ React.createElement(Section, null, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
|
|
106
104
|
classNames: "mbe-1"
|
|
107
|
-
}, "
|
|
105
|
+
}, t("column label label")), /* @__PURE__ */ React.createElement(Input.TextInput, {
|
|
108
106
|
placeholder: "Column label",
|
|
109
107
|
value: label ?? "",
|
|
110
108
|
onChange: (event) => setLabel(event.target.value),
|
|
111
109
|
autoFocus: true
|
|
112
110
|
})), /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
|
|
113
111
|
classNames: "mbe-1 mbs-3"
|
|
114
|
-
}, "
|
|
112
|
+
}, t("property key label")), /* @__PURE__ */ React.createElement(Input.TextInput, {
|
|
115
113
|
ref: propRef,
|
|
116
114
|
placeholder: "Property key",
|
|
117
115
|
// TODO(burdon): Provide hooks for value normalization, ENTER, ESC, etc.
|
|
@@ -119,18 +117,23 @@ var ColumnPanel = ({ context, tableDefs, tableDef, column, onUpdate, onDelete })
|
|
|
119
117
|
onChange: (event) => setProp(event.target.value.replace(/[^\w_]/g, ""))
|
|
120
118
|
})), /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
|
|
121
119
|
classNames: "mbe-1 mbs-3"
|
|
122
|
-
}, "
|
|
120
|
+
}, t("column type label")), /* @__PURE__ */ React.createElement(Select.Root, {
|
|
123
121
|
value: type,
|
|
124
122
|
onValueChange: setType
|
|
125
123
|
}, /* @__PURE__ */ React.createElement(Select.TriggerButton, {
|
|
126
124
|
placeholder: "Type",
|
|
127
125
|
classNames: "is-full"
|
|
128
|
-
}), /* @__PURE__ */ React.createElement(Select.Portal, null, /* @__PURE__ */ React.createElement(Select.Content, null, /* @__PURE__ */ React.createElement(Select.Viewport, null,
|
|
126
|
+
}), /* @__PURE__ */ React.createElement(Select.Portal, null, /* @__PURE__ */ React.createElement(Select.Content, null, /* @__PURE__ */ React.createElement(Select.Viewport, null, [
|
|
127
|
+
"number",
|
|
128
|
+
"boolean",
|
|
129
|
+
"string",
|
|
130
|
+
"ref"
|
|
131
|
+
].map((type2) => /* @__PURE__ */ React.createElement(Select.Option, {
|
|
129
132
|
key: type2,
|
|
130
133
|
value: type2
|
|
131
|
-
},
|
|
134
|
+
}, t(`${type2} column type label`))))))))), type === "number" && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Section, null, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
|
|
132
135
|
classNames: "mbe-1 mbs-3"
|
|
133
|
-
}, "
|
|
136
|
+
}, t("digits label")), /* @__PURE__ */ React.createElement(Input.TextInput, {
|
|
134
137
|
value: digits ?? "",
|
|
135
138
|
onChange: (event) => setDigits(event.target.value)
|
|
136
139
|
})))), type === "ref" && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Section, null, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
|
|
@@ -141,7 +144,7 @@ var ColumnPanel = ({ context, tableDefs, tableDef, column, onUpdate, onDelete })
|
|
|
141
144
|
}, /* @__PURE__ */ React.createElement(Select.TriggerButton, {
|
|
142
145
|
placeholder: "Table",
|
|
143
146
|
classNames: "is-full"
|
|
144
|
-
}), /* @__PURE__ */ React.createElement(Select.Portal, null, /* @__PURE__ */ React.createElement(Select.Content, null, /* @__PURE__ */ React.createElement(Select.Viewport, null, tableDefs.filter((
|
|
147
|
+
}), /* @__PURE__ */ React.createElement(Select.Portal, null, /* @__PURE__ */ React.createElement(Select.Content, null, /* @__PURE__ */ React.createElement(Select.Viewport, null, tableDefs.filter((t2) => t2.id !== tableDef.id).map(({ id, name }) => /* @__PURE__ */ React.createElement(Select.Option, {
|
|
145
148
|
key: id,
|
|
146
149
|
value: id
|
|
147
150
|
}, name ?? id))))))), refTable && /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
|
|
@@ -163,21 +166,23 @@ var ColumnPanel = ({ context, tableDefs, tableDef, column, onUpdate, onDelete })
|
|
|
163
166
|
variant: "primary",
|
|
164
167
|
classNames: "is-full flex gap-2",
|
|
165
168
|
onClick: handleSave
|
|
166
|
-
}, /* @__PURE__ */ React.createElement("span", null, "
|
|
169
|
+
}, /* @__PURE__ */ React.createElement("span", null, t("save label")), /* @__PURE__ */ React.createElement("div", {
|
|
167
170
|
className: "grow"
|
|
168
171
|
}), /* @__PURE__ */ React.createElement(Check, {
|
|
169
172
|
className: getSize(5)
|
|
170
173
|
})), /* @__PURE__ */ React.createElement(Button, {
|
|
171
174
|
classNames: "is-full flex gap-2",
|
|
172
175
|
onClick: handleCancel
|
|
173
|
-
}, /* @__PURE__ */ React.createElement("span", null, "
|
|
176
|
+
}, /* @__PURE__ */ React.createElement("span", null, t("cancel label", {
|
|
177
|
+
ns: "os"
|
|
178
|
+
})), /* @__PURE__ */ React.createElement("div", {
|
|
174
179
|
className: "grow"
|
|
175
180
|
}), /* @__PURE__ */ React.createElement(X, {
|
|
176
181
|
className: getSize(5)
|
|
177
182
|
})), /* @__PURE__ */ React.createElement(Button, {
|
|
178
183
|
classNames: "is-full flex gap-2",
|
|
179
184
|
onClick: () => onDelete?.(column.id)
|
|
180
|
-
}, /* @__PURE__ */ React.createElement("span", null, "
|
|
185
|
+
}, /* @__PURE__ */ React.createElement("span", null, t("delete label")), /* @__PURE__ */ React.createElement("div", {
|
|
181
186
|
className: "grow"
|
|
182
187
|
}), /* @__PURE__ */ React.createElement(Trash, {
|
|
183
188
|
className: getSize(5)
|
|
@@ -187,6 +192,7 @@ var ColumnPanel = ({ context, tableDefs, tableDef, column, onUpdate, onDelete })
|
|
|
187
192
|
// packages/ui/react-ui-table/src/components/Table/Table.tsx
|
|
188
193
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
189
194
|
import { getCoreRowModel, getGroupedRowModel, useReactTable } from "@tanstack/react-table";
|
|
195
|
+
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
190
196
|
import React6, { Fragment, useCallback, useEffect, useState as useState2 } from "react";
|
|
191
197
|
import { debounce } from "@dxos/async";
|
|
192
198
|
|
|
@@ -202,7 +208,7 @@ var [TableProvider, useUntypedTableContext] = createContext(TABLE_NAME);
|
|
|
202
208
|
var useTableContext = (consumerName) => useUntypedTableContext(consumerName);
|
|
203
209
|
|
|
204
210
|
// packages/ui/react-ui-table/src/theme.ts
|
|
205
|
-
import { chromeSurface, fixedSurface, focusRing,
|
|
211
|
+
import { chromeSurface, fixedSurface, focusRing, ghostSelected, ghostSelectedCurrent, groupBorder, mx as mx2 } from "@dxos/react-ui-theme";
|
|
206
212
|
var currentRow = "!bg-neutral-75 !dark:bg-neutral-850";
|
|
207
213
|
var selectedRow = "!bg-primary-100 dark:!bg-primary-700";
|
|
208
214
|
var flushPadding = "pli-0 plb-0";
|
|
@@ -211,13 +217,13 @@ var headPadding = "pli-2 plb-1.5";
|
|
|
211
217
|
var gridCellFocusRing = "focus:z-[11] focus:outline outline-2 outline-primary-500 dark:outline-primary-400";
|
|
212
218
|
var tableRoot = ({ fullWidth }, ...etc) => mx2("table-fixed", fullWidth && "is-full", ...etc);
|
|
213
219
|
var groupTh = (_props, ...etc) => mx2("text-start font-medium", flushPadding, ...etc);
|
|
214
|
-
var theadRoot = ({ header }, ...etc) => mx2(header ? "sticky block-start-
|
|
220
|
+
var theadRoot = ({ header, stickyHeader }, ...etc) => mx2(header ? stickyHeader && "sticky block-start-[--sticky-top] z-[1]" : "collapse", header && fixedSurface, ...etc);
|
|
215
221
|
var theadTr = (_props, ...etc) => mx2("group", ...etc);
|
|
216
222
|
var theadTh = ({ border }, ...etc) => mx2("relative text-start font-medium select-none truncate", headPadding, border && "border", border && groupBorder, ...etc);
|
|
217
223
|
var theadResizeRoot = (_props, ...etc) => mx2("absolute top-0 pis-1 h-full z-[10] w-[7px] -right-[5px] cursor-col-resize select-none touch-none opacity-20 hover:opacity-100", ...etc);
|
|
218
224
|
var theadResizeThumb = (_props, ...etc) => mx2("flex group-hover:bg-neutral-700 -ml-[2px] w-[1px] h-full", ...etc);
|
|
219
225
|
var tbodyRoot = (_props, ...etc) => mx2(...etc);
|
|
220
|
-
var tbodyTr = ({
|
|
226
|
+
var tbodyTr = ({ canBeCurrent }, ...etc) => mx2("group", canBeCurrent ? ghostSelectedCurrent : ghostSelected, canBeCurrent && focusRing, canBeCurrent && "cursor-pointer rounded", ...etc);
|
|
221
227
|
var tdRoot = ({ border, isGrid }, ...etc) => mx2("relative", flushPadding, border && "border", border && groupBorder, isGrid && gridCellFocusRing, ...etc);
|
|
222
228
|
var tdContent = (_props, ...etc) => mx2(...etc);
|
|
223
229
|
var tfootRoot = (_props, ...etc) => mx2("sticky block-end-0 z-10", chromeSurface, ...etc);
|
|
@@ -270,13 +276,14 @@ var TableBody = ({ rows }) => {
|
|
|
270
276
|
return /* @__PURE__ */ React3.createElement("tr", {
|
|
271
277
|
key: keyAccessor ? keyAccessor(row.original) : row.id,
|
|
272
278
|
className: tbodyTr({
|
|
273
|
-
isSelected,
|
|
274
|
-
isCurrent,
|
|
275
279
|
canBeCurrent
|
|
276
280
|
}),
|
|
277
281
|
...isCurrent && {
|
|
278
282
|
"aria-current": "location"
|
|
279
283
|
},
|
|
284
|
+
...isSelected && {
|
|
285
|
+
"aria-selected": "true"
|
|
286
|
+
},
|
|
280
287
|
...canBeCurrent && {
|
|
281
288
|
tabIndex: 0,
|
|
282
289
|
onClick: () => {
|
|
@@ -370,8 +377,57 @@ var TableHead = (_props) => {
|
|
|
370
377
|
TableHead.displayName = TABLE_HEAD_NAME;
|
|
371
378
|
|
|
372
379
|
// packages/ui/react-ui-table/src/components/Table/Table.tsx
|
|
380
|
+
var VirtualizedTableContent = ({ getScrollElement }) => {
|
|
381
|
+
const { table: { getRowModel } } = useTableContext("VirtualizedTableContent");
|
|
382
|
+
const rows = getRowModel().rows;
|
|
383
|
+
const { getTotalSize, getVirtualItems } = useVirtualizer({
|
|
384
|
+
getScrollElement,
|
|
385
|
+
count: rows.length,
|
|
386
|
+
overscan: 16,
|
|
387
|
+
estimateSize: () => 33
|
|
388
|
+
});
|
|
389
|
+
const virtualRows = getVirtualItems();
|
|
390
|
+
const totalSize = getTotalSize();
|
|
391
|
+
const paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0;
|
|
392
|
+
const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows?.[virtualRows.length - 1]?.end || 0) : 0;
|
|
393
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, paddingTop > 0 && /* @__PURE__ */ React6.createElement("tbody", {
|
|
394
|
+
role: "none"
|
|
395
|
+
}, /* @__PURE__ */ React6.createElement("tr", {
|
|
396
|
+
role: "none"
|
|
397
|
+
}, /* @__PURE__ */ React6.createElement("td", {
|
|
398
|
+
style: {
|
|
399
|
+
height: `${paddingTop}px`
|
|
400
|
+
},
|
|
401
|
+
role: "none"
|
|
402
|
+
}))), /* @__PURE__ */ React6.createElement(TableBody, {
|
|
403
|
+
rows: virtualRows.map((virtualRow) => rows[virtualRow.index])
|
|
404
|
+
}), paddingBottom > 0 && /* @__PURE__ */ React6.createElement("tbody", {
|
|
405
|
+
role: "none"
|
|
406
|
+
}, /* @__PURE__ */ React6.createElement("tr", {
|
|
407
|
+
role: "none"
|
|
408
|
+
}, /* @__PURE__ */ React6.createElement("td", {
|
|
409
|
+
style: {
|
|
410
|
+
height: `${paddingBottom}px`
|
|
411
|
+
},
|
|
412
|
+
role: "none"
|
|
413
|
+
}))));
|
|
414
|
+
};
|
|
415
|
+
var GroupedTableContent = () => {
|
|
416
|
+
const { table: { getGroupedRowModel: getGroupedRowModel1, getHeaderGroups, getState }, debug } = useTableContext("GroupedTableContent");
|
|
417
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, getGroupedRowModel1().rows.map((row, i) => {
|
|
418
|
+
return /* @__PURE__ */ React6.createElement(Fragment, {
|
|
419
|
+
key: i
|
|
420
|
+
}, /* @__PURE__ */ React6.createElement("thead", null, /* @__PURE__ */ React6.createElement("tr", null, debug && /* @__PURE__ */ React6.createElement("th", null), /* @__PURE__ */ React6.createElement("th", {
|
|
421
|
+
// TODO(burdon): Calculate row span.
|
|
422
|
+
colSpan: getHeaderGroups()[0].headers.length,
|
|
423
|
+
className: groupTh({})
|
|
424
|
+
}, getState().grouping[0], "[", String(row.getGroupingValue(getState().grouping[0])), "]"))), /* @__PURE__ */ React6.createElement(TableBody, {
|
|
425
|
+
rows: row.subRows
|
|
426
|
+
}));
|
|
427
|
+
}));
|
|
428
|
+
};
|
|
373
429
|
var Table = (props) => {
|
|
374
|
-
const { role, data = [], columns = [], onColumnResize, columnVisibility, header = true, footer, rowsSelectable, fullWidth, debug, onDataSelectionChange } = props;
|
|
430
|
+
const { role, data = [], columns = [], onColumnResize, columnVisibility, header = true, footer, rowsSelectable, fullWidth, debug, onDataSelectionChange, classNames, getScrollElement } = props;
|
|
375
431
|
const TableProvider2 = TableProvider;
|
|
376
432
|
const [rowSelection = {}, directlySetRowSelection] = useControllableState({
|
|
377
433
|
prop: props.rowSelection,
|
|
@@ -443,6 +499,7 @@ var Table = (props) => {
|
|
|
443
499
|
// Debug
|
|
444
500
|
debugTable: debug
|
|
445
501
|
});
|
|
502
|
+
const rows = table.getRowModel().rows;
|
|
446
503
|
useEffect(() => {
|
|
447
504
|
if (onDataSelectionChange) {
|
|
448
505
|
onDataSelectionChange(Object.keys(rowSelection).map((id) => table.getRowModel().rowsById[id].original));
|
|
@@ -461,25 +518,17 @@ var Table = (props) => {
|
|
|
461
518
|
isGrid: role === "grid" || role === "treegrid"
|
|
462
519
|
}, /* @__PURE__ */ React6.createElement("table", {
|
|
463
520
|
role,
|
|
464
|
-
className: tableRoot(props),
|
|
521
|
+
className: tableRoot(props, classNames),
|
|
465
522
|
...!fullWidth && {
|
|
466
523
|
style: {
|
|
467
524
|
width: table.getTotalSize()
|
|
468
525
|
}
|
|
469
526
|
}
|
|
470
|
-
}, /* @__PURE__ */ React6.createElement(TableHead, null), grouping.length === 0
|
|
471
|
-
|
|
472
|
-
})
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}, /* @__PURE__ */ React6.createElement("thead", null, /* @__PURE__ */ React6.createElement("tr", null, debug && /* @__PURE__ */ React6.createElement("th", null), /* @__PURE__ */ React6.createElement("th", {
|
|
476
|
-
// TODO(burdon): Calculate row span.
|
|
477
|
-
colSpan: table.getHeaderGroups()[0].headers.length,
|
|
478
|
-
className: groupTh(props)
|
|
479
|
-
}, table.getState().grouping[0], "[", String(row.getGroupingValue(table.getState().grouping[0])), "]"))), /* @__PURE__ */ React6.createElement(TableBody, {
|
|
480
|
-
rows: row.subRows
|
|
481
|
-
}));
|
|
482
|
-
}), footer && /* @__PURE__ */ React6.createElement(TableFooter, null)), debug && /* @__PURE__ */ React6.createElement("pre", {
|
|
527
|
+
}, /* @__PURE__ */ React6.createElement(TableHead, null), grouping.length === 0 ? getScrollElement ? /* @__PURE__ */ React6.createElement(VirtualizedTableContent, {
|
|
528
|
+
getScrollElement
|
|
529
|
+
}) : /* @__PURE__ */ React6.createElement(TableBody, {
|
|
530
|
+
rows
|
|
531
|
+
}) : /* @__PURE__ */ React6.createElement(GroupedTableContent, null), footer && /* @__PURE__ */ React6.createElement(TableFooter, null)), debug && /* @__PURE__ */ React6.createElement("pre", {
|
|
483
532
|
className: "font-mono text-xs text-neutral-500 my-4 p-2 ring"
|
|
484
533
|
}, /* @__PURE__ */ React6.createElement("code", null, JSON.stringify(table.getState(), void 0, 2))));
|
|
485
534
|
};
|
|
@@ -487,23 +536,9 @@ var Table = (props) => {
|
|
|
487
536
|
// packages/ui/react-ui-table/src/components/Cell/CellCombobox.tsx
|
|
488
537
|
import { CaretDown as CaretDown2 } from "@phosphor-icons/react";
|
|
489
538
|
import React7, { useCallback as useCallback2, useState as useState3 } from "react";
|
|
490
|
-
import { Popover as Popover2, useTranslation } from "@dxos/react-ui";
|
|
539
|
+
import { Popover as Popover2, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
491
540
|
import { PopoverCombobox } from "@dxos/react-ui-searchlist";
|
|
492
541
|
import { descriptionText, getSize as getSize2, mx as mx4, staticPlaceholderText } from "@dxos/react-ui-theme";
|
|
493
|
-
|
|
494
|
-
// packages/ui/react-ui-table/src/translations.ts
|
|
495
|
-
var translationKey = "table";
|
|
496
|
-
var translations_default = [
|
|
497
|
-
{
|
|
498
|
-
"en-US": {
|
|
499
|
-
[translationKey]: {
|
|
500
|
-
"no selection label": "\xA0"
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
];
|
|
505
|
-
|
|
506
|
-
// packages/ui/react-ui-table/src/components/Cell/CellCombobox.tsx
|
|
507
542
|
var initialItems = (model, value) => value ? {
|
|
508
543
|
[model.getId(value)]: {
|
|
509
544
|
label: model.getText(value),
|
|
@@ -511,7 +546,7 @@ var initialItems = (model, value) => value ? {
|
|
|
511
546
|
}
|
|
512
547
|
} : {};
|
|
513
548
|
var CellCombobox = ({ model, value, onValueChange }) => {
|
|
514
|
-
const { t } =
|
|
549
|
+
const { t } = useTranslation2(translationKey);
|
|
515
550
|
const [items, setItems] = useState3(initialItems(model, value));
|
|
516
551
|
const [loading, setLoading] = useState3(false);
|
|
517
552
|
const [searchInputValue, setSearchInputValue] = useState3("");
|
|
@@ -540,7 +575,7 @@ var CellCombobox = ({ model, value, onValueChange }) => {
|
|
|
540
575
|
variant: "ghost",
|
|
541
576
|
classNames: "is-full rounded-none ring-inset"
|
|
542
577
|
}, value ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement("span", {
|
|
543
|
-
className: mx4("font-normal text-start flex-1 min-is-0 truncate mie-2", !value && staticPlaceholderText)
|
|
578
|
+
className: mx4("font-normal text-start text-base flex-1 min-is-0 truncate mie-2", !value && staticPlaceholderText)
|
|
544
579
|
}, model.getText(value)), /* @__PURE__ */ React7.createElement(CaretDown2, {
|
|
545
580
|
weight: "bold",
|
|
546
581
|
className: getSize2(3)
|
|
@@ -568,29 +603,25 @@ var CellCombobox = ({ model, value, onValueChange }) => {
|
|
|
568
603
|
};
|
|
569
604
|
|
|
570
605
|
// packages/ui/react-ui-table/src/helpers.tsx
|
|
606
|
+
import { useFocusFinders } from "@fluentui/react-tabster";
|
|
571
607
|
import { Check as Check2, ClipboardText, X as X2 } from "@phosphor-icons/react";
|
|
572
608
|
import { createColumnHelper } from "@tanstack/react-table";
|
|
573
609
|
import format from "date-fns/format";
|
|
574
610
|
import formatDistanceToNow from "date-fns/formatDistanceToNow";
|
|
575
|
-
import
|
|
576
|
-
import React8, { useRef as useRef2, useState as useState4 } from "react";
|
|
611
|
+
import React8, { useEffect as useEffect2, useRef as useRef2, useState as useState4 } from "react";
|
|
577
612
|
import { Input as Input2, Tooltip } from "@dxos/react-ui";
|
|
578
613
|
import { getSize as getSize3, mx as mx5 } from "@dxos/react-ui-theme";
|
|
579
|
-
import { stripUndefinedValues } from "@dxos/util";
|
|
580
614
|
var createColumnBuilder = () => ({
|
|
581
615
|
helper: createColumnHelper(),
|
|
582
616
|
builder: new ColumnBuilder()
|
|
583
617
|
});
|
|
584
|
-
var defaults = (options, ...sources) => {
|
|
585
|
-
return stripUndefinedValues(defaultsDeep({}, options, ...sources));
|
|
586
|
-
};
|
|
587
618
|
var ComboboxBuilderCell = (cellContext) => {
|
|
588
619
|
const { model, onUpdate } = cellContext.column.columnDef.meta;
|
|
589
|
-
return /* @__PURE__ */ React8.createElement(CellCombobox, {
|
|
620
|
+
return model ? /* @__PURE__ */ React8.createElement(CellCombobox, {
|
|
590
621
|
model,
|
|
591
622
|
value: cellContext.getValue(),
|
|
592
623
|
onValueChange: (value) => onUpdate?.(cellContext.row.original, cellContext.column.id, value)
|
|
593
|
-
});
|
|
624
|
+
}) : null;
|
|
594
625
|
};
|
|
595
626
|
var StringBuilderCell = (cellContext) => {
|
|
596
627
|
const { onUpdate } = cellContext.column.columnDef.meta;
|
|
@@ -623,40 +654,55 @@ var StringBuilderCell = (cellContext) => {
|
|
|
623
654
|
onKeyDown: (event) => event.key === "Enter" && handleSave() || event.key === "Escape" && handleCancel()
|
|
624
655
|
}));
|
|
625
656
|
};
|
|
657
|
+
var parseNumber = (text) => text?.trim().length ? Number(text) : NaN;
|
|
658
|
+
var displayNumber = (value, digits) => value || value === 0 ? value.toLocaleString(void 0, {
|
|
659
|
+
minimumFractionDigits: digits ?? 0,
|
|
660
|
+
maximumFractionDigits: digits ?? 2
|
|
661
|
+
}) : "";
|
|
626
662
|
var NumberBuilderCell = (cellContext) => {
|
|
627
|
-
const { onUpdate,
|
|
663
|
+
const { onUpdate, digits } = cellContext.column.columnDef.meta;
|
|
628
664
|
const value = cellContext.getValue();
|
|
629
|
-
const [text, setText] = useState4();
|
|
665
|
+
const [text, setText] = useState4(displayNumber(value, digits));
|
|
666
|
+
const { findPrevFocusable } = useFocusFinders();
|
|
667
|
+
const ref = useRef2(null);
|
|
668
|
+
useEffect2(() => {
|
|
669
|
+
(!document.activeElement || document.activeElement !== ref.current) && setText(displayNumber(value, digits));
|
|
670
|
+
}, [
|
|
671
|
+
digits,
|
|
672
|
+
value
|
|
673
|
+
]);
|
|
630
674
|
const handleEdit = () => {
|
|
631
675
|
if (onUpdate) {
|
|
632
676
|
setText(value !== void 0 ? String(value) : "");
|
|
633
677
|
}
|
|
634
678
|
};
|
|
635
679
|
const handleSave = () => {
|
|
636
|
-
const
|
|
637
|
-
onUpdate?.(cellContext.row.original, cellContext.column.id, isNaN(
|
|
638
|
-
setText(
|
|
680
|
+
const nextValue = parseNumber(text);
|
|
681
|
+
onUpdate?.(cellContext.row.original, cellContext.column.id, isNaN(nextValue) ? void 0 : nextValue);
|
|
682
|
+
setText(displayNumber(nextValue, digits));
|
|
683
|
+
ref.current && document.activeElement === ref.current && findPrevFocusable(ref.current)?.focus();
|
|
639
684
|
};
|
|
640
|
-
const
|
|
641
|
-
setText(
|
|
685
|
+
const _handleCancel = () => {
|
|
686
|
+
setText(displayNumber(value, digits));
|
|
687
|
+
ref.current && findPrevFocusable(ref.current)?.focus();
|
|
642
688
|
};
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
689
|
+
return /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.TextInput, {
|
|
690
|
+
ref,
|
|
691
|
+
variant: "subdued",
|
|
692
|
+
value: text,
|
|
693
|
+
classNames: [
|
|
694
|
+
"is-full text-end font-mono",
|
|
695
|
+
textPadding
|
|
696
|
+
],
|
|
697
|
+
onBlur: handleSave,
|
|
698
|
+
onFocus: handleEdit,
|
|
699
|
+
onChange: ({ target: { value: value2 } }) => setText(value2),
|
|
700
|
+
onKeyDown: (event) => {
|
|
701
|
+
return (
|
|
702
|
+
/* (event.key === 'Escape' && handleCancel()) || */
|
|
703
|
+
event.key === "Enter" && handleSave()
|
|
704
|
+
);
|
|
705
|
+
}
|
|
660
706
|
}));
|
|
661
707
|
};
|
|
662
708
|
var RowSelectorBuilderCell = (cellContext) => {
|
|
@@ -696,15 +742,8 @@ var ColumnBuilder = class {
|
|
|
696
742
|
* Combobox value
|
|
697
743
|
*/
|
|
698
744
|
combobox({ label, classNames, model, onUpdate, ...props }) {
|
|
699
|
-
return
|
|
745
|
+
return {
|
|
700
746
|
minSize: 100,
|
|
701
|
-
meta: {
|
|
702
|
-
model,
|
|
703
|
-
onUpdate,
|
|
704
|
-
cell: {
|
|
705
|
-
classNames
|
|
706
|
-
}
|
|
707
|
-
},
|
|
708
747
|
header: (column) => {
|
|
709
748
|
return label ?? column.header.id;
|
|
710
749
|
},
|
|
@@ -713,21 +752,25 @@ var ColumnBuilder = class {
|
|
|
713
752
|
return /* @__PURE__ */ React8.createElement("div", {
|
|
714
753
|
className: mx5("truncate", classNames)
|
|
715
754
|
}, cellValue ? model?.getText(cellValue) : "");
|
|
755
|
+
},
|
|
756
|
+
...props,
|
|
757
|
+
meta: {
|
|
758
|
+
...props.meta,
|
|
759
|
+
model,
|
|
760
|
+
onUpdate,
|
|
761
|
+
cell: {
|
|
762
|
+
classNames,
|
|
763
|
+
...props.meta?.cell
|
|
764
|
+
}
|
|
716
765
|
}
|
|
717
|
-
}
|
|
766
|
+
};
|
|
718
767
|
}
|
|
719
768
|
/**
|
|
720
769
|
* String formats.
|
|
721
770
|
*/
|
|
722
771
|
string({ label, classNames, onUpdate, ...props } = {}) {
|
|
723
|
-
return
|
|
772
|
+
return {
|
|
724
773
|
minSize: 100,
|
|
725
|
-
meta: {
|
|
726
|
-
onUpdate,
|
|
727
|
-
cell: {
|
|
728
|
-
classNames
|
|
729
|
-
}
|
|
730
|
-
},
|
|
731
774
|
// TODO(burdon): Default.
|
|
732
775
|
header: (column) => {
|
|
733
776
|
return label ?? column.header.id;
|
|
@@ -737,43 +780,51 @@ var ColumnBuilder = class {
|
|
|
737
780
|
return /* @__PURE__ */ React8.createElement("div", {
|
|
738
781
|
className: mx5("truncate", textPadding, classNames)
|
|
739
782
|
}, value);
|
|
783
|
+
},
|
|
784
|
+
...props,
|
|
785
|
+
meta: {
|
|
786
|
+
...props.meta,
|
|
787
|
+
onUpdate,
|
|
788
|
+
cell: {
|
|
789
|
+
...props.meta?.cell,
|
|
790
|
+
classNames
|
|
791
|
+
}
|
|
740
792
|
}
|
|
741
|
-
}
|
|
793
|
+
};
|
|
742
794
|
}
|
|
743
795
|
/**
|
|
744
796
|
* Number formats.
|
|
745
797
|
*/
|
|
746
798
|
number({ label, minSize, classNames, digits, onUpdate, ...props } = {}) {
|
|
747
|
-
return
|
|
799
|
+
return {
|
|
748
800
|
size: 100,
|
|
749
801
|
minSize: 100,
|
|
802
|
+
header: (cell) => label ?? cell.header.id,
|
|
803
|
+
cell: NumberBuilderCell,
|
|
804
|
+
...props,
|
|
750
805
|
meta: {
|
|
806
|
+
...props.meta,
|
|
751
807
|
onUpdate,
|
|
752
808
|
digits,
|
|
753
809
|
header: {
|
|
754
|
-
classNames: "text-end"
|
|
810
|
+
classNames: "text-end",
|
|
811
|
+
...props.meta?.header
|
|
755
812
|
},
|
|
756
813
|
cell: {
|
|
814
|
+
...props.meta?.cell,
|
|
757
815
|
classNames
|
|
758
816
|
}
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
cell: NumberBuilderCell
|
|
762
|
-
});
|
|
817
|
+
}
|
|
818
|
+
};
|
|
763
819
|
}
|
|
764
820
|
/**
|
|
765
821
|
* Date formats.
|
|
766
822
|
*/
|
|
767
823
|
// TODO(burdon): Date picker (pluggable renderers?)
|
|
768
824
|
date({ label, format: formatSpec, relative, classNames, ...props } = {}) {
|
|
769
|
-
return
|
|
825
|
+
return {
|
|
770
826
|
size: 220,
|
|
771
827
|
minSize: 100,
|
|
772
|
-
meta: {
|
|
773
|
-
cell: {
|
|
774
|
-
classNames
|
|
775
|
-
}
|
|
776
|
-
},
|
|
777
828
|
header: (cell) => label ?? cell.header.id,
|
|
778
829
|
cell: (cell) => {
|
|
779
830
|
const value = cell.getValue();
|
|
@@ -788,24 +839,24 @@ var ColumnBuilder = class {
|
|
|
788
839
|
console.log(value);
|
|
789
840
|
return null;
|
|
790
841
|
}
|
|
842
|
+
},
|
|
843
|
+
...props,
|
|
844
|
+
meta: {
|
|
845
|
+
...props.meta,
|
|
846
|
+
cell: {
|
|
847
|
+
...props.meta?.cell,
|
|
848
|
+
classNames
|
|
849
|
+
}
|
|
791
850
|
}
|
|
792
|
-
}
|
|
851
|
+
};
|
|
793
852
|
}
|
|
794
853
|
/**
|
|
795
854
|
* PublicKey with tooltip.
|
|
796
855
|
*/
|
|
797
|
-
key({ label, tooltip, ...props } = {}) {
|
|
798
|
-
return
|
|
856
|
+
key({ label, tooltip, classNames, ...props } = {}) {
|
|
857
|
+
return {
|
|
799
858
|
size: 94,
|
|
800
859
|
minSize: 94,
|
|
801
|
-
meta: {
|
|
802
|
-
cell: {
|
|
803
|
-
classNames: [
|
|
804
|
-
"font-mono",
|
|
805
|
-
textPadding
|
|
806
|
-
]
|
|
807
|
-
}
|
|
808
|
-
},
|
|
809
860
|
header: (cell) => label ?? cell.header.id,
|
|
810
861
|
cell: (cell) => {
|
|
811
862
|
const value = cell.getValue();
|
|
@@ -816,21 +867,33 @@ var ColumnBuilder = class {
|
|
|
816
867
|
if (!tooltip) {
|
|
817
868
|
return element;
|
|
818
869
|
}
|
|
819
|
-
return /* @__PURE__ */ React8.createElement(Tooltip.Provider, null, /* @__PURE__ */ React8.createElement(Tooltip.Root, null, /* @__PURE__ */ React8.createElement(Tooltip.Trigger, null, element), /* @__PURE__ */ React8.createElement(Tooltip.Content, {
|
|
870
|
+
return /* @__PURE__ */ React8.createElement(Tooltip.Provider, null, /* @__PURE__ */ React8.createElement(Tooltip.Root, null, /* @__PURE__ */ React8.createElement(Tooltip.Trigger, null, element), /* @__PURE__ */ React8.createElement(Tooltip.Portal, null, /* @__PURE__ */ React8.createElement(Tooltip.Content, {
|
|
820
871
|
side: "right"
|
|
821
872
|
}, /* @__PURE__ */ React8.createElement(Tooltip.Arrow, null), /* @__PURE__ */ React8.createElement(ClipboardText, {
|
|
822
873
|
onClick: (ev) => {
|
|
823
874
|
ev.stopPropagation();
|
|
824
875
|
void navigator.clipboard.writeText(value.toHex());
|
|
825
876
|
}
|
|
826
|
-
}))));
|
|
877
|
+
})))));
|
|
878
|
+
},
|
|
879
|
+
...props,
|
|
880
|
+
meta: {
|
|
881
|
+
...props.meta,
|
|
882
|
+
cell: {
|
|
883
|
+
...props.meta?.cell,
|
|
884
|
+
classNames: [
|
|
885
|
+
"font-mono",
|
|
886
|
+
textPadding,
|
|
887
|
+
classNames
|
|
888
|
+
]
|
|
889
|
+
}
|
|
827
890
|
}
|
|
828
|
-
}
|
|
891
|
+
};
|
|
829
892
|
}
|
|
830
893
|
/**
|
|
831
894
|
* Row selector
|
|
832
895
|
*/
|
|
833
|
-
selectRow({
|
|
896
|
+
selectRow({ classNames, onUpdate, id = "selectRow" } = {}) {
|
|
834
897
|
return {
|
|
835
898
|
id,
|
|
836
899
|
size: 32,
|
|
@@ -862,21 +925,24 @@ var ColumnBuilder = class {
|
|
|
862
925
|
* Switch
|
|
863
926
|
*/
|
|
864
927
|
switch({ label, classNames, onUpdate, ...props } = {}) {
|
|
865
|
-
return
|
|
928
|
+
return {
|
|
866
929
|
size: 50,
|
|
867
930
|
minSize: 50,
|
|
931
|
+
header: (column) => label ?? column.header.id,
|
|
932
|
+
cell: SwitchBuilderCell,
|
|
933
|
+
...props,
|
|
868
934
|
meta: {
|
|
935
|
+
...props.meta,
|
|
869
936
|
onUpdate,
|
|
870
937
|
cell: {
|
|
938
|
+
...props.meta?.cell,
|
|
871
939
|
classNames: [
|
|
872
940
|
textPadding,
|
|
873
941
|
classNames
|
|
874
942
|
]
|
|
875
943
|
}
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
cell: SwitchBuilderCell
|
|
879
|
-
});
|
|
944
|
+
}
|
|
945
|
+
};
|
|
880
946
|
}
|
|
881
947
|
/**
|
|
882
948
|
* Icon based on boolean value.
|
|
@@ -884,7 +950,7 @@ var ColumnBuilder = class {
|
|
|
884
950
|
icon({ label, size, on, off, ...props } = {}) {
|
|
885
951
|
const IconOn = on?.Icon ?? Check2;
|
|
886
952
|
const IconOff = off?.Icon ?? X2;
|
|
887
|
-
return
|
|
953
|
+
return {
|
|
888
954
|
size: size ?? 32,
|
|
889
955
|
header: (column) => /* @__PURE__ */ React8.createElement("div", {
|
|
890
956
|
className: "justify-center"
|
|
@@ -902,8 +968,9 @@ var ColumnBuilder = class {
|
|
|
902
968
|
} else {
|
|
903
969
|
return null;
|
|
904
970
|
}
|
|
905
|
-
}
|
|
906
|
-
|
|
971
|
+
},
|
|
972
|
+
...props
|
|
973
|
+
};
|
|
907
974
|
}
|
|
908
975
|
};
|
|
909
976
|
export {
|
|
@@ -912,7 +979,6 @@ export {
|
|
|
912
979
|
ColumnMenu,
|
|
913
980
|
ColumnPanel,
|
|
914
981
|
Table,
|
|
915
|
-
columnTypes,
|
|
916
982
|
createColumnBuilder,
|
|
917
983
|
currentRow,
|
|
918
984
|
flushPadding,
|
|
@@ -933,6 +999,7 @@ export {
|
|
|
933
999
|
theadResizeThumb,
|
|
934
1000
|
theadRoot,
|
|
935
1001
|
theadTh,
|
|
936
|
-
theadTr
|
|
1002
|
+
theadTr,
|
|
1003
|
+
translations_default as translations
|
|
937
1004
|
};
|
|
938
1005
|
//# sourceMappingURL=index.mjs.map
|