dialog.go 1.5 KB

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