mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-18 06:03:38 +08:00
commit
9bcd45fac2
@ -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
|
||||
|
||||
`2022-02-21`
|
||||
|
@ -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
|
||||
|
||||
`2022-02-21`
|
||||
|
@ -17,7 +17,7 @@ class AffixMounter extends React.Component<{
|
||||
}> {
|
||||
private container: HTMLDivElement;
|
||||
|
||||
public affix: Affix;
|
||||
public affix: React.Component<AffixProps, AffixState>;
|
||||
|
||||
componentDidMount() {
|
||||
this.container.addEventListener = jest
|
||||
@ -58,7 +58,7 @@ describe('Affix Render', () => {
|
||||
|
||||
const domMock = jest.spyOn(HTMLElement.prototype, 'getBoundingClientRect');
|
||||
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> = {
|
||||
container: {
|
||||
@ -157,9 +157,9 @@ describe('Affix Render', () => {
|
||||
const getTarget = () => container;
|
||||
affixWrapper = mount(<Affix target={getTarget}>{null}</Affix>);
|
||||
affixWrapper.setProps({ target: () => null });
|
||||
expect(affixWrapper.instance().state.status).toBe(0);
|
||||
expect(affixWrapper.instance().state.affixStyle).toBe(undefined);
|
||||
expect(affixWrapper.instance().state.placeholderStyle).toBe(undefined);
|
||||
expect(affixWrapper.find('Affix').last().state().status).toBe(0);
|
||||
expect(affixWrapper.find('Affix').last().state().affixStyle).toBe(undefined);
|
||||
expect(affixWrapper.find('Affix').last().state().placeholderStyle).toBe(undefined);
|
||||
});
|
||||
|
||||
it('instance change', async () => {
|
||||
|
@ -126,7 +126,7 @@ class Affix extends React.Component<AffixProps, AffixState> {
|
||||
|
||||
getOffsetTop = () => {
|
||||
const { offsetBottom, offsetTop } = this.props;
|
||||
return (offsetBottom === undefined && offsetTop === undefined) ? 0 : offsetTop;
|
||||
return offsetBottom === undefined && offsetTop === undefined ? 0 : offsetTop;
|
||||
};
|
||||
|
||||
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;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import Affix from '.';
|
||||
|
||||
export type BindElement = HTMLElement | Window | null | undefined;
|
||||
|
||||
@ -41,7 +40,7 @@ const TRIGGER_EVENTS = [
|
||||
|
||||
interface ObserverEntity {
|
||||
target: HTMLElement | Window;
|
||||
affixList: Affix[];
|
||||
affixList: any[];
|
||||
eventHandlers: { [eventName: string]: any };
|
||||
}
|
||||
|
||||
@ -52,7 +51,7 @@ export function getObserverEntities() {
|
||||
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;
|
||||
|
||||
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 hasAffix = oriObserverEntity.affixList.some(item => item === affix);
|
||||
if (hasAffix) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
|
||||
export interface DividerProps {
|
||||
prefixCls?: string;
|
||||
@ -14,56 +14,54 @@ export interface DividerProps {
|
||||
plain?: boolean;
|
||||
}
|
||||
|
||||
const Divider: React.FC<DividerProps> = props => (
|
||||
<ConfigConsumer>
|
||||
{({ 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 Divider: React.FC<DividerProps> = props => {
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
|
||||
const innerStyle = {
|
||||
...(hasCustomMarginLeft && { marginLeft: orientationMargin }),
|
||||
...(hasCustomMarginRight && { marginRight: orientationMargin }),
|
||||
};
|
||||
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,
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classString} {...restProps} role="separator">
|
||||
{children && (
|
||||
<span className={`${prefixCls}-inner-text`} style={innerStyle}>
|
||||
{children}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</ConfigConsumer>
|
||||
);
|
||||
const innerStyle = {
|
||||
...(hasCustomMarginLeft && { marginLeft: orientationMargin }),
|
||||
...(hasCustomMarginRight && { marginRight: orientationMargin }),
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classString} {...restProps} role="separator">
|
||||
{children && (
|
||||
<span className={`${prefixCls}-inner-text`} style={innerStyle}>
|
||||
{children}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Divider;
|
||||
|
@ -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 | |
|
||||
| isFieldTouched | Check if a field has been operated | (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 | |
|
||||
| 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 | |
|
||||
|
@ -241,7 +241,7 @@ Form.List 渲染表单相关操作函数。
|
||||
| isFieldsTouched | 检查一组字段是否被用户操作过,`allTouched` 为 `true` 时检查是否所有字段都被操作过 | (nameList?: [NamePath](#NamePath)\[], allTouched?: boolean) => boolean | |
|
||||
| isFieldTouched | 检查对应字段是否被用户操作过 | (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 | |
|
||||
| setFields | 设置一组字段状态 | (fields: [FieldData](#FieldData)\[]) => void | |
|
||||
| setFieldsValue | 设置表单的值(该值将直接传入 form store 中。如果你不希望传入对象被修改,请克隆后传入) | (values) => void | |
|
||||
|
@ -30,14 +30,14 @@
|
||||
border-color: @hoverBorderColor;
|
||||
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;
|
||||
}
|
||||
|
||||
// == when hover
|
||||
.hover(@color: @input-hover-border-color) {
|
||||
border-color: @color;
|
||||
border-right-width: @border-width-base !important;
|
||||
border-right-width: @border-width-base;
|
||||
}
|
||||
|
||||
.disabled() {
|
||||
|
@ -77,7 +77,7 @@ Please find below some of the design resources and tools about Ant Design that w
|
||||
- MasterGo
|
||||
- https://mastergo-local-default.oss-cn-beijing.aliyuncs.com/ant-design-mastergo.svg
|
||||
- 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
|
||||
|
||||
|
@ -69,7 +69,7 @@ toc: false
|
||||
- MasterGo 组件包
|
||||
- https://mastergo-local-default.oss-cn-beijing.aliyuncs.com/ant-design-mastergo.svg
|
||||
- 可在「MasterGo」在线免费使用的全套组件和模板
|
||||
- https://mastergo.com/community/resource/31
|
||||
- https://mastergo.com/community/?utm_source=antdesign&utm_medium=link&utm_campaign=resource&cata_name=AntDesign
|
||||
|
||||
## 文章
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "4.18.8",
|
||||
"version": "4.18.9",
|
||||
"description": "An enterprise-class UI design language and React components implementation",
|
||||
"title": "Ant Design",
|
||||
"keywords": [
|
||||
@ -284,7 +284,7 @@
|
||||
"stylelint-declaration-block-no-ignored-properties": "^2.1.0",
|
||||
"stylelint-order": "^5.0.0",
|
||||
"theme-switcher": "^1.0.2",
|
||||
"typescript": "~4.5.2",
|
||||
"typescript": "~4.6.2",
|
||||
"webpack-bundle-analyzer": "^4.1.0",
|
||||
"xhr-mock": "^2.4.1",
|
||||
"yaml-front-matter": "^4.0.0"
|
||||
|
@ -35,6 +35,7 @@ const MAINTAINERS = [
|
||||
'Rustin-Liu',
|
||||
'fireairforce',
|
||||
'kerm1it',
|
||||
'MadCcc',
|
||||
].map(author => author.toLowerCase());
|
||||
|
||||
const cwd = process.cwd();
|
||||
|
Loading…
Reference in New Issue
Block a user