@@ -138,7 +138,7 @@ func (l *List) ScrollBy(lines int) {
138138 if l.gap > 0 && i < len(l.items)-1 {
139139 totalLines += l.gap
140140 }
141− if totalLines >= l.height {
141+ if totalLines > l.height-1 {
142142 lastItemIdx = i
143143 break
144144 }
@@ -165,7 +165,7 @@ func (l *List) ScrollBy(lines int) {
165165 }
166166
167167 if l.offsetLine >= item.height {
168− l.offsetLine = item.height - 1
168+ l.offsetLine = item.height
169169 }
170170 } else if lines < 0 {
171171 // Scroll up
@@ -376,7 +376,36 @@ func (l *List) ScrollToBottom() {
376376
377377// ScrollToSelected scrolls the list to the selected item.
378378func (l *List) ScrollToSelected() {
379− // TODO: Implement me
379+ if l.selectedIdx < 0 || l.selectedIdx >= len(l.items) {
380+ return
381+ }
382+
383+ startIdx, endIdx := l.findVisibleItems()
384+ if l.selectedIdx < startIdx {
385+ // Selected item is above the visible range
386+ l.offsetIdx = l.selectedIdx
387+ l.offsetLine = 0
388+ } else if l.selectedIdx > endIdx {
389+ // Selected item is below the visible range
390+ // Scroll so that the selected item is at the bottom
391+ var totalHeight int
392+ for i := l.selectedIdx; i >= 0; i-- {
393+ item := l.getItem(i)
394+ totalHeight += item.height
395+ if l.gap > 0 && i < l.selectedIdx {
396+ totalHeight += l.gap
397+ }
398+ if totalHeight >= l.height {
399+ l.offsetIdx = i
400+ l.offsetLine = totalHeight - l.height
401+ break
402+ }
403+ }
404+ if totalHeight < l.height {
405+ // All items fit in the viewport
406+ l.ScrollToTop()
407+ }
408+ }
380409}
381410
382411// SelectedItemInView returns whether the selected item is currently in view.