diff --git a/.cursor/rules/demo.mdc b/.cursor/rules/demo.mdc new file mode 100644 index 0000000000..0bfb1d3732 --- /dev/null +++ b/.cursor/rules/demo.mdc @@ -0,0 +1,80 @@ +--- +description: +globs: components/*/demo/** +alwaysApply: false +--- +# Demo 规范 + +- demo 代码尽可能简洁 +- 避免冗余代码,方便用户复制到项目直接使用 +- 每个 demo 聚焦展示一个功能点 +- 提供中英文两个版本的说明 +- demo 文件扩展名: + - 基础 demo:.tsx + - markdown 说明:.md +- 遵循展示优先原则,确保视觉效果良好 +- 展示组件的主要使用场景 +- 按照由简到繁的顺序排列 demo +- 确保 demo 在各种尺寸下都能正常展示 +- 对于复杂交互提供必要的操作说明 + +## 文件组织 + +- 每个组件演示包含 `.md`(说明文档)和 `.tsx`(实际代码)两个文件 +- 位置:组件目录下的 `demo` 子目录,如 `components/button/demo/` +- 命名:短横线连接的小写英文单词,如 `basic.tsx`、`custom-filter.tsx` +- 文件名应简洁地描述示例内容 + +## MD 文档规范 + +- 必须包含 `## zh-CN` 和 `## en-US` 两种语言说明 +- 内容简洁明了,突出组件特性和用法 +- 避免冗长段落,必要时使用列表或粗体 +- 标注注意事项和实验性功能 + +## TSX 代码规范 + +- 导入顺序:React → 依赖库 → 组件库 → 自定义组件 → 类型 → 样式 +- 类型:为复杂数据定义清晰接口,避免 `any` +- 结构: + - 使用函数式组件和 Hooks + - 复杂逻辑提取为独立函数 + - 状态管理用 `useState`/`useEffect` +- 风格: + - 2空格缩进,箭头函数,驼峰命名 + - 常量大写+下划线,布尔props用`is`/`has`前缀 + +## 示例类型 + +1. **基础用法**:展示最简用法,置于首位,代码精简 +2. **变体展示**:不同大小、类型、状态,合理分组 +3. **交互演示**:展示状态变化和用户交互 +4. **数据交互**:展示加载、过滤、排序等 +5. **边界情况**:空数据、错误状态处理 + +## 代码质量 + +- 实用且专注于单一功能 +- 关键处添加简洁注释 +- 使用有意义的数据和变量 +- 优先使用 antd 内置组件,减少外部依赖 +- 性能优化:适当使用 `useMemo`/`useCallback`,清理副作用 + +## 命名规则 + +- 基础文件:`basic.tsx`、`controlled.tsx` 等 +- 调试类:使用 `debug-` 前缀 +- 实验性:使用 `experimental-` 前缀 + +## 特殊示例 + +- **调试示例**:用于开发测试,通常不在文档显示 +- **无障碍**:展示标签关联和键盘导航 +- **响应式**:展示不同视口下的行为 +- **多语言**:展示国际化配置方法 + +## 质量要求 + +- 确保代码运行正常,无控制台错误 +- 适配常见浏览器 +- 避免过时 API,及时更新到新推荐用法 diff --git a/.cursor/rules/docs.mdc b/.cursor/rules/docs.mdc new file mode 100644 index 0000000000..6213f76cf4 --- /dev/null +++ b/.cursor/rules/docs.mdc @@ -0,0 +1,60 @@ +--- +description: 规范项目文档和 Changelog +globs: ["**/CHANGELOG*.md", "components/**/index.*.md"] +alwaysApply: false +--- +# 文档和 Changelog 规范 + +## 基本要求 + +- 提供中英文两个版本 +- 新的属性需要声明可用的版本号 +- 属性命名符合 antd 的 API 命名规则:https://github.com/ant-design/ant-design/wiki/API-Naming-rules + +## Changelog 规范 + +- 在 CHANGELOG.en-US.md 和 CHANGELOG.zh-CN.md 书写每个版本的变更 +- 对用户使用上无感知的改动建议(文档修补、微小的样式优化、代码风格重构等等)不要提及,保持 CHANGELOG 的内容有效性 +- 非 antd 组件的改动(如工程化、构建工具、开发流程等)在 changelog 区块中写 "-" +- 用面向开发者的角度和叙述方式撰写 CHANGELOG,不描述修复细节,描述问题和对开发者的影响;描述用户的原始问题,而非你的解决方式 + +### 示例 + +- 不好的例子:修复组件 Typography 的 dom 结构问题 +- 好的例子:修复了 List.Item 中内容空格丢失的问题 + +### 其他要求 + +- 新增属性时,建议用易于理解的语言补充描述用户可以感知的变化 +- 尽量给出原始的 PR 链接,社区提交的 PR 改动加上提交者的链接 +- 底层模块升级中间版本要去 rc-component 里找到改动,给出变动说明 +- 建议参考之前版本的日志写法 +- 将同组件的改动放在一起,内容子级缩进 + +### Changelog Emoji 规范 + +- 🐞 Bug 修复 +- 💄 样式更新或 token 更新 +- 🆕 新增特性,新增属性 +- 🔥 极其值得关注的新增特性 +- 🇺🇸🇨🇳🇬🇧 国际化改动 +- 📖 📝 文档或网站改进 +- ✅ 新增或更新测试用例 +- 🛎 更新警告/提示信息 +- ⌨️ ♿ 可访问性增强 +- 🗑 废弃或移除 +- 🛠 重构或工具链优化 +- ⚡️ 性能提升 + +# 文档规范 + +- 提供中英文两个版本 +- 新属性需声明可用的版本号 +- 属性命名符合 API 命名规则 +- 组件文档包含:使用场景、基础用法、API 说明 +- 文档示例应简洁明了 +- 属性的描述应清晰易懂 +- 对复杂功能提供详细说明 +- 加入 TypeScript 定义 +- 提供常见问题解答 +- 更新文档时同步更新中英文版本 diff --git a/.cursor/rules/git.mdc b/.cursor/rules/git.mdc new file mode 100644 index 0000000000..ab0cc99af5 --- /dev/null +++ b/.cursor/rules/git.mdc @@ -0,0 +1,128 @@ +--- +description: +globs: +alwaysApply: true +--- +# Git 规范 + +## 分支管理 + +- 禁止直接提交到以下保护分支: + - `master`:主分支,用于发布 + - `feature`:特性分支,用于开发新版本 + - `next`:下一个版本分支 + +## 开发流程 + +1. 从保护分支(通常是 `master`)创建新的功能分支 +2. 在新分支上进行开发 +3. 提交 Pull Request 到目标分支 +4. 等待 Code Review 和 CI 通过 +5. 合并到目标分支 + +## 分支命名规范 + +- 功能开发:`feat/description-of-feature` + - 例如:`feat/add-dark-mode` + - 例如:`feat/improve-table-performance` +- 问题修复:`fix/issue-number-or-description` + - 例如:`fix/button-style-issue` + - 例如:`fix/issue-1234` +- 文档更新:`docs/what-is-changed` + - 例如:`docs/update-api-reference` + - 例如:`docs/fix-typos` +- 代码重构:`refactor/what-is-changed` + - 例如:`refactor/button-component` + - 例如:`refactor/remove-deprecated-api` +- 样式修改:`style/what-is-changed` + - 例如:`style/update-button-tokens` + - 例如:`style/improve-mobile-layout` +- 测试相关:`test/what-is-changed` + - 例如:`test/add-button-test` + - 例如:`test/improve-coverage` +- 构建相关:`build/what-is-changed` + - 例如:`build/upgrade-webpack` + - 例如:`build/fix-ts-config` +- 持续集成:`ci/what-is-changed` + - 例如:`ci/add-e2e-test` + - 例如:`ci/fix-deploy-script` +- 性能优化:`perf/what-is-changed` + - 例如:`perf/optimize-render` + - 例如:`perf/reduce-bundle-size` +- 依赖升级:`deps/package-name-version` + - 例如:`deps/upgrade-react-18` + - 例如:`deps/update-dependencies` + +## 分支命名注意事项 + +1. 使用小写字母 +2. 使用连字符(-)分隔单词 +3. 简短但具有描述性 +4. 避免使用下划线或其他特殊字符 +5. 如果与 Issue 关联,可以包含 Issue 编号 + +## Pull Request 规范 + +### PR 标题 + +- PR 标题始终使用英文 +- 遵循格式:`类型: 简短描述` +- 例如:`fix: fix button style issues in Safari browser` +- 例如:`feat: add dark mode support` + +### PR 内容 + +- PR 内容默认使用英文 +- 尽量简洁清晰地描述改动内容和目的 +- 可以视需要在英文描述后附上中文说明 + +### PR 模板 + +提交 PR 时请使用项目中提供的模板: + +- 英文模板(推荐):[PULL_REQUEST_TEMPLATE.md](mdc:.github/PULL_REQUEST_TEMPLATE.md) +- 中文模板:[PULL_REQUEST_TEMPLATE_CN.md](mdc:.github/PULL_REQUEST_TEMPLATE_CN.md) + +### PR 提交注意事项 + +1. **合并策略**: + + - 新特性请提交至 `feature` 分支 + - 其余可提交至 `master` 分支 + +2. **审核流程**: + + - PR 需要由至少一名维护者审核通过后才能合并 + - 确保所有 CI 检查都通过 + - 解决所有 Code Review 中提出的问题 + +3. **PR 质量要求**: + + - 确保代码符合项目代码风格 + - 添加必要的测试用例 + - 更新相关文档 + - 大型改动需要更详细的说明和更多的审核者参与 + +4. **工具标注**: + - 如果是用 Cursor 提交的代码,请在 PR body 末尾进行标注:`> Submitted by Cursor` + +## 新增内容 + +- Pull Request 标题格式:[组件名]: 描述 +- 从 master 分支创建新分支 +- 分支命名规范: + - feature/xxx:新特性 + - fix/xxx:Bug 修复 + - docs/xxx:文档更新 +- PR 说明中选择改动类型: + - 🆕 新特性提交 + - 🐞 Bug 修复 + - 📝 文档改进 + - 📽️ 演示代码改进 + - 💄 样式/交互改进 + - 🤖 TypeScript 更新 + - 📦 包体积优化 + - ⚡️ 性能优化 + - 🌐 国际化改进 +- 提供改动背景和解决方案 +- 更新日志同时提供英文和中文版本 diff --git a/.cursor/rules/locale.mdc b/.cursor/rules/locale.mdc new file mode 100644 index 0000000000..d9ae35ec69 --- /dev/null +++ b/.cursor/rules/locale.mdc @@ -0,0 +1,94 @@ +--- +description: 本地化规范文档 +globs: ["components/locale/*_*.ts", "components/locale/index.tsx"] +alwaysApply: false +--- + +# 本地化规范 + +antd 中所有的本地化配置都应该在 `components/locale` 目录中完成定义,主要分为两步:类型定义和本地化配置 + +## 类型定义 + +antd 的本地化配置的类型定义的入口文件是 `components/locale/index.tsx`, 当需要添加新的本地化配置时,需要检查对应组件或全局配置的类型是否存在,如果不存在,则需要增加相应的类型描述。 +如果新增或修改的本地化配置时组件配置,那么具体的本地化类型应该在相应的组件目录定义,定义好后在 `components/locale/index.tsx` 引入对应组件的类型定义。 + +## 本地化配置 + +### 纯字符串配置 + +antd 中的本地化配置文件命名规则是:`*_*.ts`,如:`zh_CN.ts`,文件默认导出一个 `Locale` 类型对象。 +通常在为 antd 添加后修改某一项本地化配置时,如无特殊说明,需要同时修改所有语言的本地化配置。 + +本地化配置文件列表如下(包括但不限于): + +```json +["components/locale/ar_EG.ts","components/locale/az_AZ.ts","components/locale/bg_BG.ts","components/locale/bn_BD.ts","components/locale/by_BY.ts","components/locale/ca_ES.ts","components/locale/cs_CZ.ts","components/locale/da_DK.ts","components/locale/de_DE.ts","components/locale/el_GR.ts","components/locale/en_GB.ts","components/locale/en_US.ts","components/locale/es_ES.ts","components/locale/et_EE.ts","components/locale/eu_ES.ts","components/locale/fa_IR.ts","components/locale/fi_FI.ts","components/locale/fr_BE.ts","components/locale/fr_CA.ts","components/locale/fr_FR.ts","components/locale/ga_IE.ts","components/locale/gl_ES.ts","components/locale/he_IL.ts","components/locale/hi_IN.ts","components/locale/hr_HR.ts","components/locale/hu_HU.ts","components/locale/hy_AM.ts","components/locale/id_ID.ts","components/locale/is_IS.ts","components/locale/it_IT.ts","components/locale/ja_JP.ts","components/locale/ka_GE.ts","components/locale/kk_KZ.ts","components/locale/km_KH.ts","components/locale/kmr_IQ.ts","components/locale/kn_IN.ts","components/locale/ko_KR.ts","components/locale/ku_IQ.ts","components/locale/lt_LT.ts","components/locale/lv_LV.ts","components/locale/mk_MK.ts","components/locale/ml_IN.ts","components/locale/mn_MN.ts","components/locale/ms_MY.ts","components/locale/my_MM.ts","components/locale/nb_NO.ts","components/locale/ne_NP.ts","components/locale/nl_BE.ts","components/locale/nl_NL.ts","components/locale/pl_PL.ts","components/locale/pt_BR.ts","components/locale/pt_PT.ts","components/locale/ro_RO.ts","components/locale/ru_RU.ts","components/locale/si_LK.ts","components/locale/sk_SK.ts","components/locale/sl_SI.ts","components/locale/sr_RS.ts","components/locale/sv_SE.ts","components/locale/ta_IN.ts","components/locale/th_TH.ts","components/locale/tk_TK.ts","components/locale/tr_TR.ts","components/locale/uk_UA.ts","components/locale/ur_PK.ts","components/locale/uz_UZ.ts","components/locale/vi_VN.ts","components/locale/zh_CN.ts","components/locale/zh_HK.ts","components/locale/zh_TW.ts"] +``` + +本地化配置的内容通常是纯字符串,如: + +```typescript +{ + // ... + Modal: { + okText: '确定', + cancelText: '取消', + justOkText: '知道了', + } + // ... +} +``` + +### 字符串模版配置 + +当然,也有一些需要配置需要再运行时实时替换变量的模版配置,带有 `${}` 的变量将在实际使用的地方被实时替换成对应的变量内容: +```typescript +{ + // ... + date: { + format: '${label}日期格式无效', + parse: '${label}不能转换为日期', + invalid: '${label}是一个无效日期', + } + // ... +} + +``` + +### 全局配置 + +如果某个本地化配置不独属于某个组件,而是数据全局的本地化配置,此时应该在 `global` 中添加相关属性,如: + +```typescript +{ + // ... + // locales for all components + global: { + placeholder: '请选择', + }, + // ... +} +``` + +# 使用本地化 + +antd 中具体使用本地化配置时,可以使用 `components/locale/index.tsx` 文件中导出的 `useLocale` 获取全局上下文中配置的本地化,并跟组件属性中传入的本地化配置合并后得到最完整的本地化配置,如: + +```tsx +import { useLocale } from "../locale"; +import enUS from '../locale/en_US'; + +export function TestComp(props) { + const { locale: propLocale } = props; + const [contextLocale] = useLocale("TestComp", enUs); + + const locale = {...contextLocale, ...propLocale}; + + return ( +
+ {locale?.text} +
+ ); +} +``` diff --git a/.cursor/rules/naming.mdc b/.cursor/rules/naming.mdc new file mode 100644 index 0000000000..4e9036a983 --- /dev/null +++ b/.cursor/rules/naming.mdc @@ -0,0 +1,108 @@ +--- +description: +globs: +alwaysApply: true +--- +Basically, antd naming requires **FULL NAME** instead of Abbreviation. + +## Props +* Initialize prop: `default` + `PropName` +* Force render: `forceRender` + * Force render sub component: `force` + `Sub Component Name` + `Render` +* Sub Component Render: `Sub Component Name` + `Render`. e.g. +> panelRender(originNode, info: { SubComponent1, SubComponent2, [somePassedProps]: someValue }) +* Sub Item Render: `Sub Item Name` + `Render`. e.g. +> cellRender(date, info: { [somePassedProps]: someValue }) +* Data Source: `dataSource` +* Panel open: popup & dropdown `open`, additional popup `popupName` + `Open` like `tooltipOpen` + * Do not use `visible` to make sure all the visible api align +* `children`: + * Mainly display content. To avoid additional prop name. + * Option list like `Select.Option` or `Tree.TreeNode`. + * Customize wrapped component can consider use `component` prop if `children` may have other usage in future. +* Display related naming: `show` + `PropName` +* Functional: `PropName` + `able` +* Disable: `disabled` + * sub component: `disabled` + `Sub Component Name` +* Extra: `extra` + * sub component: `Sub Component Name` + `extra`. e.g. `titleExtra` +* mainly icon: `icon` + * Merge with function first: `functionName: { icon }`. e.g. `expandable: { icon: }` + * Multiple icons: `FunctionName` + `Icon` +* Trigger: `trigger` + * Sub function trigger: `Sub Function` + `Trigger` + * Trigger on the time point: `xxx` + `On` + `EventName` (e.g. `destroyOnHidden`) +* Component use other component config. Naming as component.(e.g. ``) +* ClassName: `className` + * Additional classes should be merged into `classes` (e.g. `