PluginProbe
The Innovative Form Builder – IvyForms / 1.1.1
The Innovative Form Builder – IvyForms v1.1.1
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / views / _components / table / composables / useTableHover.ts

useTableHover.ts in The Innovative Form Builder – IvyForms 1.1.1, at frontend/src/views/_components/table/composables/useTableHover.ts

77 lines 2.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { nextTick, onBeforeUnmount, ref, type Ref } from 'vue'
2
3 export interface UseTableHoverOptions {
4 tableSelector?: string
5 }
6
7 const ROW_SELECTOR = '.el-table-v2__row'
8
9 export function useTableHover<TId extends number | string = number>(
10 options: UseTableHoverOptions = {},
11 ) {
12 const { tableSelector = '.ivyforms-table' } = options
13 const hoveredRowId: Ref<TId | null> = ref(null)
14 let controller: AbortController | null = null
15
16 const setHoveredRow = (table: Element, rowKey: string | null) => {
17 table.querySelectorAll(`${ROW_SELECTOR}.hovered`).forEach((el) => {
18 if (!rowKey || el.getAttribute('rowkey') !== rowKey) el.classList.remove('hovered')
19 })
20 if (!rowKey) {
21 hoveredRowId.value = null
22 return
23 }
24 const parsed = Number(rowKey)
25 hoveredRowId.value = (Number.isNaN(parsed) ? rowKey : parsed) as TId
26 table.querySelectorAll(`${ROW_SELECTOR}[rowkey="${CSS.escape(rowKey)}"]`).forEach((el) => {
27 el.classList.add('hovered')
28 })
29 }
30
31 const syncHover = async () => {
32 await nextTick()
33
34 controller?.abort()
35 controller = new AbortController()
36 const { signal } = controller
37
38 const table = document.querySelector(tableSelector)
39 if (!table) return
40
41 table.addEventListener(
42 'mouseover',
43 (event) => {
44 const target = event.target
45 if (!(target instanceof Element)) return
46 const row = target.closest(ROW_SELECTOR)
47 if (!row || !table.contains(row)) return
48 const rowKey = row.getAttribute('rowkey')
49 if (!rowKey) return
50 setHoveredRow(table, rowKey)
51 },
52 { signal },
53 )
54
55 table.addEventListener(
56 'mouseout',
57 (event) => {
58 const target = event.target
59 if (!(target instanceof Element)) return
60 const row = target.closest(ROW_SELECTOR)
61 if (!row) return
62 const related = (event as MouseEvent).relatedTarget
63 if (related instanceof Node && row.contains(related)) return
64 setHoveredRow(table, null)
65 },
66 { signal },
67 )
68 }
69
70 onBeforeUnmount(() => {
71 controller?.abort()
72 controller = null
73 })
74
75 return { hoveredRowId, syncHover }
76 }
77