Skip to content
WANCRAFT

A.184Buttons & Controls

Scene Switch

An illustrated day / night switch: the sun springs across a tiny sky and turns into the moon.

NewReactMotionSVGCSSTailwindintermediate

Overview

Scene Switch is an on / off switch whose track is a small illustrated sky drawn in SVG and CSS. By day a warm sun disc sits beside soft layered clouds; toggle it and the disc springs across, cross-fades into a cratered moon as the craters roll in, the clouds sink away and a field of stars drifts down and begins to twinkle. Light halos travel with the disc. It is a real <button role="switch"> with aria-checked and a visible or aria label, so it works for any setting, not just a site theme. The star twinkle uses the Web Animations API and pauses offscreen, in hidden tabs and for reduced motion. Controlled or uncontrolled, in three sizes, and either scene can mean "on".

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/scene-switch.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/scene-switch.json

Method 02 · Copy and paste

  1. 1. Install the dependencies below.
  2. 2. Copy the source from the Code tab into components/ui/scene-switch.tsx.
  3. 3. Import it and adjust props.
npm install motion
Dependencies
motion
Peer
react ≥ 18, tailwindcss ≥ 4
Added
13 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { SceneSwitch } from "@/components/ui/scene-switch";

export function SceneSwitchExample() {
  return (
    <SceneSwitch onCheckedChange={(on) => console.log(on)} />
  );
}

03Props

PropTypeDefaultDescription
checkedboolean—Controlled state. Pair with onCheckedChange.
defaultCheckedbooleanfalseInitial state when uncontrolled.
onCheckedChange(checked: boolean) => void—Called with the next state on every toggle.
labelstring"Night mode"Names the switch: a visible <label> or, with showLabel off, the aria-label.
showLabelbooleantrueRender the label next to the switch.
labelPosition"start" | "end""end"Side the label sits on.
checkedScene"night" | "day""night"Which scene represents on.
size"sm" | "md" | "lg""md"Track size: 56 × 30, 76 × 40 or 100 × 52 px.
twinklebooleantrueTwinkle the stars at night (paused offscreen, in hidden tabs and for reduced motion).
spring{ stiffness: number; damping: number; mass: number }{ stiffness: 380, damping: 26, mass: 0.9 }Spring for the disc's travel.
accentstring"#FF7448"Focus ring colour.
...propsButtonHTMLAttributes—Forwarded to the <button> (disabled, aria-*, handlers); ref is forwarded.

04Features

  • 01Illustrated SVG sky: sun, halos and layered clouds by day; cratered moon and stars by night
  • 02Disc travels on a configurable spring and morphs from sun to moon
  • 03Clouds sink and stars drift in on their own springs
  • 04Star twinkle via the Web Animations API, paused offscreen and in hidden tabs
  • 05Generic: any label, either scene can mean on, controlled or uncontrolled, three sizes
motion · springmotion · tweenmotion · continuousinput · clickinput · keyboardinput · focus

05Accessibility

  • Native <button role="switch"> with aria-checked; Space and Enter toggle it.
  • Named by a visible <label htmlFor> (clicking it toggles) or, with showLabel off, by aria-label.
  • All artwork is aria-hidden; the state is conveyed by aria-checked, not by the picture.
  • Visible focus-visible ring in the accent colour; disabled state is native.
  • Reduced motion: the disc and scenery switch instantly and the stars stay still.