import { OverlayEventDetail } from '@ionic/core'; import React from 'react'; import { attachProps } from './utils'; interface OverlayBase extends HTMLElement { present: () => Promise; dismiss: (data?: any, role?: string | undefined) => Promise; } export interface ReactControllerProps { isOpen: boolean; onDidDismiss?: (event: CustomEvent) => void; } export const createControllerComponent = ( displayName: string, controller: { create: (options: OptionsType) => Promise } ) => { const dismissEventName = `on${displayName}DidDismiss`; type Props = OptionsType & ReactControllerProps; return class extends React.Component { overlay?: OverlayType; constructor(props: Props) { super(props); } static get displayName() { return displayName; } async componentDidMount() { const { isOpen } = this.props; if (isOpen as boolean) { this.present(); } } componentWillUnmount() { if (this.overlay) { this.overlay.dismiss(); } } async componentDidUpdate(prevProps: Props) { if (prevProps.isOpen !== this.props.isOpen && this.props.isOpen === true) { this.present(prevProps); } if (this.overlay && prevProps.isOpen !== this.props.isOpen && this.props.isOpen === false) { await this.overlay.dismiss(); } } async present(prevProps?: Props) { const { isOpen, onDidDismiss, ...cProps } = this.props; const overlay = this.overlay = await controller.create({ ...cProps as any }); attachProps(overlay, { [dismissEventName]: onDidDismiss }, prevProps); await overlay.present(); } render(): null { return null; } }; };