mirror of
https://github.com/Maks1mS/bubbles.git
synced 2025-03-13 12:33:43 +03:00
119 lines
2.1 KiB
Go
119 lines
2.1 KiB
Go
package layouts
|
|
|
|
import (
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
)
|
|
|
|
// Model is the Bubble Tea model for a vertical layout element.
|
|
type Model struct {
|
|
Index int
|
|
Items []tea.Model
|
|
|
|
// Focus indicates whether user focus should be on this component
|
|
focus bool
|
|
}
|
|
|
|
type FocusItem interface {
|
|
Focus() tea.Model
|
|
Blur() tea.Model
|
|
}
|
|
|
|
// NewModel creates a new model with default settings.
|
|
func NewModel() Model {
|
|
return Model{}
|
|
}
|
|
|
|
// Update is the Tea update loop.
|
|
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
|
|
if !m.focus {
|
|
return m, nil
|
|
}
|
|
|
|
switch msg := msg.(type) {
|
|
case tea.KeyMsg:
|
|
switch msg.String() {
|
|
case "shift+tab", "up":
|
|
m.Index--
|
|
if m.Index < 0 {
|
|
m.Index = len(m.Items) - 1
|
|
}
|
|
m.updateFocus()
|
|
|
|
case "tab", "down":
|
|
m.Index++
|
|
if m.Index >= len(m.Items) {
|
|
m.Index = 0
|
|
}
|
|
m.updateFocus()
|
|
}
|
|
}
|
|
|
|
cmd := m.updateItems(msg)
|
|
return m, cmd
|
|
}
|
|
|
|
// View renders the layout in its current state.
|
|
func (m Model) View() string {
|
|
var view string
|
|
|
|
for _, v := range m.Items {
|
|
if mi, ok := v.(tea.Model); ok {
|
|
view += mi.View() + "\n"
|
|
}
|
|
}
|
|
|
|
return view
|
|
}
|
|
|
|
func (m *Model) updateFocus() {
|
|
for i, v := range m.Items {
|
|
if m.Index == i {
|
|
if fi, ok := v.(FocusItem); ok {
|
|
// new focused item
|
|
m.Items[i] = fi.Focus()
|
|
}
|
|
} else {
|
|
if fi, ok := v.(FocusItem); ok {
|
|
m.Items[i] = fi.Blur()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Pass messages and models through to text input components. Only text inputs
|
|
// with Focus() set will respond, so it's safe to simply update all of them
|
|
// here without any further logic.
|
|
func (m *Model) updateItems(msg tea.Msg) tea.Cmd {
|
|
var (
|
|
cmd tea.Cmd
|
|
cmds []tea.Cmd
|
|
)
|
|
|
|
for i, v := range m.Items {
|
|
if mi, ok := v.(tea.Model); ok {
|
|
m.Items[i], cmd = mi.Update(msg)
|
|
if cmd != nil {
|
|
cmds = append(cmds, cmd)
|
|
}
|
|
}
|
|
}
|
|
|
|
return tea.Batch(cmds...)
|
|
}
|
|
|
|
// Focused returns the focus state on the model.
|
|
func (m Model) Focused() bool {
|
|
return m.focus
|
|
}
|
|
|
|
// Focus sets the focus state on the model.
|
|
func (m *Model) Focus() {
|
|
m.focus = true
|
|
m.updateFocus()
|
|
}
|
|
|
|
// Blur removes the focus state on the model.
|
|
func (m *Model) Blur() {
|
|
m.focus = false
|
|
}
|