| 1 |
import { computed, type Ref } from 'vue' |
| 2 |
|
| 3 |
export interface SelectableRow { |
| 4 |
id: number | string |
| 5 |
selected?: boolean |
| 6 |
[key: string]: unknown |
| 7 |
} |
| 8 |
|
| 9 |
export function useTableSelection<TRow extends SelectableRow>(rows: Ref<TRow[]>) { |
| 10 |
const toggle = (id: TRow['id']) => { |
| 11 |
const row = rows.value.find((r) => r.id === id) |
| 12 |
if (row) row.selected = !row.selected |
| 13 |
} |
| 14 |
|
| 15 |
const toggleAll = () => { |
| 16 |
const anyUnselected = rows.value.some((r) => !r.selected) |
| 17 |
rows.value.forEach((r) => { |
| 18 |
r.selected = anyUnselected |
| 19 |
}) |
| 20 |
} |
| 21 |
|
| 22 |
const clear = () => { |
| 23 |
rows.value.forEach((r) => { |
| 24 |
r.selected = false |
| 25 |
}) |
| 26 |
} |
| 27 |
|
| 28 |
const selectedIds = computed(() => rows.value.filter((r) => r.selected).map((r) => r.id)) |
| 29 |
const anyRowSelected = computed(() => selectedIds.value.length > 0) |
| 30 |
const allSelected = computed(() => rows.value.length > 0 && rows.value.every((r) => r.selected)) |
| 31 |
const someSelected = computed(() => anyRowSelected.value && !allSelected.value) |
| 32 |
|
| 33 |
return { |
| 34 |
toggle, |
| 35 |
toggleAll, |
| 36 |
clear, |
| 37 |
selectedIds, |
| 38 |
anyRowSelected, |
| 39 |
allSelected, |
| 40 |
someSelected, |
| 41 |
} |
| 42 |
} |
| 43 |
|