Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions textinput/textinput.go
Original file line number Diff line number Diff line change
Expand Up @@ -719,15 +719,16 @@ func (m Model) View() string {
}
}

// If a max width and background color were set fill the empty spaces with
// the background color.
// Pad the rest of the input out to its full width. The padding spaces are
// left unstyled so that Text styling stops at the value's end, matching
// the placeholder's behavior. See #245.
valWidth := uniseg.StringWidth(string(value))
if m.Width() > 0 && valWidth <= m.Width() {
padding := max(0, m.Width()-valWidth)
if valWidth+padding <= m.Width() && pos < len(value) {
padding++
}
v += styleText(strings.Repeat(" ", padding))
v += strings.Repeat(" ", padding)
}

return m.promptView() + v
Expand Down Expand Up @@ -768,9 +769,11 @@ func (m Model) placeholderView() string {
minWidth += availWidth
availWidth = 0
}
// append placeholder[len] - cursor, append padding
// append placeholder[len] - cursor, append padding (padding is
// intentionally unstyled so the placeholder color only covers the
// placeholder text itself, matching the text-mode behavior in View).
v += render(string(p[1:minWidth]))
v += render(strings.Repeat(" ", availWidth))
v += strings.Repeat(" ", availWidth)
} else {
// if there is no width, the placeholder can be any length
v += render(string(p[1:]))
Expand Down
31 changes: 31 additions & 0 deletions textinput/textinput_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

tea "charm.land/bubbletea/v2"
"charm.land/lipgloss/v2"
)

func Test_CurrentSuggestion(t *testing.T) {
Expand Down Expand Up @@ -107,6 +108,36 @@ func ExampleValidateFunc() {
}
}

func TestTextStyleAndPlaceholderStyleScopeMatch(t *testing.T) {
// Regression test for #245. The padding spaces that fill the input out to
// its full width must not pick up the Text or Placeholder style, otherwise
// the user sees a styled background extending past the actual text. Both
// the text and placeholder code paths should agree.
bg := lipgloss.NewStyle().Background(lipgloss.Color("#AFAFAF"))

m := New()
m.SetWidth(20)
m.Placeholder = "Pies"
styles := m.Styles()
styles.Focused.Text = bg
styles.Focused.Placeholder = bg
styles.Blurred.Text = bg
styles.Blurred.Placeholder = bg
m.SetStyles(styles)
m.Blur()

placeholderView := m.View()
if !strings.HasSuffix(placeholderView, strings.Repeat(" ", 17)) {
t.Errorf("placeholder view should end with unstyled padding spaces, got %q", placeholderView)
}

m.SetValue("foo")
textView := m.View()
if !strings.HasSuffix(textView, strings.Repeat(" ", 17)) {
t.Errorf("text view should end with unstyled padding spaces, got %q", textView)
}
}

func keyPress(key rune) tea.Msg {
return tea.KeyPressMsg{Code: key, Text: string(key)}
}
Expand Down