Skip to content

[macOS] Introduce VibrancyView #3026

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

Merged
merged 29 commits into from
Aug 16, 2023
Merged

Conversation

Saadnajmi
Copy link
Collaborator

@Saadnajmi Saadnajmi commented Aug 11, 2023

Platforms Impacted

  • iOS
  • macOS
  • win32 (Office)
  • windows
  • android

Description of changes

On macOS, a large part of the design system is the concept of Vibrancy, which is largely controlled and defined by NSVisualEffectView. We don't have a generic native component exposed for NSVisualEffectView, so let's create one: VibrancyView! The name was chosen as it matches well with the iOS equivalent React Native component in @react-native-community/react-native-blur, which might be a potential place to move or copy this native component, should we want to.

This also gives us the side benefit that, with blendingMode={behindWindow}, we can overlay our VibrancyView on top of Callout (which had a hardcoded NSVisualEffectView with material 'menu) and effectively render a different material, making #3001 redundant.

There were two special considerations taken to make our native component more usable on React Native macOS:

  1. Our Native VibrancyView is actually an RCTView with a NSVisualEffectView subview. This is done so that our native component inherits all of ViewProps. In order to make sure all children are subviews of our NSVisualEffectView, we override insertReactSubview.

  2. While writing this native component, I found there were lots of issues with getting rendering and register clicks properly. This is due to differences in how UIKit (used by React Native on iOS) and Appkit (used by React Native macOS) handle hit testing and coordinate systems. In React Native macOS, we have custom code in RCTView / RCTTouchHandler/etc to mitigate that, but an arbitrary native component derived from NSView will not. Therefore, instead of wrapping NSVisualEffectView directly, I wrote a FixedVisualEffectView class with some extra code to work with React Native macOS and other RCTViews properly. I put in as much comments as I can to explain what is happening. Many thanks to @lenaic for helping me find solutions here.

Verification

Wrote a test page with a lot of tests

Screen.Recording.2023-08-16.at.11.19.16.AM.mov

Pull request checklist

This PR has considered (when applicable):

  • Automated Tests
  • Documentation and examples
  • Keyboard Accessibility
  • Voiceover
  • Internationalization and Right-to-left Layouts

@rurikoaraki
Copy link
Collaborator

Only reviewed the TS

@lyzhan7
Copy link
Contributor

lyzhan7 commented Aug 16, 2023

Add video for dark mode?

@Saadnajmi
Copy link
Collaborator Author

Add video for dark mode?

updated

@Saadnajmi Saadnajmi enabled auto-merge (squash) August 16, 2023 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants