@synerise/ds-table-new 1.0.1 → 1.0.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 +8 -0
- package/README.md +57 -1
- package/dist/Table.d.ts +1 -1
- package/dist/Table.js +29 -3
- package/dist/Table.styles.d.ts +0 -1
- package/dist/Table.styles.js +0 -5
- package/dist/Table.types.d.ts +164 -10
- package/dist/VirtualTable.d.ts +1 -1
- package/dist/VirtualTable.js +33 -3
- package/dist/components/BackToTopButton/BackToTopButton.d.ts +11 -0
- package/dist/components/BackToTopButton/BackToTopButton.js +34 -0
- package/dist/components/BackToTopButton/BackToTopButton.styles.d.ts +3 -0
- package/dist/components/BackToTopButton/BackToTopButton.styles.js +8 -0
- package/dist/components/BaseTable/BaseTable.d.ts +1 -1
- package/dist/components/BaseTable/BaseTable.js +10 -5
- package/dist/components/BaseTable/BaseTable.styles.js +1 -1
- package/dist/components/Cell/LabelsWithShowMore/Modal/Modal.js +9 -14
- package/dist/components/ItemsMenu/ItemsMenu.d.ts +7 -0
- package/dist/components/ItemsMenu/ItemsMenu.js +9 -0
- package/dist/components/ItemsMenu/ItemsMenu.styles.d.ts +3 -0
- package/dist/components/ItemsMenu/ItemsMenu.styles.js +10 -0
- package/dist/components/TableBody/TableBody.d.ts +1 -1
- package/dist/components/TableBody/TableBody.js +26 -5
- package/dist/components/TableBody/TableBody.styles.d.ts +4 -1
- package/dist/components/TableBody/TableBody.styles.js +2 -2
- package/dist/components/TableBody/TableCell/TableCell.d.ts +2 -1
- package/dist/components/TableBody/TableCell/TableCell.js +2 -1
- package/dist/components/TableBody/TableCell/TableCell.styles.d.ts +4 -1
- package/dist/components/TableBody/TableCell/TableCell.styles.js +7 -2
- package/dist/components/TableBody/TableRow/TableRow.js +2 -2
- package/dist/components/TableBody/TableRow/TableRowVirtual.js +3 -2
- package/dist/components/TableBody/TableRowSelection/TableRowSelection.js +2 -1
- package/dist/components/TableColumns/TableColumns.js +2 -1
- package/dist/components/TableColumns/TableColumns.styles.d.ts +4 -1
- package/dist/components/TableColumns/TableColumns.styles.js +7 -2
- package/dist/components/TableHeader/TableHeader.d.ts +1 -1
- package/dist/components/TableHeader/TableHeader.js +14 -6
- package/dist/components/TableHeader/TableHeaderSelection/TableHeaderSelection.js +37 -16
- package/dist/components/TableHeader/TableLimit/TableLimit.js +4 -3
- package/dist/components/TableHeader/TableLimit/TableLimit.styles.d.ts +0 -1
- package/dist/components/TableHeader/TableLimit/TableLimit.styles.js +0 -5
- package/dist/components/TableHorizontalScroll/TableHorizontalScroll.js +7 -11
- package/dist/components/TreeTable/TreeTable.d.ts +3 -0
- package/dist/components/TreeTable/TreeTable.js +106 -0
- package/dist/components/TreeTable/TreeTable.styles.d.ts +15 -0
- package/dist/components/TreeTable/TreeTable.styles.js +46 -0
- package/dist/components/TreeTable/TreeTable.types.d.ts +26 -0
- package/dist/components/TreeTable/TreeTable.types.js +1 -0
- package/dist/hooks/useDefaultTexts.js +19 -15
- package/dist/hooks/useTable.d.ts +7 -2
- package/dist/hooks/useTable.js +23 -2
- package/dist/hooks/useTableHighlight.d.ts +5 -0
- package/dist/hooks/useTableHighlight.js +33 -0
- package/dist/hooks/useTableSearch.d.ts +13 -0
- package/dist/hooks/useTableSearch.js +36 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/types/table.d.ts +1 -0
- package/dist/utils/legacyColumnConfigAdapter.d.ts +1 -1
- package/dist/utils/legacyColumnConfigAdapter.js +3 -3
- package/package.json +21 -22
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useState, useEffect, useMemo } from "react";
|
|
3
|
+
import { Expander } from "@synerise/ds-button";
|
|
4
|
+
import { theme } from "@synerise/ds-core";
|
|
5
|
+
import Icon, { ChildRowLeftDownM } from "@synerise/ds-icon";
|
|
6
|
+
import { Table } from "../../Table.js";
|
|
7
|
+
import { IndentBar, TreeCellWrapper, IndentsContainer, ExpanderWrapper, INDENT_SIZE, TreeTableRoot } from "./TreeTable.styles.js";
|
|
8
|
+
const getAllKeys = (data, childrenKey, getRowKey) => {
|
|
9
|
+
const keys = [];
|
|
10
|
+
const traverse = (rows) => {
|
|
11
|
+
for (const row of rows) {
|
|
12
|
+
keys.push(getRowKey(row));
|
|
13
|
+
const children = row[childrenKey];
|
|
14
|
+
if (children?.length) {
|
|
15
|
+
traverse(children);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
traverse(data);
|
|
20
|
+
return keys;
|
|
21
|
+
};
|
|
22
|
+
const TreeTable = ({
|
|
23
|
+
data,
|
|
24
|
+
columns,
|
|
25
|
+
childrenColumnName,
|
|
26
|
+
defaultExpandAllRows,
|
|
27
|
+
expandedRowKeys: controlledExpandedKeys,
|
|
28
|
+
onExpandRow,
|
|
29
|
+
expandIconColumnIndex = 0,
|
|
30
|
+
rowKey,
|
|
31
|
+
...props
|
|
32
|
+
}) => {
|
|
33
|
+
const childrenKey = childrenColumnName ?? "children";
|
|
34
|
+
const getRowKey = useCallback((row) => {
|
|
35
|
+
if (typeof rowKey === "function") {
|
|
36
|
+
return rowKey(row);
|
|
37
|
+
}
|
|
38
|
+
if (typeof rowKey === "string") {
|
|
39
|
+
return String(row[rowKey]);
|
|
40
|
+
}
|
|
41
|
+
return String(row.key ?? row.id ?? "");
|
|
42
|
+
}, [rowKey]);
|
|
43
|
+
const [internalExpandedKeys, setInternalExpandedKeys] = useState(() => {
|
|
44
|
+
if (defaultExpandAllRows) {
|
|
45
|
+
return getAllKeys(data, childrenKey, getRowKey);
|
|
46
|
+
}
|
|
47
|
+
return [];
|
|
48
|
+
});
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (defaultExpandAllRows) {
|
|
51
|
+
setInternalExpandedKeys(getAllKeys(data, childrenKey, getRowKey));
|
|
52
|
+
}
|
|
53
|
+
}, [data, defaultExpandAllRows, childrenKey, getRowKey]);
|
|
54
|
+
const expandedKeys = controlledExpandedKeys ?? internalExpandedKeys;
|
|
55
|
+
const toggleExpand = useCallback((key) => {
|
|
56
|
+
const isExpanded = expandedKeys.includes(key);
|
|
57
|
+
onExpandRow?.(key, !isExpanded);
|
|
58
|
+
if (!controlledExpandedKeys) {
|
|
59
|
+
setInternalExpandedKeys((prev) => isExpanded ? prev.filter((k) => k !== key) : [...prev, key]);
|
|
60
|
+
}
|
|
61
|
+
}, [expandedKeys, onExpandRow, controlledExpandedKeys]);
|
|
62
|
+
const hasChildren = useCallback((row) => {
|
|
63
|
+
const children = row[childrenKey];
|
|
64
|
+
return !!children?.length;
|
|
65
|
+
}, [childrenKey]);
|
|
66
|
+
const treeColumns = useMemo(() => {
|
|
67
|
+
if (!columns.length || expandIconColumnIndex < 0) {
|
|
68
|
+
return columns;
|
|
69
|
+
}
|
|
70
|
+
const targetIndex = Math.min(expandIconColumnIndex, columns.length - 1);
|
|
71
|
+
return columns.map((col, index) => {
|
|
72
|
+
if (index !== targetIndex) {
|
|
73
|
+
return col;
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
...col,
|
|
77
|
+
cell: (info) => {
|
|
78
|
+
const depth = info.row.depth;
|
|
79
|
+
const rowData = info.row.original;
|
|
80
|
+
const rowId = getRowKey(rowData);
|
|
81
|
+
const isParent = hasChildren(rowData);
|
|
82
|
+
const isExpanded = expandedKeys.includes(rowId);
|
|
83
|
+
const indents = Array.from({
|
|
84
|
+
length: depth
|
|
85
|
+
}, (_, i) => /* @__PURE__ */ jsx(IndentBar, { $level: i, $active: i + 1 === depth }, i));
|
|
86
|
+
const originalCell = typeof col.cell === "function" ? col.cell(info) : info.getValue();
|
|
87
|
+
return /* @__PURE__ */ jsxs(TreeCellWrapper, { $indentWidth: depth * INDENT_SIZE, children: [
|
|
88
|
+
depth > 0 && /* @__PURE__ */ jsx(IndentsContainer, { $depth: depth, children: indents }),
|
|
89
|
+
/* @__PURE__ */ jsx(ExpanderWrapper, { children: isParent ? /* @__PURE__ */ jsx(Expander, { expanded: isExpanded, onClick: (e) => {
|
|
90
|
+
e.stopPropagation();
|
|
91
|
+
toggleExpand(rowId);
|
|
92
|
+
} }) : depth > 0 ? /* @__PURE__ */ jsx(Icon, { component: /* @__PURE__ */ jsx(ChildRowLeftDownM, {}), color: theme.palette["grey-400"] }) : null }),
|
|
93
|
+
originalCell
|
|
94
|
+
] });
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}, [columns, expandIconColumnIndex, getRowKey, hasChildren, expandedKeys, toggleExpand]);
|
|
99
|
+
return /* @__PURE__ */ jsx(TreeTableRoot, { children: /* @__PURE__ */ jsx(Table, { data, columns: treeColumns, rowKey, expandable: {
|
|
100
|
+
childrenColumnName: childrenKey,
|
|
101
|
+
expandedRowKeys: expandedKeys
|
|
102
|
+
}, ...props }) });
|
|
103
|
+
};
|
|
104
|
+
export {
|
|
105
|
+
TreeTable
|
|
106
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare const INDENT_SIZE = 42;
|
|
2
|
+
declare const LEVEL_COLORS: string[];
|
|
3
|
+
export declare const IndentsContainer: import('styled-components').StyledComponent<"div", any, {
|
|
4
|
+
$depth: number;
|
|
5
|
+
}, never>;
|
|
6
|
+
export declare const IndentBar: import('styled-components').StyledComponent<"span", any, {
|
|
7
|
+
$level: number;
|
|
8
|
+
$active: boolean;
|
|
9
|
+
}, never>;
|
|
10
|
+
export declare const ExpanderWrapper: import('styled-components').StyledComponent<"span", any, {}, never>;
|
|
11
|
+
export declare const TreeCellWrapper: import('styled-components').StyledComponent<"div", any, {
|
|
12
|
+
$indentWidth: number;
|
|
13
|
+
}, never>;
|
|
14
|
+
export declare const TreeTableRoot: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
15
|
+
export { INDENT_SIZE, LEVEL_COLORS };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
const INDENT_SIZE = 42;
|
|
3
|
+
const LEVEL_COLORS = ["yellow", "green", "cyan", "violet", "orange", "purple", "blue", "grey"];
|
|
4
|
+
const getColorHue = (active, level) => {
|
|
5
|
+
if (level === LEVEL_COLORS.indexOf("cyan") && active) {
|
|
6
|
+
return "500";
|
|
7
|
+
}
|
|
8
|
+
return active ? "600" : "200";
|
|
9
|
+
};
|
|
10
|
+
const IndentsContainer = /* @__PURE__ */ styled.div.withConfig({
|
|
11
|
+
displayName: "TreeTablestyles__IndentsContainer",
|
|
12
|
+
componentId: "sc-1t443rr-0"
|
|
13
|
+
})(["position:absolute;top:0;left:36px;height:100%;width:", "px;display:flex;"], ({
|
|
14
|
+
$depth
|
|
15
|
+
}) => $depth * INDENT_SIZE);
|
|
16
|
+
const IndentBar = /* @__PURE__ */ styled.span.withConfig({
|
|
17
|
+
displayName: "TreeTablestyles__IndentBar",
|
|
18
|
+
componentId: "sc-1t443rr-1"
|
|
19
|
+
})(["width:", "px;position:relative;&:before{content:'';position:absolute;top:0;left:0;height:100%;width:2px;background-color:", ";}"], INDENT_SIZE, ({
|
|
20
|
+
$level,
|
|
21
|
+
$active,
|
|
22
|
+
theme
|
|
23
|
+
}) => $level >= 0 ? theme.palette[`${LEVEL_COLORS[$level % LEVEL_COLORS.length]}-${getColorHue($active, $level)}`] : theme.palette["grey-600"]);
|
|
24
|
+
const ExpanderWrapper = /* @__PURE__ */ styled.span.withConfig({
|
|
25
|
+
displayName: "TreeTablestyles__ExpanderWrapper",
|
|
26
|
+
componentId: "sc-1t443rr-2"
|
|
27
|
+
})(["display:inline-flex;align-items:center;justify-content:flex-start;width:24px;margin-right:8px;flex-shrink:0;"]);
|
|
28
|
+
const TreeCellWrapper = /* @__PURE__ */ styled.div.withConfig({
|
|
29
|
+
displayName: "TreeTablestyles__TreeCellWrapper",
|
|
30
|
+
componentId: "sc-1t443rr-3"
|
|
31
|
+
})(["display:flex;align-items:center;width:100%;padding-left:", "px;"], ({
|
|
32
|
+
$indentWidth
|
|
33
|
+
}) => $indentWidth);
|
|
34
|
+
const TreeTableRoot = /* @__PURE__ */ styled.div.withConfig({
|
|
35
|
+
displayName: "TreeTablestyles__TreeTableRoot",
|
|
36
|
+
componentId: "sc-1t443rr-4"
|
|
37
|
+
})(["td{position:relative;font-weight:500;}"]);
|
|
38
|
+
export {
|
|
39
|
+
ExpanderWrapper,
|
|
40
|
+
INDENT_SIZE,
|
|
41
|
+
IndentBar,
|
|
42
|
+
IndentsContainer,
|
|
43
|
+
LEVEL_COLORS,
|
|
44
|
+
TreeCellWrapper,
|
|
45
|
+
TreeTableRoot
|
|
46
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { TableProps } from '../../Table.types';
|
|
2
|
+
export type TreeTableProps<TData, TValue> = Omit<TableProps<TData, TValue>, 'expandable'> & {
|
|
3
|
+
/**
|
|
4
|
+
* Property name on row data containing child rows.
|
|
5
|
+
* @default 'children'
|
|
6
|
+
*/
|
|
7
|
+
childrenColumnName?: keyof TData;
|
|
8
|
+
/**
|
|
9
|
+
* Start with all rows expanded.
|
|
10
|
+
*/
|
|
11
|
+
defaultExpandAllRows?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Controlled expanded row keys. When provided, expand state is managed externally.
|
|
14
|
+
*/
|
|
15
|
+
expandedRowKeys?: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Called when a row's expand state changes (click on expander or row).
|
|
18
|
+
*/
|
|
19
|
+
onExpandRow?: (key: string, expanded: boolean) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Index of the column where the expand icon is rendered.
|
|
22
|
+
* Set to -1 to hide the expand icon entirely.
|
|
23
|
+
* @default 0
|
|
24
|
+
*/
|
|
25
|
+
expandIconColumnIndex?: number;
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -4,21 +4,25 @@ const useDefaultTexts = (defaultTexts) => {
|
|
|
4
4
|
const intl = useIntl();
|
|
5
5
|
return useMemo(() => ({
|
|
6
6
|
infiniteScrollLoading: intl.formatMessage({
|
|
7
|
-
id: "DS.TABLE.
|
|
7
|
+
id: "DS.TABLE.INFINITE_SCROLL.LOADING",
|
|
8
8
|
defaultMessage: "Loading"
|
|
9
9
|
}),
|
|
10
10
|
infiniteScrollError: intl.formatMessage({
|
|
11
|
-
id: "DS.TABLE.
|
|
11
|
+
id: "DS.TABLE.INFINITE_SCROLL.ERROR",
|
|
12
12
|
defaultMessage: "An error occurred"
|
|
13
13
|
}),
|
|
14
14
|
infiniteScrollRetry: intl.formatMessage({
|
|
15
|
-
id: "DS.TABLE.
|
|
15
|
+
id: "DS.TABLE.INFINITE_SCROLL.RETRY",
|
|
16
16
|
defaultMessage: "Retry"
|
|
17
17
|
}),
|
|
18
18
|
infiniteScrollNoMoreData: intl.formatMessage({
|
|
19
|
-
id: "DS.TABLE.
|
|
19
|
+
id: "DS.TABLE.INFINITE_SCROLL.NO_MORE_DATA",
|
|
20
20
|
defaultMessage: "There are no more items to load"
|
|
21
21
|
}),
|
|
22
|
+
infiniteScrollBackToTop: intl.formatMessage({
|
|
23
|
+
id: "DS.TABLE.INFINITE_SCROLL.BACK_TO_TOP",
|
|
24
|
+
defaultMessage: "Back to top"
|
|
25
|
+
}),
|
|
22
26
|
columnSortClear: intl.formatMessage({
|
|
23
27
|
id: "DS.TABLE.COLUMN.SORT_CLEAR",
|
|
24
28
|
defaultMessage: "Clear"
|
|
@@ -48,43 +52,43 @@ const useDefaultTexts = (defaultTexts) => {
|
|
|
48
52
|
defaultMessage: "selected"
|
|
49
53
|
}),
|
|
50
54
|
selectAll: intl.formatMessage({
|
|
51
|
-
id: "DS.TABLE.
|
|
55
|
+
id: "DS.TABLE.SELECT_ALL",
|
|
52
56
|
defaultMessage: "Select visible"
|
|
53
57
|
}),
|
|
54
58
|
selectAllTooltip: intl.formatMessage({
|
|
55
|
-
id: "DS.TABLE.
|
|
59
|
+
id: "DS.TABLE.SELECT_ALL_BUTTON_TOOLTIP",
|
|
56
60
|
defaultMessage: "Select all"
|
|
57
61
|
}),
|
|
58
62
|
selectGlobalAll: intl.formatMessage({
|
|
59
|
-
id: "DS.TABLE.
|
|
63
|
+
id: "DS.TABLE.SELECT_GLOBAL_ALL",
|
|
60
64
|
defaultMessage: "Select all"
|
|
61
65
|
}),
|
|
62
66
|
selectInvert: intl.formatMessage({
|
|
63
|
-
id: "DS.TABLE.
|
|
64
|
-
defaultMessage: "
|
|
67
|
+
id: "DS.TABLE.SELECT_INVERT",
|
|
68
|
+
defaultMessage: "Invert selection"
|
|
65
69
|
}),
|
|
66
70
|
selectionLimitWarning: intl.formatMessage({
|
|
67
|
-
id: "DS.TABLE.
|
|
71
|
+
id: "DS.TABLE.SELECTION_LIMIT",
|
|
68
72
|
defaultMessage: "You have reached max limit"
|
|
69
73
|
}),
|
|
70
74
|
selectionOptionsTooltip: intl.formatMessage({
|
|
71
|
-
id: "DS.TABLE.
|
|
75
|
+
id: "DS.TABLE.SELECTIONS_MENU_TOOLTIP",
|
|
72
76
|
defaultMessage: "Batch selection options"
|
|
73
77
|
}),
|
|
74
78
|
unselectAll: intl.formatMessage({
|
|
75
|
-
id: "DS.TABLE.
|
|
79
|
+
id: "DS.TABLE.UNSELECT_ALL",
|
|
76
80
|
defaultMessage: "Unselect visible"
|
|
77
81
|
}),
|
|
78
82
|
unselectGlobalAll: intl.formatMessage({
|
|
79
|
-
id: "DS.TABLE.
|
|
83
|
+
id: "DS.TABLE.UNSELECT_GLOBAL_ALL",
|
|
80
84
|
defaultMessage: "Unselect all"
|
|
81
85
|
}),
|
|
82
86
|
emptyText: intl.formatMessage({
|
|
83
|
-
id: "DS.TABLE.
|
|
87
|
+
id: "DS.TABLE.NO_DATA",
|
|
84
88
|
defaultMessage: "No data"
|
|
85
89
|
}),
|
|
86
90
|
selectRowTooltip: intl.formatMessage({
|
|
87
|
-
id: "DS.TABLE.
|
|
91
|
+
id: "DS.TABLE.SELECT_ROW_TOOLTIP",
|
|
88
92
|
defaultMessage: "Select"
|
|
89
93
|
}),
|
|
90
94
|
...defaultTexts
|
package/dist/hooks/useTable.d.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { MutableRefObject } from 'react';
|
|
2
2
|
import { SharedTableProps, TableProps, VirtualTableProps } from '../Table.types';
|
|
3
|
-
type UseTableProps<TData, TValue> = Pick<VirtualTableProps<TData, TValue>, 'infiniteScroll'> & Pick<TableProps<TData, TValue>, 'pagination'> & Pick<SharedTableProps<TData, TValue>, 'data' | 'selectionConfig' | 'columns' | 'rowKey' | 'onSort' | 'expandable' | 'selectedRowKeys'> & {
|
|
3
|
+
type UseTableProps<TData, TValue> = Pick<VirtualTableProps<TData, TValue>, 'infiniteScroll'> & Pick<TableProps<TData, TValue>, 'pagination'> & Pick<SharedTableProps<TData, TValue>, 'data' | 'selectionConfig' | 'columns' | 'rowKey' | 'onSort' | 'expandable' | 'selectedRowKeys' | 'matchesSearchQuery' | 'filterData' | 'onSearchQueryChange'> & {
|
|
4
4
|
wrapperRef: MutableRefObject<HTMLDivElement | null>;
|
|
5
5
|
requireColumnSizing?: boolean;
|
|
6
6
|
};
|
|
7
|
-
export declare const useTable: <TData, TValue>({ data, selectionConfig, columns, rowKey, wrapperRef, infiniteScroll, pagination, onSort, expandable, selectedRowKeys, requireColumnSizing, }: UseTableProps<TData, TValue>) => {
|
|
7
|
+
export declare const useTable: <TData, TValue>({ data, selectionConfig, columns, rowKey, wrapperRef, infiniteScroll, pagination, onSort, expandable, selectedRowKeys, matchesSearchQuery, filterData, onSearchQueryChange, requireColumnSizing, }: UseTableProps<TData, TValue>) => {
|
|
8
8
|
table: import('@tanstack/react-table').Table<TData>;
|
|
9
9
|
paginationProps: {} | {};
|
|
10
10
|
hasPagination: boolean;
|
|
11
11
|
columnSizing: import('@tanstack/react-table').ColumnSizingState;
|
|
12
12
|
isColumnSizingReady: boolean;
|
|
13
|
+
searchQuery: string;
|
|
14
|
+
setSearchQuery: (query: string) => void;
|
|
15
|
+
handleSearchClear: () => void;
|
|
16
|
+
hasBuiltInSearch: boolean;
|
|
17
|
+
totalDataCount: number;
|
|
13
18
|
};
|
|
14
19
|
export {};
|
package/dist/hooks/useTable.js
CHANGED
|
@@ -7,6 +7,7 @@ import { getChildrenColumnName } from "../utils/getChildrenColumnName.js";
|
|
|
7
7
|
import { getPaginationConfig } from "../utils/getPaginationConfig.js";
|
|
8
8
|
import { useColumnSizing } from "./useColumnSizing.js";
|
|
9
9
|
import { useRowKey } from "./useRowKey.js";
|
|
10
|
+
import { useTableSearch } from "./useTableSearch.js";
|
|
10
11
|
const useTable = ({
|
|
11
12
|
data,
|
|
12
13
|
selectionConfig,
|
|
@@ -18,6 +19,9 @@ const useTable = ({
|
|
|
18
19
|
onSort,
|
|
19
20
|
expandable,
|
|
20
21
|
selectedRowKeys,
|
|
22
|
+
matchesSearchQuery,
|
|
23
|
+
filterData,
|
|
24
|
+
onSearchQueryChange,
|
|
21
25
|
requireColumnSizing = true
|
|
22
26
|
}) => {
|
|
23
27
|
const [rowSelection, setRowSelection] = useState({});
|
|
@@ -33,6 +37,18 @@ const useTable = ({
|
|
|
33
37
|
useLayoutEffect(() => {
|
|
34
38
|
dataRef.current = data;
|
|
35
39
|
}, [data]);
|
|
40
|
+
const {
|
|
41
|
+
displayData,
|
|
42
|
+
searchQuery,
|
|
43
|
+
setSearchQuery,
|
|
44
|
+
handleClear: handleSearchClear,
|
|
45
|
+
hasBuiltInSearch
|
|
46
|
+
} = useTableSearch({
|
|
47
|
+
data,
|
|
48
|
+
matchesSearchQuery,
|
|
49
|
+
filterData,
|
|
50
|
+
onSearchQueryChange
|
|
51
|
+
});
|
|
36
52
|
const {
|
|
37
53
|
getRowKey
|
|
38
54
|
} = useRowKey(rowKey);
|
|
@@ -117,7 +133,7 @@ const useTable = ({
|
|
|
117
133
|
const expandedKeys = expandable?.expandedRowKeys ? arrayToTrueMap(expandable?.expandedRowKeys) : void 0;
|
|
118
134
|
const table = useReactTable({
|
|
119
135
|
getRowId: memoizedGetRowKey,
|
|
120
|
-
data,
|
|
136
|
+
data: displayData,
|
|
121
137
|
columns,
|
|
122
138
|
getSubRows: childrenColumnName ? getSubRows : void 0,
|
|
123
139
|
getCoreRowModel: getCoreRowModel(),
|
|
@@ -160,7 +176,12 @@ const useTable = ({
|
|
|
160
176
|
paginationProps,
|
|
161
177
|
hasPagination,
|
|
162
178
|
columnSizing,
|
|
163
|
-
isColumnSizingReady
|
|
179
|
+
isColumnSizingReady,
|
|
180
|
+
searchQuery,
|
|
181
|
+
setSearchQuery,
|
|
182
|
+
handleSearchClear,
|
|
183
|
+
hasBuiltInSearch,
|
|
184
|
+
totalDataCount: data.length
|
|
164
185
|
};
|
|
165
186
|
};
|
|
166
187
|
export {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
const HIGHLIGHT_CLASS = "ds-table-row-highlight";
|
|
3
|
+
const DEFAULT_HIGHLIGHT_DURATION = 600;
|
|
4
|
+
const useTableHighlight = (containerRef) => {
|
|
5
|
+
const highlightRow = useCallback((rowKey, options) => {
|
|
6
|
+
const container = containerRef.current;
|
|
7
|
+
if (!container) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const escapedKey = CSS.escape(rowKey);
|
|
11
|
+
const row = container.querySelector(`tr[data-key="${escapedKey}"], tr[data-row-key="${escapedKey}"]`);
|
|
12
|
+
if (!row) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const duration = options?.duration ?? DEFAULT_HIGHLIGHT_DURATION;
|
|
16
|
+
const el = row;
|
|
17
|
+
el.classList.remove(HIGHLIGHT_CLASS);
|
|
18
|
+
void el.offsetHeight;
|
|
19
|
+
el.style.setProperty("--ds-highlight-duration", `${duration}ms`);
|
|
20
|
+
el.classList.add(HIGHLIGHT_CLASS);
|
|
21
|
+
const onEnd = () => {
|
|
22
|
+
el.classList.remove(HIGHLIGHT_CLASS);
|
|
23
|
+
el.removeEventListener("animationend", onEnd);
|
|
24
|
+
};
|
|
25
|
+
el.addEventListener("animationend", onEnd);
|
|
26
|
+
}, [containerRef]);
|
|
27
|
+
return {
|
|
28
|
+
highlightRow
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
useTableHighlight
|
|
33
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SharedTableProps } from '../Table.types';
|
|
2
|
+
type UseTableSearchProps<TData> = Pick<SharedTableProps<TData, unknown>, 'matchesSearchQuery' | 'filterData' | 'onSearchQueryChange'> & {
|
|
3
|
+
data: TData[];
|
|
4
|
+
};
|
|
5
|
+
type UseTableSearchResult<TData> = {
|
|
6
|
+
displayData: TData[];
|
|
7
|
+
searchQuery: string;
|
|
8
|
+
setSearchQuery: (query: string) => void;
|
|
9
|
+
handleClear: () => void;
|
|
10
|
+
hasBuiltInSearch: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare const useTableSearch: <TData>({ data, matchesSearchQuery, filterData, onSearchQueryChange, }: UseTableSearchProps<TData>) => UseTableSearchResult<TData>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useState, useCallback, useMemo } from "react";
|
|
2
|
+
const useTableSearch = ({
|
|
3
|
+
data,
|
|
4
|
+
matchesSearchQuery,
|
|
5
|
+
filterData,
|
|
6
|
+
onSearchQueryChange
|
|
7
|
+
}) => {
|
|
8
|
+
const [searchQuery, setSearchQueryState] = useState("");
|
|
9
|
+
const hasBuiltInSearch = !!matchesSearchQuery;
|
|
10
|
+
const setSearchQuery = useCallback((query) => {
|
|
11
|
+
setSearchQueryState(query);
|
|
12
|
+
onSearchQueryChange?.(query);
|
|
13
|
+
}, [onSearchQueryChange]);
|
|
14
|
+
const handleClear = useCallback(() => {
|
|
15
|
+
setSearchQuery("");
|
|
16
|
+
}, [setSearchQuery]);
|
|
17
|
+
const displayData = useMemo(() => {
|
|
18
|
+
if (matchesSearchQuery && searchQuery) {
|
|
19
|
+
return data.filter((row) => matchesSearchQuery(searchQuery, row));
|
|
20
|
+
}
|
|
21
|
+
if (filterData) {
|
|
22
|
+
return data.filter(filterData);
|
|
23
|
+
}
|
|
24
|
+
return data;
|
|
25
|
+
}, [data, matchesSearchQuery, searchQuery, filterData]);
|
|
26
|
+
return {
|
|
27
|
+
displayData,
|
|
28
|
+
searchQuery,
|
|
29
|
+
setSearchQuery,
|
|
30
|
+
handleClear,
|
|
31
|
+
hasBuiltInSearch
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export {
|
|
35
|
+
useTableSearch
|
|
36
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export { Table } from './Table';
|
|
2
|
+
export { TreeTable } from './components/TreeTable/TreeTable';
|
|
2
3
|
export { VirtualTable } from './VirtualTable';
|
|
3
4
|
/** @deprecated */
|
|
4
5
|
export * as TableCell from './components/Cell';
|
|
5
6
|
export * from './components/Cell';
|
|
6
7
|
export * from './Table.types';
|
|
8
|
+
export type { TreeTableProps } from './components/TreeTable/TreeTable.types';
|
|
7
9
|
export * from './Table.const';
|
|
8
10
|
export { legacyColumnConfigAdapter } from './utils/legacyColumnConfigAdapter';
|
|
9
11
|
export { type ColumnDef, type Row, type CellContext, type HeaderContext, } from '@tanstack/react-table';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Table } from "./Table.js";
|
|
2
|
+
import { TreeTable } from "./components/TreeTable/TreeTable.js";
|
|
2
3
|
import { VirtualTable } from "./VirtualTable.js";
|
|
3
4
|
import * as components_Cell_index from "./components/Cell/index.js";
|
|
4
5
|
import { ACTION_COLUMN_ID, BOTTOM_BORDER_WIDTH, DEFAULT_CELL_HEIGHT, DEFAULT_PAGINATION_CONFIG, DEFAULT_STICKY_VALUE, EMPTY_SORT_STATE, EXPANDED_ROW_PROPERTY, INFINITE_LOADER_ITEM_HEIGHT, INFINITE_SCROLL_PADDING_START, INFINITE_SCROLL_TRIGGER_THRESHOLD, SELECTION_ALL, SELECTION_COLUMN_ID, SELECTION_INVERT } from "./Table.const.js";
|
|
@@ -45,6 +46,7 @@ export {
|
|
|
45
46
|
components_Cell_index as TableCell,
|
|
46
47
|
TagIconCell,
|
|
47
48
|
TagsGroupCell,
|
|
49
|
+
TreeTable,
|
|
48
50
|
VirtualTable,
|
|
49
51
|
legacyColumnConfigAdapter
|
|
50
52
|
};
|
package/dist/types/table.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ declare module '@tanstack/react-table' {
|
|
|
7
7
|
maxWidth?: number | string;
|
|
8
8
|
width?: number | string;
|
|
9
9
|
fixed?: 'left' | 'right';
|
|
10
|
+
align?: 'left' | 'center' | 'right';
|
|
10
11
|
style?: CSSProperties<HTMLTableHeaderCellElement>;
|
|
11
12
|
sortRender?: 'string' | 'default';
|
|
12
13
|
sortOrder?: 'ascend' | 'descend' | null;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { VirtualColumnType as LegacyColumnType } from '@synerise/ds-table';
|
|
2
1
|
import { ColumnDef } from '@tanstack/react-table';
|
|
2
|
+
import { LegacyColumnType } from '../Table.types';
|
|
3
3
|
export declare const legacyColumnConfigAdapter: <DataType, DataValue>(columns: Array<LegacyColumnType<DataType>>) => ColumnDef<DataType, DataValue>[];
|
|
@@ -11,7 +11,6 @@ const getSortStateApiAdapter = (headerContext) => {
|
|
|
11
11
|
});
|
|
12
12
|
return {
|
|
13
13
|
columnsSortState: legacyColumnSortState,
|
|
14
|
-
// get sort order for column by key
|
|
15
14
|
getColumnSortOrder: (key) => {
|
|
16
15
|
switch (headerContext.table.getColumn(key)?.getIsSorted()) {
|
|
17
16
|
case "asc":
|
|
@@ -48,10 +47,10 @@ const getSortingConfig = (sorter) => {
|
|
|
48
47
|
if (typeof sorter === "function") {
|
|
49
48
|
sortFn = sorter;
|
|
50
49
|
}
|
|
51
|
-
if ("compare" in sorter && sorter.compare) {
|
|
50
|
+
if (typeof sorter === "object" && "compare" in sorter && sorter.compare) {
|
|
52
51
|
sortFn = sorter.compare;
|
|
53
52
|
enableMultiSort = !!sorter.multiple;
|
|
54
|
-
multiSortOrder = sorter.multiple;
|
|
53
|
+
multiSortOrder = typeof sorter.multiple === "number" ? sorter.multiple : void 0;
|
|
55
54
|
}
|
|
56
55
|
return {
|
|
57
56
|
sortingFn: sortFn ? (rowA, rowB, _columnId) => {
|
|
@@ -84,6 +83,7 @@ const legacyColumnConfigAdapter = (columns) => {
|
|
|
84
83
|
maxWidth: column.maxWidth,
|
|
85
84
|
width: column.width,
|
|
86
85
|
fixed: column.fixed,
|
|
86
|
+
align: column.align,
|
|
87
87
|
sortOrder: column.sortOrder,
|
|
88
88
|
sortRender: typeof column.sortRender === "string" ? column.sortRender : void 0,
|
|
89
89
|
renderCustomSortButton: customSortRender,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synerise/ds-table-new",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "TableNew UI Component for the Synerise Design System",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"repository": "Synerise/synerise-design",
|
|
@@ -34,28 +34,27 @@
|
|
|
34
34
|
"types": "dist/index.d.ts",
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@floating-ui/react": "^0.27.16",
|
|
37
|
-
"@synerise/ds-badge": "^1.0.
|
|
38
|
-
"@synerise/ds-button": "^1.5.
|
|
39
|
-
"@synerise/ds-checkbox": "^1.2.
|
|
40
|
-
"@synerise/ds-copy-icon": "^1.2.
|
|
41
|
-
"@synerise/ds-dropdown": "^1.3.
|
|
37
|
+
"@synerise/ds-badge": "^1.0.47",
|
|
38
|
+
"@synerise/ds-button": "^1.5.21",
|
|
39
|
+
"@synerise/ds-checkbox": "^1.2.24",
|
|
40
|
+
"@synerise/ds-copy-icon": "^1.2.5",
|
|
41
|
+
"@synerise/ds-dropdown": "^1.3.6",
|
|
42
42
|
"@synerise/ds-flag": "^1.0.10",
|
|
43
|
-
"@synerise/ds-icon": "^1.
|
|
44
|
-
"@synerise/ds-inline-alert": "^1.1.
|
|
45
|
-
"@synerise/ds-input": "^1.7.
|
|
46
|
-
"@synerise/ds-input-number": "^1.2.
|
|
43
|
+
"@synerise/ds-icon": "^1.16.0",
|
|
44
|
+
"@synerise/ds-inline-alert": "^1.1.18",
|
|
45
|
+
"@synerise/ds-input": "^1.7.1",
|
|
46
|
+
"@synerise/ds-input-number": "^1.2.38",
|
|
47
47
|
"@synerise/ds-loader": "^1.0.15",
|
|
48
|
-
"@synerise/ds-modal": "^1.4.
|
|
49
|
-
"@synerise/ds-pagination": "^1.0.
|
|
50
|
-
"@synerise/ds-result": "^1.0.
|
|
51
|
-
"@synerise/ds-scrollbar": "^1.2.
|
|
52
|
-
"@synerise/ds-search": "^1.5.
|
|
53
|
-
"@synerise/ds-skeleton": "^1.0.
|
|
54
|
-
"@synerise/ds-
|
|
55
|
-
"@synerise/ds-
|
|
56
|
-
"@synerise/ds-
|
|
57
|
-
"@synerise/ds-
|
|
58
|
-
"@synerise/ds-typography": "^1.1.15",
|
|
48
|
+
"@synerise/ds-modal": "^1.4.5",
|
|
49
|
+
"@synerise/ds-pagination": "^1.0.56",
|
|
50
|
+
"@synerise/ds-result": "^1.0.52",
|
|
51
|
+
"@synerise/ds-scrollbar": "^1.2.20",
|
|
52
|
+
"@synerise/ds-search": "^1.5.14",
|
|
53
|
+
"@synerise/ds-skeleton": "^1.0.48",
|
|
54
|
+
"@synerise/ds-tag": "^1.4.21",
|
|
55
|
+
"@synerise/ds-tags": "^1.5.32",
|
|
56
|
+
"@synerise/ds-tooltip": "^1.4.13",
|
|
57
|
+
"@synerise/ds-typography": "^1.1.16",
|
|
59
58
|
"@synerise/ds-utils": "^1.8.0",
|
|
60
59
|
"@tanstack/react-table": "^8.21.3",
|
|
61
60
|
"@tanstack/react-virtual": "^3.13.12",
|
|
@@ -72,5 +71,5 @@
|
|
|
72
71
|
"react-intl": ">= 3.12.0 <= 6.8",
|
|
73
72
|
"styled-components": "^5.3.3"
|
|
74
73
|
},
|
|
75
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "16b12f75e97d9c416a5cb9ca38864e97ef4f1530"
|
|
76
75
|
}
|