internal/ui/dialog/models_list.go 🔗
@@ -26,6 +26,7 @@ func NewModelsList(sty *styles.Styles, groups ...ModelGroup) *ModelsList {
groups: groups,
t: sty,
}
+ f.RegisterRenderCallback(list.FocusedRenderCallback(f.List))
return f
}
Ayman Bagabas created
internal/ui/dialog/models_list.go | 1 +
internal/ui/list/filterable.go | 1 +
internal/ui/list/focus.go | 13 +++++++++++++
internal/ui/list/list.go | 20 +++++++++++++++-----
4 files changed, 30 insertions(+), 5 deletions(-)
@@ -26,6 +26,7 @@ func NewModelsList(sty *styles.Styles, groups ...ModelGroup) *ModelsList {
groups: groups,
t: sty,
}
+ f.RegisterRenderCallback(list.FocusedRenderCallback(f.List))
return f
}
@@ -31,6 +31,7 @@ func NewFilterableList(items ...FilterableItem) *FilterableList {
List: NewList(),
items: items,
}
+ f.RegisterRenderCallback(FocusedRenderCallback(f.List))
f.SetItems(items...)
return f
}
@@ -0,0 +1,13 @@
+package list
+
+// FocusedRenderCallback is a helper function that returns a render callback
+// that marks items as focused during rendering.
+func FocusedRenderCallback(list *List) RenderCallback {
+ return func(idx, selectedIdx int, item Item) Item {
+ if focusable, ok := item.(Focusable); ok {
+ focusable.SetFocused(list.Focused() && idx == selectedIdx)
+ return focusable.(Item)
+ }
+ return item
+ }
+}
@@ -49,9 +49,13 @@ func NewList(items ...Item) *List {
return l
}
+// RenderCallback defines a function that can modify an item before it is
+// rendered.
+type RenderCallback func(idx, selectedIdx int, item Item) Item
+
// RegisterRenderCallback registers a callback to be called when rendering
// items. This can be used to modify items before they are rendered.
-func (l *List) RegisterRenderCallback(cb func(idx, selectedIdx int, item Item) Item) {
+func (l *List) RegisterRenderCallback(cb RenderCallback) {
l.renderCallbacks = append(l.renderCallbacks, cb)
}
@@ -66,6 +70,11 @@ func (l *List) SetGap(gap int) {
l.gap = gap
}
+// Gap returns the gap between items.
+func (l *List) Gap() int {
+ return l.gap
+}
+
// SetReverse shows the list in reverse order.
func (l *List) SetReverse(reverse bool) {
l.reverse = reverse
@@ -101,10 +110,6 @@ func (l *List) getItem(idx int) renderedItem {
}
}
- if focusable, isFocusable := item.(Focusable); isFocusable {
- focusable.SetFocused(l.focused && idx == l.selectedIdx)
- }
-
rendered := item.Render(l.width)
rendered = strings.TrimRight(rendered, "\n")
height := countLines(rendered)
@@ -348,6 +353,11 @@ func (l *List) RemoveItem(idx int) {
}
}
+// Focused returns whether the list is focused.
+func (l *List) Focused() bool {
+ return l.focused
+}
+
// Focus sets the focus state of the list.
func (l *List) Focus() {
l.focused = true