From b5a0ba080fa14be99ff4be1d1984802aeda3b38b Mon Sep 17 00:00:00 2001 From: Dominic Go Date: Sun, 1 Nov 2020 22:25:27 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Minor=20Changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RCTContextMenuViewManager.m | 2 +- .../RCTContextMenuViewManager.swift | 4 +- src/ContextMenuButton.ios.js | 206 +++++++++++++++++ src/ContextMenuButton.js | 211 +----------------- src/ContextMenuView.ios.js | 2 +- 5 files changed, 218 insertions(+), 207 deletions(-) create mode 100644 src/ContextMenuButton.ios.js diff --git a/ios/src_library/React Native/RCTContextMenuView/RCTContextMenuViewManager.m b/ios/src_library/React Native/RCTContextMenuView/RCTContextMenuViewManager.m index 82ea0c9..e7da40b 100644 --- a/ios/src_library/React Native/RCTContextMenuView/RCTContextMenuViewManager.m +++ b/ios/src_library/React Native/RCTContextMenuView/RCTContextMenuViewManager.m @@ -9,7 +9,7 @@ #import -@interface RCT_EXTERN_MODULE(RCTContextMenuManager, RCTViewManager) +@interface RCT_EXTERN_MODULE(RCTContextMenuViewManager, RCTViewManager) // ----------------------------------- // MARK: Props - RN Comp Props: Events diff --git a/ios/src_library/React Native/RCTContextMenuView/RCTContextMenuViewManager.swift b/ios/src_library/React Native/RCTContextMenuView/RCTContextMenuViewManager.swift index c38a3f0..8f197ba 100644 --- a/ios/src_library/React Native/RCTContextMenuView/RCTContextMenuViewManager.swift +++ b/ios/src_library/React Native/RCTContextMenuView/RCTContextMenuViewManager.swift @@ -7,8 +7,8 @@ import Foundation -@objc(RCTContextMenuManager) -class RCTContextMenuManager: RCTViewManager { +@objc(RCTContextMenuViewManager) +class RCTContextMenuViewManager: RCTViewManager { override static func requiresMainQueueSetup() -> Bool { return true; diff --git a/src/ContextMenuButton.ios.js b/src/ContextMenuButton.ios.js new file mode 100644 index 0000000..1d84716 --- /dev/null +++ b/src/ContextMenuButton.ios.js @@ -0,0 +1,206 @@ +import React from 'react'; +import { StyleSheet, Platform, requireNativeComponent, UIManager, View, TouchableOpacity } from 'react-native'; +import Proptypes from 'prop-types'; + +import { ActionSheetFallback } from './functions/ActionSheetFallback'; + + +const isContextMenuSupported = ( + (Platform.OS === 'ios') && + (parseInt(Platform.Version, 10) > 13) +); + + +const componentName = "RCTContextMenuButton"; +const NativeCommands = UIManager[componentName]?.Commands; +const NativeComponent = requireNativeComponent(componentName); + +const NATIVE_PROP_KEYS = { + // props: values -------- + menuConfig: 'menuConfig', + // props: flags --------------------------- + enableContextMenu : 'enableContextMenu' , + isMenuPrimaryAction: 'isMenuPrimaryAction', + // props: events -------------------- + onMenuWillShow : 'onMenuWillShow' , + onMenuWillHide : 'onMenuWillHide' , + onMenuWillCancel: 'onMenuWillCancel', + onMenuDidShow : 'onMenuDidShow' , + onMenuDidHide : 'onMenuDidHide' , + onMenuDidCancel : 'onMenuDidCancel' , + // props: onPress events ---------- + onPressMenuItem: 'onPressMenuItem', +}; + + +export class ContextMenuButton extends React.PureComponent { + static proptypes = { + menuConfig: Proptypes.object, + // flags ------------------------------ + enableContextMenu : Proptypes.bool, + isMenuPrimaryAction : Proptypes.bool, + useActionSheetFallback: Proptypes.bool, + wrapNativeComponent : Proptypes.bool, + // events ----------------------- + onMenuWillShow : Proptypes.func, + onMenuWillHide : Proptypes.func, + onMenuWillCancel: Proptypes.func, + onMenuDidShow : Proptypes.func, + onMenuDidHide : Proptypes.func, + onMenuDidCancel : Proptypes.func, + // onPress events -------------- + onPressMenuItem: Proptypes.func, + }; + + static defaultProps = { + enableContextMenu : true, + wrapNativeComponent : true, + useActionSheetFallback: !isContextMenuSupported, + }; + + constructor(props){ + super(props); + + this.state = { + menuVisible: false, + }; + }; + + getProps(){ + const { menuConfig, enableContextMenu, isMenuPrimaryAction, onMenuWillShow, onMenuWillHide, onMenuWillCancel, onMenuDidShow, onMenuDidHide, onMenuDidCancel, onPressMenuItem, ...otherProps } = this.props; + const nativeProps = { menuConfig, enableContextMenu, isMenuPrimaryAction, onMenuWillShow, onMenuWillHide, onMenuWillCancel, onMenuDidShow, onMenuDidHide, onMenuDidCancel, onPressMenuItem }; + return { nativeProps, ...otherProps }; + }; + + //#region - Event Handlers + _handleOnLongPress = async () => { + const { menuConfig, ...props } = this.props; + const item = await ActionSheetFallback.show(menuConfig); + + if(item == null){ + // cancelled pressed + props.onMenuDidCancel?.(); + + } else { + props.onPressMenuItem?.({nativeEvent: {...item}}); + }; + }; + + _handleOnMenuWillShow = (event) => { + const { onMenuWillShow } = this.props; + onMenuWillShow?.(event); + + this.setState({menuVisible: true}); + }; + + _handleOnMenuWillHide = (event) => { + const { onMenuWillHide } = this.props; + onMenuWillHide?.(event); + + this.setState({menuVisible: false}); + }; + + _handleOnMenuWillCancel = (event) => { + const { onMenuWillCancel } = this.props; + onMenuWillCancel?.(event); + }; + + _handleOnMenuDidShow = (event) => { + const { onMenuDidShow } = this.props; + onMenuDidShow?.(event); + }; + + _handleOnMenuDidHide = (event) => { + const { onMenuDidHide } = this.props; + onMenuDidHide?.(event); + }; + + _handleOnMenuDidCancel = (event) => { + const { onMenuDidCancel } = this.props; + onMenuDidCancel?.(event); + }; + + _handleOnPressMenuItem = (event) => { + this.props.onPressMenuItem?.(event); + }; + //#endregion + + _renderContextMenuView(){ + const { nativeProps, style, children, ...props } = this.getProps(); + const { menuVisible } = this.state; + + const nativeCompProps = { + // Native Props: Flags ------------------------------------------------- + [NATIVE_PROP_KEYS.menuConfig ]: nativeProps.menuConfig , + [NATIVE_PROP_KEYS.enableContextMenu ]: nativeProps.enableContextMenu , + [NATIVE_PROP_KEYS.isMenuPrimaryAction]: nativeProps.isMenuPrimaryAction, + // Native Props: Events ------------------------------------------ + [NATIVE_PROP_KEYS.onMenuWillShow ]: this._handleOnMenuWillShow , + [NATIVE_PROP_KEYS.onMenuWillHide ]: this._handleOnMenuWillHide , + [NATIVE_PROP_KEYS.onMenuWillCancel]: this._handleOnMenuWillCancel, + [NATIVE_PROP_KEYS.onMenuDidShow ]: this._handleOnMenuDidShow , + [NATIVE_PROP_KEYS.onMenuDidHide ]: this._handleOnMenuDidHide , + [NATIVE_PROP_KEYS.onMenuDidCancel ]: this._handleOnMenuDidCancel , + // Native Props: OnPress Events -------------------------------- + [NATIVE_PROP_KEYS.onPressMenuItem]: this._handleOnPressMenuItem, + }; + + const childItems = React.Children.map(children, child => + React.cloneElement(child, {menuVisible}) + ); + + return props.wrapNativeComponent? ( + + + {childItems} + + + ):( + + {childItems} + + ); + }; + + render(){ + const { useActionSheetFallback } = this.props; + const useContextMenuView = + (isContextMenuSupported && !useActionSheetFallback); + + return( + useContextMenuView? this._renderContextMenuView() : + useActionSheetFallback? ( + + {this.props.children} + + ):( + + {this.props.children} + + ) + ); + }; +}; + +const styles = StyleSheet.create({ + menuButton: { + backgroundColor: 'transparent', + }, + wrappedMenuButton: { + flex: 1, + }, +}); \ No newline at end of file diff --git a/src/ContextMenuButton.js b/src/ContextMenuButton.js index 1d84716..5cc1631 100644 --- a/src/ContextMenuButton.js +++ b/src/ContextMenuButton.js @@ -1,206 +1,11 @@ import React from 'react'; -import { StyleSheet, Platform, requireNativeComponent, UIManager, View, TouchableOpacity } from 'react-native'; -import Proptypes from 'prop-types'; - -import { ActionSheetFallback } from './functions/ActionSheetFallback'; +import { View } from 'react-native'; -const isContextMenuSupported = ( - (Platform.OS === 'ios') && - (parseInt(Platform.Version, 10) > 13) -); - - -const componentName = "RCTContextMenuButton"; -const NativeCommands = UIManager[componentName]?.Commands; -const NativeComponent = requireNativeComponent(componentName); - -const NATIVE_PROP_KEYS = { - // props: values -------- - menuConfig: 'menuConfig', - // props: flags --------------------------- - enableContextMenu : 'enableContextMenu' , - isMenuPrimaryAction: 'isMenuPrimaryAction', - // props: events -------------------- - onMenuWillShow : 'onMenuWillShow' , - onMenuWillHide : 'onMenuWillHide' , - onMenuWillCancel: 'onMenuWillCancel', - onMenuDidShow : 'onMenuDidShow' , - onMenuDidHide : 'onMenuDidHide' , - onMenuDidCancel : 'onMenuDidCancel' , - // props: onPress events ---------- - onPressMenuItem: 'onPressMenuItem', -}; - - -export class ContextMenuButton extends React.PureComponent { - static proptypes = { - menuConfig: Proptypes.object, - // flags ------------------------------ - enableContextMenu : Proptypes.bool, - isMenuPrimaryAction : Proptypes.bool, - useActionSheetFallback: Proptypes.bool, - wrapNativeComponent : Proptypes.bool, - // events ----------------------- - onMenuWillShow : Proptypes.func, - onMenuWillHide : Proptypes.func, - onMenuWillCancel: Proptypes.func, - onMenuDidShow : Proptypes.func, - onMenuDidHide : Proptypes.func, - onMenuDidCancel : Proptypes.func, - // onPress events -------------- - onPressMenuItem: Proptypes.func, - }; - - static defaultProps = { - enableContextMenu : true, - wrapNativeComponent : true, - useActionSheetFallback: !isContextMenuSupported, - }; - - constructor(props){ - super(props); - - this.state = { - menuVisible: false, - }; - }; - - getProps(){ - const { menuConfig, enableContextMenu, isMenuPrimaryAction, onMenuWillShow, onMenuWillHide, onMenuWillCancel, onMenuDidShow, onMenuDidHide, onMenuDidCancel, onPressMenuItem, ...otherProps } = this.props; - const nativeProps = { menuConfig, enableContextMenu, isMenuPrimaryAction, onMenuWillShow, onMenuWillHide, onMenuWillCancel, onMenuDidShow, onMenuDidHide, onMenuDidCancel, onPressMenuItem }; - return { nativeProps, ...otherProps }; - }; - - //#region - Event Handlers - _handleOnLongPress = async () => { - const { menuConfig, ...props } = this.props; - const item = await ActionSheetFallback.show(menuConfig); - - if(item == null){ - // cancelled pressed - props.onMenuDidCancel?.(); - - } else { - props.onPressMenuItem?.({nativeEvent: {...item}}); - }; - }; - - _handleOnMenuWillShow = (event) => { - const { onMenuWillShow } = this.props; - onMenuWillShow?.(event); - - this.setState({menuVisible: true}); - }; - - _handleOnMenuWillHide = (event) => { - const { onMenuWillHide } = this.props; - onMenuWillHide?.(event); - - this.setState({menuVisible: false}); - }; - - _handleOnMenuWillCancel = (event) => { - const { onMenuWillCancel } = this.props; - onMenuWillCancel?.(event); - }; - - _handleOnMenuDidShow = (event) => { - const { onMenuDidShow } = this.props; - onMenuDidShow?.(event); - }; - - _handleOnMenuDidHide = (event) => { - const { onMenuDidHide } = this.props; - onMenuDidHide?.(event); - }; - - _handleOnMenuDidCancel = (event) => { - const { onMenuDidCancel } = this.props; - onMenuDidCancel?.(event); - }; - - _handleOnPressMenuItem = (event) => { - this.props.onPressMenuItem?.(event); - }; - //#endregion - - _renderContextMenuView(){ - const { nativeProps, style, children, ...props } = this.getProps(); - const { menuVisible } = this.state; - - const nativeCompProps = { - // Native Props: Flags ------------------------------------------------- - [NATIVE_PROP_KEYS.menuConfig ]: nativeProps.menuConfig , - [NATIVE_PROP_KEYS.enableContextMenu ]: nativeProps.enableContextMenu , - [NATIVE_PROP_KEYS.isMenuPrimaryAction]: nativeProps.isMenuPrimaryAction, - // Native Props: Events ------------------------------------------ - [NATIVE_PROP_KEYS.onMenuWillShow ]: this._handleOnMenuWillShow , - [NATIVE_PROP_KEYS.onMenuWillHide ]: this._handleOnMenuWillHide , - [NATIVE_PROP_KEYS.onMenuWillCancel]: this._handleOnMenuWillCancel, - [NATIVE_PROP_KEYS.onMenuDidShow ]: this._handleOnMenuDidShow , - [NATIVE_PROP_KEYS.onMenuDidHide ]: this._handleOnMenuDidHide , - [NATIVE_PROP_KEYS.onMenuDidCancel ]: this._handleOnMenuDidCancel , - // Native Props: OnPress Events -------------------------------- - [NATIVE_PROP_KEYS.onPressMenuItem]: this._handleOnPressMenuItem, - }; - - const childItems = React.Children.map(children, child => - React.cloneElement(child, {menuVisible}) - ); - - return props.wrapNativeComponent? ( - - - {childItems} - - - ):( - - {childItems} - - ); - }; - - render(){ - const { useActionSheetFallback } = this.props; - const useContextMenuView = - (isContextMenuSupported && !useActionSheetFallback); - - return( - useContextMenuView? this._renderContextMenuView() : - useActionSheetFallback? ( - - {this.props.children} - - ):( - - {this.props.children} - - ) - ); - }; -}; - -const styles = StyleSheet.create({ - menuButton: { - backgroundColor: 'transparent', - }, - wrappedMenuButton: { - flex: 1, - }, -}); \ No newline at end of file +export function ContextMenuButton(props){ + return( + + {props.children} + + ); +}; \ No newline at end of file diff --git a/src/ContextMenuView.ios.js b/src/ContextMenuView.ios.js index 70a45b0..0d83454 100644 --- a/src/ContextMenuView.ios.js +++ b/src/ContextMenuView.ios.js @@ -11,7 +11,7 @@ const isContextMenuSupported = ( ); -const componentName = "RCTContextMenu"; +const componentName = "RCTContextMenuView"; const NativeCommands = UIManager[componentName]?.Commands; const NativeComponent = requireNativeComponent(componentName);