grok2api / frontend /src /shared /components /sortable-table-head.tsx
fromozuzhouzzz
Deploy grok2api v3.0.11 to HF Spaces
f1dd159
Raw
History Blame Contribute Delete
2.09 kB
import { ArrowDown, ArrowUp, ArrowUpDown } from "lucide-react";
import type { ComponentProps, ReactNode } from "react";
import { useTranslation } from "react-i18next";
import { TableHead } from "@/components/ui/table";
import { cn } from "@/shared/lib/cn";
import type { SortOrder } from "@/shared/lib/table-sort";
type SortableTableHeadProps = Omit<ComponentProps<typeof TableHead>, "children" | "onChange"> & {
children: ReactNode;
field: string;
sortBy: string;
sortOrder: SortOrder;
initialOrder?: SortOrder;
align?: "left" | "center" | "right";
onSort: (field: string, initialOrder: SortOrder) => void;
};
export function SortableTableHead({ children, field, sortBy, sortOrder, initialOrder = "asc", align = "left", className, onSort, ...props }: SortableTableHeadProps) {
const { t } = useTranslation();
const active = sortBy === field;
const nextOrder = active && sortOrder === "asc" ? "desc" : active ? "asc" : initialOrder;
const Icon = active ? sortOrder === "asc" ? ArrowUp : ArrowDown : ArrowUpDown;
return (
<TableHead
aria-sort={active ? sortOrder === "asc" ? "ascending" : "descending" : "none"}
className={className}
{...props}
>
<button
type="button"
className={cn(
"group/sort -mx-1 inline-flex h-8 max-w-full items-center gap-1 px-1 text-left transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40",
align === "center" && "w-full justify-center text-center",
align === "right" && "ml-auto flex w-full justify-end text-right",
)}
aria-label={t(nextOrder === "asc" ? "common.sortAscending" : "common.sortDescending", { column: typeof children === "string" ? children : "" })}
onClick={() => onSort(field, initialOrder)}
>
<span className="truncate">{children}</span>
<Icon className={cn("size-3 shrink-0", active ? "text-foreground" : "text-muted-foreground/45 group-hover/sort:text-muted-foreground")} aria-hidden />
</button>
</TableHead>
);
}