49 lines
1.2 KiB
Svelte
49 lines
1.2 KiB
Svelte
<script lang="ts">
|
|
import { setContext, type Snippet } from 'svelte';
|
|
import { type Writable, writable } from 'svelte/store';
|
|
import { getObjectEntryByKey } from '@util/objects.ts';
|
|
|
|
// types
|
|
interface Props {
|
|
data: Writable<{ [key: string]: any }[]>;
|
|
|
|
children: Snippet;
|
|
}
|
|
|
|
// inputs
|
|
const { data, children, ...restProps }: Props & Record<string, any> = $props();
|
|
|
|
setContext('sortableHeader', {
|
|
headerKey: writable(null),
|
|
onSort: onSort
|
|
});
|
|
|
|
// functions
|
|
function onSort(key: string, order: 'asc' | 'desc') {
|
|
data.update((old) => {
|
|
old.sort((a, b) => {
|
|
let entryA = getObjectEntryByKey(key, a);
|
|
let entryB = getObjectEntryByKey(key, b);
|
|
|
|
if (entryA === undefined || entryB === undefined) return 0;
|
|
|
|
if (typeof entryA === 'string') entryA = entryA.toLowerCase();
|
|
if (typeof entryB === 'string') entryB = entryB.toLowerCase();
|
|
|
|
if (order === 'asc') {
|
|
return entryA < entryB ? -1 : 1;
|
|
} else if (order === 'desc') {
|
|
return entryA > entryB ? -1 : 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
});
|
|
return old;
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<tr {...restProps}>
|
|
{@render children()}
|
|
</tr>
|