mastering-animate-presence
raphaelsalaja/skill · Agent Skill
Проверка шаблонов входа/присутствия Audit Motion и Framer Motion с практическими исправлениями для использования AnimatePresence.
Перейти к установке ↓Обзор
| Автор | |
|---|---|
| Репозиторий | raphaelsalaja/skill ↗ |
| Папка скилла | mastering-animate-presence |
| Звёзды | 42 |
| Форки | 5 |
| Файлы | 1 |
| Лицензия | MIT |
| Обновлён | 17 марта 2026 г. |
| Ссылки | Исходник скилла ↗ · Репозиторий ↗ |
Проверка Mozgi
Что мы нашли в файлах скилла. Подробности — по подписке.
Установка
Скилл — это папка с файлом SKILL.md. Выберите своего агента и скопируйте команды в терминал (macOS, Linux или Git Bash на Windows) в корне проекта.
Скопируйте промпт и вставьте в Claude, Codex или другого ассистента: он сам проверит скилл и подключит его.
Установи мне скилл «mastering-animate-presence» с mozgi.io (https://mozgi.io/skills/raphaelsalaja-mastering-animate-presence/). 1. Скачай архив: https://mozgi.io/skills/raphaelsalaja-mastering-animate-presence/download Если не скачивается — возьми папку скилла из исходника: https://github.com/raphaelsalaja/skill/tree/main/skills/mastering-animate-presence 2. Прочитай SKILL.md и остальные файлы. Проверь, что скилл безопасен: нет скрытых команд, отправки данных наружу или скриптов, которые делают не то, что описано. Если что-то подозрительно — остановись и скажи мне. 3. Положи папку «mastering-animate-presence» в папку скиллов своего агента: .claude/skills/ для Claude Code, .agents/skills/ для Codex, .cursor/skills/ для Cursor, .gemini/skills/ для Gemini CLI. В проекте — внутри проекта, иначе в домашней папке (~/.claude/skills/ и т. п.). 4. Убедись, что получилось <папка скиллов>/mastering-animate-presence/SKILL.md. 5. Коротко расскажи, что умеет этот скилл, и предложи попробовать его на моей задаче. Если какой-то шаг не можешь сделать сам — подскажи, что нажать или ввести.
git clone --depth 1 --branch main https://github.com/raphaelsalaja/skill.git /tmp/skill mkdir -p .claude/skills cp -r /tmp/skill/skills/mastering-animate-presence .claude/skills/mastering-animate-presence
Перезапустите Claude Code — скилл появится в списке, вызвать вручную: /mastering-animate-presence. Для всех проектов сразу — папка ~/.claude/skills.
git clone --depth 1 --branch main https://github.com/raphaelsalaja/skill.git /tmp/skill mkdir -p .agents/skills cp -r /tmp/skill/skills/mastering-animate-presence .agents/skills/mastering-animate-presence
Codex ищет скиллы в .agents/skills от текущей папки до корня репозитория; вызвать вручную — /skills или $mastering-animate-presence. Для всех проектов — ~/.agents/skills.
git clone --depth 1 --branch main https://github.com/raphaelsalaja/skill.git /tmp/skill mkdir -p .cursor/skills cp -r /tmp/skill/skills/mastering-animate-presence .cursor/skills/mastering-animate-presence
Cursor подхватит скилл при запуске; вызвать вручную — «/» в чате агента. Cursor также читает .claude/skills и .agents/skills. Для всех проектов — ~/.cursor/skills.
git clone --depth 1 --branch main https://github.com/raphaelsalaja/skill.git /tmp/skill mkdir -p .gemini/skills cp -r /tmp/skill/skills/mastering-animate-presence .gemini/skills/mastering-animate-presence
Gemini CLI сам предложит включить скилл, когда задача подходит, — вы подтверждаете. Для всех проектов — ~/.gemini/skills.
Просмотрите SKILL.md и сопутствующие файлы перед установкой. Клик по файлу — предпросмотр.
Содержимое SKILL.md
Оригинальный текст автора · только чтениеMastering AnimatePresence
Review Motion code for AnimatePresence and exit animation best practices.
How It Works
1. Read the specified files (or prompt user for files/pattern)
2. Check against all rules below
3. Output findings in file:line format
Rule Categories
| Priority | Category | Prefix |
|----------|----------|--------|
| 1 | Exit Animations | exit- |
| 2 | Presence Hooks | presence- |
| 3 | Mode Selection | mode- |
| 4 | Nested Exits | nested- |
Rules
Exit Animation Rules
exit-requires-wrapper
Conditional motion elements must be wrapped in AnimatePresence.
Fail:
{isVisible && (
<motion.div exit={{ opacity: 0 }} />
)}
Pass:
<AnimatePresence>
{isVisible && (
<motion.div exit={{ opacity: 0 }} />
)}
</AnimatePresence>
exit-prop-required
Elements inside AnimatePresence should have exit prop defined.
Fail:
<AnimatePresence>
{isOpen && (
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} />
)}
</AnimatePresence>
Pass:
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
/>
)}
</AnimatePresence>
exit-key-required
Dynamic lists inside AnimatePresence must have unique keys.
Fail:
<AnimatePresence>
{items.map((item, index) => (
<motion.div key={index} exit={{ opacity: 0 }} />
))}
</AnimatePresence>
Pass:
<AnimatePresence>
{items.map((item) => (
<motion.div key={item.id} exit={{ opacity: 0 }} />
))}
</AnimatePresence>
exit-matches-initial
Exit animation should mirror initial for symmetry.
Fail:
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ scale: 0 }}
/>
Pass:
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 20 }}
/>
Presence Hook Rules
presence-hook-in-child
useIsPresent must be called from child of AnimatePresence, not parent.
Fail:
function Parent() {
const isPresent = useIsPresent(); // Wrong location
return (
<AnimatePresence>
{show && <Child />}
</AnimatePresence>
);
}
Pass:
function Child() {
const isPresent = useIsPresent(); // Correct location
return <motion.div data-exiting={!isPresent} />;
}
presence-safe-to-remove
When using usePresence, always call safeToRemove after async work.
Fail:
function AsyncComponent() {
const [isPresent, safeToRemove] = usePresence();
useEffect(() => {
if (!isPresent) {
cleanup(); // Never calls safeToRemove
}
}, [isPresent]);
}
Pass:
function AsyncComponent() {
const [isPresent, safeToRemove] = usePresence();
useEffect(() => {
if (!isPresent) {
cleanup().then(safeToRemove);
}
}, [isPresent, safeToRemove]);
}
presence-disable-interactions
Disable interactions on exiting elements using isPresent.
Fail:
function Card() {
const isPresent = useIsPresent();
return <button onClick={handleClick}>Click</button>;
// Button clickable during exit
}
Pass:
function Card() {
const isPresent = useIsPresent();
return (
<button onClick={handleClick} disabled={!isPresent}>
Click
</button>
);
}
Mode Selection Rules
mode-wait-doubles-duration
Mode "wait" nearly doubles animation duration; adjust timing accordingly.
Fail:
<AnimatePresence mode="wait">
<motion.div transition={{ duration: 0.3 }} />
</AnimatePresence>
// Total time: ~600ms (too slow)
Pass:
<AnimatePresence mode="wait">
<motion.div transition={{ duration: 0.15 }} />
</AnimatePresence>
// Total time: ~300ms (acceptable)
mode-sync-layout-conflict
Mode "sync" causes layout conflicts; position exiting elements absolutely.
Fail:
<AnimatePresence mode="sync">
{items.map(item => (
<motion.div exit={{ opacity: 0 }}>{item}</motion.div>
))}
</AnimatePresence>
// Exiting and entering elements compete for space
Pass:
<AnimatePresence mode="popLayout">
{items.map(item => (
<motion.div exit={{ opacity: 0 }}>{item}</motion.div>
))}
</AnimatePresence>
mode-pop-layout-for-lists
Use popLayout mode for list reordering animations.
Fail:
<AnimatePresence>
{items.map(item => <ListItem key={item.id} />)}
</AnimatePresence>
// Layout shifts during exit
Pass:
<AnimatePresence mode="popLayout">
{items.map(item => <ListItem key={item.id} />)}
</AnimatePresence>
Nested Exit Rules
nested-propagate-required
Nested AnimatePresence must use propagate prop for coordinated exits.
Fail:
<AnimatePresence>
{isOpen && (
<motion.div exit={{ opacity: 0 }}>
<AnimatePresence>
{items.map(item => (
<motion.div key={item.id} exit={{ scale: 0 }} />
))}
</AnimatePresence>
</motion.div>
)}
</AnimatePresence>
// Children vanish instantly when parent exits
Pass:
<AnimatePresence propagate>
{isOpen && (
<motion.div exit={{ opacity: 0 }}>
<AnimatePresence propagate>
{items.map(item => (
<motion.div key={item.id} exit={{ scale: 0 }} />
))}
</AnimatePresence>
</motion.div>
)}
</AnimatePresence>
nested-consistent-timing
Parent and child exit durations should be coordinated.
Fail:
// Parent exits in 100ms, children in 500ms
<motion.div exit={{ opacity: 0 }} transition={{ duration: 0.1 }}>
<motion.div exit={{ scale: 0 }} transition={{ duration: 0.5 }} />
</motion.div>
Pass:
// Parent waits for children or exits simultaneously
<motion.div exit={{ opacity: 0 }} transition={{ duration: 0.2 }}>
<motion.div exit={{ scale: 0 }} transition={{ duration: 0.15 }} />
</motion.div>
Output Format
When reviewing files, output findings as:
file:line - [rule-id] description of issue
Example:
components/modal/index.tsx:23 - [exit-requires-wrapper] Conditional motion.div not wrapped in AnimatePresence
components/modal/index.tsx:45 - [exit-prop-required] Missing exit prop on motion element
Summary Table
After findings, output a summary:
| Rule | Count | Severity |
|------|-------|----------|
| exit-requires-wrapper | 2 | HIGH |
| exit-prop-required | 3 | HIGH |
| mode-wait-doubles-duration | 1 | MEDIUM |
References
Вопросы и ответы
Что делает скилл mastering-animate-presence?
Проверка шаблонов входа/присутствия Audit Motion и Framer Motion с практическими исправлениями для использования AnimatePresence.
Как установить mastering-animate-presence?
Откройте блок «Установка» на этой странице и выберите своего агента — Claude Code, Codex, Cursor или Gemini CLI: там готовые команды, которые копируют папку скилла в нужное место. Либо скопируйте промпт из вкладки «Через ассистента» — ассистент сам проверит и подключит скилл.
С какими нейросетями работает mastering-animate-presence?
Скиллы — это обычные инструкции в Markdown (формат Agent Skills), поэтому mastering-animate-presence подходит любому агенту, который читает SKILL.md: Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode и другие. Модель загружает инструкции только когда задача подходит под описание скилла.
Скилл mastering-animate-presence бесплатный?
Скилл опубликован автором raphaelsalaja в открытом доступе под лицензией MIT. Сам скилл ничего не стоит — вы платите только своему провайдеру нейросети за использованные токены.
Безопасно ли устанавливать скиллы?
Скилл — это инструкции, которые агент будет выполнять, поэтому перед установкой прочитайте SKILL.md и сопутствующие файлы. Скрипты из папки скилла запускаются только если их запустит агент — следите за тем, что он делает, и не давайте лишних прав.
Чем скилл отличается от MCP-сервера или плагина?
MCP-сервер и плагин дают модели новые инструменты — код, который выполняется и возвращает результат. Скилл даёт знания и порядок действий: как подходить к задаче, какие шаги делать и как выглядит хороший результат. Ему не нужен сервер или ключ API.