Theme Toggle

A dithered “hand of god” Theme toggle. Hands slide in, meet at the center, the theme changes with circular View Transition, then retreat. Uses next-themes.

Default

Click the trigger to watch the hands slide in and flip the theme. Honors prefers-reduced-motion.

Installation

$ npx shadcn add https://knot-ui.trupal.me/r/hand-toggle.json

Customization

Tune the dither resolution, cell size, and colors via props.

Props

Props

PropTypeDefaultDescription
leftImagestring"/left.png"URL of the image used for the left hand. Falls back to a drawn hand if missing.
rightImagestring"/right.png"URL of the image used for the right hand (mirrored). Falls back to a drawn hand if missing.
columnsnumber100Dither resolution — number of columns used to render each hand.
cellSizenumber10Pixel size of each dither cell before scaling.
lightColorstring"#111111"Dither color used when the light theme is active.
darkColorstring"#eaeaea"Dither color used when the dark theme is active.
travelDistancenumber—Override how far the hands slide in from the edges. Defaults to half the viewport width plus the pair width.
gapnumber10Gap (px) between the two hands at the center meet point.
classNamestring—Classes applied to the overlay layer that holds the hands.
triggerClassNamestring—Classes applied to the trigger button.
childrenReact.ReactNode<Sun /> / <Moon />Custom trigger content. Defaults to a lucide Sun icon in dark mode and a Moon icon in light mode (shadcn-style).
onToggle(isDark: boolean) => voidundefinedCallback fired after a toggle. Use together with isDark for fully controlled theming.
isDarkbooleanundefinedControlled dark state. When provided the component never manages theme itself.