Skip to content

ThemeSwitcher

ThemeSwitcher is the controller that renders the theme chooser: a small three-button toggle (Light ☀ / Auto ⊙ / Dark 🌙) that lets the end user pick how the interface is painted. It is the companion of the LanguageSwitcher and is placed the same way — dropped into a layout region via YAML — so it can appear identically on the login page and inside the home.

How it works

Unlike the language (a server-side, per-session setting), the theme is a purely client-side preference. Picking a mode needs no round-trip and no page reload:

  1. The button sets <html data-theme="light|dark"> — or clears it for Auto, which then follows the OS prefers-color-scheme.
  2. The choice is saved in the browser as localStorage['kx_theme:<AppName>'], per application, so each KittoX app remembers its own theme.
  3. All colours and fonts are CSS custom properties (--kx-*), so the new palette applies live, instantly.

An inline script in the page <head> re-reads that key before the first paint, so a reload restores the chosen theme with no flash (anti-FOUC). See Themes for the full mechanism.

Icon style/size do not switch live

Only colours and fonts update live. IconStyle / IconSize are resolved server-side when the page is generated (the SVG icons are baked into the HTML), so they come from the shared Theme settings and do not change when the user flips the switcher.

Enabling it

The switcher is gated by two Theme settings — it renders only when the theme mode is Auto and user selection is allowed:

yaml
# Config.yaml
Theme:
  Mode: Auto             # required: with Light or Dark the palette is fixed by the admin
  UserSelection: True    # default False → switcher hidden
  • With Mode: Light or Mode: Dark the admin has fixed the palette, so the controller emits nothing — a server-side decision is not silently overridden by a client-side widget.
  • When UserSelection: True is not in effect (or ModeAuto) the controller renders nothing and its container collapses, so you can drop it in defensively.
  • To give a different palette per mode (e.g. green chrome in light, neutral slate in dark), add Light: / Dark: sub-nodes under Theme: — see Themes.

Placing it

Drop the controller into any layout region:

yaml
Controller: ThemeSwitcher

Typical placements (as in the shipped examples):

Login — in a BorderPanel region of the login dialog (e.g. SouthView under the form).

Home — in a thin topbar (NorthView) or at the bottom of the left menu, next to the LanguageSwitcher. In the examples both share a small chrome band:

yaml
Controller: BorderPanel
  Width: 230
  # … NorthView (logo), CenterView (TreePanel) …
  SouthView:
    Height: 44
    Controller: BorderPanel
      Border: False
      Header: False
      WestView:
        Width: 112
        Controller: ThemeSwitcher
      CenterView:
        Controller: LanguageSwitcher

Nested BorderPanel in the login south band

Wrapping the ThemeSwitcher and another controller in a nested BorderPanel inside the login SouthView can blow the login dialog up to full height (.kx-border-panel defaults to height: 100vh). See the workaround in Themes.

Styling

The switcher's buttons use the .kx-theme-btn class in kittox.css. It is theme-aware and adapts to its container:

  • On a chrome band (.kx-region-south) the button colour is overridden to the light chrome text, so the icons stay legible on the dark surface.
  • Elsewhere it inherits the normal text colour.

Configuration summary

KeyDefaultEffect
Theme/ModeAutoMust be Auto for the switcher to appear; Light / Dark fix the palette and hide it
Theme/UserSelectionFalseTrue renders the switcher and enables the live client-side toggle

See also

  • Themes — the full theme system: modes, per-mode palettes, fonts, icons and the anti-FOUC boot script
  • LanguageSwitcher — the companion language-chooser controller
  • Login — the login page, a common host for the switcher
  • CSS Theming — overriding individual CSS custom properties

Released under Apache License, Version 2.0.