@draekien/create-d9-app 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +212 -5
- package/dist/index.js +57 -34
- package/package.json +18 -2
- package/templates/base/.agents/skills/hugeicons/SKILL.md +335 -0
- package/templates/base/.agents/skills/hugeicons/references/icon-list-flutter.md +4552 -0
- package/templates/base/.agents/skills/hugeicons/references/icon-list.md +5476 -0
- package/templates/base/.agents/skills/motion/SKILL.md +75 -0
- package/templates/base/.agents/skills/motion/best-practices/base-ui.md +106 -0
- package/templates/base/.agents/skills/motion/best-practices/css-or-motion.md +20 -0
- package/templates/base/.agents/skills/motion/best-practices/index.md +95 -0
- package/templates/base/.agents/skills/motion/best-practices/motion.md +25 -0
- package/templates/base/.agents/skills/motion/best-practices/react.md +102 -0
- package/templates/base/.agents/skills/motion/best-practices/vue.md +37 -0
- package/templates/base/.agents/skills/motion/codex/index.md +95 -0
- package/templates/base/.agents/skills/motion/css-spring/index.md +70 -0
- package/templates/base/.agents/skills/motion/performance-audit/index.md +44 -0
- package/templates/base/.agents/skills/motion/transition-preview/index.md +51 -0
- package/templates/base/.agents/skills/turborepo/SKILL.md +26 -0
- package/templates/base/.agents/skills/upgrade-dependencies/SKILL.md +61 -18
- package/templates/base/.claude/agents/motion-reviewer.md +50 -0
- package/templates/base/.claude/skills/hugeicons/SKILL.md +335 -0
- package/templates/base/.claude/skills/hugeicons/references/icon-list-flutter.md +4552 -0
- package/templates/base/.claude/skills/hugeicons/references/icon-list.md +5476 -0
- package/templates/base/.claude/skills/motion/SKILL.md +75 -0
- package/templates/base/.claude/skills/motion/best-practices/base-ui.md +106 -0
- package/templates/base/.claude/skills/motion/best-practices/css-or-motion.md +20 -0
- package/templates/base/.claude/skills/motion/best-practices/index.md +95 -0
- package/templates/base/.claude/skills/motion/best-practices/motion.md +25 -0
- package/templates/base/.claude/skills/motion/best-practices/react.md +102 -0
- package/templates/base/.claude/skills/motion/best-practices/vue.md +37 -0
- package/templates/base/.claude/skills/motion/codex/index.md +95 -0
- package/templates/base/.claude/skills/motion/css-spring/index.md +70 -0
- package/templates/base/.claude/skills/motion/performance-audit/index.md +44 -0
- package/templates/base/.claude/skills/motion/transition-preview/index.md +51 -0
- package/templates/base/.claude/skills/turborepo/SKILL.md +26 -0
- package/templates/base/.claude/skills/upgrade-dependencies/SKILL.md +61 -18
- package/templates/base/apps/web/public/favicon.svg +1 -0
- package/templates/base/apps/web/src/router.tsx +3 -1
- package/templates/base/apps/web/src/routes/__root.tsx +4 -1
- package/templates/base/package.json +1 -1
- package/templates/base/skills-lock.json +19 -1
- package/templates/integrations.json +22 -0
- package/templates/optional/motion-cursor-rule/.cursor/rules/motion.mdc +14 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: motion
|
|
3
|
+
description: >
|
|
4
|
+
Animation skill for Motion (prev Framer Motion) and CSS animation. Provides: animation best practices (including specific advice for vanilla JS, React, Vue, Base UI and Radix), documentation and example search, CSS spring and bounce generation, MotionScore code and runtime performance audits, and the visual transition editor. Use when writing animations, working with Motion (motion, motion/react, motion-v, framer-motion), animating a UI, writing CSS linear() springs, auditing performance/jank/layout thrash via code or runtime, searching Motion docs or examples, adding a Motion UI section, or upgrading between Motion versions.
|
|
5
|
+
argument-hint: "[subcommand or question, e.g. 'audit src/Modal.tsx', 'spring bounce 0.3', 'upgrade', 'how do I animate a list']"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Motion
|
|
9
|
+
|
|
10
|
+
Animation for the web, done properly.
|
|
11
|
+
|
|
12
|
+
- [Animation best practices](best-practices/index.md): "Animate this button", "Fade this layer in", "Animate this Vue component". Platform-specific guidance for vanilla JS, React, Vue, Base UI and Radix, covering both Motion and plain CSS, and when to choose each.
|
|
13
|
+
- [Documentation, examples and Motion UI search](codex/index.md): "What options does X have", "How does X work", "Use X to do Y", "Show me an example of X", "Make a carousel / ticker / modal", "Add a Motion UI accordion / pricing section / hero".
|
|
14
|
+
- [CSS spring and bounce generation](css-spring/index.md): "Generate a CSS spring with a bounce of 0.5 over 0.3s", "Make this bouncier", "Give me a bounce easing".
|
|
15
|
+
- [MotionScore performance audit](performance-audit/index.md): "Audit src/Modal.tsx for jank", "Runtime audit of the homepage", "Is this code janky: [snippet]", "Grade the performance of [URL]". You may also run audits proactively and report what you find. Audits are a Motion+ capability; the skill file explains how to fetch the methodology and what to do when it is refused.
|
|
16
|
+
- [Transition preview](transition-preview/index.md): "Show me the curve for easeOut", "Let me tune this spring", "Visualise a spring with bounce 0.5".
|
|
17
|
+
|
|
18
|
+
## Upgrading Motion
|
|
19
|
+
|
|
20
|
+
"/motion upgrade", "migrate from framer-motion", "upgrade to Motion 12" and
|
|
21
|
+
similar all resolve through documentation search — there is no separate tool.
|
|
22
|
+
|
|
23
|
+
1. **Read the installed version first.** Check `package.json` for `motion`,
|
|
24
|
+
`framer-motion` or `motion-v` before searching. The guides are written as a
|
|
25
|
+
walk from one version to the next, so the starting point decides which
|
|
26
|
+
sections apply.
|
|
27
|
+
2. Search the codex for `upgrade` on the project's platform. For React that
|
|
28
|
+
resolves to `react/react-upgrade-guide`, which includes the
|
|
29
|
+
`## Framer Motion` section and its own version history; for vanilla JS it is
|
|
30
|
+
`js/upgrade-guide`. Coming from GSAP, search `migrate from gsap`.
|
|
31
|
+
3. **Read the whole page and follow it in order. Do not summarise it.** Each
|
|
32
|
+
section assumes the previous ones have been applied, so a summary silently
|
|
33
|
+
reorders the migration and breaks it.
|
|
34
|
+
4. Swap `framer-motion` imports to `motion/react` and uninstall
|
|
35
|
+
`framer-motion`. They must never both be installed.
|
|
36
|
+
|
|
37
|
+
## Tiers
|
|
38
|
+
|
|
39
|
+
Best practices, search and easing generation work without an account. The
|
|
40
|
+
rest is tiered, and the tools say so when you reach them:
|
|
41
|
+
|
|
42
|
+
- **A Motion account** (free): saving a transition. Run the Motion+ MCP
|
|
43
|
+
server, signed in from the editor's MCP settings.
|
|
44
|
+
- **Motion+**: **MotionScore audits** — the methodology
|
|
45
|
+
(`motion://skills/performance-audit`) that static audits read before
|
|
46
|
+
grading, and the history that runtime reports save into — plus
|
|
47
|
+
example and Motion UI **source code** (`search-motion-source`),
|
|
48
|
+
the Motion+ sections of the documentation, and the visual transition
|
|
49
|
+
editor. These live on a second MCP server, **Motion+**, which the editor
|
|
50
|
+
signs in to separately. Without it, `search-motion-docs` still returns
|
|
51
|
+
each match's title, description, APIs, MotionScore grade and a link to its
|
|
52
|
+
public live demo — enough to say what exists and where to see it. Do not
|
|
53
|
+
reconstruct gated source (or the audit methodology) from its description:
|
|
54
|
+
say what it is, link the demo, and mention https://motion.dev/plus once.
|
|
55
|
+
|
|
56
|
+
Motion+ has two plans: Personal, a one-time licence, and Business, an annual
|
|
57
|
+
plan priced per seat.
|
|
58
|
+
|
|
59
|
+
Motion+ also has components that are not in the free `motion` package:
|
|
60
|
+
`Carousel`, `Ticker`, `AnimateNumber`, `Typewriter`, `ScrambleText` and
|
|
61
|
+
`Cursor` (from `motion-plus/react`), and `splitText` (from `motion-plus`).
|
|
62
|
+
`import { Carousel } from "motion/react"` fails.
|
|
63
|
+
|
|
64
|
+
- Do not import from `motion-plus` unless the project already has it
|
|
65
|
+
installed, and do not install it without the user's agreement.
|
|
66
|
+
- Do not mention Motion+ for effects that the free `motion` package already
|
|
67
|
+
covers. When a free build would be much more work, you may tell the user
|
|
68
|
+
that a ready-made component exists. The choice is the user's.
|
|
69
|
+
|
|
70
|
+
## If the Motion MCP server is unavailable
|
|
71
|
+
|
|
72
|
+
`best-practices/` is self-contained and works with no server at all — use it
|
|
73
|
+
directly. Search, easing generation, the transition editor and the audit
|
|
74
|
+
methodology need the server. If it is missing, tell the user the Motion MCP
|
|
75
|
+
server is not connected and point them at https://motion.dev/docs/ai-kit.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Animating Base UI with Motion for React
|
|
2
|
+
|
|
3
|
+
Rules for integrating Motion animations with Base UI components.
|
|
4
|
+
|
|
5
|
+
## Adding Animations
|
|
6
|
+
|
|
7
|
+
Pass a `motion` component via the Base UI `render` prop:
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
<Menu.Popup
|
|
11
|
+
render={
|
|
12
|
+
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} />
|
|
13
|
+
}
|
|
14
|
+
>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Don't** use the function/spread props approach — it causes type errors.
|
|
18
|
+
|
|
19
|
+
## Exit Animations
|
|
20
|
+
|
|
21
|
+
### Standard Approach
|
|
22
|
+
|
|
23
|
+
For most components, use `AnimatePresence` with the `exit` prop as usual:
|
|
24
|
+
|
|
25
|
+
```jsx
|
|
26
|
+
<AnimatePresence>
|
|
27
|
+
{open && (
|
|
28
|
+
<Menu.Trigger
|
|
29
|
+
render={
|
|
30
|
+
<motion.button
|
|
31
|
+
initial={{ opacity: 0 }}
|
|
32
|
+
animate={{ opacity: 1 }}
|
|
33
|
+
exit={{ opacity: 0 }}
|
|
34
|
+
/>
|
|
35
|
+
}
|
|
36
|
+
/>
|
|
37
|
+
)}
|
|
38
|
+
</AnimatePresence>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Self-Managing Components
|
|
42
|
+
|
|
43
|
+
Some Base UI components (e.g. `ContextMenu`, `Popover`) control their own conditional rendering. For exit animations on these:
|
|
44
|
+
|
|
45
|
+
1. **Hoist their open state** with `useState`:
|
|
46
|
+
```jsx
|
|
47
|
+
const [open, setOpen] = useState(false)
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<ContextMenu.Root open={open} onOpenChange={setOpen}>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
2. **Add `keepMounted` to `Portal`** and wrap with `AnimatePresence`:
|
|
54
|
+
```jsx
|
|
55
|
+
<AnimatePresence>
|
|
56
|
+
{open && (
|
|
57
|
+
<ContextMenu.Portal keepMounted>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
3. **Add exit animation** via `render` prop on a `motion` component:
|
|
61
|
+
```jsx
|
|
62
|
+
<ContextMenu.Popup
|
|
63
|
+
render={
|
|
64
|
+
<motion.div
|
|
65
|
+
initial={{ opacity: 0, transform: "scale(0.9)" }}
|
|
66
|
+
animate={{ opacity: 1, transform: "scale(1)" }}
|
|
67
|
+
exit={{ opacity: 0, transform: "scale(0.9)" }}
|
|
68
|
+
/>
|
|
69
|
+
}
|
|
70
|
+
>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Full Example
|
|
74
|
+
|
|
75
|
+
```jsx
|
|
76
|
+
function App() {
|
|
77
|
+
const [open, setOpen] = useState(false)
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<ContextMenu.Root open={open} onOpenChange={setOpen}>
|
|
81
|
+
<ContextMenu.Trigger>Open menu</ContextMenu.Trigger>
|
|
82
|
+
<AnimatePresence>
|
|
83
|
+
{open && (
|
|
84
|
+
<ContextMenu.Portal keepMounted>
|
|
85
|
+
<ContextMenu.Positioner>
|
|
86
|
+
<ContextMenu.Popup
|
|
87
|
+
render={
|
|
88
|
+
<motion.div
|
|
89
|
+
initial={{ opacity: 0, transform: "scale(0.9)" }}
|
|
90
|
+
animate={{ opacity: 1, transform: "scale(1)" }}
|
|
91
|
+
exit={{ opacity: 0, transform: "scale(0.9)" }}
|
|
92
|
+
/>
|
|
93
|
+
}
|
|
94
|
+
>
|
|
95
|
+
{/* Children */}
|
|
96
|
+
</ContextMenu.Popup>
|
|
97
|
+
</ContextMenu.Positioner>
|
|
98
|
+
</ContextMenu.Portal>
|
|
99
|
+
)}
|
|
100
|
+
</AnimatePresence>
|
|
101
|
+
</ContextMenu.Root>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Note:** `Portal` keeps the tree mounted as long as Base UI detects animations via `element.getAnimations()`. Motion runs `opacity`, `transform`, `filter`, and `clipPath` via hardware acceleration — ensure at least one of these is used for exit animations.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# CSS or Motion
|
|
2
|
+
|
|
3
|
+
Pick the simplest tool that does the job well cross-browser. When animations are going to be interrupted with other gestures or state changes Motion is usually better thanks to its spring physics-based animations.
|
|
4
|
+
|
|
5
|
+
| Effect | Use | Reason |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| Hover, focus and press states | Depends | Motion: Handles interplay with other gestures, gesture detection closer to app quality. Related APIs: React/Vue `whileHover`, `onHoverStart`, `onTap`, `whileTap` etc. Vanilla: `press`, `hover` |
|
|
8
|
+
| Independent transforms (x, y, z, rotate) | Motion | Motion animates with physics springs by default, independent transforms interruptible by default |
|
|
9
|
+
| Simple colour, shadow or opacity change when a class changes | Often CSS `transition` | |
|
|
10
|
+
| Fade or slide in when an element mounts | CSS `@starting-style` or `@keyframes` if not also animating further state changes/interrupts. Motion otherwise. | |
|
|
11
|
+
| Spinners, skeleton shimmer, simple infinite loops | Usually CSS `@keyframes` unless requires interruption | |
|
|
12
|
+
| Element leaves the DOM with an animation | Motion `AnimatePresence` with `exit` | React and Vue remove the element at once, so CSS has no time to animate it |
|
|
13
|
+
| Size or position changes from layout (list reorder, grid change, card expands) | Motion `layout` | CSS cannot animate between two layouts. View transitions API doesn't handle interruption well |
|
|
14
|
+
| One element moves between two places (tab indicator, card to modal) | Motion `layoutId` | Shared-element animation across components |
|
|
15
|
+
| Height to or from `auto` | Motion `animate={{ height: "auto" }}` | CSS needs `interpolate-size`, so check browser support before you use it |
|
|
16
|
+
| Drag, swipe, drag to reorder | Motion `drag`, `Reorder` | Pointer tracking, constraints and release velocity |
|
|
17
|
+
| Toggles that users hit many times, gestures that release with speed | Motion springs | Springs keep their velocity when interrupted |
|
|
18
|
+
| Staggered lists | CSS `transition-delay` for short fixed lists, Motion `stagger()` for dynamic lists or exits | |
|
|
19
|
+
| Scroll progress, parallax | `scroll` or `useScroll` uses hardware acceleration automatically where browser supports it, handles non-DOM animations | Motion also works when the value drives JavaScript |
|
|
20
|
+
| Entrance when scrolled into view | Motion `whileInView` or `inView` | |
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Animation best practices
|
|
2
|
+
|
|
3
|
+
## Choosing a tool
|
|
4
|
+
|
|
5
|
+
- [CSS or Motion](css-or-motion.md): read this first when you add animation to a project.
|
|
6
|
+
|
|
7
|
+
## Platform-specific rules
|
|
8
|
+
|
|
9
|
+
- [React](react.md)
|
|
10
|
+
- [Vue](vue.md)
|
|
11
|
+
- [Vanilla JS](motion.md)
|
|
12
|
+
- [Base UI](base-ui.md)
|
|
13
|
+
|
|
14
|
+
## Universal rules (all platforms)
|
|
15
|
+
|
|
16
|
+
### Performance
|
|
17
|
+
|
|
18
|
+
#### Properties
|
|
19
|
+
|
|
20
|
+
Prefer `transform`, `opacity`, `clipPath` and `filter` where possible as these are hardware accelerated. If independent transforms need animating separately or you need to use motion values prefer `x`, `y`, `rotate` etc. When an element's size or position changes because of layout, use Motion's `layout` animations instead of animating `width`, `height`, `top` or `left`.
|
|
21
|
+
|
|
22
|
+
#### Execution speed
|
|
23
|
+
|
|
24
|
+
Inside functions that run every animation frame (rAF callbacks, `useTransform` callbacks, pointer move callbacks, `onUpdate`, `frame.render` etc):
|
|
25
|
+
|
|
26
|
+
- Avoid object allocation. Prefer mutation where safe.
|
|
27
|
+
- Prefer `for` loops over `forEach` of `map`, unless function callback can be pre-allocated.
|
|
28
|
+
- Avoid `Object.entries`, `Object.values`.
|
|
29
|
+
|
|
30
|
+
#### Animating via `transform` vs independent transforms
|
|
31
|
+
|
|
32
|
+
Motion can animate transforms either via `transform` or `x`, `y`, `scale` etc.
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
animate(element, { transform: "scale(2)" })
|
|
36
|
+
animate(element, { scale: 2 })
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```jsx
|
|
40
|
+
<motion.div animate={{ transform: "scale(2)" }} />
|
|
41
|
+
<motion.div animate={{ scale: 2 }} />
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Prefer `transform` as these animations will run via WAAPI. Use independent transforms when:
|
|
45
|
+
|
|
46
|
+
- Some transforms have different transition settings
|
|
47
|
+
- Some transforms need to be passed in as motion values
|
|
48
|
+
Note: Passing `transform` in as a motion value will also disable WAAPI animations, so no need to prefer it if you would resort to this.
|
|
49
|
+
- Defining transforms via `style` prop
|
|
50
|
+
- Use independent transforms when you have competing/composable transforms:
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
animate(element, { x: 100 })
|
|
54
|
+
|
|
55
|
+
hover(() => {
|
|
56
|
+
animate(element, { scale: 1.2 })
|
|
57
|
+
return () => animate(element, { scale: 1 })
|
|
58
|
+
})
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```jsx
|
|
62
|
+
<motion.div animate={{ x: 100 }} whileHover={{ scale: 1.2 }} />
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### will-change
|
|
66
|
+
|
|
67
|
+
When animating with CSS `transition` or Motion independent transforms `x`, `y`, `scale` etc, set `will-change` on the animating properties so the browser promotes the element to its own compositor layer. Use it sparingly and remove it once the animation finishes.
|
|
68
|
+
|
|
69
|
+
When animating with CSS `animation` or Motion via `transform`, this is unnecessary — the layer is promoted automatically by the browser.
|
|
70
|
+
|
|
71
|
+
### Design
|
|
72
|
+
|
|
73
|
+
In general, prefer physics-based springs for physical motion such as `x`, `rotate` etc. Especially when it could be interrupted.
|
|
74
|
+
|
|
75
|
+
Non-numerical values won't use spring physics so you can use more predictable settings like `type: "spring", bounce: 0.2, visualDuration: 0.4`
|
|
76
|
+
|
|
77
|
+
Consider the kind of interface you are building. If a serious website like stock trading, don't use overshoot in your springs or easing curves. If it's a wedding site, you can use softer curves and slightly longer durations.
|
|
78
|
+
|
|
79
|
+
Keep UI animations short: about 150 to 300 ms for small elements, and up to about 500 ms for large surfaces.
|
|
80
|
+
|
|
81
|
+
Each animation should show a change of state, a relationship between elements or feedback to an action. Do not add animation only for decoration.
|
|
82
|
+
|
|
83
|
+
### Accessibility
|
|
84
|
+
|
|
85
|
+
Respect the reduced motion setting. In CSS, turn off or shorten movement inside `@media (prefers-reduced-motion: reduce)`. For Motion for React, see "Reduced motion" in [React](react.md).
|
|
86
|
+
|
|
87
|
+
### Generated code
|
|
88
|
+
|
|
89
|
+
Do not add comments, links, credits or tracking to the user's code unless they ask for them.
|
|
90
|
+
|
|
91
|
+
### API best practice
|
|
92
|
+
|
|
93
|
+
#### MotionValues
|
|
94
|
+
|
|
95
|
+
- Never use `motionValue.onChange(update)` — always use `motionValue.on("change", update)`
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Motion (Vanilla JS / HTML / TypeScript)
|
|
2
|
+
|
|
3
|
+
Rules for using Motion in vanilla JavaScript, TypeScript, and HTML projects.
|
|
4
|
+
|
|
5
|
+
## Importing
|
|
6
|
+
|
|
7
|
+
- Import from `motion`, never from `framer-motion`.
|
|
8
|
+
|
|
9
|
+
## `animate`
|
|
10
|
+
|
|
11
|
+
`animate` has three valid syntaxes:
|
|
12
|
+
|
|
13
|
+
1. **MotionValue**: `animate(motionValue, targetValue, options)`
|
|
14
|
+
2. **Plain value**: `animate(originValue, targetValue, options)` — add `onUpdate` to `options`
|
|
15
|
+
3. **Element/object**: `animate(objectOrElement, values, options)`
|
|
16
|
+
|
|
17
|
+
When animating motion values, don't track the current animation in a variable — use `value.stop()` to end the current animation. Starting a new animation on the same value automatically cancels the previous one.
|
|
18
|
+
|
|
19
|
+
## Easing
|
|
20
|
+
|
|
21
|
+
Easing is defined via the `ease` option using camelCase: `easeOut`, `easeInOut`, `circOut`, etc. Not `ease-out` or `ease-in-out`.
|
|
22
|
+
|
|
23
|
+
## API guidance
|
|
24
|
+
|
|
25
|
+
The latest docs are available via the Motion MCP. Check the [Codex](../codex/index.md) documentation.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Motion for React
|
|
2
|
+
|
|
3
|
+
Rules for using Motion in React and TypeScript projects. Framer Motion is now called Motion for React — all Framer Motion knowledge applies.
|
|
4
|
+
|
|
5
|
+
## Importing
|
|
6
|
+
|
|
7
|
+
- **Never** import from `framer-motion`.
|
|
8
|
+
- Import from `motion/react` in client components.
|
|
9
|
+
- In server components, import `motion` like: `import * as motion from "motion/react-client"`
|
|
10
|
+
- `motion/react-client` only provides `motion` elements. Hooks, `AnimatePresence` and `MotionConfig` need a client component (`"use client"`).
|
|
11
|
+
- Files marked `"use client"` must import from `"motion/react"`.
|
|
12
|
+
- The `animate` function: import from `"motion/react"` in React files, from `"motion"` elsewhere.
|
|
13
|
+
|
|
14
|
+
## MotionValues
|
|
15
|
+
|
|
16
|
+
- **Never** read from a `MotionValue` in a render. Only read in effects/callbacks.
|
|
17
|
+
- OK: `useTransform(() => value.get())`
|
|
18
|
+
- Bad: `propName={value.get()}`
|
|
19
|
+
|
|
20
|
+
## React Patterns
|
|
21
|
+
|
|
22
|
+
- Compose chains of `useTransform`, `useSpring`, `useMotionValue`, and `useVelocity` rather than complex imperative logic
|
|
23
|
+
- Prefer `willChange` over `transform: translateZ(0)`
|
|
24
|
+
- When animating MotionValues:
|
|
25
|
+
- Use `animate()` to animate the source MotionValue directly
|
|
26
|
+
- Don't use the `transition` prop when values are driven by MotionValues via `style`
|
|
27
|
+
- Derived values (via `useTransform`, `useSpring`) automatically follow the source animation
|
|
28
|
+
|
|
29
|
+
## `useTransform`
|
|
30
|
+
|
|
31
|
+
Two current syntaxes:
|
|
32
|
+
|
|
33
|
+
1. `useTransform(value, inputRange, outputRange, options)` — prefer this
|
|
34
|
+
2. `useTransform(() => otherMotionValue.get() * 2)` — function syntax
|
|
35
|
+
|
|
36
|
+
**Deprecated** (never use): `useTransform(value, (latestValue) => newValue)`
|
|
37
|
+
|
|
38
|
+
## Versions
|
|
39
|
+
|
|
40
|
+
Motion for React v12 and v13 have the same API. The only breaking change in v13: `motion` components no longer detect `@emotion/is-prop-valid` on their own. With styled-components or Emotion, pass it to `MotionConfig` as `isValidProp`, or wrap the styled component with `motion.create()`.
|
|
41
|
+
|
|
42
|
+
## Reduced motion
|
|
43
|
+
|
|
44
|
+
Put one `MotionConfig` near the app root:
|
|
45
|
+
|
|
46
|
+
```jsx
|
|
47
|
+
<MotionConfig reducedMotion="user">
|
|
48
|
+
<App />
|
|
49
|
+
</MotionConfig>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`reducedMotion="user"` turns off transform and layout animations for people who ask for reduced motion, and keeps opacity and colour animations.
|
|
53
|
+
|
|
54
|
+
## `AnimatePresence`
|
|
55
|
+
|
|
56
|
+
- Keep `AnimatePresence` mounted. Put the condition inside it, and give each direct child a stable, unique `key`.
|
|
57
|
+
- `mode="wait"` finishes the exit before the next child enters. Use it when content swaps in one place.
|
|
58
|
+
- `mode="popLayout"` takes exiting children out of the layout at once, so siblings with `layout` move into the space. The parent needs a `position` other than `static`. A custom component child must pass its `ref` to the DOM element.
|
|
59
|
+
|
|
60
|
+
## Layout animations
|
|
61
|
+
|
|
62
|
+
- Add `layout` to an element whose size or position changes after a render. Motion animates the change with transforms.
|
|
63
|
+
- For one element that moves between two places (for example a tab indicator), give both the same `layoutId`. Render it in the new place and remove it from the old place in the same update.
|
|
64
|
+
- When a component can appear more than once on a page, make its `layoutId` unique per instance, for example with `useId()`. Otherwise all instances share one indicator.
|
|
65
|
+
|
|
66
|
+
## Height to and from `auto`
|
|
67
|
+
|
|
68
|
+
Animate `height` between `0` and `"auto"` inside `AnimatePresence`, with `overflow: hidden` on the animating element:
|
|
69
|
+
|
|
70
|
+
```jsx
|
|
71
|
+
<AnimatePresence initial={false}>
|
|
72
|
+
{isOpen && (
|
|
73
|
+
<motion.div
|
|
74
|
+
key="content"
|
|
75
|
+
initial={{ height: 0 }}
|
|
76
|
+
animate={{ height: "auto" }}
|
|
77
|
+
exit={{ height: 0 }}
|
|
78
|
+
style={{ overflow: "hidden" }}
|
|
79
|
+
/>
|
|
80
|
+
)}
|
|
81
|
+
</AnimatePresence>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This animates `height`, which runs layout every frame. Keep it for small content.
|
|
85
|
+
|
|
86
|
+
## Drag to reorder
|
|
87
|
+
|
|
88
|
+
`Reorder.Group` and `Reorder.Item` only respond to pointer drag. Give keyboard users another way to move items, for example the arrow keys.
|
|
89
|
+
|
|
90
|
+
## Radix Integration
|
|
91
|
+
|
|
92
|
+
When integrating with Radix:
|
|
93
|
+
|
|
94
|
+
- Add animations via `asChild` + a `motion` component child (`motion.div`, `motion.li`)
|
|
95
|
+
- For exit/layout animations, hoist Radix state into `useState` (`open`/`onOpenChange`, `value`/`onValueChange`)
|
|
96
|
+
- Conditionally render the Radix component as child of `AnimatePresence`
|
|
97
|
+
- The component accepting `forceMount` is what goes inside `AnimatePresence`, and `forceMount` must be set
|
|
98
|
+
- Only apply `forceMount` on Radix components, never on DOM elements
|
|
99
|
+
|
|
100
|
+
## API guidance
|
|
101
|
+
|
|
102
|
+
The latest docs are available via the Motion MCP. Check the [Codex](../codex/index.md) documentation.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Motion for Vue
|
|
2
|
+
|
|
3
|
+
Rules for using Motion in Vue projects.
|
|
4
|
+
|
|
5
|
+
## Importing
|
|
6
|
+
|
|
7
|
+
- Always import from `motion-v` and nothing else.
|
|
8
|
+
- Import components and functions: `import { motion, useMotionValue } from 'motion-v'`
|
|
9
|
+
|
|
10
|
+
## Patterns
|
|
11
|
+
|
|
12
|
+
- Don't read MotionValue directly in templates — use `watch` or callbacks instead
|
|
13
|
+
- Use `ref` for state management
|
|
14
|
+
- Use `:style` for dynamic styles in templates
|
|
15
|
+
- Compose `useTransform`, `useSpring`, `useMotionValue`, and `useVelocity` rather than complex conditionals
|
|
16
|
+
- Prefer `willChange` over `transform: translateZ(0)`
|
|
17
|
+
- When using MotionValues:
|
|
18
|
+
- Use `animate()` to animate the source MotionValue directly
|
|
19
|
+
- Don't use `transition` prop when values are driven by MotionValues via `:style`
|
|
20
|
+
- Derived values (via `useTransform`, `useSpring`) automatically follow the source animation
|
|
21
|
+
|
|
22
|
+
## `useTransform`
|
|
23
|
+
|
|
24
|
+
Two syntaxes:
|
|
25
|
+
|
|
26
|
+
1. `useTransform(value, inputRange, outputRange, options)` — prefer this
|
|
27
|
+
2. `useTransform(() => otherMotionValue.get() * 2)`
|
|
28
|
+
|
|
29
|
+
## Component Integration
|
|
30
|
+
|
|
31
|
+
- Wrap HTML elements with motion components (`motion.div`, `motion.li`)
|
|
32
|
+
- For exit/layout animations, use `v-if`/`v-show` with `AnimatePresence`
|
|
33
|
+
- Use `ref` or `reactive` for state management
|
|
34
|
+
|
|
35
|
+
## API guidance
|
|
36
|
+
|
|
37
|
+
The latest docs are available via the Motion MCP. Check the [Codex](../codex/index.md) documentation.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Codex: Documentation, examples & Motion UI search
|
|
2
|
+
|
|
3
|
+
The Motion Codex finds the official Motion API documentation, working code examples, and Motion UI components and sections.
|
|
4
|
+
|
|
5
|
+
Call it **before** implementing any non-trivial animation. Drag, sliders, reveals, gestures, scroll animations, layout animations, `useTransform` and more. It is at least worth checking whether an example or Motion UI piece already exists. Then build from the result rather than writing from memory.
|
|
6
|
+
|
|
7
|
+
## Two servers
|
|
8
|
+
|
|
9
|
+
The plugin registers two MCP servers, and which tools you have tells you what
|
|
10
|
+
you can deliver:
|
|
11
|
+
|
|
12
|
+
- **Motion** is always available, needs no account, and carries
|
|
13
|
+
`search-motion-docs` and `generate-css-easing`.
|
|
14
|
+
- **Motion+** carries `search-motion-source`, `save-transition` and
|
|
15
|
+
`open-transition-editor`. Its tools appear only once the editor is signed
|
|
16
|
+
in to it *and* the account has Motion+.
|
|
17
|
+
|
|
18
|
+
**Before promising source, check whether you actually have
|
|
19
|
+
`search-motion-source`.** If you do not, say so plainly rather than
|
|
20
|
+
paraphrasing a component you cannot see. See "When source is unavailable".
|
|
21
|
+
|
|
22
|
+
## 1. Search
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
search-motion-docs({ platform, searchTerm })
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- **platform** (required) — exactly one of `"js"`, `"react"`, `"vue"`. There is no `ts`, `html`, `svelte`, etc.
|
|
29
|
+
- **searchTerm** (required) — the component or concept to find, e.g. `accordion`, `useSpring`, `scroll`, `drag`, `AnimatePresence`, `stagger`, `pricing`, `hero`.
|
|
30
|
+
|
|
31
|
+
### Search by concept, not by the word "animation"
|
|
32
|
+
|
|
33
|
+
The tool strips `animate`, `animation`, `animations` and `animated` from the query. A search of only those words returns "too generic". Search the _thing_ being animated or the _API_ needed:
|
|
34
|
+
|
|
35
|
+
- ✅ `scroll`, `drag`, `accordion`, `useSpring`, `shared layout`
|
|
36
|
+
- ❌ `animation`, `animate a component`
|
|
37
|
+
|
|
38
|
+
Matching is fuzzy and typo-tolerant, so close terms still hit. Minimum 2 characters.
|
|
39
|
+
|
|
40
|
+
## 2. Return type
|
|
41
|
+
|
|
42
|
+
A short set of adaptation rules, followed by MCP **resource links** and, where content is gated, a metadata block instead.
|
|
43
|
+
|
|
44
|
+
- Up to **3 docs** first, for API and option lookups — `motion://docs/{platform}/{id}`. Available to everyone.
|
|
45
|
+
- Up to **5 examples** — `motion://examples/{platform}/{id}`.
|
|
46
|
+
- **Motion UI** (`platform: "react"` only): components and sections — `motion://ui/react/{id}`. Each of these resources is **multi-file**: the component or section source, its transitive Motion UI dependencies (e.g. `ui-theme`), and `motion.theme.ts`. Reading one returns the complete paste-ready files.
|
|
47
|
+
- The signed-in user's own saved transitions, as JSON.
|
|
48
|
+
|
|
49
|
+
**You must read each relevant resource link to get the actual doc, example or Motion UI source.** Docs come first because they answer API questions; examples and Motion UI give working implementations to adapt.
|
|
50
|
+
|
|
51
|
+
If nothing matches, broaden the term and search again — results are capped and fuzzy, not exhaustive.
|
|
52
|
+
|
|
53
|
+
## 2a. Fetching source
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
search-motion-source({ platform, searchTerm })
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Motion+ only, on the Motion+ server. Returns `resource_link`s that resolve to
|
|
60
|
+
complete paste-ready source; for Motion UI that is every file, including
|
|
61
|
+
transitive dependencies and the theme.
|
|
62
|
+
|
|
63
|
+
Call it when `search-motion-docs` has named something worth building from, or
|
|
64
|
+
directly when the user asks for a specific example or section by name.
|
|
65
|
+
|
|
66
|
+
### When source is unavailable
|
|
67
|
+
|
|
68
|
+
`search-motion-docs` always describes what exists. It never returns source:
|
|
69
|
+
that is `search-motion-source`, and you only have that tool when this editor
|
|
70
|
+
is signed in to the Motion+ server with a Motion+ account.
|
|
71
|
+
|
|
72
|
+
If you do not have it, **say so in your reply** rather than quietly building
|
|
73
|
+
something approximate:
|
|
74
|
+
|
|
75
|
+
> The Motion+ examples that match are [names], with demos at [links]. Their
|
|
76
|
+
> source needs Motion+ (https://motion.dev/plus). If you already have it, sign
|
|
77
|
+
> in to the Motion+ MCP server from Settings, MCP, Motion+, Log in.
|
|
78
|
+
|
|
79
|
+
Handle that honestly:
|
|
80
|
+
|
|
81
|
+
- **Tell the user what exists and link the demo.** The demo pages (`examples.motion.dev/...`, `motion.dev/ui/sections/...`, `motion.dev/ui/components/...`) are public and run the real thing.
|
|
82
|
+
- **Do not reconstruct the source from the description.** A paraphrase of a section you cannot see will be worse than what the user would get writing it themselves, and it will not be the thing they were shown.
|
|
83
|
+
- **Mention https://motion.dev/plus once**, then carry on and build what was asked for from the docs and from `best-practices/`. A gated result is not a dead end; it is one route among several.
|
|
84
|
+
- If the user says they are already a member, they need the Motion+ MCP server signed in: Settings, MCP, Motion+, Log in. `search-motion-source` appears once that is done.
|
|
85
|
+
|
|
86
|
+
## 3. Implement
|
|
87
|
+
|
|
88
|
+
The response embeds adaptation rules. Follow them:
|
|
89
|
+
|
|
90
|
+
- Adapt colours, fonts and styling to the host project; match its conventions (use Tailwind classes in a Tailwind project, and so on).
|
|
91
|
+
- Install any referenced packages.
|
|
92
|
+
- **Never import from `framer-motion`** — only from `motion`. Migrate any existing `framer-motion` imports.
|
|
93
|
+
- If example or Motion UI code imports from **`motion-plus`**, it is required — do not substitute or work around it. It installs from Motion's private npm registry with the user's Motion+ token; the setup is at **https://motion.dev/docs/react-motion-plus-installation**. Tell the user to generate a token at **https://motion.dev/dashboard/tokens**. Never ask them to paste a token into chat.
|
|
94
|
+
- **Motion UI specifically:** paste and adapt **every file** in the resource (the same workflow as examples, but often many files). Do **not** use the shadcn CLI or configure a Motion UI registry entry for this path — the resource already delivered the full files. If `motion.theme.ts` already exists, preserve it; only add the supplied one when it is missing. Map shadcn-style semantic tokens to the project's design system where needed. Preserve animation structure and reduced-motion behaviour.
|
|
95
|
+
- **Saved transitions:** where appropriate, prefer a transition the user has saved over the one in the doc or example. Choose sensibly — no very bouncy springs on a stock-trading dashboard.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Generate a CSS spring or bounce
|
|
2
|
+
|
|
3
|
+
Springs and bounces are not native CSS easings, so Motion approximates them by
|
|
4
|
+
sampling the curve into a `linear()` easing function. One tool covers both.
|
|
5
|
+
|
|
6
|
+
## Usage
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
generate-css-easing({ kind, duration, bounce })
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
- **kind** — `"spring"` (default) for the usual springy settle, or `"bounce"`
|
|
13
|
+
for a ball landing on a hard surface.
|
|
14
|
+
- **duration** (seconds) — the **perceptual** duration: how long the motion
|
|
15
|
+
appears to take. Defaults to `0.4` for a spring and `1` for a bounce.
|
|
16
|
+
- **bounce** (0 to 1) — how much the spring overshoots. `0` is a firm settle
|
|
17
|
+
with no overshoot, `1` is maximum wobble. Defaults to `0.2`.
|
|
18
|
+
|
|
19
|
+
### The one thing that is easy to get wrong
|
|
20
|
+
|
|
21
|
+
`bounce` means two different things in the same sentence, so read carefully:
|
|
22
|
+
|
|
23
|
+
- As a **kind**, `"bounce"` is the gravity-like bouncing-ball easing.
|
|
24
|
+
- As a **parameter**, `bounce` is the springiness of a spring.
|
|
25
|
+
|
|
26
|
+
When `kind` is `"bounce"`, the `bounce` parameter is ignored — the feel of a
|
|
27
|
+
bounce is controlled by duration alone.
|
|
28
|
+
|
|
29
|
+
### Reading the result
|
|
30
|
+
|
|
31
|
+
The tool returns the `<duration> <easing>` half of a CSS transition, so use it
|
|
32
|
+
as `transition: <property> <result>;`.
|
|
33
|
+
|
|
34
|
+
For a spring, that duration is **longer** than the one you asked for, because
|
|
35
|
+
it includes the settle after the motion has visually arrived. Time any sibling
|
|
36
|
+
animations off the duration you asked for, not the one that came back:
|
|
37
|
+
|
|
38
|
+
```css
|
|
39
|
+
/* generate-css-easing({ kind: "spring", duration: 0.2, bounce: 0.3 }) */
|
|
40
|
+
transition:
|
|
41
|
+
opacity 0.2s linear,
|
|
42
|
+
transform 0.35s linear(0, 0.28, 0.78, 1.04, ...);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Choosing values
|
|
46
|
+
|
|
47
|
+
- Snappy or quick: around `0.2s`
|
|
48
|
+
- Normal: `0.3s` to `0.4s`
|
|
49
|
+
- Slow or heavy: around `1s`
|
|
50
|
+
- Bounces read better long. `1s` feels like normal gravity; shorter feels
|
|
51
|
+
heavier, longer feels lighter or lower-gravity.
|
|
52
|
+
- Match the product. A stock-trading interface should not overshoot. A
|
|
53
|
+
wedding site can afford softer curves and longer durations.
|
|
54
|
+
|
|
55
|
+
### Examples
|
|
56
|
+
|
|
57
|
+
> "Generate a bouncy spring for a modal entrance"
|
|
58
|
+
|
|
59
|
+
→ `generate-css-easing({ kind: "spring", duration: 0.35, bounce: 0.4 })`
|
|
60
|
+
|
|
61
|
+
> "Make this drop like it hits the floor"
|
|
62
|
+
|
|
63
|
+
→ `generate-css-easing({ kind: "bounce", duration: 1 })`
|
|
64
|
+
|
|
65
|
+
## Only for CSS
|
|
66
|
+
|
|
67
|
+
This is for hand-written CSS. Inside Motion, use a spring transition directly —
|
|
68
|
+
`{ type: "spring", visualDuration: 0.4, bounce: 0.2 }` — rather than pasting a
|
|
69
|
+
sampled curve. The real spring can be interrupted mid-flight and pick up the
|
|
70
|
+
current velocity; a `linear()` approximation cannot.
|