Skip to content
buttery

v1.0.0

Source on GitHub

Version 1.0.0

Onboarding

A few steps in a dialog, with a scene that morphs between them and confetti at the end.

Onboarding is a short tour in a dialog: a scene that morphs between steps, text that crossfades in place, page dots, Back and Next, and confetti once it's finished. Use Onboarding the first time someone opens an app or a feature, for three to five steps at most.

How a tour works

  • Steps

    Each of the steps has a title, which names the dialog while it shows, a body of a line or two and a scene in media, drawn 384×200.

  • Shared pieces

    Onboarding.Shared marks a piece of a scene that carries over: a piece with the same id in the next step's scene is the same piece, moved.

  • The first visit

    With a storageKey, the tour opens by itself the first time and, once it's finished or closed, never again.

  • The last step

    The last step's button finishes the tour, and onFinish runs as the confetti flies.

The dialog keeps its size as the steps change, and Next and Back carry forward and back arrows.

Reduced motion. The scene and the text change at once, and nothing celebrates.

Onboarding

When to use it

Use it for

  • Showing a new app's three to five main ideas the first time it opens
  • A short tour someone can open again from a Help button

Not for

  • A single message: use Dialog
  • A task with inputs and steps: use a page or a form
  • Tips while working: use a Tooltip or a Callout

Examples

First run tour

A tour with a storageKey opens by itself until it's finished or closed; Start the app mounts it afresh, and Forget clears what it remembered.

Not seen yet, so it opens on the next start

Help tour

A tour kept open in state, so someone can open it again from a Help button.

Welcome screen

An empty library's first screen: Take the tour opens the steps, and finishing them changes what the screen says.

No decks yet

Take a short tour first, or start a deck right away.

Variants and states

Three steps

The slide carries over between steps on spring.smooth while the background crossfades; the text crossfades in place; Done sends up confetti.

Props

Onboarding

PropTypeDefaultDescription
steps

required

readonly OnboardingStep[]The steps, in order.
openbooleanWhether it's open. Pair with onOpenChange to control it.
defaultOpenbooleanfalseWhether it starts open when uncontrolled. Defaults to false, or to true the first time with a storageKey.
onOpenChange((open: boolean) => void)Called when it opens or closes.
storageKeystringRemembers in local storage that it was finished or closed, under this key. With one, it opens by itself the first time and never again.
onFinish(() => void)Called when the last step's button finishes it, as the confetti flies.
labelsPartial<OnboardingLabels>Words to use instead of the English ones.
refRef<HTMLDivElement>The onboarding's content inside the dialog.
classNamestringExtra classes for the onboarding's content.

Onboarding.Shared

PropTypeDefaultDescription
id

required

stringNames the piece across steps: a piece with the same id in the next step's scene is the same piece, moved.
rotatenumber0How far the piece is turned in this step, in degrees. Defaults to 0.
scalenumber1How big the piece is in this step, as a scale. Defaults to 1.

It also takes MotionElementProps<"div">.

OnboardingStep

One step of an onboarding.

FieldTypeDefaultDescription
title

required

stringThe step's title. While the step shows, it names the dialog.
body

required

ReactNodeA line or two about the step.
captionReactNodeA short note under the body, such as a keyboard tip.
media

required

ReactNodeThe step's scene, drawn 384×200. Pieces that carry over to the next step go in Onboarding.Shared.
backgroundstringThe scene's background, such as a palette gradient. It crossfades between steps.

OnboardingLabels

The words an `Onboarding` uses, for other languages.

FieldTypeDefaultDescription
back

required

stringThe button that goes back a step.
next

required

stringThe button that goes on to the next step.
finish

required

stringThe forward button's label on the last step, which finishes.
close

required

stringNames the close button.
step

required

(step: number, count: number) => stringSays which step shows, for the page dots and as each step arrives.

Also exported

ExportDescription
hasSeenOnboarding(storageKey: string): booleanWhether an onboarding with this storageKey was finished or closed before, for an app that controls when it opens: open it at first only when this is false.

Accessibility

A modal dialog named by the current step's title and described by its body. As a step arrives a polite live region says "Step 2 of 4" and its title. Back is quiet but still focusable on the first step; left and right arrows move between steps outside text fields; the finish button's label changes inside the same button, so focus stays on it. The page dots are one image naming the step. With reduced motion the scenes and text fade in 100ms and the confetti stays off.

KeysWhat they do
Right arrowGoes to the next step, unless focus is in a text field
Left arrowGoes back a step, unless focus is in a text field
Enter or SpacePresses Back or the forward button, which starts focused; on the last step it finishes with confetti and closes the dialog
EscapeCloses it, remembered under its storageKey, and puts focus back on what opened it
Tab or Shift+TabMoves between Back, the forward button and the close button, staying inside the dialog

Motion

It changes shape as one surface, on `spring.smooth`, or `spring.morph` for a big change, rather than closing and reopening.

With reduced motion: The dialog, its scenes and its text fade in 100ms, shared pieces and the page dots take their new places at once, and the confetti stays off, so the last step closes the dialog without waiting for it.

Layout

It's a 400px dialog (--bt-w-dialog), never wider than the window less 16px a side: a 384 by 200 scene inset 8px at the top, which keeps its shape as the window narrows, then the title, body and caption, the page dots, and Back and the forward button in two equal columns 48px tall (--bt-h-cta). The text wraps and the dialog's height follows it from step to step, and the forward button keeps its width when Next becomes Done.

See it in the Deckhand demo.

  • Dialog

    A modal dialog that dims the page, traps focus and hands it back when it closes.

  • PageDots

    A row of dots showing which step of a few is current, the current one a pill that moves on spring.snappy.

  • Confetti

    A short burst of confetti from an element, for a genuine finish such as completing onboarding.

  • Principles

    The ten rules every buttery animation follows, and the few things it never animates.