toolbar.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { Cross2Icon } from '@radix-ui/react-icons'
  2. import { type Table } from '@tanstack/react-table'
  3. import { Button } from '@/components/ui/button'
  4. import { Input } from '@/components/ui/input'
  5. import { DataTableFacetedFilter } from './faceted-filter'
  6. import { DataTableViewOptions } from './view-options'
  7. type DataTableToolbarProps<TData> = {
  8. table: Table<TData>
  9. searchPlaceholder?: string
  10. searchKey?: string
  11. filters?: {
  12. columnId: string
  13. title: string
  14. options: {
  15. label: string
  16. value: string
  17. icon?: React.ComponentType<{ className?: string }>
  18. }[]
  19. }[]
  20. }
  21. export function DataTableToolbar<TData>({
  22. table,
  23. searchPlaceholder = 'Filter...',
  24. searchKey,
  25. filters = [],
  26. }: DataTableToolbarProps<TData>) {
  27. const isFiltered =
  28. table.getState().columnFilters.length > 0 || table.getState().globalFilter
  29. return (
  30. <div className='flex items-center justify-between'>
  31. <div className='flex flex-1 flex-col-reverse items-start gap-y-2 sm:flex-row sm:items-center sm:space-x-2'>
  32. {searchKey ? (
  33. <Input
  34. placeholder={searchPlaceholder}
  35. value={
  36. (table.getColumn(searchKey)?.getFilterValue() as string) ?? ''
  37. }
  38. onChange={(event) =>
  39. table.getColumn(searchKey)?.setFilterValue(event.target.value)
  40. }
  41. className='h-8 w-[150px] lg:w-[250px]'
  42. />
  43. ) : (
  44. <Input
  45. placeholder={searchPlaceholder}
  46. value={table.getState().globalFilter ?? ''}
  47. onChange={(event) => table.setGlobalFilter(event.target.value)}
  48. className='h-8 w-[150px] lg:w-[250px]'
  49. />
  50. )}
  51. <div className='flex gap-x-2'>
  52. {filters.map((filter) => {
  53. const column = table.getColumn(filter.columnId)
  54. if (!column) return null
  55. return (
  56. <DataTableFacetedFilter
  57. key={filter.columnId}
  58. column={column}
  59. title={filter.title}
  60. options={filter.options}
  61. />
  62. )
  63. })}
  64. </div>
  65. {isFiltered && (
  66. <Button
  67. variant='ghost'
  68. onClick={() => {
  69. table.resetColumnFilters()
  70. table.setGlobalFilter('')
  71. }}
  72. className='h-8 px-2 lg:px-3'
  73. >
  74. Reset
  75. <Cross2Icon className='ms-2 h-4 w-4' />
  76. </Button>
  77. )}
  78. </div>
  79. <DataTableViewOptions table={table} />
  80. </div>
  81. )
  82. }