A toggle with color states and a drag
Build a switch that turns green and changes its label, toggles on tap, drags on and off like iOS, and exports as a React component.
A good switch answers two ways: a tap flips it, and dragging the knob flips it too, with the knob following your finger and springing into place. In this walkthrough you build one with a single On state that recolors the track and changes the label, a tap trigger and two drag triggers, then export a working React component. About fifteen minutes.
| You'll use | Where |
|---|---|
| States with colors and text | States, Record a state |
| Tap and drag triggers | Drag and scroll triggers |
| Interactive preview | Interactive in the transport bar |
| Motion (React) export | Render (⌘E) |
1. Make the switch
- Press ⌘N and send: “A toggle switch: a 64 × 36 fully rounded track in #D1D1D6, a white 30 pt circle knob inset 3 pt on the left with a soft shadow, and a label ‘Off’ to the right of the track. Group track and knob as ‘Toggle’. No entrance, everything at rest.”
- Check the layers: a Toggle group with Track and Knob, and a Label text layer. Rename a layer by double-clicking it in the Layers tab if the names differ.
- The timeline's end is the switch's Default state: off.
2. Record the On state
- Open the Interactions tab and click Add state. The new state starts recording; the stage shows Editing state: State.
- Select Knob and press ⇧→ three times (30 pt), then ← twice, so it moves 28 pt to the right end of the track.
- Select Track. In the inspector's Fills, click the color and pick green (#34C759).
- Double-click Label on the stage and type
On. Click outside to finish. - Press ⇧⌘↩ to stop recording. The row reads “3 values”: the knob's x, the track's fill and the label's text.
- Right-click the state → Rename… →
On. Click the row and set the curve to Spring · snappy.
3. Tap to toggle
- Select the Toggle group.
- Click + next to Triggers. EaseKit adds Tap on Toggle → Go to On.
- Change the action from Go to to Toggle. A tap now switches to On, and a second tap goes back to Default.
4. Drag the knob
- Select Knob and click + next to Triggers again.
- Set the event to Drag. In the second row, set the axis to Horizontal and the distance to Past 20 pt.
- Set the action to Go to, the state to On, and the gate to Only in Default.
- Add one more trigger on Knob: Drag, Horizontal, Past −20 pt, Go to Default, Only in On.
| When | on | Options | Action | State | Only in |
|---|---|---|---|---|---|
| Tap | Toggle | Toggle | On | ||
| Drag | Knob | Horizontal, Past 20 pt | Go to | On | Default |
| Drag | Knob | Horizontal, Past −20 pt | Go to | Default | On |
5. Try it
- Click Try it on the stage. The bar says “Hover, press, tap and drag the layers”.
- Tap the switch: the knob slides, the track turns green and the label reads On. Tap again to go back.
- Drag the knob to the right and let go past the middle: it glides into the On position from where you dropped it. Drag it back to the left to turn it off.
- Let go early: the knob springs back to where it rests.
- Click Interactive in the bar to return to editing.
6. Export to React
- Press ⌘E. Under Other formats, click Motion (React) (“.tsx · interactive component”) and save
Toggle.tsx. - In your project, install Motion and use the component:
npm i motionimport Toggle from "./Toggle";
export default function Settings() {
return <Toggle />;
}The knob gets Motion's drag="x" with dragSnapToOrigin and an onDragEnd that checks the distance and the current state; the track's color and the label's text are looked up by state. HTML (and so a share link) works the same with pointer listeners, and SwiftUI uses a DragGesture.
Variations
- Hover: select the group and click Add hover for a gentle lift.
- As a component: turn the switch into a component with a
state: off | onvariant set and switch it with Set variant; every copy in a settings list then tweens on its own (see Animated variant switches). - Swipe to dismiss: a card with Drag, Free, Past 80 pt → a state where it's off-screen and faded out.
- Scroll-linked: a Scroll progress trigger scrubs the timeline as the page scrolls, for a header that shrinks.