chore: auto merge branchs (#34266)

chore: sync master into feature
This commit is contained in:
github-actions[bot] 2022-03-03 02:23:48 +00:00 committed by GitHub
commit 9bcd45fac2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 92 additions and 69 deletions

View File

@ -15,6 +15,15 @@ timeline: true
--- ---
## 4.18.9
`2022-02-28`
- 🆕 New theme less variable for Radio, Divider, Modal, Dropdown, Drawer. [#34194](https://github.com/ant-design/ant-design/pull/34194) [#34187](https://github.com/ant-design/ant-design/pull/34187) [#34191](https://github.com/ant-design/ant-design/pull/34191) [#34189](https://github.com/ant-design/ant-design/pull/34189) [#34188](https://github.com/ant-design/ant-design/pull/34188) [@qdzhaoxiaodao](https://github.com/qdzhaoxiaodao)
- 💄 Fix Dropdown item wrap style when text is too long. [#34177](https://github.com/ant-design/ant-design/pull/34177)
- TypeScript
- 🐞 Fix Upload `onChange` parameter generic passing. [#34161](https://github.com/ant-design/ant-design/pull/34161) [@wangcch](https://github.com/wangcch)
## 4.18.8 ## 4.18.8
`2022-02-21` `2022-02-21`

View File

@ -15,6 +15,16 @@ timeline: true
--- ---
## 4.18.9
`2022-02-28`
- 🆕 新增 Radio、Divider、Modal、Dropdown、Drawer 主题变量。[#34194](https://github.com/ant-design/ant-design/pull/34194) [#34187](https://github.com/ant-design/ant-design/pull/34187) [#34191](https://github.com/ant-design/ant-design/pull/34191) [#34189](https://github.com/ant-design/ant-design/pull/34189) [#34188](https://github.com/ant-design/ant-design/pull/34188) [@qdzhaoxiaodao](https://github.com/qdzhaoxiaodao)
- 🐞 修复 Form 组件当 `preserve``false``initialValues` 会被更改的问题。[#34153](https://github.com/ant-design/ant-design/pull/34153)
- 💄 修复 Dropdown 菜单项文本太长没有换行的问题。[#34177](https://github.com/ant-design/ant-design/pull/3417)
- TypeScript
- 🐞 修复 Upload `onChange` 参数泛型传递。[#34161](https://github.com/ant-design/ant-design/pull/34161) [@wangcch](https://github.com/wangcch)
## 4.18.8 ## 4.18.8
`2022-02-21` `2022-02-21`

View File

@ -17,7 +17,7 @@ class AffixMounter extends React.Component<{
}> { }> {
private container: HTMLDivElement; private container: HTMLDivElement;
public affix: Affix; public affix: React.Component<AffixProps, AffixState>;
componentDidMount() { componentDidMount() {
this.container.addEventListener = jest this.container.addEventListener = jest
@ -58,7 +58,7 @@ describe('Affix Render', () => {
const domMock = jest.spyOn(HTMLElement.prototype, 'getBoundingClientRect'); const domMock = jest.spyOn(HTMLElement.prototype, 'getBoundingClientRect');
let affixMounterWrapper: ReactWrapper<unknown, unknown, AffixMounter>; let affixMounterWrapper: ReactWrapper<unknown, unknown, AffixMounter>;
let affixWrapper: ReactWrapper<AffixProps, AffixState, Affix>; let affixWrapper: ReactWrapper<AffixProps, AffixState, React.Component<AffixProps, AffixState>>;
const classRect: Record<string, DOMRect> = { const classRect: Record<string, DOMRect> = {
container: { container: {
@ -157,9 +157,9 @@ describe('Affix Render', () => {
const getTarget = () => container; const getTarget = () => container;
affixWrapper = mount(<Affix target={getTarget}>{null}</Affix>); affixWrapper = mount(<Affix target={getTarget}>{null}</Affix>);
affixWrapper.setProps({ target: () => null }); affixWrapper.setProps({ target: () => null });
expect(affixWrapper.instance().state.status).toBe(0); expect(affixWrapper.find('Affix').last().state().status).toBe(0);
expect(affixWrapper.instance().state.affixStyle).toBe(undefined); expect(affixWrapper.find('Affix').last().state().affixStyle).toBe(undefined);
expect(affixWrapper.instance().state.placeholderStyle).toBe(undefined); expect(affixWrapper.find('Affix').last().state().placeholderStyle).toBe(undefined);
}); });
it('instance change', async () => { it('instance change', async () => {

View File

@ -126,7 +126,7 @@ class Affix extends React.Component<AffixProps, AffixState> {
getOffsetTop = () => { getOffsetTop = () => {
const { offsetBottom, offsetTop } = this.props; const { offsetBottom, offsetTop } = this.props;
return (offsetBottom === undefined && offsetTop === undefined) ? 0 : offsetTop; return offsetBottom === undefined && offsetTop === undefined ? 0 : offsetTop;
}; };
getOffsetBottom = () => this.props.offsetBottom; getOffsetBottom = () => this.props.offsetBottom;
@ -286,4 +286,10 @@ class Affix extends React.Component<AffixProps, AffixState> {
} }
} }
export default Affix; const AffixFC = React.forwardRef<Affix, AffixProps>((props, ref) => <Affix {...props} ref={ref} />);
if (process.env.NODE_ENV !== 'production') {
AffixFC.displayName = 'Affix';
}
export default AffixFC;

View File

@ -1,5 +1,4 @@
import addEventListener from 'rc-util/lib/Dom/addEventListener'; import addEventListener from 'rc-util/lib/Dom/addEventListener';
import Affix from '.';
export type BindElement = HTMLElement | Window | null | undefined; export type BindElement = HTMLElement | Window | null | undefined;
@ -41,7 +40,7 @@ const TRIGGER_EVENTS = [
interface ObserverEntity { interface ObserverEntity {
target: HTMLElement | Window; target: HTMLElement | Window;
affixList: Affix[]; affixList: any[];
eventHandlers: { [eventName: string]: any }; eventHandlers: { [eventName: string]: any };
} }
@ -52,7 +51,7 @@ export function getObserverEntities() {
return observerEntities; return observerEntities;
} }
export function addObserveTarget(target: HTMLElement | Window | null, affix: Affix): void { export function addObserveTarget<T>(target: HTMLElement | Window | null, affix: T): void {
if (!target) return; if (!target) return;
let entity: ObserverEntity | undefined = observerEntities.find(item => item.target === target); let entity: ObserverEntity | undefined = observerEntities.find(item => item.target === target);
@ -78,7 +77,7 @@ export function addObserveTarget(target: HTMLElement | Window | null, affix: Aff
} }
} }
export function removeObserveTarget(affix: Affix): void { export function removeObserveTarget<T>(affix: T): void {
const observerEntity = observerEntities.find(oriObserverEntity => { const observerEntity = observerEntities.find(oriObserverEntity => {
const hasAffix = oriObserverEntity.affixList.some(item => item === affix); const hasAffix = oriObserverEntity.affixList.some(item => item === affix);
if (hasAffix) { if (hasAffix) {

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigContext } from '../config-provider';
export interface DividerProps { export interface DividerProps {
prefixCls?: string; prefixCls?: string;
@ -14,56 +14,54 @@ export interface DividerProps {
plain?: boolean; plain?: boolean;
} }
const Divider: React.FC<DividerProps> = props => ( const Divider: React.FC<DividerProps> = props => {
<ConfigConsumer> const { getPrefixCls, direction } = React.useContext(ConfigContext);
{({ getPrefixCls, direction }: ConfigConsumerProps) => {
const {
prefixCls: customizePrefixCls,
type = 'horizontal',
orientation = 'center',
orientationMargin,
className,
children,
dashed,
plain,
...restProps
} = props;
const prefixCls = getPrefixCls('divider', customizePrefixCls);
const orientationPrefix = orientation.length > 0 ? `-${orientation}` : orientation;
const hasChildren = !!children;
const hasCustomMarginLeft = orientation === 'left' && orientationMargin != null;
const hasCustomMarginRight = orientation === 'right' && orientationMargin != null;
const classString = classNames(
prefixCls,
`${prefixCls}-${type}`,
{
[`${prefixCls}-with-text`]: hasChildren,
[`${prefixCls}-with-text${orientationPrefix}`]: hasChildren,
[`${prefixCls}-dashed`]: !!dashed,
[`${prefixCls}-plain`]: !!plain,
[`${prefixCls}-rtl`]: direction === 'rtl',
[`${prefixCls}-no-default-orientation-margin-left`]: hasCustomMarginLeft,
[`${prefixCls}-no-default-orientation-margin-right`]: hasCustomMarginRight,
},
className,
);
const innerStyle = { const {
...(hasCustomMarginLeft && { marginLeft: orientationMargin }), prefixCls: customizePrefixCls,
...(hasCustomMarginRight && { marginRight: orientationMargin }), type = 'horizontal',
}; orientation = 'center',
orientationMargin,
className,
children,
dashed,
plain,
...restProps
} = props;
const prefixCls = getPrefixCls('divider', customizePrefixCls);
const orientationPrefix = orientation.length > 0 ? `-${orientation}` : orientation;
const hasChildren = !!children;
const hasCustomMarginLeft = orientation === 'left' && orientationMargin != null;
const hasCustomMarginRight = orientation === 'right' && orientationMargin != null;
const classString = classNames(
prefixCls,
`${prefixCls}-${type}`,
{
[`${prefixCls}-with-text`]: hasChildren,
[`${prefixCls}-with-text${orientationPrefix}`]: hasChildren,
[`${prefixCls}-dashed`]: !!dashed,
[`${prefixCls}-plain`]: !!plain,
[`${prefixCls}-rtl`]: direction === 'rtl',
[`${prefixCls}-no-default-orientation-margin-left`]: hasCustomMarginLeft,
[`${prefixCls}-no-default-orientation-margin-right`]: hasCustomMarginRight,
},
className,
);
return ( const innerStyle = {
<div className={classString} {...restProps} role="separator"> ...(hasCustomMarginLeft && { marginLeft: orientationMargin }),
{children && ( ...(hasCustomMarginRight && { marginRight: orientationMargin }),
<span className={`${prefixCls}-inner-text`} style={innerStyle}> };
{children}
</span> return (
)} <div className={classString} {...restProps} role="separator">
</div> {children && (
); <span className={`${prefixCls}-inner-text`} style={innerStyle}>
}} {children}
</ConfigConsumer> </span>
); )}
</div>
);
};
export default Divider; export default Divider;

View File

@ -242,7 +242,7 @@ Provide linkage between forms. If a sub form with `name` prop update, it will au
| isFieldsTouched | Check if fields have been operated. Check if all fields is touched when `allTouched` is `true` | (nameList?: [NamePath](#NamePath)\[], allTouched?: boolean) => boolean | | | isFieldsTouched | Check if fields have been operated. Check if all fields is touched when `allTouched` is `true` | (nameList?: [NamePath](#NamePath)\[], allTouched?: boolean) => boolean | |
| isFieldTouched | Check if a field has been operated | (name: [NamePath](#NamePath)) => boolean | | | isFieldTouched | Check if a field has been operated | (name: [NamePath](#NamePath)) => boolean | |
| isFieldValidating | Check field if is in validating | (name: [NamePath](#NamePath)) => boolean | | | isFieldValidating | Check field if is in validating | (name: [NamePath](#NamePath)) => boolean | |
| resetFields | Reset fields to `initialValues` | (fields?: [FieldData](#FieldData)\[]) => void | | | resetFields | Reset fields to `initialValues` | (fields?: [NamePath](#NamePath)\[]) => void | |
| scrollToField | Scroll to field position | (name: [NamePath](#NamePath), options: \[[ScrollOptions](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options)]) => void | | | scrollToField | Scroll to field position | (name: [NamePath](#NamePath), options: \[[ScrollOptions](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options)]) => void | |
| setFields | Set fields status | (fields: [FieldData](#FieldData)\[]) => void | | | setFields | Set fields status | (fields: [FieldData](#FieldData)\[]) => void | |
| setFieldsValue | Set fields value(Will directly pass to form store. If you do not want to modify passed object, please clone first) | (values) => void | | | setFieldsValue | Set fields value(Will directly pass to form store. If you do not want to modify passed object, please clone first) | (values) => void | |

View File

@ -241,7 +241,7 @@ Form.List 渲染表单相关操作函数。
| isFieldsTouched | 检查一组字段是否被用户操作过,`allTouched` 为 `true` 时检查是否所有字段都被操作过 | (nameList?: [NamePath](#NamePath)\[], allTouched?: boolean) => boolean | | | isFieldsTouched | 检查一组字段是否被用户操作过,`allTouched` 为 `true` 时检查是否所有字段都被操作过 | (nameList?: [NamePath](#NamePath)\[], allTouched?: boolean) => boolean | |
| isFieldTouched | 检查对应字段是否被用户操作过 | (name: [NamePath](#NamePath)) => boolean | | | isFieldTouched | 检查对应字段是否被用户操作过 | (name: [NamePath](#NamePath)) => boolean | |
| isFieldValidating | 检查对应字段是否正在校验 | (name: [NamePath](#NamePath)) => boolean | | | isFieldValidating | 检查对应字段是否正在校验 | (name: [NamePath](#NamePath)) => boolean | |
| resetFields | 重置一组字段到 `initialValues` | (fields?: [FieldData](#FieldData)\[]) => void | | | resetFields | 重置一组字段到 `initialValues` | (fields?: [NamePath](#NamePath)\[]) => void | |
| scrollToField | 滚动到对应字段位置 | (name: [NamePath](#NamePath), options: [ScrollOptions](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options)) => void | | | scrollToField | 滚动到对应字段位置 | (name: [NamePath](#NamePath), options: [ScrollOptions](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options)) => void | |
| setFields | 设置一组字段状态 | (fields: [FieldData](#FieldData)\[]) => void | | | setFields | 设置一组字段状态 | (fields: [FieldData](#FieldData)\[]) => void | |
| setFieldsValue | 设置表单的值(该值将直接传入 form store 中。如果你不希望传入对象被修改,请克隆后传入) | (values) => void | | | setFieldsValue | 设置表单的值(该值将直接传入 form store 中。如果你不希望传入对象被修改,请克隆后传入) | (values) => void | |

View File

@ -30,14 +30,14 @@
border-color: @hoverBorderColor; border-color: @hoverBorderColor;
box-shadow: @input-outline-offset @outline-blur-size @outline-width @outlineColor; box-shadow: @input-outline-offset @outline-blur-size @outline-width @outlineColor;
} }
border-right-width: @border-width-base !important; border-right-width: @border-width-base;
outline: 0; outline: 0;
} }
// == when hover // == when hover
.hover(@color: @input-hover-border-color) { .hover(@color: @input-hover-border-color) {
border-color: @color; border-color: @color;
border-right-width: @border-width-base !important; border-right-width: @border-width-base;
} }
.disabled() { .disabled() {

View File

@ -77,7 +77,7 @@ Please find below some of the design resources and tools about Ant Design that w
- MasterGo - MasterGo
- https://mastergo-local-default.oss-cn-beijing.aliyuncs.com/ant-design-mastergo.svg - https://mastergo-local-default.oss-cn-beijing.aliyuncs.com/ant-design-mastergo.svg
- Use fully components and templates on MasterGo - Use fully components and templates on MasterGo
- https://mastergo.com/community/resource/31 - https://mastergo.com/community/?utm_source=antdesign&utm_medium=link&utm_campaign=resource&cata_name=AntDesign
## Articles ## Articles

View File

@ -69,7 +69,7 @@ toc: false
- MasterGo 组件包 - MasterGo 组件包
- https://mastergo-local-default.oss-cn-beijing.aliyuncs.com/ant-design-mastergo.svg - https://mastergo-local-default.oss-cn-beijing.aliyuncs.com/ant-design-mastergo.svg
- 可在「MasterGo」在线免费使用的全套组件和模板 - 可在「MasterGo」在线免费使用的全套组件和模板
- https://mastergo.com/community/resource/31 - https://mastergo.com/community/?utm_source=antdesign&utm_medium=link&utm_campaign=resource&cata_name=AntDesign
## 文章 ## 文章

View File

@ -1,6 +1,6 @@
{ {
"name": "antd", "name": "antd",
"version": "4.18.8", "version": "4.18.9",
"description": "An enterprise-class UI design language and React components implementation", "description": "An enterprise-class UI design language and React components implementation",
"title": "Ant Design", "title": "Ant Design",
"keywords": [ "keywords": [
@ -284,7 +284,7 @@
"stylelint-declaration-block-no-ignored-properties": "^2.1.0", "stylelint-declaration-block-no-ignored-properties": "^2.1.0",
"stylelint-order": "^5.0.0", "stylelint-order": "^5.0.0",
"theme-switcher": "^1.0.2", "theme-switcher": "^1.0.2",
"typescript": "~4.5.2", "typescript": "~4.6.2",
"webpack-bundle-analyzer": "^4.1.0", "webpack-bundle-analyzer": "^4.1.0",
"xhr-mock": "^2.4.1", "xhr-mock": "^2.4.1",
"yaml-front-matter": "^4.0.0" "yaml-front-matter": "^4.0.0"

View File

@ -35,6 +35,7 @@ const MAINTAINERS = [
'Rustin-Liu', 'Rustin-Liu',
'fireairforce', 'fireairforce',
'kerm1it', 'kerm1it',
'MadCcc',
].map(author => author.toLowerCase()); ].map(author => author.toLowerCase());
const cwd = process.cwd(); const cwd = process.cwd();