Spaces:
Running
Running
| <script lang="ts"> | |
| import { Button } from '$lib/components/ui/button'; | |
| import { cn } from '$lib/utils'; | |
| import CaretUpIcon from 'phosphor-svelte/lib/CaretUpIcon'; | |
| import CaretDownIcon from 'phosphor-svelte/lib/CaretDownIcon'; | |
| import CaretUpDownIcon from 'phosphor-svelte/lib/CaretUpDownIcon'; | |
| // `column` comes from the TanStack header context. Its `TData/TValue` generics | |
| // vary across columns, so we type it permissively here and only touch the | |
| // methods we actually use. | |
| interface SortableColumn { | |
| getIsSorted(): false | 'asc' | 'desc'; | |
| toggleSorting(desc?: boolean): void; | |
| } | |
| interface Props { | |
| column: SortableColumn; | |
| label: string; | |
| align?: 'start' | 'end'; | |
| class?: string; | |
| } | |
| let { column, label, align = 'start', class: className }: Props = $props(); | |
| const sort = $derived(column.getIsSorted()); | |
| </script> | |
| <Button | |
| variant="ghost" | |
| size="sm" | |
| onclick={() => column.toggleSorting(sort === 'asc')} | |
| class={cn( | |
| '-ml-2 h-7 px-2 text-[0.7rem] font-medium tracking-wide text-muted-foreground uppercase hover:text-foreground', | |
| align === 'end' && '-mr-2 ml-0 w-full justify-end', | |
| className | |
| )} | |
| > | |
| {label} | |
| {#if sort === 'asc'} | |
| <CaretUpIcon size={12} weight="bold" class="ml-1" /> | |
| {:else if sort === 'desc'} | |
| <CaretDownIcon size={12} weight="bold" class="ml-1" /> | |
| {:else} | |
| <CaretUpDownIcon size={12} weight="bold" class="ml-1 opacity-60" /> | |
| {/if} | |
| </Button> | |