@skilly-hand/skilly-hand 0.26.0 → 0.26.2
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/CHANGELOG.md +33 -0
- package/README.md +2 -0
- package/catalog/README.md +3 -1
- package/catalog/catalog-index.json +2 -0
- package/catalog/skills/frontend-design/SKILL.md +22 -11
- package/catalog/skills/frontend-design/agents/critique.md +190 -0
- package/catalog/skills/frontend-design/agents/motion-designer.md +35 -1
- package/catalog/skills/frontend-design/manifest.json +17 -8
- package/catalog/skills/gsap-animation/SKILL.md +149 -0
- package/catalog/skills/gsap-animation/manifest.json +30 -0
- package/catalog/skills/gsap-animation/references/core-patterns.md +61 -0
- package/catalog/skills/gsap-animation/references/official-source-map.md +31 -0
- package/catalog/skills/gsap-animation/references/performance-accessibility.md +61 -0
- package/catalog/skills/gsap-animation/references/plugin-selection.md +42 -0
- package/catalog/skills/gsap-animation/references/react-patterns.md +59 -0
- package/catalog/skills/gsap-animation/references/scrolltrigger-patterns.md +61 -0
- package/catalog/skills/motion-animation/SKILL.md +148 -0
- package/catalog/skills/motion-animation/manifest.json +28 -0
- package/catalog/skills/motion-animation/references/js-patterns.md +81 -0
- package/catalog/skills/motion-animation/references/official-source-map.md +32 -0
- package/catalog/skills/motion-animation/references/performance-accessibility.md +49 -0
- package/catalog/skills/motion-animation/references/react-patterns.md +86 -0
- package/package.json +1 -1
- package/packages/catalog/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/core/package.json +1 -1
- package/packages/core/src/index.js +25 -2
- package/packages/detectors/package.json +1 -1
- package/packages/detectors/src/index.js +9 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Motion React Patterns
|
|
2
|
+
|
|
3
|
+
Extracted: 2026-05-03
|
|
4
|
+
|
|
5
|
+
Sources:
|
|
6
|
+
|
|
7
|
+
- https://motion.dev/docs/react
|
|
8
|
+
- https://motion.dev/docs/react-motion-component
|
|
9
|
+
- https://motion.dev/docs/react-animate-presence
|
|
10
|
+
- https://motion.dev/docs/react-use-scroll
|
|
11
|
+
- https://motion.dev/docs/react-use-reduced-motion
|
|
12
|
+
|
|
13
|
+
## Selection
|
|
14
|
+
|
|
15
|
+
Use Motion for React when a React project already uses Motion/Framer Motion, when animation should be expressed through component props, or when the desired behavior is gestures, exit animation, layout animation, scroll animation, or SVG animation in React.
|
|
16
|
+
|
|
17
|
+
Use JavaScript patterns from [js-patterns.md](js-patterns.md) for framework-agnostic utilities. Use `gsap-animation` when the project requires GSAP-specific timelines, ScrollTrigger behavior, plugins, or existing GSAP conventions.
|
|
18
|
+
|
|
19
|
+
## Installation and Imports
|
|
20
|
+
|
|
21
|
+
Motion for React uses the same package:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install motion
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Import React APIs from `"motion/react"`:
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { motion } from "motion/react";
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Ask before adding `motion` when it is not already present.
|
|
34
|
+
|
|
35
|
+
## motion Components
|
|
36
|
+
|
|
37
|
+
Use `motion` components for animating HTML and SVG elements with props:
|
|
38
|
+
|
|
39
|
+
- `initial` defines the starting visual state.
|
|
40
|
+
- `animate` defines the current target visual state.
|
|
41
|
+
- `transition` defines duration, easing, spring, and related transition behavior.
|
|
42
|
+
- Variants can coordinate named states across parent/child component trees.
|
|
43
|
+
|
|
44
|
+
Use `motion.create()` for custom components only when the official component integration pattern is needed.
|
|
45
|
+
|
|
46
|
+
## Gestures
|
|
47
|
+
|
|
48
|
+
Use React gesture props for interaction feedback:
|
|
49
|
+
|
|
50
|
+
- `whileHover` for hover targets.
|
|
51
|
+
- `whileTap` for press/tap targets.
|
|
52
|
+
- Hover, tap, focus, and drag are supported gesture categories in the React quick start.
|
|
53
|
+
|
|
54
|
+
Keep gesture motion brief and meaningful, and pair it with accessible non-motion feedback when needed.
|
|
55
|
+
|
|
56
|
+
## Scroll Animation
|
|
57
|
+
|
|
58
|
+
Use `whileInView` for scroll-triggered animation when an element should animate as it enters or leaves the viewport.
|
|
59
|
+
|
|
60
|
+
Use `useScroll()` when a MotionValue should be linked directly to scroll progress, such as a progress bar scale.
|
|
61
|
+
|
|
62
|
+
## Layout Animation
|
|
63
|
+
|
|
64
|
+
Use `layout` when React layout changes in size, position, or reorder should animate smoothly.
|
|
65
|
+
|
|
66
|
+
Use `layoutId` for shared layout transitions between different elements.
|
|
67
|
+
|
|
68
|
+
When mixing layout animation with exits, consider official `AnimatePresence` mode guidance and `LayoutGroup` guidance if surrounding components need coordinated layout updates.
|
|
69
|
+
|
|
70
|
+
## Exit Animation
|
|
71
|
+
|
|
72
|
+
Use `AnimatePresence` when removed React elements should animate out before leaving the DOM:
|
|
73
|
+
|
|
74
|
+
- Place the conditional child inside `AnimatePresence`; do not unmount `AnimatePresence` at the same time as the child.
|
|
75
|
+
- Give every direct child a stable unique `key`.
|
|
76
|
+
- Use the `exit` prop on `motion` components.
|
|
77
|
+
- Use `mode="wait"` only for one child at a time.
|
|
78
|
+
- Use `mode="popLayout"` carefully with positioned parents and forwarded refs for custom immediate children.
|
|
79
|
+
|
|
80
|
+
## SVG Animation
|
|
81
|
+
|
|
82
|
+
Motion for React supports SVG animation. Use `motion` SVG elements and official SVG props such as `pathLength` for path drawing effects where appropriate.
|
|
83
|
+
|
|
84
|
+
## React Server Components
|
|
85
|
+
|
|
86
|
+
In React Server Component projects, components that use Motion runtime behavior must be client components. Keep Motion imports and animated components in client-side files.
|
package/package.json
CHANGED
|
@@ -269,6 +269,26 @@ function parseSkillIds(input) {
|
|
|
269
269
|
return uniq((input || []).flatMap((value) => String(value).split(",")).map((value) => value.trim()).filter(Boolean));
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
+
function expandSkillDependencies({ catalog, skillIds }) {
|
|
273
|
+
const byId = new Map(catalog.filter((skill) => skill.portable).map((skill) => [skill.id, skill]));
|
|
274
|
+
const expanded = new Set(skillIds);
|
|
275
|
+
const pending = [...skillIds];
|
|
276
|
+
|
|
277
|
+
while (pending.length > 0) {
|
|
278
|
+
const skillId = pending.pop();
|
|
279
|
+
const skill = byId.get(skillId);
|
|
280
|
+
if (!skill || !Array.isArray(skill.dependencies)) continue;
|
|
281
|
+
|
|
282
|
+
for (const dependencyId of skill.dependencies) {
|
|
283
|
+
if (!byId.has(dependencyId) || expanded.has(dependencyId)) continue;
|
|
284
|
+
expanded.add(dependencyId);
|
|
285
|
+
pending.push(dependencyId);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return expanded;
|
|
290
|
+
}
|
|
291
|
+
|
|
272
292
|
export function resolveSkillSelectionByIds({ catalog, selectedSkillIds = [] }) {
|
|
273
293
|
const ids = parseSkillIds(selectedSkillIds);
|
|
274
294
|
const portableById = new Map(
|
|
@@ -293,7 +313,9 @@ export function resolveSkillSelectionByIds({ catalog, selectedSkillIds = [] }) {
|
|
|
293
313
|
throw new Error(invalid.join("; "));
|
|
294
314
|
}
|
|
295
315
|
|
|
296
|
-
|
|
316
|
+
const expanded = expandSkillDependencies({ catalog, skillIds: ids });
|
|
317
|
+
|
|
318
|
+
return [...expanded].map((id) => portableById.get(id)).sort((a, b) => a.id.localeCompare(b.id));
|
|
297
319
|
}
|
|
298
320
|
|
|
299
321
|
export function resolveSkillSelection({ catalog, detections, includeTags = [], excludeTags = [] }) {
|
|
@@ -306,7 +328,8 @@ export function resolveSkillSelection({ catalog, detections, includeTags = [], e
|
|
|
306
328
|
}
|
|
307
329
|
}
|
|
308
330
|
|
|
309
|
-
|
|
331
|
+
const expanded = expandSkillDependencies({ catalog, skillIds: [...requested] });
|
|
332
|
+
let selected = catalog.filter((skill) => expanded.has(skill.id) && skill.portable);
|
|
310
333
|
|
|
311
334
|
if (includeTags.length > 0) {
|
|
312
335
|
selected = selected.filter((skill) => includeTags.every((tag) => skill.tags.includes(tag)));
|
|
@@ -187,6 +187,15 @@ export async function detectProject(cwd) {
|
|
|
187
187
|
});
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
if ("gsap" in deps || "@gsap/react" in deps) {
|
|
191
|
+
addDetection(results, {
|
|
192
|
+
technology: "gsap",
|
|
193
|
+
confidence: 0.95,
|
|
194
|
+
reasons: ['Dependency "gsap" or "@gsap/react" found in package.json'],
|
|
195
|
+
recommendedSkillIds: ["gsap-animation"]
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
190
199
|
return results.sort((a, b) => b.confidence - a.confidence || a.technology.localeCompare(b.technology));
|
|
191
200
|
}
|
|
192
201
|
|