blockmotion
Steps (motion)
Steps arrive in order, the one place a stagger carries meaning.
Wraps the static Steps, which renders identically with JavaScript disabled.
Preview
Installation
pnpm dlx shadcn@latest add https://facadeui.dev/r/steps-motion.jsonPulls in motion-primitives, steps. The CLI installs them for you.
Usage
The exact source of the preview above.
"use client"
/**
* The `steps` demo, with the motion variant swapped in.
*
* Identical props: the motion variant only changes which slot components
* the static section renders through.
*
* `"use client"` is required here, not incidental: the motion variant is a
* client component, and icon components cannot cross a server-to-client
* boundary as props. See the note on `IconComponent`.
*/
import { StepsMotion } from "@registry/sections/steps-motion"
import { STEPS } from "./content"
export function Demo() {
return (
<StepsMotion
eyebrow="Getting started"
title="From nothing to a landing page"
description="An ordered list, so a screen reader already announces 'step 2 of 3' without the numeral being read twice."
items={STEPS}
/>
)
}Source
What the CLI copies into your project, byte for byte.
"use client"
/**
* StepsMotion — the numbered sequence with a staggered entrance.
*
* Steps arrive in order, which is the one place a stagger carries meaning rather than decoration.
*
* A genuine wrapper: it renders the static `Steps` and only swaps the list
* slots, so no markup, styling or accessibility behaviour is duplicated.
*
* The list slot renders an `ol` rather than a `ul`, because the sequence is the
* content — which is also why the stagger belongs here at all. The item slot
* still renders an `li`: an `ol` may only contain list items, and a `div` there
* is invalid markup that axe reports as `list`.
*
* Dependencies: react, @/components/motion/slots, @/components/motion/stagger,
* @/components/sections/steps.
*/
import type { ReactNode } from "react"
import { StaggerListItem } from "@/components/motion/slots"
import { Stagger } from "@/components/motion/stagger"
import { Steps, type StepsProps } from "@/components/sections/steps"
function StaggerOl({
className,
children,
}: {
className?: string
children?: ReactNode
}) {
return (
<Stagger as="ol" className={className}>
{children}
</Stagger>
)
}
export type StepsMotionProps = Omit<StepsProps, "listAs" | "itemAs">
export function StepsMotion(props: StepsMotionProps) {
return <Steps {...props} listAs={StaggerOl} itemAs={StaggerListItem} />
}Props
StepsMotionProps
Extends Omit<StepsProps, "listAs" | "itemAs">.