Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

huh.ThemeBase and other theme functions should accept a renderer for use in Wish #320

Open
shaunco opened this issue Jul 23, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@shaunco
Copy link

shaunco commented Jul 23, 2024

Is your feature request related to a problem? Please describe.
The current method for passing the Wish renderer to the various styles in huh is clunky, in that you call one of the theme functions (like huh.ThemeBase()), then go back and replace the renderer anywhere there are colors, as shown:

custom := huh.ThemeBase()
custom.Blurred.Title = r.NewStyle().
Foreground(lipgloss.Color("#444"))
custom.Blurred.TextInput.Prompt = r.NewStyle().
Foreground(lipgloss.Color("#444"))
custom.Blurred.TextInput.Text = r.NewStyle().
Foreground(lipgloss.Color("#444"))
custom.Focused.TextInput.Cursor = r.NewStyle().
Foreground(lipgloss.Color("#7571F9"))
custom.Focused.Base = r.NewStyle().
Padding(0, 1).
Border(lipgloss.ThickBorder(), false).
BorderLeft(true).
BorderForeground(lipgloss.Color("#7571F9"))
form.WithTheme(custom)

In addition to being awkward, it also means that any new styles added to huh must be added to the code that calls ThemeBase() and then swaps out styles.

Describe the solution you'd like
A new set of functions that accept a renderer should be added (huh.ThemeBaseWithRenderer(), huh.ThemeCharmWithRenderer, etc), and then the current functions can simply pass lipgloss.DefaultRenderer() to the new functions, such as:

func ThemeBase() *Theme {
	return ThemeBaseWithRenderer(lipgloss.DefaultRenderer())
}

func ThemeBaseWithRenderer(renderer *lipgloss.Renderer) *Theme {
	var t Theme

	t.FieldSeparator = renderer.NewStyle().SetString("\n\n")

	button := renderer.NewStyle().
		Padding(buttonPaddingVertical, buttonPaddingHorizontal).
		MarginRight(1)

	// Focused styles.
	t.Focused.Base = renderer.NewStyle().PaddingLeft(1).BorderStyle(lipgloss.ThickBorder()).BorderLeft(true)
	t.Focused.Card = renderer.NewStyle().PaddingLeft(1)
	t.Focused.ErrorIndicator = renderer.NewStyle().SetString(" *")
	t.Focused.ErrorMessage = renderer.NewStyle().SetString(" *")
	t.Focused.SelectSelector = renderer.NewStyle().SetString("> ")
	t.Focused.NextIndicator = renderer.NewStyle().MarginLeft(1).SetString("→")
	t.Focused.PrevIndicator = renderer.NewStyle().MarginRight(1).SetString("←")
	t.Focused.MultiSelectSelector = renderer.NewStyle().SetString("> ")
	t.Focused.SelectedPrefix = renderer.NewStyle().SetString("[•] ")
	t.Focused.UnselectedPrefix = renderer.NewStyle().SetString("[ ] ")
	t.Focused.FocusedButton = button.Foreground(lipgloss.Color("0")).Background(lipgloss.Color("7"))
	t.Focused.BlurredButton = button.Foreground(lipgloss.Color("7")).Background(lipgloss.Color("0"))
	t.Focused.TextInput.Placeholder = renderer.NewStyle().Foreground(lipgloss.Color("8"))

	t.Help = help.New().Styles

	// Blurred styles.
	t.Blurred = t.Focused
	t.Blurred.Base = t.Blurred.Base.BorderStyle(lipgloss.HiddenBorder())
	t.Blurred.MultiSelectSelector = renderer.NewStyle().SetString("  ")
	t.Blurred.NextIndicator = renderer.NewStyle()
	t.Blurred.PrevIndicator = renderer.NewStyle()

	return &t
}
@shaunco
Copy link
Author

shaunco commented Jul 23, 2024

For now, I just call lipgloss.SetDefaultRenderer() in teaHandler(s ssh.Session):

r := bubbletea.MakeRenderer(s)
lipgloss.SetDefaultRenderer(r)

But since this is setting a global default renderer, it means that different ssh clients can cause this to change mid-ssh session.

@caarlos0 caarlos0 added the enhancement New feature or request label Nov 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants