AnimatedThemeToggler
animated-theme-togglerSwitches color themes through an animated icon transition.
Usage
Basic usage
Click the button to switch light and dark themes with a circular reveal animation (reusing Hulian ThemeProvider).
<AnimatedThemeToggler />Custom animation duration
duration Adjust the circular reveal animation duration (ms), default 500.
<AnimatedThemeToggler duration={900} />Matching description copy
The switcher is a standard button that can be placed alongside other elements in the toolbar.
<div className="flex items-center gap-3">
<AnimatedThemeToggler />
<span className="text-sm text-muted-foreground">Click: Circle Reveal Switch Light and Dark</span>
</div>When to use
Use AnimatedThemeToggler for a header or settings control that switches light and dark themes with a circular reveal radiating from the button. For an unanimated switch or custom control, compose directly with useTheme().
Import
import { AnimatedThemeToggler } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
theme | "light" | "dark" | - | Controlled theme. When set, the button's state and target are driven by this value, ignoring ThemeProvider / the standalone fallback; clicks only call onThemeChange. |
onThemeChange | (next: "light" | "dark") => void | - | Called with the next theme when a switch is requested. Fires in both modes; in controlled mode it is the only place the value lands. |
duration | number | 500 | Circular reveal duration in milliseconds. |
className | string | - | Button class name. |
aria-label | string | - | Accessible label. |
Without aria-label, the button uses built-in Chinese state-dependent copy: "\u5207\u6362\u5230\u4eae\u8272" (“Switch to light”) in dark mode and "\u5207\u6362\u5230\u6697\u8272" (“Switch to dark”) otherwise.
Example
<AnimatedThemeToggler aria-label="Toggle light and dark theme" />
// Controlled: the theme source of truth lives with the consumer (API / own storage);
// ThemeProvider only mirrors it via forcedTheme
<AnimatedThemeToggler theme={theme} onThemeChange={(next) => savePreference(next)} />Usage guidelines
- The circular reveal uses the View Transitions API. Unsupported browsers switch instantly while preserving the theme change.
- The button position determines the reveal origin, so this is a client component. Use it below a
"use client"boundary in an RSC tree. - Without
ThemeProvider, the component no longer throws. It falls back to local state, reads and writes<html data-theme>, uses thehulian-themelocalStorage key, and warns in development. This fallback does not synchronize with otheruseThemeconsumers; production applications should still installThemeProvider. - Controlled mode (#284). With
ThemeProvider forcedTheme,togglewrites the preference without changing the visual theme, so an uncontrolled toggler plays the reveal but nothing switches. When the theme source of truth is outside the library (shell + iframes each mounting aforcedThemeprovider fed from one place), passtheme+onThemeChange: the circular reveal is unchanged, only where the value lands is up to the consumer. Controlled mode never touchesuseTheme().toggleand never enters the standalone fallback. - Use
useThemewhen application code must fail without a provider. Library components and tolerant integrations can useuseThemeOptional, which returnsnullwithout context.
Related
Default toggle labels follow ConfigProvider (zhCN / enUS); an explicit aria-label always wins.
Command · ContextMenu · Toolbar · Accordion · Collapsible · Link