From afb546733555e78a5970c544062e72e9c4f4360b Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 10 Dec 2025 12:10:22 -0500 Subject: [PATCH] feat(ui): add mouse click handling to lazy list items --- internal/ui/lazylist/item.go | 12 +++++++++++- internal/ui/lazylist/list.go | 7 +++++++ internal/ui/model/items.go | 7 ++++--- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/internal/ui/lazylist/item.go b/internal/ui/lazylist/item.go index 7c6904d7ad2cd30aec0fab62b9238141343c4e9f..2a1b68a9bd666d8bba104274d51e984edc30b76e 100644 --- a/internal/ui/lazylist/item.go +++ b/internal/ui/lazylist/item.go @@ -1,6 +1,9 @@ package lazylist -import "charm.land/lipgloss/v2" +import ( + "charm.land/lipgloss/v2" + "github.com/charmbracelet/x/ansi" +) // Item represents a single item in the lazy-loaded list. type Item interface { @@ -22,3 +25,10 @@ type HighlightStylable interface { // HighlightStyle returns the style to apply for highlighted regions. HighlightStyle() lipgloss.Style } + +// MouseClickable represents an item that can handle mouse click events. +type MouseClickable interface { + // HandleMouseClick processes a mouse click event at the given coordinates. + // It returns true if the event was handled, false otherwise. + HandleMouseClick(btn ansi.MouseButton, x, y int) bool +} diff --git a/internal/ui/lazylist/list.go b/internal/ui/lazylist/list.go index 423426ed256ea28a195aa7eacdbbeb6dc377d61c..319d69a777409c8c10528911aed30b34a83d623e 100644 --- a/internal/ui/lazylist/list.go +++ b/internal/ui/lazylist/list.go @@ -5,6 +5,7 @@ import ( "strings" "charm.land/lipgloss/v2" + "github.com/charmbracelet/x/ansi" ) // List represents a list of items that can be lazily rendered. A list is @@ -550,6 +551,12 @@ func (l *List) HandleMouseDown(x, y int) bool { // Select the clicked item l.SetSelected(itemIdx) + if clickable, ok := l.items[itemIdx].(MouseClickable); ok { + clickable.HandleMouseClick(ansi.MouseButton1, x, itemY) + l.items[itemIdx] = clickable.(Item) + l.invalidateItem(itemIdx) + } + return true } diff --git a/internal/ui/model/items.go b/internal/ui/model/items.go index 7e5f732ca8e60e824b3bced67feab3667e3823af..09fa1e74a60d2f94eaaf07859edd7383a6eef787 100644 --- a/internal/ui/model/items.go +++ b/internal/ui/model/items.go @@ -351,6 +351,7 @@ type SectionHeaderItem struct { duration time.Duration isSectionHeader bool sty *styles.Styles + content string } // NewSectionHeaderItem creates a new section header item. @@ -387,13 +388,13 @@ func (s *SectionHeaderItem) BlurStyle() lipgloss.Style { // Render implements lazylist.Item. func (s *SectionHeaderItem) Render(width int) string { - content := s.sty.Chat.Message.SectionHeader.Render(fmt.Sprintf("%s %s %s", + content := fmt.Sprintf("%s %s %s", s.sty.Subtle.Render(styles.ModelIcon), s.sty.Muted.Render(s.modelName), s.sty.Subtle.Render(s.duration.String()), - )) + ) - return content + return s.sty.Chat.Message.SectionHeader.Render(content) } // GetMessageItems extracts [MessageItem]s from a [message.Message]. It returns