on main help sign in
feat(ui): add mouse click handling to lazy list items
afb5467Ayman Bagabas
internal/ui/lazylist/item.go+11−1
@@ -1,6 +1,9 @@
1package lazylist
1package lazylist
2
2
3+import (
3−import "charm.land/lipgloss/v2"
4+ "charm.land/lipgloss/v2"
5+ "github.com/charmbracelet/x/ansi"
6+)
4
7
5// Item represents a single item in the lazy-loaded list.
8// Item represents a single item in the lazy-loaded list.
6type Item interface {
9type Item interface {
@@ -22,3 +25,10 @@ type HighlightStylable interface {
22 // HighlightStyle returns the style to apply for highlighted regions.
25 // HighlightStyle returns the style to apply for highlighted regions.
23 HighlightStyle() lipgloss.Style
26 HighlightStyle() lipgloss.Style
24}
27}
28+
29+// MouseClickable represents an item that can handle mouse click events.
30+type MouseClickable interface {
31+ // HandleMouseClick processes a mouse click event at the given coordinates.
32+ // It returns true if the event was handled, false otherwise.
33+ HandleMouseClick(btn ansi.MouseButton, x, y int) bool
34+}
internal/ui/lazylist/list.go+7
@@ -5,6 +5,7 @@ import (
5 "strings"
5 "strings"
6
6
7 "charm.land/lipgloss/v2"
7 "charm.land/lipgloss/v2"
8+ "github.com/charmbracelet/x/ansi"
8)
9)
9
10
10// List represents a list of items that can be lazily rendered. A list is
11// 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 {
550 // Select the clicked item
551 // Select the clicked item
551 l.SetSelected(itemIdx)
552 l.SetSelected(itemIdx)
552
553
554+ if clickable, ok := l.items[itemIdx].(MouseClickable); ok {
555+ clickable.HandleMouseClick(ansi.MouseButton1, x, itemY)
556+ l.items[itemIdx] = clickable.(Item)
557+ l.invalidateItem(itemIdx)
558+ }
559+
553 return true
560 return true
554}
561}
555
562
internal/ui/model/items.go+4−3
@@ -351,6 +351,7 @@ type SectionHeaderItem struct {
351 duration time.Duration
351 duration time.Duration
352 isSectionHeader bool
352 isSectionHeader bool
353 sty *styles.Styles
353 sty *styles.Styles
354+ content string
354}
355}
355
356
356// NewSectionHeaderItem creates a new section header item.
357// NewSectionHeaderItem creates a new section header item.
@@ -387,13 +388,13 @@ func (s *SectionHeaderItem) BlurStyle() lipgloss.Style {
387
388
388// Render implements lazylist.Item.
389// Render implements lazylist.Item.
389func (s *SectionHeaderItem) Render(width int) string {
390func (s *SectionHeaderItem) Render(width int) string {
390− content := s.sty.Chat.Message.SectionHeader.Render(fmt.Sprintf("%s %s %s",
391+ content := fmt.Sprintf("%s %s %s",
391 s.sty.Subtle.Render(styles.ModelIcon),
392 s.sty.Subtle.Render(styles.ModelIcon),
392 s.sty.Muted.Render(s.modelName),
393 s.sty.Muted.Render(s.modelName),
393 s.sty.Subtle.Render(s.duration.String()),
394 s.sty.Subtle.Render(s.duration.String()),
394− ))
395+ )
395
396
396− return content
397+ return s.sty.Chat.Message.SectionHeader.Render(content)
397}
398}
398
399
399// GetMessageItems extracts [MessageItem]s from a [message.Message]. It returns
400// GetMessageItems extracts [MessageItem]s from a [message.Message]. It returns