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

[fabric] Fixes to core fabric components #2117

Draft
wants to merge 80 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
c437f2f
[fabric] Make text input first responder through the window instance
Aug 25, 2023
355f73b
[fabric] Fix hit testing calls going through LegacyViewManagerInterop…
Sep 8, 2023
35259d8
[fabric] Add support for clipsToBounds to RCTViewComponentView
Sep 13, 2023
db854b2
[fabric] Add text storage getter to set up text views outside text la…
Sep 20, 2023
de055ae
[fabric] Render Paragraph text using NSTextView
Sep 20, 2023
71fae19
[fabric] Support selection of Paragraph component text content
Sep 20, 2023
1b11edc
[fabric] Fix events being dispatched to wrong react component for Pap…
Oct 4, 2023
53f631f
[fabric] Fix missing import
Oct 4, 2023
b53775d
[fabric] Fix onPress not working for Text
Oct 9, 2023
5ace629
[fabric] Add native focus props to ViewComponentView
shwanton Oct 6, 2023
28a761f
[fabric] Don't flatten View if focusable or enableFocusRing
shwanton Oct 9, 2023
80b6b44
[fabric] Adapt transforms to CALayer top-left anchor point
Oct 25, 2023
0c79cb2
[fabric] Make text input resign first responder through the window in…
Oct 26, 2023
64b4213
[fabric] Disable view flattening in VirtualizedList cells
Oct 31, 2023
f74997f
[fabric] Add conditional coordinate space conversion for native view …
Nov 8, 2023
474fcb9
[fabric] Add iterator to SurfaceTelemetry.cpp
8Keep Nov 9, 2023
fadf8a8
[fabric] Disable view flattening in header/footer/empty/spacer compon…
Nov 10, 2023
99ae714
[fabric] Enable Automatic Spelling Correction
shwanton Nov 1, 2023
e8e940d
[fabric] Enable Continuous Spell Checking
shwanton Nov 9, 2023
a1602d3
[fabric] Enable Grammar Checking
shwanton Nov 9, 2023
d7d97d1
[fabric] Static cast BOOL values event data struct init for TextInput
Nov 13, 2023
f84e599
[fabric] Selection range should use the correct backed input range
shwanton Nov 2, 2023
c681a1d
[fabric][a11y] Enable accessibility property assignments for View
Dec 1, 2023
b2ac7c1
[fabric][a11y] Add role mapping for common traits
Dec 1, 2023
95fddef
[fabric][a11y] Add role mapping for desktop specific traits
Dec 1, 2023
7b11d43
[fabric][a11y] Make text render with static text role
Dec 1, 2023
1aeb068
[fabric] Add wrapper class for TextView with scroll callback support
Dec 7, 2023
6f29763
[fabric] Add responder property to backing text input view protocol
Dec 7, 2023
e017f32
[fabric] Update backed text input copy method to support view instances
Dec 7, 2023
3c8cdb6
[fabric] Use wrapped text view for multiline TextInput
Dec 7, 2023
94e4090
[fabric] Support showing/hiding the focus ring for TextInput
Dec 9, 2023
4c79515
[fabric] Implement escape/cancel key press callback for TextInput
Dec 9, 2023
042fb07
[fabric] Submit scroll view metrics when scrolling multiline TextInput
Dec 9, 2023
ea1810f
[fabric] Fix random TextInput cursor position changes while typing
Jan 15, 2024
6af8d4d
[fabric] Add submitKeyEvents property to TextInput
Jan 18, 2024
ea8abc6
[fabric] Implement TextInput key down event checking for submit
Jan 18, 2024
d7434f2
[fabric] Add support for clearing the TextInput on submit
Jan 18, 2024
64cd166
[fabric] Add support for the secure text entry to TextInput
Jan 19, 2024
737ac48
[fabric] Copy accessibility attributes when switching TextInput backi…
Jan 19, 2024
3ef4f80
[fabric] Add HostPlatformViewProps to ViewProps
Jan 29, 2024
3d5deb8
[fabric] Add HostPlatformViewEventEmitter to ViewEventEmitter
Jan 29, 2024
950074e
[fabric] Move focus props to HostPlatformViewProps
Jan 29, 2024
49b4cce
[fabric] Add valid key down/up props to View
Jan 30, 2024
ed98b65
[fabric] Add key down/up event emitters to View
Jan 30, 2024
070fd4e
[fabric] Add key down/up handling to View component
Jan 30, 2024
60d4b5d
[fabric] Add keyboard event handling to TextInput component
Jan 30, 2024
94acea9
[fabric] Fix missing includes for windows build
Jan 30, 2024
29de265
[fabric] Add mouse event props to View
Feb 7, 2024
c17a1dc
[fabric] Add mouse enter/leave tracking to the View component
Feb 7, 2024
2186042
[fabric] Disable view flattening for views using mouse events
Feb 7, 2024
403abec
[fabric] Add mouse enter/leave tracking on scroll
Feb 7, 2024
00e38a2
[fabric] Check for assigned event emitter before sending key/mouse ev…
Feb 8, 2024
160454f
[fabric] Add draggedTypes prop to View
Feb 12, 2024
b5b4ba9
[fabric] Add drag and drop event emitters to View
Feb 12, 2024
b121fc3
[fabric] Add drag and drop support to View component
Feb 12, 2024
2c06459
[fabric] Add drag and drop support to TextInput component
Feb 12, 2024
9be4bfb
[fabric] Limit draggedTypes prop values to supported options
Feb 13, 2024
53d0115
[fabric] Add file paste event emitter to TextInput component
Feb 13, 2024
81a1e3d
[fabric] Add file paste support to TextInput component
Feb 13, 2024
7ecb2f6
[fabric] Fix missing method declaration of View component
Feb 13, 2024
1b5364e
[fabric] Fix namespace in View component header
Feb 13, 2024
6f05e54
[fabric] Fix crash on key up in non focusable view
Feb 20, 2024
8b630fb
[fabric] Add missing pragma marks in macOS view event emitter
Feb 20, 2024
8c6444a
[fabric] Add focus/blur event emitters to View
Feb 20, 2024
699610c
[fabric] Add View focus/blur event emitting on first responder change
Feb 20, 2024
547d683
[fabric] Add double click event prop to View component
Feb 21, 2024
ba2378a
[fabric] Add double click support to View component
Feb 21, 2024
bb12e7a
[fabric] Make RCTViewComponentView to be layer-backed by enabling wan…
shwanton Apr 27, 2024
b0e32bb
[fabric] Clean up explicit namespace references in View component
Feb 22, 2024
62470f4
[fabric] Add support for setting a tool tip on View component
Feb 22, 2024
ed66784
[fabric] Add cursor prop to View component
Feb 23, 2024
6b82927
[fabric] Add support for updating cursor to View component
Feb 23, 2024
3a14d9b
[fabric] TextInput should get focus with `autoFocus` prop
shwanton Mar 13, 2024
398ed3f
[fabric] Fix random text display for undefined text content
Mar 26, 2024
254f4db
[fabric] TextInput should handle pasted types prop
shwanton Apr 25, 2024
d6b404c
[upstream][paper] Fix crash when statically enabling wantsUpdateLayer…
Feb 22, 2024
a430e28
[fabric][touch-handler] Remove `cancelTouchWithEvent` till surface to…
shwanton May 1, 2024
cc052f5
[fabric] Refactor MacOS view props & emitters
shwanton Apr 30, 2024
fe4989a
[fabric] Revert to Core Cursor implementation
shwanton May 1, 2024
6b0fd9c
[fabric] Fix warning & formatting
shwanton May 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#if TARGET_OS_OSX // [macOS

#import <React/RCTUIKit.h>

#import "RCTTextUIKit.h"

#import <React/RCTBackedTextInputDelegate.h>
#import <React/RCTBackedTextInputViewProtocol.h>

NS_ASSUME_NONNULL_BEGIN

@interface RCTWrappedTextView : RCTPlatformView <RCTBackedTextInputViewProtocol>

@property (nonatomic, weak) id<RCTBackedTextInputDelegate> textInputDelegate;
@property (assign) BOOL hideVerticalScrollIndicator;

@end

NS_ASSUME_NONNULL_END

#endif // macOS]
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#if TARGET_OS_OSX // [macOS

#import <React/RCTWrappedTextView.h>

#import <React/RCTUITextView.h>
#import <React/RCTTextAttributes.h>

@implementation RCTWrappedTextView {
RCTUITextView *_forwardingTextView;
RCTUIScrollView *_scrollView;
RCTClipView *_clipView;
}

- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

self.hideVerticalScrollIndicator = NO;

_scrollView = [[RCTUIScrollView alloc] initWithFrame:self.bounds];
_scrollView.backgroundColor = [RCTUIColor clearColor];
_scrollView.drawsBackground = NO;
_scrollView.borderType = NSNoBorder;
_scrollView.hasHorizontalRuler = NO;
_scrollView.hasVerticalRuler = NO;
_scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[_scrollView setHasVerticalScroller:YES];
[_scrollView setHasHorizontalScroller:NO];

_clipView = [[RCTClipView alloc] initWithFrame:_scrollView.bounds];
[_scrollView setContentView:_clipView];

_forwardingTextView = [[RCTUITextView alloc] initWithFrame:_scrollView.bounds];
_forwardingTextView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_forwardingTextView.delegate = self;

_forwardingTextView.verticallyResizable = YES;
_forwardingTextView.horizontallyResizable = YES;
_forwardingTextView.textContainer.containerSize = NSMakeSize(FLT_MAX, FLT_MAX);
_forwardingTextView.textContainer.widthTracksTextView = YES;
_forwardingTextView.textInputDelegate = self;

_scrollView.documentView = _forwardingTextView;
_scrollView.contentView.postsBoundsChangedNotifications = YES;

// Enable the focus ring by default
_scrollView.enableFocusRing = YES;
[self addSubview:_scrollView];

// a register for those notifications on the content view.
#if !TARGET_OS_OSX // [macOS]
Copy link
Author

Choose a reason for hiding this comment

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

Remove mobile code since this file is macOS only. @lenaic should we nest these files in a macos specific folder?

Copy link

Choose a reason for hiding this comment

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

The file is macOS specific, it could be placed in its own macOS subfolder to make it more obvious.

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(boundsDidChange:)
name:NSViewBoundsDidChangeNotification
object:_scrollView.contentView];
#else // [macOS
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(scrollViewDidScroll:)
name:NSViewBoundsDidChangeNotification
object:_scrollView.contentView];
#endif // macOS]
}

return self;
}

- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (BOOL)isFlipped
{
return YES;
}

#pragma mark -
#pragma mark Method forwarding to text view

- (void)forwardInvocation:(NSInvocation *)invocation
{
[invocation invokeWithTarget:_forwardingTextView];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
if ([_forwardingTextView respondsToSelector:selector]) {
return [_forwardingTextView methodSignatureForSelector:selector];
}

return [super methodSignatureForSelector:selector];
}

- (void)boundsDidChange:(NSNotification *)notification
{
}

#pragma mark -
#pragma mark First Responder forwarding

- (NSResponder *)responder
{
return _forwardingTextView;
}

- (BOOL)acceptsFirstResponder
{
return _forwardingTextView.acceptsFirstResponder;
}

- (BOOL)becomeFirstResponder
{
return [_forwardingTextView becomeFirstResponder];
}

- (BOOL)resignFirstResponder
{
return [_forwardingTextView resignFirstResponder];
}

#pragma mark -
#pragma mark Text Input delegate forwarding

- (id<RCTBackedTextInputDelegate>)textInputDelegate
{
return _forwardingTextView.textInputDelegate;
}

- (void)setTextInputDelegate:(id<RCTBackedTextInputDelegate>)textInputDelegate
{
_forwardingTextView.textInputDelegate = textInputDelegate;
}

#pragma mark -
#pragma mark Scrolling control

#if TARGET_OS_OSX // [macOS
- (void)scrollViewDidScroll:(NSNotification *)notification
{
[self.textInputDelegate scrollViewDidScroll:_scrollView];
}
#endif // macOS]

- (BOOL)scrollEnabled
{
return _scrollView.isScrollEnabled;
}

- (void)setScrollEnabled:(BOOL)scrollEnabled
{
if (scrollEnabled) {
_scrollView.scrollEnabled = YES;
[_clipView setConstrainScrolling:NO];
} else {
_scrollView.scrollEnabled = NO;
[_clipView setConstrainScrolling:YES];
}
}

- (BOOL)shouldShowVerticalScrollbar
{
// Hide vertical scrollbar if explicity set to NO
if (self.hideVerticalScrollIndicator) {
return NO;
}

// Hide vertical scrollbar if attributed text overflows view
CGSize textViewSize = [_forwardingTextView intrinsicContentSize];
NSClipView *clipView = (NSClipView *)_scrollView.contentView;
if (textViewSize.height > clipView.bounds.size.height) {
return YES;
};

return NO;
}

- (void)textInputDidChange
{
[_scrollView setHasVerticalScroller:[self shouldShowVerticalScrollbar]];
}

- (void)setAttributedText:(NSAttributedString *)attributedText
{
[_forwardingTextView setAttributedText:attributedText];
[_scrollView setHasVerticalScroller:[self shouldShowVerticalScrollbar]];
}

#pragma mark -
#pragma mark Text Container Inset override for NSTextView

// This method is there to match the textContainerInset property on RCTUITextField
- (void)setTextContainerInset:(UIEdgeInsets)textContainerInsets
{
// RCTUITextView has logic in setTextContainerInset[s] to convert th UIEdgeInsets to a valid NSSize struct
_forwardingTextView.textContainerInsets = textContainerInsets;
}

#pragma mark -
#pragma mark Focus ring

- (BOOL)enableFocusRing
{
return _scrollView.enableFocusRing;
}

- (void)setEnableFocusRing:(BOOL)enableFocusRing
{
_scrollView.enableFocusRing = enableFocusRing;
}

@end

#endif // macOS]
Original file line number Diff line number Diff line change
Expand Up @@ -391,17 +391,17 @@ - (void)textViewDidChangeSelection:(__unused UITextView *)textView
[self textViewProbablyDidChangeSelection];
}

#endif // [macOS]

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
- (void)scrollViewDidScroll:(RCTUIScrollView *)scrollView // [macOS]
{
if ([_backedTextInputView.textInputDelegate respondsToSelector:@selector(scrollViewDidScroll:)]) {
[_backedTextInputView.textInputDelegate scrollViewDidScroll:scrollView];
}
}

#endif // [macOS]

#if TARGET_OS_OSX // [macOS

#pragma mark - NSTextViewDelegate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign, readonly) BOOL textWasPasted;
#else // [macOS
@property (nonatomic, assign) BOOL textWasPasted;
@property (nonatomic, readonly) NSResponder *responder;
@property (nonatomic, assign) BOOL enableFocusRing;
#endif // macOS]
@property (nonatomic, assign, readonly) BOOL dictationRecognizing;
@property (nonatomic, assign) UIEdgeInsets textContainerInset;
Expand All @@ -62,6 +64,9 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign, readonly) UIEdgeInsets contentInset;
#if TARGET_OS_OSX // [macOS
@property (nonatomic, assign) CGFloat pointScaleFactor;
@property (nonatomic, getter=isAutomaticSpellingCorrectionEnabled) BOOL automaticSpellingCorrectionEnabled;
@property (nonatomic, getter=isGrammarCheckingEnabled) BOOL grammarCheckingEnabled;
@property (nonatomic, getter=isContinuousSpellCheckingEnabled) BOOL continuousSpellCheckingEnabled;
#endif // macOS]

// This protocol disallows direct access to `selectedTextRange` property because
Expand All @@ -81,6 +86,7 @@ NS_ASSUME_NONNULL_BEGIN
#if TARGET_OS_OSX // [macOS
// UITextInput method for OSX
- (CGSize)sizeThatFits:(CGSize)size;
- (void)setReadablePasteBoardTypes:(NSArray<NSPasteboardType> *)readablePasteboardTypes;
#endif // macOS]

// This protocol disallows direct access to `text` property because
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN
#if !TARGET_OS_OSX // [macOS]
@property (nonatomic, assign, getter=isEditable) BOOL editable;
#else // [macOS
@property (assign, getter=isEditable) BOOL editable;
@property (atomic, assign, getter=isEditable) BOOL editable;
#endif // macOS]
@property (nonatomic, getter=isScrollEnabled) BOOL scrollEnabled;
@property (nonatomic, strong, nullable) NSString *inputAccessoryViewID;
Expand All @@ -56,7 +56,7 @@ NS_ASSUME_NONNULL_BEGIN
#if TARGET_OS_OSX // [macOS
@property (nonatomic, copy, nullable) NSString *text;
@property (nonatomic, copy, nullable) NSAttributedString *attributedText;
@property (nonatomic, copy) NSDictionary<NSAttributedStringKey, id> *defaultTextAttributes;
@property (nonatomic, strong, nullable) NSDictionary<NSAttributedStringKey, id> *defaultTextAttributes;
@property (nonatomic, assign) NSTextAlignment textAlignment;
@property (nonatomic, getter=isAutomaticTextReplacementEnabled) BOOL automaticTextReplacementEnabled;
@property (nonatomic, getter=isAutomaticSpellingCorrectionEnabled) BOOL automaticSpellingCorrectionEnabled;
Expand All @@ -66,6 +66,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong, nullable) RCTUIColor *selectionColor;
@property (weak, nullable) id<RCTUITextFieldDelegate> delegate;
@property (nonatomic, assign) CGFloat pointScaleFactor;

- (void)setReadablePasteBoardTypes:(NSArray<NSPasteboardType> *)readablePasteboardTypes;
#endif // macOS]

@property (nonatomic, getter=isGhostTextChanging) BOOL ghostTextChanging; // [macOS]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ @implementation RCTUITextField {
#endif
RCTBackedTextFieldDelegateAdapter *_textInputDelegateAdapter;
NSDictionary<NSAttributedStringKey, id> *_defaultTextAttributes;
#if TARGET_OS_OSX // [macOS
NSArray<NSPasteboardType> *_readablePasteboardTypes;
#endif // macOS]
}

#if TARGET_OS_OSX // [macOS
Expand Down Expand Up @@ -196,6 +199,11 @@ - (void)setTextContainerInset:(UIEdgeInsets)textContainerInset

#if TARGET_OS_OSX // [macOS

- (NSResponder *)responder
{
return self;
}

+ (Class)cellClass
{
return RCTUITextFieldCell.class;
Expand Down Expand Up @@ -660,5 +668,12 @@ - (void)keyUp:(NSEvent *)event {
}
}
#endif // macOS]

#if TARGET_OS_OSX // [macOS
- (void)setReadablePasteBoardTypes:(NSArray<NSPasteboardType> *)readablePasteboardTypes
{
_readablePasteboardTypes = readablePasteboardTypes;
}
#endif // macOS]

@end
9 changes: 8 additions & 1 deletion packages/react-native/React/Base/macOS/RCTUIKit.m
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ @implementation RCTUIView
BOOL _clipsToBounds;
BOOL _userInteractionEnabled;
BOOL _mouseDownCanMoveWindow;
BOOL _respondsToDisplayLayer;
}

+ (NSSet<NSString *> *)keyPathsForValuesAffectingValueForKey:(NSString *)key
Expand Down Expand Up @@ -245,6 +246,7 @@ @implementation RCTUIView
self->_userInteractionEnabled = YES;
self->_enableFocusRing = YES;
self->_mouseDownCanMoveWindow = YES;
self->_respondsToDisplayLayer = [self respondsToSelector:@selector(displayLayer:)];
}
return self;
}
Expand Down Expand Up @@ -343,7 +345,12 @@ - (void)updateLayer
// so it has to be reset from the view's NSColor ivar.
[layer setBackgroundColor:[_backgroundColor CGColor]];
}
[(id<CALayerDelegate>)self displayLayer:layer];

// In Fabric, wantsUpdateLayer is always enabled and doesn't guarantee that
// the instance has a displayLayer method.
if (_respondsToDisplayLayer) {
[(id<CALayerDelegate>)self displayLayer:layer];
}
}

- (void)drawRect:(CGRect)rect
Expand Down
Loading
Loading