@synerise/ds-table-new 1.0.6 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
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
+ # [1.1.0](https://github.com/Synerise/synerise-design/compare/@synerise/ds-table-new@1.0.6...@synerise/ds-table-new@1.1.0) (2026-04-28)
7
+
8
+ ### Features
9
+
10
+ - **table-new:** summary and id generation ([8564b73](https://github.com/Synerise/synerise-design/commit/8564b73e532b190c9c62674b6ce2725418a2c619))
11
+
6
12
  ## [1.0.6](https://github.com/Synerise/synerise-design/compare/@synerise/ds-table-new@1.0.5...@synerise/ds-table-new@1.0.6) (2026-04-24)
7
13
 
8
14
  ### Bug Fixes
@@ -246,6 +246,11 @@ export type SharedTableProps<TData, TValue> = {
246
246
  * custom "Empty data" component
247
247
  */
248
248
  emptyDataComponent?: ReactNode;
249
+ /**
250
+ * Optional summary content rendered inside a <tfoot> at the bottom of the table.
251
+ * Should be a <tr> (or fragment of <tr>s) with <td>/<th> cells matching the column layout.
252
+ */
253
+ summary?: ReactNode;
249
254
  };
250
255
  export type GlobalSelectionProps = {
251
256
  /**
@@ -1,3 +1,3 @@
1
1
  import { default as React } from 'react';
2
2
  import { BaseTableProps, TableInternalProps } from '../../Table.types';
3
- export declare const BaseTable: <TData extends object, TValue>({ infiniteScroll, cellHeight, className, itemsMenu, texts, isCounterLoading, isLoading, rowKey, title, hideTitleBar, hideTitlePart, renderCustomCounter, renderSelectionTitle, searchComponent, filterComponent, headerWithBorderTop, emptyDataComponent, headerButton, hideColumnNames, expandable, columnSizing, isColumnSizingReady, paginationProps, hasPagination, disableColumnNamesLineBreak, dataSourceTotalCount, cardStyles, tableOuterRef, withScroll, withBodyScroll, maxHeight, tableBodyScrollRef, onRowClick, getRowProps, getRowTooltipProps, searchQuery, setSearchQuery, handleSearchClear, hasBuiltInSearch, searchProps, }: BaseTableProps<TData, TValue> & TableInternalProps) => React.JSX.Element;
3
+ export declare const BaseTable: <TData extends object, TValue>({ infiniteScroll, cellHeight, className, itemsMenu, texts, isCounterLoading, isLoading, rowKey, title, hideTitleBar, hideTitlePart, renderCustomCounter, renderSelectionTitle, searchComponent, filterComponent, headerWithBorderTop, emptyDataComponent, headerButton, hideColumnNames, expandable, columnSizing, isColumnSizingReady, paginationProps, hasPagination, disableColumnNamesLineBreak, dataSourceTotalCount, cardStyles, tableOuterRef, withScroll, withBodyScroll, maxHeight, tableBodyScrollRef, onRowClick, getRowProps, getRowTooltipProps, searchQuery, setSearchQuery, handleSearchClear, hasBuiltInSearch, searchProps, summary, }: BaseTableProps<TData, TValue> & TableInternalProps) => React.JSX.Element;
@@ -11,7 +11,7 @@ import { TableHeader } from "../TableHeader/TableHeader.js";
11
11
  import { TableHorizontalScroll } from "../TableHorizontalScroll/TableHorizontalScroll.js";
12
12
  import { TableHorizontalScrollBar } from "../TableHorizontalScrollBar/TableHorizontalScrollBar.js";
13
13
  import { TablePagination } from "../TablePagination/TablePagination.js";
14
- import { StyledTable, BaseTableWrapper, TableContainer, TableBodyScrollWrapper, TableColumnsHorizontalScroll } from "./BaseTable.styles.js";
14
+ import { StyledTable, Tfoot, BaseTableWrapper, TableContainer, TableBodyScrollWrapper, TableColumnsHorizontalScroll } from "./BaseTable.styles.js";
15
15
  const BaseTable = ({
16
16
  infiniteScroll,
17
17
  cellHeight = DEFAULT_CELL_HEIGHT,
@@ -52,7 +52,8 @@ const BaseTable = ({
52
52
  setSearchQuery,
53
53
  handleSearchClear,
54
54
  hasBuiltInSearch,
55
- searchProps
55
+ searchProps,
56
+ summary
56
57
  }) => {
57
58
  const horizontalScrollRefs = useRef([]);
58
59
  const tableBodyWrapperRef = useRef(null);
@@ -95,13 +96,17 @@ const BaseTable = ({
95
96
  const tableBodyContent = /* @__PURE__ */ jsx(TableHorizontalScroll, { stickyRight: table.getRightTotalSize(), stickyLeft: table.getLeftTotalSize(), ref: (element) => {
96
97
  tableBodyWrapperRef.current = element;
97
98
  addNode(element);
98
- }, children: /* @__PURE__ */ jsx(StyledTable, { role: "table", children: isLoading ? /* @__PURE__ */ jsx(TableBodySkeleton, { wrapperRef: tableBodyWrapperRef, cellHeight }, "table-body-skeleton") : /* @__PURE__ */ jsx(TableBody, { cellHeight, infiniteScroll, emptyDataComponent, texts, onRowClick, getRowProps, getRowTooltipProps }, "table-body") }) });
99
+ }, children: /* @__PURE__ */ jsxs(StyledTable, { role: "table", children: [
100
+ isLoading ? /* @__PURE__ */ jsx(TableBodySkeleton, { wrapperRef: tableBodyWrapperRef, cellHeight }, "table-body-skeleton") : /* @__PURE__ */ jsx(TableBody, { cellHeight, infiniteScroll, emptyDataComponent, texts, onRowClick, getRowProps, getRowTooltipProps }, "table-body"),
101
+ !isLoading && summary && /* @__PURE__ */ jsx(Tfoot, { children: summary })
102
+ ] }) });
99
103
  const unifiedTableContent = /* @__PURE__ */ jsx(TableHorizontalScroll, { stickyRight: table.getRightTotalSize(), stickyLeft: table.getLeftTotalSize(), ref: (element) => {
100
104
  tableBodyWrapperRef.current = element;
101
105
  addNode(element);
102
106
  }, children: /* @__PURE__ */ jsxs(StyledTable, { role: "table", children: [
103
107
  !hideColumnNames && (!isEmpty || isLoading) && /* @__PURE__ */ jsx(TableColumns, { texts, disableColumnNamesLineBreak }),
104
- isLoading ? /* @__PURE__ */ jsx(TableBodySkeleton, { wrapperRef: tableBodyWrapperRef, cellHeight }, "table-body-skeleton") : /* @__PURE__ */ jsx(TableBody, { cellHeight, infiniteScroll, emptyDataComponent, texts, onRowClick, getRowProps, getRowTooltipProps }, "table-body")
108
+ isLoading ? /* @__PURE__ */ jsx(TableBodySkeleton, { wrapperRef: tableBodyWrapperRef, cellHeight }, "table-body-skeleton") : /* @__PURE__ */ jsx(TableBody, { cellHeight, infiniteScroll, emptyDataComponent, texts, onRowClick, getRowProps, getRowTooltipProps }, "table-body"),
109
+ !isLoading && summary && /* @__PURE__ */ jsx(Tfoot, { children: summary })
105
110
  ] }) });
106
111
  return /* @__PURE__ */ jsxs(BaseTableWrapper, { isEmpty, columnSizing, $isColumnSizingReady: isColumnSizingReady, $size: size, children: [
107
112
  /* @__PURE__ */ jsxs(TableContainer, { ref: tableOuterRef, className, withBorderTop: headerWithBorderTop, cardStyles, withScroll, $maxHeight: maxHeight, "data-testid": "ds-table-container", children: [
@@ -17,6 +17,7 @@ export declare const TableBodyScrollWrapper: import('styled-components').StyledC
17
17
  export declare const TableSkeleton: import('styled-components').StyledComponent<({ size, numberOfSkeletons, width, height, className, }: import('@synerise/ds-skeleton').SkeletonProps) => React.JSX.Element, any, {
18
18
  skeletonWidth?: string;
19
19
  }, never>;
20
+ export declare const Tfoot: import('styled-components').StyledComponent<"tfoot", any, {}, never>;
20
21
  export declare const StyledTable: import('styled-components').StyledComponent<"table", any, {}, never>;
21
22
  export declare const TableColumnsHorizontalScroll: import('styled-components').StyledComponent<import('react').ForwardRefExoticComponent<{
22
23
  children?: import('react').ReactNode;
@@ -17,13 +17,17 @@ const TableSkeleton = /* @__PURE__ */ styled(DSSkeleton).withConfig({
17
17
  displayName: "BaseTablestyles__TableSkeleton",
18
18
  componentId: "sc-1oa5lc2-3"
19
19
  })(["padding:0;", ""], (props) => props.skeletonWidth && `width: ${props.skeletonWidth};`);
20
+ const Tfoot = /* @__PURE__ */ styled.tfoot.withConfig({
21
+ displayName: "BaseTablestyles__Tfoot",
22
+ componentId: "sc-1oa5lc2-4"
23
+ })([""]);
20
24
  const StyledTable = /* @__PURE__ */ styled.table.withConfig({
21
25
  displayName: "BaseTablestyles__StyledTable",
22
- componentId: "sc-1oa5lc2-4"
23
- })(["width:var(--table-size);min-width:100%;border-spacing:0;border-collapse:separate;@keyframes ds-table-row-highlight{0%{background-color:transparent;}5%{background-color:var( --ds-highlight-color,", " );}30%{background-color:var( --ds-highlight-color,", " );}100%{background-color:transparent;}}tr.ds-table-row-highlight td{transition:background 0.3s ease-in-out;animation:ds-table-row-highlight var(--ds-highlight-duration,600ms) ease-in-out forwards;}"], (props) => props.theme.palette["blue-050"], (props) => props.theme.palette["blue-050"]);
26
+ componentId: "sc-1oa5lc2-5"
27
+ })(["width:var(--table-size);min-width:100%;border-spacing:0;table-layout:fixed;border-collapse:separate;@keyframes ds-table-row-highlight{0%{background-color:transparent;}5%{background-color:var( --ds-highlight-color,", " );}30%{background-color:var( --ds-highlight-color,", " );}100%{background-color:transparent;}}tr.ds-table-row-highlight td{transition:background 0.3s ease-in-out;animation:ds-table-row-highlight var(--ds-highlight-duration,600ms) ease-in-out forwards;}"], (props) => props.theme.palette["blue-050"], (props) => props.theme.palette["blue-050"]);
24
28
  const TableColumnsHorizontalScroll = /* @__PURE__ */ styled(TableHorizontalScroll).withConfig({
25
29
  displayName: "BaseTablestyles__TableColumnsHorizontalScroll",
26
- componentId: "sc-1oa5lc2-5"
30
+ componentId: "sc-1oa5lc2-6"
27
31
  })(["", ""], ({
28
32
  stickyData,
29
33
  isScrolled,
@@ -37,5 +41,6 @@ export {
37
41
  TableBodyScrollWrapper,
38
42
  TableColumnsHorizontalScroll,
39
43
  TableContainer,
40
- TableSkeleton
44
+ TableSkeleton,
45
+ Tfoot
41
46
  };
@@ -53,6 +53,15 @@ const useTable = ({
53
53
  getRowKey
54
54
  } = useRowKey(rowKey);
55
55
  const memoizedGetRowKey = useCallback((row, index) => getRowKey(row, index), [getRowKey]);
56
+ const columnKeyById = useMemo(() => {
57
+ const map = /* @__PURE__ */ new Map();
58
+ columns.forEach((column) => {
59
+ if (column.id) {
60
+ map.set(column.id, column.meta?.columnKey ?? column.id);
61
+ }
62
+ });
63
+ return map;
64
+ }, [columns]);
56
65
  const handleSortingChange = useCallback((updaterOrValue) => {
57
66
  setSorting((oldSorting) => {
58
67
  const newSorting = typeof updaterOrValue === "function" ? updaterOrValue(oldSorting) : updaterOrValue;
@@ -61,13 +70,14 @@ const useTable = ({
61
70
  const singleColumnSort = newSorting[0];
62
71
  const sortState = {};
63
72
  newSorting.forEach((column, index) => {
64
- sortState[column.id] = {
73
+ const key = columnKeyById.get(column.id) ?? column.id;
74
+ sortState[key] = {
65
75
  sortOrder: column.desc ? "descend" : "ascend",
66
76
  multiple: index
67
77
  };
68
78
  });
69
79
  onSort({
70
- columnKey: singleColumnSort.id,
80
+ columnKey: columnKeyById.get(singleColumnSort.id) ?? singleColumnSort.id,
71
81
  order: singleColumnSort.desc ? "descend" : "ascend"
72
82
  }, sortState);
73
83
  } else {
@@ -76,7 +86,7 @@ const useTable = ({
76
86
  }
77
87
  return newSorting;
78
88
  });
79
- }, [onSort]);
89
+ }, [onSort, columnKeyById]);
80
90
  const handleSelectionChange = useCallback((updaterOrValue) => {
81
91
  setRowSelection((oldSelection) => {
82
92
  const newSelection = typeof updaterOrValue === "function" ? updaterOrValue(oldSelection) : updaterOrValue;
@@ -18,6 +18,12 @@ declare module '@tanstack/react-table' {
18
18
  skeletonCell?: () => ReactNode;
19
19
  dataIndex?: string;
20
20
  title?: string;
21
+ /**
22
+ * External-facing column key reported back to consumers (e.g. via onSort).
23
+ * Set by `legacyColumnConfigAdapter` so that internally-disambiguated column
24
+ * ids (e.g. `${key}-${index}` for duplicate-key columns) don't leak out.
25
+ */
26
+ columnKey?: string;
21
27
  enableMultiSort?: boolean;
22
28
  /**
23
29
  * Returns tooltip props for cells in this column, or false to disable tooltip.
@@ -91,6 +91,7 @@ const legacyColumnConfigAdapter = (columns) => {
91
91
  getCellTooltipProps: column.getCellTooltipProps,
92
92
  dataIndex: column.dataIndex,
93
93
  title: typeof column.title === "string" ? column.title : void 0,
94
+ columnKey: `${column.id ?? column.key ?? (Array.isArray(column.dataIndex) ? column.dataIndex.join(".") : column.dataIndex)}`,
94
95
  childCell: (info) => {
95
96
  if (column.childRender) {
96
97
  const rowData = {
@@ -107,7 +108,7 @@ const legacyColumnConfigAdapter = (columns) => {
107
108
  ...sortingConfig,
108
109
  size: calculatePixels(column.width),
109
110
  ...column,
110
- id: `${column.id || column.key || `${column.dataIndex}-${index}`}`
111
+ id: `${column.id || `${column.key ?? column.dataIndex}-${index}`}`
111
112
  };
112
113
  });
113
114
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-table-new",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
4
  "description": "TableNew UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "Synerise/synerise-design",
@@ -34,27 +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.49",
38
- "@synerise/ds-button": "^1.5.23",
39
- "@synerise/ds-checkbox": "^1.2.26",
40
- "@synerise/ds-copy-icon": "^1.2.7",
41
- "@synerise/ds-dropdown": "^1.3.8",
37
+ "@synerise/ds-badge": "^1.0.50",
38
+ "@synerise/ds-button": "^1.5.24",
39
+ "@synerise/ds-checkbox": "^1.2.27",
40
+ "@synerise/ds-copy-icon": "^1.2.8",
41
+ "@synerise/ds-dropdown": "^1.3.9",
42
42
  "@synerise/ds-flag": "^1.0.10",
43
- "@synerise/ds-icon": "^1.17.0",
44
- "@synerise/ds-inline-alert": "^1.1.19",
45
- "@synerise/ds-input": "^1.7.3",
46
- "@synerise/ds-input-number": "^1.2.40",
43
+ "@synerise/ds-icon": "^1.17.1",
44
+ "@synerise/ds-inline-alert": "^1.1.20",
45
+ "@synerise/ds-input": "^1.7.4",
46
+ "@synerise/ds-input-number": "^1.2.41",
47
47
  "@synerise/ds-loader": "^1.0.15",
48
- "@synerise/ds-modal": "^1.4.7",
49
- "@synerise/ds-pagination": "^1.0.58",
50
- "@synerise/ds-result": "^1.0.54",
51
- "@synerise/ds-scrollbar": "^1.3.1",
52
- "@synerise/ds-search": "^1.5.17",
53
- "@synerise/ds-skeleton": "^1.0.50",
54
- "@synerise/ds-tag": "^1.4.23",
55
- "@synerise/ds-tags": "^1.5.34",
56
- "@synerise/ds-tooltip": "^1.4.15",
57
- "@synerise/ds-typography": "^1.1.18",
48
+ "@synerise/ds-modal": "^1.4.8",
49
+ "@synerise/ds-pagination": "^1.0.59",
50
+ "@synerise/ds-result": "^1.0.55",
51
+ "@synerise/ds-scrollbar": "^1.3.2",
52
+ "@synerise/ds-search": "^1.5.18",
53
+ "@synerise/ds-skeleton": "^1.0.51",
54
+ "@synerise/ds-tag": "^1.4.24",
55
+ "@synerise/ds-tags": "^1.5.35",
56
+ "@synerise/ds-tooltip": "^1.4.16",
57
+ "@synerise/ds-typography": "^1.1.19",
58
58
  "@synerise/ds-utils": "^1.8.0",
59
59
  "@tanstack/react-table": "^8.21.3",
60
60
  "@tanstack/react-virtual": "^3.13.12",
@@ -71,5 +71,5 @@
71
71
  "react-intl": ">= 3.12.0 <= 6.8",
72
72
  "styled-components": "^5.3.3"
73
73
  },
74
- "gitHead": "71415efab30b82d23558094f18c9551a15234be3"
74
+ "gitHead": "25cf79a6df348141419f397813e4f6a5533deb5f"
75
75
  }