mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-08 18:39:20 +08:00
Merge branch master into master-merge-feature
This commit is contained in:
@@ -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>
|
||||
</>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
8
.github/CONTRIBUTING.md
vendored
8
.github/CONTRIBUTING.md
vendored
@@ -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
130
.github/WORKFLOWS_SECURITY.md
vendored
Normal 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)
|
||||
4
.github/workflows/pr-open-check.yml
vendored
4
.github/workflows/pr-open-check.yml
vendored
@@ -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, 🇺🇸 英文, 🇨🇳 中文'
|
||||
|
||||
25
.github/workflows/rebase.yml
vendored
25
.github/workflows/rebase.yml
vendored
@@ -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 }}
|
||||
11
.jest.js
11
.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.
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"includes": [
|
||||
"**",
|
||||
"!.dumi/tmp*",
|
||||
"!report.html",
|
||||
"!.dumi/scripts/clarity.js",
|
||||
"!dist/*",
|
||||
"!es/**/*",
|
||||
|
||||
@@ -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> | - | |
|
||||
|
||||
@@ -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> | - | |
|
||||
|
||||
@@ -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> | - | |
|
||||
|
||||
@@ -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> | - | |
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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> | - | |
|
||||
|
||||
@@ -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> | - | |
|
||||
|
||||
@@ -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)',
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
|
||||
@@ -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> | - | - |
|
||||
|
||||
@@ -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> | - | - |
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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 && (
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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' } });
|
||||
|
||||
@@ -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]`]: {
|
||||
|
||||
@@ -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 | - | |
|
||||
|
||||
@@ -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 | - | |
|
||||
|
||||
@@ -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`]: {
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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 | - | |
|
||||
|
||||
@@ -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 | - | |
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)',
|
||||
};
|
||||
|
||||
@@ -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 | - | |
|
||||
|
||||
@@ -32,7 +32,6 @@ demo:
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| autoFocus | 组件自动获取焦点 | boolean | false | |
|
||||
| checked | 指定当前是否选中 | boolean | false | |
|
||||
| checkedChildren | 选中时的内容 | ReactNode | - | |
|
||||
| className | Switch 器类名 | string | - | |
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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} />
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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]}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 | - | |
|
||||
|
||||
@@ -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 | - | |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -7,8 +7,9 @@ title: 通用属性
|
||||
|
||||
> Tips: 以下通用属性适用于 antd 大部分组件,不支持的组件会单独说明。
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| ------------- | ---------------------------- | ------------- | ------ |
|
||||
| style | 自定义样式 | CSSProperties | - |
|
||||
| className | 自定义类名 | string | - |
|
||||
| rootClassName | 添加在组件最外层的 className | string | - |
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| style | 自定义样式 | CSSProperties | - |
|
||||
| className | 自定义类名 | string | - |
|
||||
| rootClassName | 添加在组件最外层的 className | string | - |
|
||||
| autoFocus | 自动获取焦点,仅对表单类、链接、交互容器等可聚焦元素生效 | boolean | false |
|
||||
|
||||
37
package.json
37
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",
|
||||
|
||||
@@ -22,6 +22,7 @@ const excludes = [
|
||||
'renovate[bot]',
|
||||
'dependabot',
|
||||
'dependabot[bot]',
|
||||
'gemini-code-assist[bot]',
|
||||
];
|
||||
|
||||
async function execute() {
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user