Skip to content

Commit ca4373c

Browse files
committed
feat: center selected item in viewport when dialog opens or after bookmark
- Add 'center' parameter to moveTo() function - Pass center=true from effect (dialog open) and scrollToValue (bookmark toggle) - Keyboard navigation still uses edge-scroll behavior for smooth UX
1 parent 059ca29 commit ca4373c

File tree

1 file changed

+16
-11
lines changed

1 file changed

+16
-11
lines changed

packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
9898
on([() => store.filter, () => props.current], ([filter, current]) => {
9999
setTimeout(() => {
100100
if (filter.length > 0) {
101-
moveTo(0)
101+
moveTo(0, true)
102102
} else if (current) {
103103
const currentIndex = flat().findIndex((opt) => isDeepEqual(opt.value, current))
104104
if (currentIndex >= 0) {
105-
moveTo(currentIndex)
105+
moveTo(currentIndex, true)
106106
}
107107
}
108108
}, 0)
@@ -117,7 +117,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
117117
moveTo(next)
118118
}
119119

120-
function moveTo(next: number) {
120+
function moveTo(next: number, center = false) {
121121
setStore("selected", next)
122122
props.onMove?.(selected()!)
123123
if (!scroll) return
@@ -126,13 +126,18 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
126126
})
127127
if (!target) return
128128
const y = target.y - scroll.y
129-
if (y >= scroll.height) {
130-
scroll.scrollBy(y - scroll.height + 1)
131-
}
132-
if (y < 0) {
133-
scroll.scrollBy(y)
134-
if (isDeepEqual(flat()[0].value, selected()?.value)) {
135-
scroll.scrollTo(0)
129+
if (center) {
130+
const centerOffset = Math.floor(scroll.height / 2)
131+
scroll.scrollBy(y - centerOffset)
132+
} else {
133+
if (y >= scroll.height) {
134+
scroll.scrollBy(y - scroll.height + 1)
135+
}
136+
if (y < 0) {
137+
scroll.scrollBy(y)
138+
if (isDeepEqual(flat()[0].value, selected()?.value)) {
139+
scroll.scrollTo(0)
140+
}
136141
}
137142
}
138143
}
@@ -176,7 +181,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
176181
scrollToValue(value: T) {
177182
const index = flat().findIndex((opt) => isDeepEqual(opt.value, value))
178183
if (index >= 0) {
179-
moveTo(index)
184+
moveTo(index, true)
180185
}
181186
},
182187
}

0 commit comments

Comments
 (0)