Bug Fix: column widths are now propagated to body cells via CSS custom properties

This commit is contained in:
SergeantPanda 2026-04-21 11:00:18 -05:00
parent 63c10da57d
commit 7e21e3bb1a
4 changed files with 22 additions and 6 deletions

View file

@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- **Column resizing in `CustomTable`**: column widths are now propagated to body cells via CSS custom properties (`--header-{id}-size`) injected on the table wrapper, rather than reading `column.getSize()` directly in each cell's React style. This decouples body-cell widths from React renders so that memoized rows (which skip re-renders for performance) still reflect resize changes instantly via CSS cascade.
- Decoupled row expansion from row selection in `CustomTable`, expanding a channel row no longer also selects it. Added an `onRowExpansionChange` callback to `useTable` so callers can react to expansion changes independently of selection state.
- Fixed a stale-closure bug in memoized channel row checkboxes, `selectedTableIdsRef` now ensures the checkbox `onChange` handler and `handleShiftSelect` always read the current selection set rather than the stale set captured at render time. Without this, clicking any checkbox after the first would silently deselect previously checked rows.
- Fixed the "Add to Channel" per-row and bulk buttons in the Streams table not activating when a channel row is expanded. `StreamRowActions` now subscribes to the Zustand store directly (bypassing `React.memo`) so button state updates when `expandedChannelId` or `selectedChannelIds` change without any parent row props changing. Added `targetChannelId` (expanded channel takes priority; falls back to a single selected channel) used by both the per-row and bulk add paths.

View file

@ -27,6 +27,20 @@ const CustomTable = ({ table }) => {
return width;
}, [table, columnSizing]);
// CSS custom properties for each fixed-width column's current size.
// These are injected on the table wrapper and cascade to all descendant cells,
// so body cells (which are memoized and don't re-render on resize) still pick
// up the new width via CSS cascade without needing a React re-render.
const columnSizeVars = useMemo(() => {
void columnSizing;
return table.getFlatHeaders().reduce((vars, header) => {
if (!header.column.columnDef.grow) {
vars[`--header-${header.id}-size`] = `${header.getSize()}px`;
}
return vars;
}, {});
}, [table, columnSizing]);
return (
<Box
className={`divTable table-striped table-size-${tableSize}`}
@ -36,6 +50,7 @@ const CustomTable = ({ table }) => {
minWidth: `${minTableWidth}px`,
display: 'flex',
flexDirection: 'column',
...columnSizeVars,
}}
>
<CustomTableHeader

View file

@ -60,9 +60,9 @@ const MemoizedTableRow = React.memo(
}),
}
: {
flex: `0 0 ${cell.column.getSize ? cell.column.getSize() : 150}px`,
width: `${cell.column.getSize ? cell.column.getSize() : 150}px`,
maxWidth: `${cell.column.getSize ? cell.column.getSize() : 150}px`,
flex: `0 0 var(--header-${cell.column.id}-size)`,
width: `var(--header-${cell.column.id}-size)`,
maxWidth: `var(--header-${cell.column.id}-size)`,
}),
...(tableCellProps && tableCellProps({ cell })),
}}

View file

@ -117,9 +117,9 @@ const CustomTableHeader = ({
}),
}
: {
flex: `0 0 ${header.getSize ? header.getSize() : 150}px`,
width: `${header.getSize ? header.getSize() : 150}px`,
maxWidth: `${header.getSize ? header.getSize() : 150}px`,
flex: `0 0 var(--header-${header.id}-size)`,
width: `var(--header-${header.id}-size)`,
maxWidth: `var(--header-${header.id}-size)`,
}),
position: 'relative',
// ...(tableCellProps && tableCellProps({ cell: header })),