Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelog App ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip
ARC UI ARC Radiant Components
v4.2 Docs Components Tokens Synthesizer
Getting StartedFrameworksServer Rendering Design TokensThemingTheme SynthesizerTypographyUtilities All ComponentsAccessibilityBrowser SupportChangelogContributingStats App ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip

Theme Toggle

Three-state theme toggle cycling through dark, light, and auto modes with animated icon transitions and localStorage persistence.

Components Theme Toggle
input interactive
<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-theme and localStorage, and a change to that attribute from anywhere else is adopted back, so every toggle on the page agrees.
disabled boolean false
Prevents cycling and reduces opacity to 40%.
iconOnly boolean false
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-change detail: { value: 'dark' | 'light' | 'auto' }
Fired when the theme is toggled, with { theme } detail

See Also