Tutorials · Animate a Figma button with Auto Layout
Documentation

Animate a Figma button with Auto Layout

Import a button component set from Figma, let its Default, Hover and Pressed variants switch on hover and press, watch an icon appear while the label reflows, and export React.

A good hover state often changes the layout: an arrow slides in and the label makes room. In Figma that's two variants of an Auto Layout frame; in EaseKit it becomes a real animation, because the layout is solved at every frame. In this walkthrough you import a button component set, try its hover and press on the stage, tune the switch and export a working React component. About fifteen minutes.

1. Prepare the button in Figma

Use a button you already have, or make one in two minutes:

  1. Make a frame with a text layer “Get started” and an arrow icon to its right. Add Auto Layout (horizontal, gap 8, padding 12 × 20, hug on both axes) and give it a fill and a full radius.
  2. Turn it into a component named Button, then add variants: a property State with the values Default, Hover and Pressed.
  3. In Default, hide the arrow. In Hover, show it. In Pressed, show it and make the fill a little darker.
  4. Optional: make the label a text property called Label, so each instance can have its own text.

2. Import the component set

  1. If you haven't yet, connect Figma: a personal access token with File content: Read-only, pasted in Settings → Providers → Figma.
  2. In Figma, select the component set (the dashed frame around the variants), right-click and choose Copy link to selection.
  3. In EaseKit, press ⌘N for a fresh session, then choose File → Import from Figma… (⇧⌘F). The link from the clipboard is already filled in; click Import. (With a scene on the stage, clicking the stage and pressing ⌘V does the same.)
  4. The notice reads “Imported “Button” from Figma · … layers”. The stage shows one instance of the Default look on a dark canvas, with room around it to grow.
The imported button: one instance, its component with State variants, and the triggers

3. Look at what came in

  • The component: the component library (Stage → Show Components) lists Button with its variant set State: Default, Hover, Pressed. The default variant is the base; the other two are stored as their differences.
  • The triggers: the Interactions tab shows Hover → Set variant State: Hover, Hover end → Default, Press → Pressed and Release → Hover.
  • The layout: double-click the instance to open the component. Its group has the ↔ badge in the timeline, and its Auto Layout section reads Horizontal, Gap 8, Width and Height Hug.
  • The children: select the label: In Auto Layout shows Hug. The background layer (the frame's fill and radius) has Absolute position, so it stretches with the group instead of taking a slot.

Press Done in the stage pill (or esc with nothing selected) to go back to the scene.

4. Try it

  1. Click Interactive in the transport bar.
  2. Hover the button. The arrow collapses in, the label slides left to make room, and the pill grows around both, all in one motion.
  3. Press and hold: the fill darkens. Release, then move away: the button settles back to Default.
  4. Move in and out quickly. Each switch starts from wherever the last one was, like real UI.
Hover: the arrow appears, the label reflows and the pill grows

5. Tune the switch

  1. Select the instance. In the inspector's Variants section, set Transition to Bouncy spring for a playful button, or Smooth spring for a calm one.
  2. Try it again with Interactive.
  3. To change the spacing, open the component and set Gap to 10 in Auto Layout. Every variant follows.

6. Change the label

  1. If you made the Label text property, select the instance and type a longer text in its Props, for example “Start your free trial”.
  2. The pill hugs the new text at once, in every variant, and the hover still makes room for the arrow.

7. Export to React

  1. Press ⌘E to open Render. Under Other formats, click Motion (React) and save Button.tsx.
  2. In your project, install Motion and use the component:
npm i motion
import Button from "./Button";

export default function Hero() {
  return <Button />;
}

The button's group is a flexbox container, so the browser does the reflow: when the arrow appears, the label moves and the pill grows natively. The variant switch animates with Motion on hover and press, and the State set is a typed string prop.

Variations

  • A loading state: add a variant Loading in Figma with a spinner instead of the label, re-import, and ask the AI: “on tap, switch to Loading, then back to Default after 1.5 s”.
  • A chip row: import a horizontal Auto Layout frame of chips and animate one chip's width; the others slide along. See Auto Layout.
  • Fade a child out of a row: turn on Collapse when hidden for it and fade its opacity to 0; the gap closes as it fades.
  • From Claude: “Import this Figma button into EaseKit with import_figma and make the hover bouncier.”