DataTable Column Sizing Persistence
niko-table/data-table-column-sizing-persistenceFreeUtility
Opt-in localStorage persistence for column widths. Call useColumnSizingPersistence(storageKey) and wire the returned columnSizing + onColumnSizingChange into <DataTableRoot> so resized widths survive reloads. Writes immediately, SSR-safe, and sanitizes corrupt storage.
Install it
npx shadcn@latest add https://niko-table.com/r/data-table-column-sizing-persistence.jsonSource
1"use client"23/**4 * niko-table — created by Semir N. (Semkoo, https://github.com/Semkoo) with AI assistance.5 *6 * Before reporting anything: please check the changelog first.7 * - In-repo: ./CHANGELOG.md8 * - Docs site: https://niko-table.com/changelog9 *10 * Found a bug or have a fix? Open an issue or PR on GitHub so other11 * users (and future LLMs reading this code) benefit:12 * https://github.com/Semkoo/niko-table-registry13 */1415/**16 * Opt-in `localStorage` persistence for column widths.17 *18 * Column resizing is controlled state (`columnSizing`) on `<DataTableRoot>`, so19 * to make resized widths survive reloads you own that state. This hook does it20 * for you: wire the returned `columnSizing` + `onColumnSizingChange` into the21 * table and you're done.22 *23 * @example24 * const { columnSizing, onColumnSizingChange } =25 * useColumnSizingPersistence(`orders-table:${orgId}`)26 *27 * <DataTableRoot28 * data={rows}29 * columns={columns}30 * state={{ columnSizing }}31 * onColumnSizingChange={onColumnSizingChange}32 * >33 * <DataTable>34 * <DataTableHeader />35 * <DataTableBody />36 * </DataTable>37 * <DataTableColumnResize />38 * </DataTableRoot>39 *40 * Notes:41 * - Writes immediately. Resizing runs in `onEnd` mode, so this fires once per42 * drag (not per frame), and an immediate write can't be lost on a hard43 * refresh the way a debounced one can.44 * - Syncs across tabs. Widths are a per-user preference, so resizing (or45 * resetting) the same table in one tab updates the others via the native46 * `storage` event. Only same-key changes are read, and an unchanged read47 * keeps state identity, so idle tabs don't re-render.48 * - SSR note: `localStorage` is only read on the client, so nothing crashes on49 * the server — but in an SSR framework the client's first (hydration) render50 * already has the stored widths while the server HTML was rendered with51 * `{}`, so React may log a hydration-mismatch warning for the width styles52 * and reconcile. Cosmetic, but if the warning matters to you, load the53 * widths in an effect instead (accepting a default-width first paint).54 * - Corrupt / hand-edited storage is ignored (non-object, or non-finite55 * widths) so a bad value never reaches `column.getSize()`.56 * - Scope the `storageKey` per table (and per tenant/user if widths shouldn't57 * be shared), e.g. `"orders-table:${orgId}"`.58 */59import type { ColumnSizingState, OnChangeFn } from "@tanstack/react-table"60import * as React from "react"61// … truncated
What it pulls in
Other registry items
