Created
November 24, 2018 13:29
-
-
Save Jahans3/44ef456380231f537a453f08b0092a4c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
import React, { createContext, PureComponent, Children, type Element, type Component } from 'react'; | |
import { Animated, Keyboard } from 'react-native'; | |
export type OptionsTypes = 'alert' | 'warning' | 'success' | |
export type Option = { | |
icon?: number, | |
text: string, | |
onPress: Function, | |
type: OptionsTypes, | |
component?: () => Element<*> | |
} | |
export type OptionsContext = { | |
showOptionsMenu: Option => void, | |
hideOptionsMenu: () => void, | |
options: Array<Option> | |
} | |
type Props = { | |
children: Element<*> | |
} | |
type State = { | |
options: Array<Option>, | |
open: boolean, | |
overlayDisplay: 'flex' | 'none', | |
overlayOpacity: typeof Animated.Value, | |
containerPositionBottom: typeof Animated.Value, | |
} | |
const initialContext: OptionsContext = { | |
showOptionsMenu: () => null, | |
hideOptionsMenu: () => null, | |
options: [] | |
}; | |
const { Provider, Consumer } = createContext(initialContext); | |
export function withOptionsContext (WrappedComponent: Component<*>): Function { | |
return class OptionsContextHOC extends React.PureComponent { | |
render () { | |
return ( | |
<Consumer> | |
{(context: OptionsContext): Element<typeof WrappedComponent> => ( | |
<WrappedComponent {...context} {...this.props} /> | |
)} | |
</Consumer> | |
); | |
} | |
}; | |
} | |
/* eslint-disable react/no-multi-comp */ | |
class OptionsMenuProvider extends PureComponent<Props, State> { | |
state = { | |
options: [], | |
open: false, | |
overlayDisplay: 'none', | |
overlayOpacity: new Animated.Value(0), | |
containerPositionBottom: new Animated.Value(-95) | |
}; | |
showOptionsMenu: Function = ({ options }: { options: Array<Option> }): void => { | |
Keyboard.dismiss(); | |
this.setState({ overlayDisplay: 'flex', options }, () => { | |
Animated.timing(this.state.overlayOpacity, { | |
toValue: 0.5, | |
useNativeDriver: true, | |
duration: 150 | |
}).start(); | |
Animated.timing(this.state.containerPositionBottom, { | |
toValue: 0, | |
duration: 150 | |
}).start(); | |
}); | |
}; | |
hideOptionsMenu: Function = (): void => { | |
Animated.timing(this.state.containerPositionBottom, { | |
toValue: -95, | |
duration: 150 | |
}).start(); | |
Animated.timing(this.state.overlayOpacity, { | |
toValue: 0, | |
useNativeDriver: true, | |
duration: 150 | |
}).start(() => { | |
this.setState({ | |
open: false, | |
options: [], | |
overlayDisplay: 'none' | |
}); | |
}); | |
}; | |
render () { | |
return ( | |
<Provider | |
value={{ | |
showOptionsMenu: this.showOptionsMenu, | |
hideOptionsMenu: this.hideOptionsMenu, | |
...this.state | |
}} | |
> | |
{Children.only(this.props.children)} | |
</Provider> | |
); | |
} | |
} | |
export default { | |
Provider: OptionsMenuProvider, | |
Consumer | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment