| 1 | import ArrowDown from "lucide-solid/icons/arrow-down"; |
| 2 | import ArrowUp from "lucide-solid/icons/arrow-up"; |
| 3 | import { Show } from "solid-js"; |
| 4 | |
| 5 | export interface Sort<K extends string> { |
| 6 | key: K; |
| 7 | desc: boolean; |
| 8 | } |
| 9 | |
| 10 | /** A sortable column head; `num` columns right-align and sort largest first on the first click. */ |
| 11 | export function SortHeader<K extends string>(props: { |
| 12 | column: K; |
| 13 | label: string; |
| 14 | sort: Sort<K>; |
| 15 | onSort: (sort: Sort<K>) => void; |
| 16 | num?: boolean; |
| 17 | class?: string; |
| 18 | }) { |
| 19 | const active = () => props.sort.key === props.column; |
| 20 | return ( |
| 21 | <th class={props.class} classList={{ num: props.num }} |
| 22 | aria-sort={active() ? (props.sort.desc ? "descending" : "ascending") : undefined}> |
| 23 | <button class="sort" onClick={() => props.onSort({ key: props.column, desc: active() ? !props.sort.desc : !!props.num })}> |
| 24 | {props.label} |
| 25 | <Show when={active()}>{props.sort.desc ? <ArrowDown size={12} /> : <ArrowUp size={12} />}</Show> |
| 26 | </button> |
| 27 | </th> |
| 28 | ); |
| 29 | } |