rivo / tview

Terminal UI library with rich, interactive widgets — written in Golang
MIT License
11.11k stars 576 forks source link

Form Input and Checkbox Colors Not Changing in tview Form #1042

Open 0xJWLabs opened 1 month ago

0xJWLabs commented 1 month ago

Description

In my application using tview, I've created a login form with input fields for email, password, an optional code, and a checkbox. I am trying to set the background and text colors for these elements, but they don't seem to change, even though the code is correctly detecting the form items.

Extra Note: If I use lf.SetFieldBackgroundColor(...) and lf.SetFieldTextColor(...) it works, but it changes everything.

Code Snippet

Here's a snippet of the relevant part of the code:

func newLoginForm(done doneFn, cfg *config.Config) *loginForm {
    if done == nil {
        done = func(_ string, _ error) {}
    }

    lf := &loginForm{
        Form: tview.NewForm(),
        done: done,
    }

    lf.AddInputField("Email", "", 0, nil, nil)
    lf.AddPasswordField("Password", "", 0, 0, nil)
    lf.AddPasswordField("Code (optional)", "", 0, 0, nil)
    lf.AddCheckbox("Remember Me", false, nil)
    lf.AddButton("Login", lf.login)

    lf.SetButtonBackgroundColor(tcell.ColorGreen)

    lf.SetTitle("Login")
    lf.SetTitleColor(tcell.GetColor(cfg.Theme.TitleColor))
    lf.SetTitleAlign(tview.AlignLeft)

    p := cfg.Theme.BorderPadding
    lf.SetBorder(cfg.Theme.Border)
    lf.SetBorderColor(tcell.GetColor(cfg.Theme.BorderColor))
    lf.SetBorderPadding(p[0], p[1], p[2], p[3])

    lf.updateColor()

    return lf
}

func (lf *loginForm) updateColor() {
    emailInput := lf.GetFormItem(0).(*tview.InputField)
    passwordInput := lf.GetFormItem(1).(*tview.InputField)
    codeInput := lf.GetFormItem(2).(*tview.InputField)
    checkbox := lf.GetFormItem(3).(*tview.Checkbox)

    // Log checks for the form items
    backgroundColor := tcell.ColorBlack
    textColor := tcell.ColorWhite
    checkboxColor := tcell.ColorRed

    // Check if form items exist before updating
    if emailInput != nil {
        slog.Info("Email Input: exist")
        emailInput.SetFieldBackgroundColor(backgroundColor)
        emailInput.SetFieldTextColor(textColor)
    }
    if passwordInput != nil {
        slog.Info("Password: exist")
        passwordInput.SetFieldBackgroundColor(backgroundColor)
        passwordInput.SetFieldTextColor(textColor)
    }
    if codeInput != nil {
        slog.Info("Code Input: exist")
        codeInput.SetFieldBackgroundColor(backgroundColor)
        codeInput.SetFieldTextColor(textColor)
    }
    if checkbox != nil {
        slog.Info("Checkbox: exist")
        checkbox.SetFieldBackgroundColor(backgroundColor)
        checkbox.SetFieldTextColor(checkboxColor)
    }
}

Expected Behavior

Actual Behavior

jsumners-nr commented 1 month ago

Have you tried using https://pkg.go.dev/github.com/rivo/tview#InputField.SetFieldStyle? It should look something like:

table.SetSelectedStyle(
    tcell.Style{}.
        Background(tcell.GetColor("#40ea37")).
        Foreground(tcell.ColorBlack),
)
rivo commented 3 weeks ago

The documentation for AddFormItem() explains this:

Note, however, that the Form class will override some of its attributes to make it work in the form context. Specifically, these are:

  • The label width
  • The label color
  • The background color
  • The field text color
  • The field background color

You'll want to use Form.SetFieldBackgroundColor() and Form.SetFieldTextColor(), or, even better, the new Form.SetFieldStyle() function if you want to change the appearance of the form elements.