Skip to content

Icons

The theme supplies the icons widgets draw: the arrow on a back button, the check mark in a checkbox, the clear button in a search field. You can use the same icons in your own widgets, so they change along with the theme.

Use a theme icon

Each icon has a name, a bellui.ThemeIconName constant such as theme.IconNameHome. There are two ways to get it:

// Two ways to get the same icon from the current theme.
home := theme.HomeIcon()
settings := theme.Icon(theme.IconNameSettings)

toolbar := container.NewHBox(
	widget.NewButtonWithIcon("Home", home, func() {}),
	widget.NewButtonWithIcon("Settings", settings, func() {}),
	widget.NewIcon(theme.Icon(theme.IconNameNavigateBack)),
)
  • theme.Icon(name) looks the name up in the current theme.
  • The shortcut functions, such as theme.HomeIcon(), theme.SettingsIcon() or theme.DeleteIcon(), do the same for one icon each.

The theme package reference lists every IconName… constant. They cover common actions (add, remove, copy, paste, undo, search), files and folders, media controls, mail, navigation, visibility, volume, zoom and window controls.

Theme icons are SVG images. Most are drawn in the theme’s foreground colour, so they are dark in the light variant and light in the dark variant.

Directional icons

Some icons point in a reading direction: navigate back and next, the submenu arrow, and mail reply, reply all and forward. When the app’s layout is right-to-left, the theme draws these icons mirrored. Other icons, such as search or settings, are never mirrored. See Right-to-left layout.

Colour your own icons

To make your own SVG icon follow the theme, wrap it in a themed resource. The wrapper replaces the SVG’s fill colours with a theme colour each time it is drawn:

var (
	// A 24x24 SVG drawn in black. A themed resource replaces its fill
	// colour with a theme colour, so it matches light and dark variants.
	starSVG = bellui.NewStaticResource("star.svg", []byte(
		`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">`+
			`<path fill="#000000" d="M12 17.3 18.2 21l-1.6-7L22 9.2l-7.2-.6L12 2 9.2 8.6 2 9.2 7.4 14l-1.6 7z"/>`+
			`</svg>`))

	star        = theme.NewThemedResource(starSVG)        // foreground colour
	primaryStar = theme.NewPrimaryThemedResource(starSVG) // primary colour
	errorStar   = theme.NewErrorThemedResource(starSVG)   // error colour
)
ConstructorColour
theme.NewThemedResourceforeground
theme.NewPrimaryThemedResourceprimary
theme.NewErrorThemedResourceerror
theme.NewSuccessThemedResourcesuccess
theme.NewWarningThemedResourcewarning
theme.NewDisabledResourcedisabled
theme.NewColoredResourceany colour name you pass

This works for SVG icons only. For anything that is not SVG, the wrapper logs an error and draws the image with its own colours.

Replace icons in a custom theme

A custom theme’s Icon method can return a different resource for any icon name. Widgets that use that icon then draw yours. For an example, see the Icon method in Custom themes. In a JSON theme, the Icons object maps icon names to resource URIs.

Return a themed resource from Icon if your replacement should follow the theme colours like the built-in icons do.

The full program:

// Theme icons: looking them up, using them in widgets, and colouring your
// own SVG icon so it follows the theme.
package main

import (
	"github.com/belluikit/bellui"
	"github.com/belluikit/bellui/app"
	"github.com/belluikit/bellui/container"
	"github.com/belluikit/bellui/theme"
	"github.com/belluikit/bellui/widget"
)

var (
	// A 24x24 SVG drawn in black. A themed resource replaces its fill
	// colour with a theme colour, so it matches light and dark variants.
	starSVG = bellui.NewStaticResource("star.svg", []byte(
		`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">`+
			`<path fill="#000000" d="M12 17.3 18.2 21l-1.6-7L22 9.2l-7.2-.6L12 2 9.2 8.6 2 9.2 7.4 14l-1.6 7z"/>`+
			`</svg>`))

	star        = theme.NewThemedResource(starSVG)        // foreground colour
	primaryStar = theme.NewPrimaryThemedResource(starSVG) // primary colour
	errorStar   = theme.NewErrorThemedResource(starSVG)   // error colour
)


func main() {
	a := app.New()
	w := a.NewWindow("Icons")

	// Two ways to get the same icon from the current theme.
	home := theme.HomeIcon()
	settings := theme.Icon(theme.IconNameSettings)

	toolbar := container.NewHBox(
		widget.NewButtonWithIcon("Home", home, func() {}),
		widget.NewButtonWithIcon("Settings", settings, func() {}),
		widget.NewIcon(theme.Icon(theme.IconNameNavigateBack)),
	)

	w.SetContent(container.NewVBox(
		toolbar,
		container.NewHBox(widget.NewIcon(star), widget.NewIcon(primaryStar), widget.NewIcon(errorStar)),
	))
	bellui.ShowAndRun(w)
}