-
-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathOverflowMenuContext.js
60 lines (52 loc) · 1.93 KB
/
OverflowMenuContext.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
// @flow
import * as React from 'react';
import { Dimensions, Platform } from 'react-native';
import { Menu } from './vendor/Menu';
export type ToggleMenuParam = ?{|
elements: React.ChildrenArray<any>,
x: number,
y: number,
|};
export const OVERFLOW_TOP = 15;
const warn = () => {
// this is here just to satisfy Flow, the noop value will be replaced
// by OverflowMenuProvider rendered in app root
console.warn(
'It seems like you tried to open the overflow menu using the overflowMenuPressHandlerDropdownMenu' +
' - which is the default handler on android - but you forgot to wrap your root component in <OverflowMenuProvider />.' +
'Please check the installation instructions in the react-navigation-header-buttons readme!'
);
};
export const OverflowMenuContext = React.createContext<(ToggleMenuParam) => void>(warn);
type Props = {|
children: React.Element<any>,
|};
export const OverflowMenuProvider = ({ children }: Props) => {
const [visible, setVisible] = React.useState(false);
const [position, setPosition] = React.useState({ x: Dimensions.get('window').width - 10, y: 40 });
const [elements, setElements] = React.useState(null);
const hideMenu = React.useCallback(() => {
setVisible(false);
}, []);
const toggleMenu = React.useCallback((params: ToggleMenuParam) => {
setVisible((prevVisible) => !prevVisible);
setElements(params?.elements || []);
if (params) {
const { x, y } = params;
const approxAndroidStatusBarHeight = 25;
const extraDelta = Platform.select({
android: OVERFLOW_TOP + approxAndroidStatusBarHeight,
default: OVERFLOW_TOP,
});
setPosition({ x, y: y + extraDelta });
}
}, []);
return (
<OverflowMenuContext.Provider value={toggleMenu}>
{React.Children.only(children)}
<Menu visible={visible} onDismiss={hideMenu} anchor={position}>
{elements}
</Menu>
</OverflowMenuContext.Provider>
);
};