Skip to content

Instantly share code, notes, and snippets.

@Jahans3
Created November 24, 2018 13:29
Show Gist options
  • Save Jahans3/44ef456380231f537a453f08b0092a4c to your computer and use it in GitHub Desktop.
Save Jahans3/44ef456380231f537a453f08b0092a4c to your computer and use it in GitHub Desktop.
// @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