Merge branch master into master-merge-feature

This commit is contained in:
lijianan
2025-12-03 05:12:43 +08:00
67 changed files with 397 additions and 251 deletions

View File

@@ -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 = () => {
>
<GlobalStyles />
{!hideLayout && <Header />}
<VersionUpgrade />
{content}
</ConfigProvider>
</>

View File

@@ -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 = () => {
<SiteThemeProvider theme={themeConfig}>
<HappyProvider disabled={!theme.includes('happy-work')}>
<ConfigProvider {...componentsClassNames}>
<App>
{outlet}
<VersionUpgrade />
</App>
<App>{outlet}</App>
</ConfigProvider>
</HappyProvider>
</SiteThemeProvider>

View File

@@ -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<ContributorsProps> = ({ filename }) => {
const { formatMessage } = useIntl();

View File

@@ -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<string>(({ title }) => title!).filter(Boolean) || [];
const [openKeys, setOpenKeys] = React.useState<string[]>(defaultOpenKeys);
useEffect(() => {
if (openKeys.join(',') === defaultOpenKeys.join(',')) {
return;
}
setOpenKeys(defaultOpenKeys);
}, [defaultOpenKeys.join(',')]);
const menuChild = (
<ConfigProvider
theme={{ components: { Menu: { itemBg: colorBgContainer, darkItemBg: colorBgContainer } } }}
@@ -125,7 +135,8 @@ const Sidebar: React.FC = () => {
mode="inline"
theme={isDark ? 'dark' : 'light'}
selectedKeys={[selectedKey]}
defaultOpenKeys={sidebarData?.map<string>(({ title }) => title!).filter(Boolean)}
openKeys={openKeys}
onOpenChange={setOpenKeys}
/>
</ConfigProvider>
);

View File

@@ -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)** 以了解安全最佳实践。

130
.github/WORKFLOWS_SECURITY.md vendored Normal file
View File

@@ -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)

View File

@@ -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, 🇺🇸 英文, 🇨🇳 中文'

View File

@@ -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 }}

View File

@@ -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.

View File

@@ -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`

View File

@@ -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`

View File

@@ -5,6 +5,7 @@
"includes": [
"**",
"!.dumi/tmp*",
"!report.html",
"!.dumi/scripts/clarity.js",
"!dist/*",
"!es/**/*",

View File

@@ -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&lt;InputProps> | &lt;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> | - | |

View File

@@ -46,7 +46,6 @@ demo:
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| allowClear | 支持清除 | boolean \| { clearIcon?: ReactNode } | false | 5.8.0: 支持对象形式 |
| autoFocus | 自动获取焦点 | boolean | false | |
| backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false | |
| children | 自定义输入框 | HTMLInputElement \| HTMLTextAreaElement \| React.ReactElement&lt;InputProps> | &lt;Input /> | |
| classNames | 用于自定义组件内部各语义化结构的 class支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | |

View File

@@ -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> | - | |

View File

@@ -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> | - | |

View File

@@ -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 | |

View File

@@ -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 | |

View File

@@ -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: <p>{text}</p>,
},
{
key: '2',
label: 'This is panel header 2',
children: <p>{text}</p>,
},
{
key: '3',
label: 'This is panel header 3',
children: <p>{text}</p>,
},
];
<Collapse items={items} defaultActiveKey={['1']} />;
// works when <5.6.0 , deprecated when >=5.6.0 🙅🏻‍♀️
<Collapse defaultActiveKey={['1']} onChange={onChange}>
<Panel header="This is panel header 1" key="1">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 2" key="2">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 3" key="3">
<p>{text}</p>
</Panel>
</Collapse>;
```
## Examples
<!-- prettier-ignore -->

View File

@@ -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: <p>{text}</p>,
},
{
key: '2',
label: 'This is panel header 2',
children: <p>{text}</p>,
},
{
key: '3',
label: 'This is panel header 3',
children: <p>{text}</p>,
},
];
<Collapse items={items} defaultActiveKey={['1']} />;
// <5.6.0 可用,>=5.6.0 时不推荐 🙅🏻‍♀️
<Collapse defaultActiveKey={['1']} onChange={onChange}>
<Panel header="This is panel header 1" key="1">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 2" key="2">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 3" key="3">
<p>{text}</p>
</Panel>
</Collapse>;
```
## 代码演示 {#examples}
<!-- prettier-ignore -->

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -157,6 +157,7 @@ const genPickerStyle: GenerateStyle<PickerToken> = (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<PickerToken> = (token) => {
'&-small': {
...genPickerPadding(token.paddingBlockSM, token.paddingInlineSM),
borderRadius: token.borderRadiusSM,
[`${componentCls}-input > input`]: {
fontSize: inputFontSizeSM ?? fontSizeSM,
},

View File

@@ -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> | - | |

View File

@@ -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> | - | |

View File

@@ -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<DrawerToken> = (token) => {
pointerEvents: 'auto',
[`&${componentCls}-mask-blur`]: {
...blurMaskStyle,
backdropFilter: 'blur(4px)',
},
},

View File

@@ -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 | |

View File

@@ -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 | |

View File

@@ -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<ImageToken> = (token: ImageToke
previewCls,
motionDurationSlow,
componentCls,
modalMaskBg,
colorBgMask,
marginXL,
marginSM,
margin,
@@ -115,7 +109,7 @@ export const genImagePreviewStyle: GenerateStyle<ImageToken> = (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<ImageToken> = (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<ImageToken>(token, {
previewCls,
modalMaskBg: new FastColor('#000').setA(0.45).toRgbString(), // FIXME: Shared Token
imagePreviewSwitchSize: token.controlHeightLG,
});

View File

@@ -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> | - | - |

View File

@@ -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> | - | - |

View File

@@ -16,7 +16,7 @@ export interface OTPInputProps extends Omit<InputProps, 'onChange'> {
}
const OTPInput = React.forwardRef<InputRef, OTPInputProps>((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<InputRef, OTPInputProps>((props, ref) => {
});
};
const onInternalFocus = (e: React.FocusEvent<HTMLInputElement>) => {
onFocus?.(e);
syncSelection();
};
// ======================== Keyboard ========================
const onInternalKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {
const { key, ctrlKey, metaKey } = event;
@@ -74,7 +79,7 @@ const OTPInput = React.forwardRef<InputRef, OTPInputProps>((props, ref) => {
ref={inputRef}
value={value}
onInput={onInternalChange}
onFocus={syncSelection}
onFocus={onInternalFocus}
onKeyDown={onInternalKeyDown}
onMouseDown={syncSelection}
onMouseUp={syncSelection}

View File

@@ -104,6 +104,7 @@ const OTP = React.forwardRef<OTPRef, OTPProps>((props, ref) => {
mask,
type,
onInput,
onFocus,
inputMode,
classNames,
styles,
@@ -273,6 +274,19 @@ const OTP = React.forwardRef<OTPRef, OTPProps>((props, ref) => {
refs.current[nextIndex]?.focus();
};
// ======================== Focus ========================
const onInputFocus = (event: React.FocusEvent<HTMLInputElement>, 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<OTPInputProps> = {
variant,
@@ -322,6 +336,7 @@ const OTP = React.forwardRef<OTPRef, OTPProps>((props, ref) => {
value={singleValue}
onActiveChange={onInputActiveChange}
autoFocus={index === 0 && autoFocus}
onFocus={(event) => onInputFocus(event, index)}
{...inputSharedProps}
/>
{index < length - 1 && (

View File

@@ -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(
<ConfigProvider theme={{ token: { colorText } }}>
<Input variant="filled" placeholder="Filled" defaultValue="Default" />
</ConfigProvider>,
);
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', () => {

View File

@@ -109,7 +109,7 @@ describe('Input.OTP', () => {
});
it('arrow key to switch', () => {
const { container } = render(<OTP autoFocus />);
const { container } = render(<OTP autoFocus defaultValue="12" />);
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(<OTP autoFocus onFocus={onFocus} />);
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(<OTP />);
fireEvent.input(container.querySelectorAll('input')[5], { target: { value: '1' } });

View File

@@ -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]`]: {

View File

@@ -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 | - | |

View File

@@ -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 | - | |

View File

@@ -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<TokenWithCommonCls<AliasToken>> =
pointerEvents: 'none',
[`&${componentCls}-mask-blur`]: {
...blurMaskStyle,
backdropFilter: 'blur(4px)',
},
[`${componentCls}-hidden`]: {

View File

@@ -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 | |

View File

@@ -67,7 +67,6 @@ return (
<!-- prettier-ignore -->
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| 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 | |

View File

@@ -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 | &lt;StarFilled /> | function(): 4.4.0 |
| className | The custom class name of rate | string | - | |
| count | Star count | number | 5 | |

View File

@@ -36,7 +36,6 @@ demo:
| --- | --- | --- | --- | --- |
| allowClear | 是否允许再次点击后清除 | boolean | true | |
| allowHalf | 是否允许半选 | boolean | false | |
| autoFocus | 自动获取焦点 | boolean | false | |
| character | 自定义字符 | ReactNode \| (RateProps) => ReactNode | &lt;StarFilled /> | function(): 4.4.0 |
| className | 自定义样式类名 | string | - | |
| count | star 总数 | number | 5 | |

View File

@@ -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 | - | |

View File

@@ -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 | - | |

View File

@@ -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 | |

View File

@@ -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 | |

View File

@@ -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]);
});
});

View File

@@ -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;

View File

@@ -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)',
};

View File

@@ -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 | - | |

View File

@@ -32,7 +32,6 @@ demo:
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| autoFocus | 组件自动获取焦点 | boolean | false | |
| checked | 指定当前是否选中 | boolean | false | |
| checkedChildren | 选中时的内容 | ReactNode | - | |
| className | Switch 器类名 | string | - | |

View File

@@ -164,10 +164,10 @@ const useSelection = <RecordType extends AnyObject = AnyObject>(
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<RecordType[]>(
(total, [key, value]) => (keysSet.has(key) ? total : total.concat(value)),
[],
);
convertData = [...convertData, ...preserveRecords];

View File

@@ -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 = <Button>Extra Action</Button>;
const OperationsSlot: Record<PositionType, React.ReactNode> = {
const operationsSlot: Record<PositionType, React.ReactNode> = {
left: <Button className="tabs-extra-demo-button">Left Extra Action</Button>,
right: <Button>Right Extra Action</Button>,
};
@@ -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<TabBarExtraMap>(
(acc, direction) => ({ ...acc, [direction]: operationsSlot[direction] }),
{},
);
}, [position]);
@@ -44,13 +45,7 @@ const App: React.FC = () => {
<br />
<div>You can also specify its direction or both side</div>
<Divider />
<CheckboxGroup
options={options}
value={position}
onChange={(value) => {
setPosition(value as PositionType[]);
}}
/>
<CheckboxGroup<PositionType> options={options} value={position} onChange={setPosition} />
<br />
<br />
<Tabs tabBarExtraContent={slot} items={items} />

View File

@@ -1266,8 +1266,7 @@ Array [
/>
</div>,
<div
class="ant-flex css-var-test-id ant-flex-wrap-wrap ant-flex-align-center"
style="gap: 4px 0;"
class="ant-flex css-var-test-id ant-flex-wrap-wrap ant-flex-align-center ant-flex-gap-small"
>
<span
class="ant-tag ant-tag-filled css-var-test-id"
@@ -1395,8 +1394,7 @@ Array [
/>
</div>,
<div
class="ant-flex css-var-test-id ant-flex-wrap-wrap ant-flex-align-center"
style="gap: 4px 0;"
class="ant-flex css-var-test-id ant-flex-wrap-wrap ant-flex-align-center ant-flex-gap-small"
>
<span
class="ant-tag ant-tag-checkable ant-tag-checkable-checked css-var-test-id"

View File

@@ -1256,8 +1256,7 @@ Array [
/>
</div>,
<div
class="ant-flex css-var-test-id ant-flex-wrap-wrap ant-flex-align-center"
style="gap:4px 0"
class="ant-flex css-var-test-id ant-flex-wrap-wrap ant-flex-align-center ant-flex-gap-small"
>
<span
class="ant-tag ant-tag-filled css-var-test-id"
@@ -1385,8 +1384,7 @@ Array [
/>
</div>,
<div
class="ant-flex css-var-test-id ant-flex-wrap-wrap ant-flex-align-center"
style="gap:4px 0"
class="ant-flex css-var-test-id ant-flex-wrap-wrap ant-flex-align-center ant-flex-gap-small"
>
<span
class="ant-tag ant-tag-checkable ant-tag-checkable-checked css-var-test-id"

View File

@@ -19,7 +19,7 @@ const App: React.FC = () => {
return (
<>
<Divider titlePlacement="start">Tag with icon</Divider>
<Flex gap="4px 0" wrap align="center">
<Flex gap="small" wrap align="center">
<Tag icon={<TwitterOutlined />} color="#55acee">
Twitter
</Tag>
@@ -34,7 +34,7 @@ const App: React.FC = () => {
</Tag>
</Flex>
<Divider titlePlacement="start">CheckableTag with icon</Divider>
<Flex gap="4px 0" wrap align="center">
<Flex gap="small" wrap align="center">
<Tag.CheckableTag
icon={<TwitterOutlined />}
checked={checked[0]}

View File

@@ -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;

View File

@@ -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 | - | |

View File

@@ -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 | - | |

View File

@@ -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 |

View File

@@ -7,8 +7,9 @@ title: 通用属性
> Tips: 以下通用属性适用于 antd 大部分组件,不支持的组件会单独说明。
| 参数 | 说明 | 类型 | 默认值 |
| ------------- | ---------------------------- | ------------- | ------ |
| style | 自定义样式 | CSSProperties | - |
| className | 自定义类名 | string | - |
| rootClassName | 添加在组件最外层的 className | string | - |
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| style | 自定义样式 | CSSProperties | - |
| className | 自定义类名 | string | - |
| rootClassName | 添加在组件最外层的 className | string | - |
| autoFocus | 自动获取焦点,仅对表单类、链接、交互容器等可聚焦元素生效 | boolean | false |

View File

@@ -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",

View File

@@ -22,6 +22,7 @@ const excludes = [
'renovate[bot]',
'dependabot',
'dependabot[bot]',
'gemini-code-assist[bot]',
];
async function execute() {

View File

@@ -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<string[]>((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<string>();

View File

@@ -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<React.PropsWithChildren> {
container: boolean | undefined;
@@ -28,7 +29,7 @@ class MockPortal extends React.Component<React.PropsWithChildren> {
}
}
const CustomPortal = React.forwardRef<PortalRef, PortalProps | React.PropsWithChildren>(
const CustomPortal = React.forwardRef<PortalRef, React.PropsWithChildren<PortalProps>>(
(props, ref) => {
const context = React.useContext(TriggerMockContext);
if (context?.mock === false) {

View File

@@ -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<Rules>((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<any>,
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<any> = require(`../../${file}`).default;
accessibilityTest(Demo, options.disabledRules);
});
});