fix: circular dependencies in Modal & Input (#31817)

* fix(input): fix circular dependencies

* fix(input): fix circular dependencies

* fix(modal): fix circular dependencies

* fix(modal): fix test
This commit is contained in:
zhyupe 2021-08-17 16:22:42 +08:00 committed by GitHub
parent d2ef1198f5
commit 4097a6c7c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 51 additions and 43 deletions

View File

@ -2,17 +2,14 @@ import * as React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled'; import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import { tuple } from '../_util/type'; import { tuple } from '../_util/type';
import { InputProps, getInputClassName } from './Input'; import type { InputProps } from './Input';
import { DirectionType } from '../config-provider'; import { DirectionType } from '../config-provider';
import { SizeType } from '../config-provider/SizeContext'; import { SizeType } from '../config-provider/SizeContext';
import { cloneElement } from '../_util/reactNode'; import { cloneElement } from '../_util/reactNode';
import { getInputClassName, hasPrefixSuffix } from './utils';
const ClearableInputType = tuple('text', 'input'); const ClearableInputType = tuple('text', 'input');
export function hasPrefixSuffix(props: InputProps | ClearableInputProps) {
return !!(props.prefix || props.suffix || props.allowClear);
}
function hasAddon(props: InputProps | ClearableInputProps) { function hasAddon(props: InputProps | ClearableInputProps) {
return !!(props.addonBefore || props.addonAfter); return !!(props.addonBefore || props.addonAfter);
} }
@ -35,7 +32,7 @@ interface BasicProps {
} }
/** This props only for input. */ /** This props only for input. */
interface ClearableInputProps extends BasicProps { export interface ClearableInputProps extends BasicProps {
size?: SizeType; size?: SizeType;
suffix?: React.ReactNode; suffix?: React.ReactNode;
prefix?: React.ReactNode; prefix?: React.ReactNode;

View File

@ -1,15 +1,16 @@
import * as React from 'react'; import * as React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import omit from 'rc-util/lib/omit'; import omit from 'rc-util/lib/omit';
import Group from './Group'; import type Group from './Group';
import Search from './Search'; import type Search from './Search';
import TextArea from './TextArea'; import type TextArea from './TextArea';
import Password from './Password'; import type Password from './Password';
import { LiteralUnion } from '../_util/type'; import { LiteralUnion } from '../_util/type';
import ClearableLabeledInput, { hasPrefixSuffix } from './ClearableLabeledInput'; import ClearableLabeledInput from './ClearableLabeledInput';
import { ConfigConsumer, ConfigConsumerProps, DirectionType } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps, DirectionType } from '../config-provider';
import SizeContext, { SizeType } from '../config-provider/SizeContext'; import SizeContext, { SizeType } from '../config-provider/SizeContext';
import devWarning from '../_util/devWarning'; import devWarning from '../_util/devWarning';
import { getInputClassName, hasPrefixSuffix } from './utils';
export interface InputFocusOptions extends FocusOptions { export interface InputFocusOptions extends FocusOptions {
cursor?: 'start' | 'end' | 'all'; cursor?: 'start' | 'end' | 'all';
@ -102,22 +103,6 @@ export function resolveOnChange<E extends HTMLInputElement | HTMLTextAreaElement
onChange(event as React.ChangeEvent<E>); onChange(event as React.ChangeEvent<E>);
} }
export function getInputClassName(
prefixCls: string,
bordered: boolean,
size?: SizeType,
disabled?: boolean,
direction?: DirectionType,
) {
return classNames(prefixCls, {
[`${prefixCls}-sm`]: size === 'small',
[`${prefixCls}-lg`]: size === 'large',
[`${prefixCls}-disabled`]: disabled,
[`${prefixCls}-rtl`]: direction === 'rtl',
[`${prefixCls}-borderless`]: !bordered,
});
}
export function triggerFocus( export function triggerFocus(
element?: HTMLInputElement | HTMLTextAreaElement, element?: HTMLInputElement | HTMLTextAreaElement,
option?: InputFocusOptions, option?: InputFocusOptions,

25
components/input/utils.ts Normal file
View File

@ -0,0 +1,25 @@
import classNames from 'classnames';
import type { DirectionType } from '../config-provider';
import type { SizeType } from '../config-provider/SizeContext';
import type { ClearableInputProps } from './ClearableLabeledInput';
import type { InputProps } from './Input';
export function getInputClassName(
prefixCls: string,
bordered: boolean,
size?: SizeType,
disabled?: boolean,
direction?: DirectionType,
) {
return classNames(prefixCls, {
[`${prefixCls}-sm`]: size === 'small',
[`${prefixCls}-lg`]: size === 'large',
[`${prefixCls}-disabled`]: disabled,
[`${prefixCls}-rtl`]: direction === 'rtl',
[`${prefixCls}-borderless`]: !bordered,
});
}
export function hasPrefixSuffix(props: InputProps | ClearableInputProps) {
return !!(props.prefix || props.suffix || props.allowClear);
}

View File

@ -3,7 +3,6 @@ import Dialog from 'rc-dialog';
import classNames from 'classnames'; import classNames from 'classnames';
import CloseOutlined from '@ant-design/icons/CloseOutlined'; import CloseOutlined from '@ant-design/icons/CloseOutlined';
import useModal from './useModal';
import { getConfirmLocale } from './locale'; import { getConfirmLocale } from './locale';
import Button from '../button'; import Button from '../button';
import { LegacyButtonType, ButtonProps, convertLegacyProps } from '../button/button'; import { LegacyButtonType, ButtonProps, convertLegacyProps } from '../button/button';
@ -13,7 +12,6 @@ import { canUseDocElement } from '../_util/styleChecker';
import { getTransitionName } from '../_util/motion'; import { getTransitionName } from '../_util/motion';
let mousePosition: { x: number; y: number } | null; let mousePosition: { x: number; y: number } | null;
export const destroyFns: Array<() => void> = [];
// ref: https://github.com/ant-design/ant-design/issues/15795 // ref: https://github.com/ant-design/ant-design/issues/15795
const getClickPosition = (e: MouseEvent) => { const getClickPosition = (e: MouseEvent) => {
@ -131,11 +129,7 @@ export interface ModalLocale {
justOkText: string; justOkText: string;
} }
interface ModalInterface extends React.FC<ModalProps> { const Modal: React.FC<ModalProps> = props => {
useModal: typeof useModal;
}
const Modal: ModalInterface = props => {
const { const {
getPopupContainer: getContextPopupContainer, getPopupContainer: getContextPopupContainer,
getPrefixCls, getPrefixCls,
@ -222,8 +216,6 @@ const Modal: ModalInterface = props => {
); );
}; };
Modal.useModal = useModal;
Modal.defaultProps = { Modal.defaultProps = {
width: 520, width: 520,
confirmLoading: false, confirmLoading: false,

View File

@ -4,7 +4,7 @@ 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';
import Modal from '..'; import Modal from '..';
import { destroyFns } from '../Modal'; import destroyFns from '../destroyFns';
import { sleep } from '../../../tests/utils'; import { sleep } from '../../../tests/utils';
import ConfigProvider from '../../config-provider'; import ConfigProvider from '../../config-provider';

View File

@ -5,10 +5,11 @@ import CheckCircleOutlined from '@ant-design/icons/CheckCircleOutlined';
import CloseCircleOutlined from '@ant-design/icons/CloseCircleOutlined'; import CloseCircleOutlined from '@ant-design/icons/CloseCircleOutlined';
import ExclamationCircleOutlined from '@ant-design/icons/ExclamationCircleOutlined'; import ExclamationCircleOutlined from '@ant-design/icons/ExclamationCircleOutlined';
import { getConfirmLocale } from './locale'; import { getConfirmLocale } from './locale';
import { ModalFuncProps, destroyFns } from './Modal'; import type { ModalFuncProps } from './Modal';
import ConfirmDialog from './ConfirmDialog'; import ConfirmDialog from './ConfirmDialog';
import { globalConfig } from '../config-provider'; import { globalConfig } from '../config-provider';
import devWarning from '../_util/devWarning'; import devWarning from '../_util/devWarning';
import destroyFns from './destroyFns';
let defaultRootPrefixCls = ''; let defaultRootPrefixCls = '';
@ -18,9 +19,7 @@ function getRootPrefixCls() {
type ConfigUpdate = ModalFuncProps | ((prevConfig: ModalFuncProps) => ModalFuncProps); type ConfigUpdate = ModalFuncProps | ((prevConfig: ModalFuncProps) => ModalFuncProps);
export type ModalFunc = ( export type ModalFunc = (props: ModalFuncProps) => {
props: ModalFuncProps,
) => {
destroy: () => void; destroy: () => void;
update: (configUpdate: ConfigUpdate) => void; update: (configUpdate: ConfigUpdate) => void;
}; };

View File

@ -0,0 +1,2 @@
const destroyFns: Array<() => void> = [];
export default destroyFns;

View File

@ -1,4 +1,4 @@
import OriginModal, { ModalFuncProps, destroyFns } from './Modal'; import OriginModal, { ModalFuncProps } from './Modal';
import confirm, { import confirm, {
withWarn, withWarn,
withInfo, withInfo,
@ -8,6 +8,8 @@ import confirm, {
ModalStaticFunctions, ModalStaticFunctions,
modalGlobalConfig, modalGlobalConfig,
} from './confirm'; } from './confirm';
import useModal from './useModal';
import destroyFns from './destroyFns';
export { ActionButtonProps } from './ActionButton'; export { ActionButtonProps } from './ActionButton';
export { ModalProps, ModalFuncProps } from './Modal'; export { ModalProps, ModalFuncProps } from './Modal';
@ -17,10 +19,16 @@ function modalWarn(props: ModalFuncProps) {
} }
type ModalType = typeof OriginModal & type ModalType = typeof OriginModal &
ModalStaticFunctions & { destroyAll: () => void; config: typeof modalGlobalConfig }; ModalStaticFunctions & {
useModal: typeof useModal;
destroyAll: () => void;
config: typeof modalGlobalConfig;
};
const Modal = OriginModal as ModalType; const Modal = OriginModal as ModalType;
Modal.useModal = useModal;
Modal.info = function infoFn(props: ModalFuncProps) { Modal.info = function infoFn(props: ModalFuncProps) {
return confirm(withInfo(props)); return confirm(withInfo(props));
}; };