Theme setting
ProThe person's control for the theme: "Match my system", "Light", "Dark" or "High contrast", on its own, for an app with no profile page (ProfileSettings draws the same control). It stores and applies nothing: the choice goes back through onValueChange, and the app keeps it and puts it on the page, as data-theme="light", "dark" or "hc" on <html> (no attribute for "Match my system", which follows the system's setting). Nothing is chosen for the person: without a value it shows "Choose a theme".
<ThemeSetting value={settings.theme} onValueChange={(theme) => setSettings({ ...settings, theme })} />An app without a high-contrast theme leaves that choice out: choices={["system", "light", "dark"]}. If it stored a theme that isn't among them, the control still reads "Choose a theme" and its description names the theme in force ("Using High contrast").
Version 5.2.0· other versions
This page is for 5.2.0, the current release. An earlier release’s page is the Markdown that release published, so the docs match the version you have installed (candor-lock.json records it).
Not in the docs of 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.9.1, 2.0.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 2.5.0, 2.5.1, 2.6.0, 2.6.1, 2.6.2, 2.7.0, 2.8.0, 2.9.0, 2.10.0, 3.0.0, 4.0.0, 4.0.1, 4.0.2, 4.1.0 and 4.2.0: the page came later, or had another name then.
Docs pages weren’t kept for 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0 and 1.2.1: they are kept from 1.3.0 on, and before that only llms.txt was published.
Preview
Loading the preview
Install
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/theme-setting
Usage
"use client"
import * as React from "react"
import { ThemeSetting, type ThemeChoice } from "@/components/candor/theme-setting"
/*
* The app keeps the choice (here in state; in an app, with the person's settings) and puts it on the page: data-theme
* on <html>, or no attribute for "Match my system". This example keeps it in a sentence, so the docs page's own theme
* stays as it is.
*/
export default function Example() {
const [theme, setTheme] = React.useState<ThemeChoice | undefined>(undefined)
return (
<div className="flex max-w-xs flex-col gap-3 text-sm">
<ThemeSetting value={theme} onValueChange={setTheme} />
<p className="text-xs text-muted-foreground">
{theme === undefined ? "Nothing chosen yet." : theme === "system" ? "No data-theme attribute: the page follows the system." : `data-theme="${theme}" on <html>.`}
</p>
</div>
)
}<ThemeSetting>
| Prop | Type | Default | Description |
|---|---|---|---|
| value | ThemeChoice | undefined | — | The person's choice as the app last stored it. Left out, nothing is chosen and the control says "Choose a theme". |
| onValueChangerequired | (next: ThemeChoice) => void | — | Called with the choice when the person picks one. |
| label | string | undefined | — | The words above the control. Defaults to "Theme". |
| optionLabels | Partial<Record<ThemeChoice, string>> | undefined | — | The options' words, where the app keeps them somewhere other than `themeSetting` (ProfileSettings passes its own). |
| choices | readonly ThemeChoice[] | undefined | — | The choices to offer, for an app that doesn't have all four themes. Defaults to all four. They're listed in the usual order (system, light, dark, high contrast) whatever order they're given in; an empty list offers all four. A `value` that isn't among them shows as nothing chosen ("Choose a theme"), so the person picks one of the choices offered; the app goes on applying what it stored until they do. |
| locked | string | null | undefined | — | Why the theme can't be changed now (the organisation sets it). The control stays focusable and says why. |
| className | string | undefined | — | Classes for the wrapper, merged with Candor's. |
Strings
The fixed words, in English by default. Change any of them under themeSetting in <LocaleProvider strings={{ … }}>; the table is exported as themeSettingStrings.
| Key | English |
|---|---|
| label | Theme |
| placeholder | Choose a theme |
| system | Match my system |
| light | Light |
| dark | Dark |
| hc | High contrast |
| using | Using {theme} |
Types
- ThemeChoice
- The person's theme: follow the system's light or dark, or always light, dark or high contrast.
"system" | "light" | "dark" | "hc"