@snack-uikit/table 0.14.7-preview-da21d728.0 → 0.14.7

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 CHANGED
@@ -3,6 +3,16 @@
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.14.7 (2024-02-27)
7
+
8
+ ### Only dependencies have been changed
9
+ * [@snack-uikit/list@0.5.0](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/list/CHANGELOG.md)
10
+ * [@snack-uikit/toolbar@0.7.15](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/toolbar/CHANGELOG.md)
11
+
12
+
13
+
14
+
15
+
6
16
  ## 0.14.6 (2024-02-26)
7
17
 
8
18
 
@@ -23,7 +23,7 @@ export function ServerTable(_a) {
23
23
  const [tempSearch, setTempSearch] = useState(search || '');
24
24
  const handleSearch = useCallback((newValue) => {
25
25
  setTempSearch(newValue);
26
- onSearchDebounced(newValue.trim(), setSearch);
26
+ onSearchDebounced()(newValue.trim(), setSearch);
27
27
  }, [setSearch]);
28
28
  const handlePageChange = useCallback(({ pageSize, pageIndex }) => onChangePage(pageIndex * pageSize, pageSize), [onChangePage]);
29
29
  const pageIndex = useMemo(() => Math.floor(offset / limit), [limit, offset]);
@@ -1,2 +1,2 @@
1
1
  /// <reference types="lodash" />
2
- export declare const onSearchDebounced: import("lodash").DebouncedFunc<(newValue: string, onChange: (newValue: string) => void) => void>;
2
+ export declare function onSearchDebounced(): import("lodash").DebouncedFunc<(newValue: string, onChange: (newValue: string) => void) => void>;
@@ -1,5 +1,7 @@
1
1
  import debounce from 'lodash.debounce';
2
2
  import { SEARCH_DELAY } from './constants';
3
- export const onSearchDebounced = debounce((newValue, onChange) => {
4
- onChange(newValue);
5
- }, SEARCH_DELAY);
3
+ export function onSearchDebounced() {
4
+ return debounce((newValue, onChange) => {
5
+ onChange(newValue);
6
+ }, SEARCH_DELAY);
7
+ }
@@ -1,6 +1,6 @@
1
1
  import { TableProps } from '../types';
2
2
  /** Компонент таблицы */
3
- export declare function Table<TData extends object>({ data, columnDefinitions, rowSelection: rowSelectionProp, search, sorting: sortingProp, columnFilters, pagination: paginationProp, className, onRowClick, onRefresh, onDelete, pageSize, pageCount, loading, outline, moreActions, exportFileName, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar, toolbarBefore, toolbarAfter, suppressPagination, manualSorting, manualPagination, manualFiltering, scrollRef, scrollContainerRef, ...rest }: TableProps<TData>): import("react/jsx-runtime").JSX.Element;
3
+ export declare function Table<TData extends object>({ data, columnDefinitions, rowSelection, search, sorting, columnFilters, pagination, className, onRowClick, onRefresh, onDelete, pageSize, pageCount, loading, outline, moreActions, exportFileName, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar, toolbarBefore, toolbarAfter, suppressPagination, manualSorting, manualPagination, manualFiltering, scrollRef, scrollContainerRef, ...rest }: TableProps<TData>): import("react/jsx-runtime").JSX.Element;
4
4
  export declare namespace Table {
5
5
  var getStatusColumnDef: typeof import("../../helperComponents").getStatusColumnDef;
6
6
  var statusAppearances: {
@@ -10,87 +10,31 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
13
- import { getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable, } from '@tanstack/react-table';
14
13
  import cn from 'classnames';
15
14
  import { useCallback, useEffect, useMemo } from 'react';
16
15
  import { useLocale } from '@snack-uikit/locale';
17
16
  import { Scroll } from '@snack-uikit/scroll';
18
17
  import { SkeletonContextProvider } from '@snack-uikit/skeleton';
19
18
  import { Toolbar } from '@snack-uikit/toolbar';
20
- import { TruncateString } from '@snack-uikit/truncate-string';
21
19
  import { extractSupportProps } from '@snack-uikit/utils';
22
20
  import { DEFAULT_PAGE_SIZE } from '../../constants';
23
- import { BodyRow, ExportButton, getColumnId, getRowActionsColumnDef, getSelectionCellColumnDef, getStatusColumnDef, HeaderRow, STATUS_APPEARANCE, TableContext, TableEmptyState, TablePagination, useEmptyState, } from '../../helperComponents';
24
- import { fuzzyFilter } from '../../utils';
25
- import { useLoadingTable } from './hooks';
26
- import { useStateControl } from './hooks/useStateControl';
21
+ import { BodyRow, ExportButton, getColumnId, getRowActionsColumnDef, getStatusColumnDef, HeaderRow, STATUS_APPEARANCE, TableContext, TableEmptyState, TablePagination, useEmptyState, } from '../../helperComponents';
22
+ import { useLoadingTable, useTable } from './hooks';
27
23
  import styles from './styles.module.css';
28
24
  /** Компонент таблицы */
29
25
  export function Table(_a) {
30
- var { data, columnDefinitions, rowSelection: rowSelectionProp, search, sorting: sortingProp, columnFilters, pagination: paginationProp, className, onRowClick, onRefresh, onDelete, pageSize = DEFAULT_PAGE_SIZE, pageCount, loading = false, outline = false, moreActions, exportFileName, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar = false, toolbarBefore, toolbarAfter, suppressPagination = false, manualSorting = false, manualPagination = false, manualFiltering = false, scrollRef, scrollContainerRef } = _a, rest = __rest(_a, ["data", "columnDefinitions", "rowSelection", "search", "sorting", "columnFilters", "pagination", "className", "onRowClick", "onRefresh", "onDelete", "pageSize", "pageCount", "loading", "outline", "moreActions", "exportFileName", "dataFiltered", "dataError", "noDataState", "noResultsState", "errorDataState", "suppressToolbar", "toolbarBefore", "toolbarAfter", "suppressPagination", "manualSorting", "manualPagination", "manualFiltering", "scrollRef", "scrollContainerRef"]);
31
- const { state: globalFilter, onStateChange: onGlobalFilterChange } = useStateControl(search, '');
32
- const { state: rowSelection, onStateChange: onRowSelectionChange } = useStateControl(rowSelectionProp, {});
33
- const defaultPaginationState = useMemo(() => ({
34
- pageIndex: 0,
35
- pageSize,
36
- }), [pageSize]);
37
- const { state: sorting, onStateChange: onSortingChange } = useStateControl(sortingProp, []);
38
- const { state: pagination, onStateChange: onPaginationChange } = useStateControl(paginationProp, defaultPaginationState);
39
- const enableSelection = Boolean(rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable);
40
- const tableColumns = useMemo(() => {
41
- let cols = columnDefinitions;
42
- if (enableSelection) {
43
- cols = [getSelectionCellColumnDef(), ...cols];
44
- }
45
- return cols;
46
- }, [columnDefinitions, enableSelection]);
47
- const columnPinning = useMemo(() => {
48
- var _a;
49
- const pinningState = { left: [], right: [] };
50
- for (const col of tableColumns) {
51
- const id = getColumnId(col);
52
- if (col.pinned && id) {
53
- (_a = pinningState[col.pinned]) === null || _a === void 0 ? void 0 : _a.push(id);
54
- }
55
- }
56
- return pinningState;
57
- }, [tableColumns]);
58
- const table = useReactTable({
26
+ var { data, columnDefinitions, rowSelection, search, sorting, columnFilters, pagination, className, onRowClick, onRefresh, onDelete, pageSize = DEFAULT_PAGE_SIZE, pageCount, loading = false, outline = false, moreActions, exportFileName, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar = false, toolbarBefore, toolbarAfter, suppressPagination = false, manualSorting = false, manualPagination = false, manualFiltering = false, scrollRef, scrollContainerRef } = _a, rest = __rest(_a, ["data", "columnDefinitions", "rowSelection", "search", "sorting", "columnFilters", "pagination", "className", "onRowClick", "onRefresh", "onDelete", "pageSize", "pageCount", "loading", "outline", "moreActions", "exportFileName", "dataFiltered", "dataError", "noDataState", "noResultsState", "errorDataState", "suppressToolbar", "toolbarBefore", "toolbarAfter", "suppressPagination", "manualSorting", "manualPagination", "manualFiltering", "scrollRef", "scrollContainerRef"]);
27
+ const { table, tableColumns, columnPinning } = useTable({
59
28
  data,
60
- columns: tableColumns,
61
- state: {
62
- columnPinning,
63
- globalFilter,
64
- rowSelection,
65
- sorting,
66
- pagination,
67
- },
68
- pageCount,
69
- defaultColumn: {
70
- enableSorting: false,
71
- enableResizing: false,
72
- minSize: 40,
73
- cell: (cell) => _jsx(TruncateString, { text: String(cell.getValue()), maxLines: 1 }),
74
- },
75
- manualSorting,
76
- manualPagination,
29
+ sorting,
77
30
  manualFiltering,
78
- globalFilterFn: fuzzyFilter,
79
- onGlobalFilterChange,
80
- onRowSelectionChange,
81
- enableRowSelection: rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable,
82
- enableMultiRowSelection: rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow,
83
- enableFilters: true,
84
- getFilteredRowModel: getFilteredRowModel(),
85
- enableColumnResizing: true,
86
- enableSorting: true,
87
- enableMultiSort: true,
88
- onSortingChange,
89
- getSortedRowModel: getSortedRowModel(),
90
- onPaginationChange,
91
- getPaginationRowModel: getPaginationRowModel(),
92
- getCoreRowModel: getCoreRowModel(),
93
- columnResizeMode: 'onEnd',
31
+ manualPagination,
32
+ manualSorting,
33
+ columnDefinitions,
34
+ rowSelection,
35
+ pagination,
36
+ pageCount,
37
+ pageSize,
94
38
  });
95
39
  const { loadingTable } = useLoadingTable({ pageSize, columnDefinitions: tableColumns, columnPinning });
96
40
  const handleOnRefresh = useCallback(() => {
@@ -106,7 +50,7 @@ export function Table(_a) {
106
50
  }
107
51
  }, [loading, onDelete, table]);
108
52
  const handleOnCheck = useCallback(() => {
109
- if (!loading && (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow)) {
53
+ if (!loading && (rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.multiRow)) {
110
54
  table.toggleAllPageRowsSelected();
111
55
  return;
112
56
  }
@@ -114,7 +58,7 @@ export function Table(_a) {
114
58
  table.resetRowSelection();
115
59
  return;
116
60
  }
117
- }, [loading, rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow, table]);
61
+ }, [loading, rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.multiRow, table]);
118
62
  useEffect(() => { }, []);
119
63
  const columnSizeVars = useMemo(() => {
120
64
  const originalColumnDefs = table._getColumnDefs();
@@ -148,14 +92,16 @@ export function Table(_a) {
148
92
  const tempPageSize = !suppressPagination ? tablePagination === null || tablePagination === void 0 ? void 0 : tablePagination.pageSize : pageSize;
149
93
  return !tableRows.length ? Math.min(Math.max(tempPageSize, 5), DEFAULT_PAGE_SIZE) : tempPageSize;
150
94
  }, [pageSize, suppressPagination, tablePagination === null || tablePagination === void 0 ? void 0 : tablePagination.pageSize, tableRows.length]);
95
+ const enableSelection = Boolean(rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.enable);
151
96
  return (_jsx(_Fragment, { children: _jsxs("div", Object.assign({ style: {
152
97
  '--page-size': cssPageSize,
98
+ // width: table.getTotalSize(),
153
99
  }, className: cn(styles.wrapper, className) }, extractSupportProps(rest), { children: [!suppressToolbar && (_jsxs("div", { className: styles.header, children: [_jsx(Toolbar, { search: {
154
- value: globalFilter,
155
- onChange: onGlobalFilterChange,
100
+ value: table.getState().globalFilter,
101
+ onChange: table.setGlobalFilter,
156
102
  loading: search === null || search === void 0 ? void 0 : search.loading,
157
103
  placeholder: (search === null || search === void 0 ? void 0 : search.placeholder) || t('searchPlaceholder'),
158
- }, checked: table.getIsAllPageRowsSelected(), indeterminate: table.getIsSomePageRowsSelected(), className: styles.toolbar, onRefresh: onRefresh ? handleOnRefresh : undefined, onDelete: enableSelection && onDelete ? handleOnDelete : undefined, onCheck: enableSelection ? handleOnCheck : undefined, outline: outline, selectionMode: (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow) ? 'multiple' : 'single', before: toolbarBefore, after: _jsxs(_Fragment, { children: [toolbarAfter, exportFileName ? (_jsx(ExportButton, { fileName: exportFileName, columnDefinitions: columnDefinitions, data: data })) : undefined] }), moreActions: moreActions }), columnFilters && _jsxs("div", { className: styles.filtersWrapper, children: [" ", columnFilters, " "] })] })), _jsx("div", { className: styles.scrollWrapper, "data-outline": outline || undefined, children: _jsxs(Scroll, { size: 's', className: styles.table, ref: scrollContainerRef, children: [_jsx("div", { className: styles.tableContent, style: columnSizeVars, children: _jsx(TableContext.Provider, { value: { table }, children: loading ? (_jsxs(SkeletonContextProvider, { loading: true, children: [_jsx(HeaderRow, {}), loadingTableRows.map(row => (_jsx(BodyRow, { row: row }, row.id)))] })) : (_jsxs(_Fragment, { children: [tableRows.length ? _jsx(HeaderRow, {}) : null, tableRows.map(row => (_jsx(BodyRow, { row: row, onRowClick: onRowClick }, row.id))), _jsx(TableEmptyState, { emptyStates: emptyStates, dataError: dataError, dataFiltered: dataFiltered || Boolean(table.getState().globalFilter), tableRowsLength: tableRows.length })] })) }) }), _jsx("div", { className: styles.scrollStub, ref: scrollRef })] }) }), !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 }))] })) }));
104
+ }, checked: table.getIsAllPageRowsSelected(), indeterminate: table.getIsSomePageRowsSelected(), className: styles.toolbar, onRefresh: onRefresh ? handleOnRefresh : undefined, onDelete: enableSelection && onDelete ? handleOnDelete : undefined, onCheck: enableSelection ? handleOnCheck : undefined, outline: outline, selectionMode: (rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.multiRow) ? 'multiple' : 'single', before: toolbarBefore, after: _jsxs(_Fragment, { children: [toolbarAfter, exportFileName ? (_jsx(ExportButton, { fileName: exportFileName, columnDefinitions: columnDefinitions, data: data })) : undefined] }), moreActions: moreActions }), columnFilters && _jsxs("div", { className: styles.filtersWrapper, children: [" ", columnFilters, " "] })] })), _jsx("div", { className: styles.scrollWrapper, "data-outline": outline || undefined, children: _jsxs(Scroll, { size: 's', className: styles.table, ref: scrollContainerRef, children: [_jsx("div", { className: styles.tableContent, style: columnSizeVars, children: _jsx(TableContext.Provider, { value: { table }, children: loading ? (_jsxs(SkeletonContextProvider, { loading: true, children: [_jsx(HeaderRow, {}), loadingTableRows.map(row => (_jsx(BodyRow, { row: row }, row.id)))] })) : (_jsxs(_Fragment, { children: [tableRows.length ? _jsx(HeaderRow, {}) : null, tableRows.map(row => (_jsx(BodyRow, { row: row, onRowClick: onRowClick }, row.id))), _jsx(TableEmptyState, { emptyStates: emptyStates, dataError: dataError, dataFiltered: dataFiltered || Boolean(table.getState().globalFilter), tableRowsLength: tableRows.length })] })) }) }), _jsx("div", { className: styles.scrollStub, ref: scrollRef })] }) }), !suppressPagination && (_jsx(TablePagination, { table: table, options: pagination === null || pagination === void 0 ? void 0 : pagination.options, optionsLabel: pagination === null || pagination === void 0 ? void 0 : pagination.optionsLabel, pageCount: pageCount }))] })) }));
159
105
  }
160
106
  Table.getStatusColumnDef = getStatusColumnDef;
161
107
  Table.statusAppearances = STATUS_APPEARANCE;
@@ -1 +1,2 @@
1
1
  export * from './useLoadingTable';
2
+ export * from './useTable';
@@ -1 +1,2 @@
1
1
  export * from './useLoadingTable';
2
+ export * from './useTable';
@@ -0,0 +1,10 @@
1
+ import { ColumnPinningState } from '@tanstack/react-table';
2
+ import { ColumnDefinition } from '../../../types';
3
+ import { TableProps } from '../../types';
4
+ type UseTableProps<TData extends object> = Pick<TableProps<TData>, 'search' | 'rowSelection' | 'sorting' | 'pagination' | 'pageSize' | 'columnDefinitions' | 'data' | 'manualFiltering' | 'manualSorting' | 'manualPagination' | 'pageCount'>;
5
+ export declare function useTable<TData extends object>({ search, pageSize, pagination: paginationProp, rowSelection: rowSelectionProp, sorting: sortingProp, columnDefinitions, manualFiltering, manualPagination, manualSorting, pageCount, data, }: UseTableProps<TData>): {
6
+ table: import("@tanstack/react-table").Table<TData>;
7
+ tableColumns: ColumnDefinition<TData>[];
8
+ columnPinning: Required<ColumnPinningState>;
9
+ };
10
+ export {};
@@ -0,0 +1,75 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable, } from '@tanstack/react-table';
3
+ import { useMemo } from 'react';
4
+ import { TruncateString } from '@snack-uikit/truncate-string';
5
+ import { DEFAULT_PAGE_SIZE } from '../../../constants';
6
+ import { getColumnId, getSelectionCellColumnDef } from '../../../helperComponents';
7
+ import { fuzzyFilter } from '../../../utils';
8
+ import { useStateControl } from './useStateControl';
9
+ export function useTable({ search, pageSize = DEFAULT_PAGE_SIZE, pagination: paginationProp, rowSelection: rowSelectionProp, sorting: sortingProp, columnDefinitions, manualFiltering, manualPagination, manualSorting, pageCount, data, }) {
10
+ const { state: globalFilter, onStateChange: onGlobalFilterChange } = useStateControl(search, '');
11
+ const { state: rowSelection, onStateChange: onRowSelectionChange } = useStateControl(rowSelectionProp, {});
12
+ const defaultPaginationState = useMemo(() => ({
13
+ pageIndex: 0,
14
+ pageSize,
15
+ }), [pageSize]);
16
+ const { state: sorting, onStateChange: onSortingChange } = useStateControl(sortingProp, []);
17
+ const { state: pagination, onStateChange: onPaginationChange } = useStateControl(paginationProp, defaultPaginationState);
18
+ const enableSelection = Boolean(rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable);
19
+ const tableColumns = useMemo(() => {
20
+ let cols = columnDefinitions;
21
+ if (enableSelection) {
22
+ cols = [getSelectionCellColumnDef(), ...cols];
23
+ }
24
+ return cols;
25
+ }, [columnDefinitions, enableSelection]);
26
+ const columnPinning = useMemo(() => {
27
+ var _a;
28
+ const pinningState = { left: [], right: [] };
29
+ for (const col of tableColumns) {
30
+ const id = getColumnId(col);
31
+ if (col.pinned && id) {
32
+ (_a = pinningState[col.pinned]) === null || _a === void 0 ? void 0 : _a.push(id);
33
+ }
34
+ }
35
+ return pinningState;
36
+ }, [tableColumns]);
37
+ const table = useReactTable({
38
+ data,
39
+ columns: tableColumns,
40
+ state: {
41
+ columnPinning,
42
+ globalFilter,
43
+ rowSelection,
44
+ sorting,
45
+ pagination,
46
+ },
47
+ pageCount,
48
+ defaultColumn: {
49
+ enableSorting: true,
50
+ enableResizing: true,
51
+ minSize: 40,
52
+ cell: (cell) => _jsx(TruncateString, { text: String(cell.getValue()), maxLines: 1 }),
53
+ },
54
+ manualSorting,
55
+ manualPagination,
56
+ manualFiltering,
57
+ globalFilterFn: fuzzyFilter,
58
+ onGlobalFilterChange,
59
+ onRowSelectionChange,
60
+ enableRowSelection: rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable,
61
+ enableMultiRowSelection: rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow,
62
+ enableFilters: true,
63
+ getFilteredRowModel: getFilteredRowModel(),
64
+ enableColumnResizing: true,
65
+ enableSorting: true,
66
+ enableMultiSort: true,
67
+ onSortingChange,
68
+ getSortedRowModel: getSortedRowModel(),
69
+ onPaginationChange,
70
+ getPaginationRowModel: getPaginationRowModel(),
71
+ getCoreRowModel: getCoreRowModel(),
72
+ columnResizeMode: 'onEnd',
73
+ });
74
+ return { table, tableColumns, columnPinning };
75
+ }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "title": "Table",
7
- "version": "0.14.7-preview-da21d728.0",
7
+ "version": "0.14.7",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -33,17 +33,17 @@
33
33
  "scripts": {},
34
34
  "dependencies": {
35
35
  "@snack-uikit/button": "0.16.1",
36
- "@snack-uikit/chips": "0.12.1-preview-da21d728.0",
36
+ "@snack-uikit/chips": "0.12.0",
37
37
  "@snack-uikit/icon-predefined": "0.4.2",
38
38
  "@snack-uikit/icons": "0.20.1",
39
39
  "@snack-uikit/info-block": "0.3.0",
40
- "@snack-uikit/list": "0.4.2-preview-da21d728.0",
40
+ "@snack-uikit/list": "0.5.0",
41
41
  "@snack-uikit/pagination": "0.6.4",
42
42
  "@snack-uikit/scroll": "0.5.2",
43
43
  "@snack-uikit/skeleton": "0.3.3",
44
- "@snack-uikit/tag": "0.8.1-preview-da21d728.0",
44
+ "@snack-uikit/tag": "0.8.0",
45
45
  "@snack-uikit/toggles": "0.9.6",
46
- "@snack-uikit/toolbar": "0.7.15-preview-da21d728.0",
46
+ "@snack-uikit/toolbar": "0.7.15",
47
47
  "@snack-uikit/truncate-string": "0.4.9",
48
48
  "@snack-uikit/typography": "0.6.1",
49
49
  "@snack-uikit/utils": "3.2.0",
@@ -58,5 +58,5 @@
58
58
  "peerDependencies": {
59
59
  "@snack-uikit/locale": "*"
60
60
  },
61
- "gitHead": "9451c0c01e3175ef35d07864f3189c690f73c268"
61
+ "gitHead": "bfdd4a8e3c077eab0d45e177172a62b6dcbda06b"
62
62
  }
@@ -31,7 +31,7 @@ export function ServerTable<TData extends object>({
31
31
  const handleSearch = useCallback(
32
32
  (newValue: string) => {
33
33
  setTempSearch(newValue);
34
- onSearchDebounced(newValue.trim(), setSearch);
34
+ onSearchDebounced()(newValue.trim(), setSearch);
35
35
  },
36
36
 
37
37
  [setSearch],
@@ -2,6 +2,8 @@ import debounce from 'lodash.debounce';
2
2
 
3
3
  import { SEARCH_DELAY } from './constants';
4
4
 
5
- export const onSearchDebounced = debounce((newValue: string, onChange: (newValue: string) => void) => {
6
- onChange(newValue);
7
- }, SEARCH_DELAY);
5
+ export function onSearchDebounced() {
6
+ return debounce((newValue: string, onChange: (newValue: string) => void) => {
7
+ onChange(newValue);
8
+ }, SEARCH_DELAY);
9
+ }
@@ -1,15 +1,3 @@
1
- import {
2
- CellContext,
3
- ColumnPinningState,
4
- getCoreRowModel,
5
- getFilteredRowModel,
6
- getPaginationRowModel,
7
- getSortedRowModel,
8
- PaginationState,
9
- RowSelectionState,
10
- SortingState,
11
- useReactTable,
12
- } from '@tanstack/react-table';
13
1
  import cn from 'classnames';
14
2
  import { RefObject, useCallback, useEffect, useMemo } from 'react';
15
3
 
@@ -17,7 +5,6 @@ import { useLocale } from '@snack-uikit/locale';
17
5
  import { Scroll } from '@snack-uikit/scroll';
18
6
  import { SkeletonContextProvider } from '@snack-uikit/skeleton';
19
7
  import { Toolbar } from '@snack-uikit/toolbar';
20
- import { TruncateString } from '@snack-uikit/truncate-string';
21
8
  import { extractSupportProps } from '@snack-uikit/utils';
22
9
 
23
10
  import { DEFAULT_PAGE_SIZE } from '../../constants';
@@ -26,7 +13,6 @@ import {
26
13
  ExportButton,
27
14
  getColumnId,
28
15
  getRowActionsColumnDef,
29
- getSelectionCellColumnDef,
30
16
  getStatusColumnDef,
31
17
  HeaderRow,
32
18
  STATUS_APPEARANCE,
@@ -35,22 +21,19 @@ import {
35
21
  TablePagination,
36
22
  useEmptyState,
37
23
  } from '../../helperComponents';
38
- import { ColumnDefinition } from '../../types';
39
- import { fuzzyFilter } from '../../utils';
40
24
  import { TableProps } from '../types';
41
- import { useLoadingTable } from './hooks';
42
- import { useStateControl } from './hooks/useStateControl';
25
+ import { useLoadingTable, useTable } from './hooks';
43
26
  import styles from './styles.module.scss';
44
27
 
45
28
  /** Компонент таблицы */
46
29
  export function Table<TData extends object>({
47
30
  data,
48
31
  columnDefinitions,
49
- rowSelection: rowSelectionProp,
32
+ rowSelection,
50
33
  search,
51
- sorting: sortingProp,
34
+ sorting,
52
35
  columnFilters,
53
- pagination: paginationProp,
36
+ pagination,
54
37
  className,
55
38
  onRowClick,
56
39
  onRefresh,
@@ -78,84 +61,17 @@ export function Table<TData extends object>({
78
61
 
79
62
  ...rest
80
63
  }: TableProps<TData>) {
81
- const { state: globalFilter, onStateChange: onGlobalFilterChange } = useStateControl<string>(search, '');
82
- const { state: rowSelection, onStateChange: onRowSelectionChange } = useStateControl<RowSelectionState>(
83
- rowSelectionProp,
84
- {},
85
- );
86
- const defaultPaginationState = useMemo(
87
- () => ({
88
- pageIndex: 0,
89
- pageSize,
90
- }),
91
- [pageSize],
92
- );
93
-
94
- const { state: sorting, onStateChange: onSortingChange } = useStateControl<SortingState>(sortingProp, []);
95
- const { state: pagination, onStateChange: onPaginationChange } = useStateControl<PaginationState>(
96
- paginationProp,
97
- defaultPaginationState,
98
- );
99
- const enableSelection = Boolean(rowSelectionProp?.enable);
100
-
101
- const tableColumns: ColumnDefinition<TData>[] = useMemo(() => {
102
- let cols: ColumnDefinition<TData>[] = columnDefinitions;
103
- if (enableSelection) {
104
- cols = [getSelectionCellColumnDef(), ...cols];
105
- }
106
- return cols;
107
- }, [columnDefinitions, enableSelection]);
108
- const columnPinning = useMemo(() => {
109
- const pinningState: Required<ColumnPinningState> = { left: [], right: [] };
110
- for (const col of tableColumns) {
111
- const id = getColumnId(col);
112
- if (col.pinned && id) {
113
- pinningState[col.pinned]?.push(id);
114
- }
115
- }
116
- return pinningState;
117
- }, [tableColumns]);
118
-
119
- const table = useReactTable<TData>({
64
+ const { table, tableColumns, columnPinning } = useTable<TData>({
120
65
  data,
121
- columns: tableColumns,
122
- state: {
123
- columnPinning,
124
- globalFilter,
125
- rowSelection,
126
- sorting,
127
- pagination,
128
- },
129
- pageCount,
130
- defaultColumn: {
131
- enableSorting: false,
132
- enableResizing: false,
133
- minSize: 40,
134
- cell: (cell: CellContext<TData, unknown>) => <TruncateString text={String(cell.getValue())} maxLines={1} />,
135
- },
136
-
137
- manualSorting,
138
- manualPagination,
66
+ sorting,
139
67
  manualFiltering,
140
-
141
- globalFilterFn: fuzzyFilter,
142
- onGlobalFilterChange,
143
-
144
- onRowSelectionChange,
145
- enableRowSelection: rowSelectionProp?.enable,
146
- enableMultiRowSelection: rowSelectionProp?.multiRow,
147
- enableFilters: true,
148
- getFilteredRowModel: getFilteredRowModel(),
149
- enableColumnResizing: true,
150
- enableSorting: true,
151
- enableMultiSort: true,
152
- onSortingChange,
153
- getSortedRowModel: getSortedRowModel(),
154
- onPaginationChange,
155
- getPaginationRowModel: getPaginationRowModel(),
156
- getCoreRowModel: getCoreRowModel(),
157
-
158
- columnResizeMode: 'onEnd',
68
+ manualPagination,
69
+ manualSorting,
70
+ columnDefinitions,
71
+ rowSelection,
72
+ pagination,
73
+ pageCount,
74
+ pageSize,
159
75
  });
160
76
 
161
77
  const { loadingTable } = useLoadingTable({ pageSize, columnDefinitions: tableColumns, columnPinning });
@@ -176,7 +92,7 @@ export function Table<TData extends object>({
176
92
  }, [loading, onDelete, table]);
177
93
 
178
94
  const handleOnCheck = useCallback(() => {
179
- if (!loading && rowSelectionProp?.multiRow) {
95
+ if (!loading && rowSelection?.multiRow) {
180
96
  table.toggleAllPageRowsSelected();
181
97
  return;
182
98
  }
@@ -185,7 +101,7 @@ export function Table<TData extends object>({
185
101
  table.resetRowSelection();
186
102
  return;
187
103
  }
188
- }, [loading, rowSelectionProp?.multiRow, table]);
104
+ }, [loading, rowSelection?.multiRow, table]);
189
105
 
190
106
  useEffect(() => {}, []);
191
107
 
@@ -232,11 +148,14 @@ export function Table<TData extends object>({
232
148
  return !tableRows.length ? Math.min(Math.max(tempPageSize, 5), DEFAULT_PAGE_SIZE) : tempPageSize;
233
149
  }, [pageSize, suppressPagination, tablePagination?.pageSize, tableRows.length]);
234
150
 
151
+ const enableSelection = Boolean(rowSelection?.enable);
152
+
235
153
  return (
236
154
  <>
237
155
  <div
238
156
  style={{
239
157
  '--page-size': cssPageSize,
158
+ // width: table.getTotalSize(),
240
159
  }}
241
160
  className={cn(styles.wrapper, className)}
242
161
  {...extractSupportProps(rest)}
@@ -245,8 +164,8 @@ export function Table<TData extends object>({
245
164
  <div className={styles.header}>
246
165
  <Toolbar
247
166
  search={{
248
- value: globalFilter,
249
- onChange: onGlobalFilterChange,
167
+ value: table.getState().globalFilter,
168
+ onChange: table.setGlobalFilter,
250
169
  loading: search?.loading,
251
170
  placeholder: search?.placeholder || t('searchPlaceholder'),
252
171
  }}
@@ -257,7 +176,7 @@ export function Table<TData extends object>({
257
176
  onDelete={enableSelection && onDelete ? handleOnDelete : undefined}
258
177
  onCheck={enableSelection ? handleOnCheck : undefined}
259
178
  outline={outline}
260
- selectionMode={rowSelectionProp?.multiRow ? 'multiple' : 'single'}
179
+ selectionMode={rowSelection?.multiRow ? 'multiple' : 'single'}
261
180
  before={toolbarBefore}
262
181
  after={
263
182
  <>
@@ -309,8 +228,8 @@ export function Table<TData extends object>({
309
228
  {!suppressPagination && (
310
229
  <TablePagination
311
230
  table={table}
312
- options={paginationProp?.options}
313
- optionsLabel={paginationProp?.optionsLabel}
231
+ options={pagination?.options}
232
+ optionsLabel={pagination?.optionsLabel}
314
233
  pageCount={pageCount}
315
234
  />
316
235
  )}
@@ -1 +1,2 @@
1
1
  export * from './useLoadingTable';
2
+ export * from './useTable';
@@ -0,0 +1,132 @@
1
+ import {
2
+ CellContext,
3
+ ColumnPinningState,
4
+ getCoreRowModel,
5
+ getFilteredRowModel,
6
+ getPaginationRowModel,
7
+ getSortedRowModel,
8
+ PaginationState,
9
+ RowSelectionState,
10
+ SortingState,
11
+ useReactTable,
12
+ } from '@tanstack/react-table';
13
+ import { useMemo } from 'react';
14
+
15
+ import { TruncateString } from '@snack-uikit/truncate-string';
16
+
17
+ import { DEFAULT_PAGE_SIZE } from '../../../constants';
18
+ import { getColumnId, getSelectionCellColumnDef } from '../../../helperComponents';
19
+ import { ColumnDefinition } from '../../../types';
20
+ import { fuzzyFilter } from '../../../utils';
21
+ import { TableProps } from '../../types';
22
+ import { useStateControl } from './useStateControl';
23
+
24
+ type UseTableProps<TData extends object> = Pick<
25
+ TableProps<TData>,
26
+ | 'search'
27
+ | 'rowSelection'
28
+ | 'sorting'
29
+ | 'pagination'
30
+ | 'pageSize'
31
+ | 'columnDefinitions'
32
+ | 'data'
33
+ | 'manualFiltering'
34
+ | 'manualSorting'
35
+ | 'manualPagination'
36
+ | 'pageCount'
37
+ >;
38
+
39
+ export function useTable<TData extends object>({
40
+ search,
41
+ pageSize = DEFAULT_PAGE_SIZE,
42
+ pagination: paginationProp,
43
+ rowSelection: rowSelectionProp,
44
+ sorting: sortingProp,
45
+ columnDefinitions,
46
+ manualFiltering,
47
+ manualPagination,
48
+ manualSorting,
49
+ pageCount,
50
+ data,
51
+ }: UseTableProps<TData>) {
52
+ const { state: globalFilter, onStateChange: onGlobalFilterChange } = useStateControl<string>(search, '');
53
+ const { state: rowSelection, onStateChange: onRowSelectionChange } = useStateControl<RowSelectionState>(
54
+ rowSelectionProp,
55
+ {},
56
+ );
57
+ const defaultPaginationState = useMemo(
58
+ () => ({
59
+ pageIndex: 0,
60
+ pageSize,
61
+ }),
62
+ [pageSize],
63
+ );
64
+
65
+ const { state: sorting, onStateChange: onSortingChange } = useStateControl<SortingState>(sortingProp, []);
66
+ const { state: pagination, onStateChange: onPaginationChange } = useStateControl<PaginationState>(
67
+ paginationProp,
68
+ defaultPaginationState,
69
+ );
70
+ const enableSelection = Boolean(rowSelectionProp?.enable);
71
+ const tableColumns: ColumnDefinition<TData>[] = useMemo(() => {
72
+ let cols: ColumnDefinition<TData>[] = columnDefinitions;
73
+ if (enableSelection) {
74
+ cols = [getSelectionCellColumnDef(), ...cols];
75
+ }
76
+ return cols;
77
+ }, [columnDefinitions, enableSelection]);
78
+ const columnPinning = useMemo(() => {
79
+ const pinningState: Required<ColumnPinningState> = { left: [], right: [] };
80
+ for (const col of tableColumns) {
81
+ const id = getColumnId(col);
82
+ if (col.pinned && id) {
83
+ pinningState[col.pinned]?.push(id);
84
+ }
85
+ }
86
+ return pinningState;
87
+ }, [tableColumns]);
88
+
89
+ const table = useReactTable<TData>({
90
+ data,
91
+ columns: tableColumns,
92
+ state: {
93
+ columnPinning,
94
+ globalFilter,
95
+ rowSelection,
96
+ sorting,
97
+ pagination,
98
+ },
99
+ pageCount,
100
+ defaultColumn: {
101
+ enableSorting: true,
102
+ enableResizing: true,
103
+ minSize: 40,
104
+ cell: (cell: CellContext<TData, unknown>) => <TruncateString text={String(cell.getValue())} maxLines={1} />,
105
+ },
106
+
107
+ manualSorting,
108
+ manualPagination,
109
+ manualFiltering,
110
+
111
+ globalFilterFn: fuzzyFilter,
112
+ onGlobalFilterChange,
113
+
114
+ onRowSelectionChange,
115
+ enableRowSelection: rowSelectionProp?.enable,
116
+ enableMultiRowSelection: rowSelectionProp?.multiRow,
117
+ enableFilters: true,
118
+ getFilteredRowModel: getFilteredRowModel(),
119
+ enableColumnResizing: true,
120
+ enableSorting: true,
121
+ enableMultiSort: true,
122
+ onSortingChange,
123
+ getSortedRowModel: getSortedRowModel(),
124
+ onPaginationChange,
125
+ getPaginationRowModel: getPaginationRowModel(),
126
+ getCoreRowModel: getCoreRowModel(),
127
+
128
+ columnResizeMode: 'onEnd',
129
+ });
130
+
131
+ return { table, tableColumns, columnPinning };
132
+ }