@dxos/react-ui-table 0.6.12-main.89e9959 → 0.6.12-main.ac23639
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 +38 -122
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/ColumnMenu/ColumnMenu.d.ts +6 -3
- package/dist/types/src/components/ColumnMenu/ColumnMenu.d.ts.map +1 -1
- package/dist/types/src/components/ColumnMenu/ColumnMenu.stories.d.ts +3 -3
- package/dist/types/src/components/ColumnMenu/ColumnMenu.stories.d.ts.map +1 -1
- package/dist/types/src/components/ColumnMenu/ColumnSettings.d.ts +15 -0
- package/dist/types/src/components/ColumnMenu/ColumnSettings.d.ts.map +1 -0
- package/dist/types/src/components/ColumnMenu/ColumnSettings.stories.d.ts +84 -0
- package/dist/types/src/components/ColumnMenu/ColumnSettings.stories.d.ts.map +1 -0
- package/dist/types/src/components/ColumnMenu/index.d.ts +1 -1
- package/dist/types/src/components/ColumnMenu/index.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/TableContext.d.ts +2 -4
- package/dist/types/src/components/Table/TableContext.d.ts.map +1 -1
- package/dist/types/src/components/Table/index.d.ts +2 -1
- package/dist/types/src/components/Table/index.d.ts.map +1 -1
- package/dist/types/src/helpers.d.ts +1 -1
- package/dist/types/src/helpers.d.ts.map +1 -1
- package/dist/types/src/schema/{SchemaToTable.stories.d.ts → Schema.stories.d.ts} +2 -3
- package/dist/types/src/schema/Schema.stories.d.ts.map +1 -0
- package/dist/types/src/schema/{schemaToColumns.d.ts → column-utils.d.ts} +1 -1
- package/dist/types/src/schema/column-utils.d.ts.map +1 -0
- package/dist/types/src/schema/index.d.ts +1 -1
- package/dist/types/src/schema/index.d.ts.map +1 -1
- package/dist/types/src/schema/types.d.ts +4 -4
- package/dist/types/src/schema/types.d.ts.map +1 -1
- package/package.json +18 -15
- package/src/components/ColumnMenu/ColumnMenu.stories.tsx +13 -12
- package/src/components/ColumnMenu/ColumnMenu.tsx +8 -5
- package/src/components/ColumnMenu/{ColumnSettingsForm.stories.tsx → ColumnSettings.stories.tsx} +27 -23
- package/src/components/ColumnMenu/{ColumnSettingsForm.tsx → ColumnSettings.tsx} +41 -40
- package/src/components/ColumnMenu/index.ts +1 -1
- package/src/components/Table/Table.tsx +5 -6
- package/src/components/Table/TableContext.tsx +13 -7
- package/src/components/Table/index.ts +2 -1
- package/src/components/Table/props.ts +4 -4
- package/src/helpers.tsx +4 -6
- package/src/schema/{SchemaToTable.stories.tsx → Schema.stories.tsx} +5 -14
- package/src/schema/{schemaToColumns.ts → column-utils.ts} +8 -8
- package/src/schema/index.ts +1 -1
- package/src/schema/types.ts +8 -6
- package/src/translations.ts +1 -1
- package/dist/types/src/components/ColumnMenu/ColumnSettingsForm.d.ts +0 -12
- package/dist/types/src/components/ColumnMenu/ColumnSettingsForm.d.ts.map +0 -1
- package/dist/types/src/components/ColumnMenu/ColumnSettingsForm.stories.d.ts +0 -63
- package/dist/types/src/components/ColumnMenu/ColumnSettingsForm.stories.d.ts.map +0 -1
- package/dist/types/src/schema/SchemaToTable.stories.d.ts.map +0 -1
- package/dist/types/src/schema/schema.d.ts +0 -5
- package/dist/types/src/schema/schema.d.ts.map +0 -1
- package/dist/types/src/schema/schema.test.d.ts +0 -2
- package/dist/types/src/schema/schema.test.d.ts.map +0 -1
- package/dist/types/src/schema/schemaToColumns.d.ts.map +0 -1
- package/src/schema/schema.test.ts +0 -146
- package/src/schema/schema.ts +0 -92
|
@@ -9,22 +9,25 @@ import React, { useRef, useState, useCallback } from 'react';
|
|
|
9
9
|
import { Button, Popover, DropdownMenu } from '@dxos/react-ui';
|
|
10
10
|
import { getSize, mx } from '@dxos/react-ui-theme';
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import { ColumnSettings } from './ColumnSettings';
|
|
13
13
|
import { useSortColumn } from '../../hooks';
|
|
14
|
-
import { type TableDef, type
|
|
14
|
+
import { type TableDef, type ColumnDef } from '../../schema';
|
|
15
15
|
|
|
16
16
|
export type ColumnMenuProps<TData extends RowData, TValue> = {
|
|
17
17
|
context: HeaderContext<TData, TValue>;
|
|
18
18
|
tablesToReference: TableDef[];
|
|
19
19
|
tableDef: TableDef;
|
|
20
|
-
column:
|
|
20
|
+
column: ColumnDef;
|
|
21
21
|
columnOrderable: boolean;
|
|
22
22
|
columnPosition: 'start' | 'end' | undefined;
|
|
23
23
|
onColumnReorder: (columnId: string, direction: 'left' | 'right') => void;
|
|
24
|
-
onUpdate?: (id: string, column:
|
|
24
|
+
onUpdate?: (id: string, column: ColumnDef) => void;
|
|
25
25
|
onDelete?: (id: string) => void;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated
|
|
30
|
+
*/
|
|
28
31
|
export const ColumnMenu = <TData extends RowData, TValue>({
|
|
29
32
|
column,
|
|
30
33
|
columnOrderable,
|
|
@@ -138,7 +141,7 @@ export const ColumnMenu = <TData extends RowData, TValue>({
|
|
|
138
141
|
<Popover.Portal>
|
|
139
142
|
<Popover.Content>
|
|
140
143
|
<Popover.Viewport>
|
|
141
|
-
<
|
|
144
|
+
<ColumnSettings {...props} column={column} onClose={() => setIsColumnSettingsOpen(false)} />
|
|
142
145
|
</Popover.Viewport>
|
|
143
146
|
<Popover.Arrow />
|
|
144
147
|
</Popover.Content>
|
package/src/components/ColumnMenu/{ColumnSettingsForm.stories.tsx → ColumnSettings.stories.tsx}
RENAMED
|
@@ -3,25 +3,38 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
|
+
|
|
6
7
|
import React from 'react';
|
|
7
8
|
|
|
8
|
-
import {
|
|
9
|
+
import { FieldValueType } from '@dxos/schema';
|
|
10
|
+
import { withTheme, withLayout } from '@dxos/storybook-utils';
|
|
9
11
|
|
|
10
|
-
import {
|
|
12
|
+
import { ColumnSettings, type ColumnSettingsProps } from './ColumnSettings';
|
|
11
13
|
import { type TableDef } from '../../schema';
|
|
14
|
+
import translations from '../../translations';
|
|
15
|
+
|
|
16
|
+
const Story = (props: ColumnSettingsProps) => (
|
|
17
|
+
<div className='flex w-[240px] m-2 p-2 border border-separator rounded'>
|
|
18
|
+
<ColumnSettings {...props} />
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
12
21
|
|
|
13
22
|
export default {
|
|
14
|
-
title: 'react-ui-table/
|
|
15
|
-
component:
|
|
16
|
-
decorators: [withTheme],
|
|
23
|
+
title: 'react-ui-table/ColumnSettings',
|
|
24
|
+
component: ColumnSettings,
|
|
25
|
+
decorators: [withTheme, withLayout()],
|
|
26
|
+
parameters: {
|
|
27
|
+
translations,
|
|
28
|
+
},
|
|
29
|
+
render: Story,
|
|
17
30
|
};
|
|
18
31
|
|
|
19
32
|
const sampleTableDef: TableDef = {
|
|
20
33
|
id: '1',
|
|
21
34
|
name: 'Sample Table',
|
|
22
35
|
columns: [
|
|
23
|
-
{ id: 'col-1', prop: 'name', type:
|
|
24
|
-
{ id: 'col-2', prop: 'age', type:
|
|
36
|
+
{ id: 'col-1', prop: 'name', type: FieldValueType.String, label: 'Name' },
|
|
37
|
+
{ id: 'col-2', prop: 'age', type: FieldValueType.Number, label: 'Age', digits: 0 },
|
|
25
38
|
],
|
|
26
39
|
};
|
|
27
40
|
|
|
@@ -31,17 +44,17 @@ const sampleTablesToReference: TableDef[] = [
|
|
|
31
44
|
id: '2',
|
|
32
45
|
name: 'Reference Table',
|
|
33
46
|
columns: [
|
|
34
|
-
{ id: 'ref-col-1', prop: 'id', type:
|
|
35
|
-
{ id: 'ref-col-2', prop: 'description', type:
|
|
47
|
+
{ id: 'ref-col-1', prop: 'id', type: FieldValueType.String, label: 'ID' },
|
|
48
|
+
{ id: 'ref-col-2', prop: 'description', type: FieldValueType.String, label: 'Description' },
|
|
36
49
|
],
|
|
37
50
|
},
|
|
38
51
|
];
|
|
39
52
|
|
|
40
|
-
const defaultArgs:
|
|
53
|
+
const defaultArgs: ColumnSettingsProps = {
|
|
41
54
|
column: {
|
|
42
55
|
id: 'col-1',
|
|
43
56
|
prop: 'name',
|
|
44
|
-
type:
|
|
57
|
+
type: FieldValueType.String,
|
|
45
58
|
label: 'Name',
|
|
46
59
|
},
|
|
47
60
|
tableDef: sampleTableDef,
|
|
@@ -61,7 +74,7 @@ export const NumberColumn = {
|
|
|
61
74
|
column: {
|
|
62
75
|
id: 'col-2',
|
|
63
76
|
prop: 'age',
|
|
64
|
-
type:
|
|
77
|
+
type: FieldValueType.Number,
|
|
65
78
|
label: 'Age',
|
|
66
79
|
digits: 0,
|
|
67
80
|
},
|
|
@@ -74,7 +87,7 @@ export const ReferenceColumn = {
|
|
|
74
87
|
column: {
|
|
75
88
|
id: 'col-3',
|
|
76
89
|
prop: 'reference',
|
|
77
|
-
type:
|
|
90
|
+
type: FieldValueType.Ref,
|
|
78
91
|
label: 'Reference',
|
|
79
92
|
refTable: '2',
|
|
80
93
|
refProp: 'ref-col-1',
|
|
@@ -88,17 +101,8 @@ export const NewColumn = {
|
|
|
88
101
|
column: {
|
|
89
102
|
id: 'new-col',
|
|
90
103
|
prop: '',
|
|
91
|
-
type:
|
|
104
|
+
type: FieldValueType.String,
|
|
92
105
|
label: '',
|
|
93
106
|
},
|
|
94
107
|
},
|
|
95
108
|
};
|
|
96
|
-
|
|
97
|
-
const Template = (args: ColumnSettingsFormProps) => (
|
|
98
|
-
<div className='p-4 max-is-64'>
|
|
99
|
-
<ColumnSettingsForm {...args} />
|
|
100
|
-
</div>
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
export const Interactive = Template.bind({});
|
|
104
|
-
(Interactive as any).args = defaultArgs;
|
|
@@ -5,28 +5,33 @@
|
|
|
5
5
|
import React, { useRef, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { Button, Input, Select, useTranslation } from '@dxos/react-ui';
|
|
8
|
+
import { FieldValueTypes } from '@dxos/schema';
|
|
8
9
|
import { safeParseInt } from '@dxos/util';
|
|
9
10
|
|
|
10
|
-
import { type TableDef, type
|
|
11
|
+
import { type TableDef, type ColumnDef } from '../../schema';
|
|
11
12
|
import { translationKey } from '../../translations';
|
|
12
13
|
|
|
13
|
-
export type
|
|
14
|
-
column:
|
|
14
|
+
export type ColumnSettingsProps = {
|
|
15
|
+
column: ColumnDef;
|
|
15
16
|
tableDef: TableDef;
|
|
17
|
+
// TODO(burdon): Rename.
|
|
16
18
|
tablesToReference: TableDef[];
|
|
17
|
-
onUpdate?: (
|
|
18
|
-
onDelete?: (
|
|
19
|
+
onUpdate?: (id: string, column: ColumnDef) => void;
|
|
20
|
+
onDelete?: (id: string) => void;
|
|
19
21
|
onClose?: () => void;
|
|
20
22
|
};
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
/**
|
|
25
|
+
* @deprecated
|
|
26
|
+
*/
|
|
27
|
+
export const ColumnSettings = ({
|
|
23
28
|
column,
|
|
24
29
|
tableDef,
|
|
25
30
|
tablesToReference,
|
|
26
31
|
onUpdate,
|
|
27
32
|
onDelete,
|
|
28
33
|
onClose,
|
|
29
|
-
}:
|
|
34
|
+
}: ColumnSettingsProps) => {
|
|
30
35
|
const [formState, setFormState] = useState({
|
|
31
36
|
prop: column.id,
|
|
32
37
|
refTable: column.refTable,
|
|
@@ -63,7 +68,7 @@ export const ColumnSettingsForm = ({
|
|
|
63
68
|
id: prop, // TODO(burdon): Make unique.
|
|
64
69
|
prop,
|
|
65
70
|
label,
|
|
66
|
-
type: type as
|
|
71
|
+
type: type as ColumnDef['type'],
|
|
67
72
|
refTable,
|
|
68
73
|
refProp,
|
|
69
74
|
digits: safeParseInt(digits),
|
|
@@ -76,9 +81,10 @@ export const ColumnSettingsForm = ({
|
|
|
76
81
|
onClose?.();
|
|
77
82
|
};
|
|
78
83
|
|
|
84
|
+
// TODO(burdon): Standardize dialog/popup.
|
|
79
85
|
return (
|
|
80
|
-
<div className='
|
|
81
|
-
<div className='
|
|
86
|
+
<div className='flex flex-col w-full gap-4'>
|
|
87
|
+
<div className='flex flex-col gap-2'>
|
|
82
88
|
<Input.Root>
|
|
83
89
|
<Input.Label>{t('column label label')}</Input.Label>
|
|
84
90
|
<Input.TextInput
|
|
@@ -89,8 +95,7 @@ export const ColumnSettingsForm = ({
|
|
|
89
95
|
data-testid='table.column-settings.label'
|
|
90
96
|
/>
|
|
91
97
|
</Input.Root>
|
|
92
|
-
|
|
93
|
-
<div className='space-y-1'>
|
|
98
|
+
|
|
94
99
|
<Input.Root>
|
|
95
100
|
<Input.Label>{t('property key label')}</Input.Label>
|
|
96
101
|
<Input.TextInput
|
|
@@ -102,8 +107,7 @@ export const ColumnSettingsForm = ({
|
|
|
102
107
|
}
|
|
103
108
|
/>
|
|
104
109
|
</Input.Root>
|
|
105
|
-
|
|
106
|
-
<div className='space-y-1'>
|
|
110
|
+
|
|
107
111
|
<Input.Root>
|
|
108
112
|
<Input.Label>{t('column type label')}</Input.Label>
|
|
109
113
|
<Select.Root
|
|
@@ -114,7 +118,7 @@ export const ColumnSettingsForm = ({
|
|
|
114
118
|
<Select.Portal>
|
|
115
119
|
<Select.Content>
|
|
116
120
|
<Select.Viewport>
|
|
117
|
-
{
|
|
121
|
+
{FieldValueTypes.map((type) => (
|
|
118
122
|
<Select.Option key={type} value={type}>
|
|
119
123
|
{t(`${type} column type label`)}
|
|
120
124
|
</Select.Option>
|
|
@@ -124,9 +128,8 @@ export const ColumnSettingsForm = ({
|
|
|
124
128
|
</Select.Portal>
|
|
125
129
|
</Select.Root>
|
|
126
130
|
</Input.Root>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
<div className='space-y-1'>
|
|
131
|
+
|
|
132
|
+
{formState.type === 'number' && (
|
|
130
133
|
<Input.Root>
|
|
131
134
|
<Input.Label>{t('digits label')}</Input.Label>
|
|
132
135
|
<Input.TextInput
|
|
@@ -134,12 +137,10 @@ export const ColumnSettingsForm = ({
|
|
|
134
137
|
onChange={(event) => setFormState((prevState) => ({ ...prevState, digits: event.target.value }))}
|
|
135
138
|
/>
|
|
136
139
|
</Input.Root>
|
|
137
|
-
|
|
138
|
-
)}
|
|
140
|
+
)}
|
|
139
141
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
<div className='space-y-1'>
|
|
142
|
+
{formState.type === 'ref' && (
|
|
143
|
+
<>
|
|
143
144
|
<Input.Root>
|
|
144
145
|
<Input.Label>Table</Input.Label>
|
|
145
146
|
<Select.Root
|
|
@@ -162,9 +163,8 @@ export const ColumnSettingsForm = ({
|
|
|
162
163
|
</Select.Portal>
|
|
163
164
|
</Select.Root>
|
|
164
165
|
</Input.Root>
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
<div className='space-y-1'>
|
|
166
|
+
|
|
167
|
+
{formState.refTable && (
|
|
168
168
|
<Input.Root>
|
|
169
169
|
<Input.Label>Table property</Input.Label>
|
|
170
170
|
<Select.Root
|
|
@@ -187,20 +187,21 @@ export const ColumnSettingsForm = ({
|
|
|
187
187
|
</Select.Portal>
|
|
188
188
|
</Select.Root>
|
|
189
189
|
</Input.Root>
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
<div
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
190
|
+
)}
|
|
191
|
+
</>
|
|
192
|
+
)}
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<div>
|
|
196
|
+
{/* TODO(burdon): Change delete to cancel. Delete should be menu item. */}
|
|
197
|
+
<div className='flex flex-row justify-end gap-1'>
|
|
198
|
+
<Button onClick={handleDelete} data-testid='table.column-settings.delete'>
|
|
199
|
+
{t('delete label')}
|
|
200
|
+
</Button>
|
|
201
|
+
<Button variant='primary' onClick={handleSave} data-testid='table.column-settings.save'>
|
|
202
|
+
{t('save label')}
|
|
203
|
+
</Button>
|
|
204
|
+
</div>
|
|
204
205
|
</div>
|
|
205
206
|
</div>
|
|
206
207
|
);
|
|
@@ -16,13 +16,13 @@ import {
|
|
|
16
16
|
} from '@tanstack/react-table';
|
|
17
17
|
import React, {
|
|
18
18
|
type ComponentPropsWithoutRef,
|
|
19
|
+
type ReactNode,
|
|
19
20
|
Fragment,
|
|
21
|
+
memo,
|
|
20
22
|
useCallback,
|
|
21
23
|
useEffect,
|
|
22
24
|
useState,
|
|
23
25
|
useContext,
|
|
24
|
-
type ReactNode,
|
|
25
|
-
memo,
|
|
26
26
|
} from 'react';
|
|
27
27
|
|
|
28
28
|
import { DensityProvider, type ThemedClassName, useDefaultValue } from '@dxos/react-ui';
|
|
@@ -55,7 +55,6 @@ const TableViewport = ({ children, classNames, asChild, ...props }: TableViewpor
|
|
|
55
55
|
const { scrollContextRef } = useContext(TableRootContext);
|
|
56
56
|
|
|
57
57
|
const classes = mx(classNames, 'overflow-auto');
|
|
58
|
-
|
|
59
58
|
return asChild ? (
|
|
60
59
|
<Slot ref={scrollContextRef} className={classes} {...props}>
|
|
61
60
|
{children}
|
|
@@ -70,13 +69,13 @@ const TableViewport = ({ children, classNames, asChild, ...props }: TableViewpor
|
|
|
70
69
|
export const TablePrimitive = <TData extends RowData>(props: TableProps<TData>) => {
|
|
71
70
|
const {
|
|
72
71
|
role,
|
|
73
|
-
onColumnResize,
|
|
74
|
-
columnVisibility,
|
|
75
72
|
header = true,
|
|
76
73
|
rowsSelectable,
|
|
77
74
|
debug,
|
|
78
|
-
onDataSelectionChange,
|
|
79
75
|
pinLastRow,
|
|
76
|
+
columnVisibility,
|
|
77
|
+
onColumnResize,
|
|
78
|
+
onDataSelectionChange,
|
|
80
79
|
} = props;
|
|
81
80
|
|
|
82
81
|
const columns = useDefaultValue(props.columns, () => []);
|
|
@@ -3,26 +3,32 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type RowData } from '@tanstack/react-table';
|
|
6
|
-
import React, {
|
|
6
|
+
import React, {
|
|
7
|
+
useContext,
|
|
8
|
+
createContext,
|
|
9
|
+
type Context,
|
|
10
|
+
type JSX,
|
|
11
|
+
type PropsWithChildren,
|
|
12
|
+
type ReactNode,
|
|
13
|
+
} from 'react';
|
|
14
|
+
|
|
15
|
+
import { raise } from '@dxos/debug';
|
|
7
16
|
|
|
8
17
|
import { type TableContextValue } from './props';
|
|
9
18
|
|
|
10
19
|
export const TABLE_NAME = 'Table';
|
|
11
20
|
|
|
12
|
-
|
|
13
|
-
// The expectation is that the provider will always supply a value, so no need to define a default here.
|
|
14
|
-
const TableContext = createContext<TableContextValue<RowData>>({} as TableContextValue<RowData>);
|
|
21
|
+
const TableContext = createContext<TableContextValue<RowData> | undefined>(undefined);
|
|
15
22
|
|
|
16
23
|
export type TypedTableProvider<TData extends RowData> = {
|
|
17
24
|
(props: TableContextValue<TData> & { children: ReactNode }): JSX.Element;
|
|
18
25
|
displayName: string;
|
|
19
26
|
};
|
|
20
27
|
|
|
21
|
-
export const TableProvider
|
|
28
|
+
export const TableProvider = ({ children, ...value }: PropsWithChildren<TableContextValue<RowData>>) => {
|
|
22
29
|
return <TableContext.Provider value={value}>{children}</TableContext.Provider>;
|
|
23
30
|
};
|
|
24
31
|
|
|
25
|
-
// Create a custom hook to consume the context.
|
|
26
32
|
export const useTableContext = <TData extends RowData>(): TableContextValue<TData> => {
|
|
27
|
-
return useContext(TableContext as Context<TableContextValue<TData>>);
|
|
33
|
+
return useContext(TableContext as Context<TableContextValue<TData>>) ?? raise(new Error('Missing TableContext'));
|
|
28
34
|
};
|
|
@@ -25,7 +25,7 @@ export type TableFlags = Partial<{
|
|
|
25
25
|
* This is ‘current’ in the `aria-current` sense.
|
|
26
26
|
*/
|
|
27
27
|
export type TableCurrent<TData extends RowData> = Partial<{
|
|
28
|
-
// App state
|
|
28
|
+
// App state.
|
|
29
29
|
currentDatum: TData;
|
|
30
30
|
onDatumClick: (datum: TData) => void;
|
|
31
31
|
}>;
|
|
@@ -39,13 +39,13 @@ export type TableProps<TData extends RowData> = TableFlags &
|
|
|
39
39
|
onColumnResize: (state: Record<string, number>) => void;
|
|
40
40
|
onColumnReorder: (columnId: string, direction: 'left' | 'right') => void;
|
|
41
41
|
columnVisibility: VisibilityState;
|
|
42
|
-
// Controllable row selection
|
|
42
|
+
// Controllable row selection.
|
|
43
43
|
rowSelection: RowSelectionState;
|
|
44
44
|
defaultRowSelection: RowSelectionState;
|
|
45
45
|
onRowSelectionChange: (rowSelection: RowSelectionState) => void;
|
|
46
|
-
// Derived from row selection
|
|
46
|
+
// Derived from row selection.
|
|
47
47
|
onDataSelectionChange: (dataSelection: TData[]) => void;
|
|
48
|
-
// `table` element props
|
|
48
|
+
// `table` element props.
|
|
49
49
|
classNames: ClassNameValue;
|
|
50
50
|
pinLastRow: boolean;
|
|
51
51
|
}>;
|
package/src/helpers.tsx
CHANGED
|
@@ -21,8 +21,7 @@ import { log } from '@dxos/log';
|
|
|
21
21
|
import { type ClassNameValue, Input, Tooltip } from '@dxos/react-ui';
|
|
22
22
|
import { getSize, mx } from '@dxos/react-ui-theme';
|
|
23
23
|
|
|
24
|
-
import { CellCombobox } from './components';
|
|
25
|
-
import { useTableContext } from './components/Table/TableContext';
|
|
24
|
+
import { CellCombobox, useTableContext } from './components';
|
|
26
25
|
import { textPadding } from './theme';
|
|
27
26
|
|
|
28
27
|
export type ValueUpdater<TData extends RowData, TValue> = (row: TData, id: string, value: TValue) => void;
|
|
@@ -470,7 +469,7 @@ export class ColumnBuilder<TData extends RowData> {
|
|
|
470
469
|
size: 50,
|
|
471
470
|
minSize: 50,
|
|
472
471
|
header: (column) => label ?? column.header.id,
|
|
473
|
-
// TODO(zan): Implement sort algorithm
|
|
472
|
+
// TODO(zan): Implement sort algorithm.
|
|
474
473
|
enableSorting: true,
|
|
475
474
|
cell: SwitchBuilderCell,
|
|
476
475
|
...props,
|
|
@@ -486,7 +485,7 @@ export class ColumnBuilder<TData extends RowData> {
|
|
|
486
485
|
const IconOff = off?.Icon ?? X;
|
|
487
486
|
return {
|
|
488
487
|
size: size ?? 32,
|
|
489
|
-
// TODO(zan): Implement sort algorithm
|
|
488
|
+
// TODO(zan): Implement sort algorithm.
|
|
490
489
|
enableSorting: false,
|
|
491
490
|
header: (column) => <div className={'justify-center'}>{label ?? column.header.id}</div>,
|
|
492
491
|
cell: (cell) => {
|
|
@@ -506,14 +505,13 @@ export class ColumnBuilder<TData extends RowData> {
|
|
|
506
505
|
/**
|
|
507
506
|
* This display column type is for nested/unhandled data to appear as JSON.
|
|
508
507
|
*/
|
|
509
|
-
|
|
508
|
+
json({ label, classNames, ...props }: KeyColumnOptions<TData> = {}): Partial<ColumnDef<TData, PublicKey>> {
|
|
510
509
|
return {
|
|
511
510
|
size: 120,
|
|
512
511
|
minSize: 120,
|
|
513
512
|
header: (cell) => label ?? cell.header.id,
|
|
514
513
|
cell: (cell) => {
|
|
515
514
|
const value = cell.getValue();
|
|
516
|
-
|
|
517
515
|
return (
|
|
518
516
|
<div className='overflow-scroll'>
|
|
519
517
|
<code className='text-xs'>{JSON.stringify(value)}</code>
|
|
@@ -9,23 +9,14 @@ import * as fc from 'fast-check';
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
|
|
11
11
|
import { S } from '@dxos/echo-schema';
|
|
12
|
-
import {
|
|
13
|
-
import { withTheme } from '@dxos/storybook-utils';
|
|
12
|
+
import { withTheme, withLayout } from '@dxos/storybook-utils';
|
|
14
13
|
|
|
15
|
-
import { schemaToColumnDefs } from './
|
|
14
|
+
import { schemaToColumnDefs } from './column-utils';
|
|
16
15
|
import { Table } from '../components';
|
|
17
16
|
|
|
18
17
|
export default {
|
|
19
|
-
title: 'react-ui-table/
|
|
20
|
-
|
|
21
|
-
decorators: [
|
|
22
|
-
withTheme,
|
|
23
|
-
(Story: any) => (
|
|
24
|
-
<DensityProvider density='fine'>
|
|
25
|
-
<Story />
|
|
26
|
-
</DensityProvider>
|
|
27
|
-
),
|
|
28
|
-
],
|
|
18
|
+
title: 'react-ui-table/Schema',
|
|
19
|
+
decorators: [withTheme, withLayout()],
|
|
29
20
|
};
|
|
30
21
|
|
|
31
22
|
const exampleSchema = S.Struct({
|
|
@@ -49,7 +40,7 @@ const exampleSchemaArbitrary = Arbitrary.make(exampleSchema);
|
|
|
49
40
|
|
|
50
41
|
const items = fc.sample(exampleSchemaArbitrary, 10);
|
|
51
42
|
|
|
52
|
-
export const
|
|
43
|
+
export const Default = {
|
|
53
44
|
render: () => {
|
|
54
45
|
return (
|
|
55
46
|
<Table.Root>
|
|
@@ -5,37 +5,37 @@
|
|
|
5
5
|
import { type ColumnDef } from '@tanstack/react-table';
|
|
6
6
|
|
|
7
7
|
import { type S } from '@dxos/echo-schema';
|
|
8
|
+
import { FieldValueType, mapSchemaToFields } from '@dxos/schema';
|
|
8
9
|
|
|
9
|
-
import { classifySchemaProperties } from './schema';
|
|
10
10
|
import { createColumnBuilder } from '../helpers';
|
|
11
11
|
|
|
12
12
|
export const schemaToColumnDefs = <T>(schema: S.Schema<T, any>): ColumnDef<T, any>[] => {
|
|
13
13
|
const { helper, builder } = createColumnBuilder<T>();
|
|
14
14
|
|
|
15
|
-
const classified =
|
|
15
|
+
const classified = mapSchemaToFields(schema);
|
|
16
16
|
return classified.map(([name, type]) => {
|
|
17
17
|
const propertyKey = name.toString();
|
|
18
18
|
|
|
19
19
|
let column: Partial<ColumnDef<any, any>> | undefined;
|
|
20
20
|
switch (type) {
|
|
21
|
-
case
|
|
21
|
+
case FieldValueType.String: {
|
|
22
22
|
column = builder.string({ label: propertyKey });
|
|
23
23
|
break;
|
|
24
24
|
}
|
|
25
|
-
case
|
|
25
|
+
case FieldValueType.Number: {
|
|
26
26
|
column = builder.number({ label: propertyKey });
|
|
27
27
|
break;
|
|
28
28
|
}
|
|
29
|
-
case
|
|
29
|
+
case FieldValueType.Boolean: {
|
|
30
30
|
column = builder.switch({ label: propertyKey });
|
|
31
31
|
break;
|
|
32
32
|
}
|
|
33
|
-
case
|
|
33
|
+
case FieldValueType.Date: {
|
|
34
34
|
column = builder.date({ label: propertyKey });
|
|
35
35
|
break;
|
|
36
36
|
}
|
|
37
|
-
case
|
|
38
|
-
column = builder.
|
|
37
|
+
case FieldValueType.JSON: {
|
|
38
|
+
column = builder.json({ label: propertyKey, id: propertyKey });
|
|
39
39
|
break;
|
|
40
40
|
}
|
|
41
41
|
default: {
|
package/src/schema/index.ts
CHANGED
package/src/schema/types.ts
CHANGED
|
@@ -2,18 +2,20 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type FieldValueType } from '@dxos/schema';
|
|
6
|
+
|
|
7
|
+
// TODO(burdon): Reconcile with @dxos/schema/View.
|
|
5
8
|
export type TableDef = {
|
|
6
9
|
id: string;
|
|
7
|
-
name?: string;
|
|
8
|
-
columns:
|
|
10
|
+
name?: string;
|
|
11
|
+
columns: ColumnDef[];
|
|
9
12
|
};
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export type ColumnProps = {
|
|
14
|
+
// TODO(burdon): Reconcile with @dxos/schema/Field.
|
|
15
|
+
export type ColumnDef = {
|
|
14
16
|
id: string;
|
|
15
17
|
prop: string;
|
|
16
|
-
type:
|
|
18
|
+
type: FieldValueType;
|
|
17
19
|
size?: number;
|
|
18
20
|
label?: string;
|
|
19
21
|
|
package/src/translations.ts
CHANGED
|
@@ -10,7 +10,7 @@ export default [
|
|
|
10
10
|
[translationKey]: {
|
|
11
11
|
'no selection label': ' ',
|
|
12
12
|
'number column type label': 'Number',
|
|
13
|
-
'boolean column type label': '
|
|
13
|
+
'boolean column type label': 'Boolean',
|
|
14
14
|
'date column type label': 'Date',
|
|
15
15
|
'string column type label': 'Text',
|
|
16
16
|
'ref column type label': 'Reference',
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { type TableDef, type ColumnProps } from '../../schema';
|
|
3
|
-
export type ColumnSettingsFormProps = {
|
|
4
|
-
column: ColumnProps;
|
|
5
|
-
tableDef: TableDef;
|
|
6
|
-
tablesToReference: TableDef[];
|
|
7
|
-
onUpdate?: ((id: string, column: ColumnProps) => void) | undefined;
|
|
8
|
-
onDelete?: ((id: string) => void) | undefined;
|
|
9
|
-
onClose?: () => void;
|
|
10
|
-
};
|
|
11
|
-
export declare const ColumnSettingsForm: ({ column, tableDef, tablesToReference, onUpdate, onDelete, onClose, }: ColumnSettingsFormProps) => React.JSX.Element;
|
|
12
|
-
//# sourceMappingURL=ColumnSettingsForm.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ColumnSettingsForm.d.ts","sourceRoot":"","sources":["../../../../../src/components/ColumnMenu/ColumnSettingsForm.tsx"],"names":[],"mappings":"AAIA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAKhD,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAmB,MAAM,cAAc,CAAC;AAGhF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACnE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,kBAAkB,0EAO5B,uBAAuB,sBAkLzB,CAAC"}
|