@dxos/react-ui-table 0.4.7-next.f4b92be → 0.4.8-main.00e6f19
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 +93 -56
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/Cell/Cell.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +2 -0
- 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/helpers.d.ts.map +1 -1
- package/dist/types/src/theme.d.ts +1 -1
- package/dist/types/src/theme.d.ts.map +1 -1
- package/package.json +15 -14
- package/src/components/Cell/Cell.tsx +4 -1
- package/src/components/Table/Table.stories.tsx +77 -60
- package/src/components/Table/Table.tsx +45 -39
- package/src/helpers.tsx +52 -43
- package/src/theme.ts +3 -1
package/src/helpers.tsx
CHANGED
|
@@ -17,6 +17,7 @@ import { formatDistanceToNow } from 'date-fns/formatDistanceToNow';
|
|
|
17
17
|
import React, { useEffect, useRef, useState } from 'react';
|
|
18
18
|
|
|
19
19
|
import { type PublicKey } from '@dxos/keys';
|
|
20
|
+
import { log } from '@dxos/log';
|
|
20
21
|
import { type ClassNameValue, Input, Tooltip } from '@dxos/react-ui';
|
|
21
22
|
import { getSize, mx } from '@dxos/react-ui-theme';
|
|
22
23
|
|
|
@@ -94,8 +95,11 @@ const ComboboxBuilderCell = <TData extends RowData>(cellContext: CellContext<TDa
|
|
|
94
95
|
};
|
|
95
96
|
|
|
96
97
|
const StringBuilderCell = <TData extends RowData>(cellContext: CellContext<TData, string>) => {
|
|
97
|
-
const
|
|
98
|
-
const {
|
|
98
|
+
const ref = useRef<HTMLInputElement>(null);
|
|
99
|
+
const { findPrevFocusable } = useFocusFinders();
|
|
100
|
+
|
|
101
|
+
const { onUpdate, cell } = cellContext.column.columnDef.meta as ColumnMeta<TData, string>;
|
|
102
|
+
|
|
99
103
|
// https://tanstack.com/table/v8/docs/examples/react/editable-data
|
|
100
104
|
const initialValue = cellContext.getValue();
|
|
101
105
|
const [value, setValue] = useState(() => {
|
|
@@ -108,16 +112,14 @@ const StringBuilderCell = <TData extends RowData>(cellContext: CellContext<TData
|
|
|
108
112
|
});
|
|
109
113
|
|
|
110
114
|
const handleSave = () => {
|
|
111
|
-
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
115
|
+
ref.current && document.activeElement === ref.current && findPrevFocusable(ref.current)?.focus();
|
|
114
116
|
|
|
115
|
-
|
|
117
|
+
if (value !== initialValue) {
|
|
118
|
+
onUpdate?.(cellContext.row.original, cellContext.column.id, value);
|
|
119
|
+
}
|
|
116
120
|
};
|
|
117
121
|
|
|
118
|
-
const handleCancel = () =>
|
|
119
|
-
setValue(initialValue);
|
|
120
|
-
};
|
|
122
|
+
const handleCancel = () => setValue(initialValue);
|
|
121
123
|
|
|
122
124
|
// Check if first input column of last row.
|
|
123
125
|
const rows = cellContext.table.getRowModel().flatRows;
|
|
@@ -128,12 +130,12 @@ const StringBuilderCell = <TData extends RowData>(cellContext: CellContext<TData
|
|
|
128
130
|
return (
|
|
129
131
|
<Input.Root>
|
|
130
132
|
<Input.TextInput
|
|
131
|
-
ref={
|
|
133
|
+
ref={ref}
|
|
132
134
|
variant='subdued'
|
|
133
135
|
placeholder={placeholder ? 'Add row...' : undefined}
|
|
134
|
-
classNames={['is-full', textPadding]}
|
|
136
|
+
classNames={['is-full', textPadding, cell?.classNames]}
|
|
135
137
|
value={value ?? ''}
|
|
136
|
-
onBlur={
|
|
138
|
+
onBlur={handleSave}
|
|
137
139
|
onChange={(event) => setValue(event.target.value)}
|
|
138
140
|
onKeyDown={(event) => (event.key === 'Enter' && handleSave()) || (event.key === 'Escape' && handleCancel())}
|
|
139
141
|
/>
|
|
@@ -163,17 +165,20 @@ const NumberBuilderCell = <TData extends RowData>(cellContext: CellContext<TData
|
|
|
163
165
|
(!document.activeElement || document.activeElement !== ref.current) && setText(displayNumber(value, digits));
|
|
164
166
|
}, [digits, value]);
|
|
165
167
|
|
|
166
|
-
const handleEdit = () =>
|
|
167
|
-
if (onUpdate) {
|
|
168
|
-
setText(value !== undefined ? String(value) : '');
|
|
169
|
-
}
|
|
170
|
-
};
|
|
168
|
+
const handleEdit = () => setText(value !== undefined ? String(value) : '');
|
|
171
169
|
|
|
172
170
|
// TODO(burdon): Property is encoded as float (e.g., 6.1 => 6.099)
|
|
173
171
|
const handleSave = () => {
|
|
174
172
|
const nextValue = parseNumber(text);
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
|
|
174
|
+
if (!isNaN(nextValue)) {
|
|
175
|
+
onUpdate?.(cellContext.row.original, cellContext.column.id, nextValue);
|
|
176
|
+
setText(displayNumber(nextValue, digits));
|
|
177
|
+
} else {
|
|
178
|
+
// Reset the text to display the original value without updating the model.
|
|
179
|
+
setText(displayNumber(value, digits));
|
|
180
|
+
}
|
|
181
|
+
|
|
177
182
|
// Shift focus only if input is focused on save (e.g. on `Enter`).
|
|
178
183
|
ref.current && document.activeElement === ref.current && findPrevFocusable(ref.current)?.focus();
|
|
179
184
|
};
|
|
@@ -209,20 +214,23 @@ const RowSelectorBuilderCell = <TData extends RowData>(cellContext: CellContext<
|
|
|
209
214
|
const checked = row.getCanSelect()
|
|
210
215
|
? row.getIsSelected()
|
|
211
216
|
: row.getCanSelectSubRows() && (row.getIsSomeSelected() ? 'indeterminate' : row.getIsAllSubRowsSelected());
|
|
217
|
+
|
|
212
218
|
return (
|
|
213
|
-
<
|
|
214
|
-
<Input.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
row.
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
219
|
+
<div className='flex justify-center w-full h-full' role='presentation'>
|
|
220
|
+
<Input.Root>
|
|
221
|
+
<Input.Checkbox
|
|
222
|
+
size={4}
|
|
223
|
+
classNames={[cell?.classNames]}
|
|
224
|
+
checked={checked}
|
|
225
|
+
onCheckedChange={(event) => {
|
|
226
|
+
if (row.getCanSelect()) {
|
|
227
|
+
row.getToggleSelectedHandler()(event);
|
|
228
|
+
}
|
|
229
|
+
}}
|
|
230
|
+
disabled={!(row.getCanSelect() || row.getCanSelectSubRows())}
|
|
231
|
+
/>
|
|
232
|
+
</Input.Root>
|
|
233
|
+
</div>
|
|
226
234
|
);
|
|
227
235
|
};
|
|
228
236
|
|
|
@@ -359,7 +367,7 @@ export class ColumnBuilder<TData extends RowData> {
|
|
|
359
367
|
|
|
360
368
|
return <div className={mx(textPadding, classNames)}>{str}</div>;
|
|
361
369
|
} catch (err) {
|
|
362
|
-
|
|
370
|
+
log.info('formatError', { value });
|
|
363
371
|
return null;
|
|
364
372
|
}
|
|
365
373
|
},
|
|
@@ -421,21 +429,22 @@ export class ColumnBuilder<TData extends RowData> {
|
|
|
421
429
|
return {
|
|
422
430
|
id,
|
|
423
431
|
size: 32,
|
|
424
|
-
|
|
425
|
-
maxSize: 32,
|
|
432
|
+
enableResizing: false,
|
|
426
433
|
meta: { onUpdate, cell: { classNames } },
|
|
427
434
|
header: ({ table }) => {
|
|
428
435
|
const { rowsSelectable } = useTableContext('HELPER_SELECT_ROW_HEADER_CELL');
|
|
429
436
|
const checked = table.getIsSomeRowsSelected() ? 'indeterminate' : table.getIsAllRowsSelected();
|
|
430
437
|
return rowsSelectable === 'multi' ? (
|
|
431
|
-
<
|
|
432
|
-
<Input.
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
438
|
+
<div className='flex justify-center w-full h-full' role='presentation'>
|
|
439
|
+
<Input.Root>
|
|
440
|
+
<Input.Checkbox
|
|
441
|
+
size={4}
|
|
442
|
+
classNames={['mli-auto', classNames]}
|
|
443
|
+
checked={checked}
|
|
444
|
+
onCheckedChange={() => table.toggleAllRowsSelected()}
|
|
445
|
+
/>
|
|
446
|
+
</Input.Root>
|
|
447
|
+
</div>
|
|
439
448
|
) : null;
|
|
440
449
|
},
|
|
441
450
|
cell: RowSelectorBuilderCell,
|
package/src/theme.ts
CHANGED
|
@@ -23,7 +23,8 @@ export const flushPadding = 'pli-0 plb-0';
|
|
|
23
23
|
export const textPadding = 'pli-2 plb-0.5';
|
|
24
24
|
export const headPadding = 'pli-2 plb-1.5';
|
|
25
25
|
|
|
26
|
-
export const gridCellFocusRing =
|
|
26
|
+
export const gridCellFocusRing =
|
|
27
|
+
'focus-within:z-[11] focus-within:outline outline-2 outline-primary-500 dark:outline-primary-400';
|
|
27
28
|
|
|
28
29
|
//
|
|
29
30
|
// table
|
|
@@ -89,6 +90,7 @@ export const tbodyTr: ComponentFunction<TbodyTrStyleProps> = ({ canBeCurrent },
|
|
|
89
90
|
|
|
90
91
|
export const tdRoot: ComponentFunction<TbodyStyleProps> = ({ border, isGrid }, ...etc) =>
|
|
91
92
|
mx('relative', flushPadding, border && 'border', border && groupBorder, isGrid && gridCellFocusRing, ...etc);
|
|
93
|
+
|
|
92
94
|
export const tdContent: ComponentFunction<CellContext<any, any>> = (_props, ...etc) => mx(...etc);
|
|
93
95
|
|
|
94
96
|
//
|