Skip to content

v2: textinput overflows set width #812

@lrstanley

Description

@lrstanley

Describe the bug
When setting the width on the textinput component, it will overflow the provided width. Additionally, the width is also variable depending on suggestions provided to the input (it will increase in width even further beyond the limit when a suggestion is showing).

Setup

  • OS: Ubuntu (WSL2)
  • Shell: Bash
  • Terminal Emulator: Windows Terminal
  • Terminal Multiplexer: n/a
  • Locale: en_US.UTF-8

To Reproduce
Run the below example using bubbles/bubbletea/lipgloss v2, and it should panic anytime the width of the textinput does not obey what was provided with <input>.SetWidth(int)

Source Code

package main

import (
	"fmt"
	"log"

	"github.com/charmbracelet/bubbles/v2/textinput"
	tea "github.com/charmbracelet/bubbletea/v2"
	"github.com/charmbracelet/lipgloss/v2"
)

const InputWidth = 20

func main() {
	p := tea.NewProgram(initialModel(), tea.WithAltScreen())
	if _, err := p.Run(); err != nil {
		log.Fatal(err)
	}
}

type model struct {
	input textinput.Model
}

func initialModel() model {
	ti := textinput.New()
	ti.Placeholder = "Pikachu"
	ti.Focus()
	ti.VirtualCursor = true
	ti.SetWidth(InputWidth)

	return model{input: ti}
}

func (m model) Init() tea.Cmd {
	return textinput.Blink
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	var cmd tea.Cmd

	switch msg := msg.(type) {
	case tea.KeyPressMsg:
		switch msg.String() {
		case "enter", "ctrl+c", "esc":
			return m, tea.Quit
		}
	}

	m.input, cmd = m.input.Update(msg)
	return m, cmd
}

func (m model) View() string {
	input := m.input.View()

	if lipgloss.Width(input) > InputWidth {
		panic(fmt.Sprintf("input width is %d", lipgloss.Width(input)))
	}

	return lipgloss.JoinVertical(
		lipgloss.Top,
		m.headerView(),
		input,
		m.footerView(),
	)
}

func (m model) headerView() string { return "What's your favorite Pokémon?\n" }
func (m model) footerView() string { return "\n(esc to quit)" }

Expected behavior
I would expect that it should obey the provided width and handle any form of truncating internally.

Screenshots
n/a

Additional context
A user could obviously wrap the input and force cut off the width, but this should not be required.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions