All files / src/hooks useSortable.ts

95.83% Statements 23/24
94.73% Branches 18/19
100% Functions 6/6
100% Lines 20/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41                  819x 819x   819x 700x 402x 402x 402x 401x 401x 398x 402x       819x 15x 7x   8x 8x       819x 1x 1x     819x    
import { useState, useMemo } from "react";
 
type SortOrder = "asc" | "desc";
 
export function useSortable<T>(
	data: T[],
	defaultKey: keyof T,
	defaultOrder: SortOrder = "desc",
) {
	const [sortKey, setSortKey] = useState<keyof T>(defaultKey);
	const [sortOrder, setSortOrder] = useState<SortOrder>(defaultOrder);
 
	const sorted = useMemo(() => {
		return [...data].sort((a, b) => {
			const aVal = a[sortKey];
			const bVal = b[sortKey];
			if (aVal == null && bVal == null) return 0;
			Iif (aVal == null) return 1;
			if (bVal == null) return -1;
			const cmp = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
			return sortOrder === "asc" ? cmp : -cmp;
		});
	}, [data, sortKey, sortOrder]);
 
	const toggleSort = (key: keyof T) => {
		if (key === sortKey) {
			setSortOrder((o) => (o === "asc" ? "desc" : "asc"));
		} else {
			setSortKey(key);
			setSortOrder("desc");
		}
	};
 
	const setSort = (key: keyof T, order: SortOrder) => {
		setSortKey(key);
		setSortOrder(order);
	};
 
	return { sorted, sortKey, sortOrder, toggleSort, setSort };
}