const modalRoot = document.getElementById('modal-root');
class Modal extends React.Component {
constructor(props) {
super(props);
this.el = document.createElement('div');
}
componentDidMount() {
modalRoot.appendChild(this.el);
}
componentWillUnmount() {
modalRoot.removeChild(this.el);
}
render() {
return ReactDOM.createPortal(
this.props.children,
this.el,
);
}
}
interface PortalProps extends CommonComponentProps {
getContainer?: Function;
visible?: boolean;
}
class Portal extends React.Component<PortalProps> {
mountDom: HTMLElement;
container: HTMLElement;
constructor(props:PortalProps) {
super(props);
this.mountDom = document.createElement('div');
this.container = props.getContainer
? props.getContainer()
: window.document.body;
}
componentDidMount() {
this.container.appendChild(this.mountDom);
}
componentWillUnmount() {
if (this.mountDom) {
this.container.removeChild(this.mountDom);
}
}
getVisible = () => {
if ('visible' in this.props) {
return this.props.visible;
}
return true;
}
render() {
const { children } = this.props;
if (this.container && this.getVisible()) {
if (createPortal) {
return createPortal(children, this.mountDom);
}
ReactDom.render(children, this.mountDom);
}
return null;
}
}
export default Portal;
export interface DialogWrapperProps extends DialogProps {
visible?: boolean;
getContainer?: () => void;
}
class DialogWrapper extends Component<DialogWrapperProps>{
render() {
const { getContainer, children, onClose, visible } = this.props;
if (visible) {
return (
<Portal
visible={visible}
getContainer={getContainer}
>
<Dialog
onClose={onClose}
>
{children}
</Dialog>
</Portal>
);
}
return null;
}
}
export default DialogWrapper;
class Trigger extends Component<TriggerProps, {
triggerVisible: boolean
}> {
popupContainer: HTMLElement;
node: any;
popupRef: any;
clickPopupOutSideFun: void | null;
constructor(props: TriggerProps) {
}
getPortalContainer = () => {...};
creatPopupContainer = () => {...}
getContainer = () => {...};
render() {
const {
children,
className
} = this.props;
const {
triggerVisible
} = this.state;
const trigger = React.cloneElement(children, {
className: classNames('pb-dropdown-trigger', className),
ref: composeRef(this.node, (children as any).ref) // compose this component ref and children refs
});
let portal: React.ReactElement | null = null;
if (triggerVisible) {
portal = (
<Portal
key="portal"
getContainer={this.getContainer}
>
{this.getPortalContainer()}
</Portal>
);
}
const newChildProps: HTMLAttributes<HTMLElement> & { key: string } = { key: 'trigger' };
const child = (
<div>
{trigger}
{portal}
</div>
);
this.genNewChildren(newChildProps);
const newChild = React.cloneElement(child, {
...newChildProps,
ref: composeRef(this.node, (children as any).ref)
});
return newChild;
}
}
export default Trigger;