DataTableSideBarLayout.tsx52 lines · main
| 1 | import { CSSProperties, ReactNode, useMemo } from 'react' |
| 2 | import { cn } from 'ui' |
| 3 | |
| 4 | import { useDataTable } from './providers/DataTableProvider' |
| 5 | |
| 6 | interface DataTableSideBarLayoutProps { |
| 7 | children: ReactNode |
| 8 | className?: string |
| 9 | topBarHeight?: number |
| 10 | } |
| 11 | |
| 12 | export function DataTableSideBarLayout({ |
| 13 | children, |
| 14 | className, |
| 15 | topBarHeight = 0, |
| 16 | }: DataTableSideBarLayoutProps) { |
| 17 | const { table } = useDataTable() |
| 18 | |
| 19 | /** |
| 20 | * https://tanstack.com/table/v8/docs/guide/column-sizing#advanced-column-resizing-performance |
| 21 | * Instead of calling `column.getSize()` on every render for every header |
| 22 | * and especially every data cell (very expensive), |
| 23 | * we will calculate all column sizes at once at the root table level in a useMemo |
| 24 | * and pass the column sizes down as CSS variables to the <table> element. |
| 25 | */ |
| 26 | const columnSizeVars = useMemo(() => { |
| 27 | const headers = table.getFlatHeaders() |
| 28 | const colSizes: { [key: string]: string } = {} |
| 29 | for (let i = 0; i < headers.length; i++) { |
| 30 | const header = headers[i]! |
| 31 | // REMINDER: replace "." with "-" to avoid invalid CSS variable name (e.g. "timing.dns" -> "timing-dns") |
| 32 | colSizes[`--header-${header.id.replace('.', '-')}-size`] = `${header.getSize()}px` |
| 33 | colSizes[`--col-${header.column.id.replace('.', '-')}-size`] = `${header.column.getSize()}px` |
| 34 | } |
| 35 | return colSizes |
| 36 | }, [ |
| 37 | // TODO: check if we need this |
| 38 | table.getState().columnSizingInfo, |
| 39 | table.getState().columnSizing, |
| 40 | table.getState().columnVisibility, |
| 41 | ]) |
| 42 | |
| 43 | return ( |
| 44 | <div |
| 45 | className={cn('flex flex-row w-full h-full', className)} |
| 46 | // topBarHeight is the height of the chart and search bar, and 64px is the height of the top bar |
| 47 | style={{ '--top-bar-height': `${topBarHeight + 64}px`, ...columnSizeVars } as CSSProperties} |
| 48 | > |
| 49 | {children} |
| 50 | </div> |
| 51 | ) |
| 52 | } |