spinner.go RawHistoryFolder
1// Package components provides reusable TUI components for Gordon's CLI.
2package components
3
4import (
5 "github.com/bnema/gordon/internal/adapters/in/cli/ui/styles"
6
7 "github.com/charmbracelet/bubbles/spinner"
8 tea "github.com/charmbracelet/bubbletea"
9 "github.com/charmbracelet/lipgloss"
10)
11
12// SpinnerModel wraps the bubbles spinner with Gordon styling.
13type SpinnerModel struct {
14 spinner spinner.Model
15 message string
16 style lipgloss.Style
17}
18
19// SpinnerOption configures a SpinnerModel.
20type SpinnerOption func(*SpinnerModel)
21
22// NewSpinner creates a new spinner with Gordon styling.
23func NewSpinner(opts ...SpinnerOption) SpinnerModel {
24 s := spinner.New()
25 s.Spinner = spinner.Dot
26 s.Style = lipgloss.NewStyle().Foreground(styles.ColorPrimary)
27
28 m := SpinnerModel{
29 spinner: s,
30 message: "Loading...",
31 style: styles.Theme.Body,
32 }
33
34 for _, opt := range opts {
35 opt(&m)
36 }
37
38 return m
39}
40
41// WithMessage sets the spinner message.
42func WithMessage(msg string) SpinnerOption {
43 return func(m *SpinnerModel) {
44 m.message = msg
45 }
46}
47
48// WithSpinnerType sets the spinner animation type.
49func WithSpinnerType(t spinner.Spinner) SpinnerOption {
50 return func(m *SpinnerModel) {
51 m.spinner.Spinner = t
52 }
53}
54
55// WithSpinnerColor sets the spinner color.
56func WithSpinnerColor(color lipgloss.Color) SpinnerOption {
57 return func(m *SpinnerModel) {
58 m.spinner.Style = lipgloss.NewStyle().Foreground(color)
59 }
60}
61
62// Init implements tea.Model.
63func (m SpinnerModel) Init() tea.Cmd {
64 return m.spinner.Tick
65}
66
67// Update implements tea.Model.
68func (m SpinnerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
69 var cmd tea.Cmd
70 m.spinner, cmd = m.spinner.Update(msg)
71 return m, cmd
72}
73
74// View implements tea.Model.
75func (m SpinnerModel) View() string {
76 return m.spinner.View() + " " + m.style.Render(m.message)
77}
78
79// SetMessage updates the spinner message.
80func (m *SpinnerModel) SetMessage(msg string) {
81 m.message = msg
82}
83
84// Tick returns the spinner tick command for animation.
85func (m SpinnerModel) Tick() tea.Cmd {
86 return m.spinner.Tick
87}
88
89// Common spinner types with Gordon colors.
90var (
91 // SpinnerDot is the default dot spinner.
92 SpinnerDot = spinner.Dot
93
94 // SpinnerLine is a simple line spinner.
95 SpinnerLine = spinner.Line
96
97 // SpinnerMiniDot is a smaller dot spinner.
98 SpinnerMiniDot = spinner.MiniDot
99
100 // SpinnerJump is a jumping spinner.
101 SpinnerJump = spinner.Jump
102
103 // SpinnerPulse is a pulsing spinner.
104 SpinnerPulse = spinner.Pulse
105
106 // SpinnerPoints is a points spinner.
107 SpinnerPoints = spinner.Points
108
109 // SpinnerGlobe is a globe spinner.
110 SpinnerGlobe = spinner.Globe
111
112 // SpinnerMoon is a moon phase spinner.
113 SpinnerMoon = spinner.Moon
114
115 // SpinnerMonkey is a monkey spinner.
116 SpinnerMonkey = spinner.Monkey
117)