Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# Changelog

## 5.1.0 - 2026-08-13

Version 5.1 fixes fill-layout spacer rendering without changing the public API,
TanStack v9 integration, or persisted table state.

### Fixed

- Render the internal fill-layout spacer with the same header and row borders
and backgrounds as neighboring cells, keeping the grid visually continuous
through a right-pinned actions column.
- Apply the continuous grid styling to ordinary rows, virtual rows, and summary
rows while preserving the spacer's inert accessibility semantics.

### Compatibility

- No consumer migration or configuration change is required.
- Existing column widths, horizontal overflow, right-pinned actions, keyboard
navigation, and the reserved `__spacer__` behavior remain unchanged.

### Validation

- 318 unit/integration tests, including static, virtual, adapter, and summary
spacer coverage
- Chromium fill/overflow layout regression with computed border and background
comparisons
- lint, typecheck, package build, packed-consumer build, public API snapshot,
and bundle budgets

## 5.0.0 - 2026-08-13

Version 5 upgrades the package's TanStack-facing API to TanStack React Table
Expand Down
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ infinite loading, typed server data sources, and host-owned drag/upload
integrations. See
[`docs/API.md`](./docs/API.md) for the complete contract.

## 5.1.0 Compatibility

Version 5.1.0 makes the internal fill-layout spacer render as an empty table
segment with the same header, body-row, and summary-row borders/backgrounds as
its neighboring cells. It does not change the public API, TanStack v9
integration, persisted state, column widths, overflow behavior, or accessibility
semantics. No consumer migration is required.

## Breaking changes in 5.0.0

Version 5 upgrades to TanStack React Table v9.1.2 and uses `useTable` with an
Expand Down Expand Up @@ -83,8 +91,8 @@ Version 4.5.0 adds optional scrollbar visibility control and corrects
fixed-width `layoutMode="fill"` tables without removing any public API. Set
`scrollbarVisibility="always"` when persistent horizontal and vertical
scrollbars are required. When every currently visible data column has a fixed
width, fill layout now keeps those widths and automatically places a
transparent flexible spacer before a right-pinned actions column. Consumers
width, fill layout now keeps those widths and automatically places an empty
flexible spacer before a right-pinned actions column. Consumers
must not create or reference the reserved `__spacer__` column.

## 4.4.0 Compatibility
Expand All @@ -106,11 +114,11 @@ The previously planned wrapper API cleanup was ultimately deferred beyond
## Installation

```bash
pnpm add github:Dastari/data-table-pro#v5.0.0
pnpm add github:Dastari/data-table-pro#v5.1.0
```

This package is installed from GitHub refs. It is not published to npm.
Release tags such as `v5.0.0` include committed `dist/` output, so consumers
Release tags such as `v5.1.0` include committed `dist/` output, so consumers
do not need to allow package build scripts during install.

Peer dependencies:
Expand Down
51 changes: 50 additions & 1 deletion browser-tests/data-table.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,45 @@ test("fill layout gives spare width to the internal spacer and preserves overflo
const actions = headers.find(
(header) => header.dataset.columnId === "__actions__",
);
if (!scrollArea || !viewport || !name || !spacer || !actions) {
const spacerIndex = spacer ? headers.indexOf(spacer) : -1;
const adjacentHeader = headers[spacerIndex - 1];
const firstBodyRow = element.querySelector("tbody tr");
const adjacentCell = adjacentHeader?.dataset.columnId
? firstBodyRow?.querySelector<HTMLElement>(
`[data-column-id="${adjacentHeader.dataset.columnId}"]`,
)
: undefined;
const spacerCell = firstBodyRow?.querySelector<HTMLElement>(
'[data-column-id="__spacer__"]',
);
if (
!scrollArea ||
!viewport ||
!name ||
!spacer ||
!actions ||
!adjacentHeader ||
!adjacentCell ||
!spacerCell
) {
throw new Error("Expected the fill-layout regression columns");
}
const readCellAppearance = (cell: HTMLElement) => {
const styles = getComputedStyle(cell);
return {
backgroundColor: styles.backgroundColor,
borderBottomColor: styles.borderBottomColor,
borderBottomStyle: styles.borderBottomStyle,
borderBottomWidth: styles.borderBottomWidth,
};
};
return {
actionIndex: headers.indexOf(actions),
bodyAdjacentAppearance: readCellAppearance(adjacentCell),
bodySpacerAppearance: readCellAppearance(spacerCell),
clientWidth: viewport.clientWidth,
headerAdjacentAppearance: readCellAppearance(adjacentHeader),
headerSpacerAppearance: readCellAppearance(spacer),
nameWidth: name.getBoundingClientRect().width,
scrollWidth: viewport.scrollWidth,
spacerIndex: headers.indexOf(spacer),
Expand All @@ -250,6 +283,16 @@ test("fill layout gives spare width to the internal spacer and preserves overflo
expect(wideLayout.scrollWidth).toBeLessThanOrEqual(
wideLayout.clientWidth + 1,
);
expect(wideLayout.headerSpacerAppearance).toEqual(
wideLayout.headerAdjacentAppearance,
);
expect(wideLayout.bodySpacerAppearance).toEqual(
wideLayout.bodyAdjacentAppearance,
);
expect(wideLayout.headerSpacerAppearance.borderBottomWidth).not.toBe("0px");
expect(wideLayout.headerSpacerAppearance.borderBottomStyle).not.toBe("none");
expect(wideLayout.bodySpacerAppearance.borderBottomWidth).not.toBe("0px");
expect(wideLayout.bodySpacerAppearance.borderBottomStyle).not.toBe("none");

await table.evaluate((element) => {
element.style.width = "720px";
Expand All @@ -261,6 +304,12 @@ test("fill layout gives spare width to the internal spacer and preserves overflo
expect(narrowLayout.nameWidth).toBeCloseTo(220, 0);
expect(narrowLayout.spacerIndex).toBe(narrowLayout.actionIndex - 1);
expect(narrowLayout.scrollWidth).toBeGreaterThan(narrowLayout.clientWidth);
expect(narrowLayout.headerSpacerAppearance).toEqual(
narrowLayout.headerAdjacentAppearance,
);
expect(narrowLayout.bodySpacerAppearance).toEqual(
narrowLayout.bodyAdjacentAppearance,
);
});

test("interactive grid navigation follows the rendered cell geometry", async ({
Expand Down
2 changes: 1 addition & 1 deletion dist/adapter-virtual.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/adapter.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/advanced.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions dist/chunk-KUDBNY6E.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/chunk-UMW6DOXG.js.map → dist/chunk-KUDBNY6E.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dist/chunk-XZTPNWJD.js → dist/chunk-NYFLVBJD.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/chunk-XZTPNWJD.js.map → dist/chunk-NYFLVBJD.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/chunk-IZQDLLCH.js → dist/chunk-UADXBI2T.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading