import { ArrowDown, ArrowDownUp, ArrowUp } from 'lucide-react'; export type SortDirection = 'asc' | 'desc'; export function SortableColumnHeader({ label, sortKey, activeSortKey, sortDirection, onSort, align = 'left', className = '', }: { label: string; sortKey: Key; activeSortKey: Key; sortDirection: SortDirection; onSort: (sortKey: Key) => void; align?: 'left' | 'right' | 'center'; className?: string; }) { const active = activeSortKey === sortKey; const Icon = active ? (sortDirection === 'asc' ? ArrowUp : ArrowDown) : ArrowDownUp; const order = active ? (sortDirection === 'asc' ? '升序' : '降序') : '未排序'; const justify = align === 'right' ? 'justify-end' : align === 'center' ? 'justify-center' : 'justify-start'; return ( ); } export function toggleSort( currentKey: Key, currentDirection: SortDirection, nextKey: Key, ): { key: Key; direction: SortDirection } { return nextKey === currentKey ? { key: currentKey, direction: currentDirection === 'asc' ? 'desc' : 'asc' } : { key: nextKey, direction: 'desc' }; } export function sortBy( rows: Row[], sortKey: Key, sortDirection: SortDirection, valueOf: (row: Row, key: Key) => string | number | null | undefined, ): Row[] { const multiplier = sortDirection === 'asc' ? 1 : -1; // Keep the caller's row order immutable while remaining compatible with the // ES2022 target used by this dashboard (Array.prototype.toSorted is ES2023). return [...rows].sort((left, right) => { const leftValue = valueOf(left, sortKey) ?? ''; const rightValue = valueOf(right, sortKey) ?? ''; if (typeof leftValue === 'number' && typeof rightValue === 'number') return (leftValue - rightValue) * multiplier; return String(leftValue).localeCompare(String(rightValue), 'zh-CN', { numeric: true }) * multiplier; }); }