Skip to content
Composables

useGdTheme

The light/dark selector. Three states rather than two, because a two-state toggle silently overrides the operating system on first paint — which is the thing someone setting dark mode at 11pm is trying to avoid.

Anatomy

choice
system
resolved
light
label
System
next
light
Live. The values below are this page's own theme state — use the toggle in the bar above and they change.
Code
const { choice, resolved, toggle, icon, label, next } = useGdTheme()

Three states, and a script

  • “System” is a real state, not the absence of one. It follows the OS; light and dark PIN the choice by stamping data-gd-theme. A two-state toggle has no way to say “go back to following the OS”.
  • The boot script is not optional on a prerendered site. Reading the choice on mount is reading it after hydration, and after hydration is after paint — so a dark-pinned visitor sees the light HTML flash. GdApp injects it; nothing else needs to.
  • “System” needs no script at all. The stylesheet’s media query decides before paint by construction. Only a pin has to be stamped early.
  • Reach for resolved when something must PAINT itself — a map canvas picking a basemap cannot read a CSS variable, and needs the answer with system already collapsed.
  • Name the control by what it will DO. next exists for exactly that: “Switch to dark”, not “Theme”.

API

Returns

Props

PropTypeDefault
choiceRef<"system" | "light" | "dark">—

What the user picked. `system` is the default and follows the OS.

resolvedComputedRef<"light" | "dark">—

The theme actually in force, with `system` already resolved — for a canvas that must paint itself and cannot read a CSS variable.

toggle() => void—

Advance to the next choice: system → light → dark → system.

iconComputedRef<string>—

The glyph path for the current choice, ready for `GdIcon`'s `d`.

labelComputedRef<string>—

The current choice as a word — "System", "Light", "Dark".

nextComputedRef<string>—

The NEXT choice, lowercased, for an accessible name that says what the control will do: "Switch to dark".

Also exported

Props

PropTypeDefault
GD_THEME_BOOTstring—

The pre-paint boot script. Inject it into `<head>` at `critical` priority — `GdApp` already does. Without it a pinned dark page renders its light HTML first, every refresh.

GdThemeToggle is this composable with a button around it, and GdApp is where the boot script is injected.

Navigate

Esc