diff --git a/.dumi/theme/layouts/DocLayout/index.tsx b/.dumi/theme/layouts/DocLayout/index.tsx index 8e55f3b95a..176b2d7d0e 100644 --- a/.dumi/theme/layouts/DocLayout/index.tsx +++ b/.dumi/theme/layouts/DocLayout/index.tsx @@ -16,6 +16,7 @@ import SiteContext from '../../slots/SiteContext'; import IndexLayout from '../IndexLayout'; import ResourceLayout from '../ResourceLayout'; import SidebarLayout from '../SidebarLayout'; +import VersionUpgrade from '../../common/VersionUpgrade'; const locales = { cn: { @@ -114,6 +115,7 @@ const DocLayout: React.FC = () => { > {!hideLayout &&
} + {content} diff --git a/.dumi/theme/layouts/GlobalLayout.tsx b/.dumi/theme/layouts/GlobalLayout.tsx index 45013494ff..9e4e4b63a4 100644 --- a/.dumi/theme/layouts/GlobalLayout.tsx +++ b/.dumi/theme/layouts/GlobalLayout.tsx @@ -21,7 +21,6 @@ import useLocalStorage from '../../hooks/useLocalStorage'; import { getBannerData } from '../../pages/index/components/util'; import { ANT_DESIGN_SITE_THEME } from '../common/ThemeSwitch'; import type { ThemeName } from '../common/ThemeSwitch'; -import VersionUpgrade from '../common/VersionUpgrade'; import SiteThemeProvider from '../SiteThemeProvider'; import type { SimpleComponentClassNames, SiteContextProps } from '../slots/SiteContext'; import SiteContext from '../slots/SiteContext'; @@ -318,10 +317,7 @@ const GlobalLayout: React.FC = () => { - - {outlet} - - + {outlet} diff --git a/.dumi/theme/slots/Content/Contributors.tsx b/.dumi/theme/slots/Content/Contributors.tsx index 88bc65d44e..c12f83e466 100644 --- a/.dumi/theme/slots/Content/Contributors.tsx +++ b/.dumi/theme/slots/Content/Contributors.tsx @@ -38,7 +38,13 @@ interface ContributorsProps { } // 这些机器人账号不需要展示 -const blockList = ['github-actions', 'copilot', 'renovate', 'dependabot']; +const blockList = [ + 'github-actions', + 'copilot', + 'renovate', + 'dependabot', + 'gemini-code-assist[bot]', +]; const Contributors: React.FC = ({ filename }) => { const { formatMessage } = useIntl(); diff --git a/.dumi/theme/slots/Sidebar/index.tsx b/.dumi/theme/slots/Sidebar/index.tsx index 8061df9e96..336e242d6e 100644 --- a/.dumi/theme/slots/Sidebar/index.tsx +++ b/.dumi/theme/slots/Sidebar/index.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import MobileMenu from '@rc-component/drawer'; import { Col, ConfigProvider, Menu } from 'antd'; import { createStyles, useTheme } from 'antd-style'; @@ -114,6 +114,16 @@ const Sidebar: React.FC = () => { const [menuItems, selectedKey] = useMenu(); const { colorBgContainer } = useTheme(); + const defaultOpenKeys = sidebarData?.map(({ title }) => title!).filter(Boolean) || []; + const [openKeys, setOpenKeys] = React.useState(defaultOpenKeys); + + useEffect(() => { + if (openKeys.join(',') === defaultOpenKeys.join(',')) { + return; + } + setOpenKeys(defaultOpenKeys); + }, [defaultOpenKeys.join(',')]); + const menuChild = ( { mode="inline" theme={isDark ? 'dark' : 'light'} selectedKeys={[selectedKey]} - defaultOpenKeys={sidebarData?.map(({ title }) => title!).filter(Boolean)} + openKeys={openKeys} + onOpenChange={setOpenKeys} /> ); diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index e9de774fa3..39123110e3 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -4,6 +4,10 @@ Want to contribute to Ant Design? There are a few things you need to know. We wrote a **[contribution guide](https://ant.design/docs/react/contributing)** to help you get started. +## Security + +If you're working with GitHub Actions workflows, please read our **[Workflows Security Guide](.github/WORKFLOWS_SECURITY.md)** to understand security best practices. + --- # 参与共建 @@ -11,3 +15,7 @@ We wrote a **[contribution guide](https://ant.design/docs/react/contributing)** 想要给 Ant Design 贡献自己的一份力量? 我们写了一份 **[贡献指南](https://ant.design/docs/react/contributing-cn)** 来帮助你开始。 + +## 安全 + +如果你需要修改 GitHub Actions 工作流,请阅读我们的 **[工作流安全指南](.github/WORKFLOWS_SECURITY.md)** 以了解安全最佳实践。 diff --git a/.github/WORKFLOWS_SECURITY.md b/.github/WORKFLOWS_SECURITY.md new file mode 100644 index 0000000000..1264d236fa --- /dev/null +++ b/.github/WORKFLOWS_SECURITY.md @@ -0,0 +1,130 @@ +# GitHub Actions Workflows Security + +This document describes the security measures implemented in ant-design's GitHub Actions workflows to protect against common attack vectors, particularly the "PWN Request" vulnerability. + +## Background: PWN Request Vulnerability + +The "PWN Request" (or "Pull Request Target") vulnerability occurs when workflows: + +1. Use `pull_request_target`, `workflow_run`, or `issue_comment` triggers +2. Check out code from untrusted sources (fork PRs) +3. Execute that code with elevated privileges or access to secrets + +This can allow attackers to: + +- Steal repository secrets +- Execute remote code in the CI/CD environment +- Modify repository contents +- Compromise the supply chain + +**Reference**: See [GitHub Security Lab - Preventing PWN Requests](https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/) + +## Security Principles Applied + +### 1. Safe Use of `pull_request_target` + +All workflows using `pull_request_target` follow these rules: + +- ✅ **NEVER** check out PR code (`actions/checkout` with PR ref) +- ✅ **NEVER** run `npm install` or similar with PR code +- ✅ Only interact with PR metadata (comments, labels, status) +- ✅ Use minimal permissions (explicitly defined per job) + +**Safe workflows:** + +- `preview-start.yml` - Only comments on PRs +- `pr-open-notify.yml` - Only sends notifications +- `pr-open-check.yml` - Only validates PR content +- `verify-files-modify.yml` - Only checks file modifications via API +- `pr-check-merge.yml` - Only comments on branch merge PRs +- `pr-contributor-welcome.yml` - Only comments on merged PRs +- `visual-regression-diff-start.yml` - Only comments on PRs + +### 2. Separation of Build and Deploy + +We use the "build in PR, deploy in workflow_run" pattern: + +**Build Phase** (uses `pull_request` trigger): + +- `preview-build.yml` - Builds site from PR code with restricted permissions +- `visual-regression-diff-build.yml` - Generates screenshots from PR code +- Uses `pull_request` trigger (no secrets, read-only repository access) +- Uploads build artifacts (no secrets included) + +**Deploy Phase** (uses `workflow_run` trigger): + +- `preview-deploy.yml` - Downloads artifacts and deploys +- `visual-regression-diff-finish.yml` - Downloads artifacts and posts results +- Only downloads artifacts, never checks out untrusted code +- Has access to secrets for deployment +- Validates PR numbers before use + +### 3. Authorization Checks + +Workflows that can modify repository state require authorization: + +- ✅ `rebase.yml` - Restricts `/rebase` command to MEMBER, COLLABORATOR, or OWNER +- ✅ `verify-files-modify.yml` - Checks contributor authority for protected paths +- ✅ `pr-check-merge.yml` - Only runs for ant-design organization PRs + +### 4. Minimal Permissions + +All workflows follow the principle of least privilege: + +```yaml +permissions: + contents: read # Default read-only access + +jobs: + specific-job: + permissions: + # Only grant what's needed + issues: write + pull-requests: write +``` + +### 5. Pinned Action Versions + +Critical actions are pinned to specific commit SHAs: + +- `actions-cool/verify-files-modify@9f38a3b3d324d4d92c88c8a946001522e17ad554` + +This prevents supply chain attacks via compromised action updates. + +### 6. Input Validation + +All external inputs are validated: + +- PR numbers are validated as numeric before use +- File paths are checked before operations +- User associations are verified before privileged operations + +## Workflow Security Checklist + +When adding or modifying workflows, ensure: + +- [ ] If using `pull_request_target`, NEVER check out PR code +- [ ] If using `pull_request_target`, NEVER run untrusted code +- [ ] If using `issue_comment` with code execution, check `author_association` +- [ ] If using `workflow_run`, only download artifacts or check out base branch +- [ ] Permissions are explicitly set to minimum required +- [ ] Secrets are only used in trusted contexts +- [ ] All user inputs are validated +- [ ] Third-party actions are from trusted sources +- [ ] Critical actions are pinned to commit SHAs + +## Incident Response + +If a security vulnerability is discovered: + +1. Immediately disable the affected workflow +2. Report to security team via [SECURITY.md](../SECURITY.md) +3. Do not disclose publicly until patched +4. Review all recent workflow runs for signs of exploitation + +## References + +- [GitHub Security Lab - Preventing PWN Requests](https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/) +- [GitHub Actions Security Best Practices](https://blog.gitguardian.com/github-actions-security-cheat-sheet/) +- [OpenSSF - Mitigating Attack Vectors in GitHub Workflows](https://openssf.org/blog/2024/08/12/mitigating-attack-vectors-in-github-workflows/) +- [PostHog - Shai Hulud Attack Post-Mortem](https://posthog.com/blog/nov-24-shai-hulud-attack-post-mortem) diff --git a/.github/workflows/pr-open-check.yml b/.github/workflows/pr-open-check.yml index a4065abbad..e93479e820 100644 --- a/.github/workflows/pr-open-check.yml +++ b/.github/workflows/pr-open-check.yml @@ -14,7 +14,7 @@ jobs: pull-requests: write # for actions-cool/pr-welcome to request reviewer runs-on: ubuntu-latest steps: - - uses: actions-cool/pr-welcome@1c2b1c3e3ab926424a4464fbf7b6321efb67c871 + - uses: actions-cool/pr-welcome@4bd317d60ef3b40a3ccda39c22f66c3358010f92 with: refuse-issue-label: 🎱 Collaborate PR only need-creator-authority: write @@ -33,7 +33,7 @@ jobs: runs-on: ubuntu-latest steps: - name: check fill - uses: actions-cool/pr-check-fill@f19d0f252c9071fca7f97ccfe69541b7cdf9ccda + uses: actions-cool/pr-check-fill@35194e32fd717c88c4fde15fbde9005933c2d452 with: filter-start: '|' require-include: '🇺🇸 English, 🇨🇳 Chinese, 🇺🇸 英文, 🇨🇳 中文' diff --git a/.github/workflows/rebase.yml b/.github/workflows/rebase.yml deleted file mode 100644 index 6579220d5f..0000000000 --- a/.github/workflows/rebase.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Automatic Rebase - -on: - issue_comment: - types: [created] - -permissions: - contents: read - -jobs: - rebase: - permissions: - contents: write # for cirrus-actions/rebase to push code to rebase - pull-requests: read # for cirrus-actions/rebase to get info about PR - name: Rebase - if: github.event.issue.pull_request != '' && (contains(github.event.comment.body, '/rebase') || contains(github.event.comment.body, '\rebase')) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - name: Automatic Rebase - uses: cirrus-actions/rebase@1.8 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.jest.js b/.jest.js index 5da2852d24..1656c88022 100644 --- a/.jest.js +++ b/.jest.js @@ -9,14 +9,11 @@ const compileModules = [ '@rc-component', ]; -const ignoreList = []; - // cnpm use `_` as prefix -['', '_'].forEach((prefix) => { - compileModules.forEach((module) => { - ignoreList.push(`${prefix}${module}`); - }); -}); +const ignoreList = ['', '_'].reduce( + (acc, prefix) => [...acc, ...compileModules.map((module) => `${prefix}${module}`)], + [], +); const transformIgnorePatterns = [ // Ignore modules without es dir. diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index fff73fb1d6..561571b2f4 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -15,6 +15,32 @@ tag: vVERSION --- +## 6.0.1 + +`2025-12-02` + +- Flex + - 🐞 Fix Flex cannot pass `0` for `flex` property. [#55829](https://github.com/ant-design/ant-design/pull/55829) [@li-jia-nan](https://github.com/li-jia-nan) + - 🐞 Fix Flex cannot pass `0` for `gap` property. [#55803](https://github.com/ant-design/ant-design/pull/55803) [@li-jia-nan](https://github.com/li-jia-nan) +- Input + - 🐞 Fix Input `colorText` token does not work with `filled` variant without affix. [#56019](https://github.com/ant-design/ant-design/pull/56019) [@ug-hero](https://github.com/ug-hero) + - 🐞 Fix Input.OTP empty slots can be skipped when typing. [#56001](https://github.com/ant-design/ant-design/pull/56001) [@aojunhao123](https://github.com/aojunhao123) +- 🐞 Fix Anchor scroll problem when click same link rapidly. [#55814](https://github.com/ant-design/ant-design/pull/55814) [@tuzixiangs](https://github.com/tuzixiangs) [@tuzixiangs](https://github.com/tuzixiangs) +- 🐞 Fix Button hover text color in `solid` variant. [#55825](https://github.com/ant-design/ant-design/pull/55825) [@andriib-ship-it](https://github.com/andriib-ship-it) +- 🐞 Fix Cascader page scroll to top on first open with defaultValue. [#55890](https://github.com/ant-design/ant-design/pull/55890) [@tuzixiangs](https://github.com/tuzixiangs) +- 🐞 Fix DatePicker `borderRadiusSM` and `borderRadiusLG` token not working bug. [#56018](https://github.com/ant-design/ant-design/pull/56018) [@ug-hero](https://github.com/ug-hero) +- 🐞 Fix InputNumber text clipping bug with ColorPicker. [#55966](https://github.com/ant-design/ant-design/pull/55966) [@DDDDD12138](https://github.com/DDDDD12138) +- 🐞 Fix Select text color for search input in dark mode. [#55914](https://github.com/ant-design/ant-design/pull/55914) [@divyeshagrawal](https://github.com/divyeshagrawal) +- 🐞 Fix Splitter failing to fill its container when the sum of panel proportions is not 1. [#56025](https://github.com/ant-design/ant-design/pull/56025) [@zombieJ](https://github.com/zombieJ) +- 🐞 Fix Wave memory leak risk since RAF not clean up. [#55962](https://github.com/ant-design/ant-design/pull/55962) [@Copilot](https://github.com/Copilot) +- 🐞 Fix Modal/Image/Drawer that the `colorBgMask` token does not take effect. [#56031](https://github.com/ant-design/ant-design/pull/56031) [@ug-hero](https://github.com/ug-hero) +- 💄 Fix ConfigProvider default not config `theme.hashed` is `true` which will cause style conflict with multiple versions. [#55880](https://github.com/ant-design/ant-design/pull/55880) [@zombieJ](https://github.com/zombieJ) +- 💄 Fix Layout.Sider styles lost when zeroRuntime enabled. [#55864](https://github.com/ant-design/ant-design/pull/55864) [@wanpan11](https://github.com/wanpan11) +- 🛠 MISC: Fix that could not build with pnpm `hoist: false`. [#55938](https://github.com/ant-design/ant-design/pull/55938) [@afc163](https://github.com/afc163) +- TypeScript + - 🤖 Fix ConfigProvider type missing for Table `className` and `styles` config. [#55984](https://github.com/ant-design/ant-design/pull/55984) [@meet-student](https://github.com/meet-student) + - 🤖 Fix DatePicker props type definition. [#55826](https://github.com/ant-design/ant-design/pull/55826) [@divyeshagrawal](https://github.com/divyeshagrawal) + ## 6.0.0 `2025-11-22` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 44574aecbe..3de8618a46 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -15,6 +15,32 @@ tag: vVERSION --- +## 6.0.1 + +`2025-12-02` + +- Flex + - 🐞 修复 Flex 的 `flex` 属性不能设置为 `0` 的问题。[#55829](https://github.com/ant-design/ant-design/pull/55829) [@li-jia-nan](https://github.com/li-jia-nan) + - 🐞 修复 Flex 的 `gap` 属性不能设置为 `0` 的问题。[#55803](https://github.com/ant-design/ant-design/pull/55803) [@li-jia-nan](https://github.com/li-jia-nan) +- Input + - 🐞 修复 Input `colorText` token 在无前后缀的 `filled` 变体下不工作的问题。[#56019](https://github.com/ant-design/ant-design/pull/56019) [@ug-hero](https://github.com/ug-hero) + - 🐞 修复 Input.OTP 在输入时可跳过空位的问题。[#56001](https://github.com/ant-design/ant-design/pull/56001) [@aojunhao123](https://github.com/aojunhao123) +- 🐞 修复 Anchor 快速点击同一链接时的滚动问题。[#55814](https://github.com/ant-design/ant-design/pull/55814) [@tuzixiangs](https://github.com/tuzixiangs) [@tuzixiangs](https://github.com/tuzixiangs) +- 🐞 修复 Button 在 `solid` 变体下悬浮态的文字颜色。[#55825](https://github.com/ant-design/ant-design/pull/55825) [@andriib-ship-it](https://github.com/andriib-ship-it) +- 🐞 修复 Cascader 使用 defaultValue 时首次打开会滚动到页面顶部的问题。[#55890](https://github.com/ant-design/ant-design/pull/55890) [@tuzixiangs](https://github.com/tuzixiangs) +- 🐞 修复 DatePicker `borderRadiusSM` 和 `borderRadiusLG` token 未生效问题。[#56018](https://github.com/ant-design/ant-design/pull/56018) [@ug-hero](https://github.com/ug-hero) +- 🐞 修复 InputNumber 在 ColorPicker 中使用时文字被裁切的问题。[#55966](https://github.com/ant-design/ant-design/pull/55966) [@DDDDD12138](https://github.com/DDDDD12138) +- 🐞 修复 Select 在深色模式下的搜索框文本颜色。[#55914](https://github.com/ant-design/ant-design/pull/55914) [@divyeshagrawal](https://github.com/divyeshagrawal) +- 🐞 修复 Splitter 在 Panel 总占比不为 1 时出现占不满的情况。 [#56025](https://github.com/ant-design/ant-design/pull/56025) [@zombieJ](https://github.com/zombieJ) +- 🐞 修复 Wave 可能由于 RAF 未清理引发内存泄露的风险。[#55962](https://github.com/ant-design/ant-design/pull/55962) [@Copilot](https://github.com/Copilot) +- 🐞 修复 Modal/Image/Drawer 组件 `colorBgMask` token 不生效的问题。[#56031](https://github.com/ant-design/ant-design/pull/56031) [@ug-hero](https://github.com/ug-hero) +- 💄 修复 ConfigProvider 默认没有配置 `theme.hashed` 为 `true`,从而会导致多版本混用样式冲突的问题。[#55880](https://github.com/ant-design/ant-design/pull/55880) [@zombieJ](https://github.com/zombieJ) +- 💄 修复 Layout.Sider 在 zeroRuntime 开启时样式缺失的问题。[#55864](https://github.com/ant-design/ant-design/pull/55864) [@wanpan11](https://github.com/wanpan11) +- 🛠 杂项:修复版本无法在 pnpm `hoist: false` 下通过 vite 编译。[#55938](https://github.com/ant-design/ant-design/pull/55938) [@afc163](https://github.com/afc163) +- TypeScript + - 🤖 修复 ConfigProvider 的 Table `classNames` 及 `styles` 配置类型缺失的问题。[#55984](https://github.com/ant-design/ant-design/pull/55984) [@meet-student](https://github.com/meet-student) + - 🤖 修复 DatePicker 多个属性的类型定义。[#55826](https://github.com/ant-design/ant-design/pull/55826) [@divyeshagrawal](https://github.com/divyeshagrawal) + ## 6.0.0 `2025-11-22` diff --git a/biome.json b/biome.json index 5cce5c186b..3eb4e81812 100644 --- a/biome.json +++ b/biome.json @@ -5,6 +5,7 @@ "includes": [ "**", "!.dumi/tmp*", + "!report.html", "!.dumi/scripts/clarity.js", "!dist/*", "!es/**/*", diff --git a/components/auto-complete/index.en-US.md b/components/auto-complete/index.en-US.md index a4c5a6f44c..76d885f5d3 100644 --- a/components/auto-complete/index.en-US.md +++ b/components/auto-complete/index.en-US.md @@ -45,7 +45,6 @@ Common props ref:[Common props](/docs/react/common-props) | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | | allowClear | Show clear button | boolean \| { clearIcon?: ReactNode } | false | 5.8.0: Support Object type | -| autoFocus | If get focus when component mounted | boolean | false | | | backfill | If backfill selected item the input when using keyboard | boolean | false | | | children | Customize input element | HTMLInputElement \| HTMLTextAreaElement \| React.ReactElement<InputProps> | <Input /> | | | classNames | Customize class for each semantic structure inside the component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | diff --git a/components/auto-complete/index.zh-CN.md b/components/auto-complete/index.zh-CN.md index 396a0f898f..4327dac37f 100644 --- a/components/auto-complete/index.zh-CN.md +++ b/components/auto-complete/index.zh-CN.md @@ -46,7 +46,6 @@ demo: | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | | allowClear | 支持清除 | boolean \| { clearIcon?: ReactNode } | false | 5.8.0: 支持对象形式 | -| autoFocus | 自动获取焦点 | boolean | false | | | backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false | | | children | 自定义输入框 | HTMLInputElement \| HTMLTextAreaElement \| React.ReactElement<InputProps> | <Input /> | | | classNames | 用于自定义组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | diff --git a/components/cascader/index.en-US.md b/components/cascader/index.en-US.md index 44f19ac5b4..67557f427c 100644 --- a/components/cascader/index.en-US.md +++ b/components/cascader/index.en-US.md @@ -53,7 +53,6 @@ Common props ref:[Common props](/docs/react/common-props) | --- | --- | --- | --- | --- | | allowClear | Show clear button | boolean \| { clearIcon?: ReactNode } | true | 5.8.0: Support object type | | ~~autoClearSearchValue~~ | Whether the current search will be cleared on selecting an item. Only applies when `multiple` is `true` | boolean | true | 5.9.0 | -| autoFocus | If get focus when component mounted | boolean | false | | | changeOnSelect | Change value on each selection if set to true, see above demo for details | boolean | false | | | className | The additional css class | string | - | | | classNames | Customize class for each semantic structure inside the component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | diff --git a/components/cascader/index.zh-CN.md b/components/cascader/index.zh-CN.md index 567338133c..ef90c2fcd0 100644 --- a/components/cascader/index.zh-CN.md +++ b/components/cascader/index.zh-CN.md @@ -54,7 +54,6 @@ demo: | --- | --- | --- | --- | --- | | allowClear | 支持清除 | boolean \| { clearIcon?: ReactNode } | true | 5.8.0: 支持对象形式 | | ~~autoClearSearchValue~~ | 是否在选中项后清空搜索框,只在 `multiple` 为 `true` 时有效 | boolean | true | 5.9.0 | -| autoFocus | 自动获取焦点 | boolean | false | | | changeOnSelect | 单选时生效(multiple 下始终都可以选择),点选每级菜单选项值都会发生变化。 | boolean | false | | | className | 自定义类名 | string | - | | | classNames | 用于自定义组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | diff --git a/components/checkbox/index.en-US.md b/components/checkbox/index.en-US.md index d50ff2eee5..51b83527d7 100644 --- a/components/checkbox/index.en-US.md +++ b/components/checkbox/index.en-US.md @@ -36,7 +36,6 @@ Common props ref:[Common props](/docs/react/common-props) | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | -| autoFocus | If get focus when component mounted | boolean | false | | | checked | Specifies whether the checkbox is selected | boolean | false | | | classNames | Customize class for each semantic structure inside the component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | | defaultChecked | Specifies the initial state: whether or not the checkbox is selected | boolean | false | | diff --git a/components/checkbox/index.zh-CN.md b/components/checkbox/index.zh-CN.md index e9385c3f26..af3ab3c643 100644 --- a/components/checkbox/index.zh-CN.md +++ b/components/checkbox/index.zh-CN.md @@ -37,7 +37,6 @@ demo: | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | -| autoFocus | 自动获取焦点 | boolean | false | | | checked | 指定当前是否选中 | boolean | false | | | classNames | 用于自定义组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | | defaultChecked | 初始是否选中 | boolean | false | | diff --git a/components/collapse/index.en-US.md b/components/collapse/index.en-US.md index 372d516934..f11ef9c706 100644 --- a/components/collapse/index.en-US.md +++ b/components/collapse/index.en-US.md @@ -12,49 +12,6 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*sir-TK0HkWcAAA - Can be used to group or hide complex regions to keep the page clean. - `Accordion` is a special kind of `Collapse`, which allows only one panel to be expanded at a time. -```tsx | pure -// works when >= 5.6.0, recommended ✅ -const text = ` - A dog is a type of domesticated animal. - Known for its loyalty and faithfulness, - it can be found as a welcome guest in many households across the world. -`; - -const items: CollapseProps['items'] = [ - { - key: '1', - label: 'This is panel header 1', - children:

{text}

, - }, - { - key: '2', - label: 'This is panel header 2', - children:

{text}

, - }, - { - key: '3', - label: 'This is panel header 3', - children:

{text}

, - }, -]; - -; - -// works when <5.6.0 , deprecated when >=5.6.0 🙅🏻‍♀️ - - - -

{text}

-
- -

{text}

-
- -

{text}

-
-
; -``` - ## Examples diff --git a/components/collapse/index.zh-CN.md b/components/collapse/index.zh-CN.md index 048008474b..23f93af48d 100644 --- a/components/collapse/index.zh-CN.md +++ b/components/collapse/index.zh-CN.md @@ -13,49 +13,6 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*sir-TK0HkWcAAA - 对复杂区域进行分组和隐藏,保持页面的整洁。 - `手风琴` 是一种特殊的折叠面板,只允许单个内容区域展开。 -```tsx | pure -// >= 5.6.0 可用,推荐的写法 ✅ -const text = ` - A dog is a type of domesticated animal. - Known for its loyalty and faithfulness, - it can be found as a welcome guest in many households across the world. -`; - -const items: CollapseProps['items'] = [ - { - key: '1', - label: 'This is panel header 1', - children:

{text}

, - }, - { - key: '2', - label: 'This is panel header 2', - children:

{text}

, - }, - { - key: '3', - label: 'This is panel header 3', - children:

{text}

, - }, -]; - -; - -// <5.6.0 可用,>=5.6.0 时不推荐 🙅🏻‍♀️ - - - -

{text}

-
- -

{text}

-
- -

{text}

-
-
; -``` - ## 代码演示 {#examples} diff --git a/components/date-picker/index.en-US.md b/components/date-picker/index.en-US.md index 307e93f4ff..aeb835d100 100644 --- a/components/date-picker/index.en-US.md +++ b/components/date-picker/index.en-US.md @@ -95,7 +95,6 @@ The following APIs are shared by DatePicker, RangePicker. | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | | allowClear | Customize clear button | boolean \| { clearIcon?: ReactNode } | true | 5.8.0: Support object type | -| autoFocus | If get focus when component mounted | boolean | false | | | className | The picker className | string | - | | | classNames | 用于自定义组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | | dateRender | Custom rendering function for date cells, >= 5.4.0 use `cellRender` instead. | function(currentDate: dayjs, today: dayjs) => React.ReactNode | - | < 5.4.0 | diff --git a/components/date-picker/index.zh-CN.md b/components/date-picker/index.zh-CN.md index a8fcb3cf1a..1f68d967b9 100644 --- a/components/date-picker/index.zh-CN.md +++ b/components/date-picker/index.zh-CN.md @@ -96,7 +96,6 @@ dayjs.locale('zh-cn'); | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | | allowClear | 自定义清除按钮 | boolean \| { clearIcon?: ReactNode } | true | 5.8.0: 支持对象类型 | -| autoFocus | 自动获取焦点 | boolean | false | | | className | 选择器 className | string | - | | | classNames | 用于自定义组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | | dateRender | 自定义日期单元格的内容,5.4.0 起用 `cellRender` 代替 | function(currentDate: dayjs, today: dayjs) => React.ReactNode | - | < 5.4.0 | diff --git a/components/date-picker/style/index.ts b/components/date-picker/style/index.ts index 132fbdb436..51ce8576f3 100644 --- a/components/date-picker/style/index.ts +++ b/components/date-picker/style/index.ts @@ -157,6 +157,7 @@ const genPickerStyle: GenerateStyle = (token) => { // Size '&-large': { ...genPickerPadding(token.paddingBlockLG, token.paddingInlineLG), + borderRadius: token.borderRadiusLG, [`${componentCls}-input > input`]: { fontSize: inputFontSizeLG ?? fontSizeLG, lineHeight: lineHeightLG, @@ -165,6 +166,7 @@ const genPickerStyle: GenerateStyle = (token) => { '&-small': { ...genPickerPadding(token.paddingBlockSM, token.paddingInlineSM), + borderRadius: token.borderRadiusSM, [`${componentCls}-input > input`]: { fontSize: inputFontSizeSM ?? fontSizeSM, }, diff --git a/components/drawer/index.en-US.md b/components/drawer/index.en-US.md index 0831ffe746..1777a99767 100644 --- a/components/drawer/index.en-US.md +++ b/components/drawer/index.en-US.md @@ -55,7 +55,6 @@ v5 uses `rootClassName` & `rootStyle` to configure the outermost element style, | Props | Description | Type | Default | Version | | --- | --- | --- | --- | --- | -| autoFocus | Whether Drawer should get focused after open | boolean | true | 4.17.0 | | afterOpenChange | Callback after the animation ends when switching drawers | function(open) | - | | | className | Config Drawer Panel className. Use `rootClassName` if want to config top DOM style | string | - | | | classNames | Customize class for each semantic structure inside the Drawer component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | diff --git a/components/drawer/index.zh-CN.md b/components/drawer/index.zh-CN.md index 7b89062d6e..fe08bfc20b 100644 --- a/components/drawer/index.zh-CN.md +++ b/components/drawer/index.zh-CN.md @@ -55,7 +55,6 @@ v5 使用 `rootClassName` 与 `rootStyle` 来配置最外层元素样式。原 v | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | -| autoFocus | 抽屉展开后是否将焦点切换至其 DOM 节点 | boolean | true | 4.17.0 | | afterOpenChange | 切换抽屉时动画结束后的回调 | function(open) | - | | | className | Drawer 容器外层 className 设置,如果需要设置最外层,请使用 rootClassName | string | - | | | classNames | 用于自定义 Drawer 组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | @@ -72,7 +71,7 @@ v5 使用 `rootClassName` 与 `rootStyle` 来配置最外层元素样式。原 v | maskClosable | 点击蒙层是否允许关闭 | boolean | true | | | placement | 抽屉的方向 | `top` \| `right` \| `bottom` \| `left` | `right` | | | push | 用于设置多层 Drawer 的推动行为 | boolean \| { distance: string \| number } | { distance: 180 } | 4.5.0+ | -| resizable | 是否启用拖拽改变尺寸 | boolean \| [ResizableConfig](#resizableconfig) | - | boolean: 6.1.0| +| resizable | 是否启用拖拽改变尺寸 | boolean \| [ResizableConfig](#resizableconfig) | - | boolean: 6.1.0 | | rootStyle | 可用于设置 Drawer 最外层容器的样式,和 `style` 的区别是作用节点包括 `mask` | CSSProperties | - | | | size | 预设抽屉宽度(或高度),default `378px` 和 large `736px`,或自定义数字 | 'default' \| 'large' \| number | 'default' | 4.17.0 | | styles | 用于自定义 Drawer 组件内部各语义化结构的行内 style,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), CSSProperties> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), CSSProperties> | - | | diff --git a/components/drawer/style/index.ts b/components/drawer/style/index.ts index 55f78c18a2..ca775ca1a0 100644 --- a/components/drawer/style/index.ts +++ b/components/drawer/style/index.ts @@ -1,6 +1,6 @@ import { unit } from '@ant-design/cssinjs'; -import { blurMaskStyle, genFocusStyle } from '../../style'; +import { genFocusStyle } from '../../style'; import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal'; import { genStyleHooks, mergeToken } from '../../theme/internal'; import genMotionStyle from './motion'; @@ -105,7 +105,7 @@ const genDrawerStyle: GenerateStyle = (token) => { pointerEvents: 'auto', [`&${componentCls}-mask-blur`]: { - ...blurMaskStyle, + backdropFilter: 'blur(4px)', }, }, diff --git a/components/dropdown/index.en-US.md b/components/dropdown/index.en-US.md index 93359dcb50..7b43adcecd 100644 --- a/components/dropdown/index.en-US.md +++ b/components/dropdown/index.en-US.md @@ -47,7 +47,6 @@ Common props ref:[Common props](/docs/react/common-props) | --- | --- | --- | --- | --- | | arrow | Whether the dropdown arrow should be visible | boolean \| { pointAtCenter: boolean } | false | | | autoAdjustOverflow | Whether to adjust dropdown placement automatically when dropdown is off screen | boolean | true | 5.2.0 | -| autoFocus | Focus element in `overlay` when opened | boolean | false | | | classNames | Customize class for each semantic structure inside the Dropdown component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props }) => Record<[SemanticDOM](#semantic-dom), string> | - | | | disabled | Whether the dropdown menu is disabled | boolean | - | | | ~~destroyPopupOnHide~~ | Whether destroy dropdown when hidden, use `destroyOnHidden` instead | boolean | false | | diff --git a/components/dropdown/index.zh-CN.md b/components/dropdown/index.zh-CN.md index 2dec82973d..f69fe158a7 100644 --- a/components/dropdown/index.zh-CN.md +++ b/components/dropdown/index.zh-CN.md @@ -51,7 +51,6 @@ demo: | --- | --- | --- | --- | --- | | arrow | 下拉框箭头是否显示 | boolean \| { pointAtCenter: boolean } | false | | | autoAdjustOverflow | 下拉框被遮挡时自动调整位置 | boolean | true | 5.2.0 | -| autoFocus | 打开后自动聚焦下拉框 | boolean | false | | | classNames | 用于自定义 Dropdown 组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props }) => Record<[SemanticDOM](#semantic-dom), string> | - | | | disabled | 菜单是否禁用 | boolean | - | | | ~~destroyPopupOnHide~~ | 关闭后是否销毁 Dropdown,使用 `destroyOnHidden` 替换 | boolean | false | | diff --git a/components/image/style/index.ts b/components/image/style/index.ts index ad1af25927..216e76452a 100644 --- a/components/image/style/index.ts +++ b/components/image/style/index.ts @@ -2,7 +2,6 @@ import type { CSSObject } from '@ant-design/cssinjs'; import { unit } from '@ant-design/cssinjs'; import { FastColor } from '@ant-design/fast-color'; -import { blurMaskStyle } from '../../style'; import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal'; import { genStyleHooks, mergeToken } from '../../theme/internal'; @@ -44,11 +43,6 @@ export interface ImageToken extends FullToken<'Image'> { * @descEN Preview class name */ previewCls: string; - /** - * @desc 模态框遮罩背景色 - * @descEN Background color of modal mask - */ - modalMaskBg: string; /** * @desc 预览切换按钮尺寸 * @descEN Size of preview switch button @@ -102,7 +96,7 @@ export const genImagePreviewStyle: GenerateStyle = (token: ImageToke previewCls, motionDurationSlow, componentCls, - modalMaskBg, + colorBgMask, marginXL, marginSM, margin, @@ -115,7 +109,7 @@ export const genImagePreviewStyle: GenerateStyle = (token: ImageToke zIndexPopup, } = token; - const operationBg = new FastColor(modalMaskBg).setA(0.1); + const operationBg = new FastColor(colorBgMask).setA(0.1); const operationBgHover = operationBg.clone().setA(0.2); const singleBtn: CSSObject = { @@ -151,9 +145,9 @@ export const genImagePreviewStyle: GenerateStyle = (token: ImageToke [`${previewCls}-mask`]: { inset: 0, position: 'absolute', - background: modalMaskBg, + background: colorBgMask, [`&${componentCls}-preview-mask-blur`]: { - ...blurMaskStyle, + backdropFilter: 'blur(4px)', }, [`&${componentCls}-preview-mask-hidden`]: { display: 'none', @@ -346,7 +340,6 @@ export default genStyleHooks( const imageToken = mergeToken(token, { previewCls, - modalMaskBg: new FastColor('#000').setA(0.45).toRgbString(), // FIXME: Shared Token imagePreviewSwitchSize: token.controlHeightLG, }); diff --git a/components/input-number/index.en-US.md b/components/input-number/index.en-US.md index c6444ec6d6..f00431085f 100644 --- a/components/input-number/index.en-US.md +++ b/components/input-number/index.en-US.md @@ -44,7 +44,6 @@ Common props ref:[Common props](/docs/react/common-props) | --- | --- | --- | --- | --- | | ~~addonAfter~~ | The label text displayed after (on the right side of) the input field, please use Space.Compact instead | ReactNode | - | | | ~~addonBefore~~ | The label text displayed before (on the left side of) the input field, please use Space.Compact instead | ReactNode | - | | -| autoFocus | If the component gets focus when mounted | boolean | false | - | | changeOnBlur | Trigger `onChange` when blur. e.g. reset value in range by blur | boolean | true | 5.11.0 | | changeOnWheel | Allows control with mouse wheel | boolean | - | 5.14.0 | | classNames | Customize class for each semantic structure inside the component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | - | diff --git a/components/input-number/index.zh-CN.md b/components/input-number/index.zh-CN.md index 3b444f435d..ca5db1c8e3 100644 --- a/components/input-number/index.zh-CN.md +++ b/components/input-number/index.zh-CN.md @@ -45,7 +45,6 @@ demo: | --- | --- | --- | --- | --- | | ~~addonAfter~~ | 带标签的 input,设置后置标签,请使用 Space.Compact 替换 | ReactNode | - | 4.17.0 | | ~~addonBefore~~ | 带标签的 input,设置前置标签,请使用 Space.Compact 替换 | ReactNode | - | 4.17.0 | -| autoFocus | 自动获取焦点 | boolean | false | - | | changeOnBlur | 是否在失去焦点时,触发 `onChange` 事件(例如值超出范围时,重新限制回范围并触发事件) | boolean | true | 5.11.0 | | changeOnWheel | 允许鼠标滚轮改变数值 | boolean | - | 5.14.0 | | classNames | 用于自定义组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | - | diff --git a/components/input/OTP/OTPInput.tsx b/components/input/OTP/OTPInput.tsx index aecc3d4069..5f0d9b9dad 100644 --- a/components/input/OTP/OTPInput.tsx +++ b/components/input/OTP/OTPInput.tsx @@ -16,7 +16,7 @@ export interface OTPInputProps extends Omit { } const OTPInput = React.forwardRef((props, ref) => { - const { className, value, onChange, onActiveChange, index, mask, ...restProps } = props; + const { className, value, onChange, onActiveChange, index, mask, onFocus, ...restProps } = props; const { getPrefixCls } = React.useContext(ConfigContext); const prefixCls = getPrefixCls('otp'); const maskValue = typeof mask === 'string' ? mask : value; @@ -40,6 +40,11 @@ const OTPInput = React.forwardRef((props, ref) => { }); }; + const onInternalFocus = (e: React.FocusEvent) => { + onFocus?.(e); + syncSelection(); + }; + // ======================== Keyboard ======================== const onInternalKeyDown: React.KeyboardEventHandler = (event) => { const { key, ctrlKey, metaKey } = event; @@ -74,7 +79,7 @@ const OTPInput = React.forwardRef((props, ref) => { ref={inputRef} value={value} onInput={onInternalChange} - onFocus={syncSelection} + onFocus={onInternalFocus} onKeyDown={onInternalKeyDown} onMouseDown={syncSelection} onMouseUp={syncSelection} diff --git a/components/input/OTP/index.tsx b/components/input/OTP/index.tsx index d51ae7b09c..048c2c80c8 100644 --- a/components/input/OTP/index.tsx +++ b/components/input/OTP/index.tsx @@ -104,6 +104,7 @@ const OTP = React.forwardRef((props, ref) => { mask, type, onInput, + onFocus, inputMode, classNames, styles, @@ -273,6 +274,19 @@ const OTP = React.forwardRef((props, ref) => { refs.current[nextIndex]?.focus(); }; + // ======================== Focus ======================== + const onInputFocus = (event: React.FocusEvent, index: number) => { + // keep focus on the first empty cell + for (let i = 0; i < index; i += 1) { + if (!refs.current[i]?.input?.value) { + refs.current[i]?.focus(); + break; + } + } + + onFocus?.(event); + }; + // ======================== Render ======================== const inputSharedProps: Partial = { variant, @@ -322,6 +336,7 @@ const OTP = React.forwardRef((props, ref) => { value={singleValue} onActiveChange={onInputActiveChange} autoFocus={index === 0 && autoFocus} + onFocus={(event) => onInputFocus(event, index)} {...inputSharedProps} /> {index < length - 1 && ( diff --git a/components/input/__tests__/index.test.tsx b/components/input/__tests__/index.test.tsx index 74caa0e757..b8849ae1fc 100644 --- a/components/input/__tests__/index.test.tsx +++ b/components/input/__tests__/index.test.tsx @@ -6,9 +6,10 @@ import Input from '..'; import { resetWarned } from '../../_util/warning'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; -import { fireEvent, render } from '../../../tests/utils'; +import { fireEvent, render, waitFor } from '../../../tests/utils'; import Form from '../../form'; import { triggerFocus } from '../Input'; +import { ConfigProvider } from 'antd'; describe('Input', () => { const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); @@ -153,6 +154,23 @@ describe('prefix and suffix', () => { expect(container.querySelector('.prefix-with-hidden')?.getAttribute('hidden')).toBe(''); expect(container.querySelector('.suffix-with-hidden')?.getAttribute('hidden')).toBe(''); }); + + it('should apply colorText token to filled variant without affix', async () => { + const colorText = '#445566'; + + const { container } = render( + + + , + ); + + const input = container.querySelector('input') as HTMLInputElement; + + await waitFor(() => { + const computed = getComputedStyle(input).color; + expect(computed).toBe('var(--ant-color-text)'); + }); + }); }); describe('Input setting hidden', () => { diff --git a/components/input/__tests__/otp.test.tsx b/components/input/__tests__/otp.test.tsx index 3befa90150..e1bf197e09 100644 --- a/components/input/__tests__/otp.test.tsx +++ b/components/input/__tests__/otp.test.tsx @@ -109,7 +109,7 @@ describe('Input.OTP', () => { }); it('arrow key to switch', () => { - const { container } = render(); + const { container } = render(); const inputList = Array.from(container.querySelectorAll('input')); expect(document.activeElement).toEqual(inputList[0]); @@ -121,6 +121,22 @@ describe('Input.OTP', () => { expect(document.activeElement).toEqual(inputList[0]); }); + it('should not switch to next input when value is empty', () => { + const onFocus = jest.fn(); + const { container } = render(); + + const inputList = Array.from(container.querySelectorAll('input')); + expect(document.activeElement).toEqual(inputList[0]); + + // Key operation + fireEvent.keyDown(document.activeElement!, { key: 'ArrowRight' }); + expect(document.activeElement).toBe(inputList[0]); + + // Focus directly + fireEvent.focus(inputList[3]); + expect(document.activeElement).toBe(inputList[0]); + }); + it('fill last cell', () => { const { container } = render(); fireEvent.input(container.querySelectorAll('input')[5], { target: { value: '1' } }); diff --git a/components/input/style/variants.ts b/components/input/style/variants.ts index 1b4aebe4a5..c511f91e83 100644 --- a/components/input/style/variants.ts +++ b/components/input/style/variants.ts @@ -263,6 +263,7 @@ export const genFilledStyle = (token: InputToken, extraStyles?: CSSObject): CSSO bg: token.colorFillTertiary, hoverBg: token.colorFillSecondary, activeBorderColor: token.activeBorderColor, + inputColor: token.colorText, }), [`&${token.componentCls}-disabled, &[disabled]`]: { diff --git a/components/mentions/index.en-US.md b/components/mentions/index.en-US.md index a35b208539..149f0dd207 100644 --- a/components/mentions/index.en-US.md +++ b/components/mentions/index.en-US.md @@ -41,7 +41,6 @@ Common props ref:[Common props](/docs/react/common-props) | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | | allowClear | If allow to remove mentions content with clear icon | boolean \| { clearIcon?: ReactNode } | false | 5.13.0 | -| autoFocus | Auto get focus when component mounted | boolean | false | | | autoSize | Textarea height autosize feature, can be set to true \| false or an object { minRows: 2, maxRows: 6 } | boolean \| object | false | | | classNames | Customize class for each semantic structure inside the component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | | defaultValue | Default value | string | - | | diff --git a/components/mentions/index.zh-CN.md b/components/mentions/index.zh-CN.md index edc76745b6..5b73e1e201 100644 --- a/components/mentions/index.zh-CN.md +++ b/components/mentions/index.zh-CN.md @@ -42,7 +42,6 @@ demo: | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | | allowClear | 可以点击清除图标删除内容 | boolean \| { clearIcon?: ReactNode } | false | 5.13.0 | -| autoFocus | 自动获得焦点 | boolean | false | | | autoSize | 自适应内容高度,可设置为 true \| false 或对象:{ minRows: 2, maxRows: 6 } | boolean \| object | false | | | classNames | 用于自定义组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | | defaultValue | 默认值 | string | - | | diff --git a/components/modal/style/index.ts b/components/modal/style/index.ts index af4d5d369d..7e9ec4b03c 100644 --- a/components/modal/style/index.ts +++ b/components/modal/style/index.ts @@ -2,7 +2,7 @@ import type React from 'react'; import { unit } from '@ant-design/cssinjs'; import { getMediaSize } from '../../grid/style'; -import { blurMaskStyle, genFocusStyle, resetComponent } from '../../style'; +import { genFocusStyle, resetComponent } from '../../style'; import { initFadeMotion, initZoomMotion } from '../../style/motion'; import type { AliasToken, @@ -162,7 +162,7 @@ export const genModalMaskStyle: GenerateStyle> = pointerEvents: 'none', [`&${componentCls}-mask-blur`]: { - ...blurMaskStyle, + backdropFilter: 'blur(4px)', }, [`${componentCls}-hidden`]: { diff --git a/components/radio/index.en-US.md b/components/radio/index.en-US.md index a8b3298fa4..48d7b26b0d 100644 --- a/components/radio/index.en-US.md +++ b/components/radio/index.en-US.md @@ -65,7 +65,6 @@ Common props ref:[Common props](/docs/react/common-props) | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | -| autoFocus | Whether get focus when component mounted | boolean | false | | | checked | Specifies whether the radio is selected | boolean | false | | | classNames | Customize class for each semantic structure inside the component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | 6.0.0 | | defaultChecked | Specifies the initial state: whether or not the radio is selected | boolean | false | | diff --git a/components/radio/index.zh-CN.md b/components/radio/index.zh-CN.md index f2fd15299a..c1597a5d87 100644 --- a/components/radio/index.zh-CN.md +++ b/components/radio/index.zh-CN.md @@ -67,7 +67,6 @@ return ( | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | -| autoFocus | 自动获取焦点 | boolean | false | | | checked | 指定当前是否选中 | boolean | false | | | classNames | 用于自定义组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | 6.0.0 | | defaultChecked | 初始是否选中 | boolean | false | | diff --git a/components/rate/index.en-US.md b/components/rate/index.en-US.md index 8edc5df32a..86157b0081 100644 --- a/components/rate/index.en-US.md +++ b/components/rate/index.en-US.md @@ -35,7 +35,6 @@ Common props ref:[Common props](/docs/react/common-props) | --- | --- | --- | --- | --- | | allowClear | Whether to allow clear when click again | boolean | true | | | allowHalf | Whether to allow semi selection | boolean | false | | -| autoFocus | If get focus when component mounted | boolean | false | | | character | The custom character of rate | ReactNode \| (RateProps) => ReactNode | <StarFilled /> | function(): 4.4.0 | | className | The custom class name of rate | string | - | | | count | Star count | number | 5 | | diff --git a/components/rate/index.zh-CN.md b/components/rate/index.zh-CN.md index 77f9f7927b..a2cfbac743 100644 --- a/components/rate/index.zh-CN.md +++ b/components/rate/index.zh-CN.md @@ -36,7 +36,6 @@ demo: | --- | --- | --- | --- | --- | | allowClear | 是否允许再次点击后清除 | boolean | true | | | allowHalf | 是否允许半选 | boolean | false | | -| autoFocus | 自动获取焦点 | boolean | false | | | character | 自定义字符 | ReactNode \| (RateProps) => ReactNode | <StarFilled /> | function(): 4.4.0 | | className | 自定义样式类名 | string | - | | | count | star 总数 | number | 5 | | diff --git a/components/select/index.en-US.md b/components/select/index.en-US.md index 1457fd27c0..851709d9db 100644 --- a/components/select/index.en-US.md +++ b/components/select/index.en-US.md @@ -62,7 +62,6 @@ Common props ref:[Common props](/docs/react/common-props) | --- | --- | --- | --- | --- | | allowClear | Customize clear icon | boolean \| { clearIcon?: ReactNode } | false | 5.8.0: Support object type | | ~autoClearSearchValue~ | Whether the current search will be cleared on selecting an item. Only applies when `mode` is set to `multiple` or `tags` | boolean | true | | -| autoFocus | Get focus by default | boolean | false | | | classNames | Customize class for each semantic structure inside the Select component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | | defaultActiveFirstOption | Whether active first option by default | boolean | true | | | defaultOpen | Initial open state of dropdown | boolean | - | | diff --git a/components/select/index.zh-CN.md b/components/select/index.zh-CN.md index 0292e639eb..73050fe540 100644 --- a/components/select/index.zh-CN.md +++ b/components/select/index.zh-CN.md @@ -63,7 +63,6 @@ demo: | --- | --- | --- | --- | --- | | allowClear | 自定义清除按钮 | boolean \| { clearIcon?: ReactNode } | false | 5.8.0: 支持对象类型 | | ~~autoClearSearchValue~~ | 是否在选中项后清空搜索框,只在 `mode` 为 `multiple` 或 `tags` 时有效 | boolean | true | | -| autoFocus | 默认获取焦点 | boolean | false | | | classNames | 用于自定义 Select 组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props }) => Record<[SemanticDOM](#semantic-dom), string> | - | | | defaultActiveFirstOption | 是否默认高亮第一个选项 | boolean | true | | | defaultOpen | 是否默认展开下拉菜单 | boolean | - | | diff --git a/components/slider/index.en-US.md b/components/slider/index.en-US.md index f01e95ea05..94a89f4dfa 100644 --- a/components/slider/index.en-US.md +++ b/components/slider/index.en-US.md @@ -37,7 +37,6 @@ Common props ref:[Common props](/docs/react/common-props) | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | -| autoFocus | Whether to get focus when component is mounted | boolean | false | | | classNames | Customize class for each semantic structure inside the component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | | defaultValue | The default value of the slider. When `range` is false, use number, otherwise, use \[number, number] | number \| \[number, number] | 0 \| \[0, 0] | | | disabled | If true, the slider will not be interactive | boolean | false | | diff --git a/components/slider/index.zh-CN.md b/components/slider/index.zh-CN.md index b70bd75a51..52990f965a 100644 --- a/components/slider/index.zh-CN.md +++ b/components/slider/index.zh-CN.md @@ -38,7 +38,6 @@ demo: | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | -| autoFocus | 自动获取焦点 | boolean | false | | | classNames | 用于自定义组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | | | defaultValue | 设置初始取值。当 `range` 为 false 时,使用 number,否则用 \[number, number] | number \| \[number, number] | 0 \| \[0, 0] | | | disabled | 值为 true 时,滑块为禁用状态 | boolean | false | | diff --git a/components/splitter/__tests__/size.test.tsx b/components/splitter/__tests__/size.test.tsx index ddec908cd3..343bfcfa01 100644 --- a/components/splitter/__tests__/size.test.tsx +++ b/components/splitter/__tests__/size.test.tsx @@ -74,4 +74,37 @@ describe('useSizes', () => { // In impossible case, should average fill (1000 / 3 = 333.33... for each) expect(postPxSizes).toEqual([1000 / 3, 1000 / 3, 1000 / 3]); }); + + it('should average if size total is not 100%', () => { + const items = [ + { + size: '20%', + }, + { + size: '30%', + }, + ]; + + const { result } = renderHook(() => useSizes(items, containerSize)); + const [sizes] = result.current; + + // Check sizes + expect(sizes).toEqual([400, 600]); + }); + + it('should correct when all size is 0', () => { + const items = [ + { + size: 0, + }, + { + size: 0, + }, + ]; + + const { result } = renderHook(() => useSizes(items, containerSize)); + const [, postPxSizes] = result.current; + + expect(postPxSizes).toEqual([500, 500]); + }); }); diff --git a/components/splitter/hooks/sizeUtil.ts b/components/splitter/hooks/sizeUtil.ts index 5391b35bcc..1bb1b9b942 100644 --- a/components/splitter/hooks/sizeUtil.ts +++ b/components/splitter/hooks/sizeUtil.ts @@ -19,6 +19,18 @@ export function autoPtgSizes( const restPtg = 1 - currentTotalPtg; const undefinedCount = undefinedIndexes.length; + // If all sizes are defined but don't sum to 1, scale them. + if (ptgSizes.length && !undefinedIndexes.length && currentTotalPtg !== 1) { + // Handle the case when all sizes are 0 + if (currentTotalPtg === 0) { + const avg = 1 / ptgSizes.length; + return ptgSizes.map(() => avg); + } + const scale = 1 / currentTotalPtg; + // We know `size` is a number here because undefinedIndexes is empty. + return ptgSizes.map((size) => (size as number) * scale); + } + // Fill if exceed if (restPtg < 0) { const scale = 1 / currentTotalPtg; diff --git a/components/style/index.tsx b/components/style/index.tsx index eaadf8bc4b..c282890b92 100644 --- a/components/style/index.tsx +++ b/components/style/index.tsx @@ -181,8 +181,3 @@ export const operationUnit = (token: AliasToken): CSSObject => ({ textDecoration: token.linkHoverDecoration, }, }); - -export const blurMaskStyle = { - backdropFilter: 'blur(4px)', - backgroundColor: 'rgba(0, 0, 0, 0.3)', -}; diff --git a/components/switch/index.en-US.md b/components/switch/index.en-US.md index 92cc70b625..d030d73330 100644 --- a/components/switch/index.en-US.md +++ b/components/switch/index.en-US.md @@ -31,7 +31,6 @@ Common props ref:[Common props](/docs/react/common-props) | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | -| autoFocus | Whether get focus when component mounted | boolean | false | | | checked | Determine whether the Switch is checked | boolean | false | | | checkedChildren | The content to be shown when the state is checked | ReactNode | - | | | className | The additional class to Switch | string | - | | diff --git a/components/switch/index.zh-CN.md b/components/switch/index.zh-CN.md index 6a8b1085b3..ee73c13cf1 100644 --- a/components/switch/index.zh-CN.md +++ b/components/switch/index.zh-CN.md @@ -32,7 +32,6 @@ demo: | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | -| autoFocus | 组件自动获取焦点 | boolean | false | | | checked | 指定当前是否选中 | boolean | false | | | checkedChildren | 选中时的内容 | ReactNode | - | | | className | Switch 器类名 | string | - | | diff --git a/components/table/hooks/useSelection.tsx b/components/table/hooks/useSelection.tsx index fb05e8d626..2f9f71a35b 100644 --- a/components/table/hooks/useSelection.tsx +++ b/components/table/hooks/useSelection.tsx @@ -164,10 +164,10 @@ const useSelection = ( let convertData = data; if (preserveSelectedRowKeys) { // use flattedData keys - const keysSet = new Set(flattedData.map((record, index) => getRowKey(record, index))); + const keysSet = new Set(flattedData.map(getRowKey)); // remove preserveRecords that duplicate data - const preserveRecords = Array.from(preserveRecordsRef.current).reduce( - (total: RecordType[], [key, value]) => (keysSet.has(key) ? total : total.concat(value)), + const preserveRecords = Array.from(preserveRecordsRef.current).reduce( + (total, [key, value]) => (keysSet.has(key) ? total : total.concat(value)), [], ); convertData = [...convertData, ...preserveRecords]; diff --git a/components/tabs/demo/extra.tsx b/components/tabs/demo/extra.tsx index 39a48b674c..c151f4f843 100644 --- a/components/tabs/demo/extra.tsx +++ b/components/tabs/demo/extra.tsx @@ -1,11 +1,12 @@ import React, { useMemo, useState } from 'react'; +import type { TabBarExtraMap } from '@rc-component/tabs/es/interface'; import { Button, Checkbox, Divider, Tabs } from 'antd'; const CheckboxGroup = Checkbox.Group; const operations = ; -const OperationsSlot: Record = { +const operationsSlot: Record = { left: , right: , }; @@ -30,8 +31,8 @@ const App: React.FC = () => { if (position.length === 0) { return null; } - return position.reduce( - (acc, direction) => ({ ...acc, [direction]: OperationsSlot[direction] }), + return position.reduce( + (acc, direction) => ({ ...acc, [direction]: operationsSlot[direction] }), {}, ); }, [position]); @@ -44,13 +45,7 @@ const App: React.FC = () => {
You can also specify its direction or both side
- { - setPosition(value as PositionType[]); - }} - /> + options={options} value={position} onChange={setPosition} />

diff --git a/components/tag/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/tag/__tests__/__snapshots__/demo-extend.test.ts.snap index dad0cd785b..4ec5f350fa 100644 --- a/components/tag/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/tag/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -1266,8 +1266,7 @@ Array [ /> ,
,
,
,
{ return ( <> Tag with icon - + } color="#55acee"> Twitter @@ -34,7 +34,7 @@ const App: React.FC = () => { CheckableTag with icon - + } checked={checked[0]} diff --git a/components/theme/interface/maps/colors.ts b/components/theme/interface/maps/colors.ts index fe3d1b1480..520405ebe5 100644 --- a/components/theme/interface/maps/colors.ts +++ b/components/theme/interface/maps/colors.ts @@ -626,8 +626,8 @@ export interface ColorMapToken /** * @nameZH 浮层的背景蒙层颜色 * @nameEN Background color of the mask - * @desc 浮层的背景蒙层颜色,用于遮罩浮层下面的内容,Modal、Drawer 等组件的蒙层使用的是该 token - * @descEN The background color of the mask, used to cover the content below the mask, Modal, Drawer and other components use this token + * @desc 浮层的背景蒙层颜色,用于遮罩浮层下面的内容,Modal、Drawer、Image 等组件的蒙层使用的是该 token + * @descEN The background color of the mask, used to cover the content below the mask, Modal, Drawer, Image and other components use this token */ colorBgMask: string; diff --git a/components/time-picker/index.en-US.md b/components/time-picker/index.en-US.md index 20544a4b6a..1792778ca3 100644 --- a/components/time-picker/index.en-US.md +++ b/components/time-picker/index.en-US.md @@ -52,7 +52,6 @@ dayjs.extend(customParseFormat) | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | | allowClear | Customize clear icon | boolean \| { clearIcon?: ReactNode } | true | 5.8.0: Support object type | -| autoFocus | If get focus when component mounted | boolean | false | | | cellRender | Custom rendering function for picker cells | (current: number, info: { originNode: React.ReactElement, today: dayjs, range?: 'start' \| 'end', subType: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 | | changeOnScroll | Trigger selection when scroll the column | boolean | false | 5.14.0 | | className | The className of picker | string | - | | diff --git a/components/time-picker/index.zh-CN.md b/components/time-picker/index.zh-CN.md index 9364bacad0..d562606272 100644 --- a/components/time-picker/index.zh-CN.md +++ b/components/time-picker/index.zh-CN.md @@ -52,7 +52,6 @@ dayjs.extend(customParseFormat) | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | | allowClear | 自定义清除按钮 | boolean \| { clearIcon?: ReactNode } | true | 5.8.0: 支持对象类型 | -| autoFocus | 自动获取焦点 | boolean | false | | | cellRender | 自定义单元格的内容 | (current: number, info: { originNode: React.ReactNode, today: dayjs, range?: 'start' \| 'end', subType: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 | | changeOnScroll | 在滚动时改变选择值 | boolean | false | 5.14.0 | | className | 选择器类名 | string | - | | diff --git a/docs/react/common-props.en-US.md b/docs/react/common-props.en-US.md index 340f9ae27f..93502371a8 100644 --- a/docs/react/common-props.en-US.md +++ b/docs/react/common-props.en-US.md @@ -7,8 +7,9 @@ title: Common Props > Tips: The following generic properties apply to most antd components; those not supported are described separately. -| Property | Description | Type | Default | -| ------------- | ----------------------------- | ------------- | ------- | -| style | The additional style | CSSProperties | - | -| className | The additional css class | string | - | -| rootClassName | ClassName on the root element | string | - | +| Property | Description | Type | Default | +| --- | --- | --- | --- | +| style | The additional style | CSSProperties | - | +| className | The additional css class | string | - | +| rootClassName | ClassName on the root element | string | - | +| autoFocus | Auto focus when component mounted, only effective for focusable elements like forms, links, etc. | boolean | false | diff --git a/docs/react/common-props.zh-CN.md b/docs/react/common-props.zh-CN.md index 24a5042b1e..70a2128d35 100644 --- a/docs/react/common-props.zh-CN.md +++ b/docs/react/common-props.zh-CN.md @@ -7,8 +7,9 @@ title: 通用属性 > Tips: 以下通用属性适用于 antd 大部分组件,不支持的组件会单独说明。 -| 参数 | 说明 | 类型 | 默认值 | -| ------------- | ---------------------------- | ------------- | ------ | -| style | 自定义样式 | CSSProperties | - | -| className | 自定义类名 | string | - | -| rootClassName | 添加在组件最外层的 className | string | - | +| 参数 | 说明 | 类型 | 默认值 | +| --- | --- | --- | --- | +| style | 自定义样式 | CSSProperties | - | +| className | 自定义类名 | string | - | +| rootClassName | 添加在组件最外层的 className | string | - | +| autoFocus | 自动获取焦点,仅对表单类、链接、交互容器等可聚焦元素生效 | boolean | false | diff --git a/package.json b/package.json index 49ec9549f4..d299558881 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd", - "version": "6.0.0", + "version": "6.0.1", "description": "An enterprise-class UI design language and React components implementation", "license": "MIT", "funding": { @@ -115,33 +115,34 @@ "@ant-design/fast-color": "^3.0.0", "@ant-design/icons": "^6.1.0", "@ant-design/react-slick": "~1.1.2", + "@babel/runtime": "^7.28.4", "@rc-component/cascader": "~1.8.0", - "@rc-component/checkbox": "~1.0.0", - "@rc-component/collapse": "~1.1.1", - "@rc-component/color-picker": "~3.0.2", - "@rc-component/dialog": "~1.5.0", + "@rc-component/checkbox": "~1.0.1", + "@rc-component/collapse": "~1.1.2", + "@rc-component/color-picker": "~3.0.3", + "@rc-component/dialog": "~1.5.1", "@rc-component/drawer": "~1.3.0", - "@rc-component/dropdown": "~1.0.0", + "@rc-component/dropdown": "~1.0.2", "@rc-component/form": "~1.4.0", - "@rc-component/image": "~1.5.1", + "@rc-component/image": "~1.5.2", "@rc-component/input": "~1.1.2", "@rc-component/input-number": "~1.6.2", "@rc-component/mentions": "~1.5.5", "@rc-component/menu": "~1.1.5", - "@rc-component/motion": "~1.1.4", - "@rc-component/mutate-observer": "^2.0.0", + "@rc-component/motion": "~1.1.5", + "@rc-component/mutate-observer": "^2.0.1", "@rc-component/notification": "~1.2.0", "@rc-component/pagination": "~1.2.0", "@rc-component/picker": "~1.7.1", - "@rc-component/progress": "~1.0.1", - "@rc-component/qrcode": "~1.1.0", - "@rc-component/rate": "~1.0.0", + "@rc-component/progress": "~1.0.2", + "@rc-component/qrcode": "~1.1.1", + "@rc-component/rate": "~1.0.1", "@rc-component/resize-observer": "^1.0.1", "@rc-component/segmented": "~1.2.3", - "@rc-component/select": "~1.2.3", - "@rc-component/slider": "~1.0.0", + "@rc-component/select": "~1.2.4", + "@rc-component/slider": "~1.0.1", "@rc-component/steps": "~1.2.2", - "@rc-component/switch": "~1.0.2", + "@rc-component/switch": "~1.0.3", "@rc-component/table": "~1.8.2", "@rc-component/tabs": "~1.6.0", "@rc-component/textarea": "~1.1.2", @@ -164,7 +165,7 @@ "@ant-design/x": "^1.6.1", "@antfu/eslint-config": "^6.0.0", "@antv/g6": "^4.8.25", - "@biomejs/biome": "^2.2.5", + "@biomejs/biome": "^2.3.8", "@blazediff/core": "^1.4.0", "@codecov/webpack-plugin": "^1.9.1", "@codesandbox/sandpack-react": "^2.20.0", @@ -184,7 +185,7 @@ "@octokit/rest": "^22.0.0", "@prettier/sync": "^0.6.1", "@qixian.cs/github-contributors-list": "^2.0.2", - "@size-limit/file": "^11.2.0", + "@size-limit/file": "^12.0.0", "@stackblitz/sdk": "^1.11.0", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", @@ -316,7 +317,7 @@ "semver": "^7.7.2", "sharp": "^0.34.4", "simple-git": "^3.28.0", - "size-limit": "^11.2.0", + "size-limit": "^12.0.0", "spinnies": "^0.5.1", "swr": "^2.3.6", "tar": "^7.5.1", diff --git a/scripts/generate-authors.ts b/scripts/generate-authors.ts index 89d6c39963..e34b40d494 100644 --- a/scripts/generate-authors.ts +++ b/scripts/generate-authors.ts @@ -22,6 +22,7 @@ const excludes = [ 'renovate[bot]', 'dependabot', 'dependabot[bot]', + 'gemini-code-assist[bot]', ]; async function execute() { diff --git a/scripts/visual-regression/reportAdapter.ts b/scripts/visual-regression/reportAdapter.ts index ce19d0d6af..b92b097229 100644 --- a/scripts/visual-regression/reportAdapter.ts +++ b/scripts/visual-regression/reportAdapter.ts @@ -15,7 +15,7 @@ const REPORT_DIR = path.join(ROOT, 'visualRegressionReport'); const components = fg .sync('components/*/index.ts[x]', { cwd: ROOT }) - .reduce((acc, file) => { + .reduce((acc, file) => { const basePath = path.dirname(file); if ( [ @@ -26,9 +26,8 @@ const components = fg ) { acc.push(path.basename(basePath)); } - return acc; - }, [] as string[]) + }, []) .sort((a, b) => b.length - a.length); const processedComponents = new Set(); diff --git a/tests/__mocks__/rc-util/lib/Portal.tsx b/tests/__mocks__/rc-util/lib/Portal.tsx index e1e98cae59..7999181e17 100644 --- a/tests/__mocks__/rc-util/lib/Portal.tsx +++ b/tests/__mocks__/rc-util/lib/Portal.tsx @@ -2,8 +2,9 @@ import React from 'react'; import type { PortalProps, PortalRef } from '@rc-component/util/lib/Portal'; import { TriggerMockContext } from '../../../shared/demoTestContext'; -let OriginPortal = jest.requireActual('@rc-component/util/lib/Portal'); -OriginPortal = OriginPortal.default ?? OriginPortal; +const OriginPortalModule = jest.requireActual('@rc-component/util/lib/Portal'); + +const OriginPortal = OriginPortalModule.default ?? OriginPortalModule; class MockPortal extends React.Component { container: boolean | undefined; @@ -28,7 +29,7 @@ class MockPortal extends React.Component { } } -const CustomPortal = React.forwardRef( +const CustomPortal = React.forwardRef>( (props, ref) => { const context = React.useContext(TriggerMockContext); if (context?.mock === false) { diff --git a/tests/shared/accessibilityTest.tsx b/tests/shared/accessibilityTest.tsx index 78bf39feb4..0ccf6d3acd 100644 --- a/tests/shared/accessibilityTest.tsx +++ b/tests/shared/accessibilityTest.tsx @@ -49,18 +49,15 @@ type Rules = { }; }; -const convertRulesToAxeFormat = (rules: string[]): Rules => { - return rules.reduce( - (acc, rule) => ({ - ...acc, - [rule]: { enabled: false }, - }), - {}, - ); +const convertRulesToAxeFormat = (rules: string[]) => { + return rules.reduce((acc, rule) => ({ ...acc, [rule]: { enabled: false } }), {}); }; // eslint-disable-next-line jest/no-export -export function accessibilityTest(Component: React.ComponentType, disabledRules?: string[]) { +export const accessibilityTest = ( + Component: React.ComponentType, + disabledRules?: string[], +) => { beforeAll(() => { // Fake ResizeObserver global.ResizeObserver = jest.fn(() => { @@ -109,7 +106,7 @@ export function accessibilityTest(Component: React.ComponentType, disabledRules? expect(results).toHaveNoViolations(); }, 50000); }); -} +}; type Options = { /** @@ -146,7 +143,7 @@ export default function accessibilityDemoTest(component: string, options: Option const testMethod = shouldSkip ? describe.skip : describe; testMethod(`Test ${file} accessibility`, () => { - const Demo = require(`../../${file}`).default; + const Demo: React.ComponentType = require(`../../${file}`).default; accessibilityTest(Demo, options.disabledRules); }); });