Browse Source

refactor: solve modal circular dependency issue (#42808)

* refactor: solve modal circluar dependency issue

* feat: optimize code

* feat: optimize code
pull/42841/head
kiner-tang(文辉) 1 year ago
committed by GitHub
parent
commit
1d24fb5679
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      components/modal/ConfirmDialog.tsx
  2. 122
      components/modal/Modal.tsx
  3. 2
      components/modal/PurePanel.tsx
  4. 2
      components/modal/confirm.tsx
  5. 4
      components/modal/index.tsx
  6. 115
      components/modal/interface.ts
  7. 2
      components/modal/useModal/HookModal.tsx
  8. 4
      components/modal/useModal/index.tsx

2
components/modal/ConfirmDialog.tsx

@ -10,8 +10,8 @@ import warning from '../_util/warning';
import type { ThemeConfig } from '../config-provider'; import type { ThemeConfig } from '../config-provider';
import ConfigProvider from '../config-provider'; import ConfigProvider from '../config-provider';
import { useLocale } from '../locale'; import { useLocale } from '../locale';
import type { ModalFuncProps, ModalLocale } from './Modal';
import Dialog from './Modal'; import Dialog from './Modal';
import type { ModalFuncProps, ModalLocale } from './interface';
interface ConfirmDialogProps extends ModalFuncProps { interface ConfirmDialogProps extends ModalFuncProps {
afterClose?: () => void; afterClose?: () => void;

122
components/modal/Modal.tsx

@ -1,19 +1,16 @@
import classNames from 'classnames'; import classNames from 'classnames';
import Dialog from 'rc-dialog'; import Dialog from 'rc-dialog';
import * as React from 'react'; import * as React from 'react';
import type { ButtonProps, LegacyButtonType } from '../button/button';
import type { DirectionType } from '../config-provider';
import { ConfigContext } from '../config-provider';
import { NoFormStyle } from '../form/context';
import { NoCompactStyle } from '../space/Compact';
import { getTransitionName } from '../_util/motion'; import { getTransitionName } from '../_util/motion';
import { canUseDocElement } from '../_util/styleChecker'; import { canUseDocElement } from '../_util/styleChecker';
import warning from '../_util/warning'; import warning from '../_util/warning';
import { ConfigContext } from '../config-provider';
import { NoFormStyle } from '../form/context';
import { NoCompactStyle } from '../space/Compact';
import { Footer, renderCloseIcon } from './PurePanel'; import { Footer, renderCloseIcon } from './PurePanel';
import type { ModalProps, MousePosition } from './interface';
import useStyle from './style'; import useStyle from './style';
type MousePosition = { x: number; y: number } | null;
let mousePosition: MousePosition; let mousePosition: MousePosition;
// ref: https://github.com/ant-design/ant-design/issues/15795 // ref: https://github.com/ant-design/ant-design/issues/15795
@ -35,117 +32,6 @@ if (canUseDocElement()) {
document.documentElement.addEventListener('click', getClickPosition, true); document.documentElement.addEventListener('click', getClickPosition, true);
} }
export interface ModalProps {
/** Whether the modal dialog is visible or not */
open?: boolean;
/** Whether to apply loading visual effect for OK button or not */
confirmLoading?: boolean;
/** The modal dialog's title */
title?: React.ReactNode;
/** Whether a close (x) button is visible on top right of the modal dialog or not */
closable?: boolean;
/** Specify a function that will be called when a user clicks the OK button */
onOk?: (e: React.MouseEvent<HTMLButtonElement>) => void;
/** Specify a function that will be called when a user clicks mask, close button on top right or Cancel button */
onCancel?: (e: React.MouseEvent<HTMLButtonElement>) => void;
afterClose?: () => void;
/** Callback when the animation ends when Modal is turned on and off */
afterOpenChange?: (open: boolean) => void;
/** Centered Modal */
centered?: boolean;
/** Width of the modal dialog */
width?: string | number;
/** Footer content */
footer?: React.ReactNode;
/** Text of the OK button */
okText?: React.ReactNode;
/** Button `type` of the OK button */
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 */
maskClosable?: boolean;
/** Force render Modal */
forceRender?: boolean;
okButtonProps?: ButtonProps;
cancelButtonProps?: ButtonProps;
destroyOnClose?: boolean;
style?: React.CSSProperties;
wrapClassName?: string;
maskTransitionName?: string;
transitionName?: string;
className?: string;
rootClassName?: string;
getContainer?: string | HTMLElement | getContainerFunc | false;
zIndex?: number;
bodyStyle?: React.CSSProperties;
maskStyle?: React.CSSProperties;
mask?: boolean;
keyboard?: boolean;
wrapProps?: any;
prefixCls?: string;
closeIcon?: React.ReactNode;
modalRender?: (node: React.ReactNode) => React.ReactNode;
focusTriggerAfterClose?: boolean;
children?: React.ReactNode;
mousePosition?: MousePosition;
// Legacy
/** @deprecated Please use `open` instead. */
visible?: boolean;
}
type getContainerFunc = () => HTMLElement;
export interface ModalFuncProps {
prefixCls?: string;
className?: string;
rootClassName?: string;
open?: boolean;
/** @deprecated Please use `open` instead. */
visible?: boolean;
title?: React.ReactNode;
closable?: boolean;
content?: React.ReactNode;
// TODO: find out exact types
onOk?: (...args: any[]) => any;
onCancel?: (...args: any[]) => any;
afterClose?: () => void;
okButtonProps?: ButtonProps;
cancelButtonProps?: ButtonProps;
centered?: boolean;
width?: string | number;
okText?: React.ReactNode;
okType?: LegacyButtonType;
cancelText?: React.ReactNode;
icon?: React.ReactNode;
mask?: boolean;
maskClosable?: boolean;
zIndex?: number;
okCancel?: boolean;
style?: React.CSSProperties;
wrapClassName?: string;
maskStyle?: React.CSSProperties;
type?: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm';
keyboard?: boolean;
getContainer?: string | HTMLElement | getContainerFunc | false;
autoFocusButton?: null | 'ok' | 'cancel';
transitionName?: string;
maskTransitionName?: string;
direction?: DirectionType;
bodyStyle?: React.CSSProperties;
closeIcon?: React.ReactNode;
footer?: React.ReactNode;
modalRender?: (node: React.ReactNode) => React.ReactNode;
focusTriggerAfterClose?: boolean;
}
export interface ModalLocale {
okText: string;
cancelText: string;
justOkText: string;
}
const Modal: React.FC<ModalProps> = (props) => { const Modal: React.FC<ModalProps> = (props) => {
const { const {
getPopupContainer: getContextPopupContainer, getPopupContainer: getContextPopupContainer,

2
components/modal/PurePanel.tsx

@ -9,8 +9,8 @@ import { convertLegacyProps } from '../button/button';
import { ConfigContext } from '../config-provider'; import { ConfigContext } from '../config-provider';
import { useLocale } from '../locale'; import { useLocale } from '../locale';
import { ConfirmContent } from './ConfirmDialog'; import { ConfirmContent } from './ConfirmDialog';
import type { ModalFuncProps, ModalProps } from './interface';
import { getConfirmLocale } from './locale'; import { getConfirmLocale } from './locale';
import type { ModalFuncProps, ModalProps } from './Modal';
import useStyle from './style'; import useStyle from './style';
export interface PurePanelProps export interface PurePanelProps

2
components/modal/confirm.tsx

@ -3,8 +3,8 @@ import * as React from 'react';
import warning from '../_util/warning'; import warning from '../_util/warning';
import { globalConfig, warnContext } from '../config-provider'; import { globalConfig, warnContext } from '../config-provider';
import ConfirmDialog from './ConfirmDialog'; import ConfirmDialog from './ConfirmDialog';
import type { ModalFuncProps } from './Modal';
import destroyFns from './destroyFns'; import destroyFns from './destroyFns';
import type { ModalFuncProps } from './interface';
import { getConfirmLocale } from './locale'; import { getConfirmLocale } from './locale';
let defaultRootPrefixCls = ''; let defaultRootPrefixCls = '';

4
components/modal/index.tsx

@ -8,12 +8,12 @@ import confirm, {
withWarn, withWarn,
} from './confirm'; } from './confirm';
import destroyFns from './destroyFns'; import destroyFns from './destroyFns';
import type { ModalFuncProps } from './Modal'; import type { ModalFuncProps } from './interface';
import OriginModal from './Modal'; import OriginModal from './Modal';
import PurePanel from './PurePanel'; import PurePanel from './PurePanel';
import useModal from './useModal'; import useModal from './useModal';
export type { ModalFuncProps, ModalProps } from './Modal'; export type { ModalFuncProps, ModalLocale, ModalProps } from './interface';
function modalWarn(props: ModalFuncProps) { function modalWarn(props: ModalFuncProps) {
return confirm(withWarn(props)); return confirm(withWarn(props));

115
components/modal/interface.ts

@ -0,0 +1,115 @@
import type { ButtonProps, LegacyButtonType } from '../button/button';
import type { DirectionType } from '../config-provider';
export interface ModalProps {
/** Whether the modal dialog is visible or not */
open?: boolean;
/** Whether to apply loading visual effect for OK button or not */
confirmLoading?: boolean;
/** The modal dialog's title */
title?: React.ReactNode;
/** Whether a close (x) button is visible on top right of the modal dialog or not */
closable?: boolean;
/** Specify a function that will be called when a user clicks the OK button */
onOk?: (e: React.MouseEvent<HTMLButtonElement>) => void;
/** Specify a function that will be called when a user clicks mask, close button on top right or Cancel button */
onCancel?: (e: React.MouseEvent<HTMLButtonElement>) => void;
afterClose?: () => void;
/** Callback when the animation ends when Modal is turned on and off */
afterOpenChange?: (open: boolean) => void;
/** Centered Modal */
centered?: boolean;
/** Width of the modal dialog */
width?: string | number;
/** Footer content */
footer?: React.ReactNode;
/** Text of the OK button */
okText?: React.ReactNode;
/** Button `type` of the OK button */
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 */
maskClosable?: boolean;
/** Force render Modal */
forceRender?: boolean;
okButtonProps?: ButtonProps;
cancelButtonProps?: ButtonProps;
destroyOnClose?: boolean;
style?: React.CSSProperties;
wrapClassName?: string;
maskTransitionName?: string;
transitionName?: string;
className?: string;
rootClassName?: string;
getContainer?: string | HTMLElement | getContainerFunc | false;
zIndex?: number;
bodyStyle?: React.CSSProperties;
maskStyle?: React.CSSProperties;
mask?: boolean;
keyboard?: boolean;
wrapProps?: any;
prefixCls?: string;
closeIcon?: React.ReactNode;
modalRender?: (node: React.ReactNode) => React.ReactNode;
focusTriggerAfterClose?: boolean;
children?: React.ReactNode;
mousePosition?: MousePosition;
// Legacy
/** @deprecated Please use `open` instead. */
visible?: boolean;
}
type getContainerFunc = () => HTMLElement;
export interface ModalFuncProps {
prefixCls?: string;
className?: string;
rootClassName?: string;
open?: boolean;
/** @deprecated Please use `open` instead. */
visible?: boolean;
title?: React.ReactNode;
closable?: boolean;
content?: React.ReactNode;
// TODO: find out exact types
onOk?: (...args: any[]) => any;
onCancel?: (...args: any[]) => any;
afterClose?: () => void;
okButtonProps?: ButtonProps;
cancelButtonProps?: ButtonProps;
centered?: boolean;
width?: string | number;
okText?: React.ReactNode;
okType?: LegacyButtonType;
cancelText?: React.ReactNode;
icon?: React.ReactNode;
mask?: boolean;
maskClosable?: boolean;
zIndex?: number;
okCancel?: boolean;
style?: React.CSSProperties;
wrapClassName?: string;
maskStyle?: React.CSSProperties;
type?: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm';
keyboard?: boolean;
getContainer?: string | HTMLElement | getContainerFunc | false;
autoFocusButton?: null | 'ok' | 'cancel';
transitionName?: string;
maskTransitionName?: string;
direction?: DirectionType;
bodyStyle?: React.CSSProperties;
closeIcon?: React.ReactNode;
footer?: React.ReactNode;
modalRender?: (node: React.ReactNode) => React.ReactNode;
focusTriggerAfterClose?: boolean;
}
export interface ModalLocale {
okText: string;
cancelText: string;
justOkText: string;
}
export type MousePosition = { x: number; y: number } | null;

2
components/modal/useModal/HookModal.tsx

@ -3,7 +3,7 @@ import { ConfigContext } from '../../config-provider';
import defaultLocale from '../../locale/en_US'; import defaultLocale from '../../locale/en_US';
import useLocale from '../../locale/useLocale'; import useLocale from '../../locale/useLocale';
import ConfirmDialog from '../ConfirmDialog'; import ConfirmDialog from '../ConfirmDialog';
import type { ModalFuncProps } from '../Modal'; import type { ModalFuncProps } from '../interface';
export interface HookModalProps { export interface HookModalProps {
afterClose: () => void; afterClose: () => void;

4
components/modal/useModal/index.tsx

@ -2,10 +2,10 @@ import * as React from 'react';
import usePatchElement from '../../_util/hooks/usePatchElement'; import usePatchElement from '../../_util/hooks/usePatchElement';
import type { ModalStaticFunctions } from '../confirm'; import type { ModalStaticFunctions } from '../confirm';
import { withConfirm, withError, withInfo, withSuccess, withWarn } from '../confirm'; import { withConfirm, withError, withInfo, withSuccess, withWarn } from '../confirm';
import type { ModalFuncProps } from '../Modal'; import destroyFns from '../destroyFns';
import type { ModalFuncProps } from '../interface';
import type { HookModalRef } from './HookModal'; import type { HookModalRef } from './HookModal';
import HookModal from './HookModal'; import HookModal from './HookModal';
import destroyFns from '../destroyFns';
let uuid = 0; let uuid = 0;

Loading…
Cancel
Save