callstack / react-native-paper

Material Design for React Native (Android & iOS)
https://reactnativepaper.com
MIT License
12.5k stars 2.05k forks source link

Menu First Render failure on React Native Windows #3793

Open acaininet opened 1 year ago

acaininet commented 1 year ago

Current behaviour

In the video below, running on react-native-windows (.71), on attempting to open menu the first time after load, the menu is rendered in an improper location and with no menu items.

If able to dismiss the initially rendered menu, then touch the anchor element again, the menu renders properly the second time with menu items rendered properly as well.

https://user-images.githubusercontent.com/104597574/228964703-3e10dcc5-9d9d-43b8-bd8c-8a3fde5075d1.mp4

Expected behaviour

On first render, setting show attribute to true, menu should render fully, properly positioned with menu items.

How to reproduce?

Create new react native project with react native windows and implement simple menu. https://github.com/acaininet/RNWPaperMenu0323

Preview

Video attached above.

What have you tried so far?

Various manipulation of containing elements, all the way down to most elemental (current version of code, with only as container. Various types of anchors, from more complex, including clickableopacity, down to Paper Button.

Your Environment

software version
+-- @babel/core@7.21.3

+-- @babel/preset-env@7.20.2 +-- @babel/runtime@7.21.0 +-- @react-native-community/eslint-config@3.2.0 +-- @tsconfig/react-native@2.0.3 +-- @types/jest@29.5.0 +-- @types/react-test-renderer@18.0.0 +-- @types/react@18.0.29 +-- babel-jest@29.5.0 +-- eslint@8.36.0 +-- jest@29.5.0 +-- metro-config@0.73.9 +-- metro-react-native-babel-preset@0.73.8 +-- prettier@2.8.7 +-- react-native-paper@5.5.1 +-- react-native-safe-area-context@4.5.0 +-- react-native-vector-icons@9.2.0 +-- react-native-windows@0.71.4 +-- react-native@0.71.4 +-- react-test-renderer@18.2.0 +-- react@18.2.0 `-- typescript@4.8.4

lukewalczak commented 1 year ago

Hey @acaininet, unfortunately, I've never used react-native-windows. Could you please try to dive deeper into your issue and try to investigate the problem?

acaininet commented 1 year ago

Here is what I have noticed so far: In the Menu show() function, the windowLayout, menuLayout, and anchorLayout are retrieved. If any width/height is 0, then RequestAnimationFrame is called. The inline documentation references that this is handled because native views may not be rendered yet, resulting in 0 measurements. Oddly, this seems to be true in windows on any updated call to show, menuLayout is always 0,0,0,0 until requestAnimationFrame is called.

When requestAnimationFrame returns to the show() call, we do notice a difference between the first render attempt and the second render attempt.

For the first render attempt, we get back these values for the layouts: { "windowLayout": { "width": 1060.8, "height": 682.4, "scale": 1.25, "fontScale": 1 }, "_yield$Promise$all": [ { "x": 8, "y": 8, "width": 128, "height": 160.8 }, { "x": 480, "y": 50.4, "width": 100, "height": 38.4 } ], "_yield$Promise$all2": [ { "x": 8, "y": 8, "width": 128, "height": 160.8 }, { "x": 480, "y": 50.4, "width": 100, "height": 38.4 } ], "menuLayout": { "x": 8, "y": 8, "width": 128, "height": 160.8 }, "anchorLayout": { "x": 480, "y": 50.4, "width": 100, "height": 38.4 } }

And for the second render: { "windowLayout": { "width": 1060.8, "height": 682.4, "scale": 1.25, "fontScale": 1 }, "_yield$Promise$all": [ { "x": 480, "y": 50.4, "width": 128, "height": 160.8 }, { "x": 480, "y": 50.4, "width": 100, "height": 38.4 } ], "_yield$Promise$all2": [ { "x": 480, "y": 50.4, "width": 128, "height": 160.8 }, { "x": 480, "y": 50.4, "width": 100, "height": 38.4 } ], "menuLayout": { "x": 480, "y": 50.4, "width": 128, "height": 160.8 }, "anchorLayout": { "x": 480, "y": 50.4, "width": 100, "height": 38.4 } }

Very odd that the first render menuLayout resolves to x,y coordinates of 8,8. Notably, these are the values of SCREEN_INDENT.

I have tried making the anchor a coordinate, with same result, so that doesn't seem to be the source issue.

I'm working my way through the render() function, but don't have a solution yet. Other than that initial render seems to be setting up those menuLayout x,y coordinates to SCREEN_INDENT value (8).

Veeeeksi commented 1 year ago

I have seen this same behaviour when using Menu component that the absolute position differs between first and second render. That's with expo app.

afonso-tsx commented 4 months ago

I'm also facing this issue, my solution was to use Flyout, if this Menu component is not working for over 1 year on windows it should be mentioned in the docs

caguirre2021 commented 3 months ago

I fix it using style of \<Menu>. Using top and left with the same values of anchor (x, y). And fix it (more or less).