@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.
Files changed (66) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +2 -0
  3. package/dist/cjs/components/Table/Table.d.ts +1 -1
  4. package/dist/cjs/components/Table/Table.js +141 -104
  5. package/dist/cjs/components/Table/hooks/index.d.ts +1 -0
  6. package/dist/cjs/components/Table/hooks/index.js +2 -1
  7. package/dist/cjs/components/Table/hooks/useColumnOrderByDrag.d.ts +9 -0
  8. package/dist/cjs/components/Table/hooks/useColumnOrderByDrag.js +76 -0
  9. package/dist/cjs/components/Table/utils.js +6 -3
  10. package/dist/cjs/components/types.d.ts +2 -0
  11. package/dist/cjs/constants.d.ts +1 -0
  12. package/dist/cjs/constants.js +3 -2
  13. package/dist/cjs/helperComponents/Cells/BodyCell/BodyCell.d.ts +2 -1
  14. package/dist/cjs/helperComponents/Cells/BodyCell/BodyCell.js +13 -3
  15. package/dist/cjs/helperComponents/Cells/HeaderCell/DragHandle.d.ts +6 -0
  16. package/dist/cjs/helperComponents/Cells/HeaderCell/DragHandle.js +27 -0
  17. package/dist/cjs/helperComponents/Cells/HeaderCell/HeaderCell.d.ts +2 -1
  18. package/dist/cjs/helperComponents/Cells/HeaderCell/HeaderCell.js +22 -2
  19. package/dist/cjs/helperComponents/Cells/HeaderCell/styles.module.css +11 -0
  20. package/dist/cjs/helperComponents/Rows/BodyRow.d.ts +4 -1
  21. package/dist/cjs/helperComponents/Rows/BodyRow.js +30 -12
  22. package/dist/cjs/helperComponents/Rows/HeaderRow.d.ts +7 -1
  23. package/dist/cjs/helperComponents/Rows/HeaderRow.js +33 -13
  24. package/dist/cjs/helperComponents/hooks.d.ts +22 -13
  25. package/dist/cjs/helperComponents/hooks.js +63 -15
  26. package/dist/cjs/types.d.ts +5 -0
  27. package/dist/esm/components/Table/Table.d.ts +1 -1
  28. package/dist/esm/components/Table/Table.js +34 -25
  29. package/dist/esm/components/Table/hooks/index.d.ts +1 -0
  30. package/dist/esm/components/Table/hooks/index.js +1 -0
  31. package/dist/esm/components/Table/hooks/useColumnOrderByDrag.d.ts +9 -0
  32. package/dist/esm/components/Table/hooks/useColumnOrderByDrag.js +66 -0
  33. package/dist/esm/components/Table/utils.js +6 -3
  34. package/dist/esm/components/types.d.ts +2 -0
  35. package/dist/esm/constants.d.ts +1 -0
  36. package/dist/esm/constants.js +1 -0
  37. package/dist/esm/helperComponents/Cells/BodyCell/BodyCell.d.ts +2 -1
  38. package/dist/esm/helperComponents/Cells/BodyCell/BodyCell.js +7 -3
  39. package/dist/esm/helperComponents/Cells/HeaderCell/DragHandle.d.ts +6 -0
  40. package/dist/esm/helperComponents/Cells/HeaderCell/DragHandle.js +6 -0
  41. package/dist/esm/helperComponents/Cells/HeaderCell/HeaderCell.d.ts +2 -1
  42. package/dist/esm/helperComponents/Cells/HeaderCell/HeaderCell.js +13 -4
  43. package/dist/esm/helperComponents/Cells/HeaderCell/styles.module.css +11 -0
  44. package/dist/esm/helperComponents/Rows/BodyRow.d.ts +4 -1
  45. package/dist/esm/helperComponents/Rows/BodyRow.js +4 -3
  46. package/dist/esm/helperComponents/Rows/HeaderRow.d.ts +7 -1
  47. package/dist/esm/helperComponents/Rows/HeaderRow.js +4 -3
  48. package/dist/esm/helperComponents/hooks.d.ts +22 -13
  49. package/dist/esm/helperComponents/hooks.js +58 -15
  50. package/dist/esm/types.d.ts +5 -0
  51. package/package.json +6 -2
  52. package/src/components/Table/Table.tsx +151 -117
  53. package/src/components/Table/hooks/index.ts +1 -0
  54. package/src/components/Table/hooks/useColumnOrderByDrag.ts +100 -0
  55. package/src/components/Table/utils.ts +8 -3
  56. package/src/components/types.ts +3 -0
  57. package/src/constants.tsx +2 -0
  58. package/src/helperComponents/Cells/BodyCell/BodyCell.tsx +9 -2
  59. package/src/helperComponents/Cells/HeaderCell/DragHandle.tsx +18 -0
  60. package/src/helperComponents/Cells/HeaderCell/HeaderCell.tsx +19 -4
  61. package/src/helperComponents/Cells/HeaderCell/styles.module.scss +15 -4
  62. package/src/helperComponents/Rows/BodyRow.tsx +36 -9
  63. package/src/helperComponents/Rows/HeaderRow.tsx +51 -18
  64. package/src/helperComponents/Rows/styles.module.scss +2 -2
  65. package/src/helperComponents/hooks.ts +78 -15
  66. package/src/types.ts +6 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
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.30.0 (2025-02-26)
7
+
8
+
9
+ ### Features
10
+
11
+ * **PDS-1487:** freeze columns size on resize ([f5f5694](https://github.com/cloud-ru-tech/snack-uikit/commit/f5f56948a5e0ba42f071a66e2de225465f67e980))
12
+
13
+
14
+
15
+
16
+
6
17
  # 0.29.0 (2025-02-25)
7
18
 
8
19
 
package/README.md CHANGED
@@ -115,6 +115,7 @@ const columnDefinitions: ColumnDefinition<TableData>[] = [
115
115
  | copyPinnedRows | `boolean` | - | Параметр отвечает за сохранение закрепленных строк в теле таблицы |
116
116
  | enableSelectPinned | `boolean` | - | Параметр отвечает за чекбокс выбора закрепленных строк |
117
117
  | sorting | `{ initialState?: SortingState; state?: SortingState; onChange?(state: SortingState): void; }` | - | Параметры отвечают за возможность сортировки, их стоит использовать если нужно отслеживать состояние <br> <strong>initialState</strong>: Начальное состояние сортировки <br> <strong>state</strong>: Состояние сортировки, жестко устанавливаемое снаружи <br> <strong>onChange</strong>: Колбэк на изменение сортировки |
118
+ | enableColumnsOrderSortByDrag | `boolean` | - | Включение сортировки порядка столбцов вручную перетаскиванием |
118
119
  | expanding | `{ getSubRows: (element: TData) => TData[]; expandingColumnDefinition: TreeColumnDefinitionProps<TData>; }` | - | Параметр отвечает за общие настройки раскрывающихся строк |
119
120
  | rowSelection | `{ initialState?: RowSelectionState; state?: RowSelectionState; enable?: boolean \| ((row: Row<TData>) => boolean); multiRow?: boolean; onChange?(state: RowSelectionState): void; }` | - | Параметры отвечают за возможность выбора строк <br> <strong>initialState</strong>: Начальное состояние выбора строк <br> <strong>state</strong>: Состояние выбора строк, жестко устанавливаемое снаружи <br> <strong>enable</strong>: Колбэк определяющий можно ли выбрать строку <br> <strong>multiRow</strong>: Мульти-выбор строк (включен по-умолчанию, когда включается выбор) <br> <strong>onChange</strong>: Колбэк на выбор строк |
120
121
  | search | `{ initialState?: string; state?: string; placeholder?: string; loading?: boolean; onChange?(value: string): void; }` | 'Search'<br> <strong>loading</strong>: Состояние загрузки в строке поиска <br> <strong>onChange</strong>: Колбэк на изменение данных в строке поиска | Параметры отвечают за глобальный поиск в таблице <br> <strong>initialState</strong>: Начальное состояние строки поиска <br> <strong>state</strong>: Состояние строки поиска, жестко устанавливаемое снаружи <br> <strong>placeholder</strong>: Placeholder строки поиска |
@@ -180,6 +181,7 @@ const columnDefinitions: ColumnDefinition<TableData>[] = [
180
181
  | copyPinnedRows | `boolean` | false | Параметр отвечает за сохранение закрепленных строк в теле таблицы |
181
182
  | enableSelectPinned | `boolean` | - | Параметр отвечает за чекбокс выбора закрепленных строк |
182
183
  | sorting | `{ initialState?: SortingState; state?: SortingState; onChange?(state: SortingState): void; }` | - | Параметры отвечают за возможность сортировки, их стоит использовать если нужно отслеживать состояние <br> <strong>initialState</strong>: Начальное состояние сортировки <br> <strong>state</strong>: Состояние сортировки, жестко устанавливаемое снаружи <br> <strong>onChange</strong>: Колбэк на изменение сортировки |
184
+ | enableColumnsOrderSortByDrag | `boolean` | - | Включение сортировки порядка столбцов вручную перетаскиванием |
183
185
  | expanding | `{ getSubRows: (element: TData) => TData[]; expandingColumnDefinition: TreeColumnDefinitionProps<TData>; }` | - | Параметр отвечает за общие настройки раскрывающихся строк |
184
186
  | rowSelection | `{ initialState?: RowSelectionState; state?: RowSelectionState; enable?: boolean \| ((row: Row<TData>) => boolean); multiRow?: boolean; onChange?(state: RowSelectionState): void; }` | - | Параметры отвечают за возможность выбора строк <br> <strong>initialState</strong>: Начальное состояние выбора строк <br> <strong>state</strong>: Состояние выбора строк, жестко устанавливаемое снаружи <br> <strong>enable</strong>: Колбэк определяющий можно ли выбрать строку <br> <strong>multiRow</strong>: Мульти-выбор строк (включен по-умолчанию, когда включается выбор) <br> <strong>onChange</strong>: Колбэк на выбор строк |
185
187
  | enableFuzzySearch | `boolean` | - | Включить нечеткий поиск |
@@ -1,7 +1,7 @@
1
1
  import { FiltersState } from '@snack-uikit/chips';
2
2
  import { TableProps } from '../types';
3
3
  /** Компонент таблицы */
4
- export declare function Table<TData extends object, TFilters extends FiltersState = Record<string, unknown>>({ data, rowPinning, columnDefinitions, keepPinnedRows, copyPinnedRows, enableSelectPinned, rowSelection: rowSelectionProp, search, sorting: sortingProp, columnFilters, pagination: paginationProp, className, onRowClick, onRefresh, pageSize, pageCount, loading, outline, moreActions, exportSettings, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar, suppressSearch, toolbarAfter, suppressPagination, manualSorting, manualPagination, manualFiltering, autoResetPageIndex, scrollRef, scrollContainerRef, getRowId, enableFuzzySearch, savedState, expanding, bulkActions: bulkActionsProp, ...rest }: TableProps<TData, TFilters>): import("react/jsx-runtime").JSX.Element;
4
+ export declare function Table<TData extends object, TFilters extends FiltersState = Record<string, unknown>>({ data, rowPinning, columnDefinitions, keepPinnedRows, copyPinnedRows, enableSelectPinned, rowSelection: rowSelectionProp, search, sorting: sortingProp, columnFilters, pagination: paginationProp, className, onRowClick, onRefresh, pageSize, pageCount, loading, outline, moreActions, exportSettings, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar, suppressSearch, toolbarAfter, suppressPagination, manualSorting, manualPagination, manualFiltering, autoResetPageIndex, scrollRef, scrollContainerRef, getRowId, enableFuzzySearch, savedState, expanding, bulkActions: bulkActionsProp, enableColumnsOrderSortByDrag, ...rest }: TableProps<TData, TFilters>): import("react/jsx-runtime").JSX.Element;
5
5
  export declare namespace Table {
6
6
  var getStatusColumnDef: typeof import("../../helperComponents").getStatusColumnDef;
7
7
  var statusAppearances: Record<string, string>;
@@ -18,6 +18,8 @@ Object.defineProperty(exports, "__esModule", {
18
18
  });
19
19
  exports.Table = Table;
20
20
  const jsx_runtime_1 = require("react/jsx-runtime");
21
+ const core_1 = require("@dnd-kit/core");
22
+ const modifiers_1 = require("@dnd-kit/modifiers");
21
23
  const react_table_1 = require("@tanstack/react-table");
22
24
  const classnames_1 = __importDefault(require("classnames"));
23
25
  const react_1 = require("react");
@@ -80,9 +82,10 @@ function Table(_a) {
80
82
  enableFuzzySearch,
81
83
  savedState,
82
84
  expanding,
83
- bulkActions: bulkActionsProp
85
+ bulkActions: bulkActionsProp,
86
+ enableColumnsOrderSortByDrag
84
87
  } = _a,
85
- rest = __rest(_a, ["data", "rowPinning", "columnDefinitions", "keepPinnedRows", "copyPinnedRows", "enableSelectPinned", "rowSelection", "search", "sorting", "columnFilters", "pagination", "className", "onRowClick", "onRefresh", "pageSize", "pageCount", "loading", "outline", "moreActions", "exportSettings", "dataFiltered", "dataError", "noDataState", "noResultsState", "errorDataState", "suppressToolbar", "suppressSearch", "toolbarAfter", "suppressPagination", "manualSorting", "manualPagination", "manualFiltering", "autoResetPageIndex", "scrollRef", "scrollContainerRef", "getRowId", "enableFuzzySearch", "savedState", "expanding", "bulkActions"]);
88
+ rest = __rest(_a, ["data", "rowPinning", "columnDefinitions", "keepPinnedRows", "copyPinnedRows", "enableSelectPinned", "rowSelection", "search", "sorting", "columnFilters", "pagination", "className", "onRowClick", "onRefresh", "pageSize", "pageCount", "loading", "outline", "moreActions", "exportSettings", "dataFiltered", "dataError", "noDataState", "noResultsState", "errorDataState", "suppressToolbar", "suppressSearch", "toolbarAfter", "suppressPagination", "manualSorting", "manualPagination", "manualFiltering", "autoResetPageIndex", "scrollRef", "scrollContainerRef", "getRowId", "enableFuzzySearch", "savedState", "expanding", "bulkActions", "enableColumnsOrderSortByDrag"]);
86
89
  const {
87
90
  state: globalFilter,
88
91
  onStateChange: onGlobalFilterChange
@@ -114,6 +117,13 @@ function Table(_a) {
114
117
  }
115
118
  return cols;
116
119
  }, [columnDefinitions, enableSelection, enableSelectPinned, expanding]);
120
+ const {
121
+ columnOrder,
122
+ setColumnOrder,
123
+ groupedColumnOrderState,
124
+ sensors,
125
+ handleDragEnd
126
+ } = (0, hooks_1.useColumnOrderByDrag)(tableColumns);
117
127
  const columnPinning = (0, react_1.useMemo)(() => {
118
128
  var _a;
119
129
  const pinningState = {
@@ -142,6 +152,7 @@ function Table(_a) {
142
152
  columns: tableColumns,
143
153
  state: {
144
154
  columnPinning,
155
+ columnOrder,
145
156
  globalFilter,
146
157
  rowSelection,
147
158
  sorting,
@@ -160,6 +171,7 @@ function Table(_a) {
160
171
  maxLines: 1
161
172
  })
162
173
  },
174
+ onColumnOrderChange: setColumnOrder,
163
175
  manualSorting,
164
176
  manualPagination,
165
177
  manualFiltering,
@@ -229,10 +241,17 @@ function Table(_a) {
229
241
  }, [loading, rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow, table, enableSelectPinned]);
230
242
  const columnSizeVarsRef = (0, react_1.useRef)();
231
243
  const headers = table.getFlatHeaders();
232
- const columnSizeVars = (0, react_1.useMemo)(() => {
244
+ const columnSizes = (0, react_1.useMemo)(() => {
233
245
  var _a;
234
246
  const originalColumnDefs = table._getColumnDefs();
235
- const colSizes = {};
247
+ const vars = {};
248
+ const realSizes = {};
249
+ const resizedColumnIndex = headers.findIndex(_ref => {
250
+ let {
251
+ column
252
+ } = _ref;
253
+ return column.getIsResizing();
254
+ });
236
255
  for (let i = 0; i < headers.length; i++) {
237
256
  const header = headers[i];
238
257
  const {
@@ -241,8 +260,8 @@ function Table(_a) {
241
260
  } = (0, utils_3.getColumnStyleVars)(header.id);
242
261
  const originalColDef = originalColumnDefs.find(col => (0, helperComponents_1.getColumnId)(header) === col.id);
243
262
  if (header.id === 'snack_predefined_statusColumn' && !(originalColDef === null || originalColDef === void 0 ? void 0 : originalColDef.header) && !(originalColDef === null || originalColDef === void 0 ? void 0 : originalColDef.enableSorting)) {
244
- colSizes[sizeKey] = 'var(--size-table-cell-status-indicator-horizontal)';
245
- colSizes[flexKey] = '100%';
263
+ vars[sizeKey] = 'var(--size-table-cell-status-indicator-horizontal)';
264
+ vars[flexKey] = '100%';
246
265
  } else {
247
266
  const originalColumnDefSize = originalColDef === null || originalColDef === void 0 ? void 0 : originalColDef.size;
248
267
  let initSize = originalColumnDefSize ? `${originalColumnDefSize}px` : '100%';
@@ -261,12 +280,9 @@ function Table(_a) {
261
280
  if (header.column.getCanResize()) {
262
281
  const currentSize = header.getSize();
263
282
  const colDefSize = header.column.columnDef.size;
264
- size = currentSize === colDefSize ? initSize : `${currentSize}px`;
265
- if (prevSize === '100%' && currentSize !== colDefSize) {
266
- const realSize = (0, utils_3.getCurrentlyConfiguredHeaderWidth)(header.id);
267
- table.setColumnSizing(old => Object.assign(Object.assign({}, old), {
268
- [header.id]: realSize
269
- }));
283
+ if (currentSize !== colDefSize || i < resizedColumnIndex && prevSize === '100%') {
284
+ const realSize = prevSize === '100%' ? (0, utils_3.getCurrentlyConfiguredHeaderWidth)(header.id) : currentSize;
285
+ realSizes[header.id] = realSize;
270
286
  size = `${realSize}px`;
271
287
  }
272
288
  }
@@ -277,11 +293,14 @@ function Table(_a) {
277
293
  size
278
294
  });
279
295
  }
280
- colSizes[sizeKey] = size;
281
- colSizes[flexKey] = size === '100%' ? 'unset' : '0';
296
+ vars[sizeKey] = size;
297
+ vars[flexKey] = size === '100%' ? 'unset' : '0';
282
298
  }
283
299
  }
284
- return colSizes;
300
+ return {
301
+ vars,
302
+ realSizes
303
+ };
285
304
  /*
286
305
  effect must be called only on columnSizingInfo.isResizingColumn changes
287
306
  to reduce unnecessary recalculations
@@ -291,8 +310,11 @@ function Table(_a) {
291
310
  // eslint-disable-next-line react-hooks/exhaustive-deps
292
311
  }, [table.getState().columnSizingInfo.isResizingColumn, headers, table.getTotalSize()]);
293
312
  (0, react_1.useEffect)(() => {
294
- columnSizeVarsRef.current = columnSizeVars;
295
- }, [columnSizeVars]);
313
+ if (Object.keys(columnSizes.realSizes).length) {
314
+ table.setColumnSizing(old => Object.assign(Object.assign({}, old), columnSizes.realSizes));
315
+ }
316
+ columnSizeVarsRef.current = columnSizes.vars;
317
+ }, [columnSizes, table]);
296
318
  const tableRows = table.getRowModel().rows;
297
319
  const tableCenterRows = table.getCenterRows();
298
320
  const tableFilteredRows = table.getFilteredRowModel().rows;
@@ -325,96 +347,111 @@ function Table(_a) {
325
347
  updateCellMap
326
348
  } = (0, contexts_1.useCellAutoResizeController)(table);
327
349
  const showToolbar = !suppressToolbar;
328
- return (0, jsx_runtime_1.jsx)(contexts_1.CellAutoResizeContext.Provider, {
329
- value: {
330
- updateCellMap
331
- },
332
- children: (0, jsx_runtime_1.jsxs)("div", Object.assign({
333
- style: {
334
- '--page-size': cssPageSize
350
+ return (0, jsx_runtime_1.jsx)(core_1.DndContext, {
351
+ collisionDetection: core_1.closestCenter,
352
+ modifiers: [modifiers_1.restrictToHorizontalAxis],
353
+ onDragEnd: handleDragEnd,
354
+ sensors: sensors,
355
+ children: (0, jsx_runtime_1.jsx)(contexts_1.CellAutoResizeContext.Provider, {
356
+ value: {
357
+ updateCellMap
335
358
  },
336
- className: (0, classnames_1.default)(styles_module_scss_1.default.wrapper, className)
337
- }, (0, utils_1.extractSupportProps)(rest), {
338
- children: [showToolbar && (0, jsx_runtime_1.jsx)("div", {
339
- className: styles_module_scss_1.default.header,
340
- children: (0, jsx_runtime_1.jsx)(toolbar_1.Toolbar, {
341
- search: suppressSearch ? undefined : {
342
- value: globalFilter,
343
- onChange: onGlobalFilterChange,
344
- loading: search === null || search === void 0 ? void 0 : search.loading,
345
- placeholder: (search === null || search === void 0 ? void 0 : search.placeholder) || t('searchPlaceholder')
346
- },
347
- className: styles_module_scss_1.default.toolbar,
348
- onRefresh: onRefresh ? handleOnRefresh : undefined,
349
- bulkActions: bulkActions,
350
- selectionMode: (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow) ? 'multiple' : 'single',
351
- checked: table.getIsAllPageRowsSelected(),
352
- indeterminate: table.getIsSomePageRowsSelected(),
353
- onCheck: enableSelection ? handleOnToolbarCheck : undefined,
354
- outline: outline,
355
- after: toolbarAfter || exportSettings ? (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, {
356
- children: [toolbarAfter, exportSettings && (0, jsx_runtime_1.jsx)(helperComponents_1.ExportButton, {
357
- settings: exportSettings,
358
- columnDefinitions: columnDefinitions,
359
- data: data,
360
- topRows: filteredTopRows,
361
- centerRows: centerRows
362
- })]
363
- }) : undefined,
364
- moreActions: moreActions,
365
- filterRow: columnFilters,
366
- "data-test-id": constants_1.TEST_IDS.toolbar
367
- })
368
- }), (0, jsx_runtime_1.jsx)("div", {
369
- className: styles_module_scss_1.default.scrollWrapper,
370
- "data-outline": outline || undefined,
371
- children: (0, jsx_runtime_1.jsxs)(scroll_1.Scroll, {
372
- size: 's',
373
- className: styles_module_scss_1.default.table,
374
- ref: scrollContainerRef,
375
- children: [(0, jsx_runtime_1.jsx)("div", {
376
- className: styles_module_scss_1.default.tableContent,
377
- style: columnSizeVars,
378
- children: (0, jsx_runtime_1.jsx)(helperComponents_1.TableContext.Provider, {
379
- value: {
380
- table
381
- },
382
- children: loading ? (0, jsx_runtime_1.jsxs)(skeleton_1.SkeletonContextProvider, {
383
- loading: true,
384
- children: [(0, jsx_runtime_1.jsx)(helperComponents_1.HeaderRow, {}), loadingTableRows.map(row => (0, jsx_runtime_1.jsx)(helperComponents_1.BodyRow, {
385
- row: row
386
- }, row.id))]
387
- }) : (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, {
388
- children: [centerRows.length || filteredTopRows.length ? (0, jsx_runtime_1.jsx)(helperComponents_1.HeaderRow, {}) : null, filteredTopRows.length ? (0, jsx_runtime_1.jsx)("div", {
389
- className: styles_module_scss_1.default.topRowWrapper,
390
- children: filteredTopRows.map(row => (0, jsx_runtime_1.jsx)(helperComponents_1.BodyRow, {
359
+ children: (0, jsx_runtime_1.jsxs)("div", Object.assign({
360
+ style: {
361
+ '--page-size': cssPageSize
362
+ },
363
+ className: (0, classnames_1.default)(styles_module_scss_1.default.wrapper, className)
364
+ }, (0, utils_1.extractSupportProps)(rest), {
365
+ children: [showToolbar && (0, jsx_runtime_1.jsx)("div", {
366
+ className: styles_module_scss_1.default.header,
367
+ children: (0, jsx_runtime_1.jsx)(toolbar_1.Toolbar, {
368
+ search: suppressSearch ? undefined : {
369
+ value: globalFilter,
370
+ onChange: onGlobalFilterChange,
371
+ loading: search === null || search === void 0 ? void 0 : search.loading,
372
+ placeholder: (search === null || search === void 0 ? void 0 : search.placeholder) || t('searchPlaceholder')
373
+ },
374
+ className: styles_module_scss_1.default.toolbar,
375
+ onRefresh: onRefresh ? handleOnRefresh : undefined,
376
+ bulkActions: bulkActions,
377
+ selectionMode: (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow) ? 'multiple' : 'single',
378
+ checked: table.getIsAllPageRowsSelected(),
379
+ indeterminate: table.getIsSomePageRowsSelected(),
380
+ onCheck: enableSelection ? handleOnToolbarCheck : undefined,
381
+ outline: outline,
382
+ after: toolbarAfter || exportSettings ? (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, {
383
+ children: [toolbarAfter, exportSettings && (0, jsx_runtime_1.jsx)(helperComponents_1.ExportButton, {
384
+ settings: exportSettings,
385
+ columnDefinitions: columnDefinitions,
386
+ data: data,
387
+ topRows: filteredTopRows,
388
+ centerRows: centerRows
389
+ })]
390
+ }) : undefined,
391
+ moreActions: moreActions,
392
+ filterRow: columnFilters,
393
+ "data-test-id": constants_1.TEST_IDS.toolbar
394
+ })
395
+ }), (0, jsx_runtime_1.jsx)("div", {
396
+ className: styles_module_scss_1.default.scrollWrapper,
397
+ "data-outline": outline || undefined,
398
+ children: (0, jsx_runtime_1.jsxs)(scroll_1.Scroll, {
399
+ size: 's',
400
+ className: styles_module_scss_1.default.table,
401
+ ref: scrollContainerRef,
402
+ children: [(0, jsx_runtime_1.jsx)("div", {
403
+ className: styles_module_scss_1.default.tableContent,
404
+ style: columnSizes.vars,
405
+ children: (0, jsx_runtime_1.jsx)(helperComponents_1.TableContext.Provider, {
406
+ value: {
407
+ table
408
+ },
409
+ children: loading ? (0, jsx_runtime_1.jsxs)(skeleton_1.SkeletonContextProvider, {
410
+ loading: true,
411
+ children: [(0, jsx_runtime_1.jsx)(helperComponents_1.HeaderRow, {
412
+ groupedColumnOrderState: groupedColumnOrderState
413
+ }), loadingTableRows.map(row => (0, jsx_runtime_1.jsx)(helperComponents_1.BodyRow, {
414
+ row: row,
415
+ groupedColumnOrderState: groupedColumnOrderState
416
+ }, row.id))]
417
+ }) : (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, {
418
+ children: [centerRows.length || filteredTopRows.length ? (0, jsx_runtime_1.jsx)(helperComponents_1.HeaderRow, {
419
+ groupedColumnOrderState: groupedColumnOrderState,
420
+ enableColumnsOrderSortByDrag: enableColumnsOrderSortByDrag
421
+ }) : null, filteredTopRows.length ? (0, jsx_runtime_1.jsx)("div", {
422
+ className: styles_module_scss_1.default.topRowWrapper,
423
+ children: filteredTopRows.map(row => (0, jsx_runtime_1.jsx)(helperComponents_1.BodyRow, {
424
+ row: row,
425
+ onRowClick: onRowClick,
426
+ groupedColumnOrderState: groupedColumnOrderState
427
+ }, row.id))
428
+ }) : null, centerRows.map(row => (0, jsx_runtime_1.jsx)(helperComponents_1.BodyRow, {
391
429
  row: row,
392
- onRowClick: onRowClick
393
- }, row.id))
394
- }) : null, centerRows.map(row => (0, jsx_runtime_1.jsx)(helperComponents_1.BodyRow, {
395
- row: row,
396
- onRowClick: onRowClick
397
- }, row.id)), (0, jsx_runtime_1.jsx)(helperComponents_1.TableEmptyState, {
398
- emptyStates: emptyStates,
399
- dataError: dataError,
400
- dataFiltered: dataFiltered || Boolean(table.getState().globalFilter),
401
- tableRowsLength: tableRows.length + filteredTopRows.length
402
- })]
430
+ onRowClick: onRowClick,
431
+ groupedColumnOrderState: groupedColumnOrderState,
432
+ enableColumnsOrderSortByDrag: enableColumnsOrderSortByDrag
433
+ }, row.id)), (0, jsx_runtime_1.jsx)(helperComponents_1.TableEmptyState, {
434
+ emptyStates: emptyStates,
435
+ dataError: dataError,
436
+ dataFiltered: dataFiltered || Boolean(table.getState().globalFilter),
437
+ tableRowsLength: tableRows.length + filteredTopRows.length
438
+ })]
439
+ })
403
440
  })
404
- })
405
- }), (0, jsx_runtime_1.jsx)("div", {
406
- className: styles_module_scss_1.default.scrollStub,
407
- ref: scrollRef
408
- })]
409
- })
410
- }), !suppressPagination && (0, jsx_runtime_1.jsx)(helperComponents_1.TablePagination, {
411
- table: table,
412
- options: paginationProp === null || paginationProp === void 0 ? void 0 : paginationProp.options,
413
- optionsLabel: paginationProp === null || paginationProp === void 0 ? void 0 : paginationProp.optionsLabel,
414
- pageCount: pageCount,
415
- optionsRender: paginationProp === null || paginationProp === void 0 ? void 0 : paginationProp.optionsRender
416
- })]
417
- }))
441
+ }), (0, jsx_runtime_1.jsx)("div", {
442
+ className: styles_module_scss_1.default.scrollStub,
443
+ ref: scrollRef
444
+ })]
445
+ })
446
+ }), !suppressPagination && (0, jsx_runtime_1.jsx)(helperComponents_1.TablePagination, {
447
+ table: table,
448
+ options: paginationProp === null || paginationProp === void 0 ? void 0 : paginationProp.options,
449
+ optionsLabel: paginationProp === null || paginationProp === void 0 ? void 0 : paginationProp.optionsLabel,
450
+ pageCount: pageCount,
451
+ optionsRender: paginationProp === null || paginationProp === void 0 ? void 0 : paginationProp.optionsRender
452
+ })]
453
+ }))
454
+ })
418
455
  });
419
456
  }
420
457
  Table.getStatusColumnDef = helperComponents_1.getStatusColumnDef;
@@ -1,2 +1,3 @@
1
1
  export * from './useLoadingTable';
2
2
  export * from './useStateControl';
3
+ export * from './useColumnOrderByDrag';
@@ -23,4 +23,5 @@ Object.defineProperty(exports, "__esModule", {
23
23
  value: true
24
24
  });
25
25
  __exportStar(require("./useLoadingTable"), exports);
26
- __exportStar(require("./useStateControl"), exports);
26
+ __exportStar(require("./useStateControl"), exports);
27
+ __exportStar(require("./useColumnOrderByDrag"), exports);
@@ -0,0 +1,9 @@
1
+ import { DragEndEvent } from '@dnd-kit/core';
2
+ import { ColumnDefinition, GroupedColumnOrderState } from '../../../types';
3
+ export declare function useColumnOrderByDrag<TData extends object>(tableColumns: ColumnDefinition<TData>[]): {
4
+ columnOrder: string[];
5
+ setColumnOrder: import("react").Dispatch<import("react").SetStateAction<string[]>>;
6
+ groupedColumnOrderState: GroupedColumnOrderState;
7
+ handleDragEnd: ({ active, over }: DragEndEvent) => void;
8
+ sensors: import("@dnd-kit/core").SensorDescriptor<import("@dnd-kit/core").SensorOptions>[];
9
+ };
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useColumnOrderByDrag = useColumnOrderByDrag;
7
+ const core_1 = require("@dnd-kit/core");
8
+ const sortable_1 = require("@dnd-kit/sortable");
9
+ const react_1 = require("react");
10
+ const constants_1 = require("../../../constants");
11
+ function preparePinnedColumnsMap(tableColumns) {
12
+ return tableColumns.reduce((accMap, columnDefinition) => {
13
+ switch (columnDefinition.pinned) {
14
+ case 'left':
15
+ accMap[columnDefinition.id] = 'leftPinned';
16
+ break;
17
+ case 'right':
18
+ accMap[columnDefinition.id] = 'rightPinned';
19
+ break;
20
+ default:
21
+ }
22
+ return accMap;
23
+ }, {});
24
+ }
25
+ function prepareInitialState(tableColumns) {
26
+ return tableColumns.map(c => c.id).filter(id => !constants_1.UNDRAGGABLE_COLUMNS.includes(id));
27
+ }
28
+ function prepareGroupedColumnOrderState(columnOrder, pinnedColumnsMap) {
29
+ return columnOrder.reduce((accState, columnId) => {
30
+ var _a;
31
+ if (constants_1.UNDRAGGABLE_COLUMNS.includes(columnId)) {
32
+ return accState;
33
+ }
34
+ const groupName = (_a = pinnedColumnsMap[columnId]) !== null && _a !== void 0 ? _a : 'unpinned';
35
+ accState[groupName].push(columnId);
36
+ return accState;
37
+ }, {
38
+ leftPinned: [],
39
+ unpinned: [],
40
+ rightPinned: []
41
+ });
42
+ }
43
+ function useColumnOrderByDrag(tableColumns) {
44
+ const [columnOrder, setColumnOrder] = (0, react_1.useState)(() => prepareInitialState(tableColumns));
45
+ const pinnedColumnsMap = (0, react_1.useMemo)(() => preparePinnedColumnsMap(tableColumns), [tableColumns]);
46
+ const groupedColumnOrderState = (0, react_1.useMemo)(() => prepareGroupedColumnOrderState(columnOrder, pinnedColumnsMap), [columnOrder, pinnedColumnsMap]);
47
+ const handleDragEnd = (0, react_1.useCallback)(_ref => {
48
+ let {
49
+ active,
50
+ over
51
+ } = _ref;
52
+ if (active && over && active.id !== over.id) {
53
+ if (constants_1.UNDRAGGABLE_COLUMNS.includes(over.id.toString())) {
54
+ return;
55
+ }
56
+ const activeGroup = pinnedColumnsMap[active.id.toString()];
57
+ const overGroup = pinnedColumnsMap[over.id.toString()];
58
+ if (activeGroup !== overGroup) {
59
+ return;
60
+ }
61
+ setColumnOrder(columnOrder => {
62
+ const oldIndex = columnOrder.indexOf(active.id.toString());
63
+ const newIndex = columnOrder.indexOf(over.id.toString());
64
+ return (0, sortable_1.arrayMove)(columnOrder, oldIndex, newIndex);
65
+ });
66
+ }
67
+ }, [pinnedColumnsMap]);
68
+ const sensors = (0, core_1.useSensors)((0, core_1.useSensor)(core_1.MouseSensor, {}), (0, core_1.useSensor)(core_1.TouchSensor, {}), (0, core_1.useSensor)(core_1.KeyboardSensor, {}));
69
+ return {
70
+ columnOrder,
71
+ setColumnOrder,
72
+ groupedColumnOrderState,
73
+ handleDragEnd,
74
+ sensors
75
+ };
76
+ }
@@ -12,12 +12,15 @@ function getCurrentlyConfiguredHeaderWidth(id) {
12
12
  if ((0, utils_1.isBrowser)()) {
13
13
  const cell = document.querySelector(`[data-header-id="${id}"]`);
14
14
  const resizeHandler = cell === null || cell === void 0 ? void 0 : cell.querySelector('[data-test-id="table__header-cell-resize-handle-moving-part"]');
15
- if (cell && resizeHandler) {
15
+ if (cell) {
16
16
  const {
17
17
  width
18
18
  } = cell.getBoundingClientRect();
19
- const offset = parseInt(resizeHandler.style.getPropertyValue('--offset'));
20
- return width + offset;
19
+ if (resizeHandler) {
20
+ const offset = parseInt(resizeHandler.style.getPropertyValue('--offset'));
21
+ return width + offset;
22
+ }
23
+ return width;
21
24
  }
22
25
  }
23
26
  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
  /** Метод отвечает за получение дочерних строк*/
@@ -35,3 +35,4 @@ export declare const SORT_FN: {
35
35
  readonly AlphaNumeric: "alphanumeric";
36
36
  };
37
37
  export declare const DEFAULT_PAGE_SIZE = 10;
38
+ export declare const UNDRAGGABLE_COLUMNS: string[];
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.DEFAULT_PAGE_SIZE = exports.SORT_FN = exports.TEST_IDS = exports.COLUMN_ALIGN = exports.COLUMN_PIN_POSITION = void 0;
6
+ exports.UNDRAGGABLE_COLUMNS = exports.DEFAULT_PAGE_SIZE = exports.SORT_FN = exports.TEST_IDS = exports.COLUMN_ALIGN = exports.COLUMN_PIN_POSITION = void 0;
7
7
  exports.COLUMN_PIN_POSITION = {
8
8
  Left: 'left',
9
9
  Right: 'right'
@@ -40,4 +40,5 @@ exports.SORT_FN = {
40
40
  DateTime: 'datetime',
41
41
  AlphaNumeric: 'alphanumeric'
42
42
  };
43
- exports.DEFAULT_PAGE_SIZE = 10;
43
+ exports.DEFAULT_PAGE_SIZE = 10;
44
+ exports.UNDRAGGABLE_COLUMNS = ['snack_predefined_statusColumn', 'selectionCell', 'rowActions'];
@@ -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 {};
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", {
18
18
  });
19
19
  exports.BodyCell = BodyCell;
20
20
  const jsx_runtime_1 = require("react/jsx-runtime");
21
+ const sortable_1 = require("@dnd-kit/sortable");
21
22
  const react_table_1 = require("@tanstack/react-table");
22
23
  const classnames_1 = __importDefault(require("classnames"));
23
24
  const constants_1 = require("../../../constants");
@@ -27,12 +28,21 @@ const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
27
28
  function BodyCell(_a) {
28
29
  var {
29
30
  cell,
30
- className
31
+ className,
32
+ isDraggable
31
33
  } = _a,
32
- props = __rest(_a, ["cell", "className"]);
34
+ props = __rest(_a, ["cell", "className", "isDraggable"]);
33
35
  const columnDef = cell.column.columnDef;
34
- const style = (0, hooks_1.useCellSizes)(cell);
36
+ const style = (0, hooks_1.useCellSizes)(cell, {
37
+ isDraggable
38
+ });
39
+ const {
40
+ setNodeRef
41
+ } = (0, sortable_1.useSortable)({
42
+ id: cell.column.id
43
+ });
35
44
  return (0, jsx_runtime_1.jsx)(Cell_1.Cell, Object.assign({}, props, {
45
+ ref: setNodeRef,
36
46
  style: style,
37
47
  className: (0, classnames_1.default)(styles_module_scss_1.default.tableBodyCell, className, columnDef.cellClassName),
38
48
  "data-align": columnDef.align,
@@ -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,27 @@
1
+ "use strict";
2
+
3
+ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
4
+ return mod && mod.__esModule ? mod : {
5
+ "default": mod
6
+ };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", {
9
+ value: true
10
+ });
11
+ exports.DragHandle = DragHandle;
12
+ const jsx_runtime_1 = require("react/jsx-runtime");
13
+ const icons_1 = require("@snack-uikit/icons");
14
+ const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
15
+ function DragHandle(_ref) {
16
+ let {
17
+ attributes,
18
+ listeners
19
+ } = _ref;
20
+ return (0, jsx_runtime_1.jsx)("div", Object.assign({
21
+ className: styles_module_scss_1.default.dragHandle
22
+ }, attributes, listeners, {
23
+ children: (0, jsx_runtime_1.jsx)(icons_1.KebabSVG, {
24
+ className: styles_module_scss_1.default.dragIcon
25
+ })
26
+ }));
27
+ }
@@ -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 {};