DataTableSideBarLayout.tsx 1.8 KB

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