add hover highlight

This commit is contained in:
2026-01-01 02:38:45 +00:00
parent 0c5195f5a2
commit 4fdf207e50
3 changed files with 32 additions and 15 deletions
+13 -6
View File
@@ -182,13 +182,14 @@ func (t *FsTree) GetSelectedContent() (string, error) {
return string(contentBytes), nil
}
func (t *FsTree) Render() string {
func (t *FsTree) Render(hoverLine int) string {
builder := &strings.Builder{}
t.renderNode(t.root, 0, builder)
lineCounter := 0
t.renderNode(t.root, 0, builder, hoverLine, &lineCounter)
return builder.String()
}
func (t *FsTree) renderNode(node *FsNode, depth int, builder *strings.Builder) {
func (t *FsTree) renderNode(node *FsNode, depth int, builder *strings.Builder, hoverLine int, currentLine *int) {
if node == nil {
return
}
@@ -209,18 +210,24 @@ func (t *FsTree) renderNode(node *FsNode, depth int, builder *strings.Builder) {
icon = lipgloss.NewStyle().Faint(true).Render(prevIndent + icon + indent)
}
// highlight if selected
// highlight if selected or hovered
fileName := node.FileName()
if node == t.selectedNode() {
isSelected := node == t.selectedNode()
isHovered := hoverLine >= 0 && *currentLine == hoverLine
if isSelected {
fileName = lipgloss.NewStyle().Foreground(styles.Highlight).Bold(true).Render(fileName)
} else if isHovered {
fileName = lipgloss.NewStyle().Foreground(styles.HoverHighlight).Render(fileName)
}
line := icon + " " + fileName + "\n"
builder.WriteString(line)
*currentLine++
if node.expanded {
for _, child := range node.children {
t.renderNode(child, depth+1, builder)
t.renderNode(child, depth+1, builder, hoverLine, currentLine)
}
}
}
+14 -5
View File
@@ -44,9 +44,10 @@ type model struct {
tree *fs.FsTree
// spinner needs to be state as I need to update the spinner on
// each tick in update func
spinner spinner.Model
loading bool
viewport viewport.Model
spinner spinner.Model
loading bool
viewport viewport.Model
hoverLine int // track which line is being hovered
}
// initial model state
@@ -63,6 +64,7 @@ func createModel() model {
spinner: s,
loading: true,
viewport: viewport.New(0, 0),
hoverLine: -1, // no hover initially
}
}
@@ -105,6 +107,13 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.spinner, cmd = m.spinner.Update(msg)
return m, cmd
case tea.MouseMsg:
// track hover for all mouse events within file tree
if msg.X < m.width {
m.hoverLine = msg.Y
} else {
m.hoverLine = -1
}
if msg.Button == tea.MouseButtonLeft {
// within file tree
if msg.X < m.width {
@@ -151,7 +160,7 @@ func (m model) View() string {
left := lipgloss.NewStyle().
Width(m.width).
Render(m.tree.Render())
Render(m.tree.Render(m.hoverLine))
right := lipgloss.NewStyle().
Width(m.terminalWidth - m.width - 1).
@@ -173,7 +182,7 @@ func main() {
p := tea.NewProgram(
createModel(),
tea.WithAltScreen(), // full screen tui
tea.WithMouseCellMotion(),
tea.WithMouseAllMotion(),
)
if _, err := p.Run(); err != nil {
fmt.Printf("Error: %v", err)
+5 -4
View File
@@ -11,10 +11,11 @@ import "github.com/charmbracelet/lipgloss"
// ==================== colors ====================
var (
Primary = lipgloss.Color("#7D56F4")
Secondary = lipgloss.Color("#FF5C8F")
Background = lipgloss.Color("#1E1E2E")
Highlight = lipgloss.Color("#FFA500") // Orange highlight for selected node
Primary = lipgloss.Color("#7D56F4")
Secondary = lipgloss.Color("#FF5C8F")
Background = lipgloss.Color("#1E1E2E")
Highlight = lipgloss.Color("#FFA500") // Orange highlight for selected node
HoverHighlight = lipgloss.Color("#4ECDC4") // Teal highlight for hovered node
// TODO: to extend as needed, right now this is just a
// placeholder
)