diff --git a/packages/features/data-table/components/DataTableWrapper.tsx b/packages/features/data-table/components/DataTableWrapper.tsx index 7ad35f9413..8cad1618ce 100644 --- a/packages/features/data-table/components/DataTableWrapper.tsx +++ b/packages/features/data-table/components/DataTableWrapper.tsx @@ -54,7 +54,7 @@ export function DataTableWrapper({ fetchNextPage, isFetching, }); - const { sorting, setSorting } = useDataTable(); + const { sorting, setSorting, columnVisibility, setColumnVisibility } = useDataTable(); const columnFilters = useColumnFilters(); useEffect(() => { @@ -62,12 +62,14 @@ export function DataTableWrapper({ ...prev, sorting, columnFilters, + columnVisibility, })); table.setOptions((prev) => ({ ...prev, onSortingChange: setSorting, + onColumnVisibilityChange: setColumnVisibility, })); - }, [table, sorting, columnFilters]); + }, [table, sorting, columnFilters, columnVisibility]); return ( ; + + columnVisibility: VisibilityState; + setColumnVisibility: OnChangeFn; }; export const DataTableContext = createContext(null); @@ -36,6 +39,10 @@ export function DataTableProvider({ children }: { children: React.ReactNode }) { "sorting", parseAsArrayOf(parseAsJson(ZSorting.parse)).withDefault([]) ); + const [columnVisibility, setColumnVisibility] = useQueryState( + "cols", + parseAsJson(ZColumnVisibility.parse).withDefault({}) + ); const clearAll = useCallback( (exclude?: string[]) => { @@ -81,6 +88,8 @@ export function DataTableProvider({ children }: { children: React.ReactNode }) { removeFilter, sorting, setSorting, + columnVisibility, + setColumnVisibility, }}> {children} diff --git a/packages/features/data-table/lib/resizing.ts b/packages/features/data-table/lib/resizing.ts index 212803e218..82c9869bd1 100644 --- a/packages/features/data-table/lib/resizing.ts +++ b/packages/features/data-table/lib/resizing.ts @@ -49,8 +49,13 @@ function getAdjustedColumnSizing({ return currentColumnSizing; } - const getColumnSize = (id: string) => - resizedColumns.has(id) ? currentColumnSizing[id] : initialColumnSizing[id]; + const getColumnSize = (header: Header) => { + const id = header.id; + if (resizedColumns.has(id)) { + return currentColumnSizing[id] ?? initialColumnSizing[id] ?? header.getSize(); + } + return initialColumnSizing[id] ?? header.getSize(); + }; const isAdjustable = (header: Header) => header.column.columnDef.enableResizing !== false && !resizedColumns.has(header.id); @@ -59,7 +64,7 @@ function getAdjustedColumnSizing({ const numberOfAdjustableColumns = headers.filter(isAdjustable).length; // Calculate widths and required adjustments - const totalColumnsWidth = headers.reduce((total, header) => total + getColumnSize(header.id), 0); + const totalColumnsWidth = headers.reduce((total, header) => total + getColumnSize(header), 0); const widthToFill = Math.max(0, containerWidth - totalColumnsWidth); const widthPerAdjustableColumn = numberOfAdjustableColumns === 0 ? 0 : Math.floor(widthToFill / numberOfAdjustableColumns); @@ -69,7 +74,7 @@ function getAdjustedColumnSizing({ // Build the new column sizing object const newColumnSizing = headers.reduce((acc, header, index) => { - const baseWidth = getColumnSize(header.id); + const baseWidth = getColumnSize(header); const adjustmentWidth = isAdjustable(header) ? widthPerAdjustableColumn : 0; const isLastColumn = index === headers.length - 1; const extraWidth = isLastColumn ? leftoverWidth : 0; diff --git a/packages/features/data-table/lib/types.ts b/packages/features/data-table/lib/types.ts index 792d31a547..110375c157 100644 --- a/packages/features/data-table/lib/types.ts +++ b/packages/features/data-table/lib/types.ts @@ -146,3 +146,5 @@ export const ZSorting = z.object({ }); export type SortingState = Array>; + +export const ZColumnVisibility = z.record(z.string(), z.boolean());