data-table-column-header.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import {
  2. ArrowDownIcon,
  3. ArrowUpIcon,
  4. CaretSortIcon,
  5. EyeNoneIcon,
  6. } from '@radix-ui/react-icons'
  7. import { Column } from '@tanstack/react-table'
  8. import { cn } from '@/lib/utils'
  9. import { Button } from '@/components/ui/button'
  10. import {
  11. DropdownMenu,
  12. DropdownMenuContent,
  13. DropdownMenuItem,
  14. DropdownMenuSeparator,
  15. DropdownMenuTrigger,
  16. } from '@/components/ui/dropdown-menu'
  17. interface DataTableColumnHeaderProps<TData, TValue>
  18. extends React.HTMLAttributes<HTMLDivElement> {
  19. column: Column<TData, TValue>
  20. title: string
  21. }
  22. export function DataTableColumnHeader<TData, TValue>({
  23. column,
  24. title,
  25. className,
  26. }: DataTableColumnHeaderProps<TData, TValue>) {
  27. if (!column.getCanSort()) {
  28. return <div className={cn(className)}>{title}</div>
  29. }
  30. return (
  31. <div className={cn('flex items-center space-x-2', className)}>
  32. <DropdownMenu>
  33. <DropdownMenuTrigger asChild>
  34. <Button
  35. variant='ghost'
  36. size='sm'
  37. className='-ml-3 h-8 data-[state=open]:bg-accent'
  38. >
  39. <span>{title}</span>
  40. {column.getIsSorted() === 'desc' ? (
  41. <ArrowDownIcon className='ml-2 h-4 w-4' />
  42. ) : column.getIsSorted() === 'asc' ? (
  43. <ArrowUpIcon className='ml-2 h-4 w-4' />
  44. ) : (
  45. <CaretSortIcon className='ml-2 h-4 w-4' />
  46. )}
  47. </Button>
  48. </DropdownMenuTrigger>
  49. <DropdownMenuContent align='start'>
  50. <DropdownMenuItem onClick={() => column.toggleSorting(false)}>
  51. <ArrowUpIcon className='mr-2 h-3.5 w-3.5 text-muted-foreground/70' />
  52. Asc
  53. </DropdownMenuItem>
  54. <DropdownMenuItem onClick={() => column.toggleSorting(true)}>
  55. <ArrowDownIcon className='mr-2 h-3.5 w-3.5 text-muted-foreground/70' />
  56. Desc
  57. </DropdownMenuItem>
  58. <DropdownMenuSeparator />
  59. <DropdownMenuItem onClick={() => column.toggleVisibility(false)}>
  60. <EyeNoneIcon className='mr-2 h-3.5 w-3.5 text-muted-foreground/70' />
  61. Hide
  62. </DropdownMenuItem>
  63. </DropdownMenuContent>
  64. </DropdownMenu>
  65. </div>
  66. )
  67. }