This repository has been archived by the owner on Jun 10, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 42
/
LayoutContext.js
80 lines (65 loc) · 1.85 KB
/
LayoutContext.js
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
// @flow
import * as React from 'react';
import { Dimensions, Platform } from 'react-native';
import { withContext } from '@kiwicom/margarita-utils';
import { getLayout } from './LayoutContextHelpers';
import { LAYOUT } from './LayoutConstants';
type Props = {|
+children: React.Node,
|};
type State = {|
layoutReady: boolean,
layout: number,
|};
/**
* NOTE: Default `layoutReady` value needs to be `false` only on web,
* where it's switched to `true` together with `layout` value
* initialisation inside `componentDidMount` because of Next.js SSR.
*/
const defaultState = {
layoutReady: Platform.OS !== 'web',
layout:
Platform.OS === 'web'
? LAYOUT.largeDesktop
: getLayout(Dimensions.get('window').width),
};
const { Provider, Consumer } = React.createContext<State>(defaultState);
export default class LayoutContextProvider extends React.Component<
Props,
State,
> {
constructor() {
super();
this.state = {
...defaultState,
};
}
componentDidMount() {
const layout = getLayout(Dimensions.get('window').width);
if (!this.state.layoutReady || this.state.layout !== layout) {
this.setState({
layoutReady: true,
layout,
});
}
Dimensions.addEventListener('change', this.handleDimensionsChange);
}
componentWillUnmount() {
Dimensions.removeEventListener('change', this.handleDimensionsChange);
}
handleDimensionsChange = ({ window }: Object) => {
const { layout } = this.state;
const newLayout = getLayout(window.width);
if (layout !== newLayout) {
this.setState({
layout: newLayout,
});
}
};
render() {
return <Provider value={this.state}>{this.props.children}</Provider>;
}
}
export const withLayoutContext = (select: State => Object) =>
withContext<State>(select, Consumer);
export type LayoutContextState = State;