DataTableSideBarLayout.tsx52 lines · main
1import { CSSProperties, ReactNode, useMemo } from 'react'
2import { cn } from 'ui'
3
4import { useDataTable } from './providers/DataTableProvider'
5
6interface DataTableSideBarLayoutProps {
7 children: ReactNode
8 className?: string
9 topBarHeight?: number
10}
11
12export 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}