mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-09 02:49:18 +08:00
Merge branch 'feature' into change-styles-classnames-ts-1
This commit is contained in:
@@ -3,35 +3,52 @@ import { useMemo } from 'react';
|
||||
export interface MaskConfig {
|
||||
enabled?: boolean;
|
||||
blur?: boolean;
|
||||
closable?: boolean;
|
||||
}
|
||||
export type MaskType = MaskConfig | boolean;
|
||||
|
||||
const normalizeMaskConfig = (mask?: MaskType): MaskConfig => {
|
||||
export const normalizeMaskConfig = (mask?: MaskType, maskClosable?: boolean): MaskConfig => {
|
||||
let maskConfig: MaskConfig = {};
|
||||
|
||||
if (mask && typeof mask === 'object') {
|
||||
return mask;
|
||||
maskConfig = mask;
|
||||
}
|
||||
if (typeof mask === 'boolean') {
|
||||
return {
|
||||
maskConfig = {
|
||||
enabled: mask,
|
||||
blur: false,
|
||||
};
|
||||
}
|
||||
return {};
|
||||
|
||||
if (maskConfig.closable === undefined && maskClosable !== undefined) {
|
||||
maskConfig.closable = maskClosable;
|
||||
}
|
||||
|
||||
return maskConfig;
|
||||
};
|
||||
|
||||
export const useMergedMask = (
|
||||
mask?: MaskType,
|
||||
contextMask?: MaskType,
|
||||
prefixCls?: string,
|
||||
): [boolean, { [key: string]: string | undefined }] => {
|
||||
maskClosable?: boolean,
|
||||
): [
|
||||
config: boolean,
|
||||
maskBlurClassName: { [key: string]: string | undefined },
|
||||
maskClosable: boolean,
|
||||
] => {
|
||||
return useMemo(() => {
|
||||
const maskConfig = normalizeMaskConfig(mask);
|
||||
const maskConfig = normalizeMaskConfig(mask, maskClosable);
|
||||
const contextMaskConfig = normalizeMaskConfig(contextMask);
|
||||
|
||||
const mergedConfig: MaskConfig = { ...contextMaskConfig, ...maskConfig };
|
||||
const mergedConfig: MaskConfig = {
|
||||
blur: false,
|
||||
...contextMaskConfig,
|
||||
...maskConfig,
|
||||
closable: maskConfig.closable ?? maskClosable ?? contextMaskConfig.closable ?? true,
|
||||
};
|
||||
|
||||
const className = mergedConfig.blur ? `${prefixCls}-mask-blur` : undefined;
|
||||
|
||||
return [mergedConfig.enabled !== false, { mask: className }];
|
||||
}, [mask, contextMask, prefixCls]);
|
||||
return [mergedConfig.enabled !== false, { mask: className }, !!mergedConfig.closable];
|
||||
}, [mask, contextMask, prefixCls, maskClosable]);
|
||||
};
|
||||
|
||||
@@ -59,6 +59,8 @@ export interface DrawerProps
|
||||
* @since 5.25.0
|
||||
*/
|
||||
destroyOnHidden?: boolean;
|
||||
/** @deprecated Please use `mask.closable` instead */
|
||||
maskClosable?: boolean;
|
||||
mask?: MaskType;
|
||||
|
||||
focusable?: FocusableConfig;
|
||||
@@ -94,6 +96,7 @@ const Drawer: React.FC<DrawerProps> & {
|
||||
focusable,
|
||||
|
||||
// Deprecated
|
||||
maskClosable,
|
||||
maskStyle,
|
||||
drawerStyle,
|
||||
contentWrapperStyle,
|
||||
@@ -140,6 +143,7 @@ const Drawer: React.FC<DrawerProps> & {
|
||||
['destroyInactivePanel', 'destroyOnHidden'],
|
||||
['width', 'size'],
|
||||
['height', 'size'],
|
||||
['maskClosable', 'mask.closable'],
|
||||
].forEach(([deprecatedName, newName]) => {
|
||||
warning.deprecated(!(deprecatedName in props), deprecatedName, newName);
|
||||
});
|
||||
@@ -206,7 +210,12 @@ const Drawer: React.FC<DrawerProps> & {
|
||||
const [zIndex, contextZIndex] = useZIndex('Drawer', rest.zIndex);
|
||||
|
||||
// ============================ Mask ============================
|
||||
const [mergedMask, maskBlurClassName] = useMergedMask(drawerMask, contextMask, prefixCls);
|
||||
const [mergedMask, maskBlurClassName, mergedMaskClosable] = useMergedMask(
|
||||
drawerMask,
|
||||
contextMask,
|
||||
prefixCls,
|
||||
maskClosable,
|
||||
);
|
||||
|
||||
// ========================== Focusable =========================
|
||||
const mergedFocusable = useFocusable(focusable, getContainer !== false && mergedMask);
|
||||
@@ -218,6 +227,7 @@ const Drawer: React.FC<DrawerProps> & {
|
||||
zIndex,
|
||||
panelRef,
|
||||
mask: mergedMask,
|
||||
maskClosable: mergedMaskClosable,
|
||||
defaultSize,
|
||||
push,
|
||||
focusable: mergedFocusable,
|
||||
@@ -265,6 +275,7 @@ const Drawer: React.FC<DrawerProps> & {
|
||||
}}
|
||||
open={open}
|
||||
mask={mergedMask}
|
||||
maskClosable={mergedMaskClosable}
|
||||
push={push}
|
||||
size={drawerSize}
|
||||
defaultSize={defaultSize}
|
||||
|
||||
@@ -3,6 +3,7 @@ import React from 'react';
|
||||
import type { DrawerProps } from '..';
|
||||
import Drawer from '..';
|
||||
import { act, fireEvent, render } from '../../../tests/utils';
|
||||
import ConfigProvider from '../../config-provider';
|
||||
|
||||
const DrawerTest: React.FC<DrawerProps> = (props) => (
|
||||
<Drawer open getContainer={false} {...props}>
|
||||
@@ -81,6 +82,47 @@ describe('Drawer', () => {
|
||||
expect(onClose).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('mask.closable no trigger onClose', () => {
|
||||
const onClose = jest.fn();
|
||||
const { container } = render(<DrawerTest onClose={onClose} mask={{ closable: false }} />);
|
||||
|
||||
fireEvent.click(container.querySelector('.ant-drawer-mask')!);
|
||||
expect(onClose).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("mask.closable no trigger onClose by ConfigProvider's drawer config", () => {
|
||||
const onClose = jest.fn();
|
||||
const { container } = render(
|
||||
<ConfigProvider drawer={{ mask: { closable: false } }}>
|
||||
<DrawerTest onClose={onClose} />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
fireEvent.click(container.querySelector('.ant-drawer-mask')!);
|
||||
expect(onClose).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("mask.closable no trigger onClose when maskClosable is false and ConfigProvider's drawer config is true", () => {
|
||||
const onClose = jest.fn();
|
||||
const { container } = render(
|
||||
<ConfigProvider drawer={{ mask: { closable: false } }}>
|
||||
<DrawerTest onClose={onClose} maskClosable={false} />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
fireEvent.click(container.querySelector('.ant-drawer-mask')!);
|
||||
expect(onClose).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("mask.closable trigger onClose when maskClosable is true and ConfigProvider's drawer config is false", () => {
|
||||
const onClose = jest.fn();
|
||||
const { container } = render(
|
||||
<ConfigProvider drawer={{ mask: { closable: false } }}>
|
||||
<DrawerTest onClose={onClose} maskClosable={true} />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
fireEvent.click(container.querySelector('.ant-drawer-mask')!);
|
||||
expect(onClose).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('dom should be removed after close when destroyOnHidden is true', () => {
|
||||
const { container, rerender } = render(<DrawerTest destroyOnHidden />);
|
||||
expect(container.querySelector('.ant-drawer')).toBeTruthy();
|
||||
|
||||
@@ -70,8 +70,8 @@ v5 uses `rootClassName` & `rootStyle` to configure the outermost element style,
|
||||
| ~~height~~ | Placement is `top` or `bottom`, height of the Drawer dialog, please use `size` instead | string \| number | 378 | |
|
||||
| keyboard | Whether support press esc to close | boolean | true | |
|
||||
| loading | Show the Skeleton | boolean | false | 5.17.0 |
|
||||
| mask | Mask effect | boolean \| `{ enabled?: boolean, blur?: boolean }` | true | |
|
||||
| maskClosable | Clicking on the mask (area outside the Drawer) to close the Drawer or not | boolean | true | |
|
||||
| mask | Mask effect | boolean \| `{ enabled?: boolean, blur?: boolean, closable?: boolean }` | true | mask.closable: 6.3.0 |
|
||||
| ~~maskClosable~~ | Clicking on the mask (area outside the Drawer) to close the Drawer or not | boolean | true | |
|
||||
| maxSize | Maximum size (width or height depending on `placement`) when resizable | number | - | 6.0.0 |
|
||||
| open | Whether the Drawer dialog is visible or not | boolean | false | |
|
||||
| placement | The placement of the Drawer | `top` \| `right` \| `bottom` \| `left` | `right` | |
|
||||
|
||||
@@ -70,8 +70,8 @@ v5 使用 `rootClassName` 与 `rootStyle` 来配置最外层元素样式。原 v
|
||||
| ~~height~~ | 高度,在 `placement` 为 `top` 或 `bottom` 时使用,请使用 `size` 替换 | string \| number | 378 | |
|
||||
| keyboard | 是否支持键盘 esc 关闭 | boolean | true | |
|
||||
| loading | 显示骨架屏 | boolean | false | 5.17.0 |
|
||||
| mask | 遮罩效果 | boolean \| `{ enabled?: boolean, blur?: boolean }` | true | |
|
||||
| maskClosable | 点击蒙层是否允许关闭 | boolean | true | |
|
||||
| mask | 遮罩效果 | boolean \| `{ enabled?: boolean, blur?: boolean, closable?: boolean }` | true | mask.closable: 6.3.0 |
|
||||
| ~~maskClosable~~ | 点击蒙层是否允许关闭 | boolean | true | |
|
||||
| maxSize | 可拖拽的最大尺寸(宽度或高度,取决于 `placement`) | number | - | 6.0.0 |
|
||||
| open | Drawer 是否可见 | boolean | false | |
|
||||
| placement | 抽屉的方向 | `top` \| `right` \| `bottom` \| `left` | `right` | |
|
||||
|
||||
@@ -5,7 +5,7 @@ import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled';
|
||||
import InfoCircleFilled from '@ant-design/icons/InfoCircleFilled';
|
||||
import { clsx } from 'clsx';
|
||||
|
||||
import { CONTAINER_MAX_OFFSET } from '../_util/hooks';
|
||||
import { CONTAINER_MAX_OFFSET, normalizeMaskConfig } from '../_util/hooks';
|
||||
import { getTransitionName } from '../_util/motion';
|
||||
import { devUseWarning } from '../_util/warning';
|
||||
import type { ThemeConfig } from '../config-provider';
|
||||
@@ -183,6 +183,8 @@ const ConfirmDialog: React.FC<ConfirmDialogProps> = (props) => {
|
||||
onConfirm,
|
||||
styles,
|
||||
title,
|
||||
mask,
|
||||
maskClosable,
|
||||
okButtonProps,
|
||||
cancelButtonProps,
|
||||
} = props;
|
||||
@@ -215,7 +217,13 @@ const ConfirmDialog: React.FC<ConfirmDialogProps> = (props) => {
|
||||
|
||||
// ========================== Mask ==========================
|
||||
// 默认为 false,保持旧版默认行为
|
||||
const maskClosable = props.maskClosable === undefined ? false : props.maskClosable;
|
||||
const mergedMask = React.useMemo(() => {
|
||||
const nextMaskConfig = normalizeMaskConfig(mask, maskClosable);
|
||||
|
||||
nextMaskConfig.closable ??= false;
|
||||
|
||||
return nextMaskConfig;
|
||||
}, [mask, maskClosable]);
|
||||
|
||||
// ========================= zIndex =========================
|
||||
const [, token] = useToken();
|
||||
@@ -243,7 +251,7 @@ const ConfirmDialog: React.FC<ConfirmDialogProps> = (props) => {
|
||||
footer={null}
|
||||
transitionName={getTransitionName(rootPrefixCls || '', 'zoom', props.transitionName)}
|
||||
maskTransitionName={getTransitionName(rootPrefixCls || '', 'fade', props.maskTransitionName)}
|
||||
maskClosable={maskClosable}
|
||||
mask={mergedMask}
|
||||
style={style}
|
||||
styles={{ body: bodyStyle, mask: maskStyle, ...styles }}
|
||||
width={width}
|
||||
|
||||
@@ -77,6 +77,7 @@ const Modal: React.FC<ModalProps> = (props) => {
|
||||
closable,
|
||||
mask: modalMask,
|
||||
modalRender,
|
||||
maskClosable,
|
||||
|
||||
// Focusable
|
||||
focusTriggerAfterClose,
|
||||
@@ -111,7 +112,12 @@ const Modal: React.FC<ModalProps> = (props) => {
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
|
||||
// ============================ Mask ============================
|
||||
const [mergedMask, maskBlurClassName] = useMergedMask(modalMask, contextMask, prefixCls);
|
||||
const [mergedMask, maskBlurClassName, mergeMaskClosable] = useMergedMask(
|
||||
modalMask,
|
||||
contextMask,
|
||||
prefixCls,
|
||||
maskClosable,
|
||||
);
|
||||
|
||||
// ========================== Focusable =========================
|
||||
const mergedFocusable = useFocusable(focusable, mergedMask, focusTriggerAfterClose);
|
||||
@@ -139,6 +145,7 @@ const Modal: React.FC<ModalProps> = (props) => {
|
||||
['destroyOnClose', 'destroyOnHidden'],
|
||||
['autoFocusButton', 'focusable.autoFocusButton'],
|
||||
['focusTriggerAfterClose', 'focusable.focusTriggerAfterClose'],
|
||||
['maskClosable', 'mask.closable'],
|
||||
].forEach(([deprecatedName, newName]) => {
|
||||
warning.deprecated(!(deprecatedName in props), deprecatedName, newName);
|
||||
});
|
||||
@@ -203,6 +210,7 @@ const Modal: React.FC<ModalProps> = (props) => {
|
||||
focusTriggerAfterClose: mergedFocusable.focusTriggerAfterClose,
|
||||
focusable: mergedFocusable,
|
||||
mask: mergedMask,
|
||||
maskClosable: mergeMaskClosable,
|
||||
zIndex,
|
||||
};
|
||||
|
||||
@@ -259,6 +267,7 @@ const Modal: React.FC<ModalProps> = (props) => {
|
||||
transitionName={getTransitionName(rootPrefixCls, 'zoom', props.transitionName)}
|
||||
maskTransitionName={getTransitionName(rootPrefixCls, 'fade', props.maskTransitionName)}
|
||||
mask={mergedMask}
|
||||
maskClosable={mergeMaskClosable}
|
||||
className={clsx(hashId, className, contextClassName)}
|
||||
style={{ ...contextStyle, ...style, ...responsiveWidthVars }}
|
||||
classNames={{
|
||||
|
||||
@@ -257,6 +257,55 @@ describe('Modal', () => {
|
||||
expect(document.querySelector('.ant-modal-footer .ant-btn-primary.ant-btn-sm')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not close when mask.closable is false from context', () => {
|
||||
const onCancel = jest.fn();
|
||||
render(
|
||||
<ConfigProvider modal={{ mask: { closable: false } }}>
|
||||
<Modal open onCancel={onCancel} />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
const maskElement = document.querySelector('.ant-modal-mask');
|
||||
fireEvent.click(maskElement!);
|
||||
expect(onCancel).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should support maskClosable prop over mask.closable global config', async () => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
const Demo: React.FC<ModalProps> = ({ onCancel = () => {}, onOk = () => {}, ...restProps }) => {
|
||||
const [open, setOpen] = React.useState<boolean>(false);
|
||||
useEffect(() => {
|
||||
setOpen(true);
|
||||
}, []);
|
||||
const handleCancel = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
setOpen(false);
|
||||
onCancel(event);
|
||||
};
|
||||
|
||||
return <Modal open={open} onCancel={handleCancel} onOk={onOk} {...restProps} />;
|
||||
};
|
||||
|
||||
const onCancel = jest.fn();
|
||||
const onOk = jest.fn();
|
||||
|
||||
render(
|
||||
<ConfigProvider modal={{ mask: { closable: false } }}>
|
||||
<Demo onCancel={onCancel} onOk={onOk} maskClosable />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
await act(async () => {
|
||||
await waitFakeTimer(500);
|
||||
});
|
||||
const modalWrap = document.body.querySelectorAll('.ant-modal-wrap')[0];
|
||||
fireEvent.click(modalWrap!);
|
||||
await act(async () => {
|
||||
await waitFakeTimer(500);
|
||||
});
|
||||
expect(onCancel).toHaveBeenCalled();
|
||||
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should not close modal when confirmLoading is loading', async () => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
|
||||
@@ -190,6 +190,44 @@ describe('Modal.hook', () => {
|
||||
expect(cancelCount).toEqual(2); // click modal wrapper, trigger onCancel
|
||||
});
|
||||
|
||||
it('hooks modal should trigger onCancel with mask.closable', () => {
|
||||
let cancelCount = 0;
|
||||
const Demo = () => {
|
||||
const [modal, contextHolder] = Modal.useModal();
|
||||
|
||||
const openBrokenModal = React.useCallback(() => {
|
||||
modal.info({
|
||||
okType: 'default',
|
||||
mask: { closable: true },
|
||||
okCancel: true,
|
||||
onCancel: () => {
|
||||
cancelCount += 1;
|
||||
},
|
||||
content: 'Hello!',
|
||||
});
|
||||
}, [modal]);
|
||||
|
||||
return (
|
||||
<ConfigWarp>
|
||||
{contextHolder}
|
||||
<div className="open-hook-modal-btn" onClick={openBrokenModal}>
|
||||
Test hook modal
|
||||
</div>
|
||||
</ConfigWarp>
|
||||
);
|
||||
};
|
||||
|
||||
const { container } = render(<Demo />);
|
||||
|
||||
fireEvent.click(container.querySelectorAll('.open-hook-modal-btn')[0]);
|
||||
fireEvent.click(document.body.querySelectorAll('.ant-modal-confirm-btns .ant-btn')[0]);
|
||||
expect(cancelCount).toEqual(1); // click cancel btn, trigger onCancel
|
||||
|
||||
fireEvent.click(container.querySelectorAll('.open-hook-modal-btn')[0]);
|
||||
fireEvent.click(document.body.querySelectorAll('.ant-modal-wrap')[0]);
|
||||
expect(cancelCount).toEqual(2); // click modal wrapper, trigger onCancel
|
||||
});
|
||||
|
||||
it('update before render', () => {
|
||||
const Demo = () => {
|
||||
const [modal, contextHolder] = Modal.useModal();
|
||||
|
||||
@@ -39,7 +39,7 @@ const Demo: React.FC = () => {
|
||||
footer={null}
|
||||
destroyOnHidden
|
||||
onCancel={() => setIsModalOpen(false)}
|
||||
maskClosable={false}
|
||||
mask={{ closable: false }}
|
||||
closable={false}
|
||||
styles={{
|
||||
container: {
|
||||
|
||||
@@ -65,8 +65,8 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| focusable | Configuration for focus management in the Modal | `{ trap?: boolean, focusTriggerAfterClose?: boolean }` | - | 6.2.0 |
|
||||
| getContainer | The mounted node for Modal but still display at fullscreen | HTMLElement \| () => HTMLElement \| Selectors \| false | document.body | |
|
||||
| keyboard | Whether support press esc to close | boolean | true | |
|
||||
| mask | Mask effect | boolean \| `{enabled: boolean, blur: boolean}` | true | |
|
||||
| maskClosable | Whether to close the modal dialog when the mask (area outside the modal) is clicked | boolean | true | |
|
||||
| mask | Mask effect | boolean \| `{enabled?: boolean, blur?: boolean, closable?: boolean}` | true | mask.closable: 6.3.0 |
|
||||
| ~~maskClosable~~ | Whether to close the modal dialog when the mask (area outside the modal) is clicked | boolean | true | |
|
||||
| modalRender | Custom modal content render | (node: ReactNode) => ReactNode | - | 4.7.0 |
|
||||
| okButtonProps | The ok button props | [ButtonProps](/components/button/#api) | - | |
|
||||
| okText | Text of the OK button | ReactNode | `OK` | |
|
||||
|
||||
@@ -66,7 +66,7 @@ demo:
|
||||
| focusable | 对话框内焦点管理的配置 | `{ trap?: boolean, focusTriggerAfterClose?: boolean }` | - | 6.2.0 |
|
||||
| getContainer | 指定 Modal 挂载的节点,但依旧为全屏展示,`false` 为挂载在当前位置 | HTMLElement \| () => HTMLElement \| Selectors \| false | document.body | |
|
||||
| keyboard | 是否支持键盘 esc 关闭 | boolean | true | |
|
||||
| mask | 遮罩效果 | boolean \| `{enabled: boolean, blur: boolean}` | true | |
|
||||
| mask | 遮罩效果 | boolean \| `{enabled: boolean, blur: boolean, closable?: boolean}` | true | mask.closable: 6.3.0 |
|
||||
| maskClosable | 点击蒙层是否允许关闭 | boolean | true | |
|
||||
| modalRender | 自定义渲染对话框 | (node: ReactNode) => ReactNode | - | 4.7.0 |
|
||||
| okButtonProps | ok 按钮 props | [ButtonProps](/components/button-cn#api) | - | |
|
||||
@@ -118,8 +118,8 @@ demo:
|
||||
| getContainer | 指定 Modal 挂载的 HTML 节点,false 为挂载在当前 dom | HTMLElement \| () => HTMLElement \| Selectors \| false | document.body | |
|
||||
| icon | 自定义图标 | ReactNode | <ExclamationCircleFilled /> | |
|
||||
| keyboard | 是否支持键盘 esc 关闭 | boolean | true | |
|
||||
| mask | 遮罩效果 | boolean \| `{enabled: boolean, blur: boolean}` | true | |
|
||||
| maskClosable | 点击蒙层是否允许关闭 | boolean | false | |
|
||||
| mask | 遮罩效果 | boolean \| `{enabled?: boolean, blur?: boolean, closable?: boolean, closable?: true}` | true | |
|
||||
| ~~maskClosable~~ | 点击蒙层是否允许关闭 | boolean | false | |
|
||||
| okButtonProps | ok 按钮 props | [ButtonProps](/components/button-cn#api) | - | |
|
||||
| okText | 确认按钮文字 | string | `确定` | |
|
||||
| okType | 确认按钮类型 | string | `primary` | |
|
||||
|
||||
@@ -92,7 +92,10 @@ export interface ModalProps extends ModalCommonProps {
|
||||
okType?: LegacyButtonType;
|
||||
/** Text of the Cancel button */
|
||||
cancelText?: React.ReactNode;
|
||||
/** Whether to close the modal dialog when the mask (area outside the modal) is clicked */
|
||||
/**
|
||||
* @deprecated Please use `mask.closable` instead
|
||||
* @description Whether to close the modal dialog when the mask (area outside the modal) is clicked
|
||||
*/
|
||||
maskClosable?: boolean;
|
||||
/** Force render Modal */
|
||||
forceRender?: boolean;
|
||||
@@ -157,8 +160,9 @@ export interface ModalFuncProps extends ModalCommonProps {
|
||||
okType?: LegacyButtonType;
|
||||
cancelText?: React.ReactNode;
|
||||
icon?: React.ReactNode;
|
||||
mask?: MaskType;
|
||||
/** @deprecated Please use `mask.closable` instead */
|
||||
maskClosable?: boolean;
|
||||
mask?: MaskType;
|
||||
zIndex?: number;
|
||||
okCancel?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
|
||||
@@ -141,6 +141,8 @@ const genPictureCardStyle: GenerateStyle<UploadToken> = (token) => {
|
||||
[`${listCls}${listCls}-picture-card, ${listCls}${listCls}-picture-circle`]: {
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
height: uploadPictureCardSize,
|
||||
|
||||
'@supports not (gap: 1px)': {
|
||||
'& > *': {
|
||||
marginBlockEnd: token.marginXS,
|
||||
|
||||
@@ -221,7 +221,7 @@
|
||||
"adm-zip": "^0.5.16",
|
||||
"ajv": "^8.17.1",
|
||||
"ali-oss": "^6.23.0",
|
||||
"antd-img-crop": "^4.27.0",
|
||||
"antd-img-crop": "~4.27.0",
|
||||
"antd-style": "^4.1.0",
|
||||
"antd-token-previewer": "^3.0.0",
|
||||
"axios": "^1.13.2",
|
||||
|
||||
Reference in New Issue
Block a user