microsoft / microsoft/react-native-windows
[0.74] Flyout does not display when target prop reference has been disabled
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 17.3k
- Forks
- 1.2k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 33
Description
Problem Description
I'm working on a react-native-windows project which was just recently updated to 0.74 from 0.66. After updating we had some issues arise with our custom dropdown component. In this component, a Touchable Opacity acts as the dropdown button and a Flyout is rendered to display the list of options in the dropdown underneath the button, using the Touchable Opacity reference for the target prop.
We disable the dropdown by disabling the touchable opacity. When the component is enabled again, the flyout stops rendering in unless it is forced to re-draw. This behaviour was not present before updating to 0.74.
I've provided a reproducible example which also shows that this issue is also seen with Pressable. It seems any target reference that is disabled atleast once, will prevent the Flyout from displaying with that target. A video demo of this example can be viewed below:
Steps To Reproduce
- In the demo app, pressing the two buttons should bring up their respective Flyouts at first
- When you press the 'enable/disable' button, it changes the state
isDisabledwhich is passed into the disabled prop of both the buttons. - After you disable and re-enable the buttons, the flyout is no longer rendered in.
Current Workaround for us
We found that passing the reference object of the View component within Touchable Opacity or Pressable to the target prop in Flyout gets around the issue for now, so this issue isn't blocker for our project
CLI version
13.6.6
Environment
System:
OS: Windows 10 10.0.19045
CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Memory: 11.31 GB / 31.69 GB
Binaries:
Node:
version: 18.20.2
path: C:\Program Files\nodejs\node.EXE
Yarn:
version: 3.6.4
path: C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm:
version: 10.5.0
path: C:\Program Files\nodejs\npm.CMD
Watchman: Not Found
SDKs:
Android SDK: Not Found
Windows SDK:
AllowDevelopmentWithoutDevLicense: Enabled
AllowAllTrustedApps: Enabled
Versions:
- 10.0.18362.0
- 10.0.19041.0
- 10.0.22621.0
IDEs:
Android Studio: AI-222.4459.24.2221.10121639
Visual Studio:
- 17.9.34728.123 (Visual Studio Professional 2022)
Languages:
Java: Not Found
Ruby:
version: 2.7.0
path: C:\Program Files\ServiceNow\agent-client-collector\embedded\bin\ruby.EXE
npmPackages:
"@react-native-community/cli": Not Found
react:
installed: 18.3.1
wanted: 18.3.1
react-native:
installed: 0.74.1
wanted: 0.74.1
react-native-windows:
installed: 0.74.4
wanted: 0.74.4
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: Not found
newArchEnabled: Not found
Target Device(s)
Desktop
Visual Studio Version
Visual Studio 2022
Build Configuration
Debug
Snack, code example, screenshot, or link to a repository
Code Snippet from Demo App
import React, { useRef, useState } from 'react';
import {
Button,
Pressable,
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import { Flyout } from 'react-native-windows';
function App(): React.JSX.Element {
const pressableRef = useRef(null);
const touchableOpacityRef = useRef(null);
const [expanded1, setExpanded1] = useState(false);
const [expanded2, setExpanded2] = useState(false);
const [isDisabled, setIsDisabled] = useState(false);
return (
<SafeAreaView style={styles.container}>
<View style={{flexDirection: 'row'}}>
<Pressable
onPress={() => setExpanded1(!expanded1)}
disabled={isDisabled}
ref={pressableRef}>
<View style={[styles.dropdownButton, {opacity: isDisabled ? 0.2 : 0.7}]}>
<Text>Pressable Button</Text>
</View>
<Flyout
isOpen={expanded1}
onDismiss={() => setExpanded1(false)}
target={pressableRef.current}
placement={'bottom-edge-aligned-left'}>
<View style={styles.dropdown}>
<Text>This flyout is triggered by the Pressable Component</Text>
</View>
</Flyout>
</Pressable>
<TouchableOpacity
onPress={() => setExpanded2(!expanded2)}
disabled={isDisabled}
ref={touchableOpacityRef}>
<View style={[styles.dropdownButton, {opacity: isDisabled ? 0.2 : 0.7}]}>
<Text>Touchable Opacity</Text>
</View>
<Flyout
isOpen={expanded2}
onDismiss={() => setExpanded2(false)}
target={touchableOpacityRef.current}
placement={'bottom-edge-aligned-left'}>
<View style={styles.dropdown}>
<Text>This flyout is triggered by the Touchable Opacity Component</Text>
</View>
</Flyout>
</TouchableOpacity>
</View>
<View style={{paddingLeft: 15}}>
<Button
title='enable/disable'
onPress={() => setIsDisabled(!isDisabled)}
/>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
marginTop: 250,
paddingHorizontal: 24,
flexDirection: 'row',
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
},
dropdownButton : {
height: 50,
width: 100,
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'grey',
marginHorizontal: 25
},
dropdown : {
height: 200,
width: 400,
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center'
}
});
export default App;
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the behavior in the demo App with Flyout targeting the Pressable and TouchableOpacity refs, then inspect the Flyout target handling involved when disabled changes. Done means both Flyouts display again after their targets are disabled and re-enabled, with regression coverage for that sequence.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react-native
- Domain
- desktop, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100