Implement a dark-mode toggle

Add ToneSwitch or ToneChangerButton, persist the choice with persistTheme, and handle tone-aware images.

Users expect to switch between light and dark modes. XMLUI provides ToneSwitch — a drop-in toggle that flips the active tone — and App properties to remember the choice across visits.

<App defaultTone="light" autoDetectTone="{true}">
  <AppHeader>
    <SpaceFiller />
    <ToneSwitch iconLight="sun" iconDark="moon" />
  </AppHeader>
  <VStack>
    <Card title="Dashboard" subtitle="Your analytics at a glance">
      <ProgressBar value="0.72" />
      <HStack>
        <Badge value="Active" />
        <Text variant="secondary">Last updated: today</Text>
      </HStack>
    </Card>
    <HStack>
      <Button label="Primary action" variant="solid" themeColor="primary" />
      <Button label="Secondary" variant="outlined" themeColor="secondary" />
      <Button label="Danger" variant="solid" themeColor="attention" />
    </HStack>
  </VStack>
</App>
Dark-mode toggle with ToneSwitch
<App defaultTone="light" autoDetectTone="{true}">
  <AppHeader>
    <SpaceFiller />
    <ToneSwitch iconLight="sun" iconDark="moon" />
  </AppHeader>
  <VStack>
    <Card title="Dashboard" subtitle="Your analytics at a glance">
      <ProgressBar value="0.72" />
      <HStack>
        <Badge value="Active" />
        <Text variant="secondary">Last updated: today</Text>
      </HStack>
    </Card>
    <HStack>
      <Button label="Primary action" variant="solid" themeColor="primary" />
      <Button label="Secondary" variant="outlined" themeColor="secondary" />
      <Button label="Danger" variant="solid" themeColor="attention" />
    </HStack>
  </VStack>
</App>

Key points

<ToneSwitch />: A ready-made ToneSwitch control that toggles the active tone between "light" and "dark". Place it anywhere — typically in the <AppHeader> — and it works immediately with no wiring:

<AppHeader>
  <SpaceFiller />
  <ToneSwitch />
</AppHeader>

iconLight / iconDark: Customize the icons displayed for each state. Defaults are "sun" and "moon":

<ToneSwitch iconLight="sun" iconDark="moon" />

defaultTone on <App>: Sets the initial tone before any user interaction. Accepts "light" or "dark":

<App defaultTone="dark">

autoDetectTone: When set to true, the app follows the operating system's prefers-color-scheme setting on first load. Once the user clicks ToneSwitch, their explicit choice takes precedence:

<App autoDetectTone="{true}">

Scoped dark sections with <Theme tone="dark">: If you need a permanently dark region (for example a sidebar) without affecting the rest of the page, wrap that section in a <Theme> with an explicit tone attribute:

<Theme tone="dark">
  <VStack backgroundColor="$backgroundColor-primary">
    <Text>This section is always dark</Text>
  </VStack>
</Theme>

See also