forked from ionic-team/ionic-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPageManager.tsx
More file actions
106 lines (91 loc) · 3.92 KB
/
PageManager.tsx
File metadata and controls
106 lines (91 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import React from 'react';
import { mergeRefs } from '../components/react-component-lib/utils';
import { IonLifeCycleContext } from '../contexts/IonLifeCycleContext';
import type { RouteInfo } from '../models';
import { StackContext } from './StackContext';
interface PageManagerProps {
className?: string;
children?: React.ReactNode;
forwardedRef?: React.ForwardedRef<HTMLDivElement>;
routeInfo?: RouteInfo;
}
export class PageManager extends React.PureComponent<PageManagerProps> {
ionLifeCycleContext!: React.ContextType<typeof IonLifeCycleContext>;
context!: React.ContextType<typeof StackContext>;
ionPageElementRef: React.RefObject<HTMLDivElement>;
stableMergedRefs: React.RefCallback<HTMLDivElement>;
constructor(props: PageManagerProps) {
super(props);
this.ionPageElementRef = React.createRef();
// React refs must be stable (not created inline).
this.stableMergedRefs = mergeRefs(this.ionPageElementRef, this.props.forwardedRef);
/**
* This binds the scope of the following methods to the class scope.
* The `.bind` method returns a new function, so we need to assign it
* in the constructor rather than when adding or removing the listeners
* to avoid creating a new function.
*/
this.ionViewWillEnterHandler = this.ionViewWillEnterHandler.bind(this);
this.ionViewDidEnterHandler = this.ionViewDidEnterHandler.bind(this);
this.ionViewWillLeaveHandler = this.ionViewWillLeaveHandler.bind(this);
this.ionViewDidLeaveHandler = this.ionViewDidLeaveHandler.bind(this);
}
componentDidMount() {
if (this.ionPageElementRef.current) {
if (this.context.isInOutlet()) {
this.ionPageElementRef.current.classList.add('ion-page-invisible');
}
this.context.registerIonPage(this.ionPageElementRef.current, this.props.routeInfo!);
this.ionPageElementRef.current.addEventListener('ionViewWillEnter', this.ionViewWillEnterHandler);
this.ionPageElementRef.current.addEventListener('ionViewDidEnter', this.ionViewDidEnterHandler);
this.ionPageElementRef.current.addEventListener('ionViewWillLeave', this.ionViewWillLeaveHandler);
this.ionPageElementRef.current.addEventListener('ionViewDidLeave', this.ionViewDidLeaveHandler);
}
}
componentWillUnmount() {
if (this.ionPageElementRef.current) {
this.ionPageElementRef.current.removeEventListener('ionViewWillEnter', this.ionViewWillEnterHandler);
this.ionPageElementRef.current.removeEventListener('ionViewDidEnter', this.ionViewDidEnterHandler);
this.ionPageElementRef.current.removeEventListener('ionViewWillLeave', this.ionViewWillLeaveHandler);
/**
* We deliberately do not remove the `ionViewDidLeave` listener.
* The registered callback is used to unmount and remove the page.
* Removing the event listener prevents the callback from being called.
* The browser will automatically remove the event listener when the
* page element is removed from the DOM and garbage collected.
*/
}
}
ionViewWillEnterHandler() {
this.ionLifeCycleContext.ionViewWillEnter();
}
ionViewDidEnterHandler() {
this.ionLifeCycleContext.ionViewDidEnter();
}
ionViewWillLeaveHandler() {
this.ionLifeCycleContext.ionViewWillLeave();
}
ionViewDidLeaveHandler() {
this.ionLifeCycleContext.ionViewDidLeave();
}
render() {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { className, children, routeInfo, forwardedRef, ...props } = this.props;
return (
<IonLifeCycleContext.Consumer>
{(context) => {
this.ionLifeCycleContext = context;
return (
<div className={className ? `${className} ion-page` : `ion-page`} ref={this.stableMergedRefs} {...props}>
{children}
</div>
);
}}
</IonLifeCycleContext.Consumer>
);
}
static get contextType() {
return StackContext;
}
}
export default PageManager;