Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelog App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
ARC UI ARC Radiant Components
v3.2 Docs Components Tokens Synthesizer
Getting StartedFrameworksServer Rendering Design TokensThemingTheme SynthesizerTypographyUtilities All ComponentsAccessibilityBrowser SupportChangelogContributingStats App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip

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. Automatically synced to localStorage and the document root `data-theme` attribute.
disabled boolean false
Prevents cycling and reduces opacity to 40%.
icon-only 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