Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions corpus/frontend/motion/animatepresence.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: AnimatePresence
kind: component
description: >-
Enables exit animations when children are removed from the React tree. Direct
children must have unique key props.
importPath: 'import { AnimatePresence } from "motion/react"'
props:
- name: initial
type: boolean
description: Set false to disable initial animations on first render.
default: "true"
- name: mode
type: "'sync' | 'wait' | 'popLayout'"
description: "sync: simultaneous enter/exit. wait: exit completes before enter. popLayout: pop exiting elements out of layout flow."
default: "'sync'"
- name: custom
type: any
description: Data passed to exiting components via usePresenceData().
- name: onExitComplete
type: () => void
description: Fires when all exit animations finish.
- name: propagate
type: boolean
description: If true, nested AnimatePresence children fire exit animations when parent exits.
- name: root
type: ShadowRoot | HTMLElement
description: Root element for popLayout styles. Defaults to document.head. Set to a ShadowRoot for shadow DOM usage.
usage: |
<AnimatePresence>
{show && (
<motion.div
key="modal"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
/>
)}
</AnimatePresence>
examples:
- title: Modal with exit animation
category: exit
code: |
function Modal({ isOpen, onClose }) {
return (
<AnimatePresence>
{isOpen && (
<motion.div
key="backdrop"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={onClose}
>
<motion.div
key="modal"
initial={{ scale: 0.8, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
exit={{ scale: 0.8, opacity: 0 }}
onClick={e => e.stopPropagation()}
>
Modal content
</motion.div>
</motion.div>
)}
</AnimatePresence>
);
}
- title: Page transitions with wait mode
category: exit
code: |
<AnimatePresence mode="wait">
<motion.div
key={pathname}
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
>
{children}
</motion.div>
</AnimatePresence>
tips:
- "AnimatePresence must wrap the conditional - it goes OUTSIDE the {show && ...}."
- Each direct child needs a unique key prop.
- mode='wait' is useful for page transitions where old page exits before new enters.
- "mode='popLayout' pops exiting elements out of document flow immediately. Custom component children must use forwardRef (React 18) or accept ref prop (React 19)."
relatedApis:
- motion
- usePresence
- useIsPresent
- usePresenceData
6 changes: 6 additions & 0 deletions corpus/frontend/motion/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ namespace: frontend.motion
apis:
motion:
file: motion.yaml
animatepresence:
file: animatepresence.yaml
usescroll:
file: usescroll.yaml
usespring:
file: usespring.yaml
examples:
scroll:
file: examples/scroll.yaml
106 changes: 106 additions & 0 deletions corpus/frontend/motion/usescroll.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: useScroll
kind: hook
description: >-
Creates scroll-linked motion values. Tracks window or element scroll
position. Supports hardware-accelerated ScrollTimeline.
importPath: 'import { useScroll } from "motion/react"'
returns: "{ scrollX, scrollY, scrollXProgress, scrollYProgress }"
props:
- name: container
type: RefObject<HTMLElement>
description: "Scrollable element ref. Default: window."
- name: target
type: RefObject<HTMLElement>
description: Element to track progress through container.
- name: axis
type: "'x' | 'y'"
description: Scroll axis.
default: "'y'"
- name: offset
type: "[string, string]"
description: "Start/end intersection points. Format: 'targetPoint containerPoint'. Points: start, center, end, 0-1, px, %, vh, vw."
default: '["start start", "end end"]'
- name: trackContentSize
type: boolean
description: Track content size changes.
default: "false"
usage: |
// Window scroll
const { scrollYProgress } = useScroll();

// Element scroll
const ref = useRef(null);
const { scrollYProgress } = useScroll({ container: ref });

// Track element through viewport
const ref = useRef(null);
const { scrollYProgress } = useScroll({
target: ref,
offset: ["start end", "end start"]
});
examples:
- title: Scroll progress bar
category: scroll
code: |
function ProgressBar() {
const { scrollYProgress } = useScroll();

return (
<motion.div
style={{
scaleX: scrollYProgress,
position: "fixed",
top: 0,
left: 0,
right: 0,
height: 4,
background: "#0066ff",
transformOrigin: "left",
}}
/>
);
}
- title: Element reveal on scroll
category: scroll
code: |
function RevealSection() {
const ref = useRef(null);
const { scrollYProgress } = useScroll({
target: ref,
offset: ["start end", "center center"]
});
const opacity = useTransform(scrollYProgress, [0, 1], [0, 1]);
const y = useTransform(scrollYProgress, [0, 1], [100, 0]);

return (
<motion.section ref={ref} style={{ opacity, y }}>
Content revealed on scroll
</motion.section>
);
}
- title: Horizontal scroll section
category: scroll
code: |
function HorizontalScroll() {
const containerRef = useRef(null);
const { scrollYProgress } = useScroll({ target: containerRef });
const x = useTransform(scrollYProgress, [0, 1], ["0%", "-75%"]);

return (
<section ref={containerRef} style={{ height: "400vh" }}>
<div style={{ position: "sticky", top: 0, overflow: "hidden" }}>
<motion.div style={{ x, display: "flex" }}>
{panels.map(panel => <Panel key={panel.id} {...panel} />)}
</motion.div>
</div>
</section>
);
}
tips:
- "Offset format: ['start end', 'end start'] means animation starts when target's start hits viewport end, ends when target's end hits viewport start."
- Use useTransform to map scrollYProgress to transform/opacity/filter for GPU-accelerated animations.
- Combine with useSpring for smoothed scroll animations.
relatedApis:
- useTransform
- useSpring
- useMotionValue
79 changes: 79 additions & 0 deletions corpus/frontend/motion/usespring.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: useSpring
kind: hook
description: >-
Creates a motion value that animates to targets with spring physics. Can
track another motion value.
importPath: 'import { useSpring } from "motion/react"'
returns: MotionValue<number>
props:
- name: stiffness
type: number
description: Spring stiffness.
default: "1"
- name: damping
type: number
description: Spring damping.
default: "10"
- name: mass
type: number
description: Mass of the moving object.
default: "1"
- name: bounce
type: number
description: Bounciness (0-1).
default: "0.25"
- name: duration
type: number
description: Duration in seconds (spring will be configured to match).
- name: visualDuration
type: number
description: Perceived duration (spring settles to 1/10 of movement).
- name: skipInitialAnimation
type: boolean
description: Skip animation on initial render.
default: "false"
usage: |
// Direct control
const x = useSpring(0);
x.set(100); // springs to 100

// Track another value
const scrollY = useMotionValue(0);
const smoothY = useSpring(scrollY, { stiffness: 100, damping: 30 });
examples:
- title: Smooth scroll tracking
category: scroll
code: |
function SmoothScroll() {
const { scrollYProgress } = useScroll();
const smoothProgress = useSpring(scrollYProgress, {
stiffness: 100,
damping: 30,
restDelta: 0.001
});

return <motion.div style={{ scaleX: smoothProgress }} />;
}
- title: Mouse follower
category: animation
code: |
function Cursor() {
const x = useMotionValue(0);
const y = useMotionValue(0);
const springX = useSpring(x, { stiffness: 300, damping: 25 });
const springY = useSpring(y, { stiffness: 300, damping: 25 });

useEffect(() => {
const handler = (e: MouseEvent) => {
x.set(e.clientX);
y.set(e.clientY);
};
window.addEventListener("mousemove", handler);
return () => window.removeEventListener("mousemove", handler);
}, []);

return <motion.div style={{ x: springX, y: springY }} />;
}
relatedApis:
- useMotionValue
- useTransform
Loading
Loading