Skip to content

Commit

Permalink
fix: set YOffset + cursor based on first selected item
Browse files Browse the repository at this point in the history
  • Loading branch information
bashbunni committed Aug 3, 2024
1 parent 2eb851f commit 9dbab40
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 5 deletions.
26 changes: 21 additions & 5 deletions field_multiselect.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,24 @@ func (m *MultiSelect[T]) Options(options ...Option[T]) *MultiSelect[T] {
return m
}

minSelected := len(options) - 1
for i, o := range options {
for _, v := range m.accessor.Get() {
if o.Value == v {
options[i].selected = true
break
if o.selected {
options[i].selected = true
if i < minSelected {
minSelected = i
}
break
}
}
// No selected items... Start cursor at the beginning.
if minSelected == len(options)-1 {
minSelected = 0
}
m.options.val = options
m.filteredOptions = options
m.updateViewportHeight()
m.cursor = minSelected
return m
}

Expand Down Expand Up @@ -549,11 +556,20 @@ func (m *MultiSelect[T]) optionsView() string {
return sb.String()
}

// centerYOffsetToSelected sets the YOffset so the selected element is in the
// middle of the list.
func (m *MultiSelect[T]) centerYOffsetToSelected() {
if m.cursor > m.viewport.YOffset+m.viewport.Height {
// Start with the selected value in the middle of the viewport.
m.viewport.SetYOffset(m.cursor - (m.viewport.Height+m.viewport.YOffset)/2)
}
}

// View renders the multi-select field.
func (m *MultiSelect[T]) View() string {
styles := m.activeStyles()

m.viewport.SetContent(m.optionsView())
m.centerYOffsetToSelected()

var sb strings.Builder
if m.title.val != "" || m.title.fn != nil {
Expand Down
10 changes: 10 additions & 0 deletions field_select.go
Original file line number Diff line number Diff line change
Expand Up @@ -588,10 +588,20 @@ func (s *Select[T]) optionsView() string {
return sb.String()
}

// centerYOffsetToSelected sets the YOffset so the selected element is in the
// middle of the list.
func (s *Select[T]) centerYOffsetToSelected() {
if s.selected > s.viewport.YOffset+s.viewport.Height {
// Start with the selected value in the middle of the viewport.
s.viewport.SetYOffset(s.selected - (s.viewport.Height+s.viewport.YOffset)/2)
}
}

// View renders the select field.
func (s *Select[T]) View() string {
styles := s.activeStyles()
s.viewport.SetContent(s.optionsView())
s.centerYOffsetToSelected()

var sb strings.Builder
if s.title.val != "" || s.title.fn != nil {
Expand Down

0 comments on commit 9dbab40

Please sign in to comment.