Presupuestador_web/client/src/components/DataTable/DataTableColumnHeader.tsx

138 lines
4.6 KiB
TypeScript
Raw Normal View History

2024-06-11 16:48:09 +00:00
import { Header, Table, flexRender } from "@tanstack/react-table";
import { cn } from "@/lib/utils";
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
Separator,
} from "@/ui";
2024-06-13 11:09:26 +00:00
import { t } from "i18next";
import { ArrowDownIcon, ArrowDownUpIcon, ArrowUpIcon, EyeOffIcon } from "lucide-react";
2024-06-11 16:48:09 +00:00
2024-06-13 11:09:26 +00:00
interface DataTableColumnHeaderProps<TData, TValue> extends React.HTMLAttributes<HTMLDivElement> {
2024-06-11 16:48:09 +00:00
table: Table<TData>;
header: Header<TData, TValue>;
}
export function DataTableColumnHeader<TData, TValue>({
table,
header,
className,
}: DataTableColumnHeaderProps<TData, TValue>) {
if (!header.column.getCanSort()) {
return (
<>
<div className={cn("data-[state=open]:bg-accent tracking-wide text-ellipsis", className)}>
2024-06-11 16:48:09 +00:00
{header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())}
</div>
2024-06-13 11:09:26 +00:00
2024-08-25 20:06:24 +00:00
{false && header.column.getCanResize() && (
2024-06-11 16:48:09 +00:00
<Separator
2024-06-13 11:09:26 +00:00
orientation='vertical'
2024-06-11 16:48:09 +00:00
className={cn(
"absolute top-0 h-full w-[5px] bg-black/10 cursor-col-resize",
table.options.columnResizeDirection,
2024-06-13 11:09:26 +00:00
header.column.getIsResizing() ? "bg-primary opacity-100" : ""
2024-06-11 16:48:09 +00:00
)}
{...{
onDoubleClick: () => header.column.resetSize(),
onMouseDown: header.getResizeHandler(),
onTouchStart: header.getResizeHandler(),
style: {
transform:
2024-06-13 11:09:26 +00:00
table.options.columnResizeMode === "onEnd" && header.column.getIsResizing()
2024-06-11 16:48:09 +00:00
? `translateX(${
2024-06-13 11:09:26 +00:00
(table.options.columnResizeDirection === "rtl" ? -1 : 1) *
2024-06-11 16:48:09 +00:00
(table.getState().columnSizingInfo.deltaOffset ?? 0)
}px)`
: "",
},
}}
/>
)}
</>
);
}
return (
<div className={cn("flex items-center space-x-2", className)}>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
aria-label={
header.column.getIsSorted() === "desc"
2024-06-13 11:09:26 +00:00
? t("common.sort_desc_description")
2024-06-11 16:48:09 +00:00
: header.column.getIsSorted() === "asc"
2024-06-13 11:09:26 +00:00
? t("common.sort_asc_description")
: t("sort_none_description")
2024-06-11 16:48:09 +00:00
}
2024-06-13 11:09:26 +00:00
size='sm'
variant='ghost'
className='-ml-3 h-8 data-[state=open]:bg-accent font-bold text-muted-foreground'
2024-06-11 16:48:09 +00:00
>
{flexRender(header.column.columnDef.header, header.getContext())}
2024-06-13 11:09:26 +00:00
2024-06-11 16:48:09 +00:00
{header.column.getIsSorted() === "desc" ? (
2024-06-13 11:09:26 +00:00
<ArrowDownIcon className='w-4 h-4 ml-2' aria-hidden='true' />
2024-06-11 16:48:09 +00:00
) : header.column.getIsSorted() === "asc" ? (
2024-06-13 11:09:26 +00:00
<ArrowUpIcon className='w-4 h-4 ml-2' aria-hidden='true' />
2024-06-11 16:48:09 +00:00
) : (
2024-06-13 11:09:26 +00:00
<ArrowDownUpIcon
className='w-4 h-4 ml-2 text-muted-foreground/30'
aria-hidden='true'
/>
2024-06-11 16:48:09 +00:00
)}
</Button>
</DropdownMenuTrigger>
2024-06-13 11:09:26 +00:00
<DropdownMenuContent align='start'>
{header.column.getCanSort() && (
<>
<DropdownMenuItem
onClick={() => header.column.toggleSorting(false)}
aria-label={t("common.sort_asc")}
>
<ArrowUpIcon
className='mr-2 h-3.5 w-3.5 text-muted-foreground/70'
aria-hidden='true'
/>
{t("common.sort_asc")}
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => header.column.toggleSorting(true)}
aria-label={t("common.sort_desc")}
>
<ArrowDownIcon
className='mr-2 h-3.5 w-3.5 text-muted-foreground/70'
aria-hidden='true'
/>
{t("common.sort_desc")}
</DropdownMenuItem>
</>
)}
{header.column.getCanSort() && header.column.getCanHide() && <DropdownMenuSeparator />}
2024-06-11 16:48:09 +00:00
{header.column.getCanHide() && (
<DropdownMenuItem
onClick={() => header.column.toggleVisibility(false)}
2024-06-13 11:09:26 +00:00
aria-label={t("Hide")}
2024-06-11 16:48:09 +00:00
>
2024-06-13 11:09:26 +00:00
<EyeOffIcon
className='mr-2 h-3.5 w-3.5 text-muted-foreground/70'
aria-hidden='true'
/>
{t("Hide")}
2024-06-11 16:48:09 +00:00
</DropdownMenuItem>
)}
</DropdownMenuContent>
</DropdownMenu>
</div>
);
}