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
15 changes: 15 additions & 0 deletions src/components/HighTable/HighTable.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -468,5 +468,20 @@ export const FilteredData: Story = {
args: {
data: sortableDataFrame(createFilteredData()),
maxRowNumber: 10_000 * 1_000,

},
}
export const HiddenColumns: Story = {
args: {
data: sortableDataFrame(createUnsortableData()),
columnConfiguration: {
Value1: {
initiallyHidden: true,
},
Value3: {
initiallyHidden: true,
},
},
cacheKey: 'hidden-columns-demo',
},
}
10 changes: 9 additions & 1 deletion src/components/HighTable/HighTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,21 @@ function HighTableData(props: PropsData) {
// TODO(SL): onError could be in a context, as we might want to use it everywhere
const { cacheKey, orderBy, onOrderByChange, selection, onSelectionChange, onError, onColumnsVisibilityChange } = props

const initialVisibilityStates = useMemo(() => {
if (!props.columnConfiguration) return undefined
return data.columnDescriptors.map(descriptor => {
const config = props.columnConfiguration?.[descriptor.name]
return config?.initiallyHidden ? { hidden: true as const } : undefined
})
}, [props.columnConfiguration, data.columnDescriptors])

return (
/* Provide the column configuration to the table */
<ColumnParametersProvider columnConfiguration={props.columnConfiguration} data={data}>
{/* Create a new set of widths if the data has changed, but keep it if only the number of rows changed */}
<ColumnWidthsProvider key={cacheKey ?? key} localStorageKey={cacheKey ? `${cacheKey}${columnWidthsSuffix}` : undefined} numColumns={data.columnDescriptors.length}>
{/* Create a new set of hidden columns if the data has changed, but keep it if only the number of rows changed */}
<ColumnVisibilityStatesProvider key={cacheKey ?? key} localStorageKey={cacheKey ? `${cacheKey}${columnVisibilityStatesSuffix}` : undefined} numColumns={data.columnDescriptors.length} onColumnsVisibilityChange={onColumnsVisibilityChange}>
<ColumnVisibilityStatesProvider key={cacheKey ?? key} localStorageKey={cacheKey ? `${cacheKey}${columnVisibilityStatesSuffix}` : undefined} numColumns={data.columnDescriptors.length} initialVisibilityStates={initialVisibilityStates} onColumnsVisibilityChange={onColumnsVisibilityChange}>
{/* Create a new context if the dataframe changes, to flush the cache (ranks and indexes) */}
<OrderByProvider key={key} orderBy={orderBy} onOrderByChange={onOrderByChange}>
{/* Create a new selection context if the dataframe has changed */}
Expand Down
1 change: 1 addition & 0 deletions src/helpers/columnConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react'
export interface ColumnConfig {
headerComponent?: React.ReactNode;
minWidth?: number;
initiallyHidden?: boolean;
// hideable?: boolean;
// filters: Some filter structure
// cellRenderer?: (value: unknown, row: Row) => React.ReactNode;
Expand Down
21 changes: 13 additions & 8 deletions src/hooks/useColumnVisibilityStates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const ColumnVisibilityStatesContext = createContext<ColumnVisibilityState
interface ColumnVisibilityStatesProviderProps {
localStorageKey?: string // optional key to use for local storage (no local storage if not provided)
numColumns: number // number of columns (used to initialize the visibility states array)
initialVisibilityStates?: MaybeHiddenColumn[] // initial visibility states for columns (used only if no local storage value exists)
onColumnsVisibilityChange?: (columns: MaybeHiddenColumn[]) => void // callback which is called whenever the set of hidden columns changes.
children: ReactNode
}
Expand All @@ -21,7 +22,7 @@ export interface HiddenColumn {
}
export type MaybeHiddenColumn = HiddenColumn | undefined

export function ColumnVisibilityStatesProvider({ children, localStorageKey, numColumns, onColumnsVisibilityChange }: ColumnVisibilityStatesProviderProps) {
export function ColumnVisibilityStatesProvider({ children, localStorageKey, numColumns, initialVisibilityStates, onColumnsVisibilityChange }: ColumnVisibilityStatesProviderProps) {
if (!Number.isInteger(numColumns) || numColumns < 0) {
throw new Error(`Invalid numColumns: ${numColumns}. It must be a positive integer.`)
}
Expand Down Expand Up @@ -50,13 +51,16 @@ export function ColumnVisibilityStatesProvider({ children, localStorageKey, numC
})
}

// Apply initial visibility states if no persisted state exists
const effectiveColumnVisibilityStates = columnVisibilityStates ?? initialVisibilityStates

const isValidIndex = useCallback((index: number) => {
return Number.isInteger(index) && index >= 0 && index < numColumns
}, [numColumns])

const isHiddenColumn = useCallback((columnIndex: number) => {
return columnVisibilityStates?.[columnIndex]?.hidden === true
}, [columnVisibilityStates])
return effectiveColumnVisibilityStates?.[columnIndex]?.hidden === true
}, [effectiveColumnVisibilityStates])

const { numberOfHiddenColumns, numberOfVisibleColumns } = useMemo(() => {
let numberOfHiddenColumns = 0
Expand All @@ -77,22 +81,23 @@ export function ColumnVisibilityStatesProvider({ children, localStorageKey, numC
return undefined
}
return () => {
setColumnVisibilityStates(columnVisibilityStates => {
const nextColumnVisibilityStates = [...columnVisibilityStates ?? []]
setColumnVisibilityStates(currentStates => {
const nextColumnVisibilityStates = [...currentStates ?? initialVisibilityStates ?? []]
nextColumnVisibilityStates[columnIndex] = { hidden: true }
onColumnsVisibilityChange?.(nextColumnVisibilityStates)
return nextColumnVisibilityStates
})
}
}, [canBeHidden, isValidIndex, setColumnVisibilityStates, onColumnsVisibilityChange])
}, [canBeHidden, isValidIndex, setColumnVisibilityStates, onColumnsVisibilityChange, initialVisibilityStates])

const showAllColumns = useMemo(() => {
if (numberOfHiddenColumns === 0) {
return undefined
}
return () => {
setColumnVisibilityStates(undefined)
onColumnsVisibilityChange?.([])
const allVisible: MaybeHiddenColumn[] = []
setColumnVisibilityStates(allVisible)
onColumnsVisibilityChange?.(allVisible)
}
}, [numberOfHiddenColumns, setColumnVisibilityStates, onColumnsVisibilityChange])

Expand Down