@synerise/ds-table-new 1.4.2 → 1.4.4

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 (30) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/Table.d.ts +1 -1
  3. package/dist/Table.js +10 -2
  4. package/dist/Table.types.d.ts +55 -4
  5. package/dist/VirtualTable.js +1 -1
  6. package/dist/components/BaseTable/BaseTable.d.ts +1 -1
  7. package/dist/components/BaseTable/BaseTable.js +4 -2
  8. package/dist/components/BaseTable/BaseTable.styles.js +1 -1
  9. package/dist/components/BaseTable/StickyTableContent.d.ts +2 -2
  10. package/dist/components/BaseTable/StickyTableContent.js +3 -2
  11. package/dist/components/BaseTable/UnifiedTableContent.d.ts +2 -2
  12. package/dist/components/BaseTable/UnifiedTableContent.js +3 -2
  13. package/dist/components/Cell/Copyable/Copyable.types.d.ts +6 -0
  14. package/dist/components/Cell/Copyable/CopyableCell.d.ts +1 -1
  15. package/dist/components/Cell/Copyable/CopyableCell.js +2 -1
  16. package/dist/components/TableBody/TableBody.d.ts +1 -1
  17. package/dist/components/TableBody/TableBody.js +21 -7
  18. package/dist/components/TableBody/TableBody.styles.d.ts +2 -0
  19. package/dist/components/TableBody/TableBody.styles.js +10 -0
  20. package/dist/components/TableBody/TableEmptyBody/TableEmptyBody.js +1 -1
  21. package/dist/components/TableBody/TableEmptyBody/TableEmptyBody.styles.js +1 -1
  22. package/dist/components/TableBody/TableRow/TableRow.d.ts +1 -1
  23. package/dist/components/TableBody/TableRow/TableRow.js +10 -2
  24. package/dist/components/TableBody/TableRow/TableRowVirtual.d.ts +1 -1
  25. package/dist/components/TableBody/TableRow/TableRowVirtual.js +10 -2
  26. package/dist/components/TreeTable/TreeTable.d.ts +1 -1
  27. package/dist/components/TreeTable/TreeTable.js +6 -3
  28. package/dist/components/TreeTable/TreeTable.types.d.ts +6 -0
  29. package/dist/hooks/useTable.js +18 -5
  30. package/package.json +22 -22
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
+ ## [1.4.4](https://github.com/Synerise/synerise-design/compare/@synerise/ds-table-new@1.4.3...@synerise/ds-table-new@1.4.4) (2026-06-11)
7
+
8
+ **Note:** Version bump only for package @synerise/ds-table-new
9
+
10
+ ## [1.4.3](https://github.com/Synerise/synerise-design/compare/@synerise/ds-table-new@1.4.2...@synerise/ds-table-new@1.4.3) (2026-06-03)
11
+
12
+ ### Bug Fixes
13
+
14
+ - **modal:** a11y and other tweaks ([cfbeb11](https://github.com/Synerise/synerise-design/commit/cfbeb11c8e1a60d99885ec87e91783eb1800c8d9))
15
+ - **table-new:** expandalble row custom content and default table sticky header features ([4f8a670](https://github.com/Synerise/synerise-design/commit/4f8a6704e3dc2c00ee88549553af30af02fe5430))
16
+
6
17
  ## [1.4.2](https://github.com/Synerise/synerise-design/compare/@synerise/ds-table-new@1.4.1...@synerise/ds-table-new@1.4.2) (2026-05-27)
7
18
 
8
19
  **Note:** Version bump only for package @synerise/ds-table-new
package/dist/Table.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { default as React } from 'react';
2
2
  import { TableProps } from './Table.types';
3
- export declare const Table: <TData extends object, TValue>({ data, columns, texts: defaultTexts, selectionConfig, isLoading, selectedRowKeys, pagination, matchesSearchQuery, filterData, onSearchQueryChange, searchProps, expandable, rowKey, onSort, tableRef, ...props }: TableProps<TData, TValue>) => React.JSX.Element;
3
+ export declare const Table: <TData extends object, TValue>({ data, columns, texts: defaultTexts, selectionConfig, isLoading, selectedRowKeys, pagination, matchesSearchQuery, filterData, onSearchQueryChange, searchProps, expandable, rowKey, onSort, tableRef, stickyHeader, ...props }: TableProps<TData, TValue>) => React.JSX.Element;
package/dist/Table.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { useRef, useMemo, useImperativeHandle } from "react";
2
+ import { useRef, useState, useMemo, useImperativeHandle } from "react";
3
+ import { DEFAULT_STICKY_VALUE } from "./Table.const.js";
3
4
  import { BaseTable } from "./components/BaseTable/BaseTable.js";
4
5
  import { SelectionContext } from "./contexts/SelectionContext.js";
6
+ import { StickyContext } from "./contexts/StickyContext.js";
5
7
  import { TableContext } from "./contexts/TableContext.js";
6
8
  import { useDefaultTexts } from "./hooks/useDefaultTexts.js";
7
9
  import { useTable } from "./hooks/useTable.js";
@@ -24,10 +26,12 @@ const Table = ({
24
26
  rowKey,
25
27
  onSort,
26
28
  tableRef,
29
+ stickyHeader,
27
30
  ...props
28
31
  }) => {
29
32
  const texts = useDefaultTexts(defaultTexts);
30
33
  const wrapperRef = useRef(null);
34
+ const [stickyData, setStickyData] = useState(DEFAULT_STICKY_VALUE);
31
35
  const hasSelection = !!selectionConfig;
32
36
  const processedColumns = useMemo(() => {
33
37
  return columns.length ? processColumns(columns, hasSelection, texts) : columns;
@@ -72,7 +76,11 @@ const Table = ({
72
76
  table,
73
77
  getScrollContainer: () => null
74
78
  }), [table]);
75
- return /* @__PURE__ */ jsx(TableContext.Provider, { value: tableContextValue, children: /* @__PURE__ */ jsx(SelectionContext.Provider, { value: selectionConfig, children: /* @__PURE__ */ jsx(BaseTable, { texts, isLoading: effectiveIsLoading, hasPagination, paginationProps, tableOuterRef: wrapperRef, selectedRowKeys, columnSizing, isColumnSizingReady, searchQuery, setSearchQuery, handleSearchClear, hasBuiltInSearch, searchProps, dataSourceTotalCount: totalDataCount, ...props }) }) });
79
+ const stickyValue = useMemo(() => stickyHeader ? {
80
+ stickyData,
81
+ setStickyData
82
+ } : null, [stickyData, stickyHeader]);
83
+ return /* @__PURE__ */ jsx(TableContext.Provider, { value: tableContextValue, children: /* @__PURE__ */ jsx(StickyContext.Provider, { value: stickyValue, children: /* @__PURE__ */ jsx(SelectionContext.Provider, { value: selectionConfig, children: /* @__PURE__ */ jsx(BaseTable, { texts, isLoading: effectiveIsLoading, hasPagination, paginationProps, tableOuterRef: wrapperRef, selectedRowKeys, columnSizing, isColumnSizingReady, searchQuery, setSearchQuery, handleSearchClear, hasBuiltInSearch, searchProps, dataSourceTotalCount: totalDataCount, expandable, ...props }) }) }) });
76
84
  };
77
85
  export {
78
86
  Table
@@ -1,5 +1,5 @@
1
1
  import { PaginationProps } from 'antd';
2
- import { HTMLAttributes, MouseEvent, MutableRefObject, ReactElement, ReactNode, RefObject } from 'react';
2
+ import { CSSProperties, HTMLAttributes, MouseEvent, MutableRefObject, ReactElement, ReactNode, RefObject } from 'react';
3
3
  import { SearchInputProps } from '@synerise/ds-search';
4
4
  import { TooltipProps } from '@synerise/ds-tooltip';
5
5
  import { Column, ColumnDef, ColumnMeta, Row, RowData } from '@tanstack/react-table';
@@ -65,6 +65,44 @@ export type DSTableProps<TData, TValue = unknown> = SharedTableProps<TData, TVal
65
65
  export type Expandable<TData> = {
66
66
  childrenColumnName?: keyof TData;
67
67
  expandedRowKeys?: string[];
68
+ /**
69
+ * Render custom content directly below an expanded parent row.
70
+ * Result is wrapped in an extra `<tr>` containing a single `<td>` that
71
+ * spans every visible column (including the selection column when enabled).
72
+ *
73
+ * Currently honored by `Table` (non-virtual). `VirtualTable` ignores this
74
+ * prop because variable-height expanded rows require dynamic virtualization
75
+ * sizing not yet implemented.
76
+ *
77
+ * Signature mirrors antd 4 / legacy `@synerise/ds-table`:
78
+ * `(record, index, indent, expanded) => ReactNode`.
79
+ */
80
+ expandedRowRender?: (record: TData, index: number, indent: number, expanded: boolean) => ReactNode;
81
+ /**
82
+ * When true, clicking anywhere on a row toggles its expanded state.
83
+ * Composes with `onRowClick` and any `onClick` from `getRowProps` — call
84
+ * `event.preventDefault()` from those handlers to suppress the toggle.
85
+ *
86
+ * For uncontrolled use (no `expandedRowKeys`) the table updates internal
87
+ * expansion state itself. For controlled use, the toggle is delivered via
88
+ * `onExpand` and the consumer is responsible for updating `expandedRowKeys`.
89
+ *
90
+ * Suppressed for rows where `rowExpandable(record)` returns false.
91
+ */
92
+ expandRowByClick?: boolean;
93
+ /**
94
+ * Returns false to mark a row as non-expandable. Hides the expander UI in
95
+ * `TreeTable` and suppresses `expandRowByClick` for that row. Rows whose
96
+ * predicate returns undefined / true are considered expandable.
97
+ */
98
+ rowExpandable?: (record: TData) => boolean;
99
+ /**
100
+ * Fires when a row's expanded state changes via `expandRowByClick`.
101
+ * Receives the new expanded state and the row's record. In controlled mode
102
+ * (when `expandedRowKeys` is set) consumers must use this to update their
103
+ * source of truth.
104
+ */
105
+ onExpand?: (expanded: boolean, record: TData) => void;
68
106
  };
69
107
  /**
70
108
  * Table props shared virtual & non-virtual
@@ -94,6 +132,8 @@ export type SharedTableProps<TData, TValue> = {
94
132
  cellHeight?: number;
95
133
  /** optional className for styled-components composition */
96
134
  className?: string;
135
+ /** inline styles applied to the outermost table wrapper element */
136
+ style?: CSSProperties;
97
137
  /**
98
138
  * renders in table header next to title and counter when there's any selected rows
99
139
  * useful for rendering batch action items
@@ -220,6 +260,18 @@ export type SharedTableProps<TData, TValue> = {
220
260
  * render table with rounded corners and shadow
221
261
  */
222
262
  cardStyles?: boolean;
263
+ /**
264
+ * When true, the column header row uses `position: sticky` and stays pinned
265
+ * to the top of the nearest scrollable ancestor as the user scrolls.
266
+ *
267
+ * On `VirtualTable` this also switches the scroll element to the table's own
268
+ * container (or `scrollElementRef`) so the header sticks under the title bar.
269
+ *
270
+ * On `Table` (paginated) there is no internal scroll container — the header
271
+ * sticks to whatever ancestor scrolls in the consumer's layout (typically
272
+ * the page). The pagination footer flows below the body as normal.
273
+ */
274
+ stickyHeader?: boolean;
223
275
  /**
224
276
  * set to true to prevent rendering column header row with column names
225
277
  */
@@ -309,7 +361,6 @@ type VirtualProps = {
309
361
  * disables sorting - relies on data being provided pre-sorted
310
362
  */
311
363
  infiniteScroll?: InfiniteScrollProps;
312
- stickyHeader?: boolean;
313
364
  onItemsRendered?: (props: OnItemsRenderedProps) => void;
314
365
  scrollElementRef?: MutableRefObject<HTMLDivElement | null>;
315
366
  onScrollToRecordIndex?: (recordIndex: number, callback?: () => void) => void;
@@ -447,7 +498,7 @@ export type CustomCounterArgs = {
447
498
  content: ReactNode;
448
499
  };
449
500
  export type CustomCounterFn = (props: CustomCounterArgs) => ReactNode;
450
- export type TableBodyProps<TData, TValue> = Pick<BaseTableProps<TData, TValue>, 'infiniteScroll' | 'cellHeight' | 'emptyDataComponent' | 'onRowClick' | 'getRowProps' | 'getRowTooltipProps'> & {
501
+ export type TableBodyProps<TData, TValue> = Pick<BaseTableProps<TData, TValue>, 'infiniteScroll' | 'cellHeight' | 'emptyDataComponent' | 'onRowClick' | 'getRowProps' | 'getRowTooltipProps' | 'expandable'> & {
451
502
  texts: TableBodyTexts;
452
503
  };
453
504
  export type TableEmptyBodyProps<TData, TValue> = Pick<TableBodyProps<TData, TValue>, 'emptyDataComponent'> & {
@@ -512,7 +563,7 @@ export type TableRowProps<TData> = {
512
563
  isSelected?: boolean;
513
564
  isExpanded?: boolean;
514
565
  isParentExpanded?: boolean;
515
- } & Pick<SharedTableProps<TData, unknown>, 'onRowClick' | 'getRowProps' | 'getRowTooltipProps'>;
566
+ } & Pick<SharedTableProps<TData, unknown>, 'onRowClick' | 'getRowProps' | 'getRowTooltipProps' | 'expandable'>;
516
567
  export type TableRowVirtualProps<TData> = TableRowProps<TData> & {
517
568
  cellHeight: number;
518
569
  virtual: VirtualItem;
@@ -245,7 +245,7 @@ const VirtualTable = ({
245
245
  rowVirtualizer.scrollToOffset(0);
246
246
  }, [onBackToTop, rowVirtualizer]);
247
247
  return /* @__PURE__ */ jsx(TableContext.Provider, { value: tableContextValue, children: /* @__PURE__ */ jsx(StickyContext.Provider, { value: stickyValue, children: /* @__PURE__ */ jsxs(SelectionContext.Provider, { value: selectionConfig, children: [
248
- /* @__PURE__ */ jsx(BaseTable, { columnSizing, isColumnSizingReady, texts, tableOuterRef, tableBodyScrollRef, withScroll: withContainerScroll, withBodyScroll, maxHeight, hasPagination: false, infiniteScroll, isLoading: effectiveIsLoading, searchQuery, setSearchQuery, handleSearchClear, hasBuiltInSearch, searchProps, dataSourceTotalCount: totalDataCount, cellHeight, ...props }),
248
+ /* @__PURE__ */ jsx(BaseTable, { columnSizing, isColumnSizingReady, texts, tableOuterRef, tableBodyScrollRef, withScroll: withContainerScroll, withBodyScroll, maxHeight, hasPagination: false, infiniteScroll, isLoading: effectiveIsLoading, searchQuery, setSearchQuery, handleSearchClear, hasBuiltInSearch, searchProps, dataSourceTotalCount: totalDataCount, cellHeight, expandable, ...props }),
249
249
  showBackToTopButton && /* @__PURE__ */ jsx(BackToTopButton, { label: texts.infiniteScrollBackToTop, onClick: handleBackToTop, scrollContainerRef: scrollableContainerRef, hasData: !tableIsEmpty && columns.length > 0, threshold: (stickyData.titleBarHeight || 0) + (Number.isFinite(stickyData.containerPaddingTop) ? stickyData.containerPaddingTop : 0) })
250
250
  ] }) }) });
251
251
  };
@@ -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, summary, }: BaseTableProps<TData, TValue> & TableInternalProps) => React.JSX.Element;
3
+ export declare const BaseTable: <TData extends object, TValue>({ infiniteScroll, cellHeight, className, style, 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;
@@ -14,6 +14,7 @@ const BaseTable = ({
14
14
  infiniteScroll,
15
15
  cellHeight = DEFAULT_CELL_HEIGHT,
16
16
  className,
17
+ style,
17
18
  itemsMenu,
18
19
  texts,
19
20
  isCounterLoading,
@@ -85,9 +86,10 @@ const BaseTable = ({
85
86
  maxHeight,
86
87
  tableBodyScrollRef,
87
88
  addNode,
88
- isEmpty
89
+ isEmpty,
90
+ expandable
89
91
  };
90
- return /* @__PURE__ */ jsxs(BaseTableWrapper, { isEmpty, columnSizing: useColgroupLayout ? {} : columnSizing, $isColumnSizingReady: isColumnSizingReady, $size: useColgroupLayout ? void 0 : size, children: [
92
+ return /* @__PURE__ */ jsxs(BaseTableWrapper, { isEmpty, columnSizing: useColgroupLayout ? {} : columnSizing, $isColumnSizingReady: isColumnSizingReady, $size: useColgroupLayout ? void 0 : size, style, children: [
91
93
  /* @__PURE__ */ jsxs(TableContainer, { ref: tableOuterRef, className, withBorderTop: headerWithBorderTop, cardStyles, withScroll, $maxHeight: maxHeight, "data-testid": "ds-table-container", children: [
92
94
  !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 }),
93
95
  useUnifiedScroll ? /* @__PURE__ */ jsx(UnifiedTableContent, { useColgroupLayout, ...contentProps }) : /* @__PURE__ */ jsx(StickyTableContent, { ...contentProps }),
@@ -4,7 +4,7 @@ import { TableHorizontalScroll } from "../TableHorizontalScroll/TableHorizontalS
4
4
  const BaseTableWrapper = /* @__PURE__ */ styled.div.withConfig({
5
5
  displayName: "BaseTablestyles__BaseTableWrapper",
6
6
  componentId: "sc-1oa5lc2-0"
7
- })(["", " --table-size:", ";", " position:relative;z-index:1;"], (props) => css(["", ""], Object.entries(props.columnSizing || {}).map(([key, value]) => `--${key}-width: ${value}px;`).join("\n")), (props) => !props.isEmpty && props.$size ? `${props.$size}px` : "100%", (props) => !props.$isColumnSizingReady && `opacity: 0;`);
7
+ })(["", " --table-size:", ";", " position:relative;z-index:1;.ant-pagination .ant-pagination-total-text strong{font-weight:500;}"], (props) => css(["", ""], Object.entries(props.columnSizing || {}).map(([key, value]) => `--${key}-width: ${value}px;`).join("\n")), (props) => !props.isEmpty && props.$size ? `${props.$size}px` : "100%", (props) => !props.$isColumnSizingReady && `opacity: 0;`);
8
8
  const TableContainer = /* @__PURE__ */ styled.div.withConfig({
9
9
  displayName: "BaseTablestyles__TableContainer",
10
10
  componentId: "sc-1oa5lc2-1"
@@ -1,8 +1,8 @@
1
1
  import { default as React } from 'react';
2
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'> & {
3
+ export type StickyTableContentProps<TData, TValue> = Pick<BaseTableProps<TData, TValue> & TableInternalProps, 'infiniteScroll' | 'texts' | 'isLoading' | 'emptyDataComponent' | 'onRowClick' | 'getRowProps' | 'getRowTooltipProps' | 'summary' | 'hideColumnNames' | 'disableColumnNamesLineBreak' | 'withBodyScroll' | 'maxHeight' | 'tableBodyScrollRef' | 'expandable'> & {
4
4
  cellHeight: number;
5
5
  addNode: (node: HTMLDivElement | null) => void;
6
6
  isEmpty: boolean;
7
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;
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, expandable, }: StickyTableContentProps<TData, TValue>) => React.JSX.Element;
@@ -23,7 +23,8 @@ const StickyTableContent = ({
23
23
  maxHeight,
24
24
  tableBodyScrollRef,
25
25
  addNode,
26
- isEmpty
26
+ isEmpty,
27
+ expandable
27
28
  }) => {
28
29
  const {
29
30
  table,
@@ -57,7 +58,7 @@ const StickyTableContent = ({
57
58
  tableBodyWrapperRef.current = element;
58
59
  addNode(element);
59
60
  }, 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 ? /* @__PURE__ */ jsx(TableBodySkeleton, { wrapperRef: tableBodyWrapperRef, cellHeight }, "table-body-skeleton") : /* @__PURE__ */ jsx(TableBody, { cellHeight, infiniteScroll, emptyDataComponent, texts, onRowClick, getRowProps, getRowTooltipProps, expandable }, "table-body"),
61
62
  !isLoading && summary && /* @__PURE__ */ jsx(Tfoot, { children: summary })
62
63
  ] }) });
63
64
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -1,9 +1,9 @@
1
1
  import { default as React } from 'react';
2
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'> & {
3
+ export type UnifiedTableContentProps<TData, TValue> = Pick<BaseTableProps<TData, TValue> & TableInternalProps, 'infiniteScroll' | 'texts' | 'isLoading' | 'emptyDataComponent' | 'onRowClick' | 'getRowProps' | 'getRowTooltipProps' | 'summary' | 'hideColumnNames' | 'disableColumnNamesLineBreak' | 'withBodyScroll' | 'maxHeight' | 'tableBodyScrollRef' | 'expandable'> & {
4
4
  cellHeight: number;
5
5
  addNode: (node: HTMLDivElement | null) => void;
6
6
  isEmpty: boolean;
7
7
  useColgroupLayout: boolean;
8
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;
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, expandable, }: UnifiedTableContentProps<TData, TValue>) => React.JSX.Element;
@@ -24,7 +24,8 @@ const UnifiedTableContent = ({
24
24
  tableBodyScrollRef,
25
25
  addNode,
26
26
  isEmpty,
27
- useColgroupLayout
27
+ useColgroupLayout,
28
+ expandable
28
29
  }) => {
29
30
  const {
30
31
  table
@@ -36,7 +37,7 @@ const UnifiedTableContent = ({
36
37
  }, nativeScrollbar: useColgroupLayout, children: /* @__PURE__ */ jsxs(StyledTable, { role: "table", className: "ds-table", $tableLayoutAuto: useColgroupLayout, children: [
37
38
  useColgroupLayout && !isEmpty && /* @__PURE__ */ jsx("colgroup", { children: table.getVisibleLeafColumns().map((column, index) => /* @__PURE__ */ jsx("col", { style: getUnifiedColumnSizingStyle(column) }, column.id ?? `col-${index}`)) }),
38
39
  !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 ? /* @__PURE__ */ jsx(TableBodySkeleton, { wrapperRef: tableBodyWrapperRef, cellHeight }, "table-body-skeleton") : /* @__PURE__ */ jsx(TableBody, { cellHeight, infiniteScroll, emptyDataComponent, texts, onRowClick, getRowProps, getRowTooltipProps, expandable }, "table-body"),
40
41
  !isLoading && summary && /* @__PURE__ */ jsx(Tfoot, { children: summary })
41
42
  ] }) });
42
43
  return withBodyScroll ? /* @__PURE__ */ jsx(TableBodyScrollWrapper, { ref: tableBodyScrollRef, $maxHeight: maxHeight, children: body }) : body;
@@ -1,8 +1,14 @@
1
+ import { TooltipProps } from '@synerise/ds-tooltip';
1
2
  import { WithHTMLAttributes } from '@synerise/ds-utils';
2
3
  export type BaseCopyableCellProps = {
3
4
  value: string;
4
5
  confirmMessage: string;
5
6
  tooltipTimeout: number;
7
+ /**
8
+ * Tooltip placement for the copy icon's confirmation tooltip.
9
+ * @default 'top'
10
+ */
11
+ placement?: TooltipProps['placement'];
6
12
  };
7
13
  export type CopyableCellProps = WithHTMLAttributes<HTMLDivElement, BaseCopyableCellProps>;
8
14
  /**
@@ -1,4 +1,4 @@
1
1
  import { default as React } from 'react';
2
2
  import { CopyableCellProps } from './Copyable.types';
3
- declare const CopyableCell: ({ value, confirmMessage, tooltipTimeout, ...htmlAttributes }: CopyableCellProps) => React.JSX.Element;
3
+ declare const CopyableCell: ({ value, confirmMessage, tooltipTimeout, placement, ...htmlAttributes }: CopyableCellProps) => React.JSX.Element;
4
4
  export { CopyableCell };
@@ -7,6 +7,7 @@ const CopyableCell = ({
7
7
  value,
8
8
  confirmMessage,
9
9
  tooltipTimeout = DEFAULT_TIMEOUT,
10
+ placement = "top",
10
11
  ...htmlAttributes
11
12
  }) => {
12
13
  const [tooltipVisible, setTooltipVisible] = useState(false);
@@ -18,7 +19,7 @@ const CopyableCell = ({
18
19
  }, [tooltipVisible, setTooltipVisible, tooltipTimeout]);
19
20
  return /* @__PURE__ */ jsxs(Copyable, { ...htmlAttributes, children: [
20
21
  /* @__PURE__ */ jsx(CopyableValue, { children: value }),
21
- /* @__PURE__ */ jsx(CopyIcon, { copyValue: value, placement: "left", texts: {
22
+ /* @__PURE__ */ jsx(CopyIcon, { copyValue: value, placement, texts: {
22
23
  copiedTooltip: confirmMessage
23
24
  } })
24
25
  ] });
@@ -1,3 +1,3 @@
1
1
  import { default as React } from 'react';
2
2
  import { TableBodyProps } from '../../Table.types';
3
- export declare const TableBody: <TData extends object, TValue>({ cellHeight, infiniteScroll, onRowClick, getRowProps, getRowTooltipProps, emptyDataComponent, texts, }: TableBodyProps<TData, TValue>) => React.JSX.Element;
3
+ export declare const TableBody: <TData extends object, TValue>({ cellHeight, infiniteScroll, onRowClick, getRowProps, getRowTooltipProps, emptyDataComponent, texts, expandable, }: TableBodyProps<TData, TValue>) => React.JSX.Element;
@@ -1,7 +1,8 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import React from "react";
2
3
  import { DEFAULT_CELL_HEIGHT } from "../../Table.const.js";
3
4
  import { useTableContext } from "../../contexts/TableContext.js";
4
- import { TBody } from "./TableBody.styles.js";
5
+ import { TBody, ExpandedContentRow, ExpandedContentCell } from "./TableBody.styles.js";
5
6
  import { TableEmptyBody } from "./TableEmptyBody/TableEmptyBody.js";
6
7
  import { TableRow } from "./TableRow/TableRow.js";
7
8
  import { TableRowVirtual } from "./TableRow/TableRowVirtual.js";
@@ -12,7 +13,8 @@ const TableBody = ({
12
13
  getRowProps,
13
14
  getRowTooltipProps,
14
15
  emptyDataComponent,
15
- texts
16
+ texts,
17
+ expandable
16
18
  }) => {
17
19
  const {
18
20
  table,
@@ -40,14 +42,26 @@ const TableBody = ({
40
42
  height: `${rowVirtualizer.getTotalSize()}px`,
41
43
  position: "relative"
42
44
  } : void 0, children: rowVirtualizer && virtualItems.length ? (
43
- // Virtualized: place spacer and absolutely-positioned rows
45
+ // Virtualized: place spacer and absolutely-positioned rows.
46
+ // Note: `expandedRowRender` is not honored in virtual mode because
47
+ // variable-height expanded rows are not yet integrated with the
48
+ // virtualizer's size estimation.
44
49
  virtualItems.map((virtual) => {
45
50
  const row = allRows[virtual.index];
46
- return /* @__PURE__ */ jsx(TableRowVirtual, { virtual, cellHeight, row, texts, onRowClick, getRowProps, getRowTooltipProps, rowIndex: virtual.index, infiniteScroll, isLast: virtual.index === allRows.length - 1, isSelected: row.getIsSelected(), isExpanded: row.getIsExpanded(), isParentExpanded: row.getIsAllParentsExpanded() }, row.id);
51
+ return /* @__PURE__ */ jsx(TableRowVirtual, { virtual, cellHeight, row, texts, onRowClick, getRowProps, getRowTooltipProps, expandable, rowIndex: virtual.index, infiniteScroll, isLast: virtual.index === allRows.length - 1, isSelected: row.getIsSelected(), isExpanded: row.getIsExpanded(), isParentExpanded: row.getIsAllParentsExpanded() }, row.id);
47
52
  })
48
53
  ) : (
49
- // Non-virtualized: render all rows in the normal flow
50
- allRows.map((row) => /* @__PURE__ */ jsx(TableRow, { onRowClick, getRowProps, getRowTooltipProps, row, isSelected: row.getIsSelected(), isExpanded: row.getIsExpanded(), isParentExpanded: row.getIsAllParentsExpanded() }, row.id))
54
+ // Non-virtualized: render rows + optional expanded-content row after
55
+ // each expanded parent (mirrors antd's expandedRowRender behavior).
56
+ allRows.map((row) => {
57
+ const isExpanded = row.getIsExpanded();
58
+ const canExpand = !expandable?.rowExpandable || expandable.rowExpandable(row.original);
59
+ const expandedContent = expandable?.expandedRowRender && isExpanded && canExpand ? expandable.expandedRowRender(row.original, row.index, row.depth, isExpanded) : null;
60
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
61
+ /* @__PURE__ */ jsx(TableRow, { onRowClick, getRowProps, getRowTooltipProps, expandable, row, isSelected: row.getIsSelected(), isExpanded, isParentExpanded: row.getIsAllParentsExpanded() }),
62
+ expandedContent !== null && /* @__PURE__ */ jsx(ExpandedContentRow, { "data-key": `${row.id}-expanded`, "data-row-expanded-content": "true", role: "row", children: /* @__PURE__ */ jsx(ExpandedContentCell, { colSpan: row.getVisibleCells().length, children: expandedContent }) })
63
+ ] }, row.id);
64
+ })
51
65
  ) }, "virtual-table-body") : /* @__PURE__ */ jsx(TableEmptyBody, { emptyDataComponent, texts });
52
66
  };
53
67
  export {
@@ -1,2 +1,4 @@
1
1
  export declare const Tr: import('styled-components').StyledComponent<"tr", any, {}, never>;
2
2
  export declare const TBody: import('styled-components').StyledComponent<"tbody", any, {}, never>;
3
+ export declare const ExpandedContentRow: import('styled-components').StyledComponent<"tr", any, {}, never>;
4
+ export declare const ExpandedContentCell: import('styled-components').StyledComponent<"td", any, {}, never>;
@@ -9,7 +9,17 @@ const TBody = /* @__PURE__ */ styled.tbody.withConfig({
9
9
  displayName: "TableBodystyles__TBody",
10
10
  componentId: "sc-1dty8xx-1"
11
11
  })(["position:relative;display:block;"]);
12
+ const ExpandedContentRow = /* @__PURE__ */ styled.tr.withConfig({
13
+ displayName: "TableBodystyles__ExpandedContentRow",
14
+ componentId: "sc-1dty8xx-2"
15
+ })(["background:", ";"], (props) => props.theme.palette["white"]);
16
+ const ExpandedContentCell = /* @__PURE__ */ styled.td.withConfig({
17
+ displayName: "TableBodystyles__ExpandedContentCell",
18
+ componentId: "sc-1dty8xx-3"
19
+ })(["padding:0;background:", ";border-bottom:1px solid ", ";position:relative;tr:hover &{background:", ";}&:before{position:absolute;width:2px;height:100%;left:0;top:0;background-color:", ";content:'';}"], (props) => props.theme.palette["grey-050"], (props) => props.theme.palette["grey-200"], (props) => props.theme.palette["grey-100"], (props) => props.theme.palette["grey-600"]);
12
20
  export {
21
+ ExpandedContentCell,
22
+ ExpandedContentRow,
13
23
  TBody,
14
24
  Tr
15
25
  };
@@ -11,7 +11,7 @@ const TableEmptyBody = ({
11
11
  table
12
12
  } = useTableContext();
13
13
  const colSpan = table.getAllLeafColumns().length;
14
- return /* @__PURE__ */ jsx(TBody, { className: "ds-table-body", children: /* @__PURE__ */ jsx(Tr, { className: "ds-table-row", children: /* @__PURE__ */ jsx(Td, { colSpan, className: "ds-table-cell", children: /* @__PURE__ */ jsx(TableEmptyBodyWrapper, { children: emptyDataComponent !== void 0 ? emptyDataComponent : /* @__PURE__ */ jsx(Result, { description: texts.emptyText || /* @__PURE__ */ jsx(FormattedMessage, { id: "DS.TABLE.EMPTY_TEXT" }), type: "no-results", noSearchResults: true }) }) }) }) });
14
+ return /* @__PURE__ */ jsx(TBody, { className: "ds-table-body", children: /* @__PURE__ */ jsx(Tr, { className: "ds-table-row", children: /* @__PURE__ */ jsx(Td, { colSpan, className: "ds-table-cell", children: /* @__PURE__ */ jsx(TableEmptyBodyWrapper, { children: emptyDataComponent !== void 0 ? emptyDataComponent : /* @__PURE__ */ jsx(Result, { description: texts.emptyText || /* @__PURE__ */ jsx(FormattedMessage, { id: "DS.TABLE.EMPTY_TEXT" }), type: "no-results" }) }) }) }) });
15
15
  };
16
16
  export {
17
17
  TableEmptyBody
@@ -14,7 +14,7 @@ const TBody = /* @__PURE__ */ styled.tbody.withConfig({
14
14
  const TableEmptyBodyWrapper = /* @__PURE__ */ styled.div.withConfig({
15
15
  displayName: "TableEmptyBodystyles__TableEmptyBodyWrapper",
16
16
  componentId: "sc-14kyiyc-3"
17
- })(["min-height:160px;display:flex;align-items:center;"]);
17
+ })(["min-height:160px;display:flex;align-items:center;justify-content:center;"]);
18
18
  export {
19
19
  TBody,
20
20
  TableEmptyBodyWrapper,
@@ -1,3 +1,3 @@
1
1
  import { default as React } from 'react';
2
2
  import { TableRowProps } from '../../../Table.types';
3
- export declare const TableRow: <TData extends object>({ row, onRowClick, getRowProps, getRowTooltipProps, }: TableRowProps<TData>) => React.JSX.Element;
3
+ export declare const TableRow: <TData extends object>({ row, onRowClick, getRowProps, getRowTooltipProps, expandable, }: TableRowProps<TData>) => React.JSX.Element;
@@ -10,7 +10,8 @@ const TableRow = ({
10
10
  row,
11
11
  onRowClick,
12
12
  getRowProps,
13
- getRowTooltipProps
13
+ getRowTooltipProps,
14
+ expandable
14
15
  }) => {
15
16
  const isUnifiedTableContent = !useStickyContext();
16
17
  const customRowProps = getRowProps?.(row.original) ?? {};
@@ -18,8 +19,15 @@ const TableRow = ({
18
19
  onClick: customOnClick,
19
20
  ...restCustomRowProps
20
21
  } = customRowProps;
21
- const mergedOnClick = onRowClick || customOnClick ? (event) => {
22
+ const canExpand = !expandable?.rowExpandable || expandable.rowExpandable(row.original);
23
+ const togglesOnRowClick = !!expandable?.expandRowByClick && canExpand;
24
+ const mergedOnClick = onRowClick || customOnClick || togglesOnRowClick ? (event) => {
22
25
  customOnClick?.(event);
26
+ if (togglesOnRowClick && !event.isDefaultPrevented()) {
27
+ const nextExpanded = !row.getIsExpanded();
28
+ row.toggleExpanded();
29
+ expandable?.onExpand?.(nextExpanded, row.original);
30
+ }
23
31
  if (onRowClick && !event.isDefaultPrevented()) {
24
32
  event.stopPropagation();
25
33
  onRowClick(row.original, event);
@@ -1,5 +1,5 @@
1
1
  import { default as React } from 'react';
2
2
  import { TableRowVirtualProps } from '../../../Table.types';
3
- declare const TableRowVirtualInner: <TData extends object>({ cellHeight, rowIndex, virtual, infiniteScroll, texts, row, isLast, onRowClick, getRowProps, getRowTooltipProps, isExpanded: _isExpanded, isParentExpanded, }: TableRowVirtualProps<TData>) => React.JSX.Element;
3
+ declare const TableRowVirtualInner: <TData extends object>({ cellHeight, rowIndex, virtual, infiniteScroll, texts, row, isLast, onRowClick, getRowProps, getRowTooltipProps, isExpanded: _isExpanded, isParentExpanded, expandable, }: TableRowVirtualProps<TData>) => React.JSX.Element;
4
4
  export declare const TableRowVirtual: typeof TableRowVirtualInner;
5
5
  export {};
@@ -20,7 +20,8 @@ const TableRowVirtualInner = ({
20
20
  getRowProps,
21
21
  getRowTooltipProps,
22
22
  isExpanded: _isExpanded,
23
- isParentExpanded
23
+ isParentExpanded,
24
+ expandable
24
25
  }) => {
25
26
  const {
26
27
  rowVirtualizer
@@ -72,8 +73,15 @@ const TableRowVirtualInner = ({
72
73
  style: customStyle,
73
74
  ...restCustomRowProps
74
75
  } = customRowProps;
75
- const mergedOnClick = onRowClick || customOnClick ? (event) => {
76
+ const canExpand = !expandable?.rowExpandable || expandable.rowExpandable(row.original);
77
+ const togglesOnRowClick = !!expandable?.expandRowByClick && canExpand;
78
+ const mergedOnClick = onRowClick || customOnClick || togglesOnRowClick ? (event) => {
76
79
  customOnClick?.(event);
80
+ if (togglesOnRowClick && !event.isDefaultPrevented()) {
81
+ const nextExpanded = !row.getIsExpanded();
82
+ row.toggleExpanded();
83
+ expandable?.onExpand?.(nextExpanded, row.original);
84
+ }
77
85
  if (onRowClick && !event.isDefaultPrevented()) {
78
86
  event.stopPropagation();
79
87
  onRowClick(row.original, event);
@@ -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, hideExpandIcon, 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, style, rowExpandable, ...props }: TreeTableProps<TData, TValue>) => React.JSX.Element;
@@ -29,6 +29,8 @@ const TreeTable = ({
29
29
  expandIconColumnIndex = 0,
30
30
  hideExpandIcon = false,
31
31
  rowKey,
32
+ style,
33
+ rowExpandable,
32
34
  ...props
33
35
  }) => {
34
36
  const childrenKey = childrenColumnName ?? "children";
@@ -81,11 +83,12 @@ const TreeTable = ({
81
83
  const rowId = getRowKey(rowData);
82
84
  const isParent = hasChildren(rowData);
83
85
  const isExpanded = expandedKeys.includes(rowId);
86
+ const canExpand = !rowExpandable || rowExpandable(rowData);
84
87
  const indents = Array.from({
85
88
  length: depth
86
89
  }, (_, i) => /* @__PURE__ */ jsx(IndentBar, { $level: i, $active: i + 1 === depth }, i));
87
90
  const originalCell = typeof col.cell === "function" ? col.cell(info) : info.getValue();
88
- const rowPrefix = isParent && !hideExpandIcon ? /* @__PURE__ */ jsx(Expander, { expanded: isExpanded, onClick: (e) => {
91
+ const rowPrefix = isParent && canExpand && !hideExpandIcon ? /* @__PURE__ */ jsx(Expander, { expanded: isExpanded, onClick: (e) => {
89
92
  e.stopPropagation();
90
93
  toggleExpand(rowId);
91
94
  } }) : depth > 0 ? /* @__PURE__ */ jsx(Icon, { component: /* @__PURE__ */ jsx(ChildRowLeftDownM, {}), color: theme.palette["grey-400"] }) : null;
@@ -98,8 +101,8 @@ const TreeTable = ({
98
101
  }
99
102
  };
100
103
  });
101
- }, [columns, expandIconColumnIndex, getRowKey, hasChildren, expandedKeys, toggleExpand, hideExpandIcon]);
102
- return /* @__PURE__ */ jsx(TreeTableRoot, { children: /* @__PURE__ */ jsx(Table, { data, columns: treeColumns, rowKey, expandable: {
104
+ }, [columns, expandIconColumnIndex, getRowKey, hasChildren, expandedKeys, toggleExpand, hideExpandIcon, rowExpandable]);
105
+ return /* @__PURE__ */ jsx(TreeTableRoot, { style, children: /* @__PURE__ */ jsx(Table, { data, columns: treeColumns, rowKey, expandable: {
103
106
  childrenColumnName: childrenKey,
104
107
  expandedRowKeys: expandedKeys
105
108
  }, ...props }) });
@@ -32,4 +32,10 @@ export type TreeTableProps<TData, TValue> = Omit<TableProps<TData, TValue>, 'exp
32
32
  * @default false
33
33
  */
34
34
  hideExpandIcon?: boolean;
35
+ /**
36
+ * Returns false to mark a row as non-expandable. Hides the expander button
37
+ * for that row while preserving indentation. Rows whose predicate returns
38
+ * undefined / true keep the expander UI as normal.
39
+ */
40
+ rowExpandable?: (record: TData) => boolean;
35
41
  };
@@ -140,6 +140,7 @@ const useTable = ({
140
140
  const getSubRows = useCallback((row) => {
141
141
  return row[childrenColumnName];
142
142
  }, [childrenColumnName]);
143
+ const isExpansionControlled = !!expandable?.expandedRowKeys;
143
144
  const expandedKeys = expandable?.expandedRowKeys ? arrayToTrueMap(expandable?.expandedRowKeys) : void 0;
144
145
  const table = useReactTable({
145
146
  // Override TanStack's built-in sizing defaults (size: 150, minSize: 20,
@@ -162,8 +163,14 @@ const useTable = ({
162
163
  getExpandedRowModel: expandable ? getExpandedRowModel() : void 0,
163
164
  getGroupedRowModel: getGroupedRowModel(),
164
165
  onRowSelectionChange: handleSelectionChange,
165
- onExpandedChange: () => {
166
- },
166
+ // Swallow TanStack's expansion writes only when the consumer is the source
167
+ // of truth (controlled via `expandable.expandedRowKeys`). For uncontrolled
168
+ // use (e.g. `expandable.expandRowByClick` without `expandedRowKeys`) we
169
+ // omit this so `row.toggleExpanded()` can update the internal state.
170
+ ...isExpansionControlled ? {
171
+ onExpandedChange: () => {
172
+ }
173
+ } : {},
167
174
  onSortingChange: handleSortingChange,
168
175
  enableRowSelection: (row) => {
169
176
  const {
@@ -172,14 +179,16 @@ const useTable = ({
172
179
  } = selectionConfig?.checkRowSelectionStatus?.(row.original) || {};
173
180
  return !!selectionConfig && !unavailable && !disabled;
174
181
  },
175
- manualExpanding: !!expandable?.expandedRowKeys,
182
+ manualExpanding: isExpansionControlled,
176
183
  initialState: {
177
184
  columnPinning: {
178
185
  right: rightPinnedColumns,
179
186
  left: leftPinnedColumns
180
187
  },
181
188
  ...paginationInitialState,
182
- expanded: expandedKeys
189
+ ...isExpansionControlled ? {
190
+ expanded: expandedKeys
191
+ } : {}
183
192
  },
184
193
  state: {
185
194
  columnPinning: {
@@ -188,7 +197,11 @@ const useTable = ({
188
197
  },
189
198
  sorting,
190
199
  rowSelection,
191
- expanded: expandedKeys
200
+ // Only project expanded into TanStack state when controlled — otherwise
201
+ // TanStack keeps and manages its own internal state.
202
+ ...isExpansionControlled ? {
203
+ expanded: expandedKeys
204
+ } : {}
192
205
  }
193
206
  });
194
207
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-table-new",
3
- "version": "1.4.2",
3
+ "version": "1.4.4",
4
4
  "description": "TableNew UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "Synerise/synerise-design",
@@ -43,28 +43,28 @@
43
43
  "types": "dist/index.d.ts",
44
44
  "dependencies": {
45
45
  "@floating-ui/react": "^0.27.16",
46
- "@synerise/ds-badge": "^1.0.55",
47
- "@synerise/ds-button": "^1.5.31",
48
- "@synerise/ds-checkbox": "^1.2.32",
49
- "@synerise/ds-copy-icon": "^1.2.13",
50
- "@synerise/ds-dropdown": "^1.3.14",
46
+ "@synerise/ds-badge": "^1.0.56",
47
+ "@synerise/ds-button": "^1.5.32",
48
+ "@synerise/ds-checkbox": "^1.2.33",
49
+ "@synerise/ds-copy-icon": "^1.2.14",
50
+ "@synerise/ds-dropdown": "^1.3.15",
51
51
  "@synerise/ds-flag": "^1.0.12",
52
- "@synerise/ds-icon": "^1.18.2",
53
- "@synerise/ds-inline-alert": "^1.1.25",
54
- "@synerise/ds-input": "^1.7.9",
55
- "@synerise/ds-input-number": "^1.2.46",
52
+ "@synerise/ds-icon": "^1.18.3",
53
+ "@synerise/ds-inline-alert": "^1.1.26",
54
+ "@synerise/ds-input": "^1.7.10",
55
+ "@synerise/ds-input-number": "^1.2.47",
56
56
  "@synerise/ds-loader": "^1.0.17",
57
- "@synerise/ds-modal": "^1.5.1",
58
- "@synerise/ds-pagination": "^1.0.66",
59
- "@synerise/ds-result": "^1.0.62",
60
- "@synerise/ds-scrollbar": "^1.4.1",
61
- "@synerise/ds-search": "^1.5.27",
62
- "@synerise/ds-skeleton": "^1.0.56",
63
- "@synerise/ds-tag": "^1.4.29",
64
- "@synerise/ds-tags": "^1.5.43",
65
- "@synerise/ds-tooltip": "^1.5.1",
66
- "@synerise/ds-typography": "^1.1.24",
67
- "@synerise/ds-utils": "^1.9.1",
57
+ "@synerise/ds-modal": "^1.6.0",
58
+ "@synerise/ds-pagination": "^1.0.67",
59
+ "@synerise/ds-result": "^1.0.63",
60
+ "@synerise/ds-scrollbar": "^1.5.0",
61
+ "@synerise/ds-search": "^1.5.28",
62
+ "@synerise/ds-skeleton": "^1.0.57",
63
+ "@synerise/ds-tag": "^1.4.30",
64
+ "@synerise/ds-tags": "^1.5.44",
65
+ "@synerise/ds-tooltip": "^1.5.2",
66
+ "@synerise/ds-typography": "^1.1.25",
67
+ "@synerise/ds-utils": "^1.10.0",
68
68
  "@tanstack/react-table": "^8.21.3",
69
69
  "@tanstack/react-virtual": "^3.13.12",
70
70
  "unit-to-px": "^1.0.5",
@@ -80,5 +80,5 @@
80
80
  "react-intl": ">= 3.12.0 <= 6.8",
81
81
  "styled-components": "^5.3.3"
82
82
  },
83
- "gitHead": "b95ec2ba9c2c12116a41d82cedfe2b973c370449"
83
+ "gitHead": "fe3379f50afdce6d8c61a2222ebbf03324107c95"
84
84
  }