Theme Toggle
Three-state theme toggle cycling through dark, light, and auto modes with animated icon transitions and localStorage persistence.
<arc-theme-toggle> Overview
ThemeToggle is a single-button control that cycles through the three ARC UI theme modes: dark, light, and auto (system preference). Each mode is represented by a distinct icon — a moon for dark, a sun for light, and a monitor for auto — with smooth scale-and-rotate transitions between them. The component writes the selected theme to both document.documentElement.dataset.theme and localStorage, so the choice persists across page loads without any external state management.
On first mount, ThemeToggle reads the stored preference from localStorage under the key arc-theme, falling back to the data-theme attribute on the HTML element, and then to auto if neither is set. This makes it a drop-in solution for theme switching in any ARC UI application — just place the component in your top bar or settings panel and it handles the rest.
An icon-only mode is available for compact layouts like toolbars, rendering the button as a small circle without the text label. The standard mode displays the current theme name next to the icon, capitalised, giving less experienced users a clear indication of the active state.
Guidelines
When to use
- Place ThemeToggle in a persistent location like the top bar or settings panel so users can always find it
- Use `icon-only` in dense layouts like toolbars where space is limited
- Listen to `arc-change` if you need to coordinate theme changes with a backend preference API
- Ensure your application respects the `data-theme` attribute on the document root for theme switching to work
- Set an initial `data-theme` on the HTML element during SSR to prevent flash-of-wrong-theme
When not to use
- Do not place multiple ThemeToggle instances on the same page — they will compete for localStorage and document attributes
- Do not override the localStorage key `arc-theme` from external code without also updating the component
- Do not use ThemeToggle for toggling features unrelated to visual theme — use Toggle for binary settings
- Do not hide the component behind a menu — theme switching should be easily discoverable
- Avoid using ThemeToggle in iframes without ensuring the parent document also applies the theme attribute
Features
- Three-state cycle: dark -> light -> auto -> dark, covering all common theme preferences
- Animated icon transitions with scale and rotation for visually polished mode switches
- Automatic localStorage persistence under the key `arc-theme` for cross-session retention
- Sets `data-theme` attribute on the document root for immediate application-wide theme changes
- Icon-only compact mode via the `icon-only` attribute for toolbar and header usage
- Fires `arc-change` with the new theme value on every cycle for external state coordination
- Keyboard accessible with Enter and Space key support, plus visible focus ring
- Active-press scale animation (0.95) for tactile click feedback
Preview
Usage
This component requires JavaScript. No pure HTML/CSS version is available — use the Web Component directly or a framework wrapper.
<arc-theme-toggle></arc-theme-toggle> import { ThemeToggle } from '@arclux/arc-ui-react';
export default function Example() {
return (
<ThemeToggle />
);
} <script setup>
import { ThemeToggle } from '@arclux/arc-ui-vue';
</script>
<template>
<ThemeToggle />
</template> <script>
import { ThemeToggle } from '@arclux/arc-ui-svelte';
</script>
<ThemeToggle /> import { Component } from '@angular/core';
import { ThemeToggle } from '@arclux/arc-ui-angular';
@Component({
imports: [ThemeToggle],
template: `
<arc-theme-toggle></arc-theme-toggle>
`,
})
export class MyComponent {} import { ThemeToggle } from '@arclux/arc-ui-solid';
export default function Example() {
return (
<ThemeToggle />
);
} import { ThemeToggle } from '@arclux/arc-ui-preact';
export default function Example() {
return (
<ThemeToggle />
);
} API
-
theme'dark' | 'light' | 'auto''auto' - The current theme mode. Synced in both directions: changing it — by click, by key, or by assigning the property — writes the document root's
data-themeand localStorage, and a change to that attribute from anywhere else is adopted back, so every toggle on the page agrees. -
disabledbooleanfalse - Prevents cycling and reduces opacity to 40%.
-
iconOnlybooleanfalse - Renders the button as a compact square without the theme name label, matching an icon-only arc-icon-button of the same size. Attribute name is
icon-only. -
size'xs' | 'sm' | 'md' | 'lg''md' - Box size when
icon-only, on the same scale as arc-icon-button: xs=28px, sm=32px, md=36px, lg=44px. Set both controls to the same value when they sit side by side. Ignored by the labeled form, which is sized by its text.
Events
-
arc-changedetail: { value: 'dark' | 'light' | 'auto' } - Fired when the theme is toggled, with { theme } detail