import * as React from 'react'; import ReactDOM from 'react-dom'; import { Component, Styles, Text, View } from 'reactxp'; import { colors } from '../../config.json'; import { Scheduler } from '../../shared/scheduler'; import ImageView from './ImageView'; const MODAL_CONTAINER_ID = 'modalContainer'; const styles = { modalAlertBackground: Styles.createViewStyle({ flex: 1, justifyContent: 'center', paddingHorizontal: 14, paddingTop: 26, paddingBottom: 14, }), modalAlert: Styles.createViewStyle({ backgroundColor: colors.darkBlue, borderRadius: 11, padding: 16, }), modalAlertIcon: Styles.createViewStyle({ alignItems: 'center', marginTop: 8, }), modalAlertMessage: Styles.createTextStyle({ fontFamily: 'Open Sans', fontSize: 14, fontWeight: '500', lineHeight: 20, color: colors.white80, marginTop: 16, }), modalAlertButtonContainer: Styles.createViewStyle({ marginTop: 16, }), }; interface IModalContentProps { children?: React.ReactNode; } export const ModalContent: React.FC = (props: IModalContentProps) => { return (
{props.children}
); }; interface IModalBackgroundProps { children?: React.ReactNode; } const ModalBackground: React.FC = (props: IModalBackgroundProps) => { return (
{props.children}
); }; interface IModalContainerProps { children?: React.ReactNode; } export const ModalContainer: React.FC = (props: IModalContainerProps) => { return (
{props.children}
); }; export enum ModalAlertType { Info = 1, Warning, } interface IModalAlertProps { type?: ModalAlertType; message?: string; buttons: React.ReactNode[]; children?: React.ReactNode; } export class ModalAlert extends Component { private element = document.createElement('div'); private modalContainer?: Element; private appendScheduler = new Scheduler(); public componentDidMount() { const modalContainer = document.getElementById(MODAL_CONTAINER_ID); if (modalContainer) { this.modalContainer = modalContainer; // Mounting the container element immediately results in a graphical issue with the dialog // first rendering with the wrong proportions and then changing to the correct proportions. // Postponing it to the next event cycle solves this issue. this.appendScheduler.schedule(() => { modalContainer.appendChild(this.element); }); } else { throw Error('Modal container not found when mounting modal'); } } public componentWillUnmount() { this.appendScheduler.cancel(); if (this.modalContainer) { this.modalContainer.removeChild(this.element); } } public render() { return ReactDOM.createPortal(this.renderModal(), this.element); } private renderModal() { return ( {this.props.type && ( {this.renderTypeIcon(this.props.type)} )} {this.props.message && {this.props.message}} {this.props.children} {this.props.buttons.map((button, index) => ( {button} ))} ); } private renderTypeIcon(type: ModalAlertType) { let source = ''; let color = ''; switch (type) { case ModalAlertType.Info: source = 'icon-alert'; color = colors.white; break; case ModalAlertType.Warning: source = 'icon-alert'; color = colors.red; break; } return ; } } interface IModalMessageProps { children?: string; } export function ModalMessage(props: IModalMessageProps) { return {props.children}; }