mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 17:44:35 +08:00
merge feature into master
This commit is contained in:
commit
7085e22a96
@ -5,10 +5,16 @@ import { LegacyButtonType, ButtonProps, convertLegacyProps } from '../button/but
|
|||||||
export interface ActionButtonProps {
|
export interface ActionButtonProps {
|
||||||
type?: LegacyButtonType;
|
type?: LegacyButtonType;
|
||||||
actionFn?: (...args: any[]) => any | PromiseLike<any>;
|
actionFn?: (...args: any[]) => any | PromiseLike<any>;
|
||||||
closeModal: Function;
|
close: Function;
|
||||||
autoFocus?: boolean;
|
autoFocus?: boolean;
|
||||||
prefixCls: string;
|
prefixCls: string;
|
||||||
buttonProps?: ButtonProps;
|
buttonProps?: ButtonProps;
|
||||||
|
emitEvent?: boolean;
|
||||||
|
quitOnNullishReturnValue?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isThenable(thing?: PromiseLike<any>): boolean {
|
||||||
|
return !!(thing && !!thing.then);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ActionButton: React.FC<ActionButtonProps> = props => {
|
const ActionButton: React.FC<ActionButtonProps> = props => {
|
||||||
@ -30,16 +36,16 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handlePromiseOnOk = (returnValueOfOnOk?: PromiseLike<any>) => {
|
const handlePromiseOnOk = (returnValueOfOnOk?: PromiseLike<any>) => {
|
||||||
const { closeModal } = props;
|
const { close } = props;
|
||||||
if (!returnValueOfOnOk || !returnValueOfOnOk.then) {
|
if (!isThenable(returnValueOfOnOk)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
returnValueOfOnOk.then(
|
returnValueOfOnOk!.then(
|
||||||
(...args: any[]) => {
|
(...args: any[]) => {
|
||||||
// It's unnecessary to set loading=false, for the Modal will be unmounted after close.
|
setLoading(false);
|
||||||
// setState({ loading: false });
|
close(...args);
|
||||||
closeModal(...args);
|
clickedRef.current = false;
|
||||||
},
|
},
|
||||||
(e: Error) => {
|
(e: Error) => {
|
||||||
// Emit error when catch promise reject
|
// Emit error when catch promise reject
|
||||||
@ -52,25 +58,32 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onClick = () => {
|
const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
const { actionFn, closeModal } = props;
|
const { actionFn, close } = props;
|
||||||
if (clickedRef.current) {
|
if (clickedRef.current) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clickedRef.current = true;
|
clickedRef.current = true;
|
||||||
if (!actionFn) {
|
if (!actionFn) {
|
||||||
closeModal();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let returnValueOfOnOk;
|
let returnValueOfOnOk;
|
||||||
if (actionFn.length) {
|
if (props.emitEvent) {
|
||||||
returnValueOfOnOk = actionFn(closeModal);
|
returnValueOfOnOk = actionFn(e);
|
||||||
|
if (props.quitOnNullishReturnValue && !isThenable(returnValueOfOnOk)) {
|
||||||
|
clickedRef.current = false;
|
||||||
|
close(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (actionFn.length) {
|
||||||
|
returnValueOfOnOk = actionFn(close);
|
||||||
// https://github.com/ant-design/ant-design/issues/23358
|
// https://github.com/ant-design/ant-design/issues/23358
|
||||||
clickedRef.current = false;
|
clickedRef.current = false;
|
||||||
} else {
|
} else {
|
||||||
returnValueOfOnOk = actionFn();
|
returnValueOfOnOk = actionFn();
|
||||||
if (!returnValueOfOnOk) {
|
if (!returnValueOfOnOk) {
|
||||||
closeModal();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,7 +3,10 @@ import { MotionEvent } from 'rc-motion/lib/interface';
|
|||||||
|
|
||||||
// ================== Collapse Motion ==================
|
// ================== Collapse Motion ==================
|
||||||
const getCollapsedHeight: MotionEventHandler = () => ({ height: 0, opacity: 0 });
|
const getCollapsedHeight: MotionEventHandler = () => ({ height: 0, opacity: 0 });
|
||||||
const getRealHeight: MotionEventHandler = node => ({ height: node.scrollHeight, opacity: 1 });
|
const getRealHeight: MotionEventHandler = node => {
|
||||||
|
const { scrollHeight } = node;
|
||||||
|
return { height: scrollHeight, opacity: 1 };
|
||||||
|
};
|
||||||
const getCurrentHeight: MotionEventHandler = node => ({ height: node ? node.offsetHeight : 0 });
|
const getCurrentHeight: MotionEventHandler = node => ({ height: node ? node.offsetHeight : 0 });
|
||||||
const skipOpacityTransition: MotionEndEventHandler = (_, event: MotionEvent) =>
|
const skipOpacityTransition: MotionEndEventHandler = (_, event: MotionEvent) =>
|
||||||
event?.deadline === true || (event as TransitionEvent).propertyName === 'height';
|
event?.deadline === true || (event as TransitionEvent).propertyName === 'height';
|
||||||
|
@ -193,4 +193,22 @@ describe('Avatar Render', () => {
|
|||||||
wrapper.detach();
|
wrapper.detach();
|
||||||
global.document.body.removeChild(div);
|
global.document.body.removeChild(div);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should exist crossorigin attribute', () => {
|
||||||
|
const LOAD_SUCCESS_SRC = 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png';
|
||||||
|
const wrapper = mount(
|
||||||
|
<Avatar src={LOAD_SUCCESS_SRC} crossOrigin="anonymous">
|
||||||
|
crossorigin
|
||||||
|
</Avatar>,
|
||||||
|
);
|
||||||
|
expect(wrapper.html().includes('crossorigin')).toEqual(true);
|
||||||
|
expect(wrapper.find('img').prop('crossOrigin')).toEqual('anonymous');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not exist crossorigin attribute', () => {
|
||||||
|
const LOAD_SUCCESS_SRC = 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png';
|
||||||
|
const wrapper = mount(<Avatar src={LOAD_SUCCESS_SRC}>crossorigin</Avatar>);
|
||||||
|
expect(wrapper.html().includes('crossorigin')).toEqual(false);
|
||||||
|
expect(wrapper.find('img').prop('crossOrigin')).toEqual(undefined);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -29,6 +29,7 @@ export interface AvatarProps {
|
|||||||
className?: string;
|
className?: string;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
alt?: string;
|
alt?: string;
|
||||||
|
crossOrigin?: '' | 'anonymous' | 'use-credentials';
|
||||||
/* callback when img load error */
|
/* callback when img load error */
|
||||||
/* return false to prevent Avatar show default fallback behavior, then you can do fallback by your self */
|
/* return false to prevent Avatar show default fallback behavior, then you can do fallback by your self */
|
||||||
onError?: () => boolean;
|
onError?: () => boolean;
|
||||||
@ -95,6 +96,7 @@ const InternalAvatar: React.ForwardRefRenderFunction<unknown, AvatarProps> = (pr
|
|||||||
alt,
|
alt,
|
||||||
draggable,
|
draggable,
|
||||||
children,
|
children,
|
||||||
|
crossOrigin,
|
||||||
...others
|
...others
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
@ -158,7 +160,14 @@ const InternalAvatar: React.ForwardRefRenderFunction<unknown, AvatarProps> = (pr
|
|||||||
let childrenToRender;
|
let childrenToRender;
|
||||||
if (typeof src === 'string' && isImgExist) {
|
if (typeof src === 'string' && isImgExist) {
|
||||||
childrenToRender = (
|
childrenToRender = (
|
||||||
<img src={src} draggable={draggable} srcSet={srcSet} onError={handleImgLoadError} alt={alt} />
|
<img
|
||||||
|
src={src}
|
||||||
|
draggable={draggable}
|
||||||
|
srcSet={srcSet}
|
||||||
|
onError={handleImgLoadError}
|
||||||
|
alt={alt}
|
||||||
|
crossOrigin={crossOrigin}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
} else if (hasImageElement) {
|
} else if (hasImageElement) {
|
||||||
childrenToRender = src;
|
childrenToRender = src;
|
||||||
|
@ -21,6 +21,7 @@ Avatars can be used to represent people or objects. It supports images, `Icon`s,
|
|||||||
| src | The address of the image for an image avatar or image element | string \| ReactNode | - | ReactNode: 4.8.0 |
|
| src | The address of the image for an image avatar or image element | string \| ReactNode | - | ReactNode: 4.8.0 |
|
||||||
| srcSet | A list of sources to use for different screen resolutions | string | - | |
|
| srcSet | A list of sources to use for different screen resolutions | string | - | |
|
||||||
| draggable | Whether the picture is allowed to be dragged | boolean \| `'true'` \| `'false'` | - | |
|
| draggable | Whether the picture is allowed to be dragged | boolean \| `'true'` \| `'false'` | - | |
|
||||||
|
| crossOrigin | CORS settings attributes | `'anonymous'` \| `'use-credentials'` \| `''` | - | 4.17.0 |
|
||||||
| onError | Handler when img load error, return false to prevent default fallback behavior | () => boolean | - | |
|
| onError | Handler when img load error, return false to prevent default fallback behavior | () => boolean | - | |
|
||||||
|
|
||||||
> Tip: You can set `icon` or `children` as the fallback for image load error, with the priority of `icon` > `children`
|
> Tip: You can set `icon` or `children` as the fallback for image load error, with the priority of `icon` > `children`
|
||||||
|
@ -26,6 +26,7 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/aBcnbw68hP/Avatar.svg
|
|||||||
| src | 图片类头像的资源地址或者图片元素 | string \| ReactNode | - | ReactNode: 4.8.0 |
|
| src | 图片类头像的资源地址或者图片元素 | string \| ReactNode | - | ReactNode: 4.8.0 |
|
||||||
| srcSet | 设置图片类头像响应式资源地址 | string | - | |
|
| srcSet | 设置图片类头像响应式资源地址 | string | - | |
|
||||||
| draggable | 图片是否允许拖动 | boolean \| `'true'` \| `'false'` | - | |
|
| draggable | 图片是否允许拖动 | boolean \| `'true'` \| `'false'` | - | |
|
||||||
|
| crossOrigin | CORS 属性设置 | `'anonymous'` \| `'use-credentials'` \| `''` | - | 4.17.0 |
|
||||||
| onError | 图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为 | () => boolean | - | |
|
| onError | 图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为 | () => boolean | - | |
|
||||||
|
|
||||||
> Tip:你可以设置 `icon` 或 `children` 作为图片加载失败的默认 fallback 行为,优先级为 `icon` > `children`
|
> Tip:你可以设置 `icon` 或 `children` 作为图片加载失败的默认 fallback 行为,优先级为 `icon` > `children`
|
||||||
|
3
components/calendar/locale/bn_BD.tsx
Normal file
3
components/calendar/locale/bn_BD.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import bnBD from '../../date-picker/locale/bn_BD';
|
||||||
|
|
||||||
|
export default bnBD;
|
3
components/calendar/locale/ml_IN.tsx
Normal file
3
components/calendar/locale/ml_IN.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import mlIN from '../../date-picker/locale/ml_IN';
|
||||||
|
|
||||||
|
export default mlIN;
|
3
components/calendar/locale/ur_PK.tsx
Normal file
3
components/calendar/locale/ur_PK.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import urPK from '../../date-picker/locale/ur_PK';
|
||||||
|
|
||||||
|
export default urPK;
|
@ -209,6 +209,7 @@ exports[`renders ./components/cascader/demo/default-value.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-cascader-picker-label"
|
class="ant-cascader-picker-label"
|
||||||
|
title="Zhejiang / Hangzhou / West Lake"
|
||||||
>
|
>
|
||||||
Zhejiang / Hangzhou / West Lake
|
Zhejiang / Hangzhou / West Lake
|
||||||
</span>
|
</span>
|
||||||
|
@ -1117,6 +1117,7 @@ exports[`Cascader support controlled mode 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-cascader-picker-label"
|
class="ant-cascader-picker-label"
|
||||||
|
title="Zhejiang / Hangzhou / West Lake"
|
||||||
>
|
>
|
||||||
Zhejiang / Hangzhou / West Lake
|
Zhejiang / Hangzhou / West Lake
|
||||||
</span>
|
</span>
|
||||||
|
@ -316,7 +316,7 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
getLabel() {
|
getLabel() {
|
||||||
const { options, displayRender = defaultDisplayRender as Function } = this.props;
|
const { options, displayRender = defaultDisplayRender } = this.props;
|
||||||
const names = getFilledFieldNames(this.props);
|
const names = getFilledFieldNames(this.props);
|
||||||
const { value } = this.state;
|
const { value } = this.state;
|
||||||
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
|
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
|
||||||
@ -618,9 +618,15 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
|
|||||||
inputIcon = <DownOutlined className={arrowCls} />;
|
inputIcon = <DownOutlined className={arrowCls} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const label = this.getLabel();
|
||||||
const input: React.ReactElement = children || (
|
const input: React.ReactElement = children || (
|
||||||
<span style={style} className={pickerCls}>
|
<span style={style} className={pickerCls}>
|
||||||
<span className={`${prefixCls}-picker-label`}>{this.getLabel()}</span>
|
<span
|
||||||
|
className={`${prefixCls}-picker-label`}
|
||||||
|
title={typeof label === 'string' && label ? label : undefined}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</span>
|
||||||
<Input
|
<Input
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
direction: ltr;
|
direction: ltr;
|
||||||
background-color: @checkbox-check-bg;
|
background-color: @checkbox-check-bg;
|
||||||
border: @checkbox-border-width @border-style-base @border-color-base;
|
border: @checkbox-border-width @border-style-base @border-color-base;
|
||||||
border-radius: @border-radius-base;
|
border-radius: @checkbox-border-radius;
|
||||||
// Fix IE checked style
|
// Fix IE checked style
|
||||||
// https://github.com/ant-design/ant-design/issues/12597
|
// https://github.com/ant-design/ant-design/issues/12597
|
||||||
border-collapse: separate;
|
border-collapse: separate;
|
||||||
|
@ -12199,7 +12199,7 @@ exports[`ConfigProvider components Drawer configProvider 1`] = `
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-content-wrapper"
|
class="config-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-content"
|
class="config-drawer-content"
|
||||||
@ -12208,34 +12208,37 @@ exports[`ConfigProvider components Drawer configProvider 1`] = `
|
|||||||
class="config-drawer-wrapper-body"
|
class="config-drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-header-no-title"
|
class="config-drawer-header config-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="config-drawer-header-title"
|
||||||
class="config-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="config-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-body"
|
class="config-drawer-body"
|
||||||
@ -12260,7 +12263,7 @@ exports[`ConfigProvider components Drawer configProvider componentSize large 1`]
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-content-wrapper"
|
class="config-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-content"
|
class="config-drawer-content"
|
||||||
@ -12269,34 +12272,37 @@ exports[`ConfigProvider components Drawer configProvider componentSize large 1`]
|
|||||||
class="config-drawer-wrapper-body"
|
class="config-drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-header-no-title"
|
class="config-drawer-header config-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="config-drawer-header-title"
|
||||||
class="config-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="config-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-body"
|
class="config-drawer-body"
|
||||||
@ -12321,7 +12327,7 @@ exports[`ConfigProvider components Drawer configProvider componentSize middle 1`
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-content-wrapper"
|
class="config-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-content"
|
class="config-drawer-content"
|
||||||
@ -12330,34 +12336,37 @@ exports[`ConfigProvider components Drawer configProvider componentSize middle 1`
|
|||||||
class="config-drawer-wrapper-body"
|
class="config-drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-header-no-title"
|
class="config-drawer-header config-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="config-drawer-header-title"
|
||||||
class="config-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="config-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="config-drawer-body"
|
class="config-drawer-body"
|
||||||
@ -12382,7 +12391,7 @@ exports[`ConfigProvider components Drawer configProvider virtual and dropdownMat
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content-wrapper"
|
class="ant-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content"
|
class="ant-drawer-content"
|
||||||
@ -12391,34 +12400,37 @@ exports[`ConfigProvider components Drawer configProvider virtual and dropdownMat
|
|||||||
class="ant-drawer-wrapper-body"
|
class="ant-drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-header-no-title"
|
class="ant-drawer-header ant-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="ant-drawer-header-title"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="ant-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
@ -12443,7 +12455,7 @@ exports[`ConfigProvider components Drawer normal 1`] = `
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content-wrapper"
|
class="ant-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content"
|
class="ant-drawer-content"
|
||||||
@ -12452,34 +12464,37 @@ exports[`ConfigProvider components Drawer normal 1`] = `
|
|||||||
class="ant-drawer-wrapper-body"
|
class="ant-drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-header-no-title"
|
class="ant-drawer-header ant-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="ant-drawer-header-title"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="ant-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
@ -12504,7 +12519,7 @@ exports[`ConfigProvider components Drawer prefixCls 1`] = `
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="prefix-Drawer-content-wrapper"
|
class="prefix-Drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="prefix-Drawer-content"
|
class="prefix-Drawer-content"
|
||||||
@ -12513,34 +12528,37 @@ exports[`ConfigProvider components Drawer prefixCls 1`] = `
|
|||||||
class="prefix-Drawer-wrapper-body"
|
class="prefix-Drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="prefix-Drawer-header-no-title"
|
class="prefix-Drawer-header prefix-Drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="prefix-Drawer-header-title"
|
||||||
class="prefix-Drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="prefix-Drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="prefix-Drawer-body"
|
class="prefix-Drawer-body"
|
||||||
@ -13260,9 +13278,10 @@ exports[`ConfigProvider components Form configProvider 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="config-form-item-explain config-form-item-explain-error"
|
class="config-form-item-explain config-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="config-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Bamboo is Light
|
Bamboo is Light
|
||||||
@ -13297,9 +13316,10 @@ exports[`ConfigProvider components Form configProvider componentSize large 1`] =
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="config-form-item-explain config-form-item-explain-error"
|
class="config-form-item-explain config-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="config-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Bamboo is Light
|
Bamboo is Light
|
||||||
@ -13334,9 +13354,10 @@ exports[`ConfigProvider components Form configProvider componentSize middle 1`]
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="config-form-item-explain config-form-item-explain-error"
|
class="config-form-item-explain config-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="config-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Bamboo is Light
|
Bamboo is Light
|
||||||
@ -13371,9 +13392,10 @@ exports[`ConfigProvider components Form configProvider virtual and dropdownMatch
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Bamboo is Light
|
Bamboo is Light
|
||||||
@ -13408,9 +13430,10 @@ exports[`ConfigProvider components Form normal 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Bamboo is Light
|
Bamboo is Light
|
||||||
@ -13445,9 +13468,10 @@ exports[`ConfigProvider components Form prefixCls 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="prefix-Form-item-explain prefix-Form-item-explain-error"
|
class="prefix-Form-item-explain prefix-Form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="prefix-Form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Bamboo is Light
|
Bamboo is Light
|
||||||
@ -35502,11 +35526,11 @@ exports[`ConfigProvider components Tree configProvider 1`] = `
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="config-tree config-tree-icon-hide"
|
class="config-tree config-tree-icon-hide"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
@ -35565,11 +35589,11 @@ exports[`ConfigProvider components Tree configProvider 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="config-tree config-tree-block-node config-tree-directory"
|
class="config-tree config-tree-block-node config-tree-directory"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
@ -35656,11 +35680,11 @@ exports[`ConfigProvider components Tree configProvider componentSize large 1`] =
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="config-tree config-tree-icon-hide"
|
class="config-tree config-tree-icon-hide"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
@ -35719,11 +35743,11 @@ exports[`ConfigProvider components Tree configProvider componentSize large 1`] =
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="config-tree config-tree-block-node config-tree-directory"
|
class="config-tree config-tree-block-node config-tree-directory"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
@ -35810,11 +35834,11 @@ exports[`ConfigProvider components Tree configProvider componentSize middle 1`]
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="config-tree config-tree-icon-hide"
|
class="config-tree config-tree-icon-hide"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
@ -35873,11 +35897,11 @@ exports[`ConfigProvider components Tree configProvider componentSize middle 1`]
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="config-tree config-tree-block-node config-tree-directory"
|
class="config-tree config-tree-block-node config-tree-directory"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
@ -35964,11 +35988,11 @@ exports[`ConfigProvider components Tree configProvider virtual and dropdownMatch
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tree ant-tree-icon-hide"
|
class="ant-tree ant-tree-icon-hide"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
@ -36027,11 +36051,11 @@ exports[`ConfigProvider components Tree configProvider virtual and dropdownMatch
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-tree ant-tree-block-node ant-tree-directory"
|
class="ant-tree ant-tree-block-node ant-tree-directory"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
@ -36118,11 +36142,11 @@ exports[`ConfigProvider components Tree normal 1`] = `
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-tree ant-tree-icon-hide"
|
class="ant-tree ant-tree-icon-hide"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
@ -36181,11 +36205,11 @@ exports[`ConfigProvider components Tree normal 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-tree ant-tree-block-node ant-tree-directory"
|
class="ant-tree ant-tree-block-node ant-tree-directory"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
@ -36272,11 +36296,11 @@ exports[`ConfigProvider components Tree prefixCls 1`] = `
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="prefix-Tree prefix-Tree-icon-hide"
|
class="prefix-Tree prefix-Tree-icon-hide"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
@ -36335,11 +36359,11 @@ exports[`ConfigProvider components Tree prefixCls 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="prefix-Tree prefix-Tree-block-node prefix-Tree-directory"
|
class="prefix-Tree prefix-Tree-block-node prefix-Tree-directory"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
|
@ -61,7 +61,8 @@ Setting `Modal`、`Message`、`Notification` rootPrefixCls.
|
|||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
ConfigProvider.config({
|
ConfigProvider.config({
|
||||||
prefixCls: 'ant',
|
prefixCls: 'ant', // 4.13.0+
|
||||||
|
iconPrefixCls: 'anticon', // 4.17.0+
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -85,11 +85,19 @@ interface ProviderChildrenProps extends ConfigProviderProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const defaultPrefixCls = 'ant';
|
export const defaultPrefixCls = 'ant';
|
||||||
|
export const defaultIconPrefixCls = 'anticon';
|
||||||
let globalPrefixCls: string;
|
let globalPrefixCls: string;
|
||||||
|
let globalIconPrefixCls: string;
|
||||||
|
|
||||||
const setGlobalConfig = (params: Pick<ConfigProviderProps, 'prefixCls'>) => {
|
const setGlobalConfig = ({
|
||||||
if (params.prefixCls !== undefined) {
|
prefixCls,
|
||||||
globalPrefixCls = params.prefixCls;
|
iconPrefixCls,
|
||||||
|
}: Pick<ConfigProviderProps, 'prefixCls' | 'iconPrefixCls'>) => {
|
||||||
|
if (prefixCls !== undefined) {
|
||||||
|
globalPrefixCls = prefixCls;
|
||||||
|
}
|
||||||
|
if (iconPrefixCls !== undefined) {
|
||||||
|
globalIconPrefixCls = iconPrefixCls;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -97,11 +105,16 @@ function getGlobalPrefixCls() {
|
|||||||
return globalPrefixCls || defaultPrefixCls;
|
return globalPrefixCls || defaultPrefixCls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getGlobalIconPrefixCls() {
|
||||||
|
return globalIconPrefixCls || defaultIconPrefixCls;
|
||||||
|
}
|
||||||
|
|
||||||
export const globalConfig = () => ({
|
export const globalConfig = () => ({
|
||||||
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {
|
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {
|
||||||
if (customizePrefixCls) return customizePrefixCls;
|
if (customizePrefixCls) return customizePrefixCls;
|
||||||
return suffixCls ? `${getGlobalPrefixCls()}-${suffixCls}` : getGlobalPrefixCls();
|
return suffixCls ? `${getGlobalPrefixCls()}-${suffixCls}` : getGlobalPrefixCls();
|
||||||
},
|
},
|
||||||
|
getIconPrefixCls: getGlobalIconPrefixCls,
|
||||||
getRootPrefixCls: (rootPrefixCls?: string, customizePrefixCls?: string) => {
|
getRootPrefixCls: (rootPrefixCls?: string, customizePrefixCls?: string) => {
|
||||||
// Customize rootPrefixCls is first priority
|
// Customize rootPrefixCls is first priority
|
||||||
if (rootPrefixCls) {
|
if (rootPrefixCls) {
|
||||||
|
@ -62,7 +62,8 @@ export default () => (
|
|||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
ConfigProvider.config({
|
ConfigProvider.config({
|
||||||
prefixCls: 'ant',
|
prefixCls: 'ant', // 4.13.0+
|
||||||
|
iconPrefixCls: 'anticon', // 4.17.0+
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
27
components/date-picker/locale/bn_BD.tsx
Normal file
27
components/date-picker/locale/bn_BD.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import CalendarLocale from 'rc-picker/lib/locale/bn_BD';
|
||||||
|
import TimePickerLocale from '../../time-picker/locale/bn_BD';
|
||||||
|
import { PickerLocale } from '../generatePicker';
|
||||||
|
|
||||||
|
// Merge into a locale object
|
||||||
|
const locale: PickerLocale = {
|
||||||
|
lang: {
|
||||||
|
placeholder: 'তারিখ নির্বাচন',
|
||||||
|
yearPlaceholder: 'বছর নির্বাচন',
|
||||||
|
quarterPlaceholder: 'কোয়ার্টার নির্বাচন',
|
||||||
|
monthPlaceholder: 'মাস নির্বাচন',
|
||||||
|
weekPlaceholder: 'সপ্তাহ নির্বাচন',
|
||||||
|
rangePlaceholder: ['শুরুর তারিখ', 'শেষ তারিখ'],
|
||||||
|
rangeYearPlaceholder: ['শুরুর বছর', 'শেষ বছর'],
|
||||||
|
rangeMonthPlaceholder: ['শুরুর মাস', 'শেষ মাস'],
|
||||||
|
rangeWeekPlaceholder: ['শুরুর সপ্তাহ', 'শেষ সপ্তাহ'],
|
||||||
|
...CalendarLocale,
|
||||||
|
},
|
||||||
|
timePickerLocale: {
|
||||||
|
...TimePickerLocale,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// All settings at:
|
||||||
|
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||||
|
|
||||||
|
export default locale;
|
27
components/date-picker/locale/ml_IN.tsx
Normal file
27
components/date-picker/locale/ml_IN.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import CalendarLocale from 'rc-picker/lib/locale/ml_IN';
|
||||||
|
import TimePickerLocale from '../../time-picker/locale/ml_IN';
|
||||||
|
import { PickerLocale } from '../generatePicker';
|
||||||
|
|
||||||
|
// Merge into a locale object
|
||||||
|
const locale: PickerLocale = {
|
||||||
|
lang: {
|
||||||
|
placeholder: 'തിയതി തിരഞ്ഞെടുക്കുക',
|
||||||
|
yearPlaceholder: 'വർഷം തിരഞ്ഞെടുക്കുക',
|
||||||
|
quarterPlaceholder: 'ത്രൈമാസം തിരഞ്ഞെടുക്കുക',
|
||||||
|
monthPlaceholder: 'മാസം തിരഞ്ഞെടുക്കുക',
|
||||||
|
weekPlaceholder: 'വാരം തിരഞ്ഞെടുക്കുക',
|
||||||
|
rangePlaceholder: ['ആരംഭ ദിനം', 'അവസാന ദിനം'],
|
||||||
|
rangeYearPlaceholder: ['ആരംഭ വർഷം', 'അവസാന വർഷം'],
|
||||||
|
rangeMonthPlaceholder: ['ആരംഭ മാസം', 'അവസാന മാസം'],
|
||||||
|
rangeWeekPlaceholder: ['ആരംഭ വാരം', 'അവസാന വാരം'],
|
||||||
|
...CalendarLocale,
|
||||||
|
},
|
||||||
|
timePickerLocale: {
|
||||||
|
...TimePickerLocale,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// All settings at:
|
||||||
|
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||||
|
|
||||||
|
export default locale;
|
27
components/date-picker/locale/ur_PK.tsx
Normal file
27
components/date-picker/locale/ur_PK.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import CalendarLocale from 'rc-picker/lib/locale/ur_PK';
|
||||||
|
import TimePickerLocale from '../../time-picker/locale/ur_PK';
|
||||||
|
import { PickerLocale } from '../generatePicker';
|
||||||
|
|
||||||
|
// Merge into a locale object
|
||||||
|
const locale: PickerLocale = {
|
||||||
|
lang: {
|
||||||
|
placeholder: 'تاریخ منتخب کریں',
|
||||||
|
yearPlaceholder: 'سال کو منتخب کریں',
|
||||||
|
quarterPlaceholder: 'کوارٹر منتخب کریں',
|
||||||
|
monthPlaceholder: 'ماہ منتخب کریں',
|
||||||
|
weekPlaceholder: 'ہفتہ منتخب کریں',
|
||||||
|
rangePlaceholder: ['شروع کرنے کی تاریخ', 'آخری تاریخ'],
|
||||||
|
rangeYearPlaceholder: ['آغاز سال', 'آخر سال'],
|
||||||
|
rangeMonthPlaceholder: ['مہینہ شروع', 'اختتامی مہینہ'],
|
||||||
|
rangeWeekPlaceholder: ['ہفتے شروع کریں', 'اختتام ہفتہ'],
|
||||||
|
...CalendarLocale,
|
||||||
|
},
|
||||||
|
timePickerLocale: {
|
||||||
|
...TimePickerLocale,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// All settings at:
|
||||||
|
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||||
|
|
||||||
|
export default locale;
|
@ -13,7 +13,7 @@ exports[`Drawer className is test_drawer 1`] = `
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content-wrapper"
|
class="ant-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content"
|
class="ant-drawer-content"
|
||||||
@ -23,34 +23,37 @@ exports[`Drawer className is test_drawer 1`] = `
|
|||||||
style="opacity:0;transition:opacity .3s"
|
style="opacity:0;transition:opacity .3s"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-header-no-title"
|
class="ant-drawer-header ant-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="ant-drawer-header-title"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="ant-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
@ -77,7 +80,7 @@ exports[`Drawer closable is false 1`] = `
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content-wrapper"
|
class="ant-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content"
|
class="ant-drawer-content"
|
||||||
@ -110,7 +113,7 @@ exports[`Drawer destroyOnClose is true 1`] = `
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content-wrapper"
|
class="ant-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content"
|
class="ant-drawer-content"
|
||||||
@ -120,34 +123,37 @@ exports[`Drawer destroyOnClose is true 1`] = `
|
|||||||
style="opacity:0;transition:opacity .3s"
|
style="opacity:0;transition:opacity .3s"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-header-no-title"
|
class="ant-drawer-header ant-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="ant-drawer-header-title"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="ant-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
@ -186,34 +192,37 @@ exports[`Drawer getContainer return undefined 2`] = `
|
|||||||
class="ant-drawer-wrapper-body"
|
class="ant-drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-header-no-title"
|
class="ant-drawer-header ant-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="ant-drawer-header-title"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar: 0px;"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="ant-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
@ -241,7 +250,7 @@ exports[`Drawer have a footer 1`] = `
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content-wrapper"
|
class="ant-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content"
|
class="ant-drawer-content"
|
||||||
@ -250,34 +259,37 @@ exports[`Drawer have a footer 1`] = `
|
|||||||
class="ant-drawer-wrapper-body"
|
class="ant-drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-header-no-title"
|
class="ant-drawer-header ant-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="ant-drawer-header-title"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="ant-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
@ -309,7 +321,7 @@ exports[`Drawer have a title 1`] = `
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content-wrapper"
|
class="ant-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content"
|
class="ant-drawer-content"
|
||||||
@ -321,36 +333,39 @@ exports[`Drawer have a title 1`] = `
|
|||||||
class="ant-drawer-header"
|
class="ant-drawer-header"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-title"
|
class="ant-drawer-header-title"
|
||||||
>
|
>
|
||||||
Test Title
|
<button
|
||||||
</div>
|
aria-label="Close"
|
||||||
<button
|
class="ant-drawer-close"
|
||||||
aria-label="Close"
|
type="button"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
aria-label="close"
|
|
||||||
class="anticon anticon-close"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
class="ant-drawer-title"
|
||||||
|
>
|
||||||
|
Test Title
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
@ -386,34 +401,37 @@ exports[`Drawer render correctly 1`] = `
|
|||||||
class="ant-drawer-wrapper-body"
|
class="ant-drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-header-no-title"
|
class="ant-drawer-header ant-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="ant-drawer-header-title"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="ant-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
@ -449,34 +467,37 @@ exports[`Drawer render top drawer 1`] = `
|
|||||||
class="ant-drawer-wrapper-body"
|
class="ant-drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-header-no-title"
|
class="ant-drawer-header ant-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="ant-drawer-header-title"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="ant-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
@ -506,7 +527,7 @@ exports[`Drawer style/drawerStyle/headerStyle/bodyStyle should work 1`] = `
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content-wrapper"
|
class="ant-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content"
|
class="ant-drawer-content"
|
||||||
@ -516,35 +537,38 @@ exports[`Drawer style/drawerStyle/headerStyle/bodyStyle should work 1`] = `
|
|||||||
style="background-color:#08c"
|
style="background-color:#08c"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-header-no-title"
|
class="ant-drawer-header ant-drawer-header-close-only"
|
||||||
style="background-color:#08c"
|
style="background-color:#08c"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="ant-drawer-header-title"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="ant-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
@ -581,18 +605,21 @@ exports[`Drawer support closeIcon 1`] = `
|
|||||||
class="ant-drawer-wrapper-body"
|
class="ant-drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-header-no-title"
|
class="ant-drawer-header ant-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="ant-drawer-header-title"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar:0px"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span>
|
<button
|
||||||
close
|
aria-label="Close"
|
||||||
</span>
|
class="ant-drawer-close"
|
||||||
</button>
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
close
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
|
@ -22,7 +22,7 @@ exports[`Drawer render correctly 1`] = `
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content-wrapper"
|
class="ant-drawer-content-wrapper"
|
||||||
style="width: 256px;"
|
style="width: 378px;"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content"
|
class="ant-drawer-content"
|
||||||
@ -31,34 +31,37 @@ exports[`Drawer render correctly 1`] = `
|
|||||||
class="ant-drawer-wrapper-body"
|
class="ant-drawer-wrapper-body"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-header-no-title"
|
class="ant-drawer-header ant-drawer-header-close-only"
|
||||||
>
|
>
|
||||||
<button
|
<div
|
||||||
aria-label="Close"
|
class="ant-drawer-header-title"
|
||||||
class="ant-drawer-close"
|
|
||||||
style="--scroll-bar: 0px;"
|
|
||||||
type="button"
|
|
||||||
>
|
>
|
||||||
<span
|
<button
|
||||||
aria-label="close"
|
aria-label="Close"
|
||||||
class="anticon anticon-close"
|
class="ant-drawer-close"
|
||||||
role="img"
|
type="button"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close"
|
||||||
data-icon="close"
|
class="anticon anticon-close"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</span>
|
focusable="false"
|
||||||
</button>
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-body"
|
class="ant-drawer-body"
|
||||||
|
@ -26,6 +26,111 @@ exports[`renders ./components/drawer/demo/config-provider.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`renders ./components/drawer/demo/extra.md correctly 1`] = `
|
||||||
|
<div
|
||||||
|
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="margin-right:8px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-radio-group ant-radio-group-outline"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="ant-radio-wrapper"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="ant-radio"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="ant-radio-input"
|
||||||
|
type="radio"
|
||||||
|
value="top"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="ant-radio-inner"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
top
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
class="ant-radio-wrapper ant-radio-wrapper-checked"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="ant-radio ant-radio-checked"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
checked=""
|
||||||
|
class="ant-radio-input"
|
||||||
|
type="radio"
|
||||||
|
value="right"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="ant-radio-inner"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
right
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
class="ant-radio-wrapper"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="ant-radio"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="ant-radio-input"
|
||||||
|
type="radio"
|
||||||
|
value="bottom"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="ant-radio-inner"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
bottom
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
class="ant-radio-wrapper"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="ant-radio"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="ant-radio-input"
|
||||||
|
type="radio"
|
||||||
|
value="left"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="ant-radio-inner"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
left
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-btn-primary"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Open
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/drawer/demo/form-in-drawer.md correctly 1`] = `
|
exports[`renders ./components/drawer/demo/form-in-drawer.md correctly 1`] = `
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-primary"
|
class="ant-btn ant-btn-primary"
|
||||||
@ -55,7 +160,7 @@ exports[`renders ./components/drawer/demo/form-in-drawer.md correctly 1`] = `
|
|||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
New account
|
New account
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
`;
|
`;
|
||||||
@ -217,7 +322,7 @@ exports[`renders ./components/drawer/demo/render-in-current.md correctly 1`] = `
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content-wrapper"
|
class="ant-drawer-content-wrapper"
|
||||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
style="transform:translateX(100%);-ms-transform:translateX(100%);width:378px"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-content"
|
class="ant-drawer-content"
|
||||||
@ -229,9 +334,13 @@ exports[`renders ./components/drawer/demo/render-in-current.md correctly 1`] = `
|
|||||||
class="ant-drawer-header"
|
class="ant-drawer-header"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-drawer-title"
|
class="ant-drawer-header-title"
|
||||||
>
|
>
|
||||||
Basic Drawer
|
<div
|
||||||
|
class="ant-drawer-title"
|
||||||
|
>
|
||||||
|
Basic Drawer
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@ -249,6 +358,38 @@ exports[`renders ./components/drawer/demo/render-in-current.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`renders ./components/drawer/demo/size.md correctly 1`] = `
|
||||||
|
<div
|
||||||
|
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="margin-right:8px"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-btn-primary"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Open Default Size (378px)
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-btn-primary"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Open Large Size (736px)
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/drawer/demo/user-profile.md correctly 1`] = `
|
exports[`renders ./components/drawer/demo/user-profile.md correctly 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-list ant-list-split ant-list-bordered"
|
class="ant-list ant-list-split ant-list-bordered"
|
||||||
|
@ -7,7 +7,7 @@ title:
|
|||||||
|
|
||||||
## zh-CN
|
## zh-CN
|
||||||
|
|
||||||
基础抽屉,点击触发按钮抽屉从右滑出,点击遮罩区关闭
|
基础抽屉,点击触发按钮抽屉从右滑出,点击遮罩区关闭。
|
||||||
|
|
||||||
## en-US
|
## en-US
|
||||||
|
|
||||||
@ -30,13 +30,7 @@ const App: React.FC = () => {
|
|||||||
<Button type="primary" onClick={showDrawer}>
|
<Button type="primary" onClick={showDrawer}>
|
||||||
Open
|
Open
|
||||||
</Button>
|
</Button>
|
||||||
<Drawer
|
<Drawer title="Basic Drawer" placement="right" onClose={onClose} visible={visible}>
|
||||||
title="Basic Drawer"
|
|
||||||
placement="right"
|
|
||||||
closable={false}
|
|
||||||
onClose={onClose}
|
|
||||||
visible={visible}
|
|
||||||
>
|
|
||||||
<p>Some contents...</p>
|
<p>Some contents...</p>
|
||||||
<p>Some contents...</p>
|
<p>Some contents...</p>
|
||||||
<p>Some contents...</p>
|
<p>Some contents...</p>
|
||||||
|
71
components/drawer/demo/extra.md
Normal file
71
components/drawer/demo/extra.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
---
|
||||||
|
order: 1.1
|
||||||
|
title:
|
||||||
|
zh-CN: 额外操作
|
||||||
|
en-US: Extra Actions
|
||||||
|
---
|
||||||
|
|
||||||
|
## zh-CN
|
||||||
|
|
||||||
|
在 Ant Design 规范中,操作按钮建议放在抽屉的右上角,可以使用 `extra` 属性来实现。
|
||||||
|
|
||||||
|
## en-US
|
||||||
|
|
||||||
|
Extra actions should be placed at corner of drawer in Ant Design, you can using `extra` prop for that.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Drawer, Button, Space, Radio } from 'antd';
|
||||||
|
import { DrawerProps } from 'antd/es/drawer';
|
||||||
|
import { RadioChangeEvent } from 'antd/es/radio';
|
||||||
|
|
||||||
|
const App: React.FC = () => {
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
const [placement, setPlacement] = useState<DrawerProps['placement']>('right');
|
||||||
|
const showDrawer = () => {
|
||||||
|
setVisible(true);
|
||||||
|
};
|
||||||
|
const onChange = (e: RadioChangeEvent) => {
|
||||||
|
setPlacement(e.target.value);
|
||||||
|
};
|
||||||
|
const onClose = () => {
|
||||||
|
setVisible(false);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space>
|
||||||
|
<Radio.Group value={placement} onChange={onChange}>
|
||||||
|
<Radio value="top">top</Radio>
|
||||||
|
<Radio value="right">right</Radio>
|
||||||
|
<Radio value="bottom">bottom</Radio>
|
||||||
|
<Radio value="left">left</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
<Button type="primary" onClick={showDrawer}>
|
||||||
|
Open
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
<Drawer
|
||||||
|
title="Drawer with extra actions"
|
||||||
|
placement={placement}
|
||||||
|
width={500}
|
||||||
|
onClose={onClose}
|
||||||
|
visible={visible}
|
||||||
|
extra={
|
||||||
|
<Space>
|
||||||
|
<Button onClick={onClose}>Cancel</Button>
|
||||||
|
<Button type="primary" onClick={onClose}>
|
||||||
|
OK
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
</Drawer>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ReactDOM.render(<App />, mountNode);
|
||||||
|
```
|
@ -14,7 +14,7 @@ title:
|
|||||||
Use a form in Drawer with a submit button.
|
Use a form in Drawer with a submit button.
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { Drawer, Form, Button, Col, Row, Input, Select, DatePicker } from 'antd';
|
import { Drawer, Form, Button, Col, Row, Input, Select, DatePicker, Space } from 'antd';
|
||||||
import { PlusOutlined } from '@ant-design/icons';
|
import { PlusOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
@ -37,8 +37,8 @@ class DrawerForm extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button type="primary" onClick={this.showDrawer}>
|
<Button type="primary" onClick={this.showDrawer} icon={<PlusOutlined />}>
|
||||||
<PlusOutlined /> New account
|
New account
|
||||||
</Button>
|
</Button>
|
||||||
<Drawer
|
<Drawer
|
||||||
title="Create a new account"
|
title="Create a new account"
|
||||||
@ -46,19 +46,13 @@ class DrawerForm extends React.Component {
|
|||||||
onClose={this.onClose}
|
onClose={this.onClose}
|
||||||
visible={this.state.visible}
|
visible={this.state.visible}
|
||||||
bodyStyle={{ paddingBottom: 80 }}
|
bodyStyle={{ paddingBottom: 80 }}
|
||||||
footer={
|
extra={
|
||||||
<div
|
<Space>
|
||||||
style={{
|
<Button onClick={this.onClose}>Cancel</Button>
|
||||||
textAlign: 'right',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Button onClick={this.onClose} style={{ marginRight: 8 }}>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
<Button onClick={this.onClose} type="primary">
|
<Button onClick={this.onClose} type="primary">
|
||||||
Submit
|
Submit
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</Space>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Form layout="vertical" hideRequiredMark>
|
<Form layout="vertical" hideRequiredMark>
|
||||||
|
@ -7,7 +7,7 @@ title:
|
|||||||
|
|
||||||
## zh-CN
|
## zh-CN
|
||||||
|
|
||||||
自定义位置,点击触发按钮抽屉从相应的位置滑出,点击遮罩区关闭
|
自定义位置,点击触发按钮抽屉从相应的位置滑出,点击遮罩区关闭。
|
||||||
|
|
||||||
## en-US
|
## en-US
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class App extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Space>
|
<Space>
|
||||||
<Radio.Group defaultValue={placement} onChange={this.onChange}>
|
<Radio.Group value={placement} onChange={this.onChange}>
|
||||||
<Radio value="top">top</Radio>
|
<Radio value="top">top</Radio>
|
||||||
<Radio value="right">right</Radio>
|
<Radio value="right">right</Radio>
|
||||||
<Radio value="bottom">bottom</Radio>
|
<Radio value="bottom">bottom</Radio>
|
||||||
|
@ -7,11 +7,11 @@ title:
|
|||||||
|
|
||||||
## zh-CN
|
## zh-CN
|
||||||
|
|
||||||
渲染在当前 dom 里。自定义容器,查看 getContainer。
|
渲染在当前 dom 里。自定义容器,查看 `getContainer`。
|
||||||
|
|
||||||
## en-US
|
## en-US
|
||||||
|
|
||||||
Render in current dom. custom container, check getContainer.
|
Render in current dom. custom container, check `getContainer`.
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { Drawer, Button } from 'antd';
|
import { Drawer, Button } from 'antd';
|
||||||
|
69
components/drawer/demo/size.md
Normal file
69
components/drawer/demo/size.md
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
order: 10
|
||||||
|
title:
|
||||||
|
zh-CN: 预设宽度
|
||||||
|
en-US: Presetted size
|
||||||
|
---
|
||||||
|
|
||||||
|
## zh-CN
|
||||||
|
|
||||||
|
抽屉的默认宽度为 `378px`,另外还提供一个大号抽屉 `736px`,可以用 `size` 属性来设置。
|
||||||
|
|
||||||
|
## en-US
|
||||||
|
|
||||||
|
The default width (or height) of Drawer is `378px`, and there is a presetted large size `736px`.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Drawer, Button, Space } from 'antd';
|
||||||
|
import { DrawerProps } from 'antd/es/drawer';
|
||||||
|
|
||||||
|
const App: React.FC = () => {
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
const [size, setSize] = useState<DrawerProps['size']>();
|
||||||
|
const showDefaultDrawer = () => {
|
||||||
|
setSize('default');
|
||||||
|
setVisible(true);
|
||||||
|
};
|
||||||
|
const showLargeDrawer = () => {
|
||||||
|
setSize('large');
|
||||||
|
setVisible(true);
|
||||||
|
};
|
||||||
|
const onClose = () => {
|
||||||
|
setVisible(false);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space>
|
||||||
|
<Button type="primary" onClick={showDefaultDrawer}>
|
||||||
|
Open Default Size (378px)
|
||||||
|
</Button>
|
||||||
|
<Button type="primary" onClick={showLargeDrawer}>
|
||||||
|
Open Large Size (736px)
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
<Drawer
|
||||||
|
title={`${size} Drawer`}
|
||||||
|
placement="right"
|
||||||
|
size={size}
|
||||||
|
onClose={onClose}
|
||||||
|
visible={visible}
|
||||||
|
extra={
|
||||||
|
<Space>
|
||||||
|
<Button onClick={onClose}>Cancel</Button>
|
||||||
|
<Button type="primary" onClick={onClose}>
|
||||||
|
OK
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
</Drawer>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ReactDOM.render(<App />, mountNode);
|
||||||
|
```
|
@ -28,6 +28,7 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
|
|||||||
| contentWrapperStyle | Style of the drawer wrapper of content part | CSSProperties | - | |
|
| contentWrapperStyle | Style of the drawer wrapper of content part | CSSProperties | - | |
|
||||||
| destroyOnClose | Whether to unmount child components on closing drawer or not | boolean | false | |
|
| destroyOnClose | Whether to unmount child components on closing drawer or not | boolean | false | |
|
||||||
| drawerStyle | Style of the popup layer element | object | - | |
|
| drawerStyle | Style of the popup layer element | object | - | |
|
||||||
|
| extra | Extra actions area at corner | ReactNode | - | 4.17.0 |
|
||||||
| footer | The footer for Drawer | ReactNode | - | |
|
| footer | The footer for Drawer | ReactNode | - | |
|
||||||
| footerStyle | Style of the drawer footer part | CSSProperties | - | |
|
| footerStyle | Style of the drawer footer part | CSSProperties | - | |
|
||||||
| forceRender | Prerender Drawer component forcely | boolean | false | |
|
| forceRender | Prerender Drawer component forcely | boolean | false | |
|
||||||
@ -41,8 +42,9 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
|
|||||||
| placement | The placement of the Drawer | `top` \| `right` \| `bottom` \| `left` | `right` | |
|
| placement | The placement of the Drawer | `top` \| `right` \| `bottom` \| `left` | `right` | |
|
||||||
| push | Nested drawers push behavior | boolean \| { distance: string \| number } | { distance: 180 } | 4.5.0+ |
|
| push | Nested drawers push behavior | boolean \| { distance: string \| number } | { distance: 180 } | 4.5.0+ |
|
||||||
| style | Style of wrapper element which **contains mask** compare to `drawerStyle` | CSSProperties | - | |
|
| style | Style of wrapper element which **contains mask** compare to `drawerStyle` | CSSProperties | - | |
|
||||||
|
| size | presetted size of drawer, default `378px` and large `736px` | 'default' \| 'large' | 'default' | 4.17.0 |
|
||||||
| title | The title for Drawer | ReactNode | - | |
|
| title | The title for Drawer | ReactNode | - | |
|
||||||
| visible | Whether the Drawer dialog is visible or not | boolean | false | |
|
| visible | Whether the Drawer dialog is visible or not | boolean | false | |
|
||||||
| width | Width of the Drawer dialog | string \| number | 256 | |
|
| width | Width of the Drawer dialog | string \| number | 378 | |
|
||||||
| zIndex | The `z-index` of the Drawer | number | 1000 | |
|
| zIndex | The `z-index` of the Drawer | number | 1000 | |
|
||||||
| onClose | Specify a callback that will be called when a user clicks mask, close button or Cancel button | function(e) | - | |
|
| onClose | Specify a callback that will be called when a user clicks mask, close button or Cancel button | function(e) | - | |
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import RcDrawer from 'rc-drawer';
|
import RcDrawer from 'rc-drawer';
|
||||||
import getScrollBarSize from 'rc-util/lib/getScrollBarSize';
|
|
||||||
import CloseOutlined from '@ant-design/icons/CloseOutlined';
|
import CloseOutlined from '@ant-design/icons/CloseOutlined';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { ConfigContext, DirectionType } from '../config-provider';
|
import { ConfigContext, DirectionType } from '../config-provider';
|
||||||
@ -23,6 +22,9 @@ type getContainerFunc = () => HTMLElement;
|
|||||||
const PlacementTypes = tuple('top', 'right', 'bottom', 'left');
|
const PlacementTypes = tuple('top', 'right', 'bottom', 'left');
|
||||||
type placementType = typeof PlacementTypes[number];
|
type placementType = typeof PlacementTypes[number];
|
||||||
|
|
||||||
|
const SizeTypes = tuple('default', 'large');
|
||||||
|
type sizeType = typeof SizeTypes[number];
|
||||||
|
|
||||||
export interface PushState {
|
export interface PushState {
|
||||||
distance: string | number;
|
distance: string | number;
|
||||||
}
|
}
|
||||||
@ -36,6 +38,7 @@ export interface DrawerProps {
|
|||||||
mask?: boolean;
|
mask?: boolean;
|
||||||
maskStyle?: React.CSSProperties;
|
maskStyle?: React.CSSProperties;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
|
size?: sizeType;
|
||||||
/** Wrapper dom node style of header and body */
|
/** Wrapper dom node style of header and body */
|
||||||
drawerStyle?: React.CSSProperties;
|
drawerStyle?: React.CSSProperties;
|
||||||
headerStyle?: React.CSSProperties;
|
headerStyle?: React.CSSProperties;
|
||||||
@ -54,6 +57,7 @@ export interface DrawerProps {
|
|||||||
className?: string;
|
className?: string;
|
||||||
handler?: React.ReactNode;
|
handler?: React.ReactNode;
|
||||||
keyboard?: boolean;
|
keyboard?: boolean;
|
||||||
|
extra?: React.ReactNode;
|
||||||
footer?: React.ReactNode;
|
footer?: React.ReactNode;
|
||||||
footerStyle?: React.CSSProperties;
|
footerStyle?: React.CSSProperties;
|
||||||
level?: string | string[] | null | undefined;
|
level?: string | string[] | null | undefined;
|
||||||
@ -72,8 +76,9 @@ const defaultPushState: PushState = { distance: 180 };
|
|||||||
const Drawer = React.forwardRef<DrawerRef, InternalDrawerProps>(
|
const Drawer = React.forwardRef<DrawerRef, InternalDrawerProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
width = 256,
|
width,
|
||||||
height = 256,
|
height,
|
||||||
|
size = 'default',
|
||||||
closable = true,
|
closable = true,
|
||||||
placement = 'right' as placementType,
|
placement = 'right' as placementType,
|
||||||
maskClosable = true,
|
maskClosable = true,
|
||||||
@ -97,6 +102,7 @@ const Drawer = React.forwardRef<DrawerRef, InternalDrawerProps>(
|
|||||||
onClose,
|
onClose,
|
||||||
footer,
|
footer,
|
||||||
footerStyle,
|
footerStyle,
|
||||||
|
extra,
|
||||||
...rest
|
...rest
|
||||||
},
|
},
|
||||||
ref,
|
ref,
|
||||||
@ -168,9 +174,11 @@ const Drawer = React.forwardRef<DrawerRef, InternalDrawerProps>(
|
|||||||
}
|
}
|
||||||
const offsetStyle: any = {};
|
const offsetStyle: any = {};
|
||||||
if (placement === 'left' || placement === 'right') {
|
if (placement === 'left' || placement === 'right') {
|
||||||
offsetStyle.width = width;
|
const defaultWidth = size === 'large' ? 736 : 378;
|
||||||
|
offsetStyle.width = typeof width === 'undefined' ? defaultWidth : width;
|
||||||
} else {
|
} else {
|
||||||
offsetStyle.height = height;
|
const defaultHeight = size === 'large' ? 736 : 378;
|
||||||
|
offsetStyle.height = typeof height === 'undefined' ? defaultHeight : height;
|
||||||
}
|
}
|
||||||
return offsetStyle;
|
return offsetStyle;
|
||||||
};
|
};
|
||||||
@ -205,36 +213,29 @@ const Drawer = React.forwardRef<DrawerRef, InternalDrawerProps>(
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function renderCloseIcon() {
|
const closeIconNode = closable && (
|
||||||
return (
|
<button type="button" onClick={onClose} aria-label="Close" className={`${prefixCls}-close`}>
|
||||||
closable && (
|
{closeIcon}
|
||||||
<button
|
</button>
|
||||||
type="button"
|
);
|
||||||
onClick={onClose}
|
|
||||||
aria-label="Close"
|
|
||||||
className={`${prefixCls}-close`}
|
|
||||||
style={
|
|
||||||
{
|
|
||||||
'--scroll-bar': `${getScrollBarSize()}px`,
|
|
||||||
} as any
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{closeIcon}
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderHeader() {
|
function renderHeader() {
|
||||||
if (!title && !closable) {
|
if (!title && !closable) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const headerClassName = title ? `${prefixCls}-header` : `${prefixCls}-header-no-title`;
|
|
||||||
return (
|
return (
|
||||||
<div className={headerClassName} style={headerStyle}>
|
<div
|
||||||
{title && <div className={`${prefixCls}-title`}>{title}</div>}
|
className={classNames(`${prefixCls}-header`, {
|
||||||
{closable && renderCloseIcon()}
|
[`${prefixCls}-header-close-only`]: closable && !title && !extra,
|
||||||
|
})}
|
||||||
|
style={headerStyle}
|
||||||
|
>
|
||||||
|
<div className={`${prefixCls}-header-title`}>
|
||||||
|
{closeIconNode}
|
||||||
|
{title && <div className={`${prefixCls}-title`}>{title}</div>}
|
||||||
|
</div>
|
||||||
|
{extra && <div className={`${prefixCls}-extra`}>{extra}</div>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/7z8NJQhFb/Drawer.svg
|
|||||||
| contentWrapperStyle | 可用于设置 Drawer 包裹内容部分的样式 | CSSProperties | - | |
|
| contentWrapperStyle | 可用于设置 Drawer 包裹内容部分的样式 | CSSProperties | - | |
|
||||||
| destroyOnClose | 关闭时销毁 Drawer 里的子元素 | boolean | false | |
|
| destroyOnClose | 关闭时销毁 Drawer 里的子元素 | boolean | false | |
|
||||||
| drawerStyle | 用于设置 Drawer 弹出层的样式 | CSSProperties | - | |
|
| drawerStyle | 用于设置 Drawer 弹出层的样式 | CSSProperties | - | |
|
||||||
|
| extra | 抽屉右上角的操作区域 | ReactNode | - | 4.17.0 |
|
||||||
| footer | 抽屉的页脚 | ReactNode | - | |
|
| footer | 抽屉的页脚 | ReactNode | - | |
|
||||||
| footerStyle | 抽屉页脚部件的样式 | CSSProperties | - | |
|
| footerStyle | 抽屉页脚部件的样式 | CSSProperties | - | |
|
||||||
| forceRender | 预渲染 Drawer 内元素 | boolean | false | |
|
| forceRender | 预渲染 Drawer 内元素 | boolean | false | |
|
||||||
@ -39,9 +40,10 @@ cover: https://gw.alipayobjects.com/zos/alicdn/7z8NJQhFb/Drawer.svg
|
|||||||
| maskStyle | 遮罩样式 | CSSProperties | {} | |
|
| maskStyle | 遮罩样式 | CSSProperties | {} | |
|
||||||
| placement | 抽屉的方向 | `top` \| `right` \| `bottom` \| `left` | `right` | |
|
| placement | 抽屉的方向 | `top` \| `right` \| `bottom` \| `left` | `right` | |
|
||||||
| push | 用于设置多层 Drawer 的推动行为 | boolean \| { distance: string \| number } | { distance: 180 } | 4.5.0+ |
|
| push | 用于设置多层 Drawer 的推动行为 | boolean \| { distance: string \| number } | { distance: 180 } | 4.5.0+ |
|
||||||
|
| size | 预设抽屉宽度(或高度),default `378px` 和 large `736px` | 'default' \| 'large' | 'default' | 4.17.0 |
|
||||||
| style | 可用于设置 Drawer 最外层容器的样式,和 `drawerStyle` 的区别是作用节点包括 `mask` | CSSProperties | - | |
|
| style | 可用于设置 Drawer 最外层容器的样式,和 `drawerStyle` 的区别是作用节点包括 `mask` | CSSProperties | - | |
|
||||||
| title | 标题 | ReactNode | - | |
|
| title | 标题 | ReactNode | - | |
|
||||||
| visible | Drawer 是否可见 | boolean | - | |
|
| visible | Drawer 是否可见 | boolean | - | |
|
||||||
| width | 宽度 | string \| number | 256 | |
|
| width | 宽度 | string \| number | 378 | |
|
||||||
| zIndex | 设置 Drawer 的 `z-index` | number | 1000 | |
|
| zIndex | 设置 Drawer 的 `z-index` | number | 1000 | |
|
||||||
| onClose | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | - | |
|
| onClose | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | - | |
|
||||||
|
@ -148,12 +148,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-close {
|
&-close {
|
||||||
position: absolute;
|
display: inline-block;
|
||||||
top: 0;
|
margin-right: 12px;
|
||||||
right: 0;
|
|
||||||
z-index: @zindex-popup-close;
|
|
||||||
display: block;
|
|
||||||
padding: @drawer-header-close-padding;
|
|
||||||
color: @modal-close-color;
|
color: @modal-close-color;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: @font-size-lg;
|
font-size: @font-size-lg;
|
||||||
@ -174,26 +170,29 @@
|
|||||||
color: @icon-color-hover;
|
color: @icon-color-hover;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.@{drawer-prefix-cls}-header-no-title & {
|
|
||||||
margin-right: var(--scroll-bar);
|
|
||||||
/* stylelint-disable-next-line function-calc-no-invalid */
|
|
||||||
padding-right: ~'calc(@{drawer-header-close-padding} - var(--scroll-bar))';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-header {
|
&-header {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
padding: @drawer-header-padding;
|
padding: @drawer-header-padding;
|
||||||
color: @text-color;
|
color: @text-color;
|
||||||
background: @drawer-bg;
|
background: @drawer-bg;
|
||||||
border-bottom: @border-width-base @border-style-base @border-color-split;
|
border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||||
border-radius: @border-radius-base @border-radius-base 0 0;
|
border-radius: @border-radius-base @border-radius-base 0 0;
|
||||||
}
|
|
||||||
|
|
||||||
&-header-no-title {
|
&-title {
|
||||||
color: @text-color;
|
display: flex;
|
||||||
background: @drawer-bg;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-close-only {
|
||||||
|
padding-bottom: 0;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-wrapper-body {
|
&-wrapper-body {
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
&-close {
|
&-close {
|
||||||
.@{drawer-prefix-cls}-rtl & {
|
.@{drawer-prefix-cls}-rtl & {
|
||||||
right: auto;
|
margin-right: 0;
|
||||||
left: 0;
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,95 +1,117 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import CSSMotion from 'rc-motion';
|
import CSSMotion, { CSSMotionList } from 'rc-motion';
|
||||||
import useMemo from 'rc-util/lib/hooks/useMemo';
|
|
||||||
import useCacheErrors from './hooks/useCacheErrors';
|
|
||||||
import useForceUpdate from '../_util/hooks/useForceUpdate';
|
|
||||||
import { FormItemPrefixContext } from './context';
|
import { FormItemPrefixContext } from './context';
|
||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
|
import { ValidateStatus } from './FormItem';
|
||||||
|
import collapseMotion from '../_util/motion';
|
||||||
|
|
||||||
const EMPTY_LIST: React.ReactNode[] = [];
|
const EMPTY_LIST: React.ReactNode[] = [];
|
||||||
|
|
||||||
|
interface ErrorEntity {
|
||||||
|
error: React.ReactNode;
|
||||||
|
errorStatus?: ValidateStatus;
|
||||||
|
key: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toErrorEntity(
|
||||||
|
error: React.ReactNode,
|
||||||
|
errorStatus: ValidateStatus | undefined,
|
||||||
|
prefix: string,
|
||||||
|
index: number = 0,
|
||||||
|
): ErrorEntity {
|
||||||
|
return {
|
||||||
|
key: typeof error === 'string' ? error : `${prefix}-${index}`,
|
||||||
|
error,
|
||||||
|
errorStatus,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface ErrorListProps {
|
export interface ErrorListProps {
|
||||||
errors?: React.ReactNode[];
|
|
||||||
/** @private Internal Usage. Do not use in your production */
|
|
||||||
help?: React.ReactNode;
|
help?: React.ReactNode;
|
||||||
/** @private Internal Usage. Do not use in your production */
|
helpStatus?: ValidateStatus;
|
||||||
onDomErrorVisibleChange?: (visible: boolean) => void;
|
errors?: React.ReactNode[];
|
||||||
|
warnings?: React.ReactNode[];
|
||||||
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ErrorList({
|
export default function ErrorList({
|
||||||
errors = EMPTY_LIST,
|
|
||||||
help,
|
help,
|
||||||
onDomErrorVisibleChange,
|
helpStatus,
|
||||||
|
errors = EMPTY_LIST,
|
||||||
|
warnings = EMPTY_LIST,
|
||||||
|
className: rootClassName,
|
||||||
}: ErrorListProps) {
|
}: ErrorListProps) {
|
||||||
const forceUpdate = useForceUpdate();
|
const { prefixCls } = React.useContext(FormItemPrefixContext);
|
||||||
const { prefixCls, status } = React.useContext(FormItemPrefixContext);
|
|
||||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||||
|
|
||||||
const [visible, cacheErrors] = useCacheErrors(
|
|
||||||
errors,
|
|
||||||
changedVisible => {
|
|
||||||
if (changedVisible) {
|
|
||||||
/**
|
|
||||||
* We trigger in sync to avoid dom shaking but this get warning in react 16.13.
|
|
||||||
*
|
|
||||||
* So use Promise to keep in micro async to handle this.
|
|
||||||
* https://github.com/ant-design/ant-design/issues/21698#issuecomment-593743485
|
|
||||||
*/
|
|
||||||
Promise.resolve().then(() => {
|
|
||||||
onDomErrorVisibleChange?.(true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
forceUpdate();
|
|
||||||
},
|
|
||||||
!!help,
|
|
||||||
);
|
|
||||||
|
|
||||||
const memoErrors = useMemo(
|
|
||||||
() => cacheErrors,
|
|
||||||
visible,
|
|
||||||
(_, nextVisible) => nextVisible,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Memo status in same visible
|
|
||||||
const [innerStatus, setInnerStatus] = React.useState(status);
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (visible && status) {
|
|
||||||
setInnerStatus(status);
|
|
||||||
}
|
|
||||||
}, [visible, status]);
|
|
||||||
|
|
||||||
const baseClassName = `${prefixCls}-item-explain`;
|
const baseClassName = `${prefixCls}-item-explain`;
|
||||||
const rootPrefixCls = getPrefixCls();
|
const rootPrefixCls = getPrefixCls();
|
||||||
|
|
||||||
|
const fullKeyList = React.useMemo(() => {
|
||||||
|
if (help !== undefined && help !== null) {
|
||||||
|
return [toErrorEntity(help, helpStatus, 'help')];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
...errors.map((error, index) => toErrorEntity(error, 'error', 'error', index)),
|
||||||
|
...warnings.map((warning, index) => toErrorEntity(warning, 'warning', 'warning', index)),
|
||||||
|
];
|
||||||
|
}, [help, helpStatus, errors, warnings]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CSSMotion
|
<CSSMotion
|
||||||
motionDeadline={500}
|
{...collapseMotion}
|
||||||
visible={visible}
|
|
||||||
motionName={`${rootPrefixCls}-show-help`}
|
motionName={`${rootPrefixCls}-show-help`}
|
||||||
onLeaveEnd={() => {
|
motionAppear={false}
|
||||||
onDomErrorVisibleChange?.(false);
|
motionEnter={false}
|
||||||
|
visible={!!fullKeyList.length}
|
||||||
|
onLeaveStart={node => {
|
||||||
|
// Force disable css override style in index.less configured
|
||||||
|
node.style.height = 'auto';
|
||||||
|
return { height: node.offsetHeight };
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ className: motionClassName }: { className?: string }) => (
|
{holderProps => {
|
||||||
<div
|
const { className: holderClassName, style: holderStyle } = holderProps;
|
||||||
className={classNames(
|
|
||||||
baseClassName,
|
return (
|
||||||
{
|
<div
|
||||||
[`${baseClassName}-${innerStatus}`]: innerStatus,
|
className={classNames(baseClassName, holderClassName, rootClassName)}
|
||||||
},
|
style={holderStyle}
|
||||||
motionClassName,
|
>
|
||||||
)}
|
<CSSMotionList
|
||||||
key="help"
|
keys={fullKeyList}
|
||||||
>
|
{...collapseMotion}
|
||||||
{memoErrors.map((error, index) => (
|
motionName={`${rootPrefixCls}-show-help-item`}
|
||||||
// eslint-disable-next-line react/no-array-index-key
|
component={false}
|
||||||
<div key={index} role="alert">
|
>
|
||||||
{error}
|
{itemProps => {
|
||||||
</div>
|
const {
|
||||||
))}
|
key,
|
||||||
</div>
|
error,
|
||||||
)}
|
errorStatus,
|
||||||
|
className: itemClassName,
|
||||||
|
style: itemStyle,
|
||||||
|
} = itemProps;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={key}
|
||||||
|
role="alert"
|
||||||
|
className={classNames(itemClassName, {
|
||||||
|
[`${baseClassName}-${errorStatus}`]: errorStatus,
|
||||||
|
})}
|
||||||
|
style={itemStyle}
|
||||||
|
>
|
||||||
|
{error}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</CSSMotionList>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
</CSSMotion>
|
</CSSMotion>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useContext, useRef } from 'react';
|
import { useContext } from 'react';
|
||||||
import isEqual from 'lodash/isEqual';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Field, FormInstance } from 'rc-field-form';
|
import { Field, FormInstance } from 'rc-field-form';
|
||||||
import { FieldProps } from 'rc-field-form/lib/Field';
|
import { FieldProps } from 'rc-field-form/lib/Field';
|
||||||
@ -14,14 +13,20 @@ import { tuple } from '../_util/type';
|
|||||||
import devWarning from '../_util/devWarning';
|
import devWarning from '../_util/devWarning';
|
||||||
import FormItemLabel, { FormItemLabelProps, LabelTooltipType } from './FormItemLabel';
|
import FormItemLabel, { FormItemLabelProps, LabelTooltipType } from './FormItemLabel';
|
||||||
import FormItemInput, { FormItemInputProps } from './FormItemInput';
|
import FormItemInput, { FormItemInputProps } from './FormItemInput';
|
||||||
import { FormContext, FormItemContext } from './context';
|
import { FormContext, NoStyleItemContext } from './context';
|
||||||
import { toArray, getFieldId } from './util';
|
import { toArray, getFieldId } from './util';
|
||||||
import { cloneElement, isValidElement } from '../_util/reactNode';
|
import { cloneElement, isValidElement } from '../_util/reactNode';
|
||||||
import useFrameState from './hooks/useFrameState';
|
import useFrameState from './hooks/useFrameState';
|
||||||
|
import useDebounce from './hooks/useDebounce';
|
||||||
import useItemRef from './hooks/useItemRef';
|
import useItemRef from './hooks/useItemRef';
|
||||||
|
|
||||||
const NAME_SPLIT = '__SPLIT__';
|
const NAME_SPLIT = '__SPLIT__';
|
||||||
|
|
||||||
|
interface FieldError {
|
||||||
|
errors: string[];
|
||||||
|
warnings: string[];
|
||||||
|
}
|
||||||
|
|
||||||
const ValidateStatuses = tuple('success', 'warning', 'error', 'validating', '');
|
const ValidateStatuses = tuple('success', 'warning', 'error', 'validating', '');
|
||||||
export type ValidateStatus = typeof ValidateStatuses[number];
|
export type ValidateStatus = typeof ValidateStatuses[number];
|
||||||
|
|
||||||
@ -31,7 +36,7 @@ type ChildrenType<Values = any> = RenderChildren<Values> | React.ReactNode;
|
|||||||
|
|
||||||
interface MemoInputProps {
|
interface MemoInputProps {
|
||||||
value: any;
|
value: any;
|
||||||
update: number;
|
update: any;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +73,16 @@ function hasValidName(name?: NamePath): Boolean {
|
|||||||
return !(name === undefined || name === null);
|
return !(name === undefined || name === null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function genEmptyMeta(): Meta {
|
||||||
|
return {
|
||||||
|
errors: [],
|
||||||
|
warnings: [],
|
||||||
|
touched: false,
|
||||||
|
validating: false,
|
||||||
|
name: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function FormItem<Values = any>(props: FormItemProps<Values>): React.ReactElement {
|
function FormItem<Values = any>(props: FormItemProps<Values>): React.ReactElement {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
@ -91,104 +106,109 @@ function FormItem<Values = any>(props: FormItemProps<Values>): React.ReactElemen
|
|||||||
hidden,
|
hidden,
|
||||||
...restProps
|
...restProps
|
||||||
} = props;
|
} = props;
|
||||||
const destroyRef = useRef(false);
|
|
||||||
const { getPrefixCls } = useContext(ConfigContext);
|
const { getPrefixCls } = useContext(ConfigContext);
|
||||||
const { name: formName, requiredMark } = useContext(FormContext);
|
const { name: formName, requiredMark } = useContext(FormContext);
|
||||||
const { updateItemErrors } = useContext(FormItemContext);
|
const isRenderProps = typeof children === 'function';
|
||||||
const [domErrorVisible, innerSetDomErrorVisible] = React.useState(!!help);
|
const notifyParentMetaChange = useContext(NoStyleItemContext);
|
||||||
const [inlineErrors, setInlineErrors] = useFrameState<Record<string, string[]>>({});
|
|
||||||
|
|
||||||
const { validateTrigger: contextValidateTrigger } = useContext(FieldContext);
|
const { validateTrigger: contextValidateTrigger } = useContext(FieldContext);
|
||||||
const mergedValidateTrigger =
|
const mergedValidateTrigger =
|
||||||
validateTrigger !== undefined ? validateTrigger : contextValidateTrigger;
|
validateTrigger !== undefined ? validateTrigger : contextValidateTrigger;
|
||||||
|
|
||||||
const setDomErrorVisible = (visible: boolean) => {
|
|
||||||
if (!destroyRef.current) {
|
|
||||||
innerSetDomErrorVisible(visible);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const hasName = hasValidName(name);
|
const hasName = hasValidName(name);
|
||||||
|
|
||||||
// Cache Field NamePath
|
|
||||||
const nameRef = useRef<(string | number)[]>([]);
|
|
||||||
|
|
||||||
// Should clean up if Field removed
|
|
||||||
React.useEffect(
|
|
||||||
() => () => {
|
|
||||||
destroyRef.current = true;
|
|
||||||
updateItemErrors(nameRef.current.join(NAME_SPLIT), []);
|
|
||||||
},
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
|
|
||||||
const prefixCls = getPrefixCls('form', customizePrefixCls);
|
const prefixCls = getPrefixCls('form', customizePrefixCls);
|
||||||
|
|
||||||
// ======================== Errors ========================
|
// ======================== Errors ========================
|
||||||
// Collect noStyle Field error to the top FormItem
|
// >>>>> Collect sub field errors
|
||||||
const updateChildItemErrors = noStyle
|
const [subFieldErrors, setSubFieldErrors] = useFrameState<Record<string, FieldError>>({});
|
||||||
? updateItemErrors
|
|
||||||
: (subName: string, subErrors: string[], originSubName?: string) => {
|
|
||||||
setInlineErrors((prevInlineErrors = {}) => {
|
|
||||||
// Clean up origin error when name changed
|
|
||||||
if (originSubName && originSubName !== subName) {
|
|
||||||
delete prevInlineErrors[originSubName];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isEqual(prevInlineErrors[subName], subErrors)) {
|
// >>>>> Current field errors
|
||||||
return {
|
const [meta, setMeta] = React.useState<Meta>(() => genEmptyMeta());
|
||||||
...prevInlineErrors,
|
|
||||||
[subName]: subErrors,
|
const onMetaChange = (nextMeta: Meta & { destroy?: boolean }) => {
|
||||||
};
|
// Destroy will reset all the meta
|
||||||
}
|
setMeta(nextMeta.destroy ? genEmptyMeta() : nextMeta);
|
||||||
return prevInlineErrors;
|
|
||||||
});
|
// Bump to parent since noStyle
|
||||||
|
if (noStyle && notifyParentMetaChange) {
|
||||||
|
let namePath = nextMeta.name;
|
||||||
|
if (fieldKey !== undefined) {
|
||||||
|
namePath = Array.isArray(fieldKey) ? fieldKey : [fieldKey!];
|
||||||
|
}
|
||||||
|
notifyParentMetaChange(nextMeta, namePath);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// >>>>> Collect noStyle Field error to the top FormItem
|
||||||
|
const onSubItemMetaChange = (subMeta: Meta & { destroy: boolean }, uniqueKeys: React.Key[]) => {
|
||||||
|
// Only `noStyle` sub item will trigger
|
||||||
|
setSubFieldErrors(prevSubFieldErrors => {
|
||||||
|
const clone = {
|
||||||
|
...prevSubFieldErrors,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// name: ['user', 1] + key: [4] = ['user', 4]
|
||||||
|
const mergedNamePath = [...subMeta.name.slice(0, -1), ...uniqueKeys];
|
||||||
|
const mergedNameKey = mergedNamePath.join(NAME_SPLIT);
|
||||||
|
|
||||||
|
if (subMeta.destroy) {
|
||||||
|
// Remove
|
||||||
|
delete clone[mergedNameKey];
|
||||||
|
} else {
|
||||||
|
// Update
|
||||||
|
clone[mergedNameKey] = subMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// >>>>> Get merged errors
|
||||||
|
const [mergedErrors, mergedWarnings] = React.useMemo(() => {
|
||||||
|
const errorList: string[] = [...meta.errors];
|
||||||
|
const warningList: string[] = [...meta.warnings];
|
||||||
|
|
||||||
|
Object.values(subFieldErrors).forEach(subFieldError => {
|
||||||
|
errorList.push(...(subFieldError.errors || []));
|
||||||
|
warningList.push(...(subFieldError.warnings || []));
|
||||||
|
});
|
||||||
|
|
||||||
|
return [errorList, warningList];
|
||||||
|
}, [subFieldErrors, meta.errors, meta.warnings]);
|
||||||
|
|
||||||
|
const debounceErrors = useDebounce(mergedErrors);
|
||||||
|
const debounceWarnings = useDebounce(mergedWarnings);
|
||||||
|
|
||||||
// ===================== Children Ref =====================
|
// ===================== Children Ref =====================
|
||||||
const getItemRef = useItemRef();
|
const getItemRef = useItemRef();
|
||||||
|
|
||||||
|
// ======================== Render ========================
|
||||||
function renderLayout(
|
function renderLayout(
|
||||||
baseChildren: React.ReactNode,
|
baseChildren: React.ReactNode,
|
||||||
fieldId?: string,
|
fieldId?: string,
|
||||||
meta?: Meta,
|
|
||||||
isRequired?: boolean,
|
isRequired?: boolean,
|
||||||
): React.ReactNode {
|
): React.ReactNode {
|
||||||
if (noStyle && !hidden) {
|
if (noStyle && !hidden) {
|
||||||
return baseChildren;
|
return baseChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======================== Errors ========================
|
|
||||||
// >>> collect sub errors
|
|
||||||
let subErrorList: string[] = [];
|
|
||||||
Object.keys(inlineErrors).forEach(subName => {
|
|
||||||
subErrorList = [...subErrorList, ...(inlineErrors[subName] || [])];
|
|
||||||
});
|
|
||||||
|
|
||||||
// >>> merged errors
|
|
||||||
let mergedErrors: React.ReactNode[];
|
|
||||||
if (help !== undefined && help !== null) {
|
|
||||||
mergedErrors = toArray(help);
|
|
||||||
} else {
|
|
||||||
mergedErrors = meta ? meta.errors : [];
|
|
||||||
mergedErrors = [...mergedErrors, ...subErrorList];
|
|
||||||
}
|
|
||||||
|
|
||||||
// ======================== Status ========================
|
// ======================== Status ========================
|
||||||
let mergedValidateStatus: ValidateStatus = '';
|
let mergedValidateStatus: ValidateStatus = '';
|
||||||
if (validateStatus !== undefined) {
|
if (validateStatus !== undefined) {
|
||||||
mergedValidateStatus = validateStatus;
|
mergedValidateStatus = validateStatus;
|
||||||
} else if (meta?.validating) {
|
} else if (meta?.validating) {
|
||||||
mergedValidateStatus = 'validating';
|
mergedValidateStatus = 'validating';
|
||||||
} else if (meta?.errors?.length || subErrorList.length) {
|
} else if (debounceErrors.length) {
|
||||||
mergedValidateStatus = 'error';
|
mergedValidateStatus = 'error';
|
||||||
|
} else if (debounceWarnings.length) {
|
||||||
|
mergedValidateStatus = 'warning';
|
||||||
} else if (meta?.touched) {
|
} else if (meta?.touched) {
|
||||||
mergedValidateStatus = 'success';
|
mergedValidateStatus = 'success';
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemClassName = {
|
const itemClassName = {
|
||||||
[`${prefixCls}-item`]: true,
|
[`${prefixCls}-item`]: true,
|
||||||
[`${prefixCls}-item-with-help`]: domErrorVisible || !!help,
|
[`${prefixCls}-item-with-help`]: help || debounceErrors.length || debounceWarnings.length,
|
||||||
[`${className}`]: !!className,
|
[`${className}`]: !!className,
|
||||||
|
|
||||||
// Status
|
// Status
|
||||||
@ -238,26 +258,21 @@ function FormItem<Values = any>(props: FormItemProps<Values>): React.ReactElemen
|
|||||||
<FormItemInput
|
<FormItemInput
|
||||||
{...props}
|
{...props}
|
||||||
{...meta}
|
{...meta}
|
||||||
errors={mergedErrors}
|
errors={debounceErrors}
|
||||||
|
warnings={debounceWarnings}
|
||||||
prefixCls={prefixCls}
|
prefixCls={prefixCls}
|
||||||
status={mergedValidateStatus}
|
status={mergedValidateStatus}
|
||||||
onDomErrorVisibleChange={setDomErrorVisible}
|
|
||||||
validateStatus={mergedValidateStatus}
|
validateStatus={mergedValidateStatus}
|
||||||
|
help={help}
|
||||||
>
|
>
|
||||||
<FormItemContext.Provider value={{ updateItemErrors: updateChildItemErrors }}>
|
<NoStyleItemContext.Provider value={onSubItemMetaChange}>
|
||||||
{baseChildren}
|
{baseChildren}
|
||||||
</FormItemContext.Provider>
|
</NoStyleItemContext.Provider>
|
||||||
</FormItemInput>
|
</FormItemInput>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isRenderProps = typeof children === 'function';
|
|
||||||
|
|
||||||
// Record for real component render
|
|
||||||
const updateRef = useRef(0);
|
|
||||||
updateRef.current += 1;
|
|
||||||
|
|
||||||
if (!hasName && !isRenderProps && !dependencies) {
|
if (!hasName && !isRenderProps && !dependencies) {
|
||||||
return renderLayout(children) as JSX.Element;
|
return renderLayout(children) as JSX.Element;
|
||||||
}
|
}
|
||||||
@ -272,46 +287,31 @@ function FormItem<Values = any>(props: FormItemProps<Values>): React.ReactElemen
|
|||||||
variables = { ...variables, ...messageVariables };
|
variables = { ...variables, ...messageVariables };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// >>>>> With Field
|
||||||
return (
|
return (
|
||||||
<Field
|
<Field
|
||||||
{...props}
|
{...props}
|
||||||
messageVariables={variables}
|
messageVariables={variables}
|
||||||
trigger={trigger}
|
trigger={trigger}
|
||||||
validateTrigger={mergedValidateTrigger}
|
validateTrigger={mergedValidateTrigger}
|
||||||
onReset={() => {
|
onMetaChange={onMetaChange}
|
||||||
setDomErrorVisible(false);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{(control, meta, context) => {
|
{(control, renderMeta, context) => {
|
||||||
const { errors } = meta;
|
const mergedName = toArray(name).length && renderMeta ? renderMeta.name : [];
|
||||||
|
|
||||||
const mergedName = toArray(name).length && meta ? meta.name : [];
|
|
||||||
const fieldId = getFieldId(mergedName, formName);
|
const fieldId = getFieldId(mergedName, formName);
|
||||||
|
|
||||||
if (noStyle) {
|
|
||||||
// Clean up origin one
|
|
||||||
const originErrorName = nameRef.current.join(NAME_SPLIT);
|
|
||||||
|
|
||||||
nameRef.current = [...mergedName];
|
|
||||||
if (fieldKey) {
|
|
||||||
const fieldKeys = Array.isArray(fieldKey) ? fieldKey : [fieldKey];
|
|
||||||
nameRef.current = [...mergedName.slice(0, -1), ...fieldKeys];
|
|
||||||
}
|
|
||||||
updateItemErrors(nameRef.current.join(NAME_SPLIT), errors, originErrorName);
|
|
||||||
}
|
|
||||||
|
|
||||||
const isRequired =
|
const isRequired =
|
||||||
required !== undefined
|
required !== undefined
|
||||||
? required
|
? required
|
||||||
: !!(
|
: !!(
|
||||||
rules &&
|
rules &&
|
||||||
rules.some(rule => {
|
rules.some(rule => {
|
||||||
if (rule && typeof rule === 'object' && rule.required) {
|
if (rule && typeof rule === 'object' && rule.required && !rule.warningOnly) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (typeof rule === 'function') {
|
if (typeof rule === 'function') {
|
||||||
const ruleEntity = rule(context);
|
const ruleEntity = rule(context);
|
||||||
return ruleEntity && ruleEntity.required;
|
return ruleEntity && ruleEntity.required && !ruleEntity.warningOnly;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
})
|
})
|
||||||
@ -379,10 +379,7 @@ function FormItem<Values = any>(props: FormItemProps<Values>): React.ReactElemen
|
|||||||
});
|
});
|
||||||
|
|
||||||
childNode = (
|
childNode = (
|
||||||
<MemoInput
|
<MemoInput value={mergedControl[props.valuePropName || 'value']} update={children}>
|
||||||
value={mergedControl[props.valuePropName || 'value']}
|
|
||||||
update={updateRef.current}
|
|
||||||
>
|
|
||||||
{cloneElement(children, childProps)}
|
{cloneElement(children, childProps)}
|
||||||
</MemoInput>
|
</MemoInput>
|
||||||
);
|
);
|
||||||
@ -397,7 +394,7 @@ function FormItem<Values = any>(props: FormItemProps<Values>): React.ReactElemen
|
|||||||
childNode = children;
|
childNode = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderLayout(childNode, fieldId, meta, isRequired);
|
return renderLayout(childNode, fieldId, isRequired);
|
||||||
}}
|
}}
|
||||||
</Field>
|
</Field>
|
||||||
);
|
);
|
||||||
|
@ -14,9 +14,9 @@ interface FormItemInputMiscProps {
|
|||||||
prefixCls: string;
|
prefixCls: string;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
errors: React.ReactNode[];
|
errors: React.ReactNode[];
|
||||||
|
warnings: React.ReactNode[];
|
||||||
hasFeedback?: boolean;
|
hasFeedback?: boolean;
|
||||||
validateStatus?: ValidateStatus;
|
validateStatus?: ValidateStatus;
|
||||||
onDomErrorVisibleChange: (visible: boolean) => void;
|
|
||||||
/** @private Internal Usage, do not use in any of your production. */
|
/** @private Internal Usage, do not use in any of your production. */
|
||||||
_internalItemRender?: {
|
_internalItemRender?: {
|
||||||
mark: string;
|
mark: string;
|
||||||
@ -33,9 +33,9 @@ interface FormItemInputMiscProps {
|
|||||||
|
|
||||||
export interface FormItemInputProps {
|
export interface FormItemInputProps {
|
||||||
wrapperCol?: ColProps;
|
wrapperCol?: ColProps;
|
||||||
help?: React.ReactNode;
|
|
||||||
extra?: React.ReactNode;
|
extra?: React.ReactNode;
|
||||||
status?: ValidateStatus;
|
status?: ValidateStatus;
|
||||||
|
help?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconMap: { [key: string]: any } = {
|
const iconMap: { [key: string]: any } = {
|
||||||
@ -51,13 +51,13 @@ const FormItemInput: React.FC<FormItemInputProps & FormItemInputMiscProps> = pro
|
|||||||
status,
|
status,
|
||||||
wrapperCol,
|
wrapperCol,
|
||||||
children,
|
children,
|
||||||
help,
|
|
||||||
errors,
|
errors,
|
||||||
onDomErrorVisibleChange,
|
warnings,
|
||||||
hasFeedback,
|
hasFeedback,
|
||||||
_internalItemRender: formItemRender,
|
_internalItemRender: formItemRender,
|
||||||
validateStatus,
|
validateStatus,
|
||||||
extra,
|
extra,
|
||||||
|
help,
|
||||||
} = props;
|
} = props;
|
||||||
const baseClassName = `${prefixCls}-item`;
|
const baseClassName = `${prefixCls}-item`;
|
||||||
|
|
||||||
@ -67,13 +67,6 @@ const FormItemInput: React.FC<FormItemInputProps & FormItemInputMiscProps> = pro
|
|||||||
|
|
||||||
const className = classNames(`${baseClassName}-control`, mergedWrapperCol.className);
|
const className = classNames(`${baseClassName}-control`, mergedWrapperCol.className);
|
||||||
|
|
||||||
React.useEffect(
|
|
||||||
() => () => {
|
|
||||||
onDomErrorVisibleChange(false);
|
|
||||||
},
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Should provides additional icon if `hasFeedback`
|
// Should provides additional icon if `hasFeedback`
|
||||||
const IconNode = validateStatus && iconMap[validateStatus];
|
const IconNode = validateStatus && iconMap[validateStatus];
|
||||||
const icon =
|
const icon =
|
||||||
@ -96,7 +89,13 @@ const FormItemInput: React.FC<FormItemInputProps & FormItemInputMiscProps> = pro
|
|||||||
);
|
);
|
||||||
const errorListDom = (
|
const errorListDom = (
|
||||||
<FormItemPrefixContext.Provider value={{ prefixCls, status }}>
|
<FormItemPrefixContext.Provider value={{ prefixCls, status }}>
|
||||||
<ErrorList errors={errors} help={help} onDomErrorVisibleChange={onDomErrorVisibleChange} />
|
<ErrorList
|
||||||
|
errors={errors}
|
||||||
|
warnings={warnings}
|
||||||
|
help={help}
|
||||||
|
helpStatus={status}
|
||||||
|
className={`${baseClassName}-explain-connected`}
|
||||||
|
/>
|
||||||
</FormItemPrefixContext.Provider>
|
</FormItemPrefixContext.Provider>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ export interface FormListProps {
|
|||||||
children: (
|
children: (
|
||||||
fields: FormListFieldData[],
|
fields: FormListFieldData[],
|
||||||
operation: FormListOperation,
|
operation: FormListOperation,
|
||||||
meta: { errors: React.ReactNode[] },
|
meta: { errors: React.ReactNode[]; warnings: React.ReactNode[] },
|
||||||
) => React.ReactNode;
|
) => React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +48,7 @@ const FormList: React.FC<FormListProps> = ({
|
|||||||
operation,
|
operation,
|
||||||
{
|
{
|
||||||
errors: meta.errors,
|
errors: meta.errors,
|
||||||
|
warnings: meta.warnings,
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
</FormItemPrefixContext.Provider>
|
</FormItemPrefixContext.Provider>
|
||||||
|
@ -306,6 +306,7 @@ exports[`renders ./components/form/demo/advanced-search.md correctly 1`] = `
|
|||||||
|
|
||||||
exports[`renders ./components/form/demo/basic.md correctly 1`] = `
|
exports[`renders ./components/form/demo/basic.md correctly 1`] = `
|
||||||
<form
|
<form
|
||||||
|
autocomplete="off"
|
||||||
class="ant-form ant-form-horizontal"
|
class="ant-form ant-form-horizontal"
|
||||||
id="basic"
|
id="basic"
|
||||||
>
|
>
|
||||||
@ -1073,9 +1074,10 @@ exports[`renders ./components/form/demo/disabled-input-debug.md correctly 1`] =
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Buggy!
|
Buggy!
|
||||||
@ -1115,9 +1117,10 @@ exports[`renders ./components/form/demo/disabled-input-debug.md correctly 1`] =
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Buggy!
|
Buggy!
|
||||||
@ -1188,9 +1191,10 @@ exports[`renders ./components/form/demo/disabled-input-debug.md correctly 1`] =
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Buggy!
|
Buggy!
|
||||||
@ -1230,9 +1234,10 @@ exports[`renders ./components/form/demo/disabled-input-debug.md correctly 1`] =
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Buggy!
|
Buggy!
|
||||||
@ -1329,9 +1334,10 @@ exports[`renders ./components/form/demo/disabled-input-debug.md correctly 1`] =
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Buggy!
|
Buggy!
|
||||||
@ -1384,9 +1390,10 @@ exports[`renders ./components/form/demo/disabled-input-debug.md correctly 1`] =
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Buggy!
|
Buggy!
|
||||||
@ -1475,9 +1482,10 @@ exports[`renders ./components/form/demo/disabled-input-debug.md correctly 1`] =
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Buggy!
|
Buggy!
|
||||||
@ -1526,9 +1534,10 @@ exports[`renders ./components/form/demo/disabled-input-debug.md correctly 1`] =
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Buggy!
|
Buggy!
|
||||||
@ -3427,6 +3436,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-cascader-picker-label"
|
class="ant-cascader-picker-label"
|
||||||
|
title="Zhejiang / Hangzhou / West Lake"
|
||||||
>
|
>
|
||||||
Zhejiang / Hangzhou / West Lake
|
Zhejiang / Hangzhou / West Lake
|
||||||
</span>
|
</span>
|
||||||
@ -6591,9 +6601,10 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Should be combination of numbers & alphabets
|
Should be combination of numbers & alphabets
|
||||||
@ -6716,9 +6727,10 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-validating"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-validating"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
The information is being validated...
|
The information is being validated...
|
||||||
@ -6893,9 +6905,10 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Should be combination of numbers & alphabets
|
Should be combination of numbers & alphabets
|
||||||
@ -7273,9 +7286,10 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-validating"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-validating"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
The information is being validated...
|
The information is being validated...
|
||||||
@ -7361,9 +7375,10 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain ant-form-item-explain-error"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class="ant-form-item-explain-error"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
Please select the correct date
|
Please select the correct date
|
||||||
@ -7839,6 +7854,97 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
|
|||||||
</form>
|
</form>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`renders ./components/form/demo/warning-only.md correctly 1`] = `
|
||||||
|
<form
|
||||||
|
autocomplete="off"
|
||||||
|
class="ant-form ant-form-vertical"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="overflow:hidden"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-row ant-form-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-col ant-form-item-label"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="ant-form-item-required"
|
||||||
|
for="url"
|
||||||
|
title="URL"
|
||||||
|
>
|
||||||
|
URL
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-col ant-form-item-control"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-form-item-control-input"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-form-item-control-input-content"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="ant-input"
|
||||||
|
id="url"
|
||||||
|
placeholder="input placeholder"
|
||||||
|
type="text"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-row ant-form-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-col ant-form-item-control"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-form-item-control-input"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-form-item-control-input-content"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="margin-right:8px"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-btn-primary"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Submit
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="ant-btn"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Fill
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/form/demo/without-form-create.md correctly 1`] = `
|
exports[`renders ./components/form/demo/without-form-create.md correctly 1`] = `
|
||||||
<form
|
<form
|
||||||
class="ant-form ant-form-horizontal"
|
class="ant-form ant-form-horizontal"
|
||||||
@ -7944,9 +8050,10 @@ exports[`renders ./components/form/demo/without-form-create.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-form-item-explain"
|
class="ant-form-item-explain ant-form-item-explain-connected"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
class=""
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
A prime is a natural number greater than 1 that has no positive divisors other than 1 and itself.
|
A prime is a natural number greater than 1 that has no positive divisors other than 1 and itself.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
import scrollIntoView from 'scroll-into-view-if-needed';
|
import scrollIntoView from 'scroll-into-view-if-needed';
|
||||||
import Form from '..';
|
import Form from '..';
|
||||||
import Input from '../../input';
|
import Input from '../../input';
|
||||||
@ -20,10 +21,17 @@ describe('Form', () => {
|
|||||||
scrollIntoView.mockImplementation(() => {});
|
scrollIntoView.mockImplementation(() => {});
|
||||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
async function change(wrapper, index, value) {
|
async function change(wrapper, index, value, executeMockTimer) {
|
||||||
wrapper.find(Input).at(index).simulate('change', { target: { value } });
|
wrapper.find(Input).at(index).simulate('change', { target: { value } });
|
||||||
await sleep(200);
|
await sleep(200);
|
||||||
wrapper.update();
|
|
||||||
|
if (executeMockTimer) {
|
||||||
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
wrapper.update();
|
||||||
|
});
|
||||||
|
await sleep(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -42,6 +50,8 @@ describe('Form', () => {
|
|||||||
|
|
||||||
describe('noStyle Form.Item', () => {
|
describe('noStyle Form.Item', () => {
|
||||||
it('work', async () => {
|
it('work', async () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
|
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
@ -54,14 +64,18 @@ describe('Form', () => {
|
|||||||
</Form>,
|
</Form>,
|
||||||
);
|
);
|
||||||
|
|
||||||
await change(wrapper, 0, '');
|
await change(wrapper, 0, '', true);
|
||||||
expect(wrapper.find('.ant-form-item-with-help').length).toBeTruthy();
|
expect(wrapper.find('.ant-form-item-with-help').length).toBeTruthy();
|
||||||
expect(wrapper.find('.ant-form-item-has-error').length).toBeTruthy();
|
expect(wrapper.find('.ant-form-item-has-error').length).toBeTruthy();
|
||||||
|
|
||||||
expect(onChange).toHaveBeenCalled();
|
expect(onChange).toHaveBeenCalled();
|
||||||
|
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should clean up', async () => {
|
it('should clean up', async () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
const Demo = () => {
|
const Demo = () => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
@ -105,12 +119,14 @@ describe('Form', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = mount(<Demo />);
|
const wrapper = mount(<Demo />);
|
||||||
await change(wrapper, 0, '1');
|
await change(wrapper, 0, '1', true);
|
||||||
expect(wrapper.find('.ant-form-item-explain').text()).toEqual('aaa');
|
expect(wrapper.find('.ant-form-item-explain').text()).toEqual('aaa');
|
||||||
await change(wrapper, 0, '2');
|
await change(wrapper, 0, '2', true);
|
||||||
expect(wrapper.find('.ant-form-item-explain').text()).toEqual('ccc');
|
expect(wrapper.find('.ant-form-item-explain').text()).toEqual('ccc');
|
||||||
await change(wrapper, 0, '1');
|
await change(wrapper, 0, '1', true);
|
||||||
expect(wrapper.find('.ant-form-item-explain').text()).toEqual('aaa');
|
expect(wrapper.find('.ant-form-item-explain').text()).toEqual('aaa');
|
||||||
|
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -315,6 +331,8 @@ describe('Form', () => {
|
|||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/20706
|
// https://github.com/ant-design/ant-design/issues/20706
|
||||||
it('Error change should work', async () => {
|
it('Error change should work', async () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Form>
|
<Form>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@ -338,15 +356,17 @@ describe('Form', () => {
|
|||||||
|
|
||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
for (let i = 0; i < 3; i += 1) {
|
for (let i = 0; i < 3; i += 1) {
|
||||||
await change(wrapper, 0, '');
|
await change(wrapper, 0, '', true);
|
||||||
expect(wrapper.find('.ant-form-item-explain').first().text()).toEqual("'name' is required");
|
expect(wrapper.find('.ant-form-item-explain').first().text()).toEqual("'name' is required");
|
||||||
|
|
||||||
await change(wrapper, 0, 'p');
|
await change(wrapper, 0, 'p', true);
|
||||||
await sleep(100);
|
await sleep(100);
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(wrapper.find('.ant-form-item-explain').first().text()).toEqual('not a p');
|
expect(wrapper.find('.ant-form-item-explain').first().text()).toEqual('not a p');
|
||||||
}
|
}
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/20813
|
// https://github.com/ant-design/ant-design/issues/20813
|
||||||
@ -428,6 +448,8 @@ describe('Form', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Form.Item with `help` should display error style when validate failed', async () => {
|
it('Form.Item with `help` should display error style when validate failed', async () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Form>
|
<Form>
|
||||||
<Form.Item name="test" help="help" rules={[{ required: true, message: 'message' }]}>
|
<Form.Item name="test" help="help" rules={[{ required: true, message: 'message' }]}>
|
||||||
@ -436,12 +458,16 @@ describe('Form', () => {
|
|||||||
</Form>,
|
</Form>,
|
||||||
);
|
);
|
||||||
|
|
||||||
await change(wrapper, 0, '');
|
await change(wrapper, 0, '', true);
|
||||||
expect(wrapper.find('.ant-form-item').first().hasClass('ant-form-item-has-error')).toBeTruthy();
|
expect(wrapper.find('.ant-form-item').first().hasClass('ant-form-item-has-error')).toBeTruthy();
|
||||||
expect(wrapper.find('.ant-form-item-explain').text()).toEqual('help');
|
expect(wrapper.find('.ant-form-item-explain').text()).toEqual('help');
|
||||||
|
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('clear validation message when ', async () => {
|
it('clear validation message when ', async () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Form>
|
<Form>
|
||||||
<Form.Item name="username" rules={[{ required: true, message: 'message' }]}>
|
<Form.Item name="username" rules={[{ required: true, message: 'message' }]}>
|
||||||
@ -449,14 +475,18 @@ describe('Form', () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>,
|
</Form>,
|
||||||
);
|
);
|
||||||
await change(wrapper, 0, '1');
|
await change(wrapper, 0, '1', true);
|
||||||
expect(wrapper.find('.ant-form-item-explain').length).toBeFalsy();
|
expect(wrapper.find('.ant-form-item-explain').length).toBeFalsy();
|
||||||
await change(wrapper, 0, '');
|
|
||||||
|
await change(wrapper, 0, '', true);
|
||||||
expect(wrapper.find('.ant-form-item-explain').length).toBeTruthy();
|
expect(wrapper.find('.ant-form-item-explain').length).toBeTruthy();
|
||||||
await change(wrapper, 0, '123');
|
|
||||||
|
await change(wrapper, 0, '123', true);
|
||||||
await sleep(800);
|
await sleep(800);
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(wrapper.find('.ant-form-item-explain').length).toBeFalsy();
|
expect(wrapper.find('.ant-form-item-explain').length).toBeFalsy();
|
||||||
|
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/21167
|
// https://github.com/ant-design/ant-design/issues/21167
|
||||||
|
@ -200,34 +200,6 @@ describe('Form.List', () => {
|
|||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ErrorList component', () => {
|
|
||||||
it('should trigger onDomErrorVisibleChange by motion end', async () => {
|
|
||||||
jest.useFakeTimers();
|
|
||||||
|
|
||||||
const onDomErrorVisibleChange = jest.fn();
|
|
||||||
const wrapper = mount(
|
|
||||||
<Form.ErrorList
|
|
||||||
errors={['bamboo is light']}
|
|
||||||
onDomErrorVisibleChange={onDomErrorVisibleChange}
|
|
||||||
/>,
|
|
||||||
);
|
|
||||||
|
|
||||||
await act(async () => {
|
|
||||||
await sleep();
|
|
||||||
jest.runAllTimers();
|
|
||||||
wrapper.update();
|
|
||||||
});
|
|
||||||
|
|
||||||
act(() => {
|
|
||||||
wrapper.find('CSSMotion').props().onLeaveEnd();
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(onDomErrorVisibleChange).toHaveBeenCalledWith(false);
|
|
||||||
|
|
||||||
jest.useRealTimers();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render empty without errors', () => {
|
it('should render empty without errors', () => {
|
||||||
const wrapper = mount(<Form.ErrorList />);
|
const wrapper = mount(<Form.ErrorList />);
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import omit from 'rc-util/lib/omit';
|
import omit from 'rc-util/lib/omit';
|
||||||
|
import { Meta } from 'rc-field-form/lib/interface';
|
||||||
import { FormProvider as RcFormProvider } from 'rc-field-form';
|
import { FormProvider as RcFormProvider } from 'rc-field-form';
|
||||||
import { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext';
|
import { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext';
|
||||||
import { ColProps } from '../grid/col';
|
import { ColProps } from '../grid/col';
|
||||||
@ -25,14 +26,9 @@ export const FormContext = React.createContext<FormContextProps>({
|
|||||||
itemRef: (() => {}) as any,
|
itemRef: (() => {}) as any,
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Form Item Context. Used for Form noStyle Item error collection */
|
/** `noStyle` Form Item Context. Used for error collection */
|
||||||
export interface FormItemContextProps {
|
export type ReportMetaChange = (meta: Meta, uniqueKeys: React.Key[]) => void;
|
||||||
updateItemErrors: (name: string, errors: string[], originName?: string) => void;
|
export const NoStyleItemContext = React.createContext<ReportMetaChange | null>(null);
|
||||||
}
|
|
||||||
|
|
||||||
export const FormItemContext = React.createContext<FormItemContextProps>({
|
|
||||||
updateItemErrors: () => {},
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Form Provider */
|
/** Form Provider */
|
||||||
export interface FormProviderProps extends Omit<RcFormProviderProps, 'validateMessages'> {
|
export interface FormProviderProps extends Omit<RcFormProviderProps, 'validateMessages'> {
|
||||||
|
@ -33,6 +33,7 @@ const Demo = () => {
|
|||||||
initialValues={{ remember: true }}
|
initialValues={{ remember: true }}
|
||||||
onFinish={onFinish}
|
onFinish={onFinish}
|
||||||
onFinishFailed={onFinishFailed}
|
onFinishFailed={onFinishFailed}
|
||||||
|
autoComplete="off"
|
||||||
>
|
>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="Username"
|
label="Username"
|
||||||
|
@ -15,7 +15,7 @@ We recommend use `Form.useForm` to create data control. If you are using class c
|
|||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import { Form, Input, Button, Select } from 'antd';
|
import { Form, Input, Button, Select } from 'antd';
|
||||||
import { FormInstance } from 'antd/lib/form';
|
import { FormInstance } from 'antd/es/form';
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
|
73
components/form/demo/warning-only.md
Normal file
73
components/form/demo/warning-only.md
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
---
|
||||||
|
order: 3.2
|
||||||
|
title:
|
||||||
|
zh-CN: 非阻塞校验
|
||||||
|
en-US: No block rule
|
||||||
|
---
|
||||||
|
|
||||||
|
## zh-CN
|
||||||
|
|
||||||
|
`rule` 添加 `warningOnly` 后校验不再阻塞表单提交。
|
||||||
|
|
||||||
|
## en-US
|
||||||
|
|
||||||
|
`rule` with `warningOnly` will not block form submit.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import React from 'react';
|
||||||
|
import { Form, Input, message, Button, Space } from 'antd';
|
||||||
|
|
||||||
|
const Demo = () => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
|
const onFinish = () => {
|
||||||
|
message.success('Submit success!');
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFinishFailed = () => {
|
||||||
|
message.error('Submit failed!');
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFill = () => {
|
||||||
|
form.setFieldsValue({
|
||||||
|
url: 'https://taobao.com/',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form
|
||||||
|
form={form}
|
||||||
|
layout="vertical"
|
||||||
|
onFinish={onFinish}
|
||||||
|
onFinishFailed={onFinishFailed}
|
||||||
|
autoComplete="off"
|
||||||
|
>
|
||||||
|
<div style={{ overflow: 'hidden' }}>
|
||||||
|
<Form.Item
|
||||||
|
name="url"
|
||||||
|
label="URL"
|
||||||
|
rules={[
|
||||||
|
{ required: true },
|
||||||
|
{ type: 'url', warningOnly: true },
|
||||||
|
{ type: 'string', min: 6 },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input placeholder="input placeholder" />
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
<Form.Item>
|
||||||
|
<Space>
|
||||||
|
<Button type="primary" htmlType="submit">
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
<Button htmlType="button" onClick={onFill}>
|
||||||
|
Fill
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ReactDOM.render(<Demo />, mountNode);
|
||||||
|
```
|
@ -1,47 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import useForceUpdate from '../../_util/hooks/useForceUpdate';
|
|
||||||
|
|
||||||
/** Always debounce error to avoid [error -> null -> error] blink */
|
|
||||||
export default function useCacheErrors(
|
|
||||||
errors: React.ReactNode[],
|
|
||||||
changeTrigger: (visible: boolean) => void,
|
|
||||||
directly: boolean,
|
|
||||||
): [boolean, React.ReactNode[]] {
|
|
||||||
const cacheRef = React.useRef({
|
|
||||||
errors,
|
|
||||||
visible: !!errors.length,
|
|
||||||
});
|
|
||||||
|
|
||||||
const forceUpdate = useForceUpdate();
|
|
||||||
|
|
||||||
const update = () => {
|
|
||||||
const prevVisible = cacheRef.current.visible;
|
|
||||||
const newVisible = !!errors.length;
|
|
||||||
|
|
||||||
const prevErrors = cacheRef.current.errors;
|
|
||||||
cacheRef.current.errors = errors;
|
|
||||||
cacheRef.current.visible = newVisible;
|
|
||||||
|
|
||||||
if (prevVisible !== newVisible) {
|
|
||||||
changeTrigger(newVisible);
|
|
||||||
} else if (
|
|
||||||
prevErrors.length !== errors.length ||
|
|
||||||
prevErrors.some((prevErr, index) => prevErr !== errors[index])
|
|
||||||
) {
|
|
||||||
forceUpdate();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (!directly) {
|
|
||||||
const timeout = setTimeout(update, 10);
|
|
||||||
return () => clearTimeout(timeout);
|
|
||||||
}
|
|
||||||
}, [errors]);
|
|
||||||
|
|
||||||
if (directly) {
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
return [cacheRef.current.visible, cacheRef.current.errors];
|
|
||||||
}
|
|
19
components/form/hooks/useDebounce.ts
Normal file
19
components/form/hooks/useDebounce.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
export default function useDebounce<T>(value: T[]): T[] {
|
||||||
|
const [cacheValue, setCacheValue] = React.useState(value);
|
||||||
|
React.useEffect(() => {
|
||||||
|
const timeout = setTimeout(
|
||||||
|
() => {
|
||||||
|
setCacheValue(value);
|
||||||
|
},
|
||||||
|
value.length ? 0 : 10,
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
};
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
return cacheValue;
|
||||||
|
}
|
@ -302,22 +302,23 @@ Rule supports a config object, or a function returning config object:
|
|||||||
type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
|
type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
|
||||||
```
|
```
|
||||||
|
|
||||||
| Name | Description | Type |
|
| Name | Description | Type | Version |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| defaultField | Validate rule for all array elements, valid when `type` is `array` | [rule](#Rule) |
|
| defaultField | Validate rule for all array elements, valid when `type` is `array` | [rule](#Rule) | |
|
||||||
| enum | Match enum value. You need to set `type` to `enum` to enable this | any\[] |
|
| enum | Match enum value. You need to set `type` to `enum` to enable this | any\[] | |
|
||||||
| fields | Validate rule for child elements, valid when `type` is `array` or `object` | Record<string, [rule](#Rule)> |
|
| fields | Validate rule for child elements, valid when `type` is `array` or `object` | Record<string, [rule](#Rule)> | |
|
||||||
| len | Length of string, number, array | number |
|
| len | Length of string, number, array | number | |
|
||||||
| max | `type` required: max length of `string`, `number`, `array` | number |
|
| max | `type` required: max length of `string`, `number`, `array` | number | |
|
||||||
| message | Error message. Will auto generate by [template](#validateMessages) if not provided | string |
|
| message | Error message. Will auto generate by [template](#validateMessages) if not provided | string | |
|
||||||
| min | `type` required: min length of `string`, `number`, `array` | number |
|
| min | `type` required: min length of `string`, `number`, `array` | number | |
|
||||||
| pattern | Regex pattern | RegExp |
|
| pattern | Regex pattern | RegExp | |
|
||||||
| required | Required field | boolean |
|
| required | Required field | boolean | |
|
||||||
| transform | Transform value to the rule before validation | (value) => any |
|
| transform | Transform value to the rule before validation | (value) => any | |
|
||||||
| type | Normally `string` \|`number` \|`boolean` \|`url` \| `email`. More type to ref [here](https://github.com/yiminghe/async-validator#type) | string |
|
| type | Normally `string` \|`number` \|`boolean` \|`url` \| `email`. More type to ref [here](https://github.com/yiminghe/async-validator#type) | string | |
|
||||||
| validateTrigger | Set validate trigger event. Must be the sub set of `validateTrigger` in Form.Item | string \| string\[] |
|
| validateTrigger | Set validate trigger event. Must be the sub set of `validateTrigger` in Form.Item | string \| string\[] | |
|
||||||
| validator | Customize validation rule. Accept Promise as return. See [example](#components-form-demo-register) | ([rule](#Rule), value) => Promise |
|
| validator | Customize validation rule. Accept Promise as return. See [example](#components-form-demo-register) | ([rule](#Rule), value) => Promise | |
|
||||||
| whitespace | Failed if only has whitespace, only work with `type: 'string'` rule | boolean |
|
| warningOnly | Warning only. Not block form submit | boolean | 4.17.0 |
|
||||||
|
| whitespace | Failed if only has whitespace, only work with `type: 'string'` rule | boolean | |
|
||||||
|
|
||||||
## Migrate to v4
|
## Migrate to v4
|
||||||
|
|
||||||
|
@ -301,22 +301,23 @@ Rule 支持接收 object 进行配置,也支持 function 来动态获取 form
|
|||||||
type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
|
type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
|
||||||
```
|
```
|
||||||
|
|
||||||
| 名称 | 说明 | 类型 |
|
| 名称 | 说明 | 类型 | 版本 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| defaultField | 仅在 `type` 为 `array` 类型时有效,用于指定数组元素的校验规则 | [rule](#Rule) |
|
| defaultField | 仅在 `type` 为 `array` 类型时有效,用于指定数组元素的校验规则 | [rule](#Rule) | |
|
||||||
| enum | 是否匹配枚举中的值(需要将 `type` 设置为 `enum`) | any\[] |
|
| enum | 是否匹配枚举中的值(需要将 `type` 设置为 `enum`) | any\[] | |
|
||||||
| fields | 仅在 `type` 为 `array` 或 `object` 类型时有效,用于指定子元素的校验规则 | Record<string, [rule](#Rule)> |
|
| fields | 仅在 `type` 为 `array` 或 `object` 类型时有效,用于指定子元素的校验规则 | Record<string, [rule](#Rule)> | |
|
||||||
| len | string 类型时为字符串长度;number 类型时为确定数字; array 类型时为数组长度 | number |
|
| len | string 类型时为字符串长度;number 类型时为确定数字; array 类型时为数组长度 | number | |
|
||||||
| max | 必须设置 `type`:string 类型为字符串最大长度;number 类型时为最大值;array 类型时为数组最大长度 | number |
|
| max | 必须设置 `type`:string 类型为字符串最大长度;number 类型时为最大值;array 类型时为数组最大长度 | number | |
|
||||||
| message | 错误信息,不设置时会通过[模板](#validateMessages)自动生成 | string |
|
| message | 错误信息,不设置时会通过[模板](#validateMessages)自动生成 | string | |
|
||||||
| min | 必须设置 `type`:string 类型为字符串最小长度;number 类型时为最小值;array 类型时为数组最小长度 | number |
|
| min | 必须设置 `type`:string 类型为字符串最小长度;number 类型时为最小值;array 类型时为数组最小长度 | number | |
|
||||||
| pattern | 正则表达式匹配 | RegExp |
|
| pattern | 正则表达式匹配 | RegExp | |
|
||||||
| required | 是否为必选字段 | boolean |
|
| required | 是否为必选字段 | boolean | |
|
||||||
| transform | 将字段值转换成目标值后进行校验 | (value) => any |
|
| transform | 将字段值转换成目标值后进行校验 | (value) => any | |
|
||||||
| type | 类型,常见有 `string` \|`number` \|`boolean` \|`url` \| `email`。更多请参考[此处](https://github.com/yiminghe/async-validator#type) | string |
|
| type | 类型,常见有 `string` \|`number` \|`boolean` \|`url` \| `email`。更多请参考[此处](https://github.com/yiminghe/async-validator#type) | string | |
|
||||||
| validateTrigger | 设置触发验证时机,必须是 Form.Item 的 `validateTrigger` 的子集 | string \| string\[] |
|
| validateTrigger | 设置触发验证时机,必须是 Form.Item 的 `validateTrigger` 的子集 | string \| string\[] | |
|
||||||
| validator | 自定义校验,接收 Promise 作为返回值。[示例](#components-form-demo-register)参考 | ([rule](#Rule), value) => Promise |
|
| validator | 自定义校验,接收 Promise 作为返回值。[示例](#components-form-demo-register)参考 | ([rule](#Rule), value) => Promise | |
|
||||||
| whitespace | 如果字段仅包含空格则校验不通过,只在 `type: 'string'` 时生效 | boolean |
|
| warningOnly | 仅警告,不阻塞表单提交 | boolean | 4.17.0 |
|
||||||
|
| whitespace | 如果字段仅包含空格则校验不通过,只在 `type: 'string'` 时生效 | boolean | |
|
||||||
|
|
||||||
## 从 v3 升级到 v4
|
## 从 v3 升级到 v4
|
||||||
|
|
||||||
|
@ -61,9 +61,12 @@
|
|||||||
|
|
||||||
margin-bottom: @form-item-margin-bottom;
|
margin-bottom: @form-item-margin-bottom;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
// We delay one frame (0.017s) here to let CSSMotion goes
|
||||||
|
transition: margin-bottom @animation-duration-slow 0.017s linear;
|
||||||
|
|
||||||
&-with-help {
|
&-with-help {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
transition: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-hidden,
|
&-hidden,
|
||||||
@ -179,10 +182,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==============================================================
|
||||||
|
// = Explain =
|
||||||
|
// ==============================================================
|
||||||
&-explain,
|
&-explain,
|
||||||
&-extra {
|
&-extra {
|
||||||
clear: both;
|
clear: both;
|
||||||
min-height: @form-item-margin-bottom;
|
|
||||||
color: @text-color-secondary;
|
color: @text-color-secondary;
|
||||||
font-size: @font-size-base;
|
font-size: @font-size-base;
|
||||||
line-height: @line-height-base;
|
line-height: @line-height-base;
|
||||||
@ -190,43 +195,64 @@
|
|||||||
.explainAndExtraDistance((@form-item-margin-bottom - @form-font-height) / 2);
|
.explainAndExtraDistance((@form-item-margin-bottom - @form-font-height) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-explain-connected {
|
||||||
|
height: 0;
|
||||||
|
min-height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-extra {
|
||||||
|
min-height: @form-item-margin-bottom;
|
||||||
|
}
|
||||||
|
|
||||||
.@{ant-prefix}-input-textarea-show-count {
|
.@{ant-prefix}-input-textarea-show-count {
|
||||||
&::after {
|
&::after {
|
||||||
margin-bottom: -22px;
|
margin-bottom: -22px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.show-help-motion(@className, @keyframeName, @duration: @animation-duration-slow) {
|
&-with-help &-explain {
|
||||||
@name: ~'@{ant-prefix}-@{className}';
|
height: auto;
|
||||||
.make-motion(@name, @keyframeName, @duration);
|
min-height: @form-item-margin-bottom;
|
||||||
.@{name}-enter,
|
|
||||||
.@{name}-appear {
|
|
||||||
opacity: 0;
|
|
||||||
animation-timing-function: @ease-in-out;
|
|
||||||
}
|
|
||||||
.@{name}-leave {
|
|
||||||
animation-timing-function: @ease-in-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.show-help-motion(show-help, antShowHelp, 0.3s);
|
|
||||||
|
|
||||||
@keyframes antShowHelpIn {
|
|
||||||
0% {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateY(0);
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes antShowHelpOut {
|
// >>>>>>>>>> Motion <<<<<<<<<<
|
||||||
to {
|
// Explain holder
|
||||||
|
.@{ant-prefix}-show-help {
|
||||||
|
transition: height @animation-duration-slow linear, min-height @animation-duration-slow linear,
|
||||||
|
margin-bottom @animation-duration-slow @ease-in-out,
|
||||||
|
opacity @animation-duration-slow @ease-in-out;
|
||||||
|
|
||||||
|
&-leave {
|
||||||
|
min-height: @form-item-margin-bottom;
|
||||||
|
|
||||||
|
&-active {
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explain
|
||||||
|
.@{ant-prefix}-show-help-item {
|
||||||
|
overflow: hidden;
|
||||||
|
transition: height @animation-duration-slow @ease-in-out,
|
||||||
|
opacity @animation-duration-slow @ease-in-out, transform @animation-duration-slow @ease-in-out !important;
|
||||||
|
|
||||||
|
&-appear,
|
||||||
|
&-enter {
|
||||||
transform: translateY(-5px);
|
transform: translateY(-5px);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
|
&-active {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-leave-active {
|
||||||
|
transform: translateY(-5px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
// ========================= Explain =========================
|
// ========================= Explain =========================
|
||||||
/* To support leave along ErrorList. We add additional className to handle explain style */
|
/* To support leave along ErrorList. We add additional className to handle explain style */
|
||||||
&-explain {
|
&-explain {
|
||||||
&&-error {
|
&-error {
|
||||||
color: @error-color;
|
color: @error-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
&&-warning {
|
&-warning {
|
||||||
color: @warning-color;
|
color: @warning-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,11 @@ When a numeric value needs to be provided.
|
|||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| autoFocus | If get focus when component mounted | boolean | false | - |
|
| autoFocus | If get focus when component mounted | boolean | false | - |
|
||||||
| bordered | Whether has border style | boolean | true | 4.12.0 |
|
| bordered | Whether has border style | boolean | true | 4.12.0 |
|
||||||
|
| controls | Whether to show `+-` controls | boolean | true | 4.17.0 |
|
||||||
| decimalSeparator | Decimal separator | string | - | - |
|
| decimalSeparator | Decimal separator | string | - | - |
|
||||||
| defaultValue | The initial value | number | - | - |
|
| defaultValue | The initial value | number | - | - |
|
||||||
| disabled | If disable the input | boolean | false | - |
|
| disabled | If disable the input | boolean | false | - |
|
||||||
| formatter | Specifies the format of the value presented | function(value: number \| string): string | - | - |
|
| formatter | Specifies the format of the value presented | function(value: number \| string, info: { userTyping: boolean, input: string }): string | - | info: 4.17.0 |
|
||||||
| keyboard | If enable keyboard behavior | boolean | true | 4.12.0 |
|
| keyboard | If enable keyboard behavior | boolean | true | 4.12.0 |
|
||||||
| max | The max value | number | [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) | - |
|
| max | The max value | number | [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) | - |
|
||||||
| min | The min value | number | [Number.MIN_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER) | - |
|
| min | The min value | number | [Number.MIN_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER) | - |
|
||||||
|
@ -20,10 +20,11 @@ cover: https://gw.alipayobjects.com/zos/alicdn/XOS8qZ0kU/InputNumber.svg
|
|||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| autoFocus | 自动获取焦点 | boolean | false | - |
|
| autoFocus | 自动获取焦点 | boolean | false | - |
|
||||||
| bordered | 是否有边框 | boolean | true | 4.12.0 |
|
| bordered | 是否有边框 | boolean | true | 4.12.0 |
|
||||||
|
| controls | 是否显示增减按钮 | boolean | true | 4.17.0 |
|
||||||
| decimalSeparator | 小数点 | string | - | - |
|
| decimalSeparator | 小数点 | string | - | - |
|
||||||
| defaultValue | 初始值 | number | - | - |
|
| defaultValue | 初始值 | number | - | - |
|
||||||
| disabled | 禁用 | boolean | false | - |
|
| disabled | 禁用 | boolean | false | - |
|
||||||
| formatter | 指定输入框展示值的格式 | function(value: number \| string): string | - | - |
|
| formatter | 指定输入框展示值的格式 | function(value: number \| string, info: { userTyping: boolean, input: string }): string | - | info: 4.17.0 |
|
||||||
| keyboard | 是否启用键盘快捷行为 | boolean | true | 4.12.0 |
|
| keyboard | 是否启用键盘快捷行为 | boolean | true | 4.12.0 |
|
||||||
| max | 最大值 | number | [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) | - |
|
| max | 最大值 | number | [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) | - |
|
||||||
| min | 最小值 | number | [Number.MIN_SAFE_INTEGER](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER) | - |
|
| min | 最小值 | number | [Number.MIN_SAFE_INTEGER](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER) | - |
|
||||||
|
@ -696,6 +696,7 @@ Array [
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-cascader-picker-label"
|
class="ant-cascader-picker-label"
|
||||||
|
title="Zhejiang / Hangzhou / West Lake"
|
||||||
>
|
>
|
||||||
Zhejiang / Hangzhou / West Lake
|
Zhejiang / Hangzhou / West Lake
|
||||||
</span>
|
</span>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,7 @@ import LocaleProvider from '..';
|
|||||||
import arEG from '../ar_EG';
|
import arEG from '../ar_EG';
|
||||||
import azAZ from '../az_AZ';
|
import azAZ from '../az_AZ';
|
||||||
import bgBG from '../bg_BG';
|
import bgBG from '../bg_BG';
|
||||||
|
import bnBD from '../bn_BD';
|
||||||
import byBY from '../by_BY';
|
import byBY from '../by_BY';
|
||||||
import caES from '../ca_ES';
|
import caES from '../ca_ES';
|
||||||
import csCZ from '../cs_CZ';
|
import csCZ from '../cs_CZ';
|
||||||
@ -53,6 +54,7 @@ import kuIQ from '../ku_IQ';
|
|||||||
import lvLV from '../lv_LV';
|
import lvLV from '../lv_LV';
|
||||||
import ltLT from '../lt_LT';
|
import ltLT from '../lt_LT';
|
||||||
import mkMK from '../mk_MK';
|
import mkMK from '../mk_MK';
|
||||||
|
import mlIN from '../ml_IN';
|
||||||
import mnMN from '../mn_MN';
|
import mnMN from '../mn_MN';
|
||||||
import msMY from '../ms_MY';
|
import msMY from '../ms_MY';
|
||||||
import nbNO from '../nb_NO';
|
import nbNO from '../nb_NO';
|
||||||
@ -76,11 +78,13 @@ import viVN from '../vi_VN';
|
|||||||
import zhCN from '../zh_CN';
|
import zhCN from '../zh_CN';
|
||||||
import zhHK from '../zh_HK';
|
import zhHK from '../zh_HK';
|
||||||
import zhTW from '../zh_TW';
|
import zhTW from '../zh_TW';
|
||||||
|
import urPK from '../ur_PK';
|
||||||
|
|
||||||
const locales = [
|
const locales = [
|
||||||
azAZ,
|
azAZ,
|
||||||
arEG,
|
arEG,
|
||||||
bgBG,
|
bgBG,
|
||||||
|
bnBD,
|
||||||
byBY,
|
byBY,
|
||||||
caES,
|
caES,
|
||||||
csCZ,
|
csCZ,
|
||||||
@ -113,6 +117,7 @@ const locales = [
|
|||||||
kuIQ,
|
kuIQ,
|
||||||
ltLT,
|
ltLT,
|
||||||
mkMK,
|
mkMK,
|
||||||
|
mlIN,
|
||||||
msMY,
|
msMY,
|
||||||
mnMN,
|
mnMN,
|
||||||
nbNO,
|
nbNO,
|
||||||
@ -138,6 +143,7 @@ const locales = [
|
|||||||
zhCN,
|
zhCN,
|
||||||
zhHK,
|
zhHK,
|
||||||
zhTW,
|
zhTW,
|
||||||
|
urPK,
|
||||||
];
|
];
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
@ -229,9 +235,10 @@ describe('Locale Provider', () => {
|
|||||||
<ModalDemo />
|
<ModalDemo />
|
||||||
</LocaleProvider>,
|
</LocaleProvider>,
|
||||||
);
|
);
|
||||||
const currentConfirmNode = document.querySelectorAll('.ant-modal-confirm')[
|
const currentConfirmNode =
|
||||||
document.querySelectorAll('.ant-modal-confirm').length - 1
|
document.querySelectorAll('.ant-modal-confirm')[
|
||||||
];
|
document.querySelectorAll('.ant-modal-confirm').length - 1
|
||||||
|
];
|
||||||
let cancelButtonText = currentConfirmNode.querySelectorAll(
|
let cancelButtonText = currentConfirmNode.querySelectorAll(
|
||||||
'.ant-btn:not(.ant-btn-primary) span',
|
'.ant-btn:not(.ant-btn-primary) span',
|
||||||
)[0].innerHTML;
|
)[0].innerHTML;
|
||||||
|
3
components/locale-provider/bn_BD.tsx
Normal file
3
components/locale-provider/bn_BD.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import locale from '../locale/bn_BD';
|
||||||
|
|
||||||
|
export default locale;
|
3
components/locale-provider/ml_IN.tsx
Normal file
3
components/locale-provider/ml_IN.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import locale from '../locale/ml_IN';
|
||||||
|
|
||||||
|
export default locale;
|
3
components/locale-provider/ur_PK.tsx
Normal file
3
components/locale-provider/ur_PK.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import locale from '../locale/ur_PK';
|
||||||
|
|
||||||
|
export default locale;
|
134
components/locale/bn_BD.tsx
Normal file
134
components/locale/bn_BD.tsx
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/* eslint-disable no-template-curly-in-string */
|
||||||
|
import Pagination from 'rc-pagination/lib/locale/bn_BD';
|
||||||
|
import DatePicker from '../date-picker/locale/bn_BD';
|
||||||
|
import TimePicker from '../time-picker/locale/bn_BD';
|
||||||
|
import Calendar from '../calendar/locale/bn_BD';
|
||||||
|
import { Locale } from '../locale-provider';
|
||||||
|
|
||||||
|
const typeTemplate = '${label} টি সঠিক ${type} নয়।';
|
||||||
|
|
||||||
|
const localeValues: Locale = {
|
||||||
|
locale: 'bn-bd',
|
||||||
|
Pagination,
|
||||||
|
DatePicker,
|
||||||
|
TimePicker,
|
||||||
|
Calendar,
|
||||||
|
global: {
|
||||||
|
placeholder: 'অনুগ্রহ করে নির্বাচন করুন',
|
||||||
|
},
|
||||||
|
Table: {
|
||||||
|
filterTitle: 'ফিল্টার মেনু',
|
||||||
|
filterConfirm: 'ঠিক',
|
||||||
|
filterReset: 'রিসেট',
|
||||||
|
filterEmptyText: 'ফিল্টার নেই',
|
||||||
|
emptyText: 'কোনও ডেটা নেই',
|
||||||
|
selectAll: 'বর্তমান পৃষ্ঠা নির্বাচন করুন',
|
||||||
|
selectInvert: 'বর্তমান পৃষ্ঠাটি উল্টে দিন',
|
||||||
|
selectNone: 'সমস্ত ডেটা সাফ করুন',
|
||||||
|
selectionAll: 'সমস্ত ডেটা নির্বাচন করুন',
|
||||||
|
sortTitle: 'সাজান',
|
||||||
|
expand: 'সারি প্রসারিত করুন',
|
||||||
|
collapse: 'সারি সঙ্কুচিত করুন',
|
||||||
|
triggerDesc: 'অবতরণকে সাজানোর জন্য ক্লিক করুন',
|
||||||
|
triggerAsc: 'আরোহী বাছাই করতে ক্লিক করুন',
|
||||||
|
cancelSort: 'বাছাই বাতিল করতে ক্লিক করুন',
|
||||||
|
},
|
||||||
|
Modal: {
|
||||||
|
okText: 'ঠিক',
|
||||||
|
cancelText: 'বাতিল',
|
||||||
|
justOkText: 'ঠিক',
|
||||||
|
},
|
||||||
|
Popconfirm: {
|
||||||
|
okText: 'ঠিক',
|
||||||
|
cancelText: 'বাতিল',
|
||||||
|
},
|
||||||
|
Transfer: {
|
||||||
|
titles: ['', ''],
|
||||||
|
searchPlaceholder: 'এখানে অনুসন্ধান',
|
||||||
|
itemUnit: 'আইটেম',
|
||||||
|
itemsUnit: 'আইটেমসমূহ',
|
||||||
|
remove: 'অপসারণ',
|
||||||
|
selectCurrent: 'বর্তমান পৃষ্ঠা নির্বাচন করুন',
|
||||||
|
removeCurrent: 'বর্তমান পৃষ্ঠাটি সরান',
|
||||||
|
selectAll: 'সমস্ত ডেটা নির্বাচন করুন',
|
||||||
|
removeAll: 'সমস্ত ডেটা সরান',
|
||||||
|
selectInvert: 'বর্তমান পৃষ্ঠাটি উল্টে দিন',
|
||||||
|
},
|
||||||
|
Upload: {
|
||||||
|
uploading: 'আপলোড হচ্ছে ...',
|
||||||
|
removeFile: 'ফাইল সরান',
|
||||||
|
uploadError: 'আপলোডে সমস্যা',
|
||||||
|
previewFile: 'ফাইলের পূর্বরূপ',
|
||||||
|
downloadFile: 'ফাইল ডাউনলোড',
|
||||||
|
},
|
||||||
|
Empty: {
|
||||||
|
description: 'কোনও ডেটা নেই',
|
||||||
|
},
|
||||||
|
Icon: {
|
||||||
|
icon: 'আইকন',
|
||||||
|
},
|
||||||
|
Text: {
|
||||||
|
edit: 'সম্পাদনা',
|
||||||
|
copy: 'অনুলিপি',
|
||||||
|
copied: 'অনুলিপি হয়েছে',
|
||||||
|
expand: 'বিস্তৃত করা',
|
||||||
|
},
|
||||||
|
PageHeader: {
|
||||||
|
back: 'পেছনে',
|
||||||
|
},
|
||||||
|
Form: {
|
||||||
|
optional: '(ঐচ্ছিক)',
|
||||||
|
defaultValidateMessages: {
|
||||||
|
default: '${label} এর ক্ষেত্রে ক্ষেত্র বৈধতা ত্রুটি',
|
||||||
|
required: 'অনুগ্রহ করে ${label} প্রবেশ করান',
|
||||||
|
enum: '${label} অবশ্যই [${enum}] এর মধ্যে একটি হতে হবে',
|
||||||
|
whitespace: '${label} ফাঁকা অক্ষর হতে পারে না',
|
||||||
|
date: {
|
||||||
|
format: '${label} তারিখ ফরমেট সঠিক নয়।',
|
||||||
|
parse: '${label} তারিখে রূপান্তর করা যায় না',
|
||||||
|
invalid: '${label} একটি সঠিক তারিখ না।',
|
||||||
|
},
|
||||||
|
types: {
|
||||||
|
string: typeTemplate,
|
||||||
|
method: typeTemplate,
|
||||||
|
array: typeTemplate,
|
||||||
|
object: typeTemplate,
|
||||||
|
number: typeTemplate,
|
||||||
|
date: typeTemplate,
|
||||||
|
boolean: typeTemplate,
|
||||||
|
integer: typeTemplate,
|
||||||
|
float: typeTemplate,
|
||||||
|
regexp: typeTemplate,
|
||||||
|
email: typeTemplate,
|
||||||
|
url: typeTemplate,
|
||||||
|
hex: typeTemplate,
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
len: '${label} অবশ্যই ${len} অক্ষরের হতে হবে।',
|
||||||
|
min: '${label} অবশ্যই অন্তত ${min} অক্ষরের হতে হবে।',
|
||||||
|
max: '${label} অবশ্যই ${max} পর্যন্ত অক্ষরের হতে হবে।',
|
||||||
|
range: '${label} অবশ্যই ${min}-${max} অক্ষরের এর মধ্যে হতে হবে।',
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
len: '${label} অবশ্যই ${len} এর সমান হতে হবে',
|
||||||
|
min: '${label} অবশ্যই সর্বনিম্ন ${min} হতে হবে',
|
||||||
|
max: '${label} অবশ্যই সর্বোচ্চ ${max} হতে হবে',
|
||||||
|
range: '${label} অবশ্যই ${min}-${max} এর মধ্যে হতে হবে',
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
len: 'অবশ্যই ${len} ${label} হতে হবে',
|
||||||
|
min: 'কমপক্ষে ${min} ${label}',
|
||||||
|
max: 'সর্বাধিক হিসাবে ${max} ${label}',
|
||||||
|
range: '${label} এর পরিমাণ অবশ্যই ${min}-${max} এর মধ্যে হতে হবে',
|
||||||
|
},
|
||||||
|
pattern: {
|
||||||
|
mismatch: '${label} এই ${pattern} প্যাটার্নের সাথে মেলে না',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Image: {
|
||||||
|
preview: 'পূর্বরূপ',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default localeValues;
|
134
components/locale/ml_IN.tsx
Normal file
134
components/locale/ml_IN.tsx
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/* eslint-disable no-template-curly-in-string */
|
||||||
|
import Pagination from 'rc-pagination/lib/locale/ml_IN';
|
||||||
|
import DatePicker from '../date-picker/locale/ml_IN';
|
||||||
|
import TimePicker from '../time-picker/locale/ml_IN';
|
||||||
|
import Calendar from '../calendar/locale/ml_IN';
|
||||||
|
import { Locale } from '../locale-provider';
|
||||||
|
|
||||||
|
const typeTemplate = '${label} അസാധുവായ ${type} ആണ്';
|
||||||
|
|
||||||
|
const localeValues: Locale = {
|
||||||
|
locale: 'ml',
|
||||||
|
Pagination,
|
||||||
|
DatePicker,
|
||||||
|
TimePicker,
|
||||||
|
Calendar,
|
||||||
|
global: {
|
||||||
|
placeholder: 'ദയവായി തിരഞ്ഞെടുക്കുക',
|
||||||
|
},
|
||||||
|
Table: {
|
||||||
|
filterTitle: 'ഫിൽറ്റർ',
|
||||||
|
filterConfirm: 'ശരിയാണ്',
|
||||||
|
filterReset: 'പുനഃക്രമീകരിക്കുക',
|
||||||
|
filterEmptyText: 'ഫിൽറ്ററുകളൊന്നുമില്ല',
|
||||||
|
emptyText: 'ഡാറ്റയൊന്നുമില്ല',
|
||||||
|
selectAll: 'നിലവിലെ പേജ് തിരഞ്ഞെടുക്കുക',
|
||||||
|
selectInvert: 'നിലവിലെ പേജിൽ ഇല്ലാത്തത് തിരഞ്ഞെടുക്കുക',
|
||||||
|
selectNone: 'എല്ലാ ഡാറ്റയും നീക്കം ചെയ്യുക',
|
||||||
|
selectionAll: 'എല്ലാ ഡാറ്റയും തിരഞ്ഞെടുക്കുക',
|
||||||
|
sortTitle: 'ക്രമമാക്കുക',
|
||||||
|
expand: 'വരി വികസിപ്പിക്കുക',
|
||||||
|
collapse: 'വരി ചുരുക്കുക',
|
||||||
|
triggerDesc: 'അവരോഹണ ക്രമത്തിനായി ക്ലിക്ക് ചെയ്യുക',
|
||||||
|
triggerAsc: 'ആരോഹണ ക്രമത്തിനായി ക്ലിക്ക് ചെയ്യുക',
|
||||||
|
cancelSort: 'ക്രമീകരണം ഒഴിവാക്കുന്നതിനായി ക്ലിക്ക് ചെയ്യുക',
|
||||||
|
},
|
||||||
|
Modal: {
|
||||||
|
okText: 'ശരിയാണ്',
|
||||||
|
cancelText: 'റദ്ദാക്കുക',
|
||||||
|
justOkText: 'ശരിയാണ്',
|
||||||
|
},
|
||||||
|
Popconfirm: {
|
||||||
|
okText: 'ശരിയാണ്',
|
||||||
|
cancelText: 'റദ്ദാക്കുക',
|
||||||
|
},
|
||||||
|
Transfer: {
|
||||||
|
titles: ['', ''],
|
||||||
|
searchPlaceholder: 'ഇവിടെ തിരയുക',
|
||||||
|
itemUnit: 'ഇനം',
|
||||||
|
itemsUnit: 'ഇനങ്ങൾ',
|
||||||
|
remove: 'നീക്കം ചെയ്യുക',
|
||||||
|
selectCurrent: 'നിലവിലെ പേജ് തിരഞ്ഞെടുക്കുക',
|
||||||
|
removeCurrent: 'നിലവിലെ പേജ് നീക്കം ചെയ്യുക',
|
||||||
|
selectAll: 'എല്ലാ ഡാറ്റയും തിരഞ്ഞെടുക്കുക',
|
||||||
|
removeAll: 'എല്ലാ ഡാറ്റയും നീക്കം ചെയ്യുക',
|
||||||
|
selectInvert: 'നിലവിലെ പേജിൽ ഇല്ലാത്തത് തിരഞ്ഞെടുക്കുക',
|
||||||
|
},
|
||||||
|
Upload: {
|
||||||
|
uploading: 'അപ്ലോഡ് ചെയ്തു കൊണ്ടിരിക്കുന്നു...',
|
||||||
|
removeFile: 'ഫയൽ നീക്കം ചെയ്യുക',
|
||||||
|
uploadError: 'അപ്ലോഡിൽ പിശക് സംഭവിച്ചിരിക്കുന്നു',
|
||||||
|
previewFile: 'ഫയൽ പ്രിവ്യൂ ചെയ്യുക',
|
||||||
|
downloadFile: 'ഫയൽ ഡൗൺലോഡ് ചെയ്യുക',
|
||||||
|
},
|
||||||
|
Empty: {
|
||||||
|
description: 'ഡാറ്റയൊന്നുമില്ല',
|
||||||
|
},
|
||||||
|
Icon: {
|
||||||
|
icon: 'ഐക്കൺ',
|
||||||
|
},
|
||||||
|
Text: {
|
||||||
|
edit: 'തിരുത്തുക',
|
||||||
|
copy: 'കോപ്പി ചെയ്യുക',
|
||||||
|
copied: 'കോപ്പി ചെയ്തു',
|
||||||
|
expand: 'വികസിപ്പിക്കുക',
|
||||||
|
},
|
||||||
|
PageHeader: {
|
||||||
|
back: 'തിരികെ',
|
||||||
|
},
|
||||||
|
Form: {
|
||||||
|
optional: '(optional)',
|
||||||
|
defaultValidateMessages: {
|
||||||
|
default: '${label} ഫീൽഡിൽ വാലിഡേഷൻ പിശകുണ്ട്',
|
||||||
|
required: 'ദയവായി ${label} രേഖപ്പെടുത്തുക',
|
||||||
|
enum: '${label} നിർബന്ധമായും [${enum}]-ൽ നിന്നുള്ളതായിരിക്കണം',
|
||||||
|
whitespace: '${label} ശൂന്യമായി വെക്കാനാകില്ല',
|
||||||
|
date: {
|
||||||
|
format: '${label} തീയതി രൂപരേഖ അസാധുവാണ്',
|
||||||
|
parse: '${label} ഒരു തീയതിയാക്കി മാറ്റാൻ സാധിക്കില്ല',
|
||||||
|
invalid: '${label} ഒരു അസാധുവായ തീയതി ആണ്',
|
||||||
|
},
|
||||||
|
types: {
|
||||||
|
string: typeTemplate,
|
||||||
|
method: typeTemplate,
|
||||||
|
array: typeTemplate,
|
||||||
|
object: typeTemplate,
|
||||||
|
number: typeTemplate,
|
||||||
|
date: typeTemplate,
|
||||||
|
boolean: typeTemplate,
|
||||||
|
integer: typeTemplate,
|
||||||
|
float: typeTemplate,
|
||||||
|
regexp: typeTemplate,
|
||||||
|
email: typeTemplate,
|
||||||
|
url: typeTemplate,
|
||||||
|
hex: typeTemplate,
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
len: '${label} നിർബന്ധമായും ${len} അക്ഷരങ്ങൾ ഉണ്ടായിരിക്കണം',
|
||||||
|
min: '${label} നിർബന്ധമായും ${min} അക്ഷരങ്ങൾ എങ്കിലും ഉണ്ടായിരിക്കണം',
|
||||||
|
max: '${label} നിർബന്ധമായും ${max} അക്ഷരങ്ങളിൽ കൂടാൻ പാടില്ല',
|
||||||
|
range: '${label} നിർബന്ധമായും ${min}-നും ${max}-നും ഇടയിൽ അക്ഷരങ്ങൾ ഉള്ളതായിരിക്കണം',
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
len: '${label} നിർബന്ധമായും ${len}-നു തുല്യമായിരിക്കണം',
|
||||||
|
min: '${label} നിർബന്ധമായും ${min}-ൽ കുറയാൻ പാടില്ല',
|
||||||
|
max: '${label} നിർബന്ധമായും ${max}-ൽ കൂടാൻ പാടില്ല',
|
||||||
|
range: '${label} നിർബന്ധമായും ${min}-നും ${max}-നും ഇടയിൽ ആയിരിക്കണം',
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
len: 'നിർബന്ധമായും ${len} ${label} ഉണ്ടായിരിക്കണം',
|
||||||
|
min: 'കുറഞ്ഞപക്ഷം ${min} ${label} എങ്കിലും ഉണ്ടായിരിക്കണം',
|
||||||
|
max: 'അങ്ങേയറ്റം ${max} ${label} ആയിരിക്കണം',
|
||||||
|
range: '${label}-ന്റെ എണ്ണം നിർബന്ധമായും ${min}-നും ${max}-നും ഇടയിൽ ആയിരിക്കണം',
|
||||||
|
},
|
||||||
|
pattern: {
|
||||||
|
mismatch: '${label} ${pattern} മാതൃകയുമായി യോജിക്കുന്നില്ല',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Image: {
|
||||||
|
preview: 'പ്രിവ്യൂ',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default localeValues;
|
134
components/locale/ur_PK.tsx
Normal file
134
components/locale/ur_PK.tsx
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/* eslint-disable no-template-curly-in-string */
|
||||||
|
import Pagination from 'rc-pagination/lib/locale/ur_PK';
|
||||||
|
import DatePicker from '../date-picker/locale/ur_PK';
|
||||||
|
import TimePicker from '../time-picker/locale/ur_PK';
|
||||||
|
import Calendar from '../calendar/locale/ur_PK';
|
||||||
|
import { Locale } from '../locale-provider';
|
||||||
|
|
||||||
|
const typeTemplate = '${label} درست نہیں ہے ${type}';
|
||||||
|
|
||||||
|
const localeValues: Locale = {
|
||||||
|
locale: 'ur',
|
||||||
|
Pagination,
|
||||||
|
DatePicker,
|
||||||
|
TimePicker,
|
||||||
|
Calendar,
|
||||||
|
global: {
|
||||||
|
placeholder: 'منتخب کریں',
|
||||||
|
},
|
||||||
|
Table: {
|
||||||
|
filterTitle: 'فلٹر مینو',
|
||||||
|
filterConfirm: 'ٹھیک ہے',
|
||||||
|
filterReset: 'ری سیٹ کریں',
|
||||||
|
filterEmptyText: 'فلٹرز نہیں',
|
||||||
|
emptyText: 'کوئی ڈیٹا نہیں',
|
||||||
|
selectAll: 'موجودہ صفحہ منتخب کریں',
|
||||||
|
selectInvert: 'موجودہ صفحے کو الٹ دیں',
|
||||||
|
selectNone: 'تمام ڈیٹا صاف کریں',
|
||||||
|
selectionAll: 'تمام ڈیٹا کو منتخب کریں',
|
||||||
|
sortTitle: 'ترتیب دیں',
|
||||||
|
expand: 'پھیلائیں',
|
||||||
|
collapse: 'سمیٹیں',
|
||||||
|
triggerDesc: 'نزولی کو ترتیب دینے کیلئے کلک کریں',
|
||||||
|
triggerAsc: 'چڑھنے کو ترتیب دینے کیلئے کلک کریں',
|
||||||
|
cancelSort: 'ترتیب کو منسوخ کرنے کیلئے دبائیں',
|
||||||
|
},
|
||||||
|
Modal: {
|
||||||
|
okText: 'ٹھیک ہے',
|
||||||
|
cancelText: 'منسوخ کریں',
|
||||||
|
justOkText: 'ٹھیک ہے',
|
||||||
|
},
|
||||||
|
Popconfirm: {
|
||||||
|
okText: 'ٹھیک ہے',
|
||||||
|
cancelText: 'منسوخ کریں',
|
||||||
|
},
|
||||||
|
Transfer: {
|
||||||
|
titles: ['', ''],
|
||||||
|
searchPlaceholder: 'یہاں تلاش کریں',
|
||||||
|
itemUnit: 'شے',
|
||||||
|
itemsUnit: 'اشیاء',
|
||||||
|
remove: 'ہٹائیں',
|
||||||
|
selectCurrent: 'موجودہ صفحہ منتخب کریں',
|
||||||
|
removeCurrent: 'موجودہ صفحہ ہٹائیں',
|
||||||
|
selectAll: 'تمام ڈیٹا کو منتخب کریں',
|
||||||
|
removeAll: 'تمام ڈیٹا کو ہٹا دیں',
|
||||||
|
selectInvert: 'موجودہ صفحے کو الٹ دیں',
|
||||||
|
},
|
||||||
|
Upload: {
|
||||||
|
uploading: 'اپ لوڈ ہو رہا ہے…',
|
||||||
|
removeFile: 'فائل کو ہٹا دیں',
|
||||||
|
uploadError: 'اپ لوڈ کی خرابی',
|
||||||
|
previewFile: 'پیش نظار فائل',
|
||||||
|
downloadFile: 'فائل ڈاؤن لوڈ کریں',
|
||||||
|
},
|
||||||
|
Empty: {
|
||||||
|
description: 'کوئی ڈیٹا نہیں',
|
||||||
|
},
|
||||||
|
Icon: {
|
||||||
|
icon: 'آئیکن',
|
||||||
|
},
|
||||||
|
Text: {
|
||||||
|
edit: 'ترمیم',
|
||||||
|
copy: 'کاپی',
|
||||||
|
copied: 'کاپی ہوگیا',
|
||||||
|
expand: 'پھیلائیں',
|
||||||
|
},
|
||||||
|
PageHeader: {
|
||||||
|
back: 'پیچھے',
|
||||||
|
},
|
||||||
|
Form: {
|
||||||
|
optional: '(اختیاری)',
|
||||||
|
defaultValidateMessages: {
|
||||||
|
default: ' ${label} کیلئے فیلڈ کی توثیق میں نقص',
|
||||||
|
required: 'درج کریں ${label}',
|
||||||
|
enum: '${label} ایک ہونا ضروری ہے [${enum}]',
|
||||||
|
whitespace: '${label} خالی نہیں ہوسکتا',
|
||||||
|
date: {
|
||||||
|
format: '${label} تاریخ کی شکل غلط ہے',
|
||||||
|
parse: '${label} تاریخ میں تبدیل نہیں کیا جاسکتا',
|
||||||
|
invalid: '${label} غلط تاریخ ہے',
|
||||||
|
},
|
||||||
|
types: {
|
||||||
|
string: typeTemplate,
|
||||||
|
method: typeTemplate,
|
||||||
|
array: typeTemplate,
|
||||||
|
object: typeTemplate,
|
||||||
|
number: typeTemplate,
|
||||||
|
date: typeTemplate,
|
||||||
|
boolean: typeTemplate,
|
||||||
|
integer: typeTemplate,
|
||||||
|
float: typeTemplate,
|
||||||
|
regexp: typeTemplate,
|
||||||
|
email: typeTemplate,
|
||||||
|
url: typeTemplate,
|
||||||
|
hex: typeTemplate,
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
len: '${label} ضروری ہے ${len} حروف',
|
||||||
|
min: '${label} کم از کم ہونا چاہئے ${min} حروف',
|
||||||
|
max: '${label} تک ہونا چاہئے ${max} حروف',
|
||||||
|
range: '${label} کے درمیان ہونا چاہئے ${min}-${max} حروف',
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
len: '${label} کے برابر ہونا چاہئے ${len}',
|
||||||
|
min: '${label} کم از کم ہونا چاہئے ${min}',
|
||||||
|
max: '${label} زیادہ سے زیادہ ہونا چاہئے ${max}',
|
||||||
|
range: '${label} کے درمیان ہونا چاہئے ${min}-${max}',
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
len: 'ضروری ہے ${len} ${label}',
|
||||||
|
min: 'کم از کم ${min} ${label}',
|
||||||
|
max: 'زیادہ سے زیادہ ${max} ${label}',
|
||||||
|
range: 'کی رقم ${label} کے درمیان ہونا چاہئے ${min}-${max}',
|
||||||
|
},
|
||||||
|
pattern: {
|
||||||
|
mismatch: '${label} پیٹرن سے ملتا نہیں ہے ${pattern}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Image: {
|
||||||
|
preview: 'پیش نظارہ',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default localeValues;
|
32
components/menu/MenuDivider.tsx
Normal file
32
components/menu/MenuDivider.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { Divider } from 'rc-menu';
|
||||||
|
import { ConfigContext } from '../config-provider';
|
||||||
|
|
||||||
|
export interface MenuDividerProps extends React.HTMLAttributes<HTMLLIElement> {
|
||||||
|
className?: string;
|
||||||
|
prefixCls?: string;
|
||||||
|
style?: React.CSSProperties;
|
||||||
|
dashed?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MenuDivider: React.FC<MenuDividerProps> = ({
|
||||||
|
prefixCls: customizePrefixCls,
|
||||||
|
className,
|
||||||
|
dashed,
|
||||||
|
...restProps
|
||||||
|
}) => {
|
||||||
|
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||||
|
|
||||||
|
const prefixCls = getPrefixCls('menu', customizePrefixCls);
|
||||||
|
const classString = classNames(
|
||||||
|
{
|
||||||
|
[`${prefixCls}-item-divider-dashed`]: !!dashed,
|
||||||
|
},
|
||||||
|
className,
|
||||||
|
);
|
||||||
|
|
||||||
|
return <Divider className={classString} {...restProps} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MenuDivider;
|
@ -821,4 +821,25 @@ describe('Menu', () => {
|
|||||||
expect(wrapper.find('.ant-menu-inline-collapsed-noicon').first().text()).toEqual('L');
|
expect(wrapper.find('.ant-menu-inline-collapsed-noicon').first().text()).toEqual('L');
|
||||||
expect(wrapper.find('.ant-menu-inline-collapsed-noicon').last().text()).toEqual('B');
|
expect(wrapper.find('.ant-menu-inline-collapsed-noicon').last().text()).toEqual('B');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('divider should show', () => {
|
||||||
|
const wrapper = mount(
|
||||||
|
<Menu mode="vertical">
|
||||||
|
<SubMenu key="sub1" title="Navigation One">
|
||||||
|
<Menu.Item key="1">Option 1</Menu.Item>
|
||||||
|
</SubMenu>
|
||||||
|
<Menu.Divider dashed />
|
||||||
|
<SubMenu key="sub2" title="Navigation Two">
|
||||||
|
<Menu.Item key="2">Option 2</Menu.Item>
|
||||||
|
</SubMenu>
|
||||||
|
<Menu.Divider />
|
||||||
|
<SubMenu key="sub4" title="Navigation Three">
|
||||||
|
<Menu.Item key="3">Option 3</Menu.Item>
|
||||||
|
</SubMenu>
|
||||||
|
</Menu>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(wrapper.find('li.ant-menu-item-divider').length).toBe(2);
|
||||||
|
expect(wrapper.find('li.ant-menu-item-divider-dashed').length).toBe(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -30,7 +30,7 @@ ReactDOM.render(
|
|||||||
<Menu.Item key="1">Option 1</Menu.Item>
|
<Menu.Item key="1">Option 1</Menu.Item>
|
||||||
<Menu.Item key="2">Option 2</Menu.Item>
|
<Menu.Item key="2">Option 2</Menu.Item>
|
||||||
</Menu.ItemGroup>
|
</Menu.ItemGroup>
|
||||||
<Menu.ItemGroup title="Iteom 2">
|
<Menu.ItemGroup title="Item 2">
|
||||||
<Menu.Item key="3">Option 3</Menu.Item>
|
<Menu.Item key="3">Option 3</Menu.Item>
|
||||||
<Menu.Item key="4">Option 4</Menu.Item>
|
<Menu.Item key="4">Option 4</Menu.Item>
|
||||||
</Menu.ItemGroup>
|
</Menu.ItemGroup>
|
||||||
|
@ -111,6 +111,10 @@ More layouts with navigation: [Layout](/components/layout).
|
|||||||
|
|
||||||
Divider line in between menu items, only used in vertical popup Menu or Dropdown Menu.
|
Divider line in between menu items, only used in vertical popup Menu or Dropdown Menu.
|
||||||
|
|
||||||
|
| Param | Description | Type | Default value | Version |
|
||||||
|
| ------ | ---------------------- | ------- | ------------- | ------- |
|
||||||
|
| dashed | Whether line is dashed | boolean | false | 4.17.0 |
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
### Why will Menu's children be rendered twice?
|
### Why will Menu's children be rendered twice?
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import RcMenu, { Divider, ItemGroup, MenuProps as RcMenuProps } from 'rc-menu';
|
import RcMenu, { ItemGroup, MenuProps as RcMenuProps } from 'rc-menu';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import omit from 'rc-util/lib/omit';
|
import omit from 'rc-util/lib/omit';
|
||||||
import EllipsisOutlined from '@ant-design/icons/EllipsisOutlined';
|
import EllipsisOutlined from '@ant-design/icons/EllipsisOutlined';
|
||||||
@ -11,6 +11,9 @@ import { SiderContext, SiderContextProps } from '../layout/Sider';
|
|||||||
import collapseMotion from '../_util/motion';
|
import collapseMotion from '../_util/motion';
|
||||||
import { cloneElement } from '../_util/reactNode';
|
import { cloneElement } from '../_util/reactNode';
|
||||||
import MenuContext, { MenuTheme } from './MenuContext';
|
import MenuContext, { MenuTheme } from './MenuContext';
|
||||||
|
import MenuDivider from './MenuDivider';
|
||||||
|
|
||||||
|
export { MenuDividerProps } from './MenuDivider';
|
||||||
|
|
||||||
export { MenuItemGroupProps } from 'rc-menu';
|
export { MenuItemGroupProps } from 'rc-menu';
|
||||||
|
|
||||||
@ -113,7 +116,7 @@ class InternalMenu extends React.Component<InternalMenuProps> {
|
|||||||
|
|
||||||
// We should keep this as ref-able
|
// We should keep this as ref-able
|
||||||
class Menu extends React.Component<MenuProps, {}> {
|
class Menu extends React.Component<MenuProps, {}> {
|
||||||
static Divider = Divider;
|
static Divider = MenuDivider;
|
||||||
|
|
||||||
static Item = Item;
|
static Item = Item;
|
||||||
|
|
||||||
|
@ -112,6 +112,10 @@ cover: https://gw.alipayobjects.com/zos/alicdn/3XZcjGpvK/Menu.svg
|
|||||||
|
|
||||||
菜单项分割线,只用在弹出菜单内。
|
菜单项分割线,只用在弹出菜单内。
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
|
| ------ | -------- | ------- | ------ | ------ |
|
||||||
|
| dashed | 是否虚线 | boolean | false | 4.17.0 |
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
### 为何 Menu 的子元素会渲染两次?
|
### 为何 Menu 的子元素会渲染两次?
|
||||||
|
@ -118,10 +118,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-item-divider {
|
&-item-divider {
|
||||||
height: 1px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
background-color: @border-color-split;
|
border-color: @border-color-split;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-item-divider-dashed {
|
||||||
|
border-style: dashed;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-horizontal &-item,
|
&-horizontal &-item,
|
||||||
@ -238,12 +243,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
& > &-item-divider {
|
& > &-item-divider {
|
||||||
height: 1px;
|
|
||||||
margin: 1px 0;
|
margin: 1px 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow: hidden;
|
|
||||||
line-height: 0;
|
|
||||||
background-color: @border-color-split;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-submenu {
|
&-submenu {
|
||||||
|
@ -96,19 +96,20 @@ describe('message.config', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to global config rootPrefixCls', () => {
|
it('should be able to global config rootPrefixCls', () => {
|
||||||
ConfigProvider.config({ prefixCls: 'prefix-test' });
|
ConfigProvider.config({ prefixCls: 'prefix-test', iconPrefixCls: 'bamboo' });
|
||||||
message.info('last');
|
message.info('last');
|
||||||
expect(document.querySelectorAll('.ant-message-notice').length).toBe(0);
|
expect(document.querySelectorAll('.ant-message-notice')).toHaveLength(0);
|
||||||
expect(document.querySelectorAll('.prefix-test-message-notice').length).toBe(1);
|
expect(document.querySelectorAll('.prefix-test-message-notice')).toHaveLength(1);
|
||||||
ConfigProvider.config({ prefixCls: 'ant' });
|
expect(document.querySelectorAll('.bamboo-info-circle')).toHaveLength(1);
|
||||||
|
ConfigProvider.config({ prefixCls: 'ant', iconPrefixCls: null });
|
||||||
});
|
});
|
||||||
it('should be able to config prefixCls', () => {
|
it('should be able to config prefixCls', () => {
|
||||||
message.config({
|
message.config({
|
||||||
prefixCls: 'prefix-test',
|
prefixCls: 'prefix-test',
|
||||||
});
|
});
|
||||||
message.info('last');
|
message.info('last');
|
||||||
expect(document.querySelectorAll('.ant-message-notice').length).toBe(0);
|
expect(document.querySelectorAll('.ant-message-notice')).toHaveLength(0);
|
||||||
expect(document.querySelectorAll('.prefix-test-notice').length).toBe(1);
|
expect(document.querySelectorAll('.prefix-test-notice')).toHaveLength(1);
|
||||||
message.config({
|
message.config({
|
||||||
prefixCls: '', // can be set to empty, ant default value is set in ConfigProvider
|
prefixCls: '', // can be set to empty, ant default value is set in ConfigProvider
|
||||||
});
|
});
|
||||||
@ -119,7 +120,7 @@ describe('message.config', () => {
|
|||||||
transitionName: '',
|
transitionName: '',
|
||||||
});
|
});
|
||||||
message.info('last');
|
message.info('last');
|
||||||
expect(document.querySelectorAll('.ant-move-up-enter').length).toBe(0);
|
expect(document.querySelectorAll('.ant-move-up-enter')).toHaveLength(0);
|
||||||
message.config({
|
message.config({
|
||||||
transitionName: 'ant-move-up',
|
transitionName: 'ant-move-up',
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,7 @@ import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
|
|||||||
import CheckCircleFilled from '@ant-design/icons/CheckCircleFilled';
|
import CheckCircleFilled from '@ant-design/icons/CheckCircleFilled';
|
||||||
import InfoCircleFilled from '@ant-design/icons/InfoCircleFilled';
|
import InfoCircleFilled from '@ant-design/icons/InfoCircleFilled';
|
||||||
import createUseMessage from './hooks/useMessage';
|
import createUseMessage from './hooks/useMessage';
|
||||||
import { globalConfig } from '../config-provider';
|
import ConfigProvider, { globalConfig } from '../config-provider';
|
||||||
|
|
||||||
type NoticeType = 'info' | 'success' | 'error' | 'warning' | 'loading';
|
type NoticeType = 'info' | 'success' | 'error' | 'warning' | 'loading';
|
||||||
|
|
||||||
@ -74,16 +74,18 @@ function getRCNotificationInstance(
|
|||||||
callback: (info: {
|
callback: (info: {
|
||||||
prefixCls: string;
|
prefixCls: string;
|
||||||
rootPrefixCls: string;
|
rootPrefixCls: string;
|
||||||
|
iconPrefixCls: string;
|
||||||
instance: RCNotificationInstance;
|
instance: RCNotificationInstance;
|
||||||
}) => void,
|
}) => void,
|
||||||
) {
|
) {
|
||||||
const { prefixCls: customizePrefixCls } = args;
|
const { prefixCls: customizePrefixCls } = args;
|
||||||
const { getPrefixCls, getRootPrefixCls } = globalConfig();
|
const { getPrefixCls, getRootPrefixCls, getIconPrefixCls } = globalConfig();
|
||||||
const prefixCls = getPrefixCls('message', customizePrefixCls || localPrefixCls);
|
const prefixCls = getPrefixCls('message', customizePrefixCls || localPrefixCls);
|
||||||
const rootPrefixCls = getRootPrefixCls(args.rootPrefixCls, prefixCls);
|
const rootPrefixCls = getRootPrefixCls(args.rootPrefixCls, prefixCls);
|
||||||
|
const iconPrefixCls = getIconPrefixCls();
|
||||||
|
|
||||||
if (messageInstance) {
|
if (messageInstance) {
|
||||||
callback({ prefixCls, rootPrefixCls, instance: messageInstance });
|
callback({ prefixCls, rootPrefixCls, iconPrefixCls, instance: messageInstance });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +99,7 @@ function getRCNotificationInstance(
|
|||||||
|
|
||||||
RCNotification.newInstance(instanceConfig, (instance: any) => {
|
RCNotification.newInstance(instanceConfig, (instance: any) => {
|
||||||
if (messageInstance) {
|
if (messageInstance) {
|
||||||
callback({ prefixCls, rootPrefixCls, instance: messageInstance });
|
callback({ prefixCls, rootPrefixCls, iconPrefixCls, instance: messageInstance });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
messageInstance = instance;
|
messageInstance = instance;
|
||||||
@ -106,7 +108,7 @@ function getRCNotificationInstance(
|
|||||||
(messageInstance as any).config = instanceConfig;
|
(messageInstance as any).config = instanceConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
callback({ prefixCls, rootPrefixCls, instance });
|
callback({ prefixCls, rootPrefixCls, iconPrefixCls, instance });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +141,11 @@ export interface ArgsProps {
|
|||||||
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
|
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRCNoticeProps(args: ArgsProps, prefixCls: string): NoticeContent {
|
function getRCNoticeProps(
|
||||||
|
args: ArgsProps,
|
||||||
|
prefixCls: string,
|
||||||
|
iconPrefixCls?: string,
|
||||||
|
): NoticeContent {
|
||||||
const duration = args.duration !== undefined ? args.duration : defaultDuration;
|
const duration = args.duration !== undefined ? args.duration : defaultDuration;
|
||||||
const IconComponent = typeToIcon[args.type];
|
const IconComponent = typeToIcon[args.type];
|
||||||
const messageClass = classNames(`${prefixCls}-custom-content`, {
|
const messageClass = classNames(`${prefixCls}-custom-content`, {
|
||||||
@ -152,10 +158,12 @@ function getRCNoticeProps(args: ArgsProps, prefixCls: string): NoticeContent {
|
|||||||
style: args.style || {},
|
style: args.style || {},
|
||||||
className: args.className,
|
className: args.className,
|
||||||
content: (
|
content: (
|
||||||
<div className={messageClass}>
|
<ConfigProvider iconPrefixCls={iconPrefixCls}>
|
||||||
{args.icon || (IconComponent && <IconComponent />)}
|
<div className={messageClass}>
|
||||||
<span>{args.content}</span>
|
{args.icon || (IconComponent && <IconComponent />)}
|
||||||
</div>
|
<span>{args.content}</span>
|
||||||
|
</div>
|
||||||
|
</ConfigProvider>
|
||||||
),
|
),
|
||||||
onClose: args.onClose,
|
onClose: args.onClose,
|
||||||
onClick: args.onClick,
|
onClick: args.onClick,
|
||||||
@ -172,8 +180,10 @@ function notice(args: ArgsProps): MessageType {
|
|||||||
return resolve(true);
|
return resolve(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
getRCNotificationInstance(args, ({ prefixCls, instance }) => {
|
getRCNotificationInstance(args, ({ prefixCls, iconPrefixCls, instance }) => {
|
||||||
instance.notice(getRCNoticeProps({ ...args, key: target, onClose: callback }, prefixCls));
|
instance.notice(
|
||||||
|
getRCNoticeProps({ ...args, key: target, onClose: callback }, prefixCls, iconPrefixCls),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const result: any = () => {
|
const result: any = () => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import Dialog, { ModalFuncProps } from './Modal';
|
import Dialog, { ModalFuncProps } from './Modal';
|
||||||
import ActionButton from './ActionButton';
|
import ActionButton from '../_util/ActionButton';
|
||||||
import devWarning from '../_util/devWarning';
|
import devWarning from '../_util/devWarning';
|
||||||
import ConfigProvider from '../config-provider';
|
import ConfigProvider from '../config-provider';
|
||||||
import { getTransitionName } from '../_util/motion';
|
import { getTransitionName } from '../_util/motion';
|
||||||
@ -11,6 +11,7 @@ interface ConfirmDialogProps extends ModalFuncProps {
|
|||||||
close: (...args: any[]) => void;
|
close: (...args: any[]) => void;
|
||||||
autoFocusButton?: null | 'ok' | 'cancel';
|
autoFocusButton?: null | 'ok' | 'cancel';
|
||||||
rootPrefixCls: string;
|
rootPrefixCls: string;
|
||||||
|
iconPrefixCls?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConfirmDialog = (props: ConfirmDialogProps) => {
|
const ConfirmDialog = (props: ConfirmDialogProps) => {
|
||||||
@ -33,6 +34,7 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
|
|||||||
direction,
|
direction,
|
||||||
prefixCls,
|
prefixCls,
|
||||||
rootPrefixCls,
|
rootPrefixCls,
|
||||||
|
iconPrefixCls,
|
||||||
bodyStyle,
|
bodyStyle,
|
||||||
closable = false,
|
closable = false,
|
||||||
closeIcon,
|
closeIcon,
|
||||||
@ -68,7 +70,7 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
|
|||||||
const cancelButton = okCancel && (
|
const cancelButton = okCancel && (
|
||||||
<ActionButton
|
<ActionButton
|
||||||
actionFn={onCancel}
|
actionFn={onCancel}
|
||||||
closeModal={close}
|
close={close}
|
||||||
autoFocus={autoFocusButton === 'cancel'}
|
autoFocus={autoFocusButton === 'cancel'}
|
||||||
buttonProps={cancelButtonProps}
|
buttonProps={cancelButtonProps}
|
||||||
prefixCls={`${rootPrefixCls}-btn`}
|
prefixCls={`${rootPrefixCls}-btn`}
|
||||||
@ -78,33 +80,33 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<ConfigProvider prefixCls={rootPrefixCls} iconPrefixCls={iconPrefixCls} direction={direction}>
|
||||||
prefixCls={prefixCls}
|
<Dialog
|
||||||
className={classString}
|
prefixCls={prefixCls}
|
||||||
wrapClassName={classNames({ [`${contentPrefixCls}-centered`]: !!props.centered })}
|
className={classString}
|
||||||
onCancel={() => close({ triggerCancel: true })}
|
wrapClassName={classNames({ [`${contentPrefixCls}-centered`]: !!props.centered })}
|
||||||
visible={visible}
|
onCancel={() => close({ triggerCancel: true })}
|
||||||
title=""
|
visible={visible}
|
||||||
footer=""
|
title=""
|
||||||
transitionName={getTransitionName(rootPrefixCls, 'zoom', props.transitionName)}
|
footer=""
|
||||||
maskTransitionName={getTransitionName(rootPrefixCls, 'fade', props.maskTransitionName)}
|
transitionName={getTransitionName(rootPrefixCls, 'zoom', props.transitionName)}
|
||||||
mask={mask}
|
maskTransitionName={getTransitionName(rootPrefixCls, 'fade', props.maskTransitionName)}
|
||||||
maskClosable={maskClosable}
|
mask={mask}
|
||||||
maskStyle={maskStyle}
|
maskClosable={maskClosable}
|
||||||
style={style}
|
maskStyle={maskStyle}
|
||||||
width={width}
|
style={style}
|
||||||
zIndex={zIndex}
|
width={width}
|
||||||
afterClose={afterClose}
|
zIndex={zIndex}
|
||||||
keyboard={keyboard}
|
afterClose={afterClose}
|
||||||
centered={centered}
|
keyboard={keyboard}
|
||||||
getContainer={getContainer}
|
centered={centered}
|
||||||
closable={closable}
|
getContainer={getContainer}
|
||||||
closeIcon={closeIcon}
|
closable={closable}
|
||||||
modalRender={modalRender}
|
closeIcon={closeIcon}
|
||||||
focusTriggerAfterClose={focusTriggerAfterClose}
|
modalRender={modalRender}
|
||||||
>
|
focusTriggerAfterClose={focusTriggerAfterClose}
|
||||||
<div className={`${contentPrefixCls}-body-wrapper`}>
|
>
|
||||||
<ConfigProvider prefixCls={rootPrefixCls} direction={direction}>
|
<div className={`${contentPrefixCls}-body-wrapper`}>
|
||||||
<div className={`${contentPrefixCls}-body`} style={bodyStyle}>
|
<div className={`${contentPrefixCls}-body`} style={bodyStyle}>
|
||||||
{icon}
|
{icon}
|
||||||
{props.title === undefined ? null : (
|
{props.title === undefined ? null : (
|
||||||
@ -112,22 +114,22 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
|
|||||||
)}
|
)}
|
||||||
<div className={`${contentPrefixCls}-content`}>{props.content}</div>
|
<div className={`${contentPrefixCls}-content`}>{props.content}</div>
|
||||||
</div>
|
</div>
|
||||||
</ConfigProvider>
|
<div className={`${contentPrefixCls}-btns`}>
|
||||||
<div className={`${contentPrefixCls}-btns`}>
|
{cancelButton}
|
||||||
{cancelButton}
|
<ActionButton
|
||||||
<ActionButton
|
type={okType}
|
||||||
type={okType}
|
actionFn={onOk}
|
||||||
actionFn={onOk}
|
close={close}
|
||||||
closeModal={close}
|
autoFocus={autoFocusButton === 'ok'}
|
||||||
autoFocus={autoFocusButton === 'ok'}
|
buttonProps={okButtonProps}
|
||||||
buttonProps={okButtonProps}
|
prefixCls={`${rootPrefixCls}-btn`}
|
||||||
prefixCls={`${rootPrefixCls}-btn`}
|
>
|
||||||
>
|
{okText}
|
||||||
{okText}
|
</ActionButton>
|
||||||
</ActionButton>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Dialog>
|
||||||
</Dialog>
|
</ConfigProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
import * as React from 'react';
|
||||||
import TestUtils, { act } from 'react-dom/test-utils';
|
import TestUtils, { act } from 'react-dom/test-utils';
|
||||||
import CSSMotion from 'rc-motion';
|
import CSSMotion from 'rc-motion';
|
||||||
|
import { SmileOutlined } from '@ant-design/icons';
|
||||||
import { genCSSMotion } from 'rc-motion/lib/CSSMotion';
|
import { genCSSMotion } from 'rc-motion/lib/CSSMotion';
|
||||||
import KeyCode from 'rc-util/lib/KeyCode';
|
import KeyCode from 'rc-util/lib/KeyCode';
|
||||||
import { resetWarned } from 'rc-util/lib/warning';
|
import { resetWarned } from 'rc-util/lib/warning';
|
||||||
@ -472,13 +474,14 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
|||||||
|
|
||||||
it('should be able to global config rootPrefixCls', () => {
|
it('should be able to global config rootPrefixCls', () => {
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
ConfigProvider.config({ prefixCls: 'my' });
|
ConfigProvider.config({ prefixCls: 'my', iconPrefixCls: 'bamboo' });
|
||||||
confirm({ title: 'title' });
|
confirm({ title: 'title', icon: <SmileOutlined /> });
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
expect(document.querySelectorAll('.ant-btn').length).toBe(0);
|
expect(document.querySelectorAll('.ant-btn').length).toBe(0);
|
||||||
expect(document.querySelectorAll('.my-btn').length).toBe(2);
|
expect(document.querySelectorAll('.my-btn').length).toBe(2);
|
||||||
|
expect(document.querySelectorAll('.bamboo-smile').length).toBe(1);
|
||||||
expect(document.querySelectorAll('.my-modal-confirm').length).toBe(1);
|
expect(document.querySelectorAll('.my-modal-confirm').length).toBe(1);
|
||||||
ConfigProvider.config({ prefixCls: 'ant' });
|
ConfigProvider.config({ prefixCls: 'ant', iconPrefixCls: null });
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -59,16 +59,18 @@ export default function confirm(config: ModalFuncProps) {
|
|||||||
*/
|
*/
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const runtimeLocale = getConfirmLocale();
|
const runtimeLocale = getConfirmLocale();
|
||||||
const { getPrefixCls } = globalConfig();
|
const { getPrefixCls, getIconPrefixCls } = globalConfig();
|
||||||
// because Modal.config set rootPrefixCls, which is different from other components
|
// because Modal.config set rootPrefixCls, which is different from other components
|
||||||
const rootPrefixCls = getPrefixCls(undefined, getRootPrefixCls());
|
const rootPrefixCls = getPrefixCls(undefined, getRootPrefixCls());
|
||||||
const prefixCls = customizePrefixCls || `${rootPrefixCls}-modal`;
|
const prefixCls = customizePrefixCls || `${rootPrefixCls}-modal`;
|
||||||
|
const iconPrefixCls = getIconPrefixCls();
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
{...props}
|
{...props}
|
||||||
prefixCls={prefixCls}
|
prefixCls={prefixCls}
|
||||||
rootPrefixCls={rootPrefixCls}
|
rootPrefixCls={rootPrefixCls}
|
||||||
|
iconPrefixCls={iconPrefixCls}
|
||||||
okText={okText || (props.okCancel ? runtimeLocale.okText : runtimeLocale.justOkText)}
|
okText={okText || (props.okCancel ? runtimeLocale.okText : runtimeLocale.justOkText)}
|
||||||
cancelText={cancelText || runtimeLocale.cancelText}
|
cancelText={cancelText || runtimeLocale.cancelText}
|
||||||
/>,
|
/>,
|
||||||
|
@ -11,7 +11,7 @@ title:
|
|||||||
|
|
||||||
## en-US
|
## en-US
|
||||||
|
|
||||||
Asynchronously close a modal dialog when a the OK button is pressed. For example, you can use this pattern when you submit a form.
|
Asynchronously close a modal dialog when the OK button is pressed. For example, you can use this pattern when you submit a form.
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { Modal, Button } from 'antd';
|
import { Modal, Button } from 'antd';
|
||||||
|
@ -11,7 +11,6 @@ import confirm, {
|
|||||||
import useModal from './useModal';
|
import useModal from './useModal';
|
||||||
import destroyFns from './destroyFns';
|
import destroyFns from './destroyFns';
|
||||||
|
|
||||||
export { ActionButtonProps } from './ActionButton';
|
|
||||||
export { ModalProps, ModalFuncProps } from './Modal';
|
export { ModalProps, ModalFuncProps } from './Modal';
|
||||||
|
|
||||||
function modalWarn(props: ModalFuncProps) {
|
function modalWarn(props: ModalFuncProps) {
|
||||||
|
44
components/notification/__tests__/config.test.js
Normal file
44
components/notification/__tests__/config.test.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import notification, { getInstance } from '..';
|
||||||
|
import { sleep } from '../../../tests/utils';
|
||||||
|
|
||||||
|
describe('notification.config', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
notification.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to config maxCount', async () => {
|
||||||
|
notification.config({
|
||||||
|
maxCount: 5,
|
||||||
|
duration: 0.5,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let i = 0; i < 10; i += 1) {
|
||||||
|
notification.open({
|
||||||
|
message: 'Notification message',
|
||||||
|
key: i,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.open({
|
||||||
|
message: 'Notification last',
|
||||||
|
key: '11',
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.resolve();
|
||||||
|
|
||||||
|
expect(document.querySelectorAll('.ant-notification-notice').length).toBe(5);
|
||||||
|
expect(document.querySelectorAll('.ant-notification-notice')[4].textContent).toBe(
|
||||||
|
'Notification last',
|
||||||
|
);
|
||||||
|
|
||||||
|
jest.runAllTimers();
|
||||||
|
await sleep(500);
|
||||||
|
expect((await getInstance('ant-notification-topRight')).component.state.notices).toHaveLength(
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -102,11 +102,12 @@ describe('notification', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to global config rootPrefixCls', () => {
|
it('should be able to global config rootPrefixCls', () => {
|
||||||
ConfigProvider.config({ prefixCls: 'prefix-test' });
|
ConfigProvider.config({ prefixCls: 'prefix-test', iconPrefixCls: 'bamboo' });
|
||||||
notification.open({ message: 'Notification Title', duration: 0 });
|
notification.success({ message: 'Notification Title', duration: 0 });
|
||||||
expect(document.querySelectorAll('.ant-notification-notice').length).toBe(0);
|
expect(document.querySelectorAll('.ant-notification-notice')).toHaveLength(0);
|
||||||
expect(document.querySelectorAll('.prefix-test-notification-notice').length).toBe(1);
|
expect(document.querySelectorAll('.prefix-test-notification-notice')).toHaveLength(1);
|
||||||
ConfigProvider.config({ prefixCls: 'ant' });
|
expect(document.querySelectorAll('.bamboo-check-circle')).toHaveLength(1);
|
||||||
|
ConfigProvider.config({ prefixCls: 'ant', iconPrefixCls: null });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to config prefixCls', () => {
|
it('should be able to config prefixCls', () => {
|
||||||
@ -117,8 +118,8 @@ describe('notification', () => {
|
|||||||
message: 'Notification Title',
|
message: 'Notification Title',
|
||||||
duration: 0,
|
duration: 0,
|
||||||
});
|
});
|
||||||
expect(document.querySelectorAll('.ant-notification-notice').length).toBe(0);
|
expect(document.querySelectorAll('.ant-notification-notice')).toHaveLength(0);
|
||||||
expect(document.querySelectorAll('.prefix-test-notice').length).toBe(1);
|
expect(document.querySelectorAll('.prefix-test-notice')).toHaveLength(1);
|
||||||
notification.config({
|
notification.config({
|
||||||
prefixCls: '',
|
prefixCls: '',
|
||||||
});
|
});
|
||||||
|
@ -65,7 +65,7 @@ notification.config({
|
|||||||
```
|
```
|
||||||
|
|
||||||
| Property | Description | Type | Default |
|
| Property | Description | Type | Default |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| bottom | Distance from the bottom of the viewport, when `placement` is `bottomRight` or `bottomLeft` (unit: pixels) | number | 24 |
|
| bottom | Distance from the bottom of the viewport, when `placement` is `bottomRight` or `bottomLeft` (unit: pixels) | number | 24 |
|
||||||
| closeIcon | Custom close icon | ReactNode | - |
|
| closeIcon | Custom close icon | ReactNode | - |
|
||||||
| duration | Time in seconds before Notification is closed. When set to 0 or null, it will never be closed automatically | number | 4.5 |
|
| duration | Time in seconds before Notification is closed. When set to 0 or null, it will never be closed automatically | number | 4.5 |
|
||||||
@ -73,6 +73,7 @@ notification.config({
|
|||||||
| placement | Position of Notification, can be one of `topLeft` `topRight` `bottomLeft` `bottomRight` | string | `topRight` |
|
| placement | Position of Notification, can be one of `topLeft` `topRight` `bottomLeft` `bottomRight` | string | `topRight` |
|
||||||
| rtl | Whether to enable RTL mode | boolean | false |
|
| rtl | Whether to enable RTL mode | boolean | false |
|
||||||
| top | Distance from the top of the viewport, when `placement` is `topRight` or `topLeft` (unit: pixels) | number | 24 |
|
| top | Distance from the top of the viewport, when `placement` is `topRight` or `topLeft` (unit: pixels) | number | 24 |
|
||||||
|
| maxCount | Max Notification show, drop oldest if exceed limit | number | - | |
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
@ -100,4 +101,4 @@ return (
|
|||||||
|
|
||||||
### How to set static methods prefixCls ?
|
### How to set static methods prefixCls ?
|
||||||
|
|
||||||
You can config with [`ConfigProvider.config`](/components/config-provider/#ConfigProvider.config()-4.13.0+)
|
You can config with [`ConfigProvider.config`](</components/config-provider/#ConfigProvider.config()-4.13.0+>)
|
||||||
|
@ -8,7 +8,7 @@ import CloseCircleOutlined from '@ant-design/icons/CloseCircleOutlined';
|
|||||||
import ExclamationCircleOutlined from '@ant-design/icons/ExclamationCircleOutlined';
|
import ExclamationCircleOutlined from '@ant-design/icons/ExclamationCircleOutlined';
|
||||||
import InfoCircleOutlined from '@ant-design/icons/InfoCircleOutlined';
|
import InfoCircleOutlined from '@ant-design/icons/InfoCircleOutlined';
|
||||||
import createUseNotification from './hooks/useNotification';
|
import createUseNotification from './hooks/useNotification';
|
||||||
import { globalConfig } from '../config-provider';
|
import ConfigProvider, { globalConfig } from '../config-provider';
|
||||||
|
|
||||||
export type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
|
export type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
|
||||||
|
|
||||||
@ -25,6 +25,7 @@ let defaultPlacement: NotificationPlacement = 'topRight';
|
|||||||
let defaultGetContainer: () => HTMLElement;
|
let defaultGetContainer: () => HTMLElement;
|
||||||
let defaultCloseIcon: React.ReactNode;
|
let defaultCloseIcon: React.ReactNode;
|
||||||
let rtl = false;
|
let rtl = false;
|
||||||
|
let maxCount: number;
|
||||||
|
|
||||||
export interface ConfigProps {
|
export interface ConfigProps {
|
||||||
top?: number;
|
top?: number;
|
||||||
@ -35,6 +36,7 @@ export interface ConfigProps {
|
|||||||
getContainer?: () => HTMLElement;
|
getContainer?: () => HTMLElement;
|
||||||
closeIcon?: React.ReactNode;
|
closeIcon?: React.ReactNode;
|
||||||
rtl?: boolean;
|
rtl?: boolean;
|
||||||
|
maxCount?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setNotificationConfig(options: ConfigProps) {
|
function setNotificationConfig(options: ConfigProps) {
|
||||||
@ -65,6 +67,9 @@ function setNotificationConfig(options: ConfigProps) {
|
|||||||
if (options.rtl !== undefined) {
|
if (options.rtl !== undefined) {
|
||||||
rtl = options.rtl;
|
rtl = options.rtl;
|
||||||
}
|
}
|
||||||
|
if (options.maxCount !== undefined) {
|
||||||
|
maxCount = options.maxCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPlacementStyle(
|
function getPlacementStyle(
|
||||||
@ -108,7 +113,11 @@ function getPlacementStyle(
|
|||||||
|
|
||||||
function getNotificationInstance(
|
function getNotificationInstance(
|
||||||
args: ArgsProps,
|
args: ArgsProps,
|
||||||
callback: (info: { prefixCls: string; instance: RCNotificationInstance }) => void,
|
callback: (info: {
|
||||||
|
prefixCls: string;
|
||||||
|
iconPrefixCls: string;
|
||||||
|
instance: RCNotificationInstance;
|
||||||
|
}) => void,
|
||||||
) {
|
) {
|
||||||
const {
|
const {
|
||||||
placement = defaultPlacement,
|
placement = defaultPlacement,
|
||||||
@ -118,14 +127,15 @@ function getNotificationInstance(
|
|||||||
closeIcon = defaultCloseIcon,
|
closeIcon = defaultCloseIcon,
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
} = args;
|
} = args;
|
||||||
const { getPrefixCls } = globalConfig();
|
const { getPrefixCls, getIconPrefixCls } = globalConfig();
|
||||||
const prefixCls = getPrefixCls('notification', customizePrefixCls || defaultPrefixCls);
|
const prefixCls = getPrefixCls('notification', customizePrefixCls || defaultPrefixCls);
|
||||||
|
const iconPrefixCls = getIconPrefixCls();
|
||||||
|
|
||||||
const cacheKey = `${prefixCls}-${placement}`;
|
const cacheKey = `${prefixCls}-${placement}`;
|
||||||
const cacheInstance = notificationInstance[cacheKey];
|
const cacheInstance = notificationInstance[cacheKey];
|
||||||
if (cacheInstance) {
|
if (cacheInstance) {
|
||||||
Promise.resolve(cacheInstance).then(instance => {
|
Promise.resolve(cacheInstance).then(instance => {
|
||||||
callback({ prefixCls: `${prefixCls}-notice`, instance });
|
callback({ prefixCls: `${prefixCls}-notice`, iconPrefixCls, instance });
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -149,11 +159,13 @@ function getNotificationInstance(
|
|||||||
style: getPlacementStyle(placement, top, bottom),
|
style: getPlacementStyle(placement, top, bottom),
|
||||||
getContainer,
|
getContainer,
|
||||||
closeIcon: closeIconToRender,
|
closeIcon: closeIconToRender,
|
||||||
|
maxCount,
|
||||||
},
|
},
|
||||||
notification => {
|
notification => {
|
||||||
resolve(notification);
|
resolve(notification);
|
||||||
callback({
|
callback({
|
||||||
prefixCls: `${prefixCls}-notice`,
|
prefixCls: `${prefixCls}-notice`,
|
||||||
|
iconPrefixCls,
|
||||||
instance: notification,
|
instance: notification,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -188,7 +200,7 @@ export interface ArgsProps {
|
|||||||
closeIcon?: React.ReactNode;
|
closeIcon?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRCNoticeProps(args: ArgsProps, prefixCls: string) {
|
function getRCNoticeProps(args: ArgsProps, prefixCls: string, iconPrefixCls?: string) {
|
||||||
const {
|
const {
|
||||||
duration: durationArg,
|
duration: durationArg,
|
||||||
icon,
|
icon,
|
||||||
@ -221,15 +233,17 @@ function getRCNoticeProps(args: ArgsProps, prefixCls: string) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
content: (
|
content: (
|
||||||
<div className={iconNode ? `${prefixCls}-with-icon` : ''} role="alert">
|
<ConfigProvider iconPrefixCls={iconPrefixCls}>
|
||||||
{iconNode}
|
<div className={iconNode ? `${prefixCls}-with-icon` : ''} role="alert">
|
||||||
<div className={`${prefixCls}-message`}>
|
{iconNode}
|
||||||
{autoMarginTag}
|
<div className={`${prefixCls}-message`}>
|
||||||
{message}
|
{autoMarginTag}
|
||||||
|
{message}
|
||||||
|
</div>
|
||||||
|
<div className={`${prefixCls}-description`}>{description}</div>
|
||||||
|
{btn ? <span className={`${prefixCls}-btn`}>{btn}</span> : null}
|
||||||
</div>
|
</div>
|
||||||
<div className={`${prefixCls}-description`}>{description}</div>
|
</ConfigProvider>
|
||||||
{btn ? <span className={`${prefixCls}-btn`}>{btn}</span> : null}
|
|
||||||
</div>
|
|
||||||
),
|
),
|
||||||
duration,
|
duration,
|
||||||
closable: true,
|
closable: true,
|
||||||
@ -244,8 +258,8 @@ function getRCNoticeProps(args: ArgsProps, prefixCls: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function notice(args: ArgsProps) {
|
function notice(args: ArgsProps) {
|
||||||
getNotificationInstance(args, ({ prefixCls, instance }) => {
|
getNotificationInstance(args, ({ prefixCls, iconPrefixCls, instance }) => {
|
||||||
instance.notice(getRCNoticeProps(args, prefixCls));
|
instance.notice(getRCNoticeProps(args, prefixCls, iconPrefixCls));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ notification.config({
|
|||||||
```
|
```
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 |
|
| 参数 | 说明 | 类型 | 默认值 |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| bottom | 消息从底部弹出时,距离底部的位置,单位像素 | number | 24 |
|
| bottom | 消息从底部弹出时,距离底部的位置,单位像素 | number | 24 |
|
||||||
| closeIcon | 自定义关闭图标 | ReactNode | - |
|
| closeIcon | 自定义关闭图标 | ReactNode | - |
|
||||||
| duration | 默认自动关闭延时,单位秒 | number | 4.5 |
|
| duration | 默认自动关闭延时,单位秒 | number | 4.5 |
|
||||||
@ -74,6 +74,7 @@ notification.config({
|
|||||||
| placement | 弹出位置,可选 `topLeft` `topRight` `bottomLeft` `bottomRight` | string | `topRight` |
|
| placement | 弹出位置,可选 `topLeft` `topRight` `bottomLeft` `bottomRight` | string | `topRight` |
|
||||||
| rtl | 是否开启 RTL 模式 | boolean | false |
|
| rtl | 是否开启 RTL 模式 | boolean | false |
|
||||||
| top | 消息从顶部弹出时,距离顶部的位置,单位像素 | number | 24 |
|
| top | 消息从顶部弹出时,距离顶部的位置,单位像素 | number | 24 |
|
||||||
|
| maxCount | 最大显示数, 超过限制时,最早的消息会被自动关闭 | number | - | |
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
@ -101,4 +102,4 @@ return (
|
|||||||
|
|
||||||
### 静态方法如何设置 prefixCls ?
|
### 静态方法如何设置 prefixCls ?
|
||||||
|
|
||||||
你可以通过 [`ConfigProvider.config`](/components/config-provider/#ConfigProvider.config()-4.13.0+) 进行设置。
|
你可以通过 [`ConfigProvider.config`](</components/config-provider/#ConfigProvider.config()-4.13.0+>) 进行设置。
|
||||||
|
@ -179,3 +179,14 @@ exports[`renders ./components/popconfirm/demo/placement.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`renders ./components/popconfirm/demo/promise.md correctly 1`] = `
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-btn-primary"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Open Popconfirm with Promise
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
@ -131,6 +131,24 @@ describe('Popconfirm', () => {
|
|||||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false, eventObject);
|
expect(onVisibleChange).toHaveBeenLastCalledWith(false, eventObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support onConfirm to return Promise', async () => {
|
||||||
|
const confirm = () => new Promise(res => setTimeout(res, 300));
|
||||||
|
const onVisibleChange = jest.fn();
|
||||||
|
const popconfirm = mount(
|
||||||
|
<Popconfirm title="code" onConfirm={confirm} onVisibleChange={onVisibleChange}>
|
||||||
|
<span>show me your code</span>
|
||||||
|
</Popconfirm>,
|
||||||
|
);
|
||||||
|
|
||||||
|
const triggerNode = popconfirm.find('span').at(0);
|
||||||
|
triggerNode.simulate('click');
|
||||||
|
expect(onVisibleChange).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
popconfirm.find('.ant-btn').at(0).simulate('click');
|
||||||
|
await sleep(400);
|
||||||
|
expect(onVisibleChange).toHaveBeenCalledWith(false, eventObject);
|
||||||
|
});
|
||||||
|
|
||||||
it('should support customize icon', () => {
|
it('should support customize icon', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Popconfirm title="code" icon={<span className="customize-icon">custom-icon</span>}>
|
<Popconfirm title="code" icon={<span className="customize-icon">custom-icon</span>}>
|
||||||
|
37
components/popconfirm/demo/promise.md
Normal file
37
components/popconfirm/demo/promise.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
order: 7
|
||||||
|
title:
|
||||||
|
zh-CN: 基于 Promise 的异步关闭
|
||||||
|
en-US: Asynchronously close on Promise
|
||||||
|
---
|
||||||
|
|
||||||
|
## zh-CN
|
||||||
|
|
||||||
|
点击确定后异步关闭 Popconfirm,例如提交表单。
|
||||||
|
|
||||||
|
## en-US
|
||||||
|
|
||||||
|
Asynchronously close a popconfirm when the OK button is pressed. For example, you can use this pattern when you submit a form.
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { Button, Popconfirm } from 'antd';
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
const confirm = () =>
|
||||||
|
new Promise(resolve => {
|
||||||
|
setTimeout(() => resolve(), 3000);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popconfirm
|
||||||
|
title="Title"
|
||||||
|
onConfirm={confirm}
|
||||||
|
onVisibleChange={() => console.log('visible change')}
|
||||||
|
>
|
||||||
|
<Button type="primary">Open Popconfirm with Promise</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ReactDOM.render(<App />, mountNode);
|
||||||
|
```
|
@ -12,6 +12,7 @@ import { ConfigContext } from '../config-provider';
|
|||||||
import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue';
|
import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue';
|
||||||
import { cloneElement } from '../_util/reactNode';
|
import { cloneElement } from '../_util/reactNode';
|
||||||
import { getTransitionName } from '../_util/motion';
|
import { getTransitionName } from '../_util/motion';
|
||||||
|
import ActionButton from '../_util/ActionButton';
|
||||||
|
|
||||||
export interface PopconfirmProps extends AbstractTooltipProps {
|
export interface PopconfirmProps extends AbstractTooltipProps {
|
||||||
title: React.ReactNode | RenderFunction;
|
title: React.ReactNode | RenderFunction;
|
||||||
@ -40,6 +41,7 @@ export interface PopconfirmLocale {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
||||||
|
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||||
const [visible, setVisible] = useMergedState(false, {
|
const [visible, setVisible] = useMergedState(false, {
|
||||||
value: props.visible,
|
value: props.visible,
|
||||||
defaultValue: props.defaultVisible,
|
defaultValue: props.defaultVisible,
|
||||||
@ -54,11 +56,12 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
|||||||
props.onVisibleChange?.(value, e);
|
props.onVisibleChange?.(value, e);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onConfirm = (e: React.MouseEvent<HTMLButtonElement>) => {
|
const close = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
settingVisible(false, e);
|
settingVisible(false, e);
|
||||||
props.onConfirm?.call(this, e);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onConfirm = (e: React.MouseEvent<HTMLButtonElement>) => props.onConfirm?.call(this, e);
|
||||||
|
|
||||||
const onCancel = (e: React.MouseEvent<HTMLButtonElement>) => {
|
const onCancel = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
settingVisible(false, e);
|
settingVisible(false, e);
|
||||||
props.onCancel?.call(this, e);
|
props.onCancel?.call(this, e);
|
||||||
@ -90,21 +93,21 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
|||||||
<Button onClick={onCancel} size="small" {...cancelButtonProps}>
|
<Button onClick={onCancel} size="small" {...cancelButtonProps}>
|
||||||
{cancelText || popconfirmLocale.cancelText}
|
{cancelText || popconfirmLocale.cancelText}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<ActionButton
|
||||||
onClick={onConfirm}
|
buttonProps={{ size: 'small', ...convertLegacyProps(okType), ...okButtonProps }}
|
||||||
{...convertLegacyProps(okType)}
|
actionFn={onConfirm}
|
||||||
size="small"
|
close={close}
|
||||||
{...okButtonProps}
|
prefixCls={getPrefixCls('btn')}
|
||||||
|
quitOnNullishReturnValue
|
||||||
|
emitEvent
|
||||||
>
|
>
|
||||||
{okText || popconfirmLocale.okText}
|
{okText || popconfirmLocale.okText}
|
||||||
</Button>
|
</ActionButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
placement,
|
placement,
|
||||||
|
@ -6,11 +6,12 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
|||||||
|
|
||||||
export interface SkeletonButtonProps extends Omit<SkeletonElementProps, 'size'> {
|
export interface SkeletonButtonProps extends Omit<SkeletonElementProps, 'size'> {
|
||||||
size?: 'large' | 'small' | 'default';
|
size?: 'large' | 'small' | 'default';
|
||||||
|
block?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SkeletonButton = (props: SkeletonButtonProps) => {
|
const SkeletonButton = (props: SkeletonButtonProps) => {
|
||||||
const renderSkeletonButton = ({ getPrefixCls }: ConfigConsumerProps) => {
|
const renderSkeletonButton = ({ getPrefixCls }: ConfigConsumerProps) => {
|
||||||
const { prefixCls: customizePrefixCls, className, active } = props;
|
const { prefixCls: customizePrefixCls, className, active, block = false } = props;
|
||||||
const prefixCls = getPrefixCls('skeleton', customizePrefixCls);
|
const prefixCls = getPrefixCls('skeleton', customizePrefixCls);
|
||||||
const otherProps = omit(props, ['prefixCls']);
|
const otherProps = omit(props, ['prefixCls']);
|
||||||
const cls = classNames(
|
const cls = classNames(
|
||||||
@ -18,6 +19,7 @@ const SkeletonButton = (props: SkeletonButtonProps) => {
|
|||||||
`${prefixCls}-element`,
|
`${prefixCls}-element`,
|
||||||
{
|
{
|
||||||
[`${prefixCls}-active`]: active,
|
[`${prefixCls}-active`]: active,
|
||||||
|
[`${prefixCls}-block`]: block,
|
||||||
},
|
},
|
||||||
className,
|
className,
|
||||||
);
|
);
|
||||||
|
@ -118,18 +118,6 @@ Array [
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
class="ant-space-item"
|
|
||||||
style="margin-right:8px"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="ant-skeleton ant-skeleton-element"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="ant-skeleton-button"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="ant-space-item"
|
class="ant-space-item"
|
||||||
style="margin-right:8px"
|
style="margin-right:8px"
|
||||||
@ -157,6 +145,15 @@ Array [
|
|||||||
</div>,
|
</div>,
|
||||||
<br />,
|
<br />,
|
||||||
<br />,
|
<br />,
|
||||||
|
<div
|
||||||
|
class="ant-skeleton ant-skeleton-element"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="ant-skeleton-button"
|
||||||
|
/>
|
||||||
|
</div>,
|
||||||
|
<br />,
|
||||||
|
<br />,
|
||||||
<div
|
<div
|
||||||
class="ant-skeleton ant-skeleton-element"
|
class="ant-skeleton ant-skeleton-element"
|
||||||
>
|
>
|
||||||
@ -222,6 +219,45 @@ Array [
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-row ant-form-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-col ant-form-item-label"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class=""
|
||||||
|
title="Button Block"
|
||||||
|
>
|
||||||
|
Button Block
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-col ant-form-item-control"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-form-item-control-input"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-form-item-control-input-content"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
aria-checked="false"
|
||||||
|
class="ant-switch"
|
||||||
|
role="switch"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-switch-handle"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="ant-switch-inner"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-row ant-form-item"
|
class="ant-row ant-form-item"
|
||||||
>
|
>
|
||||||
|
@ -250,6 +250,16 @@ exports[`Skeleton button element active 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`Skeleton button element block 1`] = `
|
||||||
|
<div
|
||||||
|
class="ant-skeleton ant-skeleton-element ant-skeleton-block"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="ant-skeleton-button"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Skeleton button element shape 1`] = `
|
exports[`Skeleton button element shape 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-skeleton ant-skeleton-element"
|
class="ant-skeleton ant-skeleton-element"
|
||||||
|
@ -80,6 +80,10 @@ describe('Skeleton', () => {
|
|||||||
const wrapper = genSkeletonButton({ active: true });
|
const wrapper = genSkeletonButton({ active: true });
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
it('block', () => {
|
||||||
|
const wrapper = genSkeletonButton({ block: true });
|
||||||
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
|
});
|
||||||
it('size', () => {
|
it('size', () => {
|
||||||
const wrapperDefault = genSkeletonButton({ size: 'default' });
|
const wrapperDefault = genSkeletonButton({ size: 'default' });
|
||||||
expect(wrapperDefault.render()).toMatchSnapshot();
|
expect(wrapperDefault.render()).toMatchSnapshot();
|
||||||
|
@ -19,6 +19,7 @@ import { Skeleton, Space, Divider, Switch, Form, Radio } from 'antd';
|
|||||||
class Demo extends React.Component {
|
class Demo extends React.Component {
|
||||||
state = {
|
state = {
|
||||||
active: false,
|
active: false,
|
||||||
|
block: false,
|
||||||
size: 'default',
|
size: 'default',
|
||||||
buttonShape: 'default',
|
buttonShape: 'default',
|
||||||
avatarShape: 'circle',
|
avatarShape: 'circle',
|
||||||
@ -28,6 +29,10 @@ class Demo extends React.Component {
|
|||||||
this.setState({ active: checked });
|
this.setState({ active: checked });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleBlockChange = checked => {
|
||||||
|
this.setState({ block: checked });
|
||||||
|
};
|
||||||
|
|
||||||
handleSizeChange = e => {
|
handleSizeChange = e => {
|
||||||
this.setState({ size: e.target.value });
|
this.setState({ size: e.target.value });
|
||||||
};
|
};
|
||||||
@ -37,23 +42,28 @@ class Demo extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { active, size, buttonShape, avatarShape } = this.state;
|
const { active, size, buttonShape, avatarShape, block } = this.state;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Space>
|
<Space>
|
||||||
<Skeleton.Button active={active} size={size} shape={buttonShape} />
|
<Skeleton.Button active={active} size={size} shape={buttonShape} block={block} />
|
||||||
<Skeleton.Button active={active} size={size} shape={buttonShape} />
|
|
||||||
<Skeleton.Avatar active={active} size={size} shape={avatarShape} />
|
<Skeleton.Avatar active={active} size={size} shape={avatarShape} />
|
||||||
<Skeleton.Input style={{ width: 200 }} active={active} size={size} />
|
<Skeleton.Input style={{ width: 200 }} active={active} size={size} />
|
||||||
</Space>
|
</Space>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
<Skeleton.Button active={active} size={size} shape={buttonShape} block={block} />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
<Skeleton.Image />
|
<Skeleton.Image />
|
||||||
<Divider />
|
<Divider />
|
||||||
<Form layout="inline" style={{ margin: '16px 0' }}>
|
<Form layout="inline" style={{ margin: '16px 0' }}>
|
||||||
<Form.Item label="Active">
|
<Form.Item label="Active">
|
||||||
<Switch checked={active} onChange={this.handleActiveChange} />
|
<Switch checked={active} onChange={this.handleActiveChange} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item label="Button Block">
|
||||||
|
<Switch checked={block} onChange={this.handleBlockChange} />
|
||||||
|
</Form.Item>
|
||||||
<Form.Item label="Size">
|
<Form.Item label="Size">
|
||||||
<Radio.Group value={size} onChange={this.handleSizeChange}>
|
<Radio.Group value={size} onChange={this.handleSizeChange}>
|
||||||
<Radio.Button value="default">Default</Radio.Button>
|
<Radio.Button value="default">Default</Radio.Button>
|
||||||
|
@ -38,9 +38,9 @@ Provide a placeholder while you wait for content to load, or to visualise conten
|
|||||||
|
|
||||||
### SkeletonTitleProps
|
### SkeletonTitleProps
|
||||||
|
|
||||||
| Property | Description | Type | Default |
|
| Property | Description | Type | Default |
|
||||||
| --- | --- | --- | --- |
|
| -------- | ---------------------- | ---------------- | ------- |
|
||||||
| width | Set the width of title | number \| string | - |
|
| width | Set the width of title | number \| string | - |
|
||||||
|
|
||||||
### SkeletonParagraphProps
|
### SkeletonParagraphProps
|
||||||
|
|
||||||
@ -54,12 +54,13 @@ Provide a placeholder while you wait for content to load, or to visualise conten
|
|||||||
| Property | Description | Type | Default |
|
| Property | Description | Type | Default |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| active | Show animation effect | boolean | false |
|
| active | Show animation effect | boolean | false |
|
||||||
|
| block | Option to fit button width to its parent width | boolean | false |
|
||||||
| shape | Set the shape of button | `circle` \| `round` \| `default` | - |
|
| shape | Set the shape of button | `circle` \| `round` \| `default` | - |
|
||||||
| size | Set the size of button | `large` \| `small` \| `default` | - |
|
| size | Set the size of button | `large` \| `small` \| `default` | - |
|
||||||
|
|
||||||
### SkeletonInputProps
|
### SkeletonInputProps
|
||||||
|
|
||||||
| Property | Description | Type | Default |
|
| Property | Description | Type | Default |
|
||||||
| --- | --- | --- | --- |
|
| -------- | --------------------- | ------------------------------- | ------- |
|
||||||
| active | Show animation effect | boolean | false |
|
| active | Show animation effect | boolean | false |
|
||||||
| size | Set the size of input | `large` \| `small` \| `default` | - |
|
| size | Set the size of input | `large` \| `small` \| `default` | - |
|
||||||
|
@ -39,9 +39,9 @@ cover: https://gw.alipayobjects.com/zos/alicdn/KpcciCJgv/Skeleton.svg
|
|||||||
|
|
||||||
### SkeletonTitleProps
|
### SkeletonTitleProps
|
||||||
|
|
||||||
| 属性 | 说明 | 类型 | 默认值 |
|
| 属性 | 说明 | 类型 | 默认值 |
|
||||||
| --- | --- | --- | --- |
|
| ----- | -------------------- | ---------------- | ------ |
|
||||||
| width | 设置标题占位图的宽度 | number \| string | - |
|
| width | 设置标题占位图的宽度 | number \| string | - |
|
||||||
|
|
||||||
### SkeletonParagraphProps
|
### SkeletonParagraphProps
|
||||||
|
|
||||||
@ -52,15 +52,16 @@ cover: https://gw.alipayobjects.com/zos/alicdn/KpcciCJgv/Skeleton.svg
|
|||||||
|
|
||||||
### SkeletonButtonProps
|
### SkeletonButtonProps
|
||||||
|
|
||||||
| 属性 | 说明 | 类型 | 默认值 |
|
| 属性 | 说明 | 类型 | 默认值 |
|
||||||
| --- | --- | --- | --- |
|
| ------ | ------------------------------ | -------------------------------- | ------ |
|
||||||
| active | 是否展示动画效果 | boolean | false |
|
| active | 是否展示动画效果 | boolean | false |
|
||||||
| shape | 指定按钮的形状 | `circle` \| `round` \| `default` | - |
|
| block | 将按钮宽度调整为其父宽度的选项 | boolean | false |
|
||||||
| size | 设置按钮的大小 | `large` \| `small` \| `default` | - |
|
| shape | 指定按钮的形状 | `circle` \| `round` \| `default` | - |
|
||||||
|
| size | 设置按钮的大小 | `large` \| `small` \| `default` | - |
|
||||||
|
|
||||||
### SkeletonInputProps
|
### SkeletonInputProps
|
||||||
|
|
||||||
| 属性 | 说明 | 类型 | 默认值 |
|
| 属性 | 说明 | 类型 | 默认值 |
|
||||||
| --- | --- | --- | --- |
|
| ------ | ---------------- | ------------------------------- | ------ |
|
||||||
| active | 是否展示动画效果 | boolean | false |
|
| active | 是否展示动画效果 | boolean | false |
|
||||||
| size | 设置输入框的大小 | `large` \| `small` \| `default` | - |
|
| size | 设置输入框的大小 | `large` \| `small` \| `default` | - |
|
||||||
|
@ -109,6 +109,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skeleton Block Button
|
||||||
|
&.@{skeleton-prefix-cls}-block {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.@{skeleton-button-prefix-cls} {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Skeleton element
|
// Skeleton element
|
||||||
&-element {
|
&-element {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -214,10 +223,12 @@
|
|||||||
|
|
||||||
.skeleton-element-button-size(@size) {
|
.skeleton-element-button-size(@size) {
|
||||||
width: @size * 2;
|
width: @size * 2;
|
||||||
|
min-width: @size * 2;
|
||||||
.skeleton-element-common-size(@size);
|
.skeleton-element-common-size(@size);
|
||||||
|
|
||||||
&.@{skeleton-button-prefix-cls}-circle {
|
&.@{skeleton-button-prefix-cls}-circle {
|
||||||
width: @size;
|
width: @size;
|
||||||
|
min-width: @size;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,6 +230,7 @@
|
|||||||
@checkbox-check-color: #fff;
|
@checkbox-check-color: #fff;
|
||||||
@checkbox-check-bg: @checkbox-check-color;
|
@checkbox-check-bg: @checkbox-check-color;
|
||||||
@checkbox-border-width: @border-width-base;
|
@checkbox-border-width: @border-width-base;
|
||||||
|
@checkbox-border-radius: @border-radius-base;
|
||||||
@checkbox-group-item-margin-right: 8px;
|
@checkbox-group-item-margin-right: 8px;
|
||||||
|
|
||||||
// Descriptions
|
// Descriptions
|
||||||
|
@ -16705,7 +16705,21 @@ exports[`renders ./components/table/demo/sticky.md correctly 1`] = `
|
|||||||
colspan="2"
|
colspan="2"
|
||||||
style="position:sticky;left:0"
|
style="position:sticky;left:0"
|
||||||
>
|
>
|
||||||
Fix Left
|
<button
|
||||||
|
aria-checked="false"
|
||||||
|
class="ant-switch"
|
||||||
|
role="switch"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-switch-handle"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="ant-switch-inner"
|
||||||
|
>
|
||||||
|
Fixed Top
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
|
@ -14,7 +14,7 @@ title:
|
|||||||
For long table,need to scroll to view the header and scroll bar,then you can now set the fixed header and scroll bar to follow the page.
|
For long table,need to scroll to view the header and scroll bar,then you can now set the fixed header and scroll bar to follow the page.
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { Table } from 'antd';
|
import { Table, Switch } from 'antd';
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
@ -93,26 +93,38 @@ for (let i = 0; i < 100; i++) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ReactDOM.render(
|
const Demo = () => {
|
||||||
<Table
|
const [fixedTop, setFixedTop] = React.useState(false);
|
||||||
columns={columns}
|
|
||||||
dataSource={data}
|
return (
|
||||||
scroll={{ x: 1500 }}
|
<Table
|
||||||
summary={pageData => (
|
columns={columns}
|
||||||
<Table.Summary fixed>
|
dataSource={data}
|
||||||
<Table.Summary.Row>
|
scroll={{ x: 1500 }}
|
||||||
<Table.Summary.Cell index={0} colSpan={2}>
|
summary={pageData => (
|
||||||
Fix Left
|
<Table.Summary fixed={fixedTop ? 'top' : 'bottom'}>
|
||||||
</Table.Summary.Cell>
|
<Table.Summary.Row>
|
||||||
<Table.Summary.Cell index={2} colSpan={8}>
|
<Table.Summary.Cell index={0} colSpan={2}>
|
||||||
Scroll Context
|
<Switch
|
||||||
</Table.Summary.Cell>
|
checkedChildren="Fixed Top"
|
||||||
<Table.Summary.Cell index={10}>Fix Right</Table.Summary.Cell>
|
unCheckedChildren="Fixed Top"
|
||||||
</Table.Summary.Row>
|
checked={fixedTop}
|
||||||
</Table.Summary>
|
onChange={() => {
|
||||||
)}
|
setFixedTop(!fixedTop);
|
||||||
sticky
|
}}
|
||||||
/>,
|
/>
|
||||||
mountNode,
|
</Table.Summary.Cell>
|
||||||
);
|
<Table.Summary.Cell index={2} colSpan={8}>
|
||||||
|
Scroll Context
|
||||||
|
</Table.Summary.Cell>
|
||||||
|
<Table.Summary.Cell index={10}>Fix Right</Table.Summary.Cell>
|
||||||
|
</Table.Summary.Row>
|
||||||
|
</Table.Summary>
|
||||||
|
)}
|
||||||
|
sticky
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ReactDOM.render(<Demo />, mountNode);
|
||||||
```
|
```
|
||||||
|
8
components/time-picker/locale/bn_BD.tsx
Normal file
8
components/time-picker/locale/bn_BD.tsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { TimePickerLocale } from '../index';
|
||||||
|
|
||||||
|
const locale: TimePickerLocale = {
|
||||||
|
placeholder: 'সময় নির্বাচন',
|
||||||
|
rangePlaceholder: ['সময় শুরু', 'শেষ সময়'],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default locale;
|
8
components/time-picker/locale/ml_IN.tsx
Normal file
8
components/time-picker/locale/ml_IN.tsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { TimePickerLocale } from '../index';
|
||||||
|
|
||||||
|
const locale: TimePickerLocale = {
|
||||||
|
placeholder: 'സമയം തിരഞ്ഞെടുക്കുക',
|
||||||
|
rangePlaceholder: ['ആരംഭ സമയം', 'അവസാന സമയം'],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default locale;
|
8
components/time-picker/locale/ur_PK.tsx
Normal file
8
components/time-picker/locale/ur_PK.tsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { TimePickerLocale } from '../index';
|
||||||
|
|
||||||
|
const locale: TimePickerLocale = {
|
||||||
|
placeholder: 'وقت منتخب کریں',
|
||||||
|
rangePlaceholder: ['وقت منتخب کریں', 'آخر وقت'],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default locale;
|
@ -146,11 +146,11 @@ exports[`renders ./components/transfer/demo/advanced.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="ant-btn ant-btn-sm"
|
class="ant-btn ant-btn-sm"
|
||||||
style="float:right;margin:5px"
|
style="float:left;margin:5px"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
reload
|
Left button reload
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -361,7 +361,7 @@ exports[`renders ./components/transfer/demo/advanced.md correctly 1`] = `
|
|||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
reload
|
Right button reload
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -4247,11 +4247,11 @@ exports[`renders ./components/transfer/demo/tree-transfer.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-tree ant-tree-icon-hide ant-tree-block-node"
|
class="ant-tree ant-tree-icon-hide ant-tree-block-node"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
role="tree"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
aria-label="for screen reader"
|
||||||
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
style="width:0;height:0;display:flex;overflow:hidden;opacity:0;border:0;padding:0;margin:0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
value=""
|
value=""
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user