import { Component, createRef } from 'react'; import cx from 'classnames'; import focusWithoutScroll from '../utils/dom/focusWithoutScroll'; import Icon from '../icon'; import { IDialogPositionType, getPositionTransformOrigin } from './position'; export interface IMousePosition { x: number; y: number; } export interface IDialogInnerElProps { title?: React.ReactNode; onClose?: (e: KeyboardEvent | MouseEvent | TouchEvent) => void; className?: string; closeBtn?: boolean; style?: React.CSSProperties; footer?: React.ReactNode; mousePosition?: IMousePosition | null; position?: IDialogPositionType; } export class DialogInnerEl extends Component { dialogEl: HTMLDivElement | null = null; componentDidMount() { this.resetTransformOrigin(); } componentDidUpdate() { this.resetTransformOrigin(); } setTransformOrigin(style: CSSStyleDeclaration, origin: string) { ['Webkit', 'Moz', 'Ms', 'ms'].forEach(prefix => { style[`${prefix}TransformOrigin`] = origin; }); style.transformOrigin = origin; } resetTransformOrigin(props = this.props) { const { mousePosition, position } = props; let origin = getPositionTransformOrigin(position, this.dialogEl); if ( origin === undefined && mousePosition && mousePosition.x >= 0 && mousePosition.y >= 0 && this.dialogEl && this.dialogEl.getBoundingClientRect ) { const { left: x, top: y } = this.dialogEl.getBoundingClientRect(); origin = `${mousePosition.x - x}px ${mousePosition.y - y}px 0`; } if (origin && this.dialogEl) { this.setTransformOrigin(this.dialogEl.style, origin); } } renderHeader() { let { title } = this.props; if (!title) { return null; } title = typeof title === 'number' || typeof title === 'string' ? ( {title} ) : ( title ); return (
{title}
); } onClickClose = (e: React.MouseEvent) => { const { onClose } = this.props; if (onClose) { onClose(e as any); } }; render() { const { className, closeBtn, footer, style, children } = this.props; const Header = this.renderHeader(); const closeBtnCls = cx('zent-dialog-r-close', { 'zent-dialog-r-has-title': !!Header, }); const Closer = closeBtn && ( ); const Footer = footer && (
{footer}
); return (
(this.dialogEl = el)} > {Closer} {Header}
{children}
{Footer}
); } } export interface IDialogElWrapper { mask?: boolean; maskClosable?: boolean; visible?: boolean; onClose(e: MouseEvent | TouchEvent | KeyboardEvent): void; } export class DialogElWrapper extends Component { rootRef = createRef(); componentDidMount() { // Set focus to dialog iff focus is outside of dialog itself const activeElement = document.activeElement; const dialogNode = this.rootRef.current; if ( dialogNode !== activeElement && dialogNode && !dialogNode.contains(activeElement) ) { focusWithoutScroll(dialogNode); } } onMaskClick = (e: React.MouseEvent) => { if ( e.target === e.currentTarget && this.props.mask && this.props.maskClosable ) { this.props.onClose(e as any); } }; render() { const { mask, visible, children } = this.props; return (
{visible && mask &&
}
{children}
); } }