Skip to content
Native Animation
Drawn Checkbox animation preview

Drawn Checkbox

A tactile 24-point checkbox with a center-out spring fill, a hand-drawn mark, and an animated label strike-through.

Free
Get it free with your email

No password and no card: we email you a sign-in link, then the full source is yours.

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 drawn-checkbox

About this animation

A tactile 24-point checkbox with a center-out spring fill, a hand-drawn mark, and an animated label strike-through.

How it works

  1. A clipped Skia circle expands from the center with an interruptible spring.
  2. Path end reveals the check or mixed-state dash with rounded caps and joins.
  3. The same progress value attenuates the label and draws a measured strike-through from left to right.
  4. Unchecking reverses the path before the background contracts.
  5. Press feedback starts on touch-down, while a brief halo emphasizes completion.

Why this one

Most checkbox demos stop at the box. This one treats the full task row as a coordinated state change: tactile press feedback, a center-out material fill, a precisely drawn mark, and a strike-through that follows the real label width. The included onboarding demo adds a spring-driven progress bar and a restrained “All set” payoff without changing the reusable component API.

Install

npx expo install @shopify/react-native-skia expo-linear-gradient react-native-reanimated

For web, follow Expo's Skia CanvasKit setup if your bundler does not already copy the WASM asset.

Usage

<DrawnCheckbox label="Connect your calendar" defaultChecked />

<DrawnCheckbox checked={accepted} onChange={setAccepted} color="#17A673" duration={320} />

<DrawnCheckbox colorScheme="dark" glowColor="#6E56FF" label="Invite a teammate" />

Props

PropTypeDefaultDescription
checkedboolean—Controlled checked state.
defaultCheckedbooleanfalseInitial uncontrolled state.
indeterminatebooleanfalseShows a mixed-state dash.
onChange(checked: boolean) => void—Receives requested state.
labelstring—Pressable label.
sizenumber24Box size.
radiusnumber7Corner radius.
colorstring'#6E56FF'Active color.
borderColorstring'#B8B5C4'Inactive border color.
colorScheme'light' | 'dark' | 'auto''auto'Material and default-label appearance.
glowColorstringcolorCompletion halo color.
markColorstring'#FFFFFF'Check or dash color.
durationnumber240Drawing duration in milliseconds.
labelColorstringTheme contrast colorExplicit label color.
fontFamilystringSystem fontLabel font family.
accessibilityLabelstringLabel or 'Checkbox'Screen-reader label.
styleStyleProp<ViewStyle>—Outer style.
labelStyleStyleProp<TextStyle>—Label style.
testIDstring—Test identifier.

The ref exposes toggle() and setChecked(checked).

Compatibility

  • Expo SDK 57, React Native 0.86, Reanimated 4.5, Skia 2.6
  • iOS and Android supported but not device-verified; web verified by the project gate
  • Works in Expo Go

Accessibility

The full row exposes the checkbox role and boolean or mixed checked state. Labels keep high contrast in either theme. Reduced Motion completes fill, mark, strike-through, and completion feedback immediately.

Source code

Free with an account

Sign in with your email to read the full source here, or install it in one command with the CLI.

Get it free