@dxos/react-ui-table 0.8.1-staging.5be625a → 0.8.1-staging.97aedb1
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/{chunk-5MKYB7NF.mjs → chunk-YWNRUF4J.mjs} +7 -3
- package/dist/lib/browser/{chunk-5MKYB7NF.mjs.map → chunk-YWNRUF4J.mjs.map} +3 -3
- package/dist/lib/browser/index.mjs +295 -97
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node/{chunk-NRFKBRPV.cjs → chunk-TGG6OZ54.cjs} +10 -6
- package/dist/lib/node/{chunk-NRFKBRPV.cjs.map → chunk-TGG6OZ54.cjs.map} +3 -3
- package/dist/lib/node/index.cjs +293 -93
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types/index.cjs +3 -3
- package/dist/lib/node/types/index.cjs.map +1 -1
- package/dist/lib/node-esm/{chunk-SU4D55KI.mjs → chunk-KKLP54L3.mjs} +7 -3
- package/dist/lib/node-esm/{chunk-SU4D55KI.mjs.map → chunk-KKLP54L3.mjs.map} +3 -3
- package/dist/lib/node-esm/index.mjs +295 -97
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +15 -10
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +10 -0
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -0
- package/dist/types/src/components/Table/Table.d.ts +1 -1
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +2 -3
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/relations.stories.d.ts +9 -0
- package/dist/types/src/components/Table/relations.stories.d.ts.map +1 -0
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts +6 -10
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/model/index.d.ts +1 -0
- package/dist/types/src/model/index.d.ts.map +1 -1
- package/dist/types/src/model/selection-model.d.ts +6 -3
- package/dist/types/src/model/selection-model.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +13 -14
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +4 -4
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/model/table-sorting.d.ts +2 -2
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/types/table.d.ts +2 -1
- package/dist/types/src/types/table.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +21 -30
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/src/util/table-controls.d.ts +2 -2
- package/dist/types/src/util/table-controls.d.ts.map +1 -1
- package/dist/types/src/util/table.d.ts.map +1 -1
- package/package.json +33 -32
- package/src/components/Table/DynamicTable.stories.tsx +155 -0
- package/src/components/Table/DynamicTable.tsx +46 -28
- package/src/components/Table/Table.stories.tsx +129 -125
- package/src/components/Table/Table.tsx +51 -26
- package/src/components/Table/relations.stories.tsx +113 -0
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +8 -3
- package/src/components/TableCellEditor/TableCellEditor.tsx +102 -4
- package/src/components/testing.ts +0 -1
- package/src/hooks/useTableModel.ts +11 -11
- package/src/model/index.ts +1 -0
- package/src/model/selection-model.ts +12 -2
- package/src/model/table-model.test.ts +1 -1
- package/src/model/table-model.ts +27 -18
- package/src/model/table-presentation.test.ts +1 -1
- package/src/model/table-presentation.ts +65 -11
- package/src/model/table-sorting.ts +2 -2
- package/src/playwright/smoke.spec.ts +2 -3
- package/src/types/table.ts +6 -5
- package/src/util/dynamic-table.ts +57 -25
- package/src/util/table-controls.ts +4 -4
- package/src/util/table.ts +2 -1
- package/dist/lib/browser/deprecated/index.mjs +0 -1483
- package/dist/lib/browser/deprecated/index.mjs.map +0 -7
- package/dist/lib/node/deprecated/index.cjs +0 -1511
- package/dist/lib/node/deprecated/index.cjs.map +0 -7
- package/dist/lib/node-esm/deprecated/index.mjs +0 -1485
- package/dist/lib/node-esm/deprecated/index.mjs.map +0 -7
- package/dist/types/src/deprecated/components/Cell/Cell.d.ts +0 -12
- package/dist/types/src/deprecated/components/Cell/Cell.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Cell/CellCombobox.d.ts +0 -13
- package/dist/types/src/deprecated/components/Cell/CellCombobox.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Cell/index.d.ts +0 -2
- package/dist/types/src/deprecated/components/Cell/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.d.ts +0 -23
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts +0 -36
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.d.ts +0 -15
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts +0 -84
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/ColumnMenu/index.d.ts +0 -3
- package/dist/types/src/deprecated/components/ColumnMenu/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/Table.d.ts +0 -20
- package/dist/types/src/deprecated/components/Table/Table.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/Table.stories.d.ts +0 -116
- package/dist/types/src/deprecated/components/Table/Table.stories.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/TableBody.d.ts +0 -12
- package/dist/types/src/deprecated/components/Table/TableBody.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/TableContext.d.ts +0 -13
- package/dist/types/src/deprecated/components/Table/TableContext.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/TableHead.d.ts +0 -9
- package/dist/types/src/deprecated/components/Table/TableHead.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/TableRootContext.d.ts +0 -17
- package/dist/types/src/deprecated/components/Table/TableRootContext.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/index.d.ts +0 -5
- package/dist/types/src/deprecated/components/Table/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/props.d.ts +0 -42
- package/dist/types/src/deprecated/components/Table/props.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/index.d.ts +0 -4
- package/dist/types/src/deprecated/components/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/helpers.d.ts +0 -91
- package/dist/types/src/deprecated/helpers.d.ts.map +0 -1
- package/dist/types/src/deprecated/hooks/index.d.ts +0 -5
- package/dist/types/src/deprecated/hooks/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/hooks/useColumnSizing.d.ts +0 -12
- package/dist/types/src/deprecated/hooks/useColumnSizing.d.ts.map +0 -1
- package/dist/types/src/deprecated/hooks/useColumnSorting.d.ts +0 -15
- package/dist/types/src/deprecated/hooks/useColumnSorting.d.ts.map +0 -1
- package/dist/types/src/deprecated/hooks/usePinLastRow.d.ts +0 -3
- package/dist/types/src/deprecated/hooks/usePinLastRow.d.ts.map +0 -1
- package/dist/types/src/deprecated/hooks/useRowSelection.d.ts +0 -7
- package/dist/types/src/deprecated/hooks/useRowSelection.d.ts.map +0 -1
- package/dist/types/src/deprecated/index.d.ts +0 -8
- package/dist/types/src/deprecated/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/schema/Schema.stories.d.ts +0 -11
- package/dist/types/src/deprecated/schema/Schema.stories.d.ts.map +0 -1
- package/dist/types/src/deprecated/schema/column-utils.d.ts +0 -7
- package/dist/types/src/deprecated/schema/column-utils.d.ts.map +0 -1
- package/dist/types/src/deprecated/schema/index.d.ts +0 -3
- package/dist/types/src/deprecated/schema/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/schema/types.d.ts +0 -27
- package/dist/types/src/deprecated/schema/types.d.ts.map +0 -1
- package/dist/types/src/deprecated/theme.d.ts +0 -29
- package/dist/types/src/deprecated/theme.d.ts.map +0 -1
- package/dist/types/src/deprecated/translations.d.ts +0 -21
- package/dist/types/src/deprecated/translations.d.ts.map +0 -1
- package/dist/types/src/deprecated/types.d.ts +0 -26
- package/dist/types/src/deprecated/types.d.ts.map +0 -1
- package/src/deprecated/components/Cell/Cell.tsx +0 -88
- package/src/deprecated/components/Cell/CellCombobox.tsx +0 -103
- package/src/deprecated/components/Cell/index.ts +0 -5
- package/src/deprecated/components/ColumnMenu/ColumnMenu.stories.tsx +0 -129
- package/src/deprecated/components/ColumnMenu/ColumnMenu.tsx +0 -182
- package/src/deprecated/components/ColumnMenu/ColumnSettings.stories.tsx +0 -108
- package/src/deprecated/components/ColumnMenu/ColumnSettings.tsx +0 -207
- package/src/deprecated/components/ColumnMenu/index.ts +0 -6
- package/src/deprecated/components/Table/Table.stories.tsx +0 -508
- package/src/deprecated/components/Table/Table.tsx +0 -301
- package/src/deprecated/components/Table/TableBody.tsx +0 -82
- package/src/deprecated/components/Table/TableContext.tsx +0 -34
- package/src/deprecated/components/Table/TableHead.tsx +0 -78
- package/src/deprecated/components/Table/TableRootContext.ts +0 -39
- package/src/deprecated/components/Table/index.ts +0 -8
- package/src/deprecated/components/Table/props.ts +0 -60
- package/src/deprecated/components/index.ts +0 -7
- package/src/deprecated/helpers.tsx +0 -526
- package/src/deprecated/hooks/index.ts +0 -8
- package/src/deprecated/hooks/useColumnSizing.ts +0 -46
- package/src/deprecated/hooks/useColumnSorting.ts +0 -64
- package/src/deprecated/hooks/usePinLastRow.ts +0 -47
- package/src/deprecated/hooks/useRowSelection.ts +0 -40
- package/src/deprecated/index.ts +0 -12
- package/src/deprecated/schema/Schema.stories.tsx +0 -59
- package/src/deprecated/schema/column-utils.ts +0 -54
- package/src/deprecated/schema/index.ts +0 -6
- package/src/deprecated/schema/types.ts +0 -40
- package/src/deprecated/theme.ts +0 -82
- package/src/deprecated/translations.ts +0 -26
- package/src/deprecated/types.ts +0 -38
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2023 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { useFocusableGroup } from '@fluentui/react-tabster';
|
|
6
|
-
import { type Cell as CellType, type RowData } from '@tanstack/react-table';
|
|
7
|
-
import React, { useCallback, type PropsWithChildren, type KeyboardEvent } from 'react';
|
|
8
|
-
|
|
9
|
-
import { tdRoot } from '../../theme';
|
|
10
|
-
import { useTableContext } from '../Table/TableContext';
|
|
11
|
-
|
|
12
|
-
type CellProps<TData extends RowData, TValue> = PropsWithChildren<{
|
|
13
|
-
cell: CellType<TData, TValue>;
|
|
14
|
-
}>;
|
|
15
|
-
|
|
16
|
-
const CELL_NAME = 'Cell';
|
|
17
|
-
|
|
18
|
-
const FocusableCell = <TData extends RowData, TValue>({ cell, children }: CellProps<TData, TValue>) => {
|
|
19
|
-
const tableContext = useTableContext();
|
|
20
|
-
const focusableGroupAttrs = useFocusableGroup({ tabBehavior: 'limited' });
|
|
21
|
-
|
|
22
|
-
const pinned = tableContext.table.getState().rowPinning?.bottom?.includes(cell.row.id);
|
|
23
|
-
const className = tdRoot({ ...tableContext, pinned }, cell.column.columnDef.meta?.cell?.classNames);
|
|
24
|
-
|
|
25
|
-
const handleKeyDown = useCallback(({ key, currentTarget }: KeyboardEvent<HTMLTableCellElement>) => {
|
|
26
|
-
if (key !== 'Enter') {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const currentRow = currentTarget.closest('tr');
|
|
31
|
-
if (!currentRow) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const cellIndex = Array.from(currentRow.cells || []).indexOf(currentTarget);
|
|
36
|
-
|
|
37
|
-
const nextSibling = currentRow.nextElementSibling;
|
|
38
|
-
if (!(nextSibling instanceof HTMLTableRowElement)) {
|
|
39
|
-
let depth = 0;
|
|
40
|
-
// Poll for the new 'add row' row to be added to the DOM.
|
|
41
|
-
const pollForNewRow = () => {
|
|
42
|
-
const newNextSibling = currentRow.nextElementSibling;
|
|
43
|
-
if (newNextSibling instanceof HTMLTableRowElement) {
|
|
44
|
-
const nextCell = newNextSibling.cells[cellIndex];
|
|
45
|
-
// Find the input within next cell and focus it.
|
|
46
|
-
const input = nextCell.querySelector('input');
|
|
47
|
-
if (input) {
|
|
48
|
-
input.focus();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// TODO(Zan): Use the same utility that sheets uses.
|
|
52
|
-
// Scroll current row into view after it's been hidden behind the sticky add-row row.
|
|
53
|
-
currentRow.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
54
|
-
} else if (depth++ < 100) {
|
|
55
|
-
requestAnimationFrame(pollForNewRow);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
requestAnimationFrame(pollForNewRow);
|
|
59
|
-
}
|
|
60
|
-
}, []);
|
|
61
|
-
|
|
62
|
-
return (
|
|
63
|
-
<td data-testid='table.cell' tabIndex={0} {...focusableGroupAttrs} className={className} onKeyDown={handleKeyDown}>
|
|
64
|
-
{children}
|
|
65
|
-
</td>
|
|
66
|
-
);
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const StaticCell = <TData extends RowData, TValue>({ cell, children }: CellProps<TData, TValue>) => {
|
|
70
|
-
const tableContext = useTableContext();
|
|
71
|
-
return (
|
|
72
|
-
<td data-testid='table.cell' className={tdRoot(tableContext, cell.column.columnDef.meta?.cell?.classNames)}>
|
|
73
|
-
{children}
|
|
74
|
-
</td>
|
|
75
|
-
);
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const Cell = <TData extends RowData, TValue>({ cell, children }: CellProps<TData, TValue>) => {
|
|
79
|
-
const { isGrid } = useTableContext();
|
|
80
|
-
const Root = isGrid ? FocusableCell : StaticCell;
|
|
81
|
-
return <Root cell={cell}>{children}</Root>;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
Cell.displayName = CELL_NAME;
|
|
85
|
-
|
|
86
|
-
export { Cell };
|
|
87
|
-
|
|
88
|
-
export type { CellProps };
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2023 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { CaretDown } from '@phosphor-icons/react';
|
|
6
|
-
import { type RowData } from '@tanstack/react-table';
|
|
7
|
-
import React, { useCallback, useState } from 'react';
|
|
8
|
-
|
|
9
|
-
import { Popover, useTranslation } from '@dxos/react-ui';
|
|
10
|
-
import { PopoverCombobox } from '@dxos/react-ui-searchlist';
|
|
11
|
-
import { descriptionText, getSize, mx, staticPlaceholderText } from '@dxos/react-ui-theme';
|
|
12
|
-
|
|
13
|
-
import { type SearchListQueryModel } from '../../helpers';
|
|
14
|
-
import { translationKey } from '../../translations';
|
|
15
|
-
|
|
16
|
-
export type ComboboxCellItems<TData extends RowData> = Record<string, { label: string; data: TData }>;
|
|
17
|
-
|
|
18
|
-
const initialItems = <TData extends RowData>(model: SearchListQueryModel<TData>, value?: TData) =>
|
|
19
|
-
value
|
|
20
|
-
? {
|
|
21
|
-
[model.getId(value)]: { label: model.getText(value), data: value },
|
|
22
|
-
}
|
|
23
|
-
: {};
|
|
24
|
-
|
|
25
|
-
export const CellCombobox = <TData extends RowData>({
|
|
26
|
-
model,
|
|
27
|
-
value,
|
|
28
|
-
onValueChange,
|
|
29
|
-
}: {
|
|
30
|
-
model: SearchListQueryModel<TData>;
|
|
31
|
-
value: TData;
|
|
32
|
-
onValueChange: (value: TData) => void;
|
|
33
|
-
}) => {
|
|
34
|
-
const { t } = useTranslation(translationKey);
|
|
35
|
-
const [items, setItems] = useState<ComboboxCellItems<TData>>(initialItems(model, value));
|
|
36
|
-
const [loading, setLoading] = useState(false);
|
|
37
|
-
const [searchInputValue, setSearchInputValue] = useState('');
|
|
38
|
-
const handleSearchInputValueChange = async (text?: string) => {
|
|
39
|
-
setSearchInputValue(text ?? '');
|
|
40
|
-
setLoading(true);
|
|
41
|
-
const items = await model.query(text);
|
|
42
|
-
setItems(
|
|
43
|
-
items.reduce(
|
|
44
|
-
(acc: ComboboxCellItems<TData>, item) => {
|
|
45
|
-
acc[model.getId(item)] = {
|
|
46
|
-
label: model.getText(item),
|
|
47
|
-
data: item,
|
|
48
|
-
};
|
|
49
|
-
return acc;
|
|
50
|
-
},
|
|
51
|
-
initialItems(model, value),
|
|
52
|
-
),
|
|
53
|
-
);
|
|
54
|
-
setLoading(false);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const handleValueChange = useCallback(
|
|
58
|
-
(id: string) => {
|
|
59
|
-
onValueChange(items[id]?.data);
|
|
60
|
-
},
|
|
61
|
-
[items, onValueChange],
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<PopoverCombobox.Root placeholder={t('no selection label')}>
|
|
66
|
-
<PopoverCombobox.Trigger variant='ghost' classNames='is-full rounded-none ring-inset'>
|
|
67
|
-
{value ? (
|
|
68
|
-
<>
|
|
69
|
-
<span
|
|
70
|
-
className={mx(
|
|
71
|
-
'font-normal text-start text-baseText flex-1 min-is-0 truncate mie-2',
|
|
72
|
-
!value && staticPlaceholderText,
|
|
73
|
-
)}
|
|
74
|
-
>
|
|
75
|
-
{model.getText(value)}
|
|
76
|
-
</span>
|
|
77
|
-
<CaretDown weight='bold' className={getSize(3)} />
|
|
78
|
-
</>
|
|
79
|
-
) : null}
|
|
80
|
-
</PopoverCombobox.Trigger>
|
|
81
|
-
<PopoverCombobox.Content shouldFilter={false} classNames='is-[--radix-popover-trigger-width]'>
|
|
82
|
-
<PopoverCombobox.Input value={searchInputValue} onValueChange={handleSearchInputValueChange} />
|
|
83
|
-
<PopoverCombobox.List>
|
|
84
|
-
{searchInputValue.length < 1 ? (
|
|
85
|
-
<p className={mx('text-center', descriptionText)}>Start typing to search</p>
|
|
86
|
-
) : loading ? (
|
|
87
|
-
<p className={mx('text-center', descriptionText)}>Searching…</p>
|
|
88
|
-
) : (
|
|
89
|
-
<>
|
|
90
|
-
<PopoverCombobox.Empty classNames={['text-center', descriptionText]}>No results</PopoverCombobox.Empty>
|
|
91
|
-
{Object.entries(items).map(([id, { label }]) => (
|
|
92
|
-
<PopoverCombobox.Item key={id} value={id} onSelect={handleValueChange} classNames='truncate'>
|
|
93
|
-
{label}
|
|
94
|
-
</PopoverCombobox.Item>
|
|
95
|
-
))}
|
|
96
|
-
</>
|
|
97
|
-
)}
|
|
98
|
-
</PopoverCombobox.List>
|
|
99
|
-
<Popover.Arrow />
|
|
100
|
-
</PopoverCombobox.Content>
|
|
101
|
-
</PopoverCombobox.Root>
|
|
102
|
-
);
|
|
103
|
-
};
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2023 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
|
-
import { type SortDirection } from '@tanstack/react-table';
|
|
8
|
-
import React, { useState } from 'react';
|
|
9
|
-
|
|
10
|
-
import { TypeEnum } from '@dxos/echo-schema';
|
|
11
|
-
import { withTheme } from '@dxos/storybook-utils';
|
|
12
|
-
|
|
13
|
-
import { ColumnMenu } from './ColumnMenu';
|
|
14
|
-
import { type ColumnSettingsProps } from './ColumnSettings';
|
|
15
|
-
import { type ColumnDef } from '../../schema';
|
|
16
|
-
|
|
17
|
-
export default {
|
|
18
|
-
title: 'ui/react-ui-table/deprecated/ColumnMenu',
|
|
19
|
-
component: ColumnMenu,
|
|
20
|
-
decorators: [withTheme],
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const defs: Pick<ColumnSettingsProps, 'tableDef' | 'tablesToReference'> = {
|
|
24
|
-
tableDef: {
|
|
25
|
-
id: '1',
|
|
26
|
-
name: 'table 1',
|
|
27
|
-
columns: [{ id: 'col-1', prop: 'one', type: TypeEnum.String }],
|
|
28
|
-
},
|
|
29
|
-
tablesToReference: [
|
|
30
|
-
{
|
|
31
|
-
id: '1',
|
|
32
|
-
name: 'table 1',
|
|
33
|
-
columns: [{ id: 'col-1', prop: 'one', type: TypeEnum.String }],
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
id: '2',
|
|
37
|
-
name: 'table 2',
|
|
38
|
-
columns: [{ id: 'col-1', prop: 'two', type: TypeEnum.String }],
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const functions: Pick<ColumnSettingsProps, 'onUpdate' | 'onDelete'> = {
|
|
44
|
-
onUpdate: (...args: any) => console.log('onUpdate args', args),
|
|
45
|
-
onDelete: (...args: any) => console.log('onDelete args', args),
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export const Default = {
|
|
49
|
-
args: {
|
|
50
|
-
column: {
|
|
51
|
-
id: 'test',
|
|
52
|
-
label: 'test',
|
|
53
|
-
} as ColumnDef,
|
|
54
|
-
|
|
55
|
-
...defs,
|
|
56
|
-
...functions,
|
|
57
|
-
|
|
58
|
-
context: {
|
|
59
|
-
header: {
|
|
60
|
-
column: {
|
|
61
|
-
getCanSort: () => true,
|
|
62
|
-
toggleSorting: (desc?: boolean) => {
|
|
63
|
-
console.log('toggleSorting', { desc });
|
|
64
|
-
},
|
|
65
|
-
getToggleSortingHandler: () => () => {
|
|
66
|
-
console.log('Sorting handler invoked');
|
|
67
|
-
},
|
|
68
|
-
getIsSorted: () => false,
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
decorators: [
|
|
74
|
-
withTheme,
|
|
75
|
-
(Story: any) => (
|
|
76
|
-
<div className='flex flex-col items-center h-screen w-full overflow-hidden'>
|
|
77
|
-
<Story />
|
|
78
|
-
</div>
|
|
79
|
-
),
|
|
80
|
-
],
|
|
81
|
-
parameters: {
|
|
82
|
-
layout: 'fullscreen',
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export const ReactiveSort = {
|
|
87
|
-
render: () => {
|
|
88
|
-
const [sort, setSort] = useState<SortDirection | false>(false);
|
|
89
|
-
const props = {
|
|
90
|
-
column: {
|
|
91
|
-
id: 'test',
|
|
92
|
-
label: 'test',
|
|
93
|
-
} as ColumnDef,
|
|
94
|
-
context: {
|
|
95
|
-
header: {
|
|
96
|
-
column: {
|
|
97
|
-
getCanSort: () => true,
|
|
98
|
-
getIsSorted: () => sort,
|
|
99
|
-
clearSorting: () => setSort(false),
|
|
100
|
-
toggleSorting: (desc?: boolean) => {
|
|
101
|
-
if (desc === undefined) {
|
|
102
|
-
setSort(false);
|
|
103
|
-
} else if (desc) {
|
|
104
|
-
setSort('desc');
|
|
105
|
-
} else {
|
|
106
|
-
setSort('asc');
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
getToggleSortingHandler: () => () => {
|
|
110
|
-
if (sort === 'asc') {
|
|
111
|
-
setSort('desc');
|
|
112
|
-
} else {
|
|
113
|
-
setSort(false);
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
} as any;
|
|
120
|
-
|
|
121
|
-
return (
|
|
122
|
-
<div className='flex justify-around w-full overflow-hidden'>
|
|
123
|
-
<div className='grid w-48'>
|
|
124
|
-
<ColumnMenu {...props} />
|
|
125
|
-
</div>
|
|
126
|
-
</div>
|
|
127
|
-
);
|
|
128
|
-
},
|
|
129
|
-
};
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { X, GearSix, CaretDown, ArrowDown, ArrowUp, ArrowRight, ArrowLeft } from '@phosphor-icons/react';
|
|
6
|
-
import { type SortDirection, type HeaderContext, type RowData } from '@tanstack/react-table';
|
|
7
|
-
import React, { useRef, useState, useCallback } from 'react';
|
|
8
|
-
|
|
9
|
-
import { Button, Popover, DropdownMenu } from '@dxos/react-ui';
|
|
10
|
-
import { getSize, mx } from '@dxos/react-ui-theme';
|
|
11
|
-
|
|
12
|
-
import { ColumnSettings } from './ColumnSettings';
|
|
13
|
-
import { useSortColumn } from '../../hooks';
|
|
14
|
-
import { type TableDef, type ColumnDef } from '../../schema';
|
|
15
|
-
|
|
16
|
-
export type ColumnMenuProps<TData extends RowData, TValue> = {
|
|
17
|
-
context: HeaderContext<TData, TValue>;
|
|
18
|
-
tablesToReference: TableDef[];
|
|
19
|
-
tableDef: TableDef;
|
|
20
|
-
column: ColumnDef;
|
|
21
|
-
columnOrderable: boolean;
|
|
22
|
-
columnPosition: 'start' | 'end' | undefined;
|
|
23
|
-
onColumnReorder: (columnId: string, direction: 'left' | 'right') => void;
|
|
24
|
-
onUpdate?: (id: string, column: ColumnDef) => void;
|
|
25
|
-
onDelete?: (id: string) => void;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* @deprecated
|
|
30
|
-
*/
|
|
31
|
-
export const ColumnMenu = <TData extends RowData, TValue>({
|
|
32
|
-
column,
|
|
33
|
-
columnOrderable,
|
|
34
|
-
columnPosition,
|
|
35
|
-
onColumnReorder,
|
|
36
|
-
...props
|
|
37
|
-
}: ColumnMenuProps<TData, TValue>) => {
|
|
38
|
-
const title = column.label?.length ? column.label : column.id;
|
|
39
|
-
const header = props.context.header;
|
|
40
|
-
|
|
41
|
-
const { canSort, sortDirection, onSelectSort, onToggleSort, onClearSort } = useSortColumn(header.column);
|
|
42
|
-
|
|
43
|
-
const columnSettingsAnchorRef = useRef<any>(null);
|
|
44
|
-
|
|
45
|
-
const [isColumnSettingsOpen, setIsColumnSettingsOpen] = useState(false);
|
|
46
|
-
|
|
47
|
-
const shouldPreventFocusOnClose = useRef(false);
|
|
48
|
-
|
|
49
|
-
const onOpenColumnSettings = useCallback(() => {
|
|
50
|
-
shouldPreventFocusOnClose.current = true;
|
|
51
|
-
setIsColumnSettingsOpen(true);
|
|
52
|
-
}, [shouldPreventFocusOnClose, setIsColumnSettingsOpen]); // setIsColumnSettingsOpen is a dependency
|
|
53
|
-
|
|
54
|
-
const onDropdownCloseAutoFocus = useCallback(
|
|
55
|
-
(event: Event) => {
|
|
56
|
-
if (shouldPreventFocusOnClose.current) {
|
|
57
|
-
event.preventDefault();
|
|
58
|
-
shouldPreventFocusOnClose.current = false;
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
[shouldPreventFocusOnClose],
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<div className='flex items-center justify-between'>
|
|
66
|
-
<div className='flex items-center gap-1 truncate' title={title}>
|
|
67
|
-
<SortIndicator direction={sortDirection} onClick={onToggleSort} />
|
|
68
|
-
<div className='truncate'>{title}</div>
|
|
69
|
-
</div>
|
|
70
|
-
|
|
71
|
-
<DropdownMenu.Root modal={false}>
|
|
72
|
-
<Popover.Root open={isColumnSettingsOpen} onOpenChange={setIsColumnSettingsOpen} modal={false}>
|
|
73
|
-
<DropdownMenu.Trigger ref={columnSettingsAnchorRef} asChild>
|
|
74
|
-
<Popover.Anchor asChild>
|
|
75
|
-
<Button variant='ghost' data-testid='table.column-menu'>
|
|
76
|
-
<CaretDown className={getSize(4)} />
|
|
77
|
-
</Button>
|
|
78
|
-
</Popover.Anchor>
|
|
79
|
-
</DropdownMenu.Trigger>
|
|
80
|
-
|
|
81
|
-
<DropdownMenu.Portal>
|
|
82
|
-
<DropdownMenu.Content onCloseAutoFocus={onDropdownCloseAutoFocus} sideOffset={4} collisionPadding={8}>
|
|
83
|
-
<DropdownMenu.Viewport>
|
|
84
|
-
{canSort && (
|
|
85
|
-
<>
|
|
86
|
-
<DropdownMenu.Item onClick={() => onSelectSort('asc')}>
|
|
87
|
-
<span className='grow'>Sort ascending</span>
|
|
88
|
-
<span className='opacity-50'>
|
|
89
|
-
<ArrowUp className={getSize(4)} />
|
|
90
|
-
</span>
|
|
91
|
-
</DropdownMenu.Item>
|
|
92
|
-
<DropdownMenu.Item onClick={() => onSelectSort('desc')}>
|
|
93
|
-
<span className='grow'>Sort descending</span>
|
|
94
|
-
<span className='opacity-50'>
|
|
95
|
-
<ArrowDown className={getSize(4)} />
|
|
96
|
-
</span>
|
|
97
|
-
</DropdownMenu.Item>
|
|
98
|
-
{sortDirection && (
|
|
99
|
-
<DropdownMenu.Item onClick={onClearSort}>
|
|
100
|
-
<span className='grow'>Clear sort</span>
|
|
101
|
-
<span className='opacity-50'>
|
|
102
|
-
<X className={getSize(4)} />
|
|
103
|
-
</span>
|
|
104
|
-
</DropdownMenu.Item>
|
|
105
|
-
)}
|
|
106
|
-
</>
|
|
107
|
-
)}
|
|
108
|
-
|
|
109
|
-
{columnOrderable && (
|
|
110
|
-
<>
|
|
111
|
-
{columnPosition !== 'start' && (
|
|
112
|
-
<DropdownMenu.Item onClick={() => onColumnReorder(header.column.id, 'left')}>
|
|
113
|
-
<span className='grow'>Move left</span>
|
|
114
|
-
<span className='opacity-50'>
|
|
115
|
-
<ArrowLeft className={mx(getSize(4))} />
|
|
116
|
-
</span>
|
|
117
|
-
</DropdownMenu.Item>
|
|
118
|
-
)}
|
|
119
|
-
{columnPosition !== 'end' && (
|
|
120
|
-
<DropdownMenu.Item onClick={() => onColumnReorder(header.column.id, 'right')}>
|
|
121
|
-
<span className='grow'>Move right</span>
|
|
122
|
-
<span className='opacity-50'>
|
|
123
|
-
<ArrowRight className={mx(getSize(4))} />
|
|
124
|
-
</span>
|
|
125
|
-
</DropdownMenu.Item>
|
|
126
|
-
)}
|
|
127
|
-
</>
|
|
128
|
-
)}
|
|
129
|
-
|
|
130
|
-
<DropdownMenu.Item onClick={onOpenColumnSettings} data-testid='table.open-column-settings'>
|
|
131
|
-
<span className='grow'>Column settings</span>
|
|
132
|
-
<span className='opacity-50'>
|
|
133
|
-
<GearSix className={mx(getSize(4), 'rotate-90')} />
|
|
134
|
-
</span>
|
|
135
|
-
</DropdownMenu.Item>
|
|
136
|
-
</DropdownMenu.Viewport>
|
|
137
|
-
<DropdownMenu.Arrow />
|
|
138
|
-
</DropdownMenu.Content>
|
|
139
|
-
</DropdownMenu.Portal>
|
|
140
|
-
|
|
141
|
-
<Popover.Portal>
|
|
142
|
-
<Popover.Content>
|
|
143
|
-
<Popover.Viewport>
|
|
144
|
-
<ColumnSettings {...props} column={column} onClose={() => setIsColumnSettingsOpen(false)} />
|
|
145
|
-
</Popover.Viewport>
|
|
146
|
-
<Popover.Arrow />
|
|
147
|
-
</Popover.Content>
|
|
148
|
-
</Popover.Portal>
|
|
149
|
-
</Popover.Root>
|
|
150
|
-
</DropdownMenu.Root>
|
|
151
|
-
</div>
|
|
152
|
-
);
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
export const SortIndicator = ({
|
|
156
|
-
direction,
|
|
157
|
-
onClick,
|
|
158
|
-
}: {
|
|
159
|
-
direction: SortDirection | undefined;
|
|
160
|
-
onClick: (e: any) => void;
|
|
161
|
-
}) => {
|
|
162
|
-
if (direction === undefined) {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
let icon;
|
|
167
|
-
|
|
168
|
-
switch (direction) {
|
|
169
|
-
case 'asc':
|
|
170
|
-
icon = <ArrowUp className={getSize(3)} />;
|
|
171
|
-
break;
|
|
172
|
-
case 'desc':
|
|
173
|
-
icon = <ArrowDown className={getSize(3)} />;
|
|
174
|
-
break;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return (
|
|
178
|
-
<div onClick={onClick} className='flex items-center cursor-pointer'>
|
|
179
|
-
{icon}
|
|
180
|
-
</div>
|
|
181
|
-
);
|
|
182
|
-
};
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
|
-
import React from 'react';
|
|
8
|
-
|
|
9
|
-
import { TypeEnum } from '@dxos/echo-schema';
|
|
10
|
-
import { withTheme, withLayout } from '@dxos/storybook-utils';
|
|
11
|
-
|
|
12
|
-
import { ColumnSettings, type ColumnSettingsProps } from './ColumnSettings';
|
|
13
|
-
import { type TableDef } from '../../schema';
|
|
14
|
-
import translations from '../../translations';
|
|
15
|
-
|
|
16
|
-
const DefaultStory = (props: ColumnSettingsProps) => (
|
|
17
|
-
<div className='flex w-[240px] m-2 p-2 border border-separator rounded'>
|
|
18
|
-
<ColumnSettings {...props} />
|
|
19
|
-
</div>
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
export default {
|
|
23
|
-
title: 'ui/react-ui-table/deprecated/ColumnSettings',
|
|
24
|
-
component: ColumnSettings,
|
|
25
|
-
render: DefaultStory,
|
|
26
|
-
decorators: [withTheme, withLayout()],
|
|
27
|
-
parameters: {
|
|
28
|
-
translations,
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const sampleTableDef: TableDef = {
|
|
33
|
-
id: '1',
|
|
34
|
-
name: 'Sample Table',
|
|
35
|
-
columns: [
|
|
36
|
-
{ id: 'col-1', prop: 'name', type: TypeEnum.String, label: 'Name' },
|
|
37
|
-
{ id: 'col-2', prop: 'age', type: TypeEnum.Number, label: 'Age', digits: 0 },
|
|
38
|
-
],
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const sampleTablesToReference: TableDef[] = [
|
|
42
|
-
sampleTableDef,
|
|
43
|
-
{
|
|
44
|
-
id: '2',
|
|
45
|
-
name: 'Reference Table',
|
|
46
|
-
columns: [
|
|
47
|
-
{ id: 'ref-col-1', prop: 'id', type: TypeEnum.String, label: 'ID' },
|
|
48
|
-
{ id: 'ref-col-2', prop: 'description', type: TypeEnum.String, label: 'Description' },
|
|
49
|
-
],
|
|
50
|
-
},
|
|
51
|
-
];
|
|
52
|
-
|
|
53
|
-
const defaultArgs: ColumnSettingsProps = {
|
|
54
|
-
column: {
|
|
55
|
-
id: 'col-1',
|
|
56
|
-
prop: 'name',
|
|
57
|
-
type: TypeEnum.String,
|
|
58
|
-
label: 'Name',
|
|
59
|
-
},
|
|
60
|
-
tableDef: sampleTableDef,
|
|
61
|
-
tablesToReference: sampleTablesToReference,
|
|
62
|
-
onUpdate: (id, column) => console.log('onUpdate', { id, column }),
|
|
63
|
-
onDelete: (id) => console.log('onDelete', id),
|
|
64
|
-
onClose: () => console.log('onClose'),
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export const Default = {
|
|
68
|
-
args: defaultArgs,
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export const NumberColumn = {
|
|
72
|
-
args: {
|
|
73
|
-
...defaultArgs,
|
|
74
|
-
column: {
|
|
75
|
-
id: 'col-2',
|
|
76
|
-
prop: 'age',
|
|
77
|
-
type: TypeEnum.Number,
|
|
78
|
-
label: 'Age',
|
|
79
|
-
digits: 0,
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export const ReferenceColumn = {
|
|
85
|
-
args: {
|
|
86
|
-
...defaultArgs,
|
|
87
|
-
column: {
|
|
88
|
-
id: 'col-3',
|
|
89
|
-
prop: 'reference',
|
|
90
|
-
type: TypeEnum.Ref,
|
|
91
|
-
label: 'Reference',
|
|
92
|
-
refTable: '2',
|
|
93
|
-
refProp: 'ref-col-1',
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export const NewColumn = {
|
|
99
|
-
args: {
|
|
100
|
-
...defaultArgs,
|
|
101
|
-
column: {
|
|
102
|
-
id: 'new-col',
|
|
103
|
-
prop: '',
|
|
104
|
-
type: TypeEnum.String,
|
|
105
|
-
label: '',
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
};
|