DataTableToolbar.tsx 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { PanelLeftClose, PanelLeftOpen } from 'lucide-react'
  2. import { ReactNode, useMemo } from 'react'
  3. import { Button, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
  4. import { formatCompactNumber } from './DataTable.utils'
  5. import { DataTableFilterControlsDrawer } from './DataTableFilters/DataTableFilterControlsDrawer'
  6. import { DataTableResetButton } from './DataTableResetButton'
  7. import { DataTableViewOptions } from './DataTableViewOptions'
  8. import { Kbd } from './primitives/Kbd'
  9. import { useDataTable } from './providers/DataTableProvider'
  10. import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
  11. import { useShortcut } from '@/state/shortcuts/useShortcut'
  12. interface DataTableToolbarProps {
  13. renderActions?: () => ReactNode
  14. isFilterBarOpen: boolean
  15. setIsFilterBarOpen: React.Dispatch<React.SetStateAction<boolean>>
  16. }
  17. export function DataTableToolbar({
  18. renderActions,
  19. isFilterBarOpen,
  20. setIsFilterBarOpen,
  21. }: DataTableToolbarProps) {
  22. const { table, isLoading, columnFilters } = useDataTable()
  23. const filters = table.getState().columnFilters
  24. useShortcut(SHORTCUT_IDS.DATA_TABLE_TOGGLE_FILTERS, () => setIsFilterBarOpen((prev) => !prev))
  25. const rows = useMemo(
  26. () => ({
  27. total: table.getCoreRowModel().rows.length,
  28. filtered: table.getFilteredRowModel().rows.length,
  29. }),
  30. [isLoading, columnFilters]
  31. )
  32. return (
  33. <div className="flex flex-wrap items-center justify-between gap-4">
  34. <div className="flex flex-wrap items-center gap-2">
  35. <Tooltip>
  36. <TooltipTrigger asChild>
  37. <Button
  38. size="tiny"
  39. type="default"
  40. icon={isFilterBarOpen ? <PanelLeftClose /> : <PanelLeftOpen />}
  41. onClick={() => setIsFilterBarOpen((prev) => !prev)}
  42. className="hidden sm:flex"
  43. >
  44. <span className="hidden md:block">{isFilterBarOpen ? 'Hide' : 'Show'} Controls</span>
  45. </Button>
  46. </TooltipTrigger>
  47. <TooltipContent side="right">
  48. <p>
  49. Toggle controls with{' '}
  50. <Kbd className="ml-1 text-muted-foreground group-hover:text-accent-foreground">
  51. <span className="mr-1">⌘</span>
  52. <span>B</span>
  53. </Kbd>
  54. </p>
  55. </TooltipContent>
  56. </Tooltip>
  57. <div className="block sm:hidden">
  58. <DataTableFilterControlsDrawer />
  59. </div>
  60. <div>
  61. <p className="hidden text-sm text-muted-foreground sm:block">
  62. <span className="font-mono font-medium">{formatCompactNumber(rows.filtered)}</span> of{' '}
  63. <span className="font-mono font-medium">{formatCompactNumber(rows.total)}</span> row(s){' '}
  64. <span className="sr-only sm:not-sr-only">filtered</span>
  65. </p>
  66. <p className="block text-sm text-muted-foreground sm:hidden">
  67. <span className="font-mono font-medium">{formatCompactNumber(rows.filtered)}</span>{' '}
  68. row(s)
  69. </p>
  70. </div>
  71. </div>
  72. <div className="ml-auto flex items-center gap-2">
  73. {filters.length ? <DataTableResetButton /> : null}
  74. {renderActions?.()}
  75. <DataTableViewOptions />
  76. </div>
  77. </div>
  78. )
  79. }