@dxos/react-ui-table 0.4.10-main.dd2b9ae → 0.4.10-main.dfa0529
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 +115 -68
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/ColumnMenu/ColumnMenu.stories.d.ts +5 -1
- package/dist/types/src/components/ColumnMenu/ColumnMenu.stories.d.ts.map +1 -1
- package/dist/types/src/components/ColumnMenu/ColumnSettingsForm.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 +3 -0
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/usePinLastRow.d.ts +1 -1
- package/dist/types/src/hooks/usePinLastRow.d.ts.map +1 -1
- package/package.json +15 -15
- package/src/components/ColumnMenu/ColumnMenu.stories.tsx +30 -0
- package/src/components/ColumnMenu/ColumnSettingsForm.tsx +69 -63
- package/src/components/Table/Table.stories.tsx +56 -1
- package/src/components/Table/Table.tsx +23 -8
- package/src/hooks/usePinLastRow.ts +41 -20
|
@@ -92,7 +92,7 @@ var CellCombobox = ({ model, value, onValueChange }) => {
|
|
|
92
92
|
|
|
93
93
|
// packages/ui/react-ui-table/src/components/ColumnMenu/ColumnMenu.tsx
|
|
94
94
|
import { X as X2, GearSix, CaretDown as CaretDown2, ArrowDown, ArrowUp } from "@phosphor-icons/react";
|
|
95
|
-
import React3, { useRef as useRef2, useState as useState5, useCallback as
|
|
95
|
+
import React3, { useRef as useRef2, useState as useState5, useCallback as useCallback3 } from "react";
|
|
96
96
|
import { Button as Button2, DensityProvider, Popover as Popover2, DropdownMenu } from "@dxos/react-ui";
|
|
97
97
|
import { getSize as getSize3, mx as mx3 } from "@dxos/react-ui-theme";
|
|
98
98
|
|
|
@@ -107,19 +107,21 @@ var Section = ({ children, className }) => /* @__PURE__ */ React2.createElement(
|
|
|
107
107
|
className: mx2("p-2", className)
|
|
108
108
|
}, children);
|
|
109
109
|
var ColumnSettingsForm = ({ column, tableDef, tableDefs, onUpdate, onDelete, onClose }) => {
|
|
110
|
-
const [
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
110
|
+
const [formState, setFormState] = useState2({
|
|
111
|
+
prop: column.id,
|
|
112
|
+
refTable: column.refTable,
|
|
113
|
+
refProp: column.refProp,
|
|
114
|
+
type: String(column.type),
|
|
115
|
+
label: column.label,
|
|
116
|
+
digits: String(column.digits ?? "0")
|
|
117
|
+
});
|
|
116
118
|
const propRef = useRef(null);
|
|
117
119
|
const { t } = useTranslation2(translationKey);
|
|
118
120
|
const handleCancel = () => {
|
|
119
|
-
setProp(column.id);
|
|
120
121
|
onClose?.();
|
|
121
122
|
};
|
|
122
123
|
const handleSave = () => {
|
|
124
|
+
const { prop, refTable, refProp, type, label, digits } = formState;
|
|
123
125
|
if (!prop.length || !prop.match(/^[a-zA-Z_].+/i)) {
|
|
124
126
|
propRef.current?.focus();
|
|
125
127
|
return;
|
|
@@ -131,7 +133,7 @@ var ColumnSettingsForm = ({ column, tableDef, tableDefs, onUpdate, onDelete, onC
|
|
|
131
133
|
return;
|
|
132
134
|
}
|
|
133
135
|
}
|
|
134
|
-
onUpdate?.(
|
|
136
|
+
onUpdate?.(column.id, {
|
|
135
137
|
id: prop,
|
|
136
138
|
prop,
|
|
137
139
|
label,
|
|
@@ -148,22 +150,30 @@ var ColumnSettingsForm = ({ column, tableDef, tableDefs, onUpdate, onDelete, onC
|
|
|
148
150
|
classNames: "mbe-1"
|
|
149
151
|
}, t("column label label")), /* @__PURE__ */ React2.createElement(Input.TextInput, {
|
|
150
152
|
placeholder: "Column label",
|
|
151
|
-
value: label ?? "",
|
|
152
|
-
onChange: (event) =>
|
|
153
|
+
value: formState.label ?? "",
|
|
154
|
+
onChange: (event) => setFormState((prevState) => ({
|
|
155
|
+
...prevState,
|
|
156
|
+
label: event.target.value
|
|
157
|
+
})),
|
|
153
158
|
autoFocus: true
|
|
154
159
|
})), /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
|
|
155
160
|
classNames: "mbe-1 mbs-3"
|
|
156
161
|
}, t("property key label")), /* @__PURE__ */ React2.createElement(Input.TextInput, {
|
|
157
162
|
ref: propRef,
|
|
158
163
|
placeholder: "Property key",
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
164
|
+
value: formState.prop ?? "",
|
|
165
|
+
onChange: (event) => setFormState((prevState) => ({
|
|
166
|
+
...prevState,
|
|
167
|
+
prop: event.target.value.replace(/[^\w_]/g, "")
|
|
168
|
+
}))
|
|
162
169
|
})), /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
|
|
163
170
|
classNames: "mbe-1 mbs-3"
|
|
164
171
|
}, t("column type label")), /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
165
|
-
value: type,
|
|
166
|
-
onValueChange:
|
|
172
|
+
value: formState.type,
|
|
173
|
+
onValueChange: (value) => setFormState((prevState) => ({
|
|
174
|
+
...prevState,
|
|
175
|
+
type: value
|
|
176
|
+
}))
|
|
167
177
|
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
168
178
|
placeholder: "Type",
|
|
169
179
|
classNames: "is-full"
|
|
@@ -172,37 +182,46 @@ var ColumnSettingsForm = ({ column, tableDef, tableDefs, onUpdate, onDelete, onC
|
|
|
172
182
|
"boolean",
|
|
173
183
|
"string",
|
|
174
184
|
"ref"
|
|
175
|
-
].map((
|
|
176
|
-
key:
|
|
177
|
-
value:
|
|
178
|
-
}, t(`${
|
|
185
|
+
].map((type) => /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
186
|
+
key: type,
|
|
187
|
+
value: type
|
|
188
|
+
}, t(`${type} column type label`))))))))), formState.type === "number" && /* @__PURE__ */ React2.createElement(Section, null, /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
|
|
179
189
|
classNames: "mbe-1 mbs-3"
|
|
180
190
|
}, t("digits label")), /* @__PURE__ */ React2.createElement(Input.TextInput, {
|
|
181
|
-
value: digits ?? "",
|
|
182
|
-
onChange: (event) =>
|
|
183
|
-
|
|
191
|
+
value: formState.digits ?? "",
|
|
192
|
+
onChange: (event) => setFormState((prevState) => ({
|
|
193
|
+
...prevState,
|
|
194
|
+
digits: event.target.value
|
|
195
|
+
}))
|
|
196
|
+
}))), formState.type === "ref" && /* @__PURE__ */ React2.createElement(Section, null, /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
|
|
184
197
|
classNames: "mbe-1 mbs-3"
|
|
185
198
|
}, "Table"), /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
186
|
-
value: refTable,
|
|
187
|
-
onValueChange:
|
|
199
|
+
value: formState.refTable,
|
|
200
|
+
onValueChange: (value) => setFormState((prevState) => ({
|
|
201
|
+
...prevState,
|
|
202
|
+
refTable: value
|
|
203
|
+
}))
|
|
188
204
|
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
189
205
|
placeholder: "Table",
|
|
190
206
|
classNames: "is-full"
|
|
191
207
|
}), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, tableDefs.filter((t2) => t2.id !== tableDef.id).map(({ id, name }) => /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
192
208
|
key: id,
|
|
193
209
|
value: id
|
|
194
|
-
}, name ?? id))))))), refTable && /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
|
|
210
|
+
}, name ?? id))))))), formState.refTable && /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
|
|
195
211
|
classNames: "mbe-1 mbs-3"
|
|
196
212
|
}, "Table property"), /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
197
|
-
value: refProp,
|
|
198
|
-
onValueChange:
|
|
213
|
+
value: formState.refProp,
|
|
214
|
+
onValueChange: (value) => setFormState((prevState) => ({
|
|
215
|
+
...prevState,
|
|
216
|
+
refProp: value
|
|
217
|
+
}))
|
|
199
218
|
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
200
219
|
placeholder: "Property",
|
|
201
220
|
classNames: "is-full"
|
|
202
|
-
}), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, tableDefs.find((tableDef2) => tableDef2.id === refTable)?.columns.map(({ id, label
|
|
221
|
+
}), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, tableDefs.find((tableDef2) => tableDef2.id === formState.refTable)?.columns.map(({ id, label }) => /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
203
222
|
key: id,
|
|
204
223
|
value: id
|
|
205
|
-
},
|
|
224
|
+
}, label ?? id)))))))), /* @__PURE__ */ React2.createElement(Separator, {
|
|
206
225
|
classNames: "mli-2"
|
|
207
226
|
}), /* @__PURE__ */ React2.createElement(Section, {
|
|
208
227
|
className: "space-b-1.5"
|
|
@@ -280,38 +299,58 @@ var useColumnSorting = (column) => {
|
|
|
280
299
|
};
|
|
281
300
|
|
|
282
301
|
// packages/ui/react-ui-table/src/hooks/usePinLastRow.ts
|
|
283
|
-
import { useEffect, useState as useState4 } from "react";
|
|
302
|
+
import { useCallback as useCallback2, useEffect, useState as useState4 } from "react";
|
|
284
303
|
var usePinLastRow = (pinLastRow, table, data, getScrollElement) => {
|
|
285
304
|
const [pinnedRowKey, setPinnedRowKey] = useState4();
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
305
|
+
const scrollToBottom = useCallback2(() => {
|
|
306
|
+
const scrollElement = getScrollElement?.();
|
|
307
|
+
if (scrollElement) {
|
|
308
|
+
requestAnimationFrame(() => scrollElement.scrollTo({
|
|
309
|
+
top: scrollElement.scrollHeight
|
|
310
|
+
}));
|
|
289
311
|
}
|
|
312
|
+
}, [
|
|
313
|
+
getScrollElement
|
|
314
|
+
]);
|
|
315
|
+
const pinRow = useCallback2((rowToPin) => {
|
|
316
|
+
table.resetRowPinning();
|
|
317
|
+
rowToPin.pin("bottom");
|
|
318
|
+
setPinnedRowKey(rowToPin.id);
|
|
319
|
+
}, [
|
|
320
|
+
table
|
|
321
|
+
]);
|
|
322
|
+
const clearRowPinning = useCallback2(() => {
|
|
323
|
+
table.resetRowPinning();
|
|
324
|
+
setPinnedRowKey(void 0);
|
|
325
|
+
}, [
|
|
326
|
+
table
|
|
327
|
+
]);
|
|
328
|
+
const pinLastRowCallback = useCallback2(() => {
|
|
290
329
|
const rows = table.getRowModel().rows;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
330
|
+
if (rows.length === 0) {
|
|
331
|
+
return clearRowPinning();
|
|
332
|
+
}
|
|
333
|
+
const lastRow = rows[rows.length - 1];
|
|
334
|
+
if (lastRow.id === pinnedRowKey) {
|
|
294
335
|
return;
|
|
295
336
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const isFirstRender = pinnedRowKey === void 0;
|
|
300
|
-
if (scrollElement && !isFirstRender) {
|
|
301
|
-
requestAnimationFrame(() => {
|
|
302
|
-
scrollElement.scrollTo({
|
|
303
|
-
top: scrollElement.scrollHeight
|
|
304
|
-
});
|
|
305
|
-
});
|
|
337
|
+
pinRow(lastRow);
|
|
338
|
+
if (pinnedRowKey !== void 0) {
|
|
339
|
+
scrollToBottom();
|
|
306
340
|
}
|
|
307
|
-
setPinnedRowKey(rowId);
|
|
308
341
|
}, [
|
|
309
|
-
pinLastRow,
|
|
310
342
|
table,
|
|
311
|
-
|
|
312
|
-
pinnedRowKey
|
|
313
|
-
|
|
314
|
-
|
|
343
|
+
scrollToBottom,
|
|
344
|
+
pinnedRowKey
|
|
345
|
+
]);
|
|
346
|
+
useEffect(() => {
|
|
347
|
+
if (pinLastRow) {
|
|
348
|
+
pinLastRowCallback();
|
|
349
|
+
}
|
|
350
|
+
}, [
|
|
351
|
+
data,
|
|
352
|
+
pinLastRow,
|
|
353
|
+
pinLastRowCallback
|
|
315
354
|
]);
|
|
316
355
|
};
|
|
317
356
|
|
|
@@ -323,14 +362,14 @@ var ColumnMenu = ({ column, ...props }) => {
|
|
|
323
362
|
const columnSettingsAnchorRef = useRef2(null);
|
|
324
363
|
const [isColumnSettingsOpen, setIsColumnSettingsOpen] = useState5(false);
|
|
325
364
|
const shouldPreventFocusOnClose = useRef2(false);
|
|
326
|
-
const onOpenColumnSettings =
|
|
365
|
+
const onOpenColumnSettings = useCallback3(() => {
|
|
327
366
|
shouldPreventFocusOnClose.current = true;
|
|
328
367
|
setIsColumnSettingsOpen(true);
|
|
329
368
|
}, [
|
|
330
369
|
shouldPreventFocusOnClose,
|
|
331
370
|
setIsColumnSettingsOpen
|
|
332
371
|
]);
|
|
333
|
-
const onDropdownCloseAutoFocus =
|
|
372
|
+
const onDropdownCloseAutoFocus = useCallback3((event) => {
|
|
334
373
|
if (shouldPreventFocusOnClose.current) {
|
|
335
374
|
event.preventDefault();
|
|
336
375
|
shouldPreventFocusOnClose.current = false;
|
|
@@ -444,7 +483,7 @@ var SortIndicator = ({ direction, onClick }) => {
|
|
|
444
483
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
445
484
|
import { getCoreRowModel, getSortedRowModel, useReactTable, getGroupedRowModel, getExpandedRowModel } from "@tanstack/react-table";
|
|
446
485
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
447
|
-
import React9, { Fragment, useCallback as
|
|
486
|
+
import React9, { Fragment, useCallback as useCallback4, useEffect as useEffect2, useState as useState6 } from "react";
|
|
448
487
|
import { log } from "@dxos/log";
|
|
449
488
|
import { useDefaultValue, useOnTransition } from "@dxos/react-ui";
|
|
450
489
|
|
|
@@ -660,7 +699,7 @@ var Table = (props) => {
|
|
|
660
699
|
setColumnSizing
|
|
661
700
|
]);
|
|
662
701
|
const [columnSizingInfo, setColumnSizingInfo] = useState6({});
|
|
663
|
-
const notifyColumnResize =
|
|
702
|
+
const notifyColumnResize = useCallback4(() => onColumnResize?.(columnSizing), [
|
|
664
703
|
onColumnResize,
|
|
665
704
|
columnSizing
|
|
666
705
|
]);
|
|
@@ -670,7 +709,7 @@ var Table = (props) => {
|
|
|
670
709
|
onChange: props.onRowSelectionChange,
|
|
671
710
|
defaultProp: props.defaultRowSelection
|
|
672
711
|
});
|
|
673
|
-
const handleRowSelectionChange =
|
|
712
|
+
const handleRowSelectionChange = useCallback4((updaterOrValue) => {
|
|
674
713
|
const nextRowSelection = typeof updaterOrValue === "function" ? updaterOrValue(rowSelection) : updaterOrValue;
|
|
675
714
|
if (rowsSelectable === "multi") {
|
|
676
715
|
setRowSelection(nextRowSelection);
|
|
@@ -742,7 +781,7 @@ var Table = (props) => {
|
|
|
742
781
|
if (!getScrollElement) {
|
|
743
782
|
log.warn("Table: getScrollElement is not set. This is required for virtualized tables.", void 0, {
|
|
744
783
|
F: __dxlog_file,
|
|
745
|
-
L:
|
|
784
|
+
L: 160,
|
|
746
785
|
S: void 0,
|
|
747
786
|
C: (f, a) => f(...a)
|
|
748
787
|
});
|
|
@@ -762,12 +801,6 @@ var Table = (props) => {
|
|
|
762
801
|
var TableImpl = (props) => {
|
|
763
802
|
const { debug, classNames, getScrollElement, role, footer, grouping, fullWidth } = props;
|
|
764
803
|
const { table } = useTableContext();
|
|
765
|
-
const centerRows = table.getCenterRows();
|
|
766
|
-
const bottomRows = table.getBottomRows();
|
|
767
|
-
const rows = [
|
|
768
|
-
...centerRows,
|
|
769
|
-
...bottomRows
|
|
770
|
-
];
|
|
771
804
|
if (debug) {
|
|
772
805
|
return /* @__PURE__ */ React9.createElement("pre", {
|
|
773
806
|
className: "font-mono text-xs text-neutral-500 m-1 p-2 ring"
|
|
@@ -787,14 +820,28 @@ var TableImpl = (props) => {
|
|
|
787
820
|
getScrollElement
|
|
788
821
|
}) : /* @__PURE__ */ React9.createElement(VirtualizedTableContent, {
|
|
789
822
|
getScrollElement
|
|
790
|
-
}) : /* @__PURE__ */ React9.createElement(
|
|
823
|
+
}) : /* @__PURE__ */ React9.createElement(UnvirtualizedTableContent, null) : /* @__PURE__ */ React9.createElement(GroupedTableContent, null), footer && /* @__PURE__ */ React9.createElement(TableFooter, null));
|
|
824
|
+
};
|
|
825
|
+
var UnvirtualizedTableContent = () => {
|
|
826
|
+
const { table } = useTableContext();
|
|
827
|
+
const centerRows = table.getCenterRows();
|
|
828
|
+
const pinnedRows = table.getBottomRows();
|
|
829
|
+
const rows = [
|
|
830
|
+
...centerRows,
|
|
831
|
+
...pinnedRows
|
|
832
|
+
];
|
|
833
|
+
return /* @__PURE__ */ React9.createElement(TableBody, {
|
|
791
834
|
rows
|
|
792
|
-
})
|
|
835
|
+
});
|
|
793
836
|
};
|
|
794
837
|
var VirtualizedTableContent = ({ getScrollElement }) => {
|
|
795
838
|
const { table } = useTableContext();
|
|
796
839
|
const centerRows = table.getCenterRows();
|
|
797
|
-
|
|
840
|
+
let pinnedRows = [];
|
|
841
|
+
try {
|
|
842
|
+
pinnedRows = table.getBottomRows();
|
|
843
|
+
} catch (_) {
|
|
844
|
+
}
|
|
798
845
|
const { getTotalSize, getVirtualItems } = useVirtualizer({
|
|
799
846
|
getScrollElement,
|
|
800
847
|
count: centerRows.length,
|