Motion and depth

@sushindustries/atoms

Every transition, animation and perspective in the stylesheet, what each is for, and where it is used.

9 min read
View as MarkdownEdit on GitHub

RevealRevealFades and rises its children the first time they reach the viewport. Never un-reveals.@sushindustries/ui · motion is what actually flips data-reveal from "out" to "in" - the attribute this page describes is inert on its own, and this is it wired up:

Viewport width
Phone22remthe floor, the narrowest this promises to work at
tanstacktanstack add https://adamjurek.com/r/tanstack/reveal.jsonshadcnpnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/reveal.json

Press Compare. The frames are real viewports, so a layout that breaks at 320 breaks here too rather than in somebody's hands.

In a page

import { Reveal } from "@sushindustries/ui";

export function FeatureSection() {
	return (
		<Reveal>
			<h2>A section that arrives once, on the way past</h2>
			<p>Not scenery repeated on every scroll back up the page.</p>
		</Reveal>
	);
}
tsx

RevealRevealFades and rises its children the first time they reach the viewport. Never un-reveals.@sushindustries/ui · motion sets data-reveal="out" before it has intersected the viewport and flips it to "in" the first time it does, never back - the CSS in this package only knows how to animate between the two states, not when to switch.

What this example is not

The 700ms duration and the 18px rise are the token's numbers, not RevealRevealFades and rises its children the first time they reach the viewport. Never un-reveals.@sushindustries/ui · motion's - changing how this looks means editing scroll-reveal.css, not passing a prop, because there is no prop for it. This is scenery, timed the same everywhere on purpose.