Browse Source
chore: auto merge branches (#43420 )
chore: merge master into feature
pull/43418/head
github-actions[bot]
1 year ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with
159 additions and
30 deletions
.dumi/theme/builtins/ComponentTokenTable/index.tsx
.dumi/theme/common/Link.tsx
components/collapse/Collapse.tsx
components/config-provider/__tests__/form.test.tsx
components/config-provider/context.ts
components/config-provider/index.tsx
components/descriptions/index.en-US.md
components/descriptions/index.zh-CN.md
components/descriptions/style/index.ts
components/dropdown/index.en-US.md
components/dropdown/index.zh-CN.md
components/form/index.en-US.md
components/form/index.zh-CN.md
components/table/index.en-US.md
components/table/index.zh-CN.md
components/tag/style/index.ts
docs/react/customize-theme.en-US.md
docs/react/customize-theme.zh-CN.md
docs/react/demo/motion.md
docs/react/demo/motion.tsx
package.json
@ -150,11 +150,13 @@ const ComponentTokenTable: React.FC<ComponentTokenTableProps> = ({ component })
return (
< >
< SubTokenTable
title = { locale . componentToken }
tokens = { tokenMeta . components [ component ] . map ( ( item ) = > item . token ) }
component = { component }
/ >
{ tokenMeta . components [ component ] && (
< SubTokenTable
title = { locale . componentToken }
tokens = { tokenMeta . components [ component ] . map ( ( item ) = > item . token ) }
component = { component }
/ >
) }
< SubTokenTable title = { locale . globalToken } tokens = { mergedGlobalTokens } / >
< / >
) ;
@ -14,10 +14,13 @@ const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
const handleClick = ( e : MouseEvent < HTMLAnchorElement > ) = > {
if ( ! to . startsWith ( 'http' ) ) {
e . preventDefault ( ) ;
startTransition ( ( ) = > {
navigate ( to ) ;
} ) ;
// Should support open in new tab
if ( ! e . metaKey && ! e . ctrlKey && ! e . shiftKey ) {
e . preventDefault ( ) ;
startTransition ( ( ) = > {
navigate ( to ) ;
} ) ;
}
}
} ;
@ -102,7 +102,10 @@ const Collapse = React.forwardRef<HTMLDivElement, CollapseProps>((props, ref) =>
) as React . ReactNode ;
return cloneElement ( icon , ( ) = > ( {
className : classNames ( ( icon as any ) . props . className , ` ${ prefixCls } -arrow ` ) ,
className : classNames (
( icon as React . ReactElement < any > ) . props . className ,
` ${ prefixCls } -arrow ` ,
) ,
} ) ) ;
} ;
@ -148,6 +148,42 @@ describe('ConfigProvider.Form', () => {
'age must be between 18-99' ,
) ;
} ) ;
// https://github.com/ant-design/ant-design/issues/43210
it ( 'should merge parent ConfigProvider validateMessages' , async ( ) = > {
const MyForm = ( ) = > (
< Form >
< Form.Item name = "name" label = "Name" rules = { [ { required : true } ] } >
< Input / >
< / Form.Item >
< Button type = "primary" htmlType = "submit" >
Submit
< / Button >
< / Form >
) ;
const { container , getAllByRole , getAllByText } = render (
< ConfigProvider >
< MyForm / >
< ConfigProvider form = { { validateMessages : { required : 'Required' } } } >
< MyForm / >
< ConfigProvider >
< MyForm / >
< / ConfigProvider >
< / ConfigProvider >
< / ConfigProvider > ,
) ;
const submitButtons = getAllByRole ( 'button' ) ;
expect ( submitButtons ) . toHaveLength ( 3 ) ;
submitButtons . forEach ( fireEvent . click ) ;
await waitFakeTimer ( ) ;
expect ( container . querySelectorAll ( '.ant-form-item-explain-error' ) ) . toHaveLength ( 3 ) ;
expect ( getAllByText ( 'Please enter Name' ) ) . toHaveLength ( 1 ) ;
expect ( getAllByText ( 'Required' ) ) . toHaveLength ( 2 ) ;
} ) ;
} ) ;
describe ( 'form requiredMark' , ( ) = > {
@ -1,4 +1,5 @@
import type { DerivativeFunc } from '@ant-design/cssinjs' ;
import type { ValidateMessages } from 'rc-field-form/lib/interface' ;
import * as React from 'react' ;
import type { Options } from 'scroll-into-view-if-needed' ;
import type { BadgeProps } from '../badge' ;
@ -89,6 +90,7 @@ export interface ConfigConsumerProps {
requiredMark? : RequiredMark ;
colon? : boolean ;
scrollToFirstError? : Options | boolean ;
validateMessages? : ValidateMessages ;
} ;
theme? : ThemeConfig ;
select? : ComponentStyleConfig & {
@ -456,6 +456,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {
merge (
defaultLocale . Form ? . defaultValidateMessages || { } ,
memoedConfig . locale ? . Form ? . defaultValidateMessages || { } ,
memoedConfig . form ? . validateMessages || { } ,
form ? . validateMessages || { } ,
) ,
[ memoedConfig , form ? . validateMessages ] ,
@ -33,7 +33,7 @@ Commonly displayed on the details page.
| --- | --- | --- | --- | --- |
| bordered | Whether to display the border | boolean | false | |
| colon | Change default props `colon` value of Descriptions.Item | boolean | true | |
| column | The number of `DescriptionItems` in a row,could be a number or a object like `{ xs: 8, sm: 16, md: 24}` ,(Only set `bordered={true}` to take effect) | number | 3 | |
| column | The number of `DescriptionItems` in a row,could be a number or a object like `{ xs: 8, sm: 16, md: 24}` ,(Only set `bordered={true}` to take effect) | number \| [Record<Breakpoint, number> ](https://github.com/ant-design/ant-design/blob/84ca0d23ae52e4f0940f20b0e22eabe743f90dca/components/descriptions/index.tsx#L111C21-L111C56 ) | 3 | |
| contentStyle | Customize content style | CSSProperties | - | 4.10.0 |
| extra | The action area of the description list, placed at the top-right | ReactNode | - | 4.5.0 |
| labelStyle | Customize label style | CSSProperties | - | 4.10.0 |
@ -34,7 +34,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*d27AQJrowGAAAA
| --- | --- | --- | --- | --- |
| bordered | 是否展示边框 | boolean | false | |
| colon | 配置 `Descriptions.Item` 的 `colon` 的默认值 | boolean | true | |
| column | 一行的 `DescriptionItems` 数量,可以写成像素值或支持响应式的对象写法 `{ xs: 8, sm: 16, md: 24}` | number | 3 | |
| column | 一行的 `DescriptionItems` 数量,可以写成像素值或支持响应式的对象写法 `{ xs: 8, sm: 16, md: 24}` | number \| [Record<Breakpoint, number> ](https://github.com/ant-design/ant-design/blob/84ca0d23ae52e4f0940f20b0e22eabe743f90dca/components/descriptions/index.tsx#L111C21-L111C56 ) | 3 | |
| contentStyle | 自定义内容样式 | CSSProperties | - | 4.10.0 |
| extra | 描述列表的操作区域,显示在右上方 | ReactNode | - | 4.5.0 |
| labelStyle | 自定义标签样式 | CSSProperties | - | 4.10.0 |
@ -22,12 +22,12 @@ export interface ComponentToken {
* /
itemPaddingBottom : number ;
/ * *
* @desc 分 号 右 间 距
* @desc 冒 号 右 间 距
* @descEN Right margin of colon
* /
colonMarginRight : number ;
/ * *
* @desc 分 号 左 间 距
* @desc 冒 号 左 间 距
* @descEN Left margin of colon
* /
colonMarginLeft : number ;
@ -77,3 +77,9 @@ Please ensure that the child node of `Dropdown` accepts `onMouseEnter`, `onMouse
## Design Token
< ComponentTokenTable component = "Dropdown" > < / ComponentTokenTable >
## FAQ
### How to prevent Dropdown from being squeezed when it exceeds the screen horizontally?
You can use `width: max-content` style to handle this. ref [#43025 ](https://github.com/ant-design/ant-design/issues/43025#issuecomment-1594394135 ).
@ -81,3 +81,9 @@ demo:
## Design Token
< ComponentTokenTable component = "Dropdown" > < / ComponentTokenTable >
## FAQ
### Dropdown 在水平方向超出屏幕时会被挤压改怎么办?
你可以通过 `width: max-content` 来解决这个问题,参考 [#43025 ](https://github.com/ant-design/ant-design/issues/43025#issuecomment-1594394135 )。
@ -545,6 +545,10 @@ In most case, we always recommend to use Form `initialValues`. Use Item `initial
1. Form `initialValues` is the first priority
2. Field `initialValue` is secondary \*. Does not work when multiple Item with same `name` setting the `initialValue`
### Why can't `getFieldsValue` get value at first render?
`getFieldsValue` returns collected field data by default, but the Form.Item node is not ready at the first render. You can get all field data by `getFieldsValue(true)` .
### Why does `onFieldsChange` trigger three times on change when field sets `rules` ?
Validating is also part of the value updating. It pass follow steps:
@ -544,6 +544,10 @@ validator(rule, value, callback) => {
1. Form 的 `initialValues` 拥有最高优先级
2. Field 的 `initialValue` 次之 \*. 多个同 `name` Item 都设置 `initialValue` 时,则 Item 的 `initialValue` 不生效
### 为什么 `getFieldsValue` 在初次渲染的时候拿不到值?
`getFieldsValue` 默认返回收集的字段数据,而在初次渲染时 Form.Item 节点尚未渲染,因而无法收集到数据。你可以通过 `getFieldsValue(true)` 来获取所有字段数据。
### 为什么字段设置 `rules` 后更改值 `onFieldsChange` 会触发三次?
字段除了本身的值变化外,校验也是其状态之一。因而在触发字段变化会经历以下几个阶段:
@ -192,7 +192,7 @@ One of the Table `columns` prop for describing the table's columns, Column has t
| shouldCellUpdate | Control cell render logic | (record, prevRecord) => boolean | - | 4.3.0 |
| showSorterTooltip | If header show next sorter direction tooltip, override `showSorterTooltip` in table | boolean \| [Tooltip props ](/components/tooltip/ ) | true | |
| sortDirections | Supported sort way, override `sortDirections` in `Table` , could be `ascend` , `descend` | Array | \[`ascend` , `descend` ] | |
| sorter | Sort function for local sort, see [Array.sort ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort )'s compareFunction. If you need sort buttons only, set to `true` | function \| boolean \| { compare: function: multiple: number } | - | |
| sorter | Sort function for local sort, see [Array.sort ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort )'s compareFunction. If you need sort buttons only, set to `true` | function \| boolean \| { compare: function, multiple: number } | - | |
| sortOrder | Order of sorted values: `ascend` `descend` `null` | `ascend` \| `descend` \| null | - | |
| sortIcon | Customized sort icon | (props: { sortOrder }) => ReactNode | - | 5.6.0 |
| title | Title of this column | ReactNode \| ({ sortOrder, sortColumn, filters }) => ReactNode | - | |
@ -194,7 +194,7 @@ const columns = [
| shouldCellUpdate | 自定义单元格渲染时机 | (record, prevRecord) => boolean | - | 4.3.0 |
| showSorterTooltip | 表头显示下一次排序的 tooltip 提示, 覆盖 table 中 `showSorterTooltip` | boolean \| [Tooltip props ](/components/tooltip-cn/#api ) | true | |
| sortDirections | 支持的排序方式,覆盖 `Table` 中 `sortDirections` , 取值为 `ascend` `descend` | Array | \[`ascend` , `descend` ] | |
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort ) 的 compareFunction),需要服务端排序可设为 true | function \| boolean \| { compare: function: multiple: number } | - | |
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort ) 的 compareFunction),需要服务端排序可设为 true | function \| boolean \| { compare: function, multiple: number } | - | |
| sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `ascend` `descend` `null` | `ascend` \| `descend` \| null | - | |
| sortIcon | 自定义 sort 图标 | (props: { sortOrder }) => ReactNode | - | 5.6.0 |
| title | 列头显示文字(函数用法 `3.10.0` 后支持) | ReactNode \| ({ sortOrder, sortColumn, filters }) => ReactNode | - | |
@ -88,6 +88,7 @@ const genBaseStyle = (token: TagToken): CSSInterpolation => {
opacity : 1 ,
transition : ` all ${ token . motionDurationMid } ` ,
textAlign : 'start' ,
position : 'relative' ,
// RTL
[ ` & ${ componentCls } -rtl ` ] : {
@ -96,6 +96,13 @@ In this way, we changed the primary color of Radio to <ColorChunk color="#00b96b
> Notice: `ConfigProvider` will not take effect on static methods such as `message.xxx` , `Modal.xxx` , `notification.xxx` , because in these methods, antd will dynamically create new ones through `ReactDOM.render` React entities. Its context is not the same as the context of the current code, so context information cannot be obtained. When you need context information (such as the content configured by ConfigProvider), you can use the `Modal.useModal` method to return the modal entity and the contextHolder node. Just insert it where you need to get the context, or you can use [App Component ](/components/app ) to simplify the problem of usingModal and other methods that need to manually implant the contextHolder.
### Disable Motion
antd has built-in interaction animations to make enterprise-level pages more detailed. In some extreme scenarios, it may affect the performance of page interaction. If you need to turn off the animation, you can use the following method:
<!-- prettier - ignore -->
< code src = "./demo/motion.tsx" > Motion< / code >
## Other Ways to Use Dynamic Themes
### Switch Themes Dynamically
@ -560,12 +567,11 @@ export default class MyDocument extends Document {
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
(
< Style Provider cache = {cache} >
< App { . . . props } / >
< / StyleProvider >
),
enhanceApp: (App) => (props) => (
< Style Provider cache = {cache} >
< App { . . . props } / >
< / StyleProvider >
),
});
const initialProps = await Document.getInitialProps(ctx);
@ -96,6 +96,13 @@ export default App;
> 注意:`ConfigProvider` 对 `message.xxx` 、`Modal.xxx`、`notification.xxx` 等静态方法不会生效,原因是在这些方法中,antd 会通过 `ReactDOM.render` 动态创建新的 React 实体。其 context 与当前代码所在 context 并不相同,因而无法获取 context 信息。当你需要 context 信息(例如 ConfigProvider 配置的内容)时,可以通过 `Modal.useModal` 方法会返回 modal 实体以及 contextHolder 节点。将其插入到你需要获取 context 位置即可,也可通过 [App 包裹组件 ](/components/app-cn ) 简化 useModal 等方法需要手动植入 contextHolder 的问题。
### 禁用动画
antd 默认内置了一些组件交互动效让企业级页面更加富有细节,在一些极端场景可能会影响页面交互性能,如需关闭动画可以使用下面的方式:
<!-- prettier - ignore -->
< code src = "./demo/motion.tsx" > 动画控制< / code >
## 动态主题的其他使用方式
### 动态切换
@ -556,12 +563,11 @@ export default class MyDocument extends Document {
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
(
< Style Provider cache = {cache} >
< App { . . . props } / >
< / StyleProvider >
),
enhanceApp: (App) => (props) => (
< Style Provider cache = {cache} >
< App { . . . props } / >
< / StyleProvider >
),
});
const initialProps = await Document.getInitialProps(ctx);
@ -0,0 +1,7 @@
## zh-CN
通过 `token` 进行动画效果配置。
## en-US
Config animation effect by `token` .
@ -0,0 +1,42 @@
import React from 'react' ;
import { Switch , ConfigProvider , Space , Checkbox , Radio , Row , Col } from 'antd' ;
export default ( ) = > {
const [ checked , setChecked ] = React . useState ( false ) ;
React . useEffect ( ( ) = > {
const id = setInterval ( ( ) = > {
setChecked ( ( prev ) = > ! prev ) ;
} , 500 ) ;
return ( ) = > {
clearInterval ( id ) ;
} ;
} , [ ] ) ;
const nodes = (
< Space >
< Checkbox checked = { checked } > Checkbox < / Checkbox >
< Radio checked = { checked } > Radio < / Radio >
< Switch checked = { checked } / >
< / Space >
) ;
return (
< Row gutter = { [ 24 , 24 ] } >
< Col span = { 24 } > { nodes } < / Col >
< Col span = { 24 } >
< ConfigProvider
theme = { {
token : {
motion : false ,
} ,
} }
>
{ nodes }
< / ConfigProvider >
< / Col >
< / Row >
) ;
} ;
@ -258,7 +258,7 @@
"mockdate" : "^3.0.0" ,
"node-notifier" : "^10.0.1" ,
"open" : "^9.0.0" ,
"prettier" : "^2.3.2 " ,
"prettier" : "^3.0.0 " ,
"prettier-plugin-jsdoc" : "^0.4.2" ,
"pretty-format" : "^29.0.0" ,
"prismjs" : "^1.29.0" ,
@ -290,7 +290,7 @@
"size-limit" : "^8.1.0" ,
"stylelint" : "^15.1.0" ,
"stylelint-config-rational-order" : "^0.1.2" ,
"stylelint-config-standard" : "^33 .0.0" ,
"stylelint-config-standard" : "^34 .0.0" ,
"stylelint-prettier" : "^3.0.0" ,
"sylvanas" : "^0.6.1" ,
"terser" : "^5.16.1" ,