import { computed, ref, watch, type Ref } from 'vue' export type SortOrder = 'asc' | 'desc' export function nextSortState( currentField: string | null, currentOrder: SortOrder | null, prop: string, order: SortOrder ): { sortField: string | null; sortOrder: SortOrder | null } { if (currentField === prop && currentOrder === order) { return { sortField: null, sortOrder: null } } return { sortField: prop, sortOrder: order } } export function useColumnSort(options?: { onChange?: () => void }) { const sortField = ref(null) const sortOrder = ref(null) const hasActiveSort = computed(() => Boolean(sortField.value && sortOrder.value)) function setSort(prop: string, order: SortOrder) { const next = nextSortState(sortField.value, sortOrder.value, prop, order) sortField.value = next.sortField sortOrder.value = next.sortOrder options?.onChange?.() } function clearSort() { if (!sortField.value && !sortOrder.value) return sortField.value = null sortOrder.value = null options?.onChange?.() } function isSortActive(prop: string, order?: SortOrder) { if (!sortField.value || sortField.value !== prop) return false if (order == null) return true return sortOrder.value === order } function toQueryParams(): Record { if (!sortField.value || !sortOrder.value) return {} return { sortField: sortField.value, sortOrder: sortOrder.value } } function onColumnHidden(prop: string) { if (sortField.value === prop) clearSort() } function watchVisibleColumns(visibleProps: Ref) { watch( visibleProps, (next, prev) => { if (!prev) return const nextSet = new Set(next || []) for (const p of prev) { if (!nextSet.has(p)) onColumnHidden(p) } }, { deep: true } ) } return { sortField, sortOrder, hasActiveSort, setSort, clearSort, isSortActive, toQueryParams, onColumnHidden, watchVisibleColumns } }