Skip to content
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

Add cursor prop to View and Touchables #760

Merged
merged 19 commits into from
Aug 22, 2022

Conversation

ryanlntn
Copy link

Please select one of the following

  • I am removing an existing difference between facebook/react-native and microsoft/react-native-macos 👍
  • I am cherry-picking a change from Facebook's react-native into microsoft/react-native-macos 👍
  • I am making a fix / change for the macOS implementation of react-native
  • I am making a change required for Microsoft usage of react-native

Summary

Adds support for managing cursor update events per Apple's Managing Cursor-Update Events documentation. Supports NSCursor name values and as many CSS name values as I could figure out given what's available on NSCursor.

Changelog

[macOS] [Added] - Add cursor prop to View and Touchables

Test Plan

Screen.Recording.2021-04-20.at.9.09.18.AM.mov

@"operationNotAllowed" : @(RCTCursorOperationNotAllowed),
@"dragLink" : @(RCTCursorDragLink),
@"dragCopy" : @(RCTCursorDragCopy),
@"contextualMenu" : @(RCTCursorContextualMenu),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we stick to the official CSS snake-case names? https://developer.mozilla.org/en-US/docs/Web/CSS/cursor

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me. I'm including "disappearing-item" as well which as far as I can tell has no equivalent in CSS.

case RCTCursorAuto:
if (self.focusable) {
[self addCursorRect:self.bounds cursor:[NSCursor pointingHandCursor]];
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm concerned about auto here since most buttons and other clickable items are focusable, but showing the hand over those is more appropriate on the web than for native applications.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm porting a web app so and using enough electron based apps that I didn't even notice this. You're right, most native applications tend not to use pointing hand on hover of buttons. I dropped this case.

@@ -1380,6 +1380,70 @@ - (void)drawFocusRingMask
#pragma mark - macOS Event Handler

#if TARGET_OS_OSX
- (void)resetCursorRects
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you might need to call [self discardCursorRects] here before adding new ones below.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, may I recommend having a NSCursor *cursor variable that can get set in the switch below, then afterwards add it to reduce some of the repetition here?

if (cursor) {
  [self addCursorRect:self.bounds cursor:cursor];
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I add one line of code: [super resetCursorRects];
It will stable display for cursor.

@"dragCopy" : @(RCTCursorDragCopy),
@"contextualMenu" : @(RCTCursorContextualMenu),
}),
RCTCursorAuto,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we default to "default" (RCTCursorArrow) here instead?

@NickGerleman
Copy link

I think some of the folks on Win32 Office came up with a similar prop. Let me dig it up for reference, in case it makes sense to align.

@NickGerleman
Copy link

Here was the windows one. Same cursor prop on view, exposing some different options.

https://github.com/microsoft/react-native-windows/blob/master/packages/%40office-iss/react-native-win32/src/Libraries/Components/View/ViewWin32.Props.ts

export type Cursor =
  | 'auto'
  | 'default'
  | 'pointer'
  | 'help'
  | 'not-allowed'
  | 'wait'
  | 'move'
  | 'nesw-resize'
  | 'ns-resize'
  | 'nwse-resize'
  | 'we-resize'
  | 'text'

@NickGerleman
Copy link

So I think everything is aligning to CSS props, but just exposing different ones for now.

@lyahdav
Copy link
Collaborator

lyahdav commented Apr 29, 2021

Thank you so much @ryanlntn for this PR, very timely as I was going to have to do this myself soon.

One thing I think should be changed: right now if you try to nest a View inside another View that has the cursor prop set, the cursor sometimes doesn't get updated correctly. To resolve you can:

  1. Update the RCT_ENUM_CONVERTER so that the default is RCTCursorAuto.
  2. Update switch in resetCursorRects to include:
    case RCTCursorArrow:
      cursor = [NSCursor arrowCursor];
      break;
  1. Remove the default from that switch.
  2. Move the call to discardCursorRects outside the if (cursor) check.

@ryanlntn
Copy link
Author

Thanks @lyahdav! Updated per the latest feedback.

@lyahdav
Copy link
Collaborator

lyahdav commented May 3, 2021

I have a couple more comments:

  1. @necolas gave feedback that this should be added to the styles and not added as a prop, and match the W3C spec as much as possible.
  2. We are repeating the list of valid cursor values in JS in TouchableWithoutFeedback.js and ViewPropTypes.js. Can we make this a Flow type that we reference everywhere it's needed instead?

@lyahdav
Copy link
Collaborator

lyahdav commented May 4, 2021

Here's a git patch of this PR making it a style prop:
0001-Add-cursor-prop-to-View.txt

@NickGerleman
Copy link

@lyahdav @appden it looks you're on top of this change. Lmk when it's ready for merge and I can bring it in.

@@ -24,6 +24,39 @@
#import "RCTTVView.h"
#endif

#if TARGET_OS_OSX
@implementation RCTConvert (UIView)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@implementation RCTConvert (UIView)
@implementation RCTConvert (RCTCursor)

@@ -16,6 +16,30 @@
extern const UIAccessibilityTraits SwitchAccessibilityTrait;
#endif // TODO(macOS ISS#2323203)

#if TARGET_OS_OSX
typedef NS_ENUM(NSInteger, RCTCursor) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put this into RCTCursor.h header along with the RCTConvert definition into a RCTCursor.m file, much like how RCTResizeMode is handled?

Copy link

@analysis-bot analysis-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code analysis results:

  • eslint found some issues. Run yarn lint --fix to automatically fix problems.

Libraries/Components/View/ViewPropTypes.js Outdated Show resolved Hide resolved
Libraries/Components/View/ViewPropTypes.js Outdated Show resolved Hide resolved
Libraries/StyleSheet/StyleSheetTypes.js Outdated Show resolved Hide resolved
@ghost ghost removed the Needs: Author Feedback label Aug 9, 2022
@shwanton
Copy link

shwanton commented Aug 9, 2022

@ryanlntn Thank you for pushing those changes!

Here is what the cursor looks like on View

CleanShot 2022-08-09 at 15 07 25

@Saadnajmi
Copy link
Collaborator

This should be good to go once build issues are fixed

@Saadnajmi
Copy link
Collaborator

Actually wait, is this a View prop or View_Style_ prop? I think windows implemented this as a View prop. Could we try and be consistent?

https://github.com/microsoft/react-native-windows/blob/ea292e188b4252c11a80a56ef8e94f7cfe5a6909/packages/%40office-iss/react-native-win32/src/Libraries/Components/View/Tests/ViewWin32Test.tsx#L226

@ryanlntn
Copy link
Author

@Saadnajmi It's both. I originally implemented as a view prop and extended to add as a view style prop as well per this feedback.

@ghost ghost removed the Needs: Author Feedback label Aug 10, 2022
@Saadnajmi
Copy link
Collaborator

OK, I just did a lot of chatting offline and it's agreed we prefer this as a style prop. Could you remove the bits that implement cursor a view prop and not a style prop and fix the build errors so we can move this PR forward?

@analysis-bot
Copy link

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: 7783f88
Branch: main

@mischreiber mischreiber merged commit 0ef7992 into microsoft:main Aug 22, 2022
@shwanton shwanton mentioned this pull request Nov 4, 2022
4 tasks
shwanton pushed a commit to shwanton/react-native-macos that referenced this pull request Feb 13, 2023
Summary: This brings in PR microsoft#760 to our repo.

Test Plan:
RNTester > View:

{F612877442}

Reviewers: skyle

Reviewed By: skyle

Subscribers: necolas, eliwhite

Differential Revision: https://phabricator.intern.facebook.com/D28158243

Tasks: T78743077

Signature: 28158243:1620330169:72c6c9e2371f2ac1a9edabedf3fd9d68468ccb8c

# Conflicts:
#	Libraries/Components/View/ReactNativeViewViewConfigMacOS.js
#	React/Views/RCTView.h
#	React/Views/RCTViewManager.m

# Conflicts:
#	packages/rn-tester/js/examples/Text/TextExample.ios.js
shwanton pushed a commit to shwanton/react-native-macos that referenced this pull request Feb 13, 2023
Summary: This brings in PR microsoft#760 to our repo.

Test Plan:
RNTester > View:

{F612877442}

Reviewers: skyle

Reviewed By: skyle

Subscribers: necolas, eliwhite

Differential Revision: https://phabricator.intern.facebook.com/D28158243

Tasks: T78743077

Signature: 28158243:1620330169:72c6c9e2371f2ac1a9edabedf3fd9d68468ccb8c

Remove Cursor for Text Component
shwanton pushed a commit to shwanton/react-native-macos that referenced this pull request Mar 10, 2023
Summary: This brings in PR microsoft#760 to our repo.

Test Plan:
RNTester > View:

{F612877442}

Reviewers: skyle

Reviewed By: skyle

Subscribers: necolas, eliwhite

Differential Revision: https://phabricator.intern.facebook.com/D28158243

Tasks: T78743077

Signature: 28158243:1620330169:72c6c9e2371f2ac1a9edabedf3fd9d68468ccb8c

# Conflicts:
#	Libraries/Components/View/ReactNativeViewViewConfigMacOS.js
#	React/Views/RCTView.h
#	React/Views/RCTViewManager.m

# Conflicts:
#	packages/rn-tester/js/examples/Text/TextExample.ios.js
facebook-github-bot pushed a commit to facebook/react-native that referenced this pull request Mar 5, 2024
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
huntie pushed a commit to facebook/react-native that referenced this pull request Mar 11, 2024
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.