From 454c3ac4bdce2c73b653cd93e2fbce50711179ba Mon Sep 17 00:00:00 2001 From: "ilia.brauer" Date: Thu, 20 Aug 2026 09:00:45 +0200 Subject: [PATCH 1/2] [data-table] improved cells rerenders --- .../data-table/src/components/Body/Body.tsx | 10 +++--- .../data-table/src/components/Body/Cell.tsx | 3 +- .../data-table/src/components/Body/Row.tsx | 35 +++++++++++++++++-- .../src/components/Body/Row.types.ts | 10 +++--- .../src/components/Body/RowGroup.tsx | 6 ++-- .../data-table/src/components/Head/Column.tsx | 2 +- .../checkbox_in_big_table_reactive/index.tsx | 26 +++++++------- .../checkbox_in_big_table_reactive/table.tsx | 3 +- 8 files changed, 65 insertions(+), 30 deletions(-) diff --git a/semcore/data-table/src/components/Body/Body.tsx b/semcore/data-table/src/components/Body/Body.tsx index 89c8f92c43..8d8b2d3bf0 100644 --- a/semcore/data-table/src/components/Body/Body.tsx +++ b/semcore/data-table/src/components/Body/Body.tsx @@ -115,7 +115,6 @@ class BodyRoot extends Component extends Component extends Component extends Component extends Component extends Component - {emptyRow && } + {emptyRow && } {needMarginTop && rowMarginTop && } {rowsToRender.map((row, index) => { if (Array.isArray(row)) { @@ -376,6 +373,7 @@ class BodyRoot extends Component ); } @@ -386,6 +384,8 @@ class BodyRoot extends Component ); })} diff --git a/semcore/data-table/src/components/Body/Cell.tsx b/semcore/data-table/src/components/Body/Cell.tsx index 735d3cee01..f815470aa0 100644 --- a/semcore/data-table/src/components/Body/Cell.tsx +++ b/semcore/data-table/src/components/Body/Cell.tsx @@ -1,5 +1,4 @@ import { Box, Flex } from '@semcore/base-components'; -import type { Intergalactic } from '@semcore/core'; import { Root, sstyled, createComponent, Component } from '@semcore/core'; import { getFocusableIn } from '@semcore/core/lib/utils/focus-lock/getFocusableIn'; import { isFocusInside } from '@semcore/core/lib/utils/focus-lock/isFocusInside'; @@ -105,7 +104,7 @@ class CellRoot gridArea={gridArea} fixed={column.fixed} style={style} - shadowVertical={column.showShadowVertical ? shadowVertical : undefined} + shadowVertical={shadowVertical} > extends Component< DataTableRowProps, [], @@ -45,6 +47,7 @@ export class RowRoot extends Component< private cellName: string = ''; private closeAccordionTimeout = 0; private openAccordionTimeout = 0; + private readonly cellStyle = new Map(); rowElementRef = React.createRef(); @@ -58,6 +61,8 @@ export class RowRoot extends Component< super(props); this.handleClickRow = this.handleClickRow.bind(this); + + this.recalculateCellStyle(); } componentDidMount() { @@ -79,6 +84,31 @@ export class RowRoot extends Component< this.asProps.componentRef?.(null); } + onPropsChange(changedProps: Record) { + if ('columns' in changedProps) { + this.recalculateCellStyle(); + } + } + + recalculateCellStyle() { + const { columns, getFixedStyle } = this.props; + + columns.forEach((column) => { + if (column.fixed) { + const styles: React.CSSProperties = {}; + this.cellStyle.set(column.name, styles); + + const [name, value] = getFixedStyle(column); + + if (name !== undefined && value !== undefined) { + styles[name] = value; + } + } else { + this.cellStyle.delete(column.name); + } + }); + } + setAccordion() { const { row } = this.asProps; @@ -267,7 +297,6 @@ export class RowRoot extends Component< tableRef, onCellClick, rawData, - shadowVertical, flatRows, variant, isAccordionRow, @@ -313,7 +342,6 @@ export class RowRoot extends Component< children: props?.children ?? defaultRender(), onClick: onCellClick, flatRows: this.asProps.flatRows, - shadowVertical, withoutBorder, theme, }; @@ -575,7 +603,8 @@ export class RowRoot extends Component< accordionRowIndex={accordionRowIndex} rows={rows} aria-hidden={isCellHidden} - style={style} + style={this.cellStyle.get(column.name)} + shadowVertical={column.showShadowVertical ? shadowVertical : undefined} data-aria-level={index === 0 ? ariaLevel : undefined} /> ); diff --git a/semcore/data-table/src/components/Body/Row.types.ts b/semcore/data-table/src/components/Body/Row.types.ts index 899ac3c7d5..e867cfb534 100644 --- a/semcore/data-table/src/components/Body/Row.types.ts +++ b/semcore/data-table/src/components/Body/Row.types.ts @@ -48,6 +48,12 @@ export type DataTableRowProps = { accordionIndex?: number; theme?: Theme; + + columns: DTColumn[]; + + getFixedStyle: ( + cell: Pick, + ) => [side: 'left' | 'right', style: string | number] | [side: undefined, style: undefined]; }; export type RowPropsInner = JSX.IntrinsicElements['div'] & { @@ -57,7 +63,6 @@ export type RowPropsInner = JSX.Intrins */ mergedRow?: boolean; - columns: DTColumn[]; row: DTRow | DTRow[]; rows: DTRows; flatRows: DTRow[]; @@ -86,9 +91,6 @@ export type RowPropsInner = JSX.Intrins scrollAreaRef: React.RefObject; uid: string; sideIndents?: 'wide'; - getFixedStyle: ( - cell: Pick, - ) => [side: 'left' | 'right', style: string | number] | [side: undefined, style: undefined]; renderCell?: (props: CellRenderProps) => React.ReactNode | Record; getI18nText: (key: string) => string; diff --git a/semcore/data-table/src/components/Body/RowGroup.tsx b/semcore/data-table/src/components/Body/RowGroup.tsx index 0ee4bc1a4b..f1e86b5d12 100644 --- a/semcore/data-table/src/components/Body/RowGroup.tsx +++ b/semcore/data-table/src/components/Body/RowGroup.tsx @@ -20,13 +20,13 @@ type RowGroupProps = { rowIndex: number; handleRef: (index: number, row: DTRow) => (node: HTMLElement | null) => void; handleComponentRef: (row: DTRow) => (component: RowRoot | null) => void; - + getFixedStyle: DataTableRowProps['getFixedStyle']; }; export class RowGroup extends React.PureComponent> { render() { const SRowGroup = Box; - const { rows, selectedRows, columns, startIndex, rowIndex } = this.props; + const { rows, selectedRows, columns, startIndex, rowIndex, getFixedStyle } = this.props; const groupUniqKey = rows[0][UNIQ_ROW_KEY]; @@ -50,6 +50,8 @@ export class RowGroup extends React.Pur row: item, mergedRow: i > 0 ? true : false, componentRef: this.props.handleComponentRef(item), + columns, + getFixedStyle, }; return ( diff --git a/semcore/data-table/src/components/Head/Column.tsx b/semcore/data-table/src/components/Head/Column.tsx index 2fbce0af28..274902617f 100644 --- a/semcore/data-table/src/components/Head/Column.tsx +++ b/semcore/data-table/src/components/Head/Column.tsx @@ -17,7 +17,7 @@ import { handleFocusCell, handleKeydownFocusCell } from '../../enhancers/focusab import type { ROW_GROUP } from '../DataTable/DataTable'; import type { DataTableData, SortDirection } from '../DataTable/DataTable.types'; -const SORTING_ICON: { [key in SortDirection]: React.FC> } = { +const SORTING_ICON: { [key in SortDirection]: typeof SortAsc | typeof SortDesc } = { desc: SortDesc, asc: SortAsc, } as const; diff --git a/stories/components/data-table/advanced/examples/checkbox_in_big_table_reactive/index.tsx b/stories/components/data-table/advanced/examples/checkbox_in_big_table_reactive/index.tsx index 2e76a15521..97475f72da 100644 --- a/stories/components/data-table/advanced/examples/checkbox_in_big_table_reactive/index.tsx +++ b/stories/components/data-table/advanced/examples/checkbox_in_big_table_reactive/index.tsx @@ -16,14 +16,15 @@ type CheckboxExampleProps = { compact?: boolean; }; -const selectedRows = new SelectableRows(); +// const selectedRows = new SelectableRows(); const Demo = (props: CheckboxExampleProps) => { - const { count: selectedRowsDisplay } = useSelectedRowsCount(selectedRows); + const [selectedRows, setSelectedRows] = React.useState([]); + // const { count: selectedRowsDisplay } = useSelectedRowsCount(selectedRows); const tableRef = React.useRef(null); const handleDeselectAll = () => { - selectedRows.clearAll(); + // selectedRows.clearAll(); tableRef.current?.focus(); }; @@ -56,18 +57,19 @@ const Demo = (props: CheckboxExampleProps) => { 'var(--intergalactic-bg-primary-neutral, #ffffff)', }} > - - - Selected rows: {selectedRowsDisplay} - - {selectedRowsDisplay > 0 && ( - - )} + {/* */} + {/* */} + {/* Selected rows: {selectedRowsDisplay} */} + {/* */} + {/* {selectedRowsDisplay > 0 && ( */} + {/* */} + {/* )} */} ; + handleSelectRows: any; tableRef: React.Ref; sideIndents?: 'wide'; @@ -41,7 +42,7 @@ export const Table = (props: TableProps) => { aria-label='Table example with selectable rows' defaultGridTemplateColumnWidth='auto' selectedRows={props.selectedRows} - // onSelectedRowsChange={props.handleChangeSelectedRows} + onSelectedRowsChange={props.handleSelectRows} ref={props.tableRef} sideIndents={props.sideIndents} loading={props.loading} From 79554b1aa11ab9d230bc3b0ec63c5e31a2024701 Mon Sep 17 00:00:00 2001 From: "ilia.brauer" Date: Fri, 21 Aug 2026 09:45:46 +0200 Subject: [PATCH 2/2] [data-table] improved cells rerenders --- .../data-table/src/components/Body/Row.tsx | 2 ++ .../checkbox_in_big_table_reactive/index.tsx | 26 +++++++++---------- .../checkbox_in_big_table_reactive/table.tsx | 2 -- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/semcore/data-table/src/components/Body/Row.tsx b/semcore/data-table/src/components/Body/Row.tsx index 8a25cca2b1..c85316b393 100644 --- a/semcore/data-table/src/components/Body/Row.tsx +++ b/semcore/data-table/src/components/Body/Row.tsx @@ -82,6 +82,8 @@ export class RowRoot extends Component< componentWillUnmount() { this.asProps.componentRef?.(null); + + this.cellStyle.clear(); } onPropsChange(changedProps: Record) { diff --git a/stories/components/data-table/advanced/examples/checkbox_in_big_table_reactive/index.tsx b/stories/components/data-table/advanced/examples/checkbox_in_big_table_reactive/index.tsx index 97475f72da..2e76a15521 100644 --- a/stories/components/data-table/advanced/examples/checkbox_in_big_table_reactive/index.tsx +++ b/stories/components/data-table/advanced/examples/checkbox_in_big_table_reactive/index.tsx @@ -16,15 +16,14 @@ type CheckboxExampleProps = { compact?: boolean; }; -// const selectedRows = new SelectableRows(); +const selectedRows = new SelectableRows(); const Demo = (props: CheckboxExampleProps) => { - const [selectedRows, setSelectedRows] = React.useState([]); - // const { count: selectedRowsDisplay } = useSelectedRowsCount(selectedRows); + const { count: selectedRowsDisplay } = useSelectedRowsCount(selectedRows); const tableRef = React.useRef(null); const handleDeselectAll = () => { - // selectedRows.clearAll(); + selectedRows.clearAll(); tableRef.current?.focus(); }; @@ -57,19 +56,18 @@ const Demo = (props: CheckboxExampleProps) => { 'var(--intergalactic-bg-primary-neutral, #ffffff)', }} > - {/* */} - {/* */} - {/* Selected rows: {selectedRowsDisplay} */} - {/* */} - {/* {selectedRowsDisplay > 0 && ( */} - {/* */} - {/* )} */} + + + Selected rows: {selectedRowsDisplay} + + {selectedRowsDisplay > 0 && ( + + )}
; - handleSelectRows: any; tableRef: React.Ref; sideIndents?: 'wide'; @@ -42,7 +41,6 @@ export const Table = (props: TableProps) => { aria-label='Table example with selectable rows' defaultGridTemplateColumnWidth='auto' selectedRows={props.selectedRows} - onSelectedRowsChange={props.handleSelectRows} ref={props.tableRef} sideIndents={props.sideIndents} loading={props.loading}