diff --git a/packages/rn-tester/js/components/RNTOption.js b/packages/rn-tester/js/components/RNTOption.js index 98993c4247d..0761424e17d 100644 --- a/packages/rn-tester/js/components/RNTOption.js +++ b/packages/rn-tester/js/components/RNTOption.js @@ -42,7 +42,7 @@ export default function RNTOption(props: Props): React.Node { : props.selected } hitSlop={4} - onPress={props.onPress} + onPress={props.disabled === true ? undefined : props.onPress} onPressIn={() => setPressed(true)} onPressOut={() => setPressed(false)} testID={props.testID}> diff --git a/packages/rn-tester/js/examples/Modal/ModalPresentation.js b/packages/rn-tester/js/examples/Modal/ModalPresentation.js index b2b2aab6bb6..7d4c42293dd 100644 --- a/packages/rn-tester/js/examples/Modal/ModalPresentation.js +++ b/packages/rn-tester/js/examples/Modal/ModalPresentation.js @@ -13,18 +13,10 @@ import * as React from 'react'; import {Modal, Platform, StyleSheet, Switch, Text, View} from 'react-native'; import type {RNTesterModuleExample} from '../../types/RNTesterTypes'; +import type {Props as ModalProps} from 'react-native/Libraries/Modal/Modal'; import RNTOption from '../../components/RNTOption'; const RNTesterButton = require('../../components/RNTesterButton'); -const supportedOrientations = { - Portrait: ['portrait'], - Landscape: ['landscape'], - 'Landscape Left': ['landscape-left'], - 'Portrait and Landscape Right': ['portrait', 'landscape-right'], - 'Portrait and Landscape': ['portrait', 'landscape'], - Default: [], -}; - const animationTypes = ['slide', 'none', 'fade']; const presentationStyles = [ 'fullScreen', @@ -32,76 +24,220 @@ const presentationStyles = [ 'formSheet', 'overFullScreen', ]; -const iOSActions = ['None', 'On Dismiss', 'On Show']; -const noniOSActions = ['None', 'On Show']; +const supportedOrientations = [ + 'portrait', + 'portrait-upside-down', + 'landscape', + 'landscape-left', + 'landscape-right', +]; function ModalPresentation() { - const [animationType, setAnimationType] = React.useState('none'); - const [transparent, setTransparent] = React.useState(false); - const [visible, setVisible] = React.useState(false); - const [hardwareAccelerated, setHardwareAccelerated] = React.useState(false); - const [statusBarTranslucent, setStatusBarTranslucent] = React.useState(false); - const [presentationStyle, setPresentationStyle] = - React.useState('fullScreen'); - const [supportedOrientationKey, setSupportedOrientationKey] = - React.useState('Portrait'); + const onDismiss = React.useCallback(() => { + alert('onDismiss'); + }, []); + + const onShow = React.useCallback(() => { + alert('onShow'); + }, []); + + const onRequestClose = React.useCallback(() => { + console.log('onRequestClose'); + }, []); + + const [props, setProps] = React.useState({ + animationType: 'none', + transparent: false, + hardwareAccelerated: false, + statusBarTranslucent: false, + presentationStyle: Platform.select({ + ios: 'fullScreen', + default: undefined, + }), + supportedOrientations: Platform.select({ + ios: ['portrait'], + default: undefined, + }), + onDismiss: undefined, + onShow: undefined, + visible: false, + }); + const presentationStyle = props.presentationStyle; + const hardwareAccelerated = props.hardwareAccelerated; + const statusBarTranslucent = props.statusBarTranslucent; + const [currentOrientation, setCurrentOrientation] = React.useState('unknown'); - const [action, setAction] = React.useState('None'); - const actions = Platform.OS === 'ios' ? iOSActions : noniOSActions; - const onDismiss = () => { - setVisible(false); - if (action === 'onDismiss') { - alert('onDismiss'); - } - }; - const onShow = () => { - if (action === 'onShow') { - alert('onShow'); - } - }; /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's * LTI update could not be added via codemod */ const onOrientationChange = event => setCurrentOrientation(event.nativeEvent.orientation); - const modalBackgroundStyle = { - backgroundColor: transparent ? 'rgba(0, 0, 0, 0.5)' : '#f5fcff', - }; - const innerContainerTransparentStyle = transparent - ? {backgroundColor: '#fff', padding: 20} - : null; + + const controls = ( + <> + + Status Bar Translucent 🟢 + + setProps(prev => ({...prev, statusBarTranslucent: enabled})) + } + /> + + + Hardware Acceleration 🟢 + + setProps(prev => ({ + ...prev, + hardwareAccelerated: enabled, + })) + } + /> + + + Presentation Style ⚫️ + + {presentationStyles.map(type => ( + + setProps(prev => { + if (type === 'overFullScreen' && prev.transparent === true) { + return { + ...prev, + presentationStyle: type, + transparent: false, + }; + } + return { + ...prev, + presentationStyle: + type === prev.presentationStyle ? undefined : type, + }; + }) + } + selected={type === presentationStyle} + /> + ))} + + + + + Transparent + + setProps(prev => ({...prev, transparent: enabled})) + } + /> + + {Platform.OS === 'ios' && presentationStyle !== 'overFullScreen' ? ( + + iOS Modal can only be transparent with 'overFullScreen' Presentation + Style + + ) : null} + + + Supported Orientation ⚫️ + + {supportedOrientations.map(orientation => ( + + setProps(prev => { + if (prev.supportedOrientations?.includes(orientation)) { + return { + ...prev, + supportedOrientations: prev.supportedOrientations?.filter( + o => o !== orientation, + ), + }; + } + return { + ...prev, + supportedOrientations: [ + ...(prev.supportedOrientations ?? []), + orientation, + ], + }; + }) + } + selected={props.supportedOrientations?.includes(orientation)} + /> + ))} + + + + Actions + + + setProps(prev => ({ + ...prev, + onShow: prev.onShow ? undefined : onShow, + })) + } + selected={!!props.onShow} + /> + + setProps(prev => ({ + ...prev, + onDismiss: prev.onDismiss ? undefined : onDismiss, + })) + } + selected={!!props.onDismiss} + /> + + + + ); + return ( - setVisible(true)}> + setProps(prev => ({...prev, visible: true}))}> Show Modal - - + {...props} + onRequestClose={onRequestClose} + onOrientationChange={onOrientationChange}> + + - This modal was presented with animationType: '{animationType}' + This modal was presented with animationType: ' + {props.animationType}' {Platform.OS === 'ios' ? ( It is currently displayed in {currentOrientation} mode. ) : null} - Close + setProps(prev => ({...prev, visible: false}))}> + Close + + {controls} @@ -113,101 +249,13 @@ function ModalPresentation() { key={type} style={styles.option} label={type} - onPress={() => setAnimationType(type)} - selected={type === animationType} + onPress={() => setProps(prev => ({...prev, animationType: type}))} + selected={type === props.animationType} /> ))} - {Platform.OS === 'android' && Platform.isTV !== true ? ( - <> - - Status Bar Translucent - - setStatusBarTranslucent(!statusBarTranslucent) - } - /> - - - Hardware Acceleration - setHardwareAccelerated(!hardwareAccelerated)} - /> - - - ) : null} - {Platform.isTV !== true ? ( - <> - {Platform.OS === 'ios' ? ( - - Presentation Style - - {presentationStyles.map(type => ( - { - if (type !== 'overFullScreen' && transparent) { - setTransparent(false); - } - setPresentationStyle(type); - }} - selected={type === presentationStyle} - /> - ))} - - - ) : null} - - - Transparent - setTransparent(!transparent)} - /> - - {Platform.OS === 'ios' && presentationStyle !== 'overFullScreen' ? ( - - iOS Modal can only be transparent with 'overFullScreen' - Presentation Style - - ) : null} - - - Supported Orientation - - {Object.keys(supportedOrientations).map(label => ( - setSupportedOrientationKey(label)} - selected={label === supportedOrientationKey} - /> - ))} - - - - Actions - - {actions.map(value => ( - setAction(value)} - selected={value === action} - /> - ))} - - - - ) : null} + {controls} ); } @@ -249,7 +297,8 @@ const styles = StyleSheet.create({ }, modalInnerContainer: { borderRadius: 10, - alignItems: 'center', + backgroundColor: '#fff', + padding: 10, }, warning: { margin: 3,