Skip to content
Native Animation
Sun Moon Toggle animation preview

Sun Moon Toggle

A tactile day-to-night switch that sends a circular theme reveal across a complete appearance screen.

$9 for this animation

Checkout opens soon. Leave your email and we will tell you the moment you can buy it.

One email when checkout opens. No spam.

Add to your project

Copy the component and its assets into your app with the Native Animation CLI, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

npx nativeanimation add sun-moon-toggle

About this animation

A tactile day-to-night switch that sends a circular theme reveal across a complete appearance screen.

Why this one

Most theme toggles stop at recoloring a small track or fading the page. This version makes the switch the physical source of the change: one continuous progress value moves the thumb, rolls the sun into a crescent moon, clears the clouds, staggers eight stars, and expands the dark surface from the thumb across the whole composition. The surrounding preview and settings make the interaction feel like a real product decision instead of an isolated control.

How it works

  1. A single Reanimated shared value represents the full light-to-dark range and remains directly draggable.
  2. Releasing the gesture projects its velocity toward light or dark, then settles with a configurable-feeling spring tuned to damping 16 and stiffness 180.
  3. Track color, clouds, stars, thumb travel, sun rotation, lunar cutout, craters, and screen materials are derived from that same progress.
  4. A screen-sized circle is centered on the thumb and scales with progress, producing the signature radial theme wipe without a rectangular overlay.
  5. A forwarded ref exposes toggle() and setDark() for onboarding, previews, and autoplay.

Icons: Lucide (ISC).

Install

npx expo install expo-image expo-linear-gradient @shopify/react-native-skia react-native-gesture-handler react-native-reanimated react-native-worklets

Usage

import SunMoonToggle from './SunMoonToggle';

export function AppearanceScreen() {
  return <SunMoonToggle previewImage={require('./photo.jpg')} />;
}

Customize the content and typography:

<SunMoonToggle
  brandName="Northwind"
  previewImage={require('./coast.jpg')}
  previewTitle="Coastal light"
  previewMeta="Travel collection"
  previewDetail="18 photographs · Updated today"
  settings={[
    { icon: 'type', label: 'Text size', value: 'Large' },
    { icon: 'bell', label: 'Alerts', value: 'Highlights only' },
    { icon: 'lock', label: 'Private previews', value: 'On' },
  ]}
  fontFamily="Geist-Regular"
  mediumFontFamily="Geist-Medium"
  titleFontFamily="InstrumentSerif-Regular"
  onValueChange={(dark) => setDark(dark)}
/>

Props

PropTypeDefaultDescription
valuebooleanUncontrolledControlled dark-theme value.
defaultValuebooleanfalseInitial value when uncontrolled.
onValueChange(dark: boolean) => void—Called after a press or drag chooses a theme.
titlestring'Appearance'Screen heading.
brandNamestring'Studio'Name beside the aperture tile.
previewImageImageSourcePropTypeGradient fallbackPreview photograph.
previewTitlestring'Quiet geometry'Preview title.
previewMetastring'Editorial collection'First preview detail.
previewDetailstring'12 photographs · Updated today'Second preview detail.
settingsAppearanceSetting[]Three defaultsUp to three setting rows using type, bell, or lock.
lightBackgroundColorstring'#F6F5F2'Light screen color.
darkBackgroundColorstring'#0B0D14'Dark reveal color.
lightTextColorstring'#18181B'Light-theme foreground.
darkTextColorstring'#F4F4F7'Dark-theme foreground.
fontFamilystringSystem fontInterface copy family.
mediumFontFamilystringSystem fontLabels and values family.
titleFontFamilystringSystem fontMain heading family.
accessibilityLabelstring'Use dark appearance'Switch label for screen readers.
styleStyleProp<ViewStyle>—Full-screen container style.
testIDstring—Test identifier.

The forwarded ref exposes toggle() and setDark(dark).

Compatibility

  • Expo SDK 57
  • React Native 0.86
  • Reanimated 4.5 and Worklets 0.10
  • Skia 2.6
  • iOS: supported, not yet verified on a device
  • Android: supported, not yet verified on a device
  • Web: supported, pending visual verification
  • Works in Expo Go with the SDK-bundled native modules

Accessibility

The switch exposes its checked state, a 120 × 56 point hit area, and a tap alternative to dragging. Screen-reader activation can also reverse the selected appearance. Reduced Motion removes the spring, rolling, cloud travel, star stagger, and radial growth, applying the final theme immediately.