@snack-uikit/table 0.34.2 → 0.34.3
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/CHANGELOG.md +12 -0
- package/dist/cjs/components/Table/Table.js +29 -17
- package/dist/cjs/components/Table/hooks/useColumnOrderByDrag.js +2 -1
- package/dist/cjs/components/Table/utils.d.ts +1 -0
- package/dist/cjs/components/Table/utils.js +15 -5
- package/dist/cjs/helperComponents/Cells/BodyCell/BodyCell.js +1 -1
- package/dist/cjs/helperComponents/Cells/HeaderCell/HeaderCell.js +11 -6
- package/dist/cjs/types.d.ts +4 -0
- package/dist/esm/components/Table/Table.js +27 -11
- package/dist/esm/components/Table/hooks/useColumnOrderByDrag.js +2 -1
- package/dist/esm/components/Table/utils.d.ts +1 -0
- package/dist/esm/components/Table/utils.js +14 -5
- package/dist/esm/helperComponents/Cells/BodyCell/BodyCell.js +1 -1
- package/dist/esm/helperComponents/Cells/HeaderCell/HeaderCell.js +11 -6
- package/dist/esm/types.d.ts +4 -0
- package/package.json +2 -2
- package/src/components/Table/Table.tsx +33 -25
- package/src/components/Table/hooks/useColumnOrderByDrag.ts +2 -1
- package/src/components/Table/utils.ts +16 -5
- package/src/helperComponents/Cells/BodyCell/BodyCell.tsx +1 -1
- package/src/helperComponents/Cells/HeaderCell/HeaderCell.tsx +16 -8
- package/src/types.ts +11 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## 0.34.3 (2025-03-12)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **PDS-1483:** invalid behavior with disabled columns sort by drag fixed ([4d4fc57](https://github.com/cloud-ru-tech/snack-uikit/commit/4d4fc5770f204378c37333a9d9fdf5f05520de48))
|
|
12
|
+
* **PDS-1483:** invalid columns order without id fixed ([c35ce70](https://github.com/cloud-ru-tech/snack-uikit/commit/c35ce70c162fcac4bf87f376ef3ed44cb230470a))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
6
18
|
## 0.34.2 (2025-03-11)
|
|
7
19
|
|
|
8
20
|
### Only dependencies have been changed
|
|
@@ -151,12 +151,18 @@ function Table(_a) {
|
|
|
151
151
|
const enableSelection = Boolean(rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable);
|
|
152
152
|
const manualPagination = infiniteLoading || manualPaginationProp;
|
|
153
153
|
const [enabledColumns, setEnabledColumns] = (0, react_1.useState)(() => (0, utils_3.prepareColumnsSettingsMap)(columnDefinitions));
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
const areColumnsSettingsEnabled = Boolean(columnsSettingsProp === null || columnsSettingsProp === void 0 ? void 0 : columnsSettingsProp.enableSettingsMenu);
|
|
155
|
+
const filteredColumnDefinitions = (0, react_1.useMemo)(() => {
|
|
156
|
+
if (!areColumnsSettingsEnabled) {
|
|
157
|
+
return columnDefinitions;
|
|
157
158
|
}
|
|
158
|
-
return
|
|
159
|
-
|
|
159
|
+
return columnDefinitions.filter(colDef => {
|
|
160
|
+
if ((0, utils_3.isFilterableColumn)(colDef)) {
|
|
161
|
+
return enabledColumns.includes((0, utils_3.getColumnIdentifier)(colDef));
|
|
162
|
+
}
|
|
163
|
+
return true;
|
|
164
|
+
});
|
|
165
|
+
}, [columnDefinitions, enabledColumns, areColumnsSettingsEnabled]);
|
|
160
166
|
const tableColumns = (0, react_1.useMemo)(() => {
|
|
161
167
|
let cols = filteredColumnDefinitions;
|
|
162
168
|
if (enableSelection && !expanding) {
|
|
@@ -167,12 +173,24 @@ function Table(_a) {
|
|
|
167
173
|
}
|
|
168
174
|
return cols;
|
|
169
175
|
}, [filteredColumnDefinitions, enableSelection, enableSelectPinned, expanding]);
|
|
176
|
+
const enableColumnsOrderSortByDrag = Boolean(columnsSettingsProp === null || columnsSettingsProp === void 0 ? void 0 : columnsSettingsProp.enableDrag);
|
|
170
177
|
const {
|
|
171
178
|
columnOrder,
|
|
172
179
|
setColumnOrder,
|
|
173
180
|
sensors,
|
|
174
181
|
handleDragEnd
|
|
175
182
|
} = (0, hooks_1.useColumnOrderByDrag)(tableColumns);
|
|
183
|
+
const dndContextProps = (0, react_1.useMemo)(() => {
|
|
184
|
+
if (!enableColumnsOrderSortByDrag) {
|
|
185
|
+
return {};
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
collisionDetection: core_1.closestCenter,
|
|
189
|
+
modifiers: [modifiers_1.restrictToHorizontalAxis],
|
|
190
|
+
onDragEnd: handleDragEnd,
|
|
191
|
+
sensors: sensors
|
|
192
|
+
};
|
|
193
|
+
}, [enableColumnsOrderSortByDrag, handleDragEnd, sensors]);
|
|
176
194
|
const filterableColumns = (0, react_1.useMemo)(() => columnDefinitions.filter(utils_3.isFilterableColumn), [columnDefinitions]);
|
|
177
195
|
const areAllColumnsEnabled = filterableColumns.length === enabledColumns.length;
|
|
178
196
|
const {
|
|
@@ -212,7 +230,7 @@ function Table(_a) {
|
|
|
212
230
|
columns: tableColumns,
|
|
213
231
|
state: {
|
|
214
232
|
columnPinning,
|
|
215
|
-
columnOrder,
|
|
233
|
+
columnOrder: enableColumnsOrderSortByDrag ? columnOrder : undefined,
|
|
216
234
|
globalFilter,
|
|
217
235
|
rowSelection,
|
|
218
236
|
sorting,
|
|
@@ -236,7 +254,7 @@ function Table(_a) {
|
|
|
236
254
|
});
|
|
237
255
|
}
|
|
238
256
|
},
|
|
239
|
-
onColumnOrderChange: setColumnOrder,
|
|
257
|
+
onColumnOrderChange: enableColumnsOrderSortByDrag ? setColumnOrder : undefined,
|
|
240
258
|
manualSorting,
|
|
241
259
|
manualPagination,
|
|
242
260
|
manualFiltering,
|
|
@@ -404,8 +422,6 @@ function Table(_a) {
|
|
|
404
422
|
updateCellMap
|
|
405
423
|
} = (0, contexts_1.useCellAutoResizeController)(table);
|
|
406
424
|
const showToolbar = !suppressToolbar;
|
|
407
|
-
const showColumnsSettings = Boolean(columnsSettingsProp === null || columnsSettingsProp === void 0 ? void 0 : columnsSettingsProp.enableSettingsMenu);
|
|
408
|
-
const enableColumnsOrderSortByDrag = Boolean(columnsSettingsProp === null || columnsSettingsProp === void 0 ? void 0 : columnsSettingsProp.enableDrag);
|
|
409
425
|
return (0, jsx_runtime_1.jsxs)("div", Object.assign({
|
|
410
426
|
className: (0, classnames_1.default)(styles_module_scss_1.default.wrapper, className)
|
|
411
427
|
}, (0, utils_1.extractSupportProps)(rest), {
|
|
@@ -426,14 +442,14 @@ function Table(_a) {
|
|
|
426
442
|
indeterminate: table.getIsSomePageRowsSelected(),
|
|
427
443
|
onCheck: enableSelection ? handleOnToolbarCheck : undefined,
|
|
428
444
|
outline: outline,
|
|
429
|
-
after: toolbarAfter || exportSettings ||
|
|
445
|
+
after: toolbarAfter || exportSettings || areColumnsSettingsEnabled ? (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, {
|
|
430
446
|
children: [toolbarAfter, exportSettings && (0, jsx_runtime_1.jsx)(helperComponents_1.ExportButton, {
|
|
431
447
|
settings: exportSettings,
|
|
432
448
|
columnDefinitions: columnDefinitions,
|
|
433
449
|
data: data,
|
|
434
450
|
topRows: filteredTopRows,
|
|
435
451
|
centerRows: centerRows
|
|
436
|
-
}),
|
|
452
|
+
}), areColumnsSettingsEnabled && (0, jsx_runtime_1.jsx)(helperComponents_1.ColumnsSettings, {
|
|
437
453
|
columnsSettings: columnsSettings,
|
|
438
454
|
enabledColumns: enabledColumns,
|
|
439
455
|
setEnabledColumns: setEnabledColumns
|
|
@@ -455,11 +471,7 @@ function Table(_a) {
|
|
|
455
471
|
value: {
|
|
456
472
|
updateCellMap
|
|
457
473
|
},
|
|
458
|
-
children: (0, jsx_runtime_1.jsx)(core_1.DndContext, {
|
|
459
|
-
collisionDetection: core_1.closestCenter,
|
|
460
|
-
modifiers: [modifiers_1.restrictToHorizontalAxis],
|
|
461
|
-
onDragEnd: handleDragEnd,
|
|
462
|
-
sensors: sensors,
|
|
474
|
+
children: (0, jsx_runtime_1.jsx)(core_1.DndContext, Object.assign({}, dndContextProps, {
|
|
463
475
|
children: (0, jsx_runtime_1.jsx)(helperComponents_1.TableContext.Provider, {
|
|
464
476
|
value: {
|
|
465
477
|
table
|
|
@@ -509,7 +521,7 @@ function Table(_a) {
|
|
|
509
521
|
})]
|
|
510
522
|
})
|
|
511
523
|
})
|
|
512
|
-
})
|
|
524
|
+
}))
|
|
513
525
|
})
|
|
514
526
|
}), (0, jsx_runtime_1.jsx)("div", {
|
|
515
527
|
className: styles_module_scss_1.default.scrollStub,
|
|
@@ -7,8 +7,9 @@ exports.useColumnOrderByDrag = useColumnOrderByDrag;
|
|
|
7
7
|
const core_1 = require("@dnd-kit/core");
|
|
8
8
|
const sortable_1 = require("@dnd-kit/sortable");
|
|
9
9
|
const react_1 = require("react");
|
|
10
|
+
const utils_1 = require("../utils");
|
|
10
11
|
function prepareInitialState(tableColumns) {
|
|
11
|
-
return tableColumns.filter(column => column.pinned !== 'left' && column.pinned !== 'right').map(
|
|
12
|
+
return tableColumns.filter(column => column.pinned !== 'left' && column.pinned !== 'right').map(utils_1.getColumnIdentifier);
|
|
12
13
|
}
|
|
13
14
|
const draggingOptions = {
|
|
14
15
|
activationConstraint: {
|
|
@@ -19,6 +19,7 @@ type SaveStateToLocalStorageProps = {
|
|
|
19
19
|
};
|
|
20
20
|
export declare function saveStateToLocalStorage({ id, columnId, size }: SaveStateToLocalStorageProps): void;
|
|
21
21
|
export declare function isFilterableColumn<TData extends object>(colDef: ColumnDefinition<TData>): colDef is FilterableColumnDefinition<TData>;
|
|
22
|
+
export declare function getColumnIdentifier<TData extends object>(colDef: ColumnDefinition<TData>): string;
|
|
22
23
|
export declare function prepareColumnsSettingsMap<TData extends object>(columnDefinitions: ColumnDefinition<TData>[]): string[];
|
|
23
24
|
type PrepareColumnsSettingsProps<TData extends object> = {
|
|
24
25
|
columnDefinitions: ColumnDefinition<TData>[];
|
|
@@ -8,6 +8,7 @@ exports.getColumnStyleVars = getColumnStyleVars;
|
|
|
8
8
|
exports.getInitColumnSizeFromLocalStorage = getInitColumnSizeFromLocalStorage;
|
|
9
9
|
exports.saveStateToLocalStorage = saveStateToLocalStorage;
|
|
10
10
|
exports.isFilterableColumn = isFilterableColumn;
|
|
11
|
+
exports.getColumnIdentifier = getColumnIdentifier;
|
|
11
12
|
exports.prepareColumnsSettingsMap = prepareColumnsSettingsMap;
|
|
12
13
|
exports.prepareColumnsSettings = prepareColumnsSettings;
|
|
13
14
|
exports.getInitialColumnsOpenValue = getInitialColumnsOpenValue;
|
|
@@ -62,19 +63,28 @@ function saveStateToLocalStorage(_ref2) {
|
|
|
62
63
|
})));
|
|
63
64
|
}
|
|
64
65
|
function isFilterableColumn(colDef) {
|
|
65
|
-
return 'id' in colDef && 'headerConfigLabel' in colDef;
|
|
66
|
+
return ('id' in colDef || 'accessorKey' in colDef) && 'headerConfigLabel' in colDef;
|
|
67
|
+
}
|
|
68
|
+
function getColumnIdentifier(colDef) {
|
|
69
|
+
if ('id' in colDef && colDef.id) {
|
|
70
|
+
return colDef.id;
|
|
71
|
+
}
|
|
72
|
+
// Either id or accessorKey is always present
|
|
73
|
+
// eslint-disable-next-line
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
return colDef.accessorKey;
|
|
66
76
|
}
|
|
67
77
|
function prepareColumnsSettingsMap(columnDefinitions) {
|
|
68
|
-
return columnDefinitions.filter(isFilterableColumn).map(
|
|
78
|
+
return columnDefinitions.filter(isFilterableColumn).map(getColumnIdentifier);
|
|
69
79
|
}
|
|
70
80
|
const sortColumnDefinitions = columnOrder => function sortColDefs(colDefA, colDefB) {
|
|
71
|
-
const indexItemA = columnOrder.findIndex(columnIndex => columnIndex === colDefA
|
|
72
|
-
const indexItemB = columnOrder.findIndex(columnIndex => columnIndex === colDefB
|
|
81
|
+
const indexItemA = columnOrder.findIndex(columnIndex => columnIndex === getColumnIdentifier(colDefA));
|
|
82
|
+
const indexItemB = columnOrder.findIndex(columnIndex => columnIndex === getColumnIdentifier(colDefB));
|
|
73
83
|
return indexItemA - indexItemB;
|
|
74
84
|
};
|
|
75
85
|
function createColumnsSettingsOption(columnDefinition) {
|
|
76
86
|
return {
|
|
77
|
-
id: columnDefinition
|
|
87
|
+
id: getColumnIdentifier(columnDefinition),
|
|
78
88
|
content: {
|
|
79
89
|
option: columnDefinition.headerConfigLabel
|
|
80
90
|
},
|
|
@@ -43,7 +43,7 @@ function BodyCell(_a) {
|
|
|
43
43
|
id: cell.column.id
|
|
44
44
|
});
|
|
45
45
|
return (0, jsx_runtime_1.jsx)(Cell_1.Cell, Object.assign({}, props, {
|
|
46
|
-
ref: setNodeRef,
|
|
46
|
+
ref: isDraggable ? setNodeRef : undefined,
|
|
47
47
|
style: style,
|
|
48
48
|
className: (0, classnames_1.default)(styles_module_scss_1.default.tableBodyCell, className, columnDef.cellClassName),
|
|
49
49
|
"data-row-auto-height": rowAutoHeight || undefined,
|
|
@@ -54,9 +54,12 @@ function HeaderCell(_ref) {
|
|
|
54
54
|
if (isSomeColumnResizing) return;
|
|
55
55
|
return (_a = header.column.getToggleSortingHandler()) === null || _a === void 0 ? void 0 : _a(e);
|
|
56
56
|
};
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
const draggableProps = (0, react_1.useMemo)(() => {
|
|
58
|
+
if (!isDraggable || constants_1.DEFAULT_COLUMNS.includes(header.column.id)) {
|
|
59
|
+
return {};
|
|
60
|
+
}
|
|
61
|
+
return Object.assign(Object.assign({}, attributes), listeners);
|
|
62
|
+
}, [attributes, header.column.id, isDraggable, listeners]);
|
|
60
63
|
return (0, jsx_runtime_1.jsxs)(Cell_1.Cell, {
|
|
61
64
|
style: style,
|
|
62
65
|
onClick: sortingHandler,
|
|
@@ -73,13 +76,15 @@ function HeaderCell(_ref) {
|
|
|
73
76
|
role: 'columnheader',
|
|
74
77
|
className: (0, classnames_1.default)(styles_module_scss_1.default.tableHeaderCell, className, columnDef.headerClassName),
|
|
75
78
|
ref: element => {
|
|
76
|
-
|
|
79
|
+
if (isDraggable) {
|
|
80
|
+
setNodeRef(element);
|
|
81
|
+
}
|
|
77
82
|
return cellRef;
|
|
78
83
|
},
|
|
79
84
|
children: [(0, jsx_runtime_1.jsx)("div", Object.assign({
|
|
80
85
|
className: styles_module_scss_1.default.tableHeaderCellDragWrapper,
|
|
81
|
-
"data-dragging": isDragging || undefined
|
|
82
|
-
},
|
|
86
|
+
"data-dragging": isDraggable && isDragging || undefined
|
|
87
|
+
}, draggableProps, {
|
|
83
88
|
children: (0, jsx_runtime_1.jsxs)("div", {
|
|
84
89
|
className: styles_module_scss_1.default.tableHeaderCellMain,
|
|
85
90
|
children: [columnDef.header && (0, jsx_runtime_1.jsx)("div", {
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -42,6 +42,10 @@ type FilterableProps = {
|
|
|
42
42
|
id: string;
|
|
43
43
|
/** Название колонки в настройках таблицы */
|
|
44
44
|
headerConfigLabel?: string;
|
|
45
|
+
} | {
|
|
46
|
+
accessorKey: string;
|
|
47
|
+
/** Название колонки в настройках таблицы */
|
|
48
|
+
headerConfigLabel?: string;
|
|
45
49
|
};
|
|
46
50
|
type FilterableNormalColumnDefinition<TData> = NormalColumnDefinition<TData> & FilterableProps;
|
|
47
51
|
type FilterablePinnedColumnDefinition<TData> = PinnedColumnDefinition<TData> & FilterableProps;
|
|
@@ -30,7 +30,7 @@ import { useColumnOrderByDrag, useLoadingTable, useStateControl } from './hooks'
|
|
|
30
30
|
import { usePageReset } from './hooks/usePageReset';
|
|
31
31
|
import { useSaveTableSettings } from './hooks/useSaveTableSettings';
|
|
32
32
|
import styles from './styles.module.css';
|
|
33
|
-
import { getColumnStyleVars, getCurrentlyConfiguredHeaderWidth, getInitColumnSizeFromLocalStorage, getInitialColumnsOpenValue, isFilterableColumn, prepareColumnsSettings, prepareColumnsSettingsMap, saveStateToLocalStorage, } from './utils';
|
|
33
|
+
import { getColumnIdentifier, getColumnStyleVars, getCurrentlyConfiguredHeaderWidth, getInitColumnSizeFromLocalStorage, getInitialColumnsOpenValue, isFilterableColumn, prepareColumnsSettings, prepareColumnsSettingsMap, saveStateToLocalStorage, } from './utils';
|
|
34
34
|
/** Компонент таблицы */
|
|
35
35
|
export function Table(_a) {
|
|
36
36
|
var { data, rowPinning = {
|
|
@@ -82,12 +82,18 @@ export function Table(_a) {
|
|
|
82
82
|
const enableSelection = Boolean(rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable);
|
|
83
83
|
const manualPagination = infiniteLoading || manualPaginationProp;
|
|
84
84
|
const [enabledColumns, setEnabledColumns] = useState(() => prepareColumnsSettingsMap(columnDefinitions));
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
const areColumnsSettingsEnabled = Boolean(columnsSettingsProp === null || columnsSettingsProp === void 0 ? void 0 : columnsSettingsProp.enableSettingsMenu);
|
|
86
|
+
const filteredColumnDefinitions = useMemo(() => {
|
|
87
|
+
if (!areColumnsSettingsEnabled) {
|
|
88
|
+
return columnDefinitions;
|
|
88
89
|
}
|
|
89
|
-
return
|
|
90
|
-
|
|
90
|
+
return columnDefinitions.filter(colDef => {
|
|
91
|
+
if (isFilterableColumn(colDef)) {
|
|
92
|
+
return enabledColumns.includes(getColumnIdentifier(colDef));
|
|
93
|
+
}
|
|
94
|
+
return true;
|
|
95
|
+
});
|
|
96
|
+
}, [columnDefinitions, enabledColumns, areColumnsSettingsEnabled]);
|
|
91
97
|
const tableColumns = useMemo(() => {
|
|
92
98
|
let cols = filteredColumnDefinitions;
|
|
93
99
|
if (enableSelection && !expanding) {
|
|
@@ -98,7 +104,19 @@ export function Table(_a) {
|
|
|
98
104
|
}
|
|
99
105
|
return cols;
|
|
100
106
|
}, [filteredColumnDefinitions, enableSelection, enableSelectPinned, expanding]);
|
|
107
|
+
const enableColumnsOrderSortByDrag = Boolean(columnsSettingsProp === null || columnsSettingsProp === void 0 ? void 0 : columnsSettingsProp.enableDrag);
|
|
101
108
|
const { columnOrder, setColumnOrder, sensors, handleDragEnd } = useColumnOrderByDrag(tableColumns);
|
|
109
|
+
const dndContextProps = useMemo(() => {
|
|
110
|
+
if (!enableColumnsOrderSortByDrag) {
|
|
111
|
+
return {};
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
collisionDetection: closestCenter,
|
|
115
|
+
modifiers: [restrictToHorizontalAxis],
|
|
116
|
+
onDragEnd: handleDragEnd,
|
|
117
|
+
sensors: sensors,
|
|
118
|
+
};
|
|
119
|
+
}, [enableColumnsOrderSortByDrag, handleDragEnd, sensors]);
|
|
102
120
|
const filterableColumns = useMemo(() => columnDefinitions.filter(isFilterableColumn), [columnDefinitions]);
|
|
103
121
|
const areAllColumnsEnabled = filterableColumns.length === enabledColumns.length;
|
|
104
122
|
const { t } = useLocale('Table');
|
|
@@ -134,7 +152,7 @@ export function Table(_a) {
|
|
|
134
152
|
columns: tableColumns,
|
|
135
153
|
state: {
|
|
136
154
|
columnPinning,
|
|
137
|
-
columnOrder,
|
|
155
|
+
columnOrder: enableColumnsOrderSortByDrag ? columnOrder : undefined,
|
|
138
156
|
globalFilter,
|
|
139
157
|
rowSelection,
|
|
140
158
|
sorting,
|
|
@@ -153,7 +171,7 @@ export function Table(_a) {
|
|
|
153
171
|
return _jsx(TruncateString, { text: String(cell.getValue()), maxLines: 1 });
|
|
154
172
|
},
|
|
155
173
|
},
|
|
156
|
-
onColumnOrderChange: setColumnOrder,
|
|
174
|
+
onColumnOrderChange: enableColumnsOrderSortByDrag ? setColumnOrder : undefined,
|
|
157
175
|
manualSorting,
|
|
158
176
|
manualPagination,
|
|
159
177
|
manualFiltering,
|
|
@@ -297,8 +315,6 @@ export function Table(_a) {
|
|
|
297
315
|
});
|
|
298
316
|
const { updateCellMap } = useCellAutoResizeController(table);
|
|
299
317
|
const showToolbar = !suppressToolbar;
|
|
300
|
-
const showColumnsSettings = Boolean(columnsSettingsProp === null || columnsSettingsProp === void 0 ? void 0 : columnsSettingsProp.enableSettingsMenu);
|
|
301
|
-
const enableColumnsOrderSortByDrag = Boolean(columnsSettingsProp === null || columnsSettingsProp === void 0 ? void 0 : columnsSettingsProp.enableDrag);
|
|
302
318
|
return (_jsxs("div", Object.assign({ className: cn(styles.wrapper, className) }, extractSupportProps(rest), { children: [showToolbar && (_jsx("div", { className: styles.header, children: _jsx(Toolbar, { search: suppressSearch
|
|
303
319
|
? undefined
|
|
304
320
|
: {
|
|
@@ -306,7 +322,7 @@ export function Table(_a) {
|
|
|
306
322
|
onChange: onGlobalFilterChange,
|
|
307
323
|
loading: search === null || search === void 0 ? void 0 : search.loading,
|
|
308
324
|
placeholder: (search === null || search === void 0 ? void 0 : search.placeholder) || t('searchPlaceholder'),
|
|
309
|
-
}, className: styles.toolbar, onRefresh: onRefresh ? handleOnRefresh : undefined, bulkActions: bulkActions, selectionMode: (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow) ? 'multiple' : 'single', checked: table.getIsAllPageRowsSelected(), indeterminate: table.getIsSomePageRowsSelected(), onCheck: enableSelection ? handleOnToolbarCheck : undefined, outline: outline, after: toolbarAfter || exportSettings ||
|
|
325
|
+
}, className: styles.toolbar, onRefresh: onRefresh ? handleOnRefresh : undefined, bulkActions: bulkActions, selectionMode: (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow) ? 'multiple' : 'single', checked: table.getIsAllPageRowsSelected(), indeterminate: table.getIsSomePageRowsSelected(), onCheck: enableSelection ? handleOnToolbarCheck : undefined, outline: outline, after: toolbarAfter || exportSettings || areColumnsSettingsEnabled ? (_jsxs(_Fragment, { children: [toolbarAfter, exportSettings && (_jsx(ExportButton, { settings: exportSettings, columnDefinitions: columnDefinitions, data: data, topRows: filteredTopRows, centerRows: centerRows })), areColumnsSettingsEnabled && (_jsx(ColumnsSettings, { columnsSettings: columnsSettings, enabledColumns: enabledColumns, setEnabledColumns: setEnabledColumns }))] })) : undefined, moreActions: moreActions, filterRow: patchedFilter, "data-test-id": TEST_IDS.toolbar }) })), _jsxs(Scroll, { size: 's', className: styles.table, ref: scrollContainerRef, "data-outline": outline || undefined, children: [_jsx("div", { className: styles.tableContent, style: columnSizes.vars, children: _jsx(CellAutoResizeContext.Provider, { value: { updateCellMap }, children: _jsx(DndContext, Object.assign({}, dndContextProps, { children: _jsx(TableContext.Provider, { value: { table }, children: (!infiniteLoading || !data.length) && loading ? (_jsxs(SkeletonContextProvider, { loading: true, children: [_jsx(HeaderRow, { rowAutoHeight: rowAutoHeight, columnOrder: columnOrder }), loadingTableRows.map(row => (_jsx(BodyRow, { row: row, rowAutoHeight: rowAutoHeight, columnOrder: columnOrder }, row.id)))] })) : (_jsxs(_Fragment, { children: [centerRows.length || filteredTopRows.length ? (_jsx(HeaderRow, { rowAutoHeight: rowAutoHeight, columnOrder: columnOrder, enableColumnsOrderSortByDrag: enableColumnsOrderSortByDrag })) : null, filteredTopRows.length ? (_jsx("div", { className: styles.topRowWrapper, children: filteredTopRows.map(row => (_jsx(BodyRow, { row: row, onRowClick: onRowClick, rowAutoHeight: rowAutoHeight, columnOrder: columnOrder, enableColumnsOrderSortByDrag: enableColumnsOrderSortByDrag }, row.id))) })) : null, centerRows.map(row => (_jsx(BodyRow, { row: row, onRowClick: onRowClick, rowAutoHeight: rowAutoHeight, columnOrder: columnOrder, enableColumnsOrderSortByDrag: enableColumnsOrderSortByDrag }, row.id))), data.length > 0 && infiniteLoading && loading && !dataError && (_jsx(SkeletonContextProvider, { loading: true, children: loadingTableRows.slice(0, 3).map(row => (_jsx(BodyRow, { row: row, columnOrder: columnOrder, enableColumnsOrderSortByDrag: enableColumnsOrderSortByDrag }, row.id))) })), _jsx(TableEmptyState, { emptyStates: emptyStates, dataError: dataError, dataFiltered: dataFiltered || Boolean(table.getState().globalFilter), tableRowsLength: tableRows.length + filteredTopRows.length })] })) }) })) }) }), _jsx("div", { className: styles.scrollStub, ref: scrollRef })] }), !infiniteLoading && !suppressPagination && (_jsx(TablePagination, { table: table, options: paginationProp === null || paginationProp === void 0 ? void 0 : paginationProp.options, optionsLabel: paginationProp === null || paginationProp === void 0 ? void 0 : paginationProp.optionsLabel, pageCount: pageCount, optionsRender: paginationProp === null || paginationProp === void 0 ? void 0 : paginationProp.optionsRender }))] })));
|
|
310
326
|
}
|
|
311
327
|
Table.getStatusColumnDef = getStatusColumnDef;
|
|
312
328
|
Table.statusAppearances = STATUS_APPEARANCE;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { KeyboardSensor, MouseSensor, TouchSensor, useSensor, useSensors, } from '@dnd-kit/core';
|
|
2
2
|
import { arrayMove } from '@dnd-kit/sortable';
|
|
3
3
|
import { useCallback, useState } from 'react';
|
|
4
|
+
import { getColumnIdentifier } from '../utils';
|
|
4
5
|
function prepareInitialState(tableColumns) {
|
|
5
|
-
return tableColumns.filter(column => column.pinned !== 'left' && column.pinned !== 'right').map(
|
|
6
|
+
return tableColumns.filter(column => column.pinned !== 'left' && column.pinned !== 'right').map(getColumnIdentifier);
|
|
6
7
|
}
|
|
7
8
|
const draggingOptions = {
|
|
8
9
|
activationConstraint: {
|
|
@@ -19,6 +19,7 @@ type SaveStateToLocalStorageProps = {
|
|
|
19
19
|
};
|
|
20
20
|
export declare function saveStateToLocalStorage({ id, columnId, size }: SaveStateToLocalStorageProps): void;
|
|
21
21
|
export declare function isFilterableColumn<TData extends object>(colDef: ColumnDefinition<TData>): colDef is FilterableColumnDefinition<TData>;
|
|
22
|
+
export declare function getColumnIdentifier<TData extends object>(colDef: ColumnDefinition<TData>): string;
|
|
22
23
|
export declare function prepareColumnsSettingsMap<TData extends object>(columnDefinitions: ColumnDefinition<TData>[]): string[];
|
|
23
24
|
type PrepareColumnsSettingsProps<TData extends object> = {
|
|
24
25
|
columnDefinitions: ColumnDefinition<TData>[];
|
|
@@ -36,19 +36,28 @@ export function saveStateToLocalStorage({ id, columnId, size }) {
|
|
|
36
36
|
localStorage.setItem(id, JSON.stringify(Object.assign(Object.assign({}, (savedStateFromStorage || {})), { resizeState: newResizeState })));
|
|
37
37
|
}
|
|
38
38
|
export function isFilterableColumn(colDef) {
|
|
39
|
-
return 'id' in colDef && 'headerConfigLabel' in colDef;
|
|
39
|
+
return ('id' in colDef || 'accessorKey' in colDef) && 'headerConfigLabel' in colDef;
|
|
40
|
+
}
|
|
41
|
+
export function getColumnIdentifier(colDef) {
|
|
42
|
+
if ('id' in colDef && colDef.id) {
|
|
43
|
+
return colDef.id;
|
|
44
|
+
}
|
|
45
|
+
// Either id or accessorKey is always present
|
|
46
|
+
// eslint-disable-next-line
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
return colDef.accessorKey;
|
|
40
49
|
}
|
|
41
50
|
export function prepareColumnsSettingsMap(columnDefinitions) {
|
|
42
|
-
return columnDefinitions.filter(isFilterableColumn).map(
|
|
51
|
+
return columnDefinitions.filter(isFilterableColumn).map(getColumnIdentifier);
|
|
43
52
|
}
|
|
44
53
|
const sortColumnDefinitions = (columnOrder) => function sortColDefs(colDefA, colDefB) {
|
|
45
|
-
const indexItemA = columnOrder.findIndex(columnIndex => columnIndex === colDefA
|
|
46
|
-
const indexItemB = columnOrder.findIndex(columnIndex => columnIndex === colDefB
|
|
54
|
+
const indexItemA = columnOrder.findIndex(columnIndex => columnIndex === getColumnIdentifier(colDefA));
|
|
55
|
+
const indexItemB = columnOrder.findIndex(columnIndex => columnIndex === getColumnIdentifier(colDefB));
|
|
47
56
|
return indexItemA - indexItemB;
|
|
48
57
|
};
|
|
49
58
|
function createColumnsSettingsOption(columnDefinition) {
|
|
50
59
|
return {
|
|
51
|
-
id: columnDefinition
|
|
60
|
+
id: getColumnIdentifier(columnDefinition),
|
|
52
61
|
content: {
|
|
53
62
|
option: columnDefinition.headerConfigLabel,
|
|
54
63
|
},
|
|
@@ -24,5 +24,5 @@ export function BodyCell(_a) {
|
|
|
24
24
|
const { setNodeRef } = useSortable({
|
|
25
25
|
id: cell.column.id,
|
|
26
26
|
});
|
|
27
|
-
return (_jsx(Cell, Object.assign({}, props, { ref: setNodeRef, style: style, className: cn(styles.tableBodyCell, className, columnDef.cellClassName), "data-row-auto-height": rowAutoHeight || undefined, "data-align": columnDef.align, "data-no-padding": columnDef.noBodyCellPadding || undefined, "data-column-id": cell.column.id, "data-test-id": TEST_IDS.bodyCell, children: flexRender(columnDef.cell, cell.getContext()) })));
|
|
27
|
+
return (_jsx(Cell, Object.assign({}, props, { ref: isDraggable ? setNodeRef : undefined, style: style, className: cn(styles.tableBodyCell, className, columnDef.cellClassName), "data-row-auto-height": rowAutoHeight || undefined, "data-align": columnDef.align, "data-no-padding": columnDef.noBodyCellPadding || undefined, "data-column-id": cell.column.id, "data-test-id": TEST_IDS.bodyCell, children: flexRender(columnDef.cell, cell.getContext()) })));
|
|
28
28
|
}
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useSortable } from '@dnd-kit/sortable';
|
|
3
3
|
import { flexRender } from '@tanstack/react-table';
|
|
4
4
|
import cn from 'classnames';
|
|
5
|
-
import { useRef } from 'react';
|
|
5
|
+
import { useMemo, useRef } from 'react';
|
|
6
6
|
import { TruncateString } from '@snack-uikit/truncate-string';
|
|
7
7
|
import { DEFAULT_COLUMNS, TEST_IDS } from '../../../constants';
|
|
8
8
|
import { useCellSizes } from '../../hooks';
|
|
@@ -30,11 +30,16 @@ export function HeaderCell({ header, pinPosition, className, rowAutoHeight, isDr
|
|
|
30
30
|
return;
|
|
31
31
|
return (_a = header.column.getToggleSortingHandler()) === null || _a === void 0 ? void 0 : _a(e);
|
|
32
32
|
};
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
const draggableProps = useMemo(() => {
|
|
34
|
+
if (!isDraggable || DEFAULT_COLUMNS.includes(header.column.id)) {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
return Object.assign(Object.assign({}, attributes), listeners);
|
|
38
|
+
}, [attributes, header.column.id, isDraggable, listeners]);
|
|
36
39
|
return (_jsxs(Cell, { style: style, onClick: sortingHandler, "data-sortable": isSortable || undefined, "data-draggable": isDraggable || undefined, "data-no-padding": columnDef.noHeaderCellPadding || undefined, "data-no-offset": columnDef.noHeaderCellBorderOffset || undefined, "data-test-id": TEST_IDS.headerCell, "data-align": columnDef.headerAlign || undefined, "data-header-id": header.id, "data-resizing": isResizing || undefined, "data-pin-position": pinPosition || undefined, "data-row-auto-height": rowAutoHeight || undefined, role: 'columnheader', className: cn(styles.tableHeaderCell, className, columnDef.headerClassName), ref: element => {
|
|
37
|
-
|
|
40
|
+
if (isDraggable) {
|
|
41
|
+
setNodeRef(element);
|
|
42
|
+
}
|
|
38
43
|
return cellRef;
|
|
39
|
-
}, children: [_jsx("div", Object.assign({ className: styles.tableHeaderCellDragWrapper, "data-dragging": isDragging || undefined },
|
|
44
|
+
}, children: [_jsx("div", Object.assign({ className: styles.tableHeaderCellDragWrapper, "data-dragging": (isDraggable && isDragging) || undefined }, draggableProps, { children: _jsxs("div", { className: styles.tableHeaderCellMain, children: [columnDef.header && (_jsx("div", { className: styles.tableHeaderCellName, children: rowAutoHeight ? (flexRender(columnDef.header, header.getContext())) : (_jsx(TruncateString, { text: flexRender(columnDef.header, header.getContext()) })) })), Boolean(sortIcon) && (_jsx("div", { className: styles.tableHeaderIcon, "data-sort-direction": sortDirection, "data-test-id": TEST_IDS.headerSortIndicator, children: sortIcon }))] }) })), Boolean(isResizable) && _jsx(ResizeHandle, { header: header, cellRef: cellRef })] }));
|
|
40
45
|
}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -42,6 +42,10 @@ type FilterableProps = {
|
|
|
42
42
|
id: string;
|
|
43
43
|
/** Название колонки в настройках таблицы */
|
|
44
44
|
headerConfigLabel?: string;
|
|
45
|
+
} | {
|
|
46
|
+
accessorKey: string;
|
|
47
|
+
/** Название колонки в настройках таблицы */
|
|
48
|
+
headerConfigLabel?: string;
|
|
45
49
|
};
|
|
46
50
|
type FilterableNormalColumnDefinition<TData> = NormalColumnDefinition<TData> & FilterableProps;
|
|
47
51
|
type FilterablePinnedColumnDefinition<TData> = PinnedColumnDefinition<TData> & FilterableProps;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Table",
|
|
7
|
-
"version": "0.34.
|
|
7
|
+
"version": "0.34.3",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"@snack-uikit/locale": "*"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "92b00e691dc439c405ca1256c297352eeb8ba3ca"
|
|
70
70
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { closestCenter, DndContext } from '@dnd-kit/core';
|
|
1
|
+
import { closestCenter, DndContext, DndContextProps } from '@dnd-kit/core';
|
|
2
2
|
import { restrictToHorizontalAxis } from '@dnd-kit/modifiers';
|
|
3
3
|
import {
|
|
4
4
|
CellContext,
|
|
@@ -57,6 +57,7 @@ import { usePageReset } from './hooks/usePageReset';
|
|
|
57
57
|
import { useSaveTableSettings } from './hooks/useSaveTableSettings';
|
|
58
58
|
import styles from './styles.module.scss';
|
|
59
59
|
import {
|
|
60
|
+
getColumnIdentifier,
|
|
60
61
|
getColumnStyleVars,
|
|
61
62
|
getCurrentlyConfiguredHeaderWidth,
|
|
62
63
|
getInitColumnSizeFromLocalStorage,
|
|
@@ -199,18 +200,21 @@ export function Table<TData extends object, TFilters extends FiltersState = Reco
|
|
|
199
200
|
const manualPagination = infiniteLoading || manualPaginationProp;
|
|
200
201
|
|
|
201
202
|
const [enabledColumns, setEnabledColumns] = useState<string[]>(() => prepareColumnsSettingsMap(columnDefinitions));
|
|
203
|
+
const areColumnsSettingsEnabled = Boolean(columnsSettingsProp?.enableSettingsMenu);
|
|
202
204
|
|
|
203
|
-
const filteredColumnDefinitions = useMemo(
|
|
204
|
-
()
|
|
205
|
-
columnDefinitions
|
|
206
|
-
|
|
207
|
-
return enabledColumns.includes(colDef.id);
|
|
208
|
-
}
|
|
205
|
+
const filteredColumnDefinitions = useMemo(() => {
|
|
206
|
+
if (!areColumnsSettingsEnabled) {
|
|
207
|
+
return columnDefinitions;
|
|
208
|
+
}
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
210
|
+
return columnDefinitions.filter(colDef => {
|
|
211
|
+
if (isFilterableColumn(colDef)) {
|
|
212
|
+
return enabledColumns.includes(getColumnIdentifier(colDef));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return true;
|
|
216
|
+
});
|
|
217
|
+
}, [columnDefinitions, enabledColumns, areColumnsSettingsEnabled]);
|
|
214
218
|
|
|
215
219
|
const tableColumns: ColumnDefinition<TData>[] = useMemo(() => {
|
|
216
220
|
let cols: ColumnDefinition<TData>[] = filteredColumnDefinitions;
|
|
@@ -223,13 +227,24 @@ export function Table<TData extends object, TFilters extends FiltersState = Reco
|
|
|
223
227
|
return cols;
|
|
224
228
|
}, [filteredColumnDefinitions, enableSelection, enableSelectPinned, expanding]);
|
|
225
229
|
|
|
230
|
+
const enableColumnsOrderSortByDrag = Boolean(columnsSettingsProp?.enableDrag);
|
|
226
231
|
const { columnOrder, setColumnOrder, sensors, handleDragEnd } = useColumnOrderByDrag(tableColumns);
|
|
232
|
+
const dndContextProps: DndContextProps = useMemo(() => {
|
|
233
|
+
if (!enableColumnsOrderSortByDrag) {
|
|
234
|
+
return {};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
collisionDetection: closestCenter,
|
|
239
|
+
modifiers: [restrictToHorizontalAxis],
|
|
240
|
+
onDragEnd: handleDragEnd,
|
|
241
|
+
sensors: sensors,
|
|
242
|
+
};
|
|
243
|
+
}, [enableColumnsOrderSortByDrag, handleDragEnd, sensors]);
|
|
227
244
|
|
|
228
245
|
const filterableColumns = useMemo(() => columnDefinitions.filter(isFilterableColumn), [columnDefinitions]);
|
|
229
246
|
const areAllColumnsEnabled = filterableColumns.length === enabledColumns.length;
|
|
230
|
-
|
|
231
247
|
const { t } = useLocale('Table');
|
|
232
|
-
|
|
233
248
|
const columnsSettings = useMemo(
|
|
234
249
|
() =>
|
|
235
250
|
prepareColumnsSettings({
|
|
@@ -271,7 +286,7 @@ export function Table<TData extends object, TFilters extends FiltersState = Reco
|
|
|
271
286
|
columns: tableColumns,
|
|
272
287
|
state: {
|
|
273
288
|
columnPinning,
|
|
274
|
-
columnOrder,
|
|
289
|
+
columnOrder: enableColumnsOrderSortByDrag ? columnOrder : undefined,
|
|
275
290
|
globalFilter,
|
|
276
291
|
rowSelection,
|
|
277
292
|
sorting,
|
|
@@ -291,7 +306,7 @@ export function Table<TData extends object, TFilters extends FiltersState = Reco
|
|
|
291
306
|
return <TruncateString text={String(cell.getValue())} maxLines={1} />;
|
|
292
307
|
},
|
|
293
308
|
},
|
|
294
|
-
onColumnOrderChange: setColumnOrder,
|
|
309
|
+
onColumnOrderChange: enableColumnsOrderSortByDrag ? setColumnOrder : undefined,
|
|
295
310
|
|
|
296
311
|
manualSorting,
|
|
297
312
|
manualPagination,
|
|
@@ -471,8 +486,6 @@ export function Table<TData extends object, TFilters extends FiltersState = Reco
|
|
|
471
486
|
const { updateCellMap } = useCellAutoResizeController(table);
|
|
472
487
|
|
|
473
488
|
const showToolbar = !suppressToolbar;
|
|
474
|
-
const showColumnsSettings = Boolean(columnsSettingsProp?.enableSettingsMenu);
|
|
475
|
-
const enableColumnsOrderSortByDrag = Boolean(columnsSettingsProp?.enableDrag);
|
|
476
489
|
|
|
477
490
|
return (
|
|
478
491
|
<div className={cn(styles.wrapper, className)} {...extractSupportProps(rest)}>
|
|
@@ -498,7 +511,7 @@ export function Table<TData extends object, TFilters extends FiltersState = Reco
|
|
|
498
511
|
onCheck={enableSelection ? handleOnToolbarCheck : undefined}
|
|
499
512
|
outline={outline}
|
|
500
513
|
after={
|
|
501
|
-
toolbarAfter || exportSettings ||
|
|
514
|
+
toolbarAfter || exportSettings || areColumnsSettingsEnabled ? (
|
|
502
515
|
<>
|
|
503
516
|
{toolbarAfter}
|
|
504
517
|
{exportSettings && (
|
|
@@ -510,7 +523,7 @@ export function Table<TData extends object, TFilters extends FiltersState = Reco
|
|
|
510
523
|
centerRows={centerRows}
|
|
511
524
|
/>
|
|
512
525
|
)}
|
|
513
|
-
{
|
|
526
|
+
{areColumnsSettingsEnabled && (
|
|
514
527
|
<ColumnsSettings
|
|
515
528
|
columnsSettings={columnsSettings}
|
|
516
529
|
enabledColumns={enabledColumns}
|
|
@@ -530,12 +543,7 @@ export function Table<TData extends object, TFilters extends FiltersState = Reco
|
|
|
530
543
|
<Scroll size='s' className={styles.table} ref={scrollContainerRef} data-outline={outline || undefined}>
|
|
531
544
|
<div className={styles.tableContent} style={columnSizes.vars}>
|
|
532
545
|
<CellAutoResizeContext.Provider value={{ updateCellMap }}>
|
|
533
|
-
<DndContext
|
|
534
|
-
collisionDetection={closestCenter}
|
|
535
|
-
modifiers={[restrictToHorizontalAxis]}
|
|
536
|
-
onDragEnd={handleDragEnd}
|
|
537
|
-
sensors={sensors}
|
|
538
|
-
>
|
|
546
|
+
<DndContext {...dndContextProps}>
|
|
539
547
|
<TableContext.Provider value={{ table }}>
|
|
540
548
|
{(!infiniteLoading || !data.length) && loading ? (
|
|
541
549
|
<SkeletonContextProvider loading>
|
|
@@ -11,9 +11,10 @@ import { arrayMove } from '@dnd-kit/sortable';
|
|
|
11
11
|
import { useCallback, useState } from 'react';
|
|
12
12
|
|
|
13
13
|
import { ColumnDefinition } from '../../../types';
|
|
14
|
+
import { getColumnIdentifier } from '../utils';
|
|
14
15
|
|
|
15
16
|
function prepareInitialState<TData extends object>(tableColumns: ColumnDefinition<TData>[]) {
|
|
16
|
-
return tableColumns.filter(column => column.pinned !== 'left' && column.pinned !== 'right').map(
|
|
17
|
+
return tableColumns.filter(column => column.pinned !== 'left' && column.pinned !== 'right').map(getColumnIdentifier);
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
const draggingOptions: SensorOptions = {
|
|
@@ -72,13 +72,24 @@ export function saveStateToLocalStorage({ id, columnId, size }: SaveStateToLocal
|
|
|
72
72
|
export function isFilterableColumn<TData extends object>(
|
|
73
73
|
colDef: ColumnDefinition<TData>,
|
|
74
74
|
): colDef is FilterableColumnDefinition<TData> {
|
|
75
|
-
return 'id' in colDef && 'headerConfigLabel' in colDef;
|
|
75
|
+
return ('id' in colDef || 'accessorKey' in colDef) && 'headerConfigLabel' in colDef;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function getColumnIdentifier<TData extends object>(colDef: ColumnDefinition<TData>): string {
|
|
79
|
+
if ('id' in colDef && colDef.id) {
|
|
80
|
+
return colDef.id;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Either id or accessorKey is always present
|
|
84
|
+
// eslint-disable-next-line
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
return colDef.accessorKey as unknown as string;
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
export function prepareColumnsSettingsMap<TData extends object>(
|
|
79
90
|
columnDefinitions: ColumnDefinition<TData>[],
|
|
80
91
|
): string[] {
|
|
81
|
-
return columnDefinitions.filter(isFilterableColumn).map(
|
|
92
|
+
return columnDefinitions.filter(isFilterableColumn).map(getColumnIdentifier);
|
|
82
93
|
}
|
|
83
94
|
|
|
84
95
|
const sortColumnDefinitions = (columnOrder: string[]) =>
|
|
@@ -86,8 +97,8 @@ const sortColumnDefinitions = (columnOrder: string[]) =>
|
|
|
86
97
|
colDefA: FilterableColumnDefinition<TData>,
|
|
87
98
|
colDefB: FilterableColumnDefinition<TData>,
|
|
88
99
|
) {
|
|
89
|
-
const indexItemA = columnOrder.findIndex(columnIndex => columnIndex === colDefA
|
|
90
|
-
const indexItemB = columnOrder.findIndex(columnIndex => columnIndex === colDefB
|
|
100
|
+
const indexItemA = columnOrder.findIndex(columnIndex => columnIndex === getColumnIdentifier(colDefA));
|
|
101
|
+
const indexItemB = columnOrder.findIndex(columnIndex => columnIndex === getColumnIdentifier(colDefB));
|
|
91
102
|
|
|
92
103
|
return indexItemA - indexItemB;
|
|
93
104
|
};
|
|
@@ -96,7 +107,7 @@ function createColumnsSettingsOption<TData extends object>(
|
|
|
96
107
|
columnDefinition: FilterableColumnDefinition<TData>,
|
|
97
108
|
): BaseItemProps {
|
|
98
109
|
return {
|
|
99
|
-
id: columnDefinition
|
|
110
|
+
id: getColumnIdentifier(columnDefinition),
|
|
100
111
|
content: {
|
|
101
112
|
option: columnDefinition.headerConfigLabel as string,
|
|
102
113
|
},
|
|
@@ -26,7 +26,7 @@ export function BodyCell<TData>({ cell, className, rowAutoHeight, isDraggable, .
|
|
|
26
26
|
return (
|
|
27
27
|
<Cell
|
|
28
28
|
{...props}
|
|
29
|
-
ref={setNodeRef}
|
|
29
|
+
ref={isDraggable ? setNodeRef : undefined}
|
|
30
30
|
style={style}
|
|
31
31
|
className={cn(styles.tableBodyCell, className, columnDef.cellClassName)}
|
|
32
32
|
data-row-auto-height={rowAutoHeight || undefined}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useSortable } from '@dnd-kit/sortable';
|
|
2
2
|
import { flexRender, Header } from '@tanstack/react-table';
|
|
3
3
|
import cn from 'classnames';
|
|
4
|
-
import { MouseEvent, useRef } from 'react';
|
|
4
|
+
import { MouseEvent, useMemo, useRef } from 'react';
|
|
5
5
|
|
|
6
6
|
import { TruncateString } from '@snack-uikit/truncate-string';
|
|
7
7
|
|
|
@@ -52,9 +52,16 @@ export function HeaderCell<TData>({
|
|
|
52
52
|
return header.column.getToggleSortingHandler()?.(e);
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
const draggableProps = useMemo(() => {
|
|
56
|
+
if (!isDraggable || DEFAULT_COLUMNS.includes(header.column.id)) {
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
...attributes,
|
|
62
|
+
...listeners,
|
|
63
|
+
};
|
|
64
|
+
}, [attributes, header.column.id, isDraggable, listeners]);
|
|
58
65
|
|
|
59
66
|
return (
|
|
60
67
|
<Cell
|
|
@@ -73,15 +80,16 @@ export function HeaderCell<TData>({
|
|
|
73
80
|
role='columnheader'
|
|
74
81
|
className={cn(styles.tableHeaderCell, className, columnDef.headerClassName)}
|
|
75
82
|
ref={element => {
|
|
76
|
-
|
|
83
|
+
if (isDraggable) {
|
|
84
|
+
setNodeRef(element);
|
|
85
|
+
}
|
|
77
86
|
return cellRef;
|
|
78
87
|
}}
|
|
79
88
|
>
|
|
80
89
|
<div
|
|
81
90
|
className={styles.tableHeaderCellDragWrapper}
|
|
82
|
-
data-dragging={isDragging || undefined}
|
|
83
|
-
{...
|
|
84
|
-
{...listenersAttributes}
|
|
91
|
+
data-dragging={(isDraggable && isDragging) || undefined}
|
|
92
|
+
{...draggableProps}
|
|
85
93
|
>
|
|
86
94
|
<div className={styles.tableHeaderCellMain}>
|
|
87
95
|
{columnDef.header && (
|
package/src/types.ts
CHANGED
|
@@ -63,11 +63,17 @@ type PinnedColumnDefinition<TData> = BaseColumnDefinition<TData> & {
|
|
|
63
63
|
size: number;
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
type FilterableProps =
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
type FilterableProps =
|
|
67
|
+
| {
|
|
68
|
+
id: string;
|
|
69
|
+
/** Название колонки в настройках таблицы */
|
|
70
|
+
headerConfigLabel?: string;
|
|
71
|
+
}
|
|
72
|
+
| {
|
|
73
|
+
accessorKey: string;
|
|
74
|
+
/** Название колонки в настройках таблицы */
|
|
75
|
+
headerConfigLabel?: string;
|
|
76
|
+
};
|
|
71
77
|
|
|
72
78
|
type FilterableNormalColumnDefinition<TData> = NormalColumnDefinition<TData> & FilterableProps;
|
|
73
79
|
|