mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
90 lines
2.3 KiB
TypeScript
90 lines
2.3 KiB
TypeScript
import React from 'react';
|
|
|
|
import { generateId, isDevMode } from '../utils';
|
|
|
|
import { RouteManagerContext } from './RouteManagerContext';
|
|
import { View } from './View';
|
|
import { ViewItem } from './ViewItem';
|
|
import { ViewTransitionManager } from './ViewTransitionManager';
|
|
|
|
interface StackManagerProps {
|
|
id?: string;
|
|
}
|
|
|
|
export class StackManager extends React.Component<StackManagerProps, {}> {
|
|
routerOutletEl: React.RefObject<HTMLIonRouterOutletElement> = React.createRef();
|
|
context!: React.ContextType<typeof RouteManagerContext>;
|
|
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);
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.context.setupIonRouter(this.id, this.props.children, this.routerOutletEl.current!);
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.context.removeViewStack(this.id);
|
|
}
|
|
|
|
handleViewSync(page: HTMLElement, viewId: string) {
|
|
this.context.syncView(page, viewId);
|
|
}
|
|
|
|
handleHideView(viewId: string) {
|
|
this.context.hideView(viewId);
|
|
}
|
|
|
|
renderChild(item: ViewItem) {
|
|
const component = React.cloneElement(item.route, {
|
|
computedMatch: item.routeData.match
|
|
});
|
|
return component;
|
|
}
|
|
|
|
render() {
|
|
const context = this.context;
|
|
const viewStack = context.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 childElements = views.map(view => {
|
|
return (
|
|
<ViewTransitionManager
|
|
id={view.id}
|
|
key={view.key}
|
|
mount={view.mount}
|
|
>
|
|
<View
|
|
onViewSync={this.handleViewSync}
|
|
onHideView={this.handleHideView}
|
|
view={view}
|
|
>
|
|
{this.renderChild(view)}
|
|
</View>
|
|
</ViewTransitionManager>
|
|
);
|
|
});
|
|
|
|
const elementProps: any = {
|
|
ref: this.routerOutletEl
|
|
};
|
|
|
|
if (isDevMode()) {
|
|
elementProps['data-stack-id'] = this.id;
|
|
}
|
|
|
|
const routerOutletChild = React.cloneElement(ionRouterOutlet, elementProps, childElements);
|
|
|
|
return routerOutletChild;
|
|
}
|
|
|
|
static get contextType() {
|
|
return RouteManagerContext;
|
|
}
|
|
}
|