@@ -31,6 +31,7 @@ const (
3131type ListModel interface {
3232 util.Model
3333 layout.Sizeable
34+ layout.Focusable
3435 SetItems([]util.Model) tea.Cmd // Replace all items in the list
3536 AppendItem(util.Model) tea.Cmd // Add an item to the end of the list
3637 PrependItem(util.Model) tea.Cmd // Add an item to the beginning of the list
@@ -40,7 +41,6 @@ type ListModel interface {
4041 Items() []util.Model // Get all items in the list
4142 SelectedIndex() int // Get the index of the currently selected item
4243 SetSelected(int) tea.Cmd // Set the selected item by index and scroll to it
43− ClearSelection() tea.Cmd // Clear the current selection
4444 Filter(string) tea.Cmd // Filter items based on a search term
4545}
4646
@@ -143,6 +143,8 @@ type model struct {
143143 inputStyle lipgloss.Style // Style for the input field
144144 hideFilterInput bool // Whether to hide the filter input field
145145 currentSearch string // Current search term for filtering
146+
147+ isFocused bool // Whether the list is currently focused
146148}
147149
148150// listOptions is a function type for configuring list options.
@@ -238,6 +240,7 @@ func New(opts ...listOptions) ListModel {
238240 selectionState: selectionState{selectedIndex: NoSelection},
239241 filterPlaceholder: "Type to filter...",
240242 inputStyle: t.S().Base.Padding(0, 1, 1, 1),
243+ isFocused: true,
241244 }
242245 for _, opt := range opts {
243246 opt(m)
@@ -746,8 +749,10 @@ func (m *model) ensureVisibleReverse(cachedItem renderedItem) {
746749func (m *model) goToBottom() tea.Cmd {
747750 cmds := []tea.Cmd{m.blurSelected()}
748751 m.viewState.reverse = true
749− m.selectionState.selectedIndex = m.findLastSelectableItem()
750− cmds = append(cmds, m.focusSelected())
752+ if m.isFocused {
753+ m.selectionState.selectedIndex = m.findLastSelectableItem()
754+ cmds = append(cmds, m.focusSelected())
755+ }
751756 m.ResetView()
752757 return tea.Batch(cmds...)
753758}
@@ -774,6 +779,9 @@ func (m *model) ResetView() {
774779// focusSelected gives focus to the currently selected item if it supports focus.
775780// Triggers a re-render of the item to show its focused state.
776781func (m *model) focusSelected() tea.Cmd {
782+ if !m.isFocused {
783+ return nil // No focus change if the list is not focused
784+ }
777785 if !m.selectionState.isValidIndex(len(m.filteredItems)) {
778786 return nil
779787 }
@@ -953,9 +961,7 @@ func (m *model) UpdateItem(inx int, item util.Model) {
953961 }
954962 m.filteredItems[inx] = item
955963 if m.selectionState.selectedIndex == inx {
956− if i, ok := m.filteredItems[m.selectionState.selectedIndex].(layout.Focusable); ok {
957− i.Focus()
958− }
964+ m.focusSelected()
959965 }
960966 m.setItemSize(inx)
961967 m.rerenderItem(inx)
@@ -1334,14 +1340,21 @@ func (m *model) SetSelected(index int) tea.Cmd {
13341340 return tea.Batch(cmds...)
13351341}
13361342
1337−// ClearSelection clears the current selection and focus.
1338−func (m *model) ClearSelection() tea.Cmd {
1339− cmds := []tea.Cmd{}
1340− if m.selectionState.selectedIndex >= 0 && m.selectionState.selectedIndex < len(m.filteredItems) {
1341− if i, ok := m.filteredItems[m.selectionState.selectedIndex].(layout.Focusable); ok {
1342− cmds = append(cmds, i.Blur())
1343− }
1344− }
1345− m.selectionState.selectedIndex = NoSelection
1346− return tea.Batch(cmds...)
1343+// Blur implements ListModel.
1344+func (m *model) Blur() tea.Cmd {
1345+ m.isFocused = false
1346+ cmd := m.blurSelected()
1347+ return cmd
1348+}
1349+
1350+// Focus implements ListModel.
1351+func (m *model) Focus() tea.Cmd {
1352+ m.isFocused = true
1353+ cmd := m.focusSelected()
1354+ return cmd
1355+}
1356+
1357+// IsFocused implements ListModel.
1358+func (m *model) IsFocused() bool {
1359+ return m.isFocused
13471360}