-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cursor pointer API #750
Cursor pointer API #750
Conversation
7736dbc
to
9b8b0fc
Compare
|
||
Additionally, We have lots of React Native experiences in brownfield contexts at Microsoft. The value add of React Native over something like a webview is that we can access the system APIs, and provide the best UX for the platform. This includes iPadOS / visionOS, where hover events are now a part of the UX language and built into UIKit controls. In order for React Native experiences to thrive living side by side with native experiences, we would live to have as close UX as possible. | ||
|
||
This API can work side by side with the Pointer Events API. Users can choose to either spin up their own custom interactions with the pointer events API, or use Apple OS default. Adding a hover effect shouldn’t affect pointer events being fired or not. https://reactnative.dev/blog/2022/12/13/pointer-events-in-react-native |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@javache shared that Vision Pro SDK does not currently allow tracking gaze, beyond declarative hover events, to protect privacy of what the user is looking at. Under that model, pointer events don't seem possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, are you saying the existing pointer events API in React Native won't work in visionOS? The new hover effects that visionOS added seemed to me something separate from the existing APIs, which I thought should still work without issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vincent left more comprehensive information about this below.
<Pressable hoverEffect=”lift” onPress={onPressFunction}> | ||
<Text>I'm pressable!</Text> | ||
</Pressable> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having unprefixed, single platform props for shared components like Pressable
is a little bit smelly.
There are various schemes for prefixing and suffixing platform specific props in RN, and also ones we can do that we haven't tried yet (<Pressable apple:hoverEffect="lift">
)
This might actually belong on the Platform's View (or VisionOSView
instead), if we would ever want to support hover style outside Pressables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my head, something like hoverEffectIOS
or hoverEffectApple
is fine, though I feel it has been somewhat inconsistent in the past ( elevation
isn't elevationAndroid
, etc..). As implemented in the visionOS fork right now, it is a prop on the base <View>
, and <Pressable>
just sets a default that isn't none
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m curious, what do you call these events for Windows Ink (Surface or Asus Pen)? Or for hand selection tracking in MRTK/HoloLens? I think there’s both prior art and probably a way to (finally) pull some of these offshoots forward in a unified way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea what windows would call it 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RN Windows solution for this is pretty crummy.
The event shape for custom onMouseEnter
, onMouseLeave
is effectively exact copy of PointerPoint
So, API is not coherent with other platforms. IIRC it may not even be typed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pointer events unifies all of that, for I guess everything but Vision OS requiring declarative handling.
|
||
## Alternatives | ||
|
||
- This API might be also implemented using Pointer Events API by detecting hover and applying some custom styling to the view but this would be less performant than using native solution. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RN on Quest ends up doing something like:
- Set declarative information on view
- In native, on pointer move, show underlay, vibrate controllers, etc on native hit test, before ever dispatching to JS
Some of this is exposed via Animated.event
, which is a facility to animate native props when firing en event, before delivered to JS.
Thank you so much for putting together this RFC! I’m more or less going to take this opportunity to elaborate on my own alternative to this proposal that I’ve been thinking about for a while now, but didn’t have the bandwidth/priority to put one together myself. The summary/motivation you’ve described in this RFC is extremely similar to what I was thinking but there are big differences in how we approach the API design. As additional context I am part of the XPlat React/Convergence workstreams focusing on interoperability between platforms including web, and that greatly informs the lens I look through when approaching these APIs. As the person who is working on implementing Pointer Events, I was immediately curious as to the Vision Pro could take advantage of my work when it was announced. I quickly learned that the underlying eye gaze coordinates are never provided raw to userland code (unless an indirect/direct gesture is underway). This is instead done declaratively either through the APIs mentioned in the parent RFC or by default with Apple’s provided UI elements like UIButton — but this made me curious as to what Apple was doing for websites/Safari. Turns out Apple may have done the API design for us already! In the WWDC 2023 session titled “Meet Safari for spatial computing” around 4:58 they address this gap by saying that Safari will provide the hover highlight effect 1) on elements with roles that suggest they’re interactive or — most importantly — elements with the CSS style This is the API I think will best provide interoperability between all of the platforms I can think of, and makes the introduction of a new API to the core more palatable as its no longer specific to Apple platforms. Using The only rub with this API design is that Apple’s API doesn’t just have one As for the other, more specific effects I think those should be platform specific and we should use “prefixed” values like the web does (at least they used to). The core can consider the To begin with though (and to keep the scope of this RFC small) I’d suggest to at least start with just the |
@vincentriemer Thanks for the detailed response! I spoke with @okwasniewski offline and I think we both agree that
|
Thanks, @vincentriemer @Saadnajmi @NickGerleman @matthargett for great feedback on this RFC. I've updated the proposed solution as @vincentriemer described in his comment. |
Here we initialize a new `UIShape` which reassembles the current’s view layer `cornerRadius`. Next we are creating a `UIHoverEffect` instance based on the value passed by user. | ||
|
||
The current API implementation might need some polish to correctly retrieve corner radius. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would require some refactoring, but it would be nice if we could support the full custom border via separate-corner-radiuses-per-corner that RN supports (see RCTBorderDrawing.h
). This is easier to do on Fabric than on Paper I think, but should be doable with both.
- Only Android equivalent I found is: https://developer.android.com/reference/android/view/MotionEvent which doesn’t provide any built-in effect but allows to create custom ones. | ||
- There might be different plan for the Pointer Events API. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be curious to connect a mouse to an Android phone or tablet and see if the pointer ever changes around the system UI. I know you get a mouse cursor, I can test later. Regardless, this RFC should be apple-only to start IMO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Android has a cursor that's more similar to web than Apple platforms via this method on View. I'd rather limit the RFC to apply to all platforms (at least theoretically) but limit the APIs surface area (like focusing on just pointer: cursor
instead of all the different types).
I think to start with we should say that
Agreed. I do think it's worth exploring putting |
@vincentriemer I agree that limiting this to |
Update: Ready for review! |
Summary: Implement the cursor style prop for iOS (and consequently, visionOS), as described in this RFC: react-native-community/discussions-and-proposals#750 See related PR in React Native macOS, where we target macOS and visionOS (not running in iPad compatibility mode) with the same change: microsoft#2080 Docs update: facebook/react-native-website#4033 ## Changelog: [IOS] [ADDED] - Implement cursor style prop Pull Request resolved: #43078 Test Plan: See the added example page, running on iOS with the new architecture enabled. This also runs the same on the old architecture. https://github.com/facebook/react-native/assets/6722175/2af60a0c-1c1f-45c4-8d66-a20f6d5815df See the example page running on all three apple platforms. The JS is slightly different because: 1. The "macOS Cursors" example is not part of this PR but the one in React Native macOS. 2. This PR (and exapmple) has went though a bunch of iterations and It got hard taking videos of every change 😅 https://github.com/facebook/react-native/assets/6722175/7775ba7c-8624-4873-a735-7665b94b7233 ## Notes - React Native macOS added the cursor prop to View with microsoft#760 and Text with microsoft#1469 . Much of the implementation comes from there. - Due to an Apple bug, as of iOS 17.4 Beta 4, the shape of the iOS cursor hover effect doesn't render in the correct bounds (but it does on visionOS). I've worked around it with an ifdef. The result is that the hover effect will work on iOS and visionOS, but not iPad apps running in compatibility mode on visionOS. Reviewed By: NickGerleman Differential Revision: D54512945 Pulled By: vincentriemer fbshipit-source-id: 699e3a01a901f55a466a2c1a19f667aede5aab80
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Summary: Implement the cursor style prop for iOS (and consequently, visionOS), as described in this RFC: react-native-community/discussions-and-proposals#750 See related PR in React Native macOS, where we target macOS and visionOS (not running in iPad compatibility mode) with the same change: microsoft#2080 Docs update: facebook/react-native-website#4033 ## Changelog: [IOS] [ADDED] - Implement cursor style prop Pull Request resolved: #43078 Test Plan: See the added example page, running on iOS with the new architecture enabled. This also runs the same on the old architecture. https://github.com/facebook/react-native/assets/6722175/2af60a0c-1c1f-45c4-8d66-a20f6d5815df See the example page running on all three apple platforms. The JS is slightly different because: 1. The "macOS Cursors" example is not part of this PR but the one in React Native macOS. 2. This PR (and exapmple) has went though a bunch of iterations and It got hard taking videos of every change 😅 https://github.com/facebook/react-native/assets/6722175/7775ba7c-8624-4873-a735-7665b94b7233 ## Notes - React Native macOS added the cursor prop to View with microsoft#760 and Text with microsoft#1469 . Much of the implementation comes from there. - Due to an Apple bug, as of iOS 17.4 Beta 4, the shape of the iOS cursor hover effect doesn't render in the correct bounds (but it does on visionOS). I've worked around it with an ifdef. The result is that the hover effect will work on iOS and visionOS, but not iPad apps running in compatibility mode on visionOS. Reviewed By: NickGerleman Differential Revision: D54512945 Pulled By: vincentriemer fbshipit-source-id: 699e3a01a901f55a466a2c1a19f667aede5aab80
Hey! As this got implemented in facebook/react-native#43078 I think this PR can be merged (?) |
While we're on the subject, are there opinions against extending the "pointer-events" prop (not the new w3c api but the old one that controlled touch events) to also apply to cursors? That particular would help with some edge cases related to nested cursors, but I also know it's an old prop and may not be one we want to reuse. I think can be outside the scope of this rfc since the initial implementation already merged. |
@Saadnajmi Great addition! I haven't seen any discussion about See this WWDC 2020 video (timestamped link) for more details. Does it make sense to add support for |
@dlindenkreuz I decided not to try
I didn't realize it allowed the other cursor styles though! I'm not sure it makes sense to have both |
Agree. There are four effect styles: UIPointerEffect docs I don't think a CSS rule
Looks like |
This PR describes a new
cursor: "pointer"
API for iPad and Apple Vision Pro.I've created this proposal together with @Saadnajmi
A rendered version of the proposal can be read here