import React from 'react'; import { generateId, isDevMode } from '../utils'; import { RouteManagerContext, RouteManagerContextState } from './RouteManagerContext'; import { View } from './View'; import { ViewItem } from './ViewItem'; import { ViewTransitionManager } from './ViewTransitionManager'; interface StackManagerProps { id?: string; routeManager: RouteManagerContextState; children?: React.ReactNode; } interface StackManagerState { routerOutletReady: boolean; } class StackManagerInner extends React.Component { routerOutletEl: React.RefObject = React.createRef(); id: string; constructor(props: StackManagerProps) { super(props); this.id = this.props.id || generateId(); this.handleViewSync = this.handleViewSync.bind(this); this.handleHideView = this.handleHideView.bind(this); this.state = { routerOutletReady: false }; } componentDidMount() { this.props.routeManager.setupIonRouter(this.id, this.props.children, this.routerOutletEl.current!); this.routerOutletEl.current!.addEventListener('routerOutletReady', () => { this.setState({ routerOutletReady: true }); }); } static getDerivedStateFromProps(props: StackManagerProps, state: StackManagerState) { props.routeManager.syncRoute('', props.children); return state; } componentWillUnmount() { this.props.routeManager.removeViewStack(this.id); } handleViewSync(page: HTMLElement, viewId: string) { this.props.routeManager.syncView(page, viewId); } handleHideView(viewId: string) { this.props.routeManager.hideView(viewId); } renderChild(item: ViewItem, route: any) { const component = React.cloneElement(route, { computedMatch: item.routeData.match }); return component; } render() { const routeManager = this.props.routeManager; const viewStack = routeManager.viewStacks.get(this.id); const views = (viewStack || { views: [] }).views.filter(x => x.show); const ionRouterOutlet = React.Children.only(this.props.children) as React.ReactElement; const { routerOutletReady } = this.state; const childElements = routerOutletReady ? views.map(view => { const route = routeManager.getRoute(view.routeId); return ( {this.renderChild(view, route)} ); }) :
; const elementProps: any = { ref: this.routerOutletEl }; if(ionRouterOutlet.props.forwardedRef) { ionRouterOutlet.props.forwardedRef.current = this.routerOutletEl; } if (isDevMode()) { elementProps['data-stack-id'] = this.id; } const routerOutletChild = React.cloneElement(ionRouterOutlet, elementProps, childElements); return routerOutletChild; } } const withContext = (Component: any) => { return (props: any) => ( {context => } ) } export const StackManager = withContext(StackManagerInner);