@synerise/ds-table-new 1.2.0 → 1.3.1

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 (26) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/components/BaseTable/BaseTable.js +26 -50
  3. package/dist/components/BaseTable/BaseTable.styles.d.ts +5 -2
  4. package/dist/components/BaseTable/BaseTable.styles.js +1 -1
  5. package/dist/components/BaseTable/StickyTableContent.d.ts +8 -0
  6. package/dist/components/BaseTable/StickyTableContent.js +70 -0
  7. package/dist/components/BaseTable/UnifiedTableContent.d.ts +9 -0
  8. package/dist/components/BaseTable/UnifiedTableContent.js +46 -0
  9. package/dist/components/Cell/FlagLabel/FlagLabelCell.styles.js +1 -1
  10. package/dist/components/Cell/IconLabel/IconLabel.js +2 -2
  11. package/dist/components/Cell/IconLabel/IconLabel.styles.d.ts +1 -0
  12. package/dist/components/Cell/IconLabel/IconLabel.styles.js +6 -1
  13. package/dist/components/Cell/StatusLabel/StatusLabel.styles.js +1 -1
  14. package/dist/components/TableBody/TableRow/TableRow.js +7 -1
  15. package/dist/components/TableColumns/TableColumns.js +9 -2
  16. package/dist/components/TableHorizontalScroll/TableHorizontalScroll.d.ts +2 -1
  17. package/dist/components/TableHorizontalScroll/TableHorizontalScroll.js +2 -1
  18. package/dist/components/TableHorizontalScroll/TableHorizontalScroll.styles.d.ts +3 -1
  19. package/dist/components/TableHorizontalScroll/TableHorizontalScroll.styles.js +1 -1
  20. package/dist/components/TreeTable/TreeTable.d.ts +1 -1
  21. package/dist/components/TreeTable/TreeTable.js +10 -7
  22. package/dist/components/TreeTable/TreeTable.types.d.ts +10 -1
  23. package/dist/hooks/useTable.js +10 -0
  24. package/dist/utils/getUnifiedColumnSizingStyle.d.ts +3 -0
  25. package/dist/utils/getUnifiedColumnSizingStyle.js +30 -0
  26. package/package.json +8 -8
package/CHANGELOG.md CHANGED
@@ -3,6 +3,18 @@
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.3.1](https://github.com/Synerise/synerise-design/compare/@synerise/ds-table-new@1.3.0...@synerise/ds-table-new@1.3.1) (2026-05-19)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **table-new:** reinstate optional indent without expander ([015517a](https://github.com/Synerise/synerise-design/commit/015517a00a7d9dd1a4b50e7dad20c7fb71ede2d8))
11
+
12
+ # [1.3.0](https://github.com/Synerise/synerise-design/compare/@synerise/ds-table-new@1.2.0...@synerise/ds-table-new@1.3.0) (2026-05-15)
13
+
14
+ ### Features
15
+
16
+ - **table-new:** render column widths via <colgroup> in unified mode ([5f0fa79](https://github.com/Synerise/synerise-design/commit/5f0fa79a5ef1da6506a5ae3bd0c624c9b794866f))
17
+
6
18
  # [1.2.0](https://github.com/Synerise/synerise-design/compare/@synerise/ds-table-new@1.1.4...@synerise/ds-table-new@1.2.0) (2026-05-13)
7
19
 
8
20
  ### Features
@@ -1,17 +1,15 @@
1
- import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import { useRef, useEffect, useCallback } from "react";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useRef, useCallback } from "react";
3
3
  import { DEFAULT_CELL_HEIGHT } from "../../Table.const.js";
4
4
  import { useStickyContext } from "../../contexts/StickyContext.js";
5
5
  import { useTableContext } from "../../contexts/TableContext.js";
6
6
  import { useScrollSync } from "../../hooks/useScrollSync.js";
7
- import { TableBody } from "../TableBody/TableBody.js";
8
- import { TableBodySkeleton } from "../TableBody/TableBodySkeleton/TableBodySkeleton.js";
9
- import { TableColumns } from "../TableColumns/TableColumns.js";
10
7
  import { TableHeader } from "../TableHeader/TableHeader.js";
11
- import { TableHorizontalScroll } from "../TableHorizontalScroll/TableHorizontalScroll.js";
12
8
  import { TableHorizontalScrollBar } from "../TableHorizontalScrollBar/TableHorizontalScrollBar.js";
13
9
  import { TablePagination } from "../TablePagination/TablePagination.js";
14
- import { StyledTable, Tfoot, BaseTableWrapper, TableContainer, TableBodyScrollWrapper, TableColumnsHorizontalScroll } from "./BaseTable.styles.js";
10
+ import { BaseTableWrapper, TableContainer } from "./BaseTable.styles.js";
11
+ import { StickyTableContent } from "./StickyTableContent.js";
12
+ import { UnifiedTableContent } from "./UnifiedTableContent.js";
15
13
  const BaseTable = ({
16
14
  infiniteScroll,
17
15
  cellHeight = DEFAULT_CELL_HEIGHT,
@@ -56,19 +54,14 @@ const BaseTable = ({
56
54
  summary
57
55
  }) => {
58
56
  const horizontalScrollRefs = useRef([]);
59
- const tableBodyWrapperRef = useRef(null);
60
- const tableColumnsWrapperRef = useRef(null);
61
57
  useScrollSync(horizontalScrollRefs);
62
58
  const {
63
59
  table,
64
60
  rowVirtualizer
65
61
  } = useTableContext();
66
62
  const stickyContext = useStickyContext();
67
- const stickyContextRef = useRef(stickyContext);
68
63
  const useUnifiedScroll = !stickyContext;
69
- useEffect(() => {
70
- stickyContextRef.current = stickyContext;
71
- }, [stickyContext]);
64
+ const useColgroupLayout = useUnifiedScroll && !rowVirtualizer;
72
65
  const addNode = useCallback((node) => {
73
66
  if (node && !horizontalScrollRefs.current.includes(node)) {
74
67
  horizontalScrollRefs.current.push(node);
@@ -76,45 +69,28 @@ const BaseTable = ({
76
69
  }, []);
77
70
  const size = Object.values(columnSizing).reduce((sum, n) => sum + n, 0);
78
71
  const isEmpty = !table.getRowModel().flatRows.length;
79
- const handleRef = useCallback((element) => {
80
- tableColumnsWrapperRef.current = element;
81
- if (!element) {
82
- return;
83
- }
84
- const ctx = stickyContextRef.current;
85
- if (element.clientHeight && ctx && ctx.stickyData.columnHeadersHeight !== element.clientHeight) {
86
- const {
87
- setStickyData
88
- } = ctx;
89
- setStickyData((prevValue) => ({
90
- ...prevValue,
91
- columnHeadersHeight: element.clientHeight
92
- }));
93
- }
94
- addNode(element);
95
- }, [addNode]);
96
- const tableBodyContent = /* @__PURE__ */ jsx(TableHorizontalScroll, { stickyRight: table.getRightTotalSize(), stickyLeft: table.getLeftTotalSize(), ref: (element) => {
97
- tableBodyWrapperRef.current = element;
98
- addNode(element);
99
- }, children: /* @__PURE__ */ jsxs(StyledTable, { role: "table", className: "ds-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
- ] }) });
103
- const unifiedTableContent = /* @__PURE__ */ jsx(TableHorizontalScroll, { stickyRight: table.getRightTotalSize(), stickyLeft: table.getLeftTotalSize(), ref: (element) => {
104
- tableBodyWrapperRef.current = element;
105
- addNode(element);
106
- }, children: /* @__PURE__ */ jsxs(StyledTable, { role: "table", className: "ds-table", children: [
107
- !hideColumnNames && (!isEmpty || isLoading) && /* @__PURE__ */ jsx(TableColumns, { texts, disableColumnNamesLineBreak }),
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 })
110
- ] }) });
111
- return /* @__PURE__ */ jsxs(BaseTableWrapper, { isEmpty, columnSizing, $isColumnSizingReady: isColumnSizingReady, $size: size, children: [
72
+ const contentProps = {
73
+ infiniteScroll,
74
+ cellHeight,
75
+ texts,
76
+ isLoading,
77
+ emptyDataComponent,
78
+ onRowClick,
79
+ getRowProps,
80
+ getRowTooltipProps,
81
+ summary,
82
+ hideColumnNames,
83
+ disableColumnNamesLineBreak,
84
+ withBodyScroll,
85
+ maxHeight,
86
+ tableBodyScrollRef,
87
+ addNode,
88
+ isEmpty
89
+ };
90
+ return /* @__PURE__ */ jsxs(BaseTableWrapper, { isEmpty, columnSizing: useColgroupLayout ? {} : columnSizing, $isColumnSizingReady: isColumnSizingReady, $size: useColgroupLayout ? void 0 : size, children: [
112
91
  /* @__PURE__ */ jsxs(TableContainer, { ref: tableOuterRef, className, withBorderTop: headerWithBorderTop, cardStyles, withScroll, $maxHeight: maxHeight, "data-testid": "ds-table-container", children: [
113
92
  !hideTitleBar && /* @__PURE__ */ jsx(TableHeader, { itemsMenu, texts, childrenColumnName: expandable?.childrenColumnName, isCounterLoading, isLoading, rowKey, title, hideTitlePart, renderCustomCounter, renderSelectionTitle, searchComponent, filterComponent, headerButton, dataSourceTotalCount, searchQuery, setSearchQuery, handleSearchClear, hasBuiltInSearch, searchProps }),
114
- useUnifiedScroll ? withBodyScroll ? /* @__PURE__ */ jsx(TableBodyScrollWrapper, { ref: tableBodyScrollRef, $maxHeight: maxHeight, children: unifiedTableContent }) : unifiedTableContent : /* @__PURE__ */ jsxs(Fragment, { children: [
115
- !hideColumnNames && (!isEmpty || isLoading) && /* @__PURE__ */ jsx(TableColumnsHorizontalScroll, { stickyRight: table.getRightTotalSize(), stickyLeft: table.getLeftTotalSize(), stickyData: stickyContext?.stickyData, isScrolled: rowVirtualizer?.scrollOffset, ref: handleRef, children: /* @__PURE__ */ jsx(StyledTable, { role: "table", className: "ds-table", children: /* @__PURE__ */ jsx(TableColumns, { texts, disableColumnNamesLineBreak }) }) }),
116
- withBodyScroll ? /* @__PURE__ */ jsx(TableBodyScrollWrapper, { ref: tableBodyScrollRef, $maxHeight: maxHeight, children: tableBodyContent }) : tableBodyContent
117
- ] }),
93
+ useUnifiedScroll ? /* @__PURE__ */ jsx(UnifiedTableContent, { useColgroupLayout, ...contentProps }) : /* @__PURE__ */ jsx(StickyTableContent, { ...contentProps }),
118
94
  hasPagination && /* @__PURE__ */ jsx(TablePagination, { ...paginationProps })
119
95
  ] }),
120
96
  !isEmpty && !!stickyContext && /* @__PURE__ */ jsx(TableHorizontalScrollBar, { contentRef: (element) => addNode(element) })
@@ -18,12 +18,15 @@ export declare const TableSkeleton: import('styled-components').StyledComponent<
18
18
  skeletonWidth?: string;
19
19
  }, never>;
20
20
  export declare const Tfoot: import('styled-components').StyledComponent<"tfoot", any, {}, never>;
21
- export declare const StyledTable: import('styled-components').StyledComponent<"table", any, {}, never>;
21
+ export declare const StyledTable: import('styled-components').StyledComponent<"table", any, {
22
+ $tableLayoutAuto?: boolean;
23
+ }, never>;
22
24
  export declare const TableColumnsHorizontalScroll: import('styled-components').StyledComponent<import('react').ForwardRefExoticComponent<{
23
25
  children?: import('react').ReactNode;
24
26
  stickyLeft?: number;
25
27
  stickyRight?: number;
26
- } & Omit<import('react').HTMLAttributes<HTMLDivElement>, "children" | "stickyLeft" | "stickyRight"> & import('@synerise/ds-utils').DataAttributes & import('react').RefAttributes<HTMLDivElement>>, any, {
28
+ nativeScrollbar?: boolean;
29
+ } & Omit<import('react').HTMLAttributes<HTMLDivElement>, "children" | "nativeScrollbar" | "stickyLeft" | "stickyRight"> & import('@synerise/ds-utils').DataAttributes & import('react').RefAttributes<HTMLDivElement>>, any, {
27
30
  stickyData?: StickyData;
28
31
  isScrolled?: number | null;
29
32
  }, never>;
@@ -24,7 +24,7 @@ const Tfoot = /* @__PURE__ */ styled.tfoot.withConfig({
24
24
  const StyledTable = /* @__PURE__ */ styled.table.withConfig({
25
25
  displayName: "BaseTablestyles__StyledTable",
26
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"]);
27
+ })(["width:var(--table-size);min-width:100%;border-spacing:0;table-layout:", ";border-collapse:separate;", " ", " 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.$tableLayoutAuto ? "auto" : "fixed", (props) => props.$tableLayoutAuto && css(["&& tr{display:table-row;width:auto;table-layout:auto;}&& thead{display:table-header-group;}&& tbody{display:table-row-group;}&& th,&& td{display:table-cell;}"]), (props) => css(["@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;}}"], props.theme.palette["blue-050"], props.theme.palette["blue-050"]));
28
28
  const TableColumnsHorizontalScroll = /* @__PURE__ */ styled(TableHorizontalScroll).withConfig({
29
29
  displayName: "BaseTablestyles__TableColumnsHorizontalScroll",
30
30
  componentId: "sc-1oa5lc2-6"
@@ -0,0 +1,8 @@
1
+ import { default as React } from 'react';
2
+ import { BaseTableProps, TableInternalProps } from '../../Table.types';
3
+ export type StickyTableContentProps<TData, TValue> = Pick<BaseTableProps<TData, TValue> & TableInternalProps, 'infiniteScroll' | 'texts' | 'isLoading' | 'emptyDataComponent' | 'onRowClick' | 'getRowProps' | 'getRowTooltipProps' | 'summary' | 'hideColumnNames' | 'disableColumnNamesLineBreak' | 'withBodyScroll' | 'maxHeight' | 'tableBodyScrollRef'> & {
4
+ cellHeight: number;
5
+ addNode: (node: HTMLDivElement | null) => void;
6
+ isEmpty: boolean;
7
+ };
8
+ export declare const StickyTableContent: <TData extends object, TValue>({ infiniteScroll, cellHeight, texts, isLoading, emptyDataComponent, onRowClick, getRowProps, getRowTooltipProps, summary, hideColumnNames, disableColumnNamesLineBreak, withBodyScroll, maxHeight, tableBodyScrollRef, addNode, isEmpty, }: StickyTableContentProps<TData, TValue>) => React.JSX.Element;
@@ -0,0 +1,70 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { useRef, useEffect, useCallback } from "react";
3
+ import { useStickyContext } from "../../contexts/StickyContext.js";
4
+ import { useTableContext } from "../../contexts/TableContext.js";
5
+ import { TableBody } from "../TableBody/TableBody.js";
6
+ import { TableBodySkeleton } from "../TableBody/TableBodySkeleton/TableBodySkeleton.js";
7
+ import { TableColumns } from "../TableColumns/TableColumns.js";
8
+ import { TableHorizontalScroll } from "../TableHorizontalScroll/TableHorizontalScroll.js";
9
+ import { StyledTable, Tfoot, TableColumnsHorizontalScroll, TableBodyScrollWrapper } from "./BaseTable.styles.js";
10
+ const StickyTableContent = ({
11
+ infiniteScroll,
12
+ cellHeight,
13
+ texts,
14
+ isLoading,
15
+ emptyDataComponent,
16
+ onRowClick,
17
+ getRowProps,
18
+ getRowTooltipProps,
19
+ summary,
20
+ hideColumnNames,
21
+ disableColumnNamesLineBreak,
22
+ withBodyScroll,
23
+ maxHeight,
24
+ tableBodyScrollRef,
25
+ addNode,
26
+ isEmpty
27
+ }) => {
28
+ const {
29
+ table,
30
+ rowVirtualizer
31
+ } = useTableContext();
32
+ const stickyContext = useStickyContext();
33
+ const stickyContextRef = useRef(stickyContext);
34
+ const tableBodyWrapperRef = useRef(null);
35
+ const tableColumnsWrapperRef = useRef(null);
36
+ useEffect(() => {
37
+ stickyContextRef.current = stickyContext;
38
+ }, [stickyContext]);
39
+ const handleColumnsRef = useCallback((element) => {
40
+ tableColumnsWrapperRef.current = element;
41
+ if (!element) {
42
+ return;
43
+ }
44
+ const ctx = stickyContextRef.current;
45
+ if (element.clientHeight && ctx && ctx.stickyData.columnHeadersHeight !== element.clientHeight) {
46
+ const {
47
+ setStickyData
48
+ } = ctx;
49
+ setStickyData((prevValue) => ({
50
+ ...prevValue,
51
+ columnHeadersHeight: element.clientHeight
52
+ }));
53
+ }
54
+ addNode(element);
55
+ }, [addNode]);
56
+ const body = /* @__PURE__ */ jsx(TableHorizontalScroll, { stickyRight: table.getRightTotalSize(), stickyLeft: table.getLeftTotalSize(), ref: (element) => {
57
+ tableBodyWrapperRef.current = element;
58
+ addNode(element);
59
+ }, children: /* @__PURE__ */ jsxs(StyledTable, { role: "table", className: "ds-table", children: [
60
+ isLoading ? /* @__PURE__ */ jsx(TableBodySkeleton, { wrapperRef: tableBodyWrapperRef, cellHeight }, "table-body-skeleton") : /* @__PURE__ */ jsx(TableBody, { cellHeight, infiniteScroll, emptyDataComponent, texts, onRowClick, getRowProps, getRowTooltipProps }, "table-body"),
61
+ !isLoading && summary && /* @__PURE__ */ jsx(Tfoot, { children: summary })
62
+ ] }) });
63
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
64
+ !hideColumnNames && (!isEmpty || isLoading) && /* @__PURE__ */ jsx(TableColumnsHorizontalScroll, { stickyRight: table.getRightTotalSize(), stickyLeft: table.getLeftTotalSize(), stickyData: stickyContext?.stickyData, isScrolled: rowVirtualizer?.scrollOffset, ref: handleColumnsRef, children: /* @__PURE__ */ jsx(StyledTable, { role: "table", className: "ds-table", children: /* @__PURE__ */ jsx(TableColumns, { texts, disableColumnNamesLineBreak }) }) }),
65
+ withBodyScroll ? /* @__PURE__ */ jsx(TableBodyScrollWrapper, { ref: tableBodyScrollRef, $maxHeight: maxHeight, children: body }) : body
66
+ ] });
67
+ };
68
+ export {
69
+ StickyTableContent
70
+ };
@@ -0,0 +1,9 @@
1
+ import { default as React } from 'react';
2
+ import { BaseTableProps, TableInternalProps } from '../../Table.types';
3
+ export type UnifiedTableContentProps<TData, TValue> = Pick<BaseTableProps<TData, TValue> & TableInternalProps, 'infiniteScroll' | 'texts' | 'isLoading' | 'emptyDataComponent' | 'onRowClick' | 'getRowProps' | 'getRowTooltipProps' | 'summary' | 'hideColumnNames' | 'disableColumnNamesLineBreak' | 'withBodyScroll' | 'maxHeight' | 'tableBodyScrollRef'> & {
4
+ cellHeight: number;
5
+ addNode: (node: HTMLDivElement | null) => void;
6
+ isEmpty: boolean;
7
+ useColgroupLayout: boolean;
8
+ };
9
+ export declare const UnifiedTableContent: <TData extends object, TValue>({ infiniteScroll, cellHeight, texts, isLoading, emptyDataComponent, onRowClick, getRowProps, getRowTooltipProps, summary, hideColumnNames, disableColumnNamesLineBreak, withBodyScroll, maxHeight, tableBodyScrollRef, addNode, isEmpty, useColgroupLayout, }: UnifiedTableContentProps<TData, TValue>) => React.JSX.Element;
@@ -0,0 +1,46 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useRef } from "react";
3
+ import { useTableContext } from "../../contexts/TableContext.js";
4
+ import { getUnifiedColumnSizingStyle } from "../../utils/getUnifiedColumnSizingStyle.js";
5
+ import { TableBody } from "../TableBody/TableBody.js";
6
+ import { TableBodySkeleton } from "../TableBody/TableBodySkeleton/TableBodySkeleton.js";
7
+ import { TableColumns } from "../TableColumns/TableColumns.js";
8
+ import { TableHorizontalScroll } from "../TableHorizontalScroll/TableHorizontalScroll.js";
9
+ import { StyledTable, Tfoot, TableBodyScrollWrapper } from "./BaseTable.styles.js";
10
+ const UnifiedTableContent = ({
11
+ infiniteScroll,
12
+ cellHeight,
13
+ texts,
14
+ isLoading,
15
+ emptyDataComponent,
16
+ onRowClick,
17
+ getRowProps,
18
+ getRowTooltipProps,
19
+ summary,
20
+ hideColumnNames,
21
+ disableColumnNamesLineBreak,
22
+ withBodyScroll,
23
+ maxHeight,
24
+ tableBodyScrollRef,
25
+ addNode,
26
+ isEmpty,
27
+ useColgroupLayout
28
+ }) => {
29
+ const {
30
+ table
31
+ } = useTableContext();
32
+ const tableBodyWrapperRef = useRef(null);
33
+ const body = /* @__PURE__ */ jsx(TableHorizontalScroll, { stickyRight: table.getRightTotalSize(), stickyLeft: table.getLeftTotalSize(), ref: (element) => {
34
+ tableBodyWrapperRef.current = element;
35
+ addNode(element);
36
+ }, nativeScrollbar: useColgroupLayout, children: /* @__PURE__ */ jsxs(StyledTable, { role: "table", className: "ds-table", $tableLayoutAuto: useColgroupLayout, children: [
37
+ useColgroupLayout && !isEmpty && /* @__PURE__ */ jsx("colgroup", { children: table.getVisibleLeafColumns().map((column, index) => /* @__PURE__ */ jsx("col", { style: getUnifiedColumnSizingStyle(column) }, column.id ?? `col-${index}`)) }),
38
+ !hideColumnNames && (!isEmpty || isLoading) && /* @__PURE__ */ jsx(TableColumns, { texts, disableColumnNamesLineBreak }),
39
+ isLoading ? /* @__PURE__ */ jsx(TableBodySkeleton, { wrapperRef: tableBodyWrapperRef, cellHeight }, "table-body-skeleton") : /* @__PURE__ */ jsx(TableBody, { cellHeight, infiniteScroll, emptyDataComponent, texts, onRowClick, getRowProps, getRowTooltipProps }, "table-body"),
40
+ !isLoading && summary && /* @__PURE__ */ jsx(Tfoot, { children: summary })
41
+ ] }) });
42
+ return withBodyScroll ? /* @__PURE__ */ jsx(TableBodyScrollWrapper, { ref: tableBodyScrollRef, $maxHeight: maxHeight, children: body }) : body;
43
+ };
44
+ export {
45
+ UnifiedTableContent
46
+ };
@@ -2,7 +2,7 @@ import styled from "styled-components";
2
2
  const FlagLabel = /* @__PURE__ */ styled.div.withConfig({
3
3
  displayName: "FlagLabelCellstyles__FlagLabel",
4
4
  componentId: "sc-17tek3-0"
5
- })(["display:flex;align-items:center;justify-content:flex-start;span{margin-left:8px;}"]);
5
+ })(["display:flex;align-items:center;justify-content:flex-start;span{margin-left:8px;min-width:0;overflow:hidden;text-overflow:ellipsis;}"]);
6
6
  export {
7
7
  FlagLabel
8
8
  };
@@ -1,6 +1,6 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import Icon from "@synerise/ds-icon";
3
- import { IconLabelCell as IconLabelCell$1 } from "./IconLabel.styles.js";
3
+ import { IconLabelCell as IconLabelCell$1, Label } from "./IconLabel.styles.js";
4
4
  const IconLabelCell = ({
5
5
  label,
6
6
  icon,
@@ -8,7 +8,7 @@ const IconLabelCell = ({
8
8
  ...htmlAttributes
9
9
  }) => /* @__PURE__ */ jsxs(IconLabelCell$1, { isDisabled: disabled, ...htmlAttributes, children: [
10
10
  icon && /* @__PURE__ */ jsx(Icon, { ...icon }),
11
- label && /* @__PURE__ */ jsx("span", { children: label })
11
+ label && /* @__PURE__ */ jsx(Label, { children: label })
12
12
  ] });
13
13
  export {
14
14
  IconLabelCell
@@ -1,3 +1,4 @@
1
1
  export declare const IconLabelCell: import('styled-components').StyledComponent<"span", any, {
2
2
  isDisabled?: boolean;
3
3
  }, never>;
4
+ export declare const Label: import('styled-components').StyledComponent<"span", any, {}, never>;
@@ -4,6 +4,11 @@ const IconLabelCell = /* @__PURE__ */ styled.span.withConfig({
4
4
  displayName: "IconLabelstyles__IconLabelCell",
5
5
  componentId: "sc-1ydzkrb-0"
6
6
  })(["display:flex;flex-direction:row;align-items:center;justify-content:flex-start;", " ", "{margin-right:8px;}"], (props) => props.isDisabled && "opacity: 0.4;", IconContainer);
7
+ const Label = /* @__PURE__ */ styled.span.withConfig({
8
+ displayName: "IconLabelstyles__Label",
9
+ componentId: "sc-1ydzkrb-1"
10
+ })(["min-width:0;overflow:hidden;text-overflow:ellipsis;"]);
7
11
  export {
8
- IconLabelCell
12
+ IconLabelCell,
13
+ Label
9
14
  };
@@ -6,7 +6,7 @@ const StatusLabel = /* @__PURE__ */ styled.div.withConfig({
6
6
  const Label = /* @__PURE__ */ styled.span.withConfig({
7
7
  displayName: "StatusLabelstyles__Label",
8
8
  componentId: "sc-1jilb6u-1"
9
- })(["color:", ";font-weight:500;font-size:13px;line-height:1.38;"], (props) => props.theme.palette["grey-700"]);
9
+ })(["color:", ";font-weight:500;font-size:13px;line-height:1.38;min-width:0;text-overflow:ellipsis;overflow:hidden;"], (props) => props.theme.palette["grey-700"]);
10
10
  export {
11
11
  Label,
12
12
  StatusLabel
@@ -1,6 +1,8 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import Tooltip from "@synerise/ds-tooltip";
3
3
  import { flexRender } from "@tanstack/react-table";
4
+ import { useStickyContext } from "../../../contexts/StickyContext.js";
5
+ import { getUnifiedColumnSizingStyle } from "../../../utils/getUnifiedColumnSizingStyle.js";
4
6
  import { isSorted } from "../../../utils/sort.js";
5
7
  import { TableCell } from "../TableCell/TableCell.js";
6
8
  import { Tr } from "./TableRow.styles.js";
@@ -10,6 +12,7 @@ const TableRow = ({
10
12
  getRowProps,
11
13
  getRowTooltipProps
12
14
  }) => {
15
+ const isUnifiedTableContent = !useStickyContext();
13
16
  const customRowProps = getRowProps?.(row.original) ?? {};
14
17
  const {
15
18
  onClick: customOnClick,
@@ -27,7 +30,10 @@ const TableRow = ({
27
30
  const isColumnSorted = isSorted(cell.column);
28
31
  const cellContent = flexRender(cell.column.columnDef.cell, cell.getContext());
29
32
  const cellTooltipProps = cell.column.columnDef.meta?.getCellTooltipProps?.(row.original);
30
- return /* @__PURE__ */ jsx(TableCell, { isSorted: isColumnSorted, headerIndex: columnIndex, cellKey: cellId, width: cell.column.getSize(), isPinned: cell.column.getIsPinned(), rightOffset: cell.column.getAfter("right"), leftOffset: cell.column.getStart("left"), align: cell.column.columnDef.meta?.align, style: cell.column.columnDef.meta?.style, "data-cell-id": cellId, "data-column-dataindex": cell.column.columnDef.meta?.dataIndex, "data-column-title": cell.column.columnDef.meta?.title, children: cellTooltipProps ? /* @__PURE__ */ jsx(Tooltip, { ...cellTooltipProps, children: /* @__PURE__ */ jsx("span", { children: cellContent }) }) : cellContent }, cellId);
33
+ return /* @__PURE__ */ jsx(TableCell, { isSorted: isColumnSorted, headerIndex: columnIndex, cellKey: cellId, width: isUnifiedTableContent ? void 0 : cell.column.getSize(), isPinned: cell.column.getIsPinned(), rightOffset: cell.column.getAfter("right"), leftOffset: cell.column.getStart("left"), align: cell.column.columnDef.meta?.align, style: isUnifiedTableContent ? {
34
+ ...getUnifiedColumnSizingStyle(cell.column),
35
+ ...cell.column.columnDef.meta?.style
36
+ } : cell.column.columnDef.meta?.style, "data-cell-id": cellId, "data-column-dataindex": cell.column.columnDef.meta?.dataIndex, "data-column-title": cell.column.columnDef.meta?.title, children: cellTooltipProps ? /* @__PURE__ */ jsx(Tooltip, { ...cellTooltipProps, children: /* @__PURE__ */ jsx("span", { children: cellContent }) }) : cellContent }, cellId);
31
37
  }) }, row.id);
32
38
  const rowTooltipProps = getRowTooltipProps?.(row.original);
33
39
  return rowTooltipProps ? /* @__PURE__ */ jsx(Tooltip, { ...rowTooltipProps, children: rowContent }) : rowContent;
@@ -1,6 +1,8 @@
1
1
  import { jsx, Fragment, jsxs } from "react/jsx-runtime";
2
2
  import { flexRender } from "@tanstack/react-table";
3
+ import { useStickyContext } from "../../contexts/StickyContext.js";
3
4
  import { useTableContext } from "../../contexts/TableContext.js";
5
+ import { getUnifiedColumnSizingStyle } from "../../utils/getUnifiedColumnSizingStyle.js";
4
6
  import { isSorted } from "../../utils/sort.js";
5
7
  import { TableColumnSorter } from "./TableColumnSorter/TableColumnSorter.js";
6
8
  import { THead, Tr, Th, HeaderWrapper, Label } from "./TableColumns.styles.js";
@@ -9,8 +11,10 @@ const TableColumns = ({
9
11
  disableColumnNamesLineBreak
10
12
  }) => {
11
13
  const {
12
- table
14
+ table,
15
+ rowVirtualizer
13
16
  } = useTableContext();
17
+ const useColgroupSizing = !useStickyContext() && !rowVirtualizer;
14
18
  const headerGroups = table.getHeaderGroups();
15
19
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(THead, { className: "ds-table-head", role: "rowgroup", "data-testid": "ds-table-columns", children: headerGroups.map((headerGroup) => /* @__PURE__ */ jsx(Tr, { role: "row", className: "ds-table-row", children: headerGroup.headers.map((header, columnIndex) => {
16
20
  const id = header.id;
@@ -18,7 +22,10 @@ const TableColumns = ({
18
22
  const hasSorter = header.column.getCanSort();
19
23
  const isColumnSorted = isSorted(header.column);
20
24
  const align = header.column.columnDef.meta?.align;
21
- return /* @__PURE__ */ jsx(Th, { className: "ds-table-header-cell", headerIndex: columnIndex, colSpan: header.colSpan, style: header.column.columnDef.meta?.style, isPinned: header.column.getIsPinned(), leftOffset: header.column.getStart("left"), rightOffset: header.column.getAfter("right"), isSorted: isColumnSorted, hasSorter, $align: align, "data-sticky": isSticky ? "true" : void 0, role: "columnheader", children: /* @__PURE__ */ jsxs(HeaderWrapper, { $align: align, children: [
25
+ return /* @__PURE__ */ jsx(Th, { className: "ds-table-header-cell", headerIndex: columnIndex, colSpan: header.colSpan, style: useColgroupSizing ? {
26
+ ...getUnifiedColumnSizingStyle(header.column),
27
+ ...header.column.columnDef.meta?.style
28
+ } : header.column.columnDef.meta?.style, isPinned: header.column.getIsPinned(), leftOffset: header.column.getStart("left"), rightOffset: header.column.getAfter("right"), isSorted: isColumnSorted, hasSorter, $align: align, "data-sticky": isSticky ? "true" : void 0, role: "columnheader", children: /* @__PURE__ */ jsxs(HeaderWrapper, { $align: align, children: [
22
29
  /* @__PURE__ */ jsx(Label, { disableColumnNamesLineBreak, children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()) }),
23
30
  hasSorter && (header.column.columnDef.meta?.renderCustomSortButton?.(header.getContext()) || /* @__PURE__ */ jsx(TableColumnSorter, { texts, column: header.column }))
24
31
  ] }) }, id);
@@ -3,4 +3,5 @@ export declare const TableHorizontalScroll: React.ForwardRefExoticComponent<{
3
3
  children?: ReactNode;
4
4
  stickyLeft?: number;
5
5
  stickyRight?: number;
6
- } & Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "stickyLeft" | "stickyRight"> & import('@synerise/ds-utils').DataAttributes & React.RefAttributes<HTMLDivElement>>;
6
+ nativeScrollbar?: boolean;
7
+ } & Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "nativeScrollbar" | "stickyLeft" | "stickyRight"> & import('@synerise/ds-utils').DataAttributes & React.RefAttributes<HTMLDivElement>>;
@@ -7,6 +7,7 @@ const TableHorizontalScroll = forwardRef(({
7
7
  children,
8
8
  stickyLeft = 0,
9
9
  stickyRight = 0,
10
+ nativeScrollbar,
10
11
  ...rest
11
12
  }, ref) => {
12
13
  const [isMaxLeft, setIsMaxLeft] = useState(true);
@@ -28,7 +29,7 @@ const TableHorizontalScroll = forwardRef(({
28
29
  useResizeObserver(wrapperRef, () => wrapperRef.current && calculateOffsets(wrapperRef.current));
29
30
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(HorizontalScrollContainer, { showLeftShadow: !isMaxLeft, showRightShadow: !isMaxRight, ...rest, children: [
30
31
  /* @__PURE__ */ jsx(LeftShadow, { offset: stickyLeft }),
31
- /* @__PURE__ */ jsx(HorizontalScrollWrapper, { ref: mergedRef, onScroll: handleScroll, children }),
32
+ /* @__PURE__ */ jsx(HorizontalScrollWrapper, { nativeScrollbar, ref: mergedRef, onScroll: handleScroll, children }),
32
33
  /* @__PURE__ */ jsx(RightShadow, { offset: stickyRight })
33
34
  ] }) });
34
35
  });
@@ -1,4 +1,6 @@
1
- export declare const HorizontalScrollWrapper: import('styled-components').StyledComponent<"div", any, {}, never>;
1
+ export declare const HorizontalScrollWrapper: import('styled-components').StyledComponent<"div", any, {
2
+ nativeScrollbar?: boolean;
3
+ }, never>;
2
4
  export declare const LeftShadow: import('styled-components').StyledComponent<"div", any, {
3
5
  offset: number;
4
6
  }, never>;
@@ -3,7 +3,7 @@ import { hexToRgba } from "@synerise/ds-utils";
3
3
  const HorizontalScrollWrapper = /* @__PURE__ */ styled.div.withConfig({
4
4
  displayName: "TableHorizontalScrollstyles__HorizontalScrollWrapper",
5
5
  componentId: "sc-16m24d3-0"
6
- })(["overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-y:auto;overscroll-behavior-x:contain;"]);
6
+ })(["overflow-x:auto;overflow-y:hidden;", " overscroll-behavior-y:auto;overscroll-behavior-x:contain;"], (props) => !props.nativeScrollbar && "scrollbar-width: none;");
7
7
  const LeftShadow = /* @__PURE__ */ styled.div.withConfig({
8
8
  displayName: "TableHorizontalScrollstyles__LeftShadow",
9
9
  componentId: "sc-16m24d3-1"
@@ -1,3 +1,3 @@
1
1
  import { default as React } from 'react';
2
2
  import { TreeTableProps } from './TreeTable.types';
3
- export declare const TreeTable: <TData extends object, TValue>({ data, columns, childrenColumnName, defaultExpandAllRows, expandedRowKeys: controlledExpandedKeys, onExpandRow, expandIconColumnIndex, rowKey, ...props }: TreeTableProps<TData, TValue>) => React.JSX.Element;
3
+ export declare const TreeTable: <TData extends object, TValue>({ data, columns, childrenColumnName, defaultExpandAllRows, expandedRowKeys: controlledExpandedKeys, onExpandRow, expandIconColumnIndex, hideExpandIcon, rowKey, ...props }: TreeTableProps<TData, TValue>) => React.JSX.Element;
@@ -27,6 +27,7 @@ const TreeTable = ({
27
27
  expandedRowKeys: controlledExpandedKeys,
28
28
  onExpandRow,
29
29
  expandIconColumnIndex = 0,
30
+ hideExpandIcon = false,
30
31
  rowKey,
31
32
  ...props
32
33
  }) => {
@@ -84,18 +85,20 @@ const TreeTable = ({
84
85
  length: depth
85
86
  }, (_, i) => /* @__PURE__ */ jsx(IndentBar, { $level: i, $active: i + 1 === depth }, i));
86
87
  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 }),
88
+ const rowPrefix = isParent && !hideExpandIcon ? /* @__PURE__ */ jsx(Expander, { expanded: isExpanded, onClick: (e) => {
89
+ e.stopPropagation();
90
+ toggleExpand(rowId);
91
+ } }) : depth > 0 ? /* @__PURE__ */ jsx(Icon, { component: /* @__PURE__ */ jsx(ChildRowLeftDownM, {}), color: theme.palette["grey-400"] }) : null;
92
+ const finalDepth = hideExpandIcon && depth > 0 ? depth - 1 : depth;
93
+ return /* @__PURE__ */ jsxs(TreeCellWrapper, { $indentWidth: finalDepth * INDENT_SIZE, children: [
94
+ depth > 0 && !hideExpandIcon && /* @__PURE__ */ jsx(IndentsContainer, { $depth: depth, children: indents }),
95
+ rowPrefix && /* @__PURE__ */ jsx(ExpanderWrapper, { children: rowPrefix }),
93
96
  originalCell
94
97
  ] });
95
98
  }
96
99
  };
97
100
  });
98
- }, [columns, expandIconColumnIndex, getRowKey, hasChildren, expandedKeys, toggleExpand]);
101
+ }, [columns, expandIconColumnIndex, getRowKey, hasChildren, expandedKeys, toggleExpand, hideExpandIcon]);
99
102
  return /* @__PURE__ */ jsx(TreeTableRoot, { children: /* @__PURE__ */ jsx(Table, { data, columns: treeColumns, rowKey, expandable: {
100
103
  childrenColumnName: childrenKey,
101
104
  expandedRowKeys: expandedKeys
@@ -19,8 +19,17 @@ export type TreeTableProps<TData, TValue> = Omit<TableProps<TData, TValue>, 'exp
19
19
  onExpandRow?: (key: string, expanded: boolean) => void;
20
20
  /**
21
21
  * Index of the column where the expand icon is rendered.
22
- * Set to -1 to hide the expand icon entirely.
22
+ * Set to -1 to hide the expand icon and skip indentation entirely.
23
23
  * @default 0
24
24
  */
25
25
  expandIconColumnIndex?: number;
26
+ /**
27
+ * Suppress the expander button on parent rows while still rendering
28
+ * indentation and the leaf glyph (ChildRowLeftDownM) on every indented row.
29
+ * Use when expand/collapse is not user-controllable but you still want
30
+ * visual hierarchy matching the legacy antd table.
31
+ * Ignored when `expandIconColumnIndex` is negative.
32
+ * @default false
33
+ */
34
+ hideExpandIcon?: boolean;
26
35
  };
@@ -142,6 +142,16 @@ const useTable = ({
142
142
  }, [childrenColumnName]);
143
143
  const expandedKeys = expandable?.expandedRowKeys ? arrayToTrueMap(expandable?.expandedRowKeys) : void 0;
144
144
  const table = useReactTable({
145
+ // Override TanStack's built-in sizing defaults (size: 150, minSize: 20,
146
+ // maxSize: Number.MAX_SAFE_INTEGER) so column.columnDef.size/minSize/maxSize
147
+ // stay undefined when the consumer did not set them. BaseTable's
148
+ // unified-mode <colgroup> uses these to detect user-set widths;
149
+ // column.getSize() still falls back to TanStack's internal defaults.
150
+ defaultColumn: {
151
+ size: void 0,
152
+ minSize: void 0,
153
+ maxSize: void 0
154
+ },
145
155
  getRowId: memoizedGetRowKey,
146
156
  data: displayData,
147
157
  columns,
@@ -0,0 +1,3 @@
1
+ import { CSSProperties } from 'react';
2
+ import { Column } from '@tanstack/react-table';
3
+ export declare const getUnifiedColumnSizingStyle: <TData, TValue>(column: Column<TData, TValue>) => CSSProperties;
@@ -0,0 +1,30 @@
1
+ const toCssLength = (v) => {
2
+ if (v === void 0 || v === null) {
3
+ return void 0;
4
+ }
5
+ return typeof v === "number" ? `${v}px` : v;
6
+ };
7
+ const positiveOrUndefined = (v) => typeof v === "number" && v > 0 ? v : void 0;
8
+ const getUnifiedColumnSizingStyle = (column) => {
9
+ const meta = column.columnDef.meta;
10
+ const widthRaw = meta?.width ?? positiveOrUndefined(column.columnDef.size);
11
+ const minWidthRaw = meta?.minWidth ?? positiveOrUndefined(column.columnDef.minSize);
12
+ const maxWidthRaw = meta?.maxWidth ?? positiveOrUndefined(column.columnDef.maxSize);
13
+ const width = toCssLength(widthRaw);
14
+ const minWidth = toCssLength(minWidthRaw ?? widthRaw);
15
+ const maxWidth = toCssLength(maxWidthRaw ?? widthRaw);
16
+ const style = {};
17
+ if (width !== void 0) {
18
+ style.width = width;
19
+ }
20
+ if (minWidth !== void 0) {
21
+ style.minWidth = minWidth;
22
+ }
23
+ if (maxWidth !== void 0) {
24
+ style.maxWidth = maxWidth;
25
+ }
26
+ return style;
27
+ };
28
+ export {
29
+ getUnifiedColumnSizingStyle
30
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-table-new",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "TableNew UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "Synerise/synerise-design",
@@ -44,7 +44,7 @@
44
44
  "dependencies": {
45
45
  "@floating-ui/react": "^0.27.16",
46
46
  "@synerise/ds-badge": "^1.0.53",
47
- "@synerise/ds-button": "^1.5.28",
47
+ "@synerise/ds-button": "^1.5.29",
48
48
  "@synerise/ds-checkbox": "^1.2.30",
49
49
  "@synerise/ds-copy-icon": "^1.2.11",
50
50
  "@synerise/ds-dropdown": "^1.3.12",
@@ -54,14 +54,14 @@
54
54
  "@synerise/ds-input": "^1.7.7",
55
55
  "@synerise/ds-input-number": "^1.2.44",
56
56
  "@synerise/ds-loader": "^1.0.16",
57
- "@synerise/ds-modal": "^1.4.13",
58
- "@synerise/ds-pagination": "^1.0.63",
59
- "@synerise/ds-result": "^1.0.59",
57
+ "@synerise/ds-modal": "^1.4.14",
58
+ "@synerise/ds-pagination": "^1.0.64",
59
+ "@synerise/ds-result": "^1.0.60",
60
60
  "@synerise/ds-scrollbar": "^1.3.5",
61
- "@synerise/ds-search": "^1.5.23",
61
+ "@synerise/ds-search": "^1.5.24",
62
62
  "@synerise/ds-skeleton": "^1.0.54",
63
63
  "@synerise/ds-tag": "^1.4.27",
64
- "@synerise/ds-tags": "^1.5.40",
64
+ "@synerise/ds-tags": "^1.5.41",
65
65
  "@synerise/ds-tooltip": "^1.4.19",
66
66
  "@synerise/ds-typography": "^1.1.22",
67
67
  "@synerise/ds-utils": "^1.8.1",
@@ -80,5 +80,5 @@
80
80
  "react-intl": ">= 3.12.0 <= 6.8",
81
81
  "styled-components": "^5.3.3"
82
82
  },
83
- "gitHead": "1132c21afce924c3e3b8e75e2ebd5e7b5db69bd2"
83
+ "gitHead": "b757d8f81066fcba3d1a739dfbbcdb49c13b9f90"
84
84
  }