mcpField
A
auto-animate

auto-animate

github.com/jezweb设计与 UI1.1k355 次安装3 周前更新
代码仓库

关于 auto-animate

面向使用 @formkit/auto-animate 的开发者,提供动画集成与排错指南,涵盖 SSR、框架配置和常见布局问题。

主要功能

  1. 01SSR 安全集成建议
  2. 02React、Vue 等框架示例
  3. 0315 类问题排查建议
  4. 04可访问性与动效注意事项
  5. 05附带模板和参考资料

适用场景

  1. 01排查 Next.js 的导入错误
  2. 02修复列表动画闪烁或错位
  3. 03处理 Vue 或 Nuxt 注册问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jezweb/claude-skills --skill auto-animate

安装后在 Claude Code 中输入/auto-animate确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
.claude-plugin/
plugin.json
assets/
example-template.txt
references/
auto-animate-vs-motion.md
css-conflicts.md
example-reference.md
ssr-patterns.md
scripts/
example-script.sh
init-auto-animate.sh
templates/
accordion.tsx
filter-sort-list.tsx
form-validation.tsx
react-basic.tsx
react-typescript.tsx
toast-notifications.tsx
vite-ssr-safe.tsx

详细介绍

AutoAnimate - 错误预防指南

软件包:@formkit/[email protected](当前版本) 框架:React、Vue、Solid、Svelte、Preact 最后更新:2026-01-21


SSR 安全模式(对 Cloudflare Workers/Next.js 至关重要)

// 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;
}

为何重要:可避免问题 #1(SSR/Next.js 导入错误)。AutoAnimate 使用了服务器上不可用的 DOM API。


已知问题预防(15 个已记录错误)

此技能可预防 15 个已记录的问题:

问题 #1:SSR/Next.js 导入错误

错误:“无法从非 EcmaScript 模块导入命名导出 ‘useEffect’” 来源:https://github.com/formkit/auto-animate/issues/55 原因:AutoAnimate 使用了服务器上不可用的 DOM API 预防措施:使用动态导入(参见 templates/vite-ssr-safe.tsx)

问题 #2:条件渲染父元素

错误:父元素为条件渲染时,动画无法运行 来源:https://github.com/formkit/auto-animate/issues/8 原因:Ref 无法附加到不存在的元素 预防措施:

React 模式:

// ❌ Wrong
{showList && <ul ref={parent}>...</ul>}

// ✅ Correct
<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 问题 #8,Vue 问题 #193

问题 #3:缺少唯一键

错误:项目动画异常或闪烁 来源:官方文档 原因:React 无法跟踪哪些项目发生了变化 预防措施:始终使用唯一且稳定的键(key={item.id})

问题 #4:Flexbox 宽度和抖动问题

错误:元素直接跳到目标宽度,而不是平滑地播放动画;或者移除元素时容器抖动 来源:官方文档,问题 #212 原因:flex-grow: 1 会等待周围内容,导致时序问题 预防措施:对带动画的元素使用明确的宽度,而不是 flex-grow

// ❌ 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>

维护者说明:justin-schroeder 已确认,Flex 容器需要固定尺寸

问题 #5:表格行显示问题

错误:移除行时表格结构会损坏 来源:https://github.com/formkit/auto-animate/issues/7 原因:Display: table-row 与动画冲突 预防措施:将其应用于 <tbody>,而不是单独的行;或者使用基于 div 的布局

问题 #6:Jest 测试错误

错误:“找不到模块 ‘@formkit/auto-animate/react’” 来源:https://github.com/formkit/auto-animate/issues/29 原因:Jest 无法正确解析 ESM 导出 预防措施:在 jest.config.js 中配置 moduleNameMapper

问题 #7:esbuild 兼容性

错误:“软件包未导出路径 ‘.’” 来源:https://github.com/formkit/auto-animate/issues/36 原因:ESM/CommonJS 条件不匹配 预防措施:配置 esbuild,以正确处理 ESM 模块

问题 #8:CSS 定位的副作用

错误:添加 AutoAnimate 后布局损坏 来源:官方文档 原因:父元素会自动获得 position: relative 预防措施:在 CSS 中考虑定位变化,或显式设置定位

问题 #9:Vue/Nuxt 注册错误

错误:“无法解析指令:auto-animate” 来源:https://github.com/formkit/auto-animate/issues/43 原因:插件未正确注册 预防措施:在 Vue/Nuxt 配置中正确设置插件(参见 references/)

Nuxt 3 说明:需要 v0.8.2+(2024 年 4 月)。较早版本存在 ESM 导入问题,已由 Daniel Roe 修复。参见问题 #199

问题 #10:Angular ESM 问题

错误:构建失败,并提示“仅支持 ESM 的软件包” 来源:https://github.com/formkit/auto-animate/issues/72 原因:CommonJS 构建环境 预防措施:为 Angular Package Format 配置 ng-packagr

问题 #11:React 19 StrictMode 双重调用 Bug

错误:React 19 StrictMode 下子元素动画无法运行 来源:https://github.com/formkit/auto-animate/issues/232 原因:StrictMode 会调用两次 useEffect,导致 autoAnimate 初始化两次 预防措施:使用 ref 跟踪初始化状态

// ❌ 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;
}, []);

注意:React 19 在开发环境中默认启用 StrictMode。这会影响所有 React 19+ 项目。

问题 #12:视口外动画失效

错误:列表位于视口外时,动画失效 来源: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]);
问题 #13:已删除的元素覆盖现有内容

错误:移除的项目在淡出期间覆盖其他项目 来源:https://github.com/formkit/auto-animate/issues/231 原因:退出动画会保留 z-index,遮挡活动内容 预防措施:显式处理 z-index

// CSS workaround
<style>{`
  [data-auto-animate-target] {
    z-index: -1 !important;
  }
`}</style>
问题 #14:拖放期间无法禁用

错误:调用 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>
);
问题 #15:CSS Transform 父元素位置 Bug

错误:父元素执行 transform 后,项目从错误的位置开始动画 来源:https://github.com/formkit/auto-animate/issues/227 原因:项目会记住 transform 前的原始位置 预防措施:等 transform 完成后再调用 autoAnimate

useEffect(() => {
  if (showList && parent.current) {
    setTimeout(() => {
      autoAnimate(parent.current);
    }, 300); // Match CSS transition duration
  }
}, [showList]);

关键规则(避免错误)

始终做到

✅ 使用唯一且稳定的键 - 使用 key={item.id},而不是 key={index} ✅ 让父元素保留在 DOM 中 - 父元素的 ref 始终保持渲染 ✅ SSR 时仅在客户端使用 - 在服务器环境中使用动态导入 ✅ 遵循无障碍要求 - 保持 disrespectUserMotionPreference: false ✅ 在禁用动画时测试 - 验证界面在没有动画时仍能正常运行 ✅ 使用显式宽度 - 避免在动画元素上使用 flex-grow ✅ 对表格应用于 tbody - 不要应用于单独的行

切勿这样做

❌ 有条件地渲染父元素 - {show && <ul ref={parent}>} ❌ 将索引用作键 - key={index} 会导致动画失效 ❌ 忽略 SSR - 会在 Cloudflare Workers/Next.js 中出错 ❌ 强制播放动画 - disrespectUserMotionPreference: true 会影响无障碍体验 ❌ 直接对表格添加动画 - 使用 tbody 或基于 div 的布局 ❌ 省略唯一键 - 正确播放动画的必要条件 ❌ 使用复杂动画 - 改用 Motion

注意:AutoAnimate 会自动遵循 prefers-reduced-motion(切勿禁用此行为)。


社区技巧(来自社区)

注意:这些技巧来自社区讨论。请根据你使用的版本进行验证。

技巧:使用模拟的包避免测试卡顿

来源:问题 #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 };
技巧:防止内存泄漏

来源:问题 #180 | 可信度:低 适用版本:所有版本

对于长期运行的 SPA,请确保正确清理:

useEffect(() => {
  const cleanup = autoAnimate(parent.current);
  return () => cleanup && cleanup();
}, []);

// useAutoAnimate hook handles cleanup automatically
const [parent] = useAutoAnimate(); // Preferred

包版本

最新版本:@formkit/[email protected](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 模式、库比较

评论

支持 Markdown