@snack-uikit/table 0.29.0 → 0.30.1-preview-9a03a1c9.0
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 +11 -0
- package/README.md +2 -0
- package/dist/cjs/components/Table/Table.d.ts +1 -1
- package/dist/cjs/components/Table/Table.js +141 -104
- package/dist/cjs/components/Table/hooks/index.d.ts +1 -0
- package/dist/cjs/components/Table/hooks/index.js +2 -1
- package/dist/cjs/components/Table/hooks/useColumnOrderByDrag.d.ts +9 -0
- package/dist/cjs/components/Table/hooks/useColumnOrderByDrag.js +76 -0
- package/dist/cjs/components/Table/utils.js +6 -3
- package/dist/cjs/components/types.d.ts +2 -0
- package/dist/cjs/constants.d.ts +1 -0
- package/dist/cjs/constants.js +3 -2
- package/dist/cjs/helperComponents/Cells/BodyCell/BodyCell.d.ts +2 -1
- package/dist/cjs/helperComponents/Cells/BodyCell/BodyCell.js +13 -3
- package/dist/cjs/helperComponents/Cells/HeaderCell/DragHandle.d.ts +6 -0
- package/dist/cjs/helperComponents/Cells/HeaderCell/DragHandle.js +27 -0
- package/dist/cjs/helperComponents/Cells/HeaderCell/HeaderCell.d.ts +2 -1
- package/dist/cjs/helperComponents/Cells/HeaderCell/HeaderCell.js +22 -2
- package/dist/cjs/helperComponents/Cells/HeaderCell/styles.module.css +11 -0
- package/dist/cjs/helperComponents/Rows/BodyRow.d.ts +4 -1
- package/dist/cjs/helperComponents/Rows/BodyRow.js +30 -12
- package/dist/cjs/helperComponents/Rows/HeaderRow.d.ts +7 -1
- package/dist/cjs/helperComponents/Rows/HeaderRow.js +33 -13
- package/dist/cjs/helperComponents/hooks.d.ts +22 -13
- package/dist/cjs/helperComponents/hooks.js +63 -15
- package/dist/cjs/types.d.ts +5 -0
- package/dist/esm/components/Table/Table.d.ts +1 -1
- package/dist/esm/components/Table/Table.js +34 -25
- package/dist/esm/components/Table/hooks/index.d.ts +1 -0
- package/dist/esm/components/Table/hooks/index.js +1 -0
- package/dist/esm/components/Table/hooks/useColumnOrderByDrag.d.ts +9 -0
- package/dist/esm/components/Table/hooks/useColumnOrderByDrag.js +66 -0
- package/dist/esm/components/Table/utils.js +6 -3
- package/dist/esm/components/types.d.ts +2 -0
- package/dist/esm/constants.d.ts +1 -0
- package/dist/esm/constants.js +1 -0
- package/dist/esm/helperComponents/Cells/BodyCell/BodyCell.d.ts +2 -1
- package/dist/esm/helperComponents/Cells/BodyCell/BodyCell.js +7 -3
- package/dist/esm/helperComponents/Cells/HeaderCell/DragHandle.d.ts +6 -0
- package/dist/esm/helperComponents/Cells/HeaderCell/DragHandle.js +6 -0
- package/dist/esm/helperComponents/Cells/HeaderCell/HeaderCell.d.ts +2 -1
- package/dist/esm/helperComponents/Cells/HeaderCell/HeaderCell.js +13 -4
- package/dist/esm/helperComponents/Cells/HeaderCell/styles.module.css +11 -0
- package/dist/esm/helperComponents/Rows/BodyRow.d.ts +4 -1
- package/dist/esm/helperComponents/Rows/BodyRow.js +4 -3
- package/dist/esm/helperComponents/Rows/HeaderRow.d.ts +7 -1
- package/dist/esm/helperComponents/Rows/HeaderRow.js +4 -3
- package/dist/esm/helperComponents/hooks.d.ts +22 -13
- package/dist/esm/helperComponents/hooks.js +58 -15
- package/dist/esm/types.d.ts +5 -0
- package/package.json +6 -2
- package/src/components/Table/Table.tsx +151 -117
- package/src/components/Table/hooks/index.ts +1 -0
- package/src/components/Table/hooks/useColumnOrderByDrag.ts +100 -0
- package/src/components/Table/utils.ts +8 -3
- package/src/components/types.ts +3 -0
- package/src/constants.tsx +2 -0
- package/src/helperComponents/Cells/BodyCell/BodyCell.tsx +9 -2
- package/src/helperComponents/Cells/HeaderCell/DragHandle.tsx +18 -0
- package/src/helperComponents/Cells/HeaderCell/HeaderCell.tsx +19 -4
- package/src/helperComponents/Cells/HeaderCell/styles.module.scss +15 -4
- package/src/helperComponents/Rows/BodyRow.tsx +36 -9
- package/src/helperComponents/Rows/HeaderRow.tsx +51 -18
- package/src/helperComponents/Rows/styles.module.scss +2 -2
- package/src/helperComponents/hooks.ts +78 -15
- package/src/types.ts +6 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { KeyboardSensor, MouseSensor, TouchSensor, useSensor, useSensors } from '@dnd-kit/core';
|
|
2
|
+
import { arrayMove } from '@dnd-kit/sortable';
|
|
3
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
4
|
+
import { UNDRAGGABLE_COLUMNS } from '../../../constants';
|
|
5
|
+
function preparePinnedColumnsMap(tableColumns) {
|
|
6
|
+
return tableColumns.reduce((accMap, columnDefinition) => {
|
|
7
|
+
switch (columnDefinition.pinned) {
|
|
8
|
+
case 'left':
|
|
9
|
+
accMap[columnDefinition.id] = 'leftPinned';
|
|
10
|
+
break;
|
|
11
|
+
case 'right':
|
|
12
|
+
accMap[columnDefinition.id] = 'rightPinned';
|
|
13
|
+
break;
|
|
14
|
+
default:
|
|
15
|
+
}
|
|
16
|
+
return accMap;
|
|
17
|
+
}, {});
|
|
18
|
+
}
|
|
19
|
+
function prepareInitialState(tableColumns) {
|
|
20
|
+
return tableColumns.map(c => c.id).filter(id => !UNDRAGGABLE_COLUMNS.includes(id));
|
|
21
|
+
}
|
|
22
|
+
function prepareGroupedColumnOrderState(columnOrder, pinnedColumnsMap) {
|
|
23
|
+
return columnOrder.reduce((accState, columnId) => {
|
|
24
|
+
var _a;
|
|
25
|
+
if (UNDRAGGABLE_COLUMNS.includes(columnId)) {
|
|
26
|
+
return accState;
|
|
27
|
+
}
|
|
28
|
+
const groupName = (_a = pinnedColumnsMap[columnId]) !== null && _a !== void 0 ? _a : 'unpinned';
|
|
29
|
+
accState[groupName].push(columnId);
|
|
30
|
+
return accState;
|
|
31
|
+
}, {
|
|
32
|
+
leftPinned: [],
|
|
33
|
+
unpinned: [],
|
|
34
|
+
rightPinned: [],
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export function useColumnOrderByDrag(tableColumns) {
|
|
38
|
+
const [columnOrder, setColumnOrder] = useState(() => prepareInitialState(tableColumns));
|
|
39
|
+
const pinnedColumnsMap = useMemo(() => preparePinnedColumnsMap(tableColumns), [tableColumns]);
|
|
40
|
+
const groupedColumnOrderState = useMemo(() => prepareGroupedColumnOrderState(columnOrder, pinnedColumnsMap), [columnOrder, pinnedColumnsMap]);
|
|
41
|
+
const handleDragEnd = useCallback(({ active, over }) => {
|
|
42
|
+
if (active && over && active.id !== over.id) {
|
|
43
|
+
if (UNDRAGGABLE_COLUMNS.includes(over.id.toString())) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const activeGroup = pinnedColumnsMap[active.id.toString()];
|
|
47
|
+
const overGroup = pinnedColumnsMap[over.id.toString()];
|
|
48
|
+
if (activeGroup !== overGroup) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
setColumnOrder(columnOrder => {
|
|
52
|
+
const oldIndex = columnOrder.indexOf(active.id.toString());
|
|
53
|
+
const newIndex = columnOrder.indexOf(over.id.toString());
|
|
54
|
+
return arrayMove(columnOrder, oldIndex, newIndex);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}, [pinnedColumnsMap]);
|
|
58
|
+
const sensors = useSensors(useSensor(MouseSensor, {}), useSensor(TouchSensor, {}), useSensor(KeyboardSensor, {}));
|
|
59
|
+
return {
|
|
60
|
+
columnOrder,
|
|
61
|
+
setColumnOrder,
|
|
62
|
+
groupedColumnOrderState,
|
|
63
|
+
handleDragEnd,
|
|
64
|
+
sensors,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -3,10 +3,13 @@ export function getCurrentlyConfiguredHeaderWidth(id) {
|
|
|
3
3
|
if (isBrowser()) {
|
|
4
4
|
const cell = document.querySelector(`[data-header-id="${id}"]`);
|
|
5
5
|
const resizeHandler = cell === null || cell === void 0 ? void 0 : cell.querySelector('[data-test-id="table__header-cell-resize-handle-moving-part"]');
|
|
6
|
-
if (cell
|
|
6
|
+
if (cell) {
|
|
7
7
|
const { width } = cell.getBoundingClientRect();
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
if (resizeHandler) {
|
|
9
|
+
const offset = parseInt(resizeHandler.style.getPropertyValue('--offset'));
|
|
10
|
+
return width + offset;
|
|
11
|
+
}
|
|
12
|
+
return width;
|
|
10
13
|
}
|
|
11
14
|
}
|
|
12
15
|
return 0;
|
|
@@ -30,6 +30,8 @@ export type TableProps<TData extends object, TFilters extends FiltersState = Rec
|
|
|
30
30
|
state?: SortingState;
|
|
31
31
|
onChange?(state: SortingState): void;
|
|
32
32
|
};
|
|
33
|
+
/** Включение сортировки порядка столбцов вручную перетаскиванием */
|
|
34
|
+
enableColumnsOrderSortByDrag?: boolean;
|
|
33
35
|
/** Параметр отвечает за общие настройки раскрывающихся строк*/
|
|
34
36
|
expanding?: {
|
|
35
37
|
/** Метод отвечает за получение дочерних строк*/
|
package/dist/esm/constants.d.ts
CHANGED
package/dist/esm/constants.js
CHANGED
|
@@ -2,6 +2,7 @@ import { Cell as TableCell } from '@tanstack/react-table';
|
|
|
2
2
|
import { CellProps } from '../Cell';
|
|
3
3
|
type BodyCellProps<TData> = Omit<CellProps, 'style' | 'children'> & {
|
|
4
4
|
cell: TableCell<TData, unknown>;
|
|
5
|
+
isDraggable?: boolean;
|
|
5
6
|
};
|
|
6
|
-
export declare function BodyCell<TData>({ cell, className, ...props }: BodyCellProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function BodyCell<TData>({ cell, className, isDraggable, ...props }: BodyCellProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
7
8
|
export {};
|
|
@@ -10,6 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
import { useSortable } from '@dnd-kit/sortable';
|
|
13
14
|
import { flexRender } from '@tanstack/react-table';
|
|
14
15
|
import cn from 'classnames';
|
|
15
16
|
import { TEST_IDS } from '../../../constants';
|
|
@@ -17,8 +18,11 @@ import { useCellSizes } from '../../hooks';
|
|
|
17
18
|
import { Cell } from '../Cell';
|
|
18
19
|
import styles from './styles.module.css';
|
|
19
20
|
export function BodyCell(_a) {
|
|
20
|
-
var { cell, className } = _a, props = __rest(_a, ["cell", "className"]);
|
|
21
|
+
var { cell, className, isDraggable } = _a, props = __rest(_a, ["cell", "className", "isDraggable"]);
|
|
21
22
|
const columnDef = cell.column.columnDef;
|
|
22
|
-
const style = useCellSizes(cell);
|
|
23
|
-
|
|
23
|
+
const style = useCellSizes(cell, { isDraggable });
|
|
24
|
+
const { setNodeRef } = useSortable({
|
|
25
|
+
id: cell.column.id,
|
|
26
|
+
});
|
|
27
|
+
return (_jsx(Cell, Object.assign({}, props, { ref: setNodeRef, style: style, className: cn(styles.tableBodyCell, className, columnDef.cellClassName), "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()) })));
|
|
24
28
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { useSortable } from '@dnd-kit/sortable';
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
3
|
+
export type DragHandleProps = Pick<ReturnType<typeof useSortable>, 'attributes' | 'listeners'> & {
|
|
4
|
+
style?: CSSProperties;
|
|
5
|
+
};
|
|
6
|
+
export declare function DragHandle({ attributes, listeners }: DragHandleProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { KebabSVG } from '@snack-uikit/icons';
|
|
3
|
+
import styles from './styles.module.css';
|
|
4
|
+
export function DragHandle({ attributes, listeners }) {
|
|
5
|
+
return (_jsx("div", Object.assign({ className: styles.dragHandle }, attributes, listeners, { children: _jsx(KebabSVG, { className: styles.dragIcon }) })));
|
|
6
|
+
}
|
|
@@ -4,6 +4,7 @@ import { CellProps } from '../Cell';
|
|
|
4
4
|
type HeaderCellProps<TData> = Omit<CellProps, 'align' | 'children' | 'onClick' | 'style'> & {
|
|
5
5
|
header: Header<TData, unknown>;
|
|
6
6
|
pinPosition?: ColumnPinPosition;
|
|
7
|
+
isDraggable?: boolean;
|
|
7
8
|
};
|
|
8
|
-
export declare function HeaderCell<TData>({ header, pinPosition, className }: HeaderCellProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function HeaderCell<TData>({ header, pinPosition, isDraggable, className }: HeaderCellProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
9
10
|
export {};
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useSortable } from '@dnd-kit/sortable';
|
|
2
3
|
import { flexRender } from '@tanstack/react-table';
|
|
3
4
|
import cn from 'classnames';
|
|
4
5
|
import { useRef } from 'react';
|
|
5
6
|
import { TruncateString } from '@snack-uikit/truncate-string';
|
|
6
|
-
import { TEST_IDS } from '../../../constants';
|
|
7
|
+
import { TEST_IDS, UNDRAGGABLE_COLUMNS } from '../../../constants';
|
|
7
8
|
import { useCellSizes } from '../../hooks';
|
|
8
9
|
import { Cell } from '../Cell';
|
|
10
|
+
import { DragHandle } from './DragHandle';
|
|
9
11
|
import { getSortingIcon } from './helpers';
|
|
10
12
|
import { ResizeHandle } from './ResizeHandle';
|
|
11
13
|
import styles from './styles.module.css';
|
|
12
|
-
export function HeaderCell({ header, pinPosition, className }) {
|
|
14
|
+
export function HeaderCell({ header, pinPosition, isDraggable, className }) {
|
|
13
15
|
const cellRef = useRef(null);
|
|
14
16
|
const isSortable = header.column.getCanSort();
|
|
15
17
|
const isResizable = header.column.getCanResize();
|
|
@@ -19,12 +21,19 @@ export function HeaderCell({ header, pinPosition, className }) {
|
|
|
19
21
|
const columnSizingInfo = header.getContext().table.getState().columnSizingInfo;
|
|
20
22
|
const isSomeColumnResizing = columnSizingInfo.isResizingColumn;
|
|
21
23
|
const columnDef = header.column.columnDef;
|
|
22
|
-
const style = useCellSizes(header);
|
|
24
|
+
const style = useCellSizes(header, { isDraggable });
|
|
25
|
+
const { attributes, listeners, setNodeRef } = useSortable({
|
|
26
|
+
id: header.column.id,
|
|
27
|
+
});
|
|
23
28
|
const sortingHandler = (e) => {
|
|
24
29
|
var _a;
|
|
25
30
|
if (isSomeColumnResizing)
|
|
26
31
|
return;
|
|
27
32
|
return (_a = header.column.getToggleSortingHandler()) === null || _a === void 0 ? void 0 : _a(e);
|
|
28
33
|
};
|
|
29
|
-
|
|
34
|
+
const isAvailableForDrag = !UNDRAGGABLE_COLUMNS.includes(header.column.id);
|
|
35
|
+
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, role: 'columnheader', className: cn(styles.tableHeaderCell, className, columnDef.headerClassName), ref: element => {
|
|
36
|
+
setNodeRef(element);
|
|
37
|
+
return cellRef;
|
|
38
|
+
}, children: [_jsxs("div", { className: styles.tableHeaderCellMain, children: [columnDef.header && (_jsx("div", { className: styles.tableHeaderCellName, children: _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 }))] }), isAvailableForDrag && Boolean(isDraggable) && _jsx(DragHandle, { attributes: attributes, listeners: listeners }), Boolean(isResizable) && _jsx(ResizeHandle, { header: header, cellRef: cellRef })] }));
|
|
30
39
|
}
|
|
@@ -129,4 +129,15 @@
|
|
|
129
129
|
.tableHeaderIcon svg{
|
|
130
130
|
width:var(--size-icon-container-xs, 16px) !important;
|
|
131
131
|
height:var(--size-icon-container-xs, 16px) !important;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.dragHandle{
|
|
135
|
+
cursor:pointer;
|
|
136
|
+
display:flex;
|
|
137
|
+
flex-direction:row;
|
|
138
|
+
gap:2px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.dragIcon{
|
|
142
|
+
color:var(--sys-neutral-text-light, #8b8e9b);
|
|
132
143
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Row as TableRow } from '@tanstack/react-table';
|
|
2
2
|
import { MouseEvent } from 'react';
|
|
3
|
+
import { GroupedColumnOrderState } from '../../types';
|
|
3
4
|
export type RowInfo<TData> = {
|
|
4
5
|
id: string;
|
|
5
6
|
data: TData;
|
|
@@ -10,5 +11,7 @@ export type RowClickHandler<TData> = (e: MouseEvent<HTMLDivElement>, row: RowInf
|
|
|
10
11
|
export type BodyRowProps<TData> = {
|
|
11
12
|
row: TableRow<TData>;
|
|
12
13
|
onRowClick?: RowClickHandler<TData>;
|
|
14
|
+
groupedColumnOrderState: GroupedColumnOrderState;
|
|
15
|
+
enableColumnsOrderSortByDrag?: boolean;
|
|
13
16
|
};
|
|
14
|
-
export declare function BodyRow<TData>({ row, onRowClick }: BodyRowProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export declare function BodyRow<TData>({ row, onRowClick, groupedColumnOrderState, enableColumnsOrderSortByDrag, }: BodyRowProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { horizontalListSortingStrategy, SortableContext } from '@dnd-kit/sortable';
|
|
2
3
|
import { useState } from 'react';
|
|
3
4
|
import { COLUMN_PIN_POSITION, TEST_IDS } from '../../constants';
|
|
4
5
|
import { BodyCell } from '../Cells';
|
|
@@ -7,8 +8,8 @@ import { useRowCells } from '../hooks';
|
|
|
7
8
|
import { PinnedCells } from './PinnedCells';
|
|
8
9
|
import { Row } from './Row';
|
|
9
10
|
import styles from './styles.module.css';
|
|
10
|
-
export function BodyRow({ row, onRowClick }) {
|
|
11
|
-
const {
|
|
11
|
+
export function BodyRow({ row, onRowClick, groupedColumnOrderState, enableColumnsOrderSortByDrag, }) {
|
|
12
|
+
const { leftPinned, rightPinned, unpinned } = useRowCells(row, groupedColumnOrderState);
|
|
12
13
|
const [dropListOpened, setDropListOpen] = useState(false);
|
|
13
14
|
const disabled = !row.getCanSelect();
|
|
14
15
|
const handleRowClick = (e) => {
|
|
@@ -23,5 +24,5 @@ export function BodyRow({ row, onRowClick }) {
|
|
|
23
24
|
};
|
|
24
25
|
return (_jsx(RowContext.Provider, { value: { dropListOpened, setDropListOpen }, children: _jsxs(Row, { onClick: handleRowClick, "data-clickable": Boolean(onRowClick) || undefined, "data-disabled": disabled || undefined, "data-selected": row.getIsSelected() ||
|
|
25
26
|
(row.getIsSomeSelected() && !row.getCanMultiSelect() && !row.getIsExpanded()) ||
|
|
26
|
-
undefined, "data-actions-opened": dropListOpened || undefined, "data-test-id": TEST_IDS.bodyRow, "data-row-id": row.id, className: styles.bodyRow, children: [
|
|
27
|
+
undefined, "data-actions-opened": dropListOpened || undefined, "data-test-id": TEST_IDS.bodyRow, "data-row-id": row.id, className: styles.bodyRow, children: [leftPinned && (_jsx(PinnedCells, { position: COLUMN_PIN_POSITION.Left, children: leftPinned.map(cell => (_jsx(SortableContext, { items: groupedColumnOrderState.leftPinned, strategy: horizontalListSortingStrategy, children: _jsx(BodyCell, { cell: cell, isDraggable: enableColumnsOrderSortByDrag }, cell.id) }, cell.id))) })), unpinned.map(cell => (_jsx(SortableContext, { items: groupedColumnOrderState.unpinned, strategy: horizontalListSortingStrategy, children: _jsx(BodyCell, { cell: cell, isDraggable: enableColumnsOrderSortByDrag }, cell.id) }, cell.id))), rightPinned && (_jsx(PinnedCells, { position: COLUMN_PIN_POSITION.Right, children: rightPinned.map(cell => (_jsx(SortableContext, { items: groupedColumnOrderState.rightPinned, strategy: horizontalListSortingStrategy, children: _jsx(BodyCell, { cell: cell, isDraggable: enableColumnsOrderSortByDrag }, cell.id) }, cell.id))) }))] }) }));
|
|
27
28
|
}
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { GroupedColumnOrderState } from '../../types';
|
|
2
|
+
type Props = {
|
|
3
|
+
groupedColumnOrderState: GroupedColumnOrderState;
|
|
4
|
+
enableColumnsOrderSortByDrag?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare function HeaderRow({ groupedColumnOrderState, enableColumnsOrderSortByDrag }: Props): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { horizontalListSortingStrategy, SortableContext } from '@dnd-kit/sortable';
|
|
2
3
|
import { COLUMN_PIN_POSITION, TEST_IDS } from '../../constants';
|
|
3
4
|
import { HeaderCell } from '../Cells';
|
|
4
5
|
import { useHeaderGroups } from '../hooks';
|
|
5
6
|
import { PinnedCells } from './PinnedCells';
|
|
6
7
|
import { Row } from './Row';
|
|
7
8
|
import styles from './styles.module.css';
|
|
8
|
-
export function HeaderRow() {
|
|
9
|
-
const { leftPinned, unpinned, rightPinned } = useHeaderGroups();
|
|
10
|
-
return (_jsxs(Row, { className: styles.tableHeader, "data-test-id": TEST_IDS.headerRow, children: [leftPinned && (_jsx(PinnedCells, { position: COLUMN_PIN_POSITION.Left, children: leftPinned.map(headerGroup => headerGroup.headers.map(header => header.isPlaceholder ? null : _jsx(HeaderCell, { header: header }, header.id))) })), unpinned.map(headerGroup => headerGroup.headers.map(header => _jsx(HeaderCell, { header: header }, header.id))), rightPinned && (_jsx(PinnedCells, { position: COLUMN_PIN_POSITION.Right, children: rightPinned.map(headerGroup => headerGroup.headers.map(header => header.isPlaceholder ? null : (_jsx(HeaderCell, { header: header, pinPosition: COLUMN_PIN_POSITION.Right }, header.id)))) }))] }));
|
|
9
|
+
export function HeaderRow({ groupedColumnOrderState, enableColumnsOrderSortByDrag }) {
|
|
10
|
+
const { leftPinned, unpinned, rightPinned } = useHeaderGroups(groupedColumnOrderState);
|
|
11
|
+
return (_jsxs(Row, { className: styles.tableHeader, "data-test-id": TEST_IDS.headerRow, children: [leftPinned && (_jsx(SortableContext, { items: groupedColumnOrderState.leftPinned, strategy: horizontalListSortingStrategy, children: _jsx(PinnedCells, { position: COLUMN_PIN_POSITION.Left, children: leftPinned.map(headerGroup => headerGroup.headers.map(header => header.isPlaceholder ? null : (_jsx(HeaderCell, { header: header, isDraggable: enableColumnsOrderSortByDrag && groupedColumnOrderState.leftPinned.length > 1 }, header.id)))) }) })), _jsx(SortableContext, { items: groupedColumnOrderState.unpinned, strategy: horizontalListSortingStrategy, children: unpinned.map(headerGroup => headerGroup.headers.map(header => (_jsx(HeaderCell, { header: header, isDraggable: enableColumnsOrderSortByDrag && groupedColumnOrderState.unpinned.length > 1 }, header.id)))) }), rightPinned && (_jsx(SortableContext, { items: groupedColumnOrderState.rightPinned, strategy: horizontalListSortingStrategy, children: _jsx(PinnedCells, { position: COLUMN_PIN_POSITION.Right, children: rightPinned.map(headerGroup => headerGroup.headers.map(header => header.isPlaceholder ? null : (_jsx(HeaderCell, { header: header, pinPosition: COLUMN_PIN_POSITION.Right, isDraggable: enableColumnsOrderSortByDrag && groupedColumnOrderState.rightPinned.length > 1 }, header.id)))) }) }))] }));
|
|
11
12
|
}
|
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
import { Cell, Header, HeaderGroup, Row } from '@tanstack/react-table';
|
|
2
|
-
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
3
|
+
import { GroupedColumnOrderState } from '../types';
|
|
4
|
+
export declare function useHeaderGroups(groupedColumnOrderState: GroupedColumnOrderState): {
|
|
3
5
|
unpinned: HeaderGroup<any>[];
|
|
4
6
|
leftPinned?: undefined;
|
|
5
7
|
rightPinned?: undefined;
|
|
6
8
|
} | {
|
|
7
|
-
leftPinned:
|
|
8
|
-
|
|
9
|
+
leftPinned: {
|
|
10
|
+
headers: Header<unknown, unknown>[];
|
|
11
|
+
depth: number;
|
|
12
|
+
id: string;
|
|
13
|
+
}[] | undefined;
|
|
14
|
+
rightPinned: {
|
|
15
|
+
headers: Header<unknown, unknown>[];
|
|
16
|
+
depth: number;
|
|
17
|
+
id: string;
|
|
18
|
+
}[] | undefined;
|
|
9
19
|
unpinned: HeaderGroup<any>[];
|
|
10
20
|
};
|
|
11
|
-
export declare function useRowCells<TData>(row: Row<TData
|
|
21
|
+
export declare function useRowCells<TData>(row: Row<TData>, groupedColumnOrderState: GroupedColumnOrderState): {
|
|
12
22
|
unpinned: Cell<TData, unknown>[];
|
|
13
|
-
|
|
14
|
-
|
|
23
|
+
leftPinned?: undefined;
|
|
24
|
+
rightPinned?: undefined;
|
|
15
25
|
} | {
|
|
16
|
-
|
|
17
|
-
|
|
26
|
+
leftPinned: Cell<TData, unknown>[] | undefined;
|
|
27
|
+
rightPinned: Cell<TData, unknown>[] | undefined;
|
|
18
28
|
unpinned: Cell<TData, unknown>[];
|
|
19
29
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
width: string;
|
|
23
|
-
maxWidth: number | undefined;
|
|
24
|
-
flexShrink: string;
|
|
30
|
+
type CellSizesOptions = {
|
|
31
|
+
isDraggable?: boolean;
|
|
25
32
|
};
|
|
33
|
+
export declare function useCellSizes<TData>(element: Cell<TData, unknown> | Header<TData, unknown>, options?: CellSizesOptions): CSSProperties;
|
|
34
|
+
export {};
|
|
@@ -1,12 +1,23 @@
|
|
|
1
|
+
import { useSortable } from '@dnd-kit/sortable';
|
|
2
|
+
import { CSS } from '@dnd-kit/utilities';
|
|
1
3
|
import { useMemo } from 'react';
|
|
2
4
|
import { useTableContext } from './contexts';
|
|
3
5
|
function hasHeaders(groups) {
|
|
4
6
|
return groups.some(group => group.headers.length);
|
|
5
7
|
}
|
|
6
|
-
|
|
8
|
+
const sortHeaderGroup = (groups, groupOrder) => groups.map(group => (Object.assign(Object.assign({}, group), { headers: group.headers.sort((a, b) => {
|
|
9
|
+
const indexA = groupOrder.findIndex(columnId => columnId === a.id);
|
|
10
|
+
const indexB = groupOrder.findIndex(columnId => columnId === b.id);
|
|
11
|
+
if (indexA > -1 && indexB > -1) {
|
|
12
|
+
return indexA - indexB;
|
|
13
|
+
}
|
|
14
|
+
return 0;
|
|
15
|
+
}) })));
|
|
16
|
+
export function useHeaderGroups(groupedColumnOrderState) {
|
|
7
17
|
const { table } = useTableContext();
|
|
8
18
|
const columnDefs = table._getColumnDefs();
|
|
9
19
|
const pinEnabled = table.getIsSomeColumnsPinned();
|
|
20
|
+
const { columnOrder } = table.getState();
|
|
10
21
|
return useMemo(() => {
|
|
11
22
|
if (!pinEnabled) {
|
|
12
23
|
return {
|
|
@@ -16,18 +27,29 @@ export function useHeaderGroups() {
|
|
|
16
27
|
const left = table.getLeftHeaderGroups();
|
|
17
28
|
const right = table.getRightHeaderGroups();
|
|
18
29
|
return {
|
|
19
|
-
leftPinned: hasHeaders(left) ? left : undefined,
|
|
20
|
-
rightPinned: hasHeaders(right) ? right : undefined,
|
|
30
|
+
leftPinned: hasHeaders(left) ? sortHeaderGroup(left, groupedColumnOrderState.leftPinned) : undefined,
|
|
31
|
+
rightPinned: hasHeaders(right) ? sortHeaderGroup(right, groupedColumnOrderState.rightPinned) : undefined,
|
|
21
32
|
unpinned: table.getCenterHeaderGroups(),
|
|
22
33
|
};
|
|
23
34
|
// need to rebuild if columnDefinitions has changed
|
|
24
35
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
25
|
-
}, [table, pinEnabled, columnDefs]);
|
|
36
|
+
}, [table, pinEnabled, columnDefs, columnOrder, groupedColumnOrderState]);
|
|
37
|
+
}
|
|
38
|
+
function sortPinnedColumnsByOrderState(groupOrder) {
|
|
39
|
+
return (a, b) => {
|
|
40
|
+
const indexA = groupOrder.findIndex(columnId => columnId === a.column.id);
|
|
41
|
+
const indexB = groupOrder.findIndex(columnId => columnId === b.column.id);
|
|
42
|
+
if (indexA > -1 && indexB > -1) {
|
|
43
|
+
return indexA - indexB;
|
|
44
|
+
}
|
|
45
|
+
return 0;
|
|
46
|
+
};
|
|
26
47
|
}
|
|
27
|
-
export function useRowCells(row) {
|
|
48
|
+
export function useRowCells(row, groupedColumnOrderState) {
|
|
28
49
|
const { table } = useTableContext();
|
|
29
50
|
const pinEnabled = table.getIsSomeColumnsPinned();
|
|
30
51
|
const columnDefs = table._getColumnDefs();
|
|
52
|
+
const { columnOrder } = table.getState();
|
|
31
53
|
return useMemo(() => {
|
|
32
54
|
if (!pinEnabled) {
|
|
33
55
|
return {
|
|
@@ -37,24 +59,45 @@ export function useRowCells(row) {
|
|
|
37
59
|
const left = row.getLeftVisibleCells();
|
|
38
60
|
const right = row.getRightVisibleCells();
|
|
39
61
|
return {
|
|
40
|
-
|
|
41
|
-
|
|
62
|
+
leftPinned: left.length
|
|
63
|
+
? left.slice().sort(sortPinnedColumnsByOrderState(groupedColumnOrderState.leftPinned))
|
|
64
|
+
: undefined,
|
|
65
|
+
rightPinned: right.length
|
|
66
|
+
? right.slice().sort(sortPinnedColumnsByOrderState(groupedColumnOrderState.rightPinned))
|
|
67
|
+
: undefined,
|
|
42
68
|
unpinned: row.getCenterVisibleCells(),
|
|
43
69
|
};
|
|
44
70
|
// need to rebuild if columnDefinitions has changed
|
|
45
71
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
46
|
-
}, [row, pinEnabled, columnDefs]);
|
|
72
|
+
}, [row, pinEnabled, columnDefs, columnOrder, groupedColumnOrderState]);
|
|
47
73
|
}
|
|
48
|
-
export function useCellSizes(element) {
|
|
74
|
+
export function useCellSizes(element, options) {
|
|
49
75
|
const column = element.column;
|
|
76
|
+
const { isDragging, transform } = useSortable({
|
|
77
|
+
id: column.id,
|
|
78
|
+
});
|
|
50
79
|
const minWidth = column.columnDef.minSize;
|
|
51
80
|
const maxWidth = column.columnDef.maxSize;
|
|
52
81
|
const width = `var(--table-column-${column.id}-size)`;
|
|
53
82
|
const flexShrink = `var(--table-column-${column.id}-flex)`;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
83
|
+
const isHeaderCell = 'headerGroup' in element;
|
|
84
|
+
return useMemo(() => {
|
|
85
|
+
const styles = {
|
|
86
|
+
minWidth,
|
|
87
|
+
width,
|
|
88
|
+
maxWidth,
|
|
89
|
+
flexShrink,
|
|
90
|
+
};
|
|
91
|
+
if (options === null || options === void 0 ? void 0 : options.isDraggable) {
|
|
92
|
+
styles.opacity = isDragging ? 0.8 : 1;
|
|
93
|
+
styles.position = 'relative';
|
|
94
|
+
styles.transform = CSS.Translate.toString(transform);
|
|
95
|
+
styles.transition = 'width transform 0.2s ease-in-out';
|
|
96
|
+
styles.zIndex = isDragging ? 1 : 0;
|
|
97
|
+
if (isHeaderCell) {
|
|
98
|
+
styles.whiteSpace = 'nowrap';
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return styles;
|
|
102
|
+
}, [options === null || options === void 0 ? void 0 : options.isDraggable, flexShrink, isDragging, isHeaderCell, maxWidth, minWidth, transform, width]);
|
|
60
103
|
}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -40,5 +40,10 @@ type PinnedColumnDefinition<TData> = BaseColumnDefinition<TData> & {
|
|
|
40
40
|
size: number;
|
|
41
41
|
};
|
|
42
42
|
export type ColumnDefinition<TData> = NormalColumnDefinition<TData> | PinnedColumnDefinition<TData>;
|
|
43
|
+
export type GroupedColumnOrderState = {
|
|
44
|
+
leftPinned: string[];
|
|
45
|
+
rightPinned: string[];
|
|
46
|
+
unpinned: string[];
|
|
47
|
+
};
|
|
43
48
|
export type { RowActionsColumnDefProps, StatusColumnDefinitionProps, RowInfo, RowClickHandler, ActionsGenerator, CopyCellProps, MapStatusToAppearanceFnType, } from './helperComponents';
|
|
44
49
|
export type { ColumnPinPosition, PaginationState, SortingState, RowSelectionState, RowSelectionOptions, EmptyStateProps, ToolbarProps, HeaderContext, CellContext, };
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Table",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.30.1-preview-9a03a1c9.0",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -36,6 +36,10 @@
|
|
|
36
36
|
"license": "Apache-2.0",
|
|
37
37
|
"scripts": {},
|
|
38
38
|
"dependencies": {
|
|
39
|
+
"@dnd-kit/core": "6.3.1",
|
|
40
|
+
"@dnd-kit/modifiers": "9.0.0",
|
|
41
|
+
"@dnd-kit/sortable": "10.0.0",
|
|
42
|
+
"@dnd-kit/utilities": "3.2.2",
|
|
39
43
|
"@snack-uikit/button": "0.19.7",
|
|
40
44
|
"@snack-uikit/chips": "0.25.3",
|
|
41
45
|
"@snack-uikit/icon-predefined": "0.7.3",
|
|
@@ -61,5 +65,5 @@
|
|
|
61
65
|
"peerDependencies": {
|
|
62
66
|
"@snack-uikit/locale": "*"
|
|
63
67
|
},
|
|
64
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "a7e76287bbbbb376afb7bc895cfa1e125751608f"
|
|
65
69
|
}
|