Skip to content

feat: accept column pinning in a server-mode data table's initial state - #129

Merged
joshunrau merged 1 commit into
mainfrom
fix/server-data-table-column-pinning
Oct 30, 2026
Merged

joshunrau merged 1 commit into
mainfrom
fix/server-data-table-column-pinning

Conversation

@thomasbeaudry

Copy link
Copy Markdown
Collaborator

Problem

ServerDataTableStoreParams typed initialState as never, so a DataTable in server mode could pin nothing. Pinning is the only way to give a column a width of its own: calculateColumnSizing honours columnDef.size on a pinned column and splits the remainder evenly between the unpinned ones. A server-mode table therefore had no way to let one column take the room its content needs — every column got an identical share — while a client-mode table does exactly that:

// a client-mode table, today
initialState={{ columnPinning: { right: ['url', 'instrumentCount', 'lastSynced'] } }}

Open Data Capture hit this on an activity log table that pages and sorts server-side: its repository column holds owner/some-long-repository-name and was stuck at one seventh of the table.

Change

  • ServerDataTableInitialState = { columnPinning?: ColumnPinningState }, and server params accept it in place of never.
  • ClientDataTableInitialState now composes from it, adding columnFilters and sorting. Those stay client-only: in server mode filtering and sorting belong to the request, not to the table.
  • getTanstackTableState reads the initial state through the client shape, which the server one is a subset of, so the union's narrower member does not make columnFilters and sorting unreadable there.

This is a type-level change only. getTanstackTableState already read initialState regardless of mode, and reset() deliberately never rebuilds it, so the runtime already behaved correctly — nothing but the type stopped a consumer from asking.

Tests

Two cases in DataTable.spec.tsx covering a server-mode table with and without pinning, asserting against the sticky positioning DataTableHead gives a pinned column. Verified red first: without this change tsc rejects the spec with

error TS2322: ... Types of property 'mode' are incompatible.
  Type '"server"' is not assignable to type '"client"'.

so the spec guards the type as well as the behaviour.

pnpm lint clean, vitest run src/components/DataTable 8/8.

🤖 Generated with Claude Code

`ServerDataTableStoreParams` typed `initialState` as `never`, so a table paging
and sorting server-side could pin nothing. Pinning is the only way to give a
column a width of its own: `calculateColumnSizing` honours `size` on a pinned
column and splits the remainder evenly between the rest. A server-mode table
therefore had no way to let one column take the room its content needs, while a
client-mode table does.

Pinning is layout, not a view of the data, so it is the one piece of initial
state that means the same thing in either mode. `columnFilters` and `sorting`
stay client-only: in server mode those belong to the request. The store already
read `initialState` regardless of mode and `reset()` deliberately never rebuilds
it, so this is a type-level change alone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
thomasbeaudry added a commit to DouglasNeuroInformatics/OpenDataCapture that referenced this pull request Oct 30, 2026
`ServerDataTableStoreParams` types `initialState` as `never`, and
`calculateColumnSizing` honours `columnDef.size` only on a pinned column, so a
table that pages server-side could not give one column the room its content
needs: every column took an identical share of the width.

The patch is type-only -- the store already read `initialState` in both modes
and `reset()` deliberately never rebuilds it. It carries
DouglasNeuroInformatics/libui#129; delete it and the `patchedDependencies` entry
when the catalog moves to the release that includes it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@joshunrau
joshunrau merged commit a443548 into main Oct 30, 2026
1 check passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 6.19.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

thomasbeaudry added a commit to DouglasNeuroInformatics/OpenDataCapture that referenced this pull request Oct 30, 2026
`ServerDataTableStoreParams` types `initialState` as `never`, and
`calculateColumnSizing` honours `columnDef.size` only on a pinned column, so a
table that pages server-side could not give one column the room its content
needs: every column took an identical share of the width.

The patch is type-only -- the store already read `initialState` in both modes
and `reset()` deliberately never rebuilds it. It carries
DouglasNeuroInformatics/libui#129; delete it and the `patchedDependencies` entry
when the catalog moves to the release that includes it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants