noph-ui 0.24.11 → 0.24.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -74,6 +74,33 @@
|
|
|
74
74
|
if (activeIndex >= displayOptions.length) {
|
|
75
75
|
activeIndex = -1
|
|
76
76
|
}
|
|
77
|
+
|
|
78
|
+
if (menuOpen && activeIndex >= 0) {
|
|
79
|
+
const id = `${uid}-opt-${activeIndex}`
|
|
80
|
+
const optEl = document.getElementById(id)
|
|
81
|
+
if (optEl) {
|
|
82
|
+
optEl.scrollIntoView({ block: 'nearest' })
|
|
83
|
+
} else if (useVirtualList && menuElement) {
|
|
84
|
+
const viewport = menuElement.querySelector(
|
|
85
|
+
'svelte-virtual-list-viewport',
|
|
86
|
+
) as HTMLElement | null
|
|
87
|
+
if (viewport) {
|
|
88
|
+
let rowHeight = 48
|
|
89
|
+
const firstRow = viewport.querySelector('[id^="' + uid + '-opt-"]') as HTMLElement | null
|
|
90
|
+
if (firstRow) {
|
|
91
|
+
rowHeight = firstRow.offsetHeight || rowHeight
|
|
92
|
+
}
|
|
93
|
+
const top = activeIndex * rowHeight
|
|
94
|
+
const bottom = top + rowHeight
|
|
95
|
+
const { scrollTop, clientHeight } = viewport
|
|
96
|
+
if (top < scrollTop) {
|
|
97
|
+
viewport.scrollTop = top
|
|
98
|
+
} else if (bottom > scrollTop + clientHeight) {
|
|
99
|
+
viewport.scrollTop = bottom - clientHeight
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
77
104
|
})
|
|
78
105
|
</script>
|
|
79
106
|
|
|
@@ -83,6 +110,7 @@
|
|
|
83
110
|
softFocus={index === activeIndex}
|
|
84
111
|
aria-selected={index === activeIndex}
|
|
85
112
|
role="option"
|
|
113
|
+
tabindex={-1}
|
|
86
114
|
onmousedown={(e) => {
|
|
87
115
|
e.preventDefault()
|
|
88
116
|
}}
|
|
@@ -165,7 +165,28 @@
|
|
|
165
165
|
focusIndex = Math.min(Math.max(index, 0), options.length - 1)
|
|
166
166
|
await tick()
|
|
167
167
|
const el = document.getElementById(`${uid}-opt-${focusIndex}`)
|
|
168
|
-
|
|
168
|
+
if (el) {
|
|
169
|
+
el.focus()
|
|
170
|
+
} else if (useVirtualList && menuElement) {
|
|
171
|
+
const viewport = menuElement.querySelector(
|
|
172
|
+
'svelte-virtual-list-viewport',
|
|
173
|
+
) as HTMLElement | null
|
|
174
|
+
if (viewport) {
|
|
175
|
+
let rowHeight = 48
|
|
176
|
+
const firstRow = viewport.querySelector('[id^="' + uid + '-opt-"]') as HTMLElement | null
|
|
177
|
+
if (firstRow) {
|
|
178
|
+
rowHeight = firstRow.offsetHeight || rowHeight
|
|
179
|
+
}
|
|
180
|
+
const top = focusIndex * rowHeight
|
|
181
|
+
const bottom = top + rowHeight
|
|
182
|
+
const { scrollTop, clientHeight } = viewport
|
|
183
|
+
if (top < scrollTop) {
|
|
184
|
+
viewport.scrollTop = top
|
|
185
|
+
} else if (bottom > scrollTop + clientHeight) {
|
|
186
|
+
viewport.scrollTop = bottom - clientHeight
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
169
190
|
}
|
|
170
191
|
|
|
171
192
|
const moveFocus = (delta: number) => {
|
|
@@ -572,9 +593,6 @@
|
|
|
572
593
|
}
|
|
573
594
|
if (idx < 0) idx = 0
|
|
574
595
|
focusIndex = idx
|
|
575
|
-
await tick()
|
|
576
|
-
const el = document.getElementById(`${uid}-opt-${focusIndex}`)
|
|
577
|
-
;(el as HTMLElement | null)?.focus?.()
|
|
578
596
|
} else {
|
|
579
597
|
menuOpen = false
|
|
580
598
|
focusIndex = -1
|
|
@@ -583,7 +601,17 @@
|
|
|
583
601
|
bind:element={menuElement}
|
|
584
602
|
>
|
|
585
603
|
{#if useVirtualList}
|
|
586
|
-
<VirtualList
|
|
604
|
+
<VirtualList
|
|
605
|
+
height="250px"
|
|
606
|
+
itemHeight={48}
|
|
607
|
+
items={options}
|
|
608
|
+
rendered={({ start, end }) => {
|
|
609
|
+
if (focusIndex >= start && focusIndex < end) {
|
|
610
|
+
const el = document.getElementById(`${uid}-opt-${focusIndex}`)
|
|
611
|
+
el?.focus()
|
|
612
|
+
}
|
|
613
|
+
}}
|
|
614
|
+
>
|
|
587
615
|
{#snippet row(option, index)}
|
|
588
616
|
{@render item(option, index)}
|
|
589
617
|
{/snippet}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
end?: number
|
|
11
11
|
row: Snippet<[T, number]>
|
|
12
12
|
overscan?: number
|
|
13
|
+
rendered?: (event: { start: number; end: number }) => void
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
let {
|
|
@@ -19,7 +20,8 @@
|
|
|
19
20
|
start = $bindable(0),
|
|
20
21
|
end = $bindable(0),
|
|
21
22
|
row,
|
|
22
|
-
overscan =
|
|
23
|
+
overscan = 0,
|
|
24
|
+
rendered,
|
|
23
25
|
}: VirtualListProps = $props()
|
|
24
26
|
|
|
25
27
|
let height_map: number[] = []
|
|
@@ -79,6 +81,8 @@
|
|
|
79
81
|
|
|
80
82
|
bottom = remaining * average_height
|
|
81
83
|
height_map.length = items.length
|
|
84
|
+
|
|
85
|
+
rendered?.({ start, end })
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
async function handle_scroll() {
|
|
@@ -151,6 +155,8 @@
|
|
|
151
155
|
const d = actual_height - expected_height
|
|
152
156
|
viewport.scrollTo(0, scrollTop + d)
|
|
153
157
|
}
|
|
158
|
+
await tick()
|
|
159
|
+
rendered?.({ start, end })
|
|
154
160
|
}
|
|
155
161
|
|
|
156
162
|
onMount(() => {
|