auto-animate by jezweb/claude-skills
npx skills add https://github.com/jezweb/claude-skills --skill auto-animate包 : @formkit/auto-animate@0.9.0 (当前) 框架 : React, Vue, Solid, Svelte, Preact 最后更新 : 2026-01-21
// 使用仅客户端导入以防止 SSR 错误
import { useState, useEffect } from "react";
export function useAutoAnimateSafe<T extends HTMLElement>() {
const [parent, setParent] = useState<T | null>(null);
useEffect(() => {
if (typeof window !== "undefined" && parent) {
import("@formkit/auto-animate").then(({ default: autoAnimate }) => {
autoAnimate(parent);
});
}
}, [parent]);
return [parent, setParent] as const;
}
为何重要 : 防止问题 #1 (SSR/Next.js 导入错误)。AutoAnimate 使用了服务器上不可用的 DOM API。
此技能可预防 15 个已记录的问题:
错误 : "无法从非 EcmaScript 模块导入命名导出 'useEffect'" 来源 : https://github.com/formkit/auto-animate/issues/55 原因 : AutoAnimate 使用了服务器上不可用的 DOM API 预防 : 使用动态导入 (参见 templates/vite-ssr-safe.tsx)
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
错误 : 当父元素是条件渲染时动画不工作 来源 : https://github.com/formkit/auto-animate/issues/8 原因 : Ref 无法附加到不存在的元素 预防 :
React 模式 :
// ❌ 错误
{showList && <ul ref={parent}>...</ul>}
// ✅ 正确
<ul ref={parent}>{showList && items.map(...)}</ul>
Vue.js 模式 :
<!-- ❌ 错误 - 父元素条件渲染 -->
<ul v-if="showList" ref="parent">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
<!-- ✅ 正确 - 子元素条件渲染 -->
<ul ref="parent">
<li v-if="showList" v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</ul>
来源 : React Issue #8, Vue Issue #193
错误 : 项目动画不正确或闪烁 来源 : 官方文档 原因 : React 无法跟踪哪些项目发生了变化 预防 : 始终使用唯一、稳定的键 (key={item.id})
错误 : 元素突然改变宽度而不是平滑动画,或者容器在移除时抖动 来源 : 官方文档, Issue #212 原因 : flex-grow: 1 等待周围内容,导致时序问题 预防 : 对动画元素使用显式宽度而不是 flex-grow
// ❌ 错误 - 导致抖动
<ul ref={parent} style={{ display: 'flex' }}>
{items.map(item => (
<li key={item.id} style={{ flex: '1 1 auto' }}>{item.text}</li>
))}
</ul>
// ✅ 正确 - 固定尺寸
<ul ref={parent} style={{ display: 'flex', gap: '1rem' }}>
{items.map(item => (
<li
key={item.id}
style={{ minWidth: '200px', maxWidth: '200px' }}
>
{item.text}
</li>
))}
</ul>
维护者说明 : justin-schroeder 确认 flex 容器需要固定尺寸
错误 : 移除行时表格结构损坏 来源 : https://github.com/formkit/auto-animate/issues/7 原因 : Display: table-row 与动画冲突 预防 : 应用于 <tbody> 而不是单个行,或使用基于 div 的布局
错误 : "找不到模块 '@formkit/auto-animate/react'" 来源 : https://github.com/formkit/auto-animate/issues/29 原因 : Jest 无法正确解析 ESM 导出 预防 : 在 jest.config.js 中配置 moduleNameMapper
错误 : "包未导出路径 '.'" 来源 : https://github.com/formkit/auto-animate/issues/36 原因 : ESM/CommonJS 条件不匹配 预防 : 配置 esbuild 以正确处理 ESM 模块
错误 : 添加 AutoAnimate 后布局损坏 来源 : 官方文档 原因 : 父元素自动获得 position: relative 预防 : 在 CSS 中考虑定位变化或显式设置
错误 : "无法解析指令: auto-animate" 来源 : https://github.com/formkit/auto-animate/issues/43 原因 : 插件未正确注册 预防 : 在 Vue/Nuxt 配置中进行正确的插件设置 (参见 references/)
Nuxt 3 说明 : 需要 v0.8.2+ (2024年4月)。早期版本存在 Daniel Roe 修复的 ESM 导入问题。参见 Issue #199
错误 : 构建失败,提示 "仅 ESM 包" 来源 : https://github.com/formkit/auto-animate/issues/72 原因 : CommonJS 构建环境 预防 : 为 Angular 包格式配置 ng-packagr
错误 : 在 React 19 StrictMode 中,子元素动画不工作 来源 : https://github.com/formkit/auto-animate/issues/232 原因 : StrictMode 调用 useEffect 两次,触发 autoAnimate 初始化两次 预防 : 使用 ref 跟踪初始化状态
// ❌ 错误 - 在 StrictMode 中失效
const [parent] = useAutoAnimate();
// ✅ 正确 - 防止双重初始化
const [parent] = useAutoAnimate();
const initialized = useRef(false);
useEffect(() => {
if (initialized.current) return;
initialized.current = true;
}, []);
注意 : React 19 在开发环境中默认启用 StrictMode。这会影响所有 React 19+ 项目。
错误 : 当列表在视口外时动画损坏 来源 : https://github.com/formkit/auto-animate/issues/222 原因 : Chrome 可能不会为屏幕外元素运行 Animation API 预防 : 在应用 autoAnimate 之前确保父元素可见
const isInViewport = (element) => {
const rect = element.getBoundingClientRect();
return rect.top >= 0 && rect.bottom <= window.innerHeight;
};
useEffect(() => {
if (parent.current && isInViewport(parent.current)) {
autoAnimate(parent.current);
}
}, [parent]);
错误 : 移除的项目在淡出过程中覆盖其他项目 来源 : https://github.com/formkit/auto-animate/issues/231 原因 : 退出动画保持 z-index,覆盖了活动内容 预防 : 添加显式的 z-index 处理
// CSS 解决方法
<style>{`
[data-auto-animate-target] {
z-index: -1 !important;
}
`}</style>
错误 : 调用 enable(false) 无法防止拖放期间的动画 来源 : https://github.com/formkit/auto-animate/issues/215 原因 : 在拖放过程中禁用不可靠 预防 : 在拖放期间有条件地移除 ref
const [isDragging, setIsDragging] = useState(false);
const [parent] = useAutoAnimate();
return (
<ul ref={isDragging ? null : parent}>
{/* items */}
</ul>
);
错误 : 父元素变换后,项目从错误位置开始动画 来源 : https://github.com/formkit/auto-animate/issues/227 原因 : 项目记住了变换前的位置 预防 : 延迟 autoAnimate 直到变换完成
useEffect(() => {
if (showList && parent.current) {
setTimeout(() => {
autoAnimate(parent.current);
}, 300); // 匹配 CSS 过渡持续时间
}
}, [showList]);
✅ 使用唯一、稳定的键 - key={item.id} 而不是 key={index} ✅ 保持父元素在 DOM 中 - 父元素 ref 始终渲染 ✅ 对 SSR 使用仅客户端 - 服务器环境使用动态导入 ✅ 尊重无障碍性 - 保持 disrespectUserMotionPreference: false ✅ 测试禁用动画的情况 - 验证 UI 在没有动画的情况下正常工作 ✅ 使用显式宽度 - 避免在动画元素上使用 flex-grow ✅ 对表格应用 tbody - 而不是单个行
❌ 条件渲染父元素 - {show && <ul ref={parent}>} ❌ 使用索引作为键 - key={index} 会破坏动画 ❌ 忽略 SSR - 在 Cloudflare Workers/Next.js 中会损坏 ❌ 强制动画 - disrespectUserMotionPreference: true 破坏无障碍性 ❌ 直接动画表格 - 使用 tbody 或基于 div 的布局 ❌ 跳过唯一键 - 正确动画所必需 ❌ 复杂动画 - 使用 Motion 代替
注意 : AutoAnimate 自动尊重 prefers-reduced-motion (切勿禁用此功能)。
注意 : 这些提示来自社区讨论。请根据您的版本进行验证。
来源 : Issue #230 | 置信度 : 中等 适用于 : v0.8.2+
当包被模拟时,测试可能会冻结约 10 秒。添加 ResizeObserver 模拟:
// jest.setup.js
global.ResizeObserver = jest.fn().mockImplementation(() => ({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
}));
// __mocks__/@formkit/auto-animate.js
const autoAnimate = jest.fn(() => () => {});
const useAutoAnimate = jest.fn(() => [null, jest.fn(), jest.fn()]);
module.exports = { default: autoAnimate, useAutoAnimate };
来源 : Issue #180 | 置信度 : 低 适用于 : 所有版本
对于长期运行的 SPA,确保正确清理:
useEffect(() => {
const cleanup = autoAnimate(parent.current);
return () => cleanup && cleanup();
}, []);
// useAutoAnimate 钩子自动处理清理
const [parent] = useAutoAnimate(); // 推荐
最新 : @formkit/auto-animate@0.9.0 (2025年9月5日)
近期发布 :
v0.9.0 (2025年9月5日) - 当前稳定版
v0.8.2 (2024年4月10日) - 修复了 Nuxt 3 ESM 导入,ResizeObserver 防护
{ "dependencies": { "@formkit/auto-animate": "^0.9.0" } }
框架兼容性 : React 18+, Vue 3+, Solid, Svelte, Preact
重要 : 对于 Nuxt 3 用户,需要 v0.8.2+。早期版本存在 ESM 导入问题
参见捆绑的资源:
templates/ - 可直接复制的示例 (SSR 安全、手风琴、通知、表单)references/ - CSS 冲突、SSR 模式、库比较每周安装量
355
仓库
GitHub 星标
650
首次出现
2026年1月20日
安全审计
安装于
claude-code289
opencode239
gemini-cli236
cursor218
antigravity214
codex210
Package : @formkit/auto-animate@0.9.0 (current) Frameworks : React, Vue, Solid, Svelte, Preact Last Updated : 2026-01-21
// Use client-only import to prevent SSR errors
import { useState, useEffect } from "react";
export function useAutoAnimateSafe<T extends HTMLElement>() {
const [parent, setParent] = useState<T | null>(null);
useEffect(() => {
if (typeof window !== "undefined" && parent) {
import("@formkit/auto-animate").then(({ default: autoAnimate }) => {
autoAnimate(parent);
});
}
}, [parent]);
return [parent, setParent] as const;
}
Why this matters : Prevents Issue #1 (SSR/Next.js import errors). AutoAnimate uses DOM APIs not available on server.
This skill prevents 15 documented issues:
Error : "Can't import the named export 'useEffect' from non EcmaScript module" Source : https://github.com/formkit/auto-animate/issues/55 Why It Happens : AutoAnimate uses DOM APIs not available on server Prevention : Use dynamic imports (see templates/vite-ssr-safe.tsx)
Error : Animations don't work when parent is conditional Source : https://github.com/formkit/auto-animate/issues/8 Why It Happens : Ref can't attach to non-existent element Prevention :
React Pattern :
// ❌ Wrong
{showList && <ul ref={parent}>...</ul>}
// ✅ Correct
<ul ref={parent}>{showList && items.map(...)}</ul>
Vue.js Pattern :
<!-- ❌ Wrong - parent conditional -->
<ul v-if="showList" ref="parent">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
<!-- ✅ Correct - children conditional -->
<ul ref="parent">
<li v-if="showList" v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</ul>
Source : React Issue #8, Vue Issue #193
Error : Items don't animate correctly or flash Source : Official docs Why It Happens : React can't track which items changed Prevention : Always use unique, stable keys (key={item.id})
Error : Elements snap to width instead of animating smoothly, or container shakes on remove Source : Official docs, Issue #212 Why It Happens : flex-grow: 1 waits for surrounding content, causing timing issues Prevention : Use explicit width instead of flex-grow for animated elements
// ❌ Wrong - causes shaking
<ul ref={parent} style={{ display: 'flex' }}>
{items.map(item => (
<li key={item.id} style={{ flex: '1 1 auto' }}>{item.text}</li>
))}
</ul>
// ✅ Correct - fixed sizes
<ul ref={parent} style={{ display: 'flex', gap: '1rem' }}>
{items.map(item => (
<li
key={item.id}
style={{ minWidth: '200px', maxWidth: '200px' }}
>
{item.text}
</li>
))}
</ul>
Maintainer Note : justin-schroeder confirmed fixed sizes are required for flex containers
Error : Table structure breaks when removing rows Source : https://github.com/formkit/auto-animate/issues/7 Why It Happens : Display: table-row conflicts with animations Prevention : Apply to <tbody> instead of individual rows, or use div-based layouts
Error : "Cannot find module '@formkit/auto-animate/react'" Source : https://github.com/formkit/auto-animate/issues/29 Why It Happens : Jest doesn't resolve ESM exports correctly Prevention : Configure moduleNameMapper in jest.config.js
Error : "Path '.' not exported by package" Source : https://github.com/formkit/auto-animate/issues/36 Why It Happens : ESM/CommonJS condition mismatch Prevention : Configure esbuild to handle ESM modules properly
Error : Layout breaks after adding AutoAnimate Source : Official docs Why It Happens : Parent automatically gets position: relative Prevention : Account for position change in CSS or set explicitly
Error : "Failed to resolve directive: auto-animate" Source : https://github.com/formkit/auto-animate/issues/43 Why It Happens : Plugin not registered correctly Prevention : Proper plugin setup in Vue/Nuxt config (see references/)
Nuxt 3 Note : Requires v0.8.2+ (April 2024). Earlier versions have ESM import issues fixed by Daniel Roe. See Issue #199
Error : Build fails with "ESM-only package" Source : https://github.com/formkit/auto-animate/issues/72 Why It Happens : CommonJS build environment Prevention : Configure ng-packagr for Angular Package Format
Error : Child animations don't work in React 19 StrictMode Source : https://github.com/formkit/auto-animate/issues/232 Why It Happens : StrictMode calls useEffect twice, triggering autoAnimate initialization twice Prevention : Use ref to track initialization
// ❌ Wrong - breaks in StrictMode
const [parent] = useAutoAnimate();
// ✅ Correct - prevents double initialization
const [parent] = useAutoAnimate();
const initialized = useRef(false);
useEffect(() => {
if (initialized.current) return;
initialized.current = true;
}, []);
Note : React 19 enables StrictMode by default in development. This affects all React 19+ projects.
Error : Animations broken when list is outside viewport Source : https://github.com/formkit/auto-animate/issues/222 Why It Happens : Chrome may not run Animation API for off-screen elements Prevention : Ensure parent is visible before applying autoAnimate
const isInViewport = (element) => {
const rect = element.getBoundingClientRect();
return rect.top >= 0 && rect.bottom <= window.innerHeight;
};
useEffect(() => {
if (parent.current && isInViewport(parent.current)) {
autoAnimate(parent.current);
}
}, [parent]);
Error : Removed items overlay other items during fade out Source : https://github.com/formkit/auto-animate/issues/231 Why It Happens : Exit animation maintains z-index, covering active content Prevention : Add explicit z-index handling
// CSS workaround
<style>{`
[data-auto-animate-target] {
z-index: -1 !important;
}
`}</style>
Error : Calling enable(false) doesn't prevent animations during drag Source : https://github.com/formkit/auto-animate/issues/215 Why It Happens : Disable doesn't work reliably mid-drag Prevention : Conditionally remove ref during drag
const [isDragging, setIsDragging] = useState(false);
const [parent] = useAutoAnimate();
return (
<ul ref={isDragging ? null : parent}>
{/* items */}
</ul>
);
Error : Items animate from wrong position after parent transform Source : https://github.com/formkit/auto-animate/issues/227 Why It Happens : Items remember original position before transform Prevention : Delay autoAnimate until transform completes
useEffect(() => {
if (showList && parent.current) {
setTimeout(() => {
autoAnimate(parent.current);
}, 300); // Match CSS transition duration
}
}, [showList]);
✅ Use unique, stable keys - key={item.id} not key={index} ✅ Keep parent in DOM - Parent ref element always rendered ✅ Client-only for SSR - Dynamic import for server environments ✅ Respect accessibility - Keep disrespectUserMotionPreference: false ✅ Test with motion disabled - Verify UI works without animations ✅ Use explicit width - Avoid flex-grow on animated elements ✅ Apply to tbody for tables - Not individual rows
❌ Conditional parent - {show && <ul ref={parent}>} ❌ Index as key - key={index} breaks animations ❌ Ignore SSR - Will break in Cloudflare Workers/Next.js ❌ Force animations - disrespectUserMotionPreference: true breaks accessibility ❌ Animate tables directly - Use tbody or div-based layout ❌ Skip unique keys - Required for proper animation ❌ Complex animations - Use Motion instead
Note : AutoAnimate respects prefers-reduced-motion automatically (never disable this).
Note : These tips come from community discussions. Verify against your version.
Source : Issue #230 | Confidence : MEDIUM Applies to : v0.8.2+
Tests may freeze for ~10 seconds when package is mocked. Add ResizeObserver mock:
// jest.setup.js
global.ResizeObserver = jest.fn().mockImplementation(() => ({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
}));
// __mocks__/@formkit/auto-animate.js
const autoAnimate = jest.fn(() => () => {});
const useAutoAnimate = jest.fn(() => [null, jest.fn(), jest.fn()]);
module.exports = { default: autoAnimate, useAutoAnimate };
Source : Issue #180 | Confidence : LOW Applies to : All versions
For long-lived SPAs, ensure proper cleanup:
useEffect(() => {
const cleanup = autoAnimate(parent.current);
return () => cleanup && cleanup();
}, []);
// useAutoAnimate hook handles cleanup automatically
const [parent] = useAutoAnimate(); // Preferred
Latest : @formkit/auto-animate@0.9.0 (Sept 5, 2025)
Recent Releases :
v0.9.0 (Sept 5, 2025) - Current stable
v0.8.2 (April 10, 2024) - Fixed Nuxt 3 ESM imports, ResizeObserver guard
{ "dependencies": { "@formkit/auto-animate": "^0.9.0" } }
Framework Compatibility : React 18+, Vue 3+, Solid, Svelte, Preact
Important : For Nuxt 3 users, v0.8.2+ is required. Earlier versions have ESM import issues
See bundled resources:
templates/ - Copy-paste examples (SSR-safe, accordion, toast, forms)references/ - CSS conflicts, SSR patterns, library comparisonsWeekly Installs
355
Repository
GitHub Stars
650
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code289
opencode239
gemini-cli236
cursor218
antigravity214
codex210
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
105,000 周安装
react-grab:AI 开发助手,一键复制 React 组件上下文到剪贴板
343 周安装
风险评估插件:AI驱动风险矩阵与登记册生成工具,系统识别操作财务合规战略安全风险
344 周安装
Agent Manager Skill:并行运行多个CLI代理,管理tmux会话和任务分配
344 周安装
Flags SDK:Next.js和SvelteKit功能开关工具包,支持Vercel等提供商
344 周安装
sag 命令行工具:使用 ElevenLabs TTS 进行本地文本转语音播放与音频生成
344 周安装
Slack消息最佳实践指南:mrkdwn格式、消息结构与频道礼仪完整教程
345 周安装