dialog.go

 1package core
 2
 3import (
 4	"github.com/charmbracelet/bubbles/key"
 5	tea "github.com/charmbracelet/bubbletea"
 6	"github.com/charmbracelet/lipgloss"
 7	"github.com/kujtimiihoxha/termai/internal/tui/layout"
 8	"github.com/kujtimiihoxha/termai/internal/tui/util"
 9)
10
11type SizeableModel interface {
12	tea.Model
13	layout.Sizeable
14}
15
16type DialogMsg struct {
17	Content SizeableModel
18}
19
20type DialogCloseMsg struct{}
21
22type KeyBindings struct {
23	Return key.Binding
24}
25
26var keys = KeyBindings{
27	Return: key.NewBinding(
28		key.WithKeys("esc"),
29		key.WithHelp("esc", "close"),
30	),
31}
32
33type DialogCmp interface {
34	tea.Model
35	layout.Bindings
36}
37
38type dialogCmp struct {
39	content SizeableModel
40}
41
42func (d *dialogCmp) Init() tea.Cmd {
43	return nil
44}
45
46func (d *dialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
47	switch msg := msg.(type) {
48	case DialogMsg:
49		d.content = msg.Content
50	case DialogCloseMsg:
51		d.content = nil
52		return d, nil
53	case tea.KeyMsg:
54		if key.Matches(msg, keys.Return) {
55			return d, util.CmdHandler(DialogCloseMsg{})
56		}
57	}
58	if d.content != nil {
59		u, cmd := d.content.Update(msg)
60		d.content = u.(SizeableModel)
61		return d, cmd
62	}
63	return d, nil
64}
65
66func (d *dialogCmp) BindingKeys() []key.Binding {
67	bindings := []key.Binding{keys.Return}
68	if d.content == nil {
69		return bindings
70	}
71	if c, ok := d.content.(layout.Bindings); ok {
72		return append(bindings, c.BindingKeys()...)
73	}
74	return bindings
75}
76
77func (d *dialogCmp) View() string {
78	w, h := d.content.GetSize()
79	return lipgloss.NewStyle().Width(w).Height(h).Render(d.content.View())
80}
81
82func NewDialogCmp() DialogCmp {
83	return &dialogCmp{}
84}