mirror of
https://github.com/charmbracelet/bubbles.git
synced 2026-07-21 02:59:28 -06:00
fix(textinput): stop applying Text/Placeholder style to padding
When Width is set, View pads the input out to that width with spaces. Both the text path and the placeholder path were running those padding spaces through the active style, so setting a background color on either Text or Placeholder caused the bg to extend well past the actual content, which doesn't match how a placeholder usually reads in CSS terms (you expect the style to scope to the text itself). Drop the styling on the padding in both code paths so the two views behave the same way: style covers the text, the rest is empty space. Closes #245. Signed-off-by: Charlie Tonneslan <cst0520@gmail.com>
This commit is contained in:
parent
dc61c1b4ba
commit
60b0b13dfa
@ -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
|
||||
@ -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:]))
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
|
||||
tea "charm.land/bubbletea/v2"
|
||||
"charm.land/lipgloss/v2"
|
||||
)
|
||||
|
||||
func Test_CurrentSuggestion(t *testing.T) {
|
||||
@ -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)}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user