3 Commits
Author SHA1 Message Date
Hadi b22ce7cbf7 minimum window size package
Signed-off-by: Hadi <[email protected]>
2026-08-23 10:50:15 +02:00
Hadi 0648e7a761 app msgs
Signed-off-by: Hadi <[email protected]>
2026-08-20 20:23:15 +02:00
Hadi 55cb4be01d v0.2.1 2026-08-20 15:43:56 +02:00
4 changed files with 118 additions and 4 deletions
+33
View File
@@ -0,0 +1,33 @@
package app
import tea "charm.land/bubbletea/v2"
type QuitMsg struct{}
func Quit() tea.Cmd {
return func() tea.Msg { return QuitMsg{} }
}
type FocusMsg struct{}
func Focus() tea.Cmd {
return func() tea.Msg { return FocusMsg{} }
}
type BlurMsg struct{}
func Blur() tea.Cmd {
return func() tea.Msg { return BlurMsg{} }
}
type RequestFocusMsg struct{}
func RequestFocus() tea.Cmd {
return func() tea.Msg { return RequestFocusMsg{} }
}
type SetTitleMsg struct{ Title string }
func SetTitle(title string) tea.Cmd {
return func() tea.Msg { return SetTitleMsg{Title: title} }
}
+16 -2
View File
@@ -1,10 +1,13 @@
package helpbar package helpbar
import ( import (
"strings"
"charm.land/bubbles/v2/help" "charm.land/bubbles/v2/help"
"charm.land/bubbles/v2/key" "charm.land/bubbles/v2/key"
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"charm.land/lipgloss/v2" "charm.land/lipgloss/v2"
"github.com/charmbracelet/x/ansi"
"github.com/anotherhadi/ilovetui/bubbles" "github.com/anotherhadi/ilovetui/bubbles"
) )
@@ -59,10 +62,21 @@ func (m Model) View(contextual ...key.Binding) string {
if len(bindings) == 0 || m.width <= 0 { if len(bindings) == 0 || m.width <= 0 {
return "" return ""
} }
var view string
if !m.ShowAll { if !m.ShowAll {
return m.help.ShortHelpView(bindings) view = m.help.ShortHelpView(bindings)
} else {
view = m.help.FullHelpView(m.columns(bindings))
} }
return m.help.FullHelpView(m.columns(bindings)) return m.clampWidth(view)
}
func (m Model) clampWidth(view string) string {
lines := strings.Split(view, "\n")
for i, line := range lines {
lines[i] = ansi.Truncate(line, m.width, "")
}
return strings.Join(lines, "\n")
} }
func (m Model) Height(contextual ...key.Binding) int { func (m Model) Height(contextual ...key.Binding) int {
+60
View File
@@ -0,0 +1,60 @@
package minsize
import (
"fmt"
"charm.land/lipgloss/v2"
"github.com/anotherhadi/ilovetui/style"
)
type Model struct {
MinWidth int
MinHeight int
Style lipgloss.Style
}
type Option func(*Model)
func WithStyle(s lipgloss.Style) Option {
return func(m *Model) { m.Style = s }
}
func New(minWidth, minHeight int, opts ...Option) Model {
m := Model{
MinWidth: minWidth,
MinHeight: minHeight,
Style: lipgloss.NewStyle().Foreground(style.S.Muted),
}
for _, opt := range opts {
opt(&m)
}
return m
}
func (m Model) Fits(width, height int) bool {
return width >= m.MinWidth && height >= m.MinHeight
}
func (m Model) View(width, height int) string {
msg := m.Style.Render(m.message(width, height))
if width < 1 || height < 1 {
return msg
}
return lipgloss.Place(width, height, lipgloss.Center, lipgloss.Center, msg)
}
func (m Model) message(width, height int) string {
tooNarrow := width < m.MinWidth
tooShort := height < m.MinHeight
switch {
case tooNarrow && tooShort:
return fmt.Sprintf("minimum is %dx%d", m.MinWidth, m.MinHeight)
case tooNarrow:
return fmt.Sprintf("minimum width: %d", m.MinWidth)
case tooShort:
return fmt.Sprintf("minimum height: %d", m.MinHeight)
default:
return ""
}
}
+9 -2
View File
@@ -4,6 +4,7 @@ import (
"strings" "strings"
"charm.land/lipgloss/v2" "charm.land/lipgloss/v2"
"github.com/charmbracelet/x/ansi"
) )
var borderTypes = map[string]lipgloss.Border{ var borderTypes = map[string]lipgloss.Border{
@@ -41,12 +42,18 @@ func RenderWithTitle(border lipgloss.Style, title, content string, width, height
box := border.BorderTop(false).Width(width).Height(boxH).Render(content) box := border.BorderTop(false).Width(width).Height(boxH).Render(content)
boxWidth := lipgloss.Width(strings.SplitN(box, "\n", 2)[0]) boxWidth := lipgloss.Width(strings.SplitN(box, "\n", 2)[0])
titleW := lipgloss.Width(title)
b, _, _, _, _ := border.GetBorder() b, _, _, _, _ := border.GetBorder()
topLeft, top, topRight := b.TopLeft, b.Top, b.TopRight topLeft, top, topRight := b.TopLeft, b.Top, b.TopRight
overhead := lipgloss.Width(topLeft) + lipgloss.Width(topRight) + 2
fillW := boxWidth - titleW - lipgloss.Width(topLeft) - lipgloss.Width(topRight) - 2 maxTitleW := max(boxWidth-overhead, 0)
if titleW := lipgloss.Width(title); titleW > maxTitleW {
title = ansi.Truncate(title, maxTitleW, "")
}
titleW := lipgloss.Width(title)
fillW := boxWidth - titleW - overhead
if fillW < 0 { if fillW < 0 {
fillW = 0 fillW = 0
} }