Files
CapaKraken/apps/web/src/components/ui/SortableColumnHeader.tsx
T

74 lines
2.0 KiB
TypeScript

import { InfoTooltip } from "./InfoTooltip.js";
interface SortIconProps {
dir: "asc" | "desc" | null;
}
function SortIcon({ dir }: SortIconProps) {
return (
<span className="inline-flex flex-col leading-none ml-0.5">
<svg width="8" height="12" viewBox="0 0 8 12" fill="none" aria-hidden>
{/* Up chevron */}
<path
d="M1 5L4 2L7 5"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
className={dir === "asc" ? "stroke-brand-600" : "stroke-gray-300"}
/>
{/* Down chevron */}
<path
d="M1 7L4 10L7 7"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
className={dir === "desc" ? "stroke-brand-600" : "stroke-gray-300"}
/>
</svg>
</span>
);
}
interface SortableColumnHeaderProps {
label: string;
field: string;
sortField: string | null;
sortDir: "asc" | "desc" | null;
onSort: (field: string) => void;
className?: string;
align?: "left" | "right" | "center";
tooltip?: string;
tooltipWidth?: string;
}
export function SortableColumnHeader({
label,
field,
sortField,
sortDir,
onSort,
className = "",
align = "left",
tooltip,
tooltipWidth,
}: SortableColumnHeaderProps) {
const activeDir = sortField === field ? sortDir : null;
const alignClass = align === "right" ? "justify-end" : align === "center" ? "justify-center" : "justify-start";
return (
<th className={`px-3 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider ${className}`}>
<div className={`flex items-center gap-0.5 ${alignClass}`}>
<button
type="button"
onClick={() => onSort(field)}
className="flex items-center gap-0.5 hover:text-gray-700 transition-colors group"
>
<span>{label}</span>
<SortIcon dir={activeDir} />
</button>
{tooltip && <InfoTooltip content={tooltip} {...(tooltipWidth !== undefined ? { width: tooltipWidth } : {})} />}
</div>
</th>
);
}