store/resources/js/components/data-table/DataTableColumnHeader.vue

49 lines
1.4 KiB
Vue

<script setup lang="ts">
import { ArrowDown, ArrowUp, ChevronsUpDown } from '@lucide/vue';
import { inject } from 'vue';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import type { DataTableSort } from '@/types/data-table';
const props = withDefaults(
defineProps<{
title: string;
column: string;
class?: string;
}>(),
{},
);
type DataTableSortContext = {
sort: () => DataTableSort | null | undefined;
onSort: (column: string) => void;
};
const sortContext = inject<DataTableSortContext>('data-table-sort');
function isSorted(): boolean {
return sortContext?.sort()?.column === props.column;
}
function sortDirection(): 'asc' | 'desc' | null {
if (!isSorted()) {
return null;
}
return sortContext?.sort()?.direction ?? null;
}
</script>
<template>
<div :class="cn('flex items-center gap-2', props.class)">
<Button variant="ghost" size="sm"
:class="cn('-ml-3 h-8 data-[state=open]:bg-accent', props.class?.includes('justify-end') && 'ml-auto')"
@click="sortContext?.onSort(column)">
<span>{{ title }}</span>
<ArrowDown v-if="sortDirection() === 'desc'" class="size-4" />
<ArrowUp v-else-if="sortDirection() === 'asc'" class="size-4" />
<ChevronsUpDown v-else class="size-4" />
</Button>
</div>
</template>