diff --git a/.github/scripts/__tests__/resolve-hermes-test.js b/.github/scripts/__tests__/resolve-hermes-test.js index 699b14a8f83..6d82cde1bce 100644 --- a/.github/scripts/__tests__/resolve-hermes-test.js +++ b/.github/scripts/__tests__/resolve-hermes-test.js @@ -88,8 +88,7 @@ test.each([ ...(flag == null ? {} : {RCT_HERMES_V1_ENABLED: flag}), ...(flag === '0' ? { - HERMES_TEST_PROPERTIES: - `HERMES_VERSION_NAME=${version}\nHERMES_V1_VERSION_NAME=1000.0.0`, + HERMES_TEST_PROPERTIES: `HERMES_VERSION_NAME=${version}\nHERMES_V1_VERSION_NAME=1000.0.0`, } : {}), HERMES_TEST_DOWNLOAD: 'release', @@ -175,7 +174,10 @@ const invalidMetadata = [ ['', 'Expected one exact HERMES_V1_VERSION_NAME'], ['UNREADABLE', 'EACCES'], ['HERMES_VERSION_NAME=1.2.3', 'Expected one exact HERMES_V1_VERSION_NAME'], - ['HERMES_V1_VERSION_NAME=^1.2.3', 'Expected one exact HERMES_V1_VERSION_NAME'], + [ + 'HERMES_V1_VERSION_NAME=^1.2.3', + 'Expected one exact HERMES_V1_VERSION_NAME', + ], [ 'HERMES_V1_VERSION_NAME=1.2.3\nHERMES_V1_VERSION_NAME=1.2.3', 'Expected one exact HERMES_V1_VERSION_NAME', diff --git a/packages/react-native/React/CoreModules/RCTRedBox.mm b/packages/react-native/React/CoreModules/RCTRedBox.mm index 9f425218f10..6e0a2b617c2 100644 --- a/packages/react-native/React/CoreModules/RCTRedBox.mm +++ b/packages/react-native/React/CoreModules/RCTRedBox.mm @@ -21,9 +21,7 @@ #import "CoreModulesPlugins.h" #import "RCTRedBox+Internal.h" -#if !TARGET_OS_OSX // [macOS] #import "RCTRedBox2Controller+Internal.h" -#endif // [macOS] #import "RCTRedBoxController+Internal.h" #if RCT_DEV_MENU @@ -197,11 +195,9 @@ - (void)showErrorMessage:(NSString *)message errorInfo = [self _customizeError:errorInfo]; if (self->_controller == nullptr) { - if (!TARGET_OS_OSX && facebook::react::ReactNativeFeatureFlags::redBoxV2IOS()) { // [macOS] -#if !TARGET_OS_OSX // [macOS] + if (facebook::react::ReactNativeFeatureFlags::redBoxV2IOS()) { self->_controller = [[RCTRedBox2Controller alloc] initWithCustomButtonTitles:self->_customButtonTitles customButtonHandlers:self->_customButtonHandlers]; -#endif // [macOS] } else { self->_controller = [[RCTRedBoxController alloc] initWithCustomButtonTitles:self->_customButtonTitles customButtonHandlers:self->_customButtonHandlers]; diff --git a/packages/react-native/React/CoreModules/RCTRedBox2AnsiParser+Internal.h b/packages/react-native/React/CoreModules/RCTRedBox2AnsiParser+Internal.h index 3f6a63e67a2..4fa60a55adc 100644 --- a/packages/react-native/React/CoreModules/RCTRedBox2AnsiParser+Internal.h +++ b/packages/react-native/React/CoreModules/RCTRedBox2AnsiParser+Internal.h @@ -5,10 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -#import - -#if !TARGET_OS_OSX // [macOS] -#import +#import // [macOS] /** * Parses ANSI escape sequences in text and produces an NSAttributedString @@ -18,10 +15,14 @@ */ @interface RCTRedBox2AnsiParser : NSObject +#if !TARGET_OS_OSX // [macOS] + (NSAttributedString *)attributedStringFromAnsiText:(NSString *)text baseFont:(UIFont *)font baseColor:(UIColor *)color; +#else // [macOS ++ (NSAttributedString *)attributedStringFromAnsiText:(NSString *)text + baseFont:(UIFont *)font + baseColor:(RCTPlatformColor *)color; +#endif // macOS] @end - -#endif // [macOS] diff --git a/packages/react-native/React/CoreModules/RCTRedBox2AnsiParser.mm b/packages/react-native/React/CoreModules/RCTRedBox2AnsiParser.mm index a7a75b93c1f..ba3c39798ce 100644 --- a/packages/react-native/React/CoreModules/RCTRedBox2AnsiParser.mm +++ b/packages/react-native/React/CoreModules/RCTRedBox2AnsiParser.mm @@ -10,19 +10,32 @@ #import #import -#if RCT_DEV_MENU && !TARGET_OS_OSX // [macOS] +#if RCT_DEV_MENU using facebook::react::unstable_redbox::AnsiColor; using facebook::react::unstable_redbox::parseAnsi; +#if !TARGET_OS_OSX // [macOS] static UIColor *RCTUIColorFromAnsiColor(const AnsiColor &c) { return [UIColor colorWithRed:c.r / 255.0 green:c.g / 255.0 blue:c.b / 255.0 alpha:1.0]; } +#else // [macOS +static RCTPlatformColor *RCTUIColorFromAnsiColor(const AnsiColor &c) +{ + return [RCTPlatformColor colorWithRed:c.r / 255.0 green:c.g / 255.0 blue:c.b / 255.0 alpha:1.0]; +} +#endif // macOS] @implementation RCTRedBox2AnsiParser +#if !TARGET_OS_OSX // [macOS] + (NSAttributedString *)attributedStringFromAnsiText:(NSString *)text baseFont:(UIFont *)font baseColor:(UIColor *)color +#else // [macOS ++ (NSAttributedString *)attributedStringFromAnsiText:(NSString *)text + baseFont:(UIFont *)font + baseColor:(RCTPlatformColor *)color +#endif // macOS] { if (text == nil) { return [[NSAttributedString alloc] init]; diff --git a/packages/react-native/React/CoreModules/RCTRedBox2Controller+Internal.h b/packages/react-native/React/CoreModules/RCTRedBox2Controller+Internal.h index 56fb86f387b..905e9398487 100644 --- a/packages/react-native/React/CoreModules/RCTRedBox2Controller+Internal.h +++ b/packages/react-native/React/CoreModules/RCTRedBox2Controller+Internal.h @@ -6,14 +6,16 @@ */ #import +#import // [macOS] #import "RCTRedBox+Internal.h" -#if RCT_DEV_MENU && !TARGET_OS_OSX // [macOS] +#if RCT_DEV_MENU typedef void (^RCTRedBox2ButtonPressHandler)(void); -@interface RCTRedBox2Controller : UIViewController +@interface RCTRedBox2Controller + : RCTPlatformViewController // [macOS] @property (nonatomic, weak) id actionDelegate; diff --git a/packages/react-native/React/CoreModules/RCTRedBox2Controller.mm b/packages/react-native/React/CoreModules/RCTRedBox2Controller.mm index 4fa0cd0b610..9cd5e4e04ea 100644 --- a/packages/react-native/React/CoreModules/RCTRedBox2Controller.mm +++ b/packages/react-native/React/CoreModules/RCTRedBox2Controller.mm @@ -22,25 +22,27 @@ // @lint-ignore-every CLANGTIDY clang-diagnostic-switch-default // NOTE: clang-diagnostic-switch-default conflicts with clang-diagnostic-switch-enum -#if RCT_DEV_MENU && !TARGET_OS_OSX // [macOS] +#if RCT_DEV_MENU #pragma mark - RCTRedBox2Controller // Color Palette (matching LogBoxStyle.js) -static UIColor *RCTRedBox2BackgroundColor() +// [macOS +static RCTUIColor *RCTRedBox2BackgroundColor() { - return [UIColor colorWithRed:51.0 / 255 green:51.0 / 255 blue:51.0 / 255 alpha:1.0]; + return [RCTUIColor colorWithRed:51.0 / 255 green:51.0 / 255 blue:51.0 / 255 alpha:1.0]; } -static UIColor *RCTRedBox2ErrorColor() +static RCTUIColor *RCTRedBox2ErrorColor() { - return [UIColor colorWithRed:243.0 / 255 green:83.0 / 255 blue:105.0 / 255 alpha:1.0]; + return [RCTUIColor colorWithRed:243.0 / 255 green:83.0 / 255 blue:105.0 / 255 alpha:1.0]; } -static UIColor *RCTRedBox2TextColor(CGFloat opacity) +static RCTUIColor *RCTRedBox2TextColor(CGFloat opacity) { - return [UIColor colorWithWhite:1.0 alpha:opacity]; + return [RCTUIColor colorWithWhite:1.0 alpha:opacity]; } +// macOS] enum class Section : uint8_t { Message, CodeFrame, CallStack, kMaxValue }; static constexpr size_t kSectionCount = static_cast(Section::kMaxValue); @@ -52,9 +54,11 @@ static const NSTimeInterval kAutoRetryInterval = 20.0; @implementation RCTRedBox2Controller { - UITableView *_stackTraceTableView; - UILabel *_headerTitleLabel; - UILabel *_errorCategoryLabel; + // [macOS + RCTUITableView *_stackTraceTableView; + RCTUILabel *_headerTitleLabel; + RCTUILabel *_errorCategoryLabel; + // macOS] NSString *_lastErrorMessage; NSArray *_lastStackTrace; NSArray *_customButtonTitles; @@ -64,7 +68,7 @@ @implementation RCTRedBox2Controller { std::array _sectionStates; NSTimer *_autoRetryTimer; NSInteger _autoRetryCountdown; - UIButton *_reloadButton; + RCTUIButton *_reloadButton; // [macOS] NSString *_reloadBaseText; RCTRedBoxHMRClient *_hmrClient; } @@ -77,7 +81,9 @@ - (instancetype)initWithCustomButtonTitles:(NSArray *)customButtonTi _lastErrorCookie = -1; _customButtonTitles = customButtonTitles; _customButtonHandlers = customButtonHandlers; +#if !TARGET_OS_OSX // [macOS] self.modalPresentationStyle = UIModalPresentationFullScreen; +#endif // [macOS] } return self; } @@ -85,25 +91,32 @@ - (instancetype)initWithCustomButtonTitles:(NSArray *)customButtonTi - (void)viewDidLoad { [super viewDidLoad]; +#if !TARGET_OS_OSX // [macOS] self.view.backgroundColor = RCTRedBox2BackgroundColor(); +#else // [macOS + self.view.wantsLayer = YES; + self.view.layer.backgroundColor = RCTRedBox2BackgroundColor().CGColor; +#endif // macOS] - // Header bar (adds itself to self.view) - UIView *headerBar = [self createHeaderBar]; - - // Footer button bar - UIView *footerBar = [self createFooterBar]; + RCTPlatformView *headerBar = [self createHeaderBar]; // [macOS] + RCTPlatformView *footerBar = [self createFooterBar]; // [macOS] // Stack trace table - _stackTraceTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; - _stackTraceTableView.translatesAutoresizingMaskIntoConstraints = NO; - _stackTraceTableView.delegate = self; - _stackTraceTableView.dataSource = self; +#if !TARGET_OS_OSX // [macOS] + _stackTraceTableView = [[RCTUITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; // [macOS] _stackTraceTableView.backgroundColor = [UIColor clearColor]; #if !TARGET_OS_TV _stackTraceTableView.separatorStyle = UITableViewCellSeparatorStyleNone; #endif _stackTraceTableView.indicatorStyle = UIScrollViewIndicatorStyleWhite; _stackTraceTableView.bounces = NO; +#else // [macOS + _stackTraceTableView = [[RCTUITableView alloc] initWithFrame:NSZeroRect]; + _stackTraceTableView.hasVerticalScroller = YES; +#endif // macOS] + _stackTraceTableView.translatesAutoresizingMaskIntoConstraints = NO; + _stackTraceTableView.dataSource = self; + _stackTraceTableView.delegate = self; [self.view addSubview:_stackTraceTableView]; [NSLayoutConstraint activateConstraints:@[ @@ -116,30 +129,40 @@ - (void)viewDidLoad #pragma mark - Header Bar -- (UIView *)createHeaderBar +- (RCTUILabel *)makeLabel // [macOS] +{ + RCTUILabel *label = [[RCTUILabel alloc] initWithFrame:CGRectZero]; + label.translatesAutoresizingMaskIntoConstraints = NO; + label.lineBreakMode = NSLineBreakByWordWrapping; + label.numberOfLines = 0; // [macOS] + return label; +} + +- (RCTPlatformView *)createHeaderBar // [macOS] { - UIView *headerContainer = [[UIView alloc] init]; + RCTUIView *headerContainer = [[RCTUIView alloc] init]; // [macOS] headerContainer.translatesAutoresizingMaskIntoConstraints = NO; headerContainer.backgroundColor = RCTRedBox2ErrorColor(); - _headerTitleLabel = [[UILabel alloc] init]; - _headerTitleLabel.translatesAutoresizingMaskIntoConstraints = NO; - _headerTitleLabel.textColor = [UIColor whiteColor]; - _headerTitleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; - _headerTitleLabel.textAlignment = NSTextAlignmentCenter; + _headerTitleLabel = [self makeLabel]; // [macOS] + _headerTitleLabel.textColor = [RCTUIColor whiteColor]; // [macOS] + _headerTitleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; // [macOS] + _headerTitleLabel.textAlignment = NSTextAlignmentCenter; // [macOS] [headerContainer addSubview:_headerTitleLabel]; - [self.view addSubview:headerContainer]; [NSLayoutConstraint activateConstraints:@[ [headerContainer.topAnchor constraintEqualToAnchor:self.view.topAnchor], [headerContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], [headerContainer.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor], - [_headerTitleLabel.leadingAnchor constraintEqualToAnchor:headerContainer.leadingAnchor constant:12], [_headerTitleLabel.trailingAnchor constraintEqualToAnchor:headerContainer.trailingAnchor constant:-12], [_headerTitleLabel.bottomAnchor constraintEqualToAnchor:headerContainer.bottomAnchor constant:-12], +#if !TARGET_OS_OSX // [macOS] [_headerTitleLabel.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:12], +#else // [macOS + [_headerTitleLabel.topAnchor constraintEqualToAnchor:headerContainer.topAnchor constant:12], +#endif // macOS] ]]; return headerContainer; @@ -147,102 +170,107 @@ - (UIView *)createHeaderBar #pragma mark - Footer Bar -- (UIView *)createFooterBar +- (RCTPlatformView *)createFooterBar // [macOS] { const CGFloat buttonHeight = 48; - NSString *reloadText = @"Reload"; - NSString *dismissText = @"Dismiss"; - NSString *copyText = @"Copy"; - UIButton *dismissButton = [self footerButton:dismissText - accessibilityIdentifier:@"redbox-dismiss" - selector:@selector(dismiss)]; + __weak __typeof(self) weakSelf = self; + RCTUIButton *dismissButton = [self footerButton:@"Dismiss" + accessibilityIdentifier:@"redbox-dismiss" + handler:^{ + [weakSelf dismiss]; + }]; // [macOS] _reloadBaseText = reloadText; - _reloadButton = [self footerButton:reloadText accessibilityIdentifier:@"redbox-reload" selector:@selector(reload)]; - UIButton *copyButton = [self footerButton:copyText - accessibilityIdentifier:@"redbox-copy" - selector:@selector(copyStack)]; - + _reloadButton = [self footerButton:reloadText + accessibilityIdentifier:@"redbox-reload" + handler:^{ + [weakSelf reload]; + }]; + RCTUIButton *copyButton = [self footerButton:@"Copy" + accessibilityIdentifier:@"redbox-copy" + handler:^{ + [weakSelf copyStack]; + }]; // [macOS] + +#if !TARGET_OS_OSX // [macOS] UIStackView *buttonStackView = [[UIStackView alloc] init]; - buttonStackView.translatesAutoresizingMaskIntoConstraints = NO; buttonStackView.axis = UILayoutConstraintAxisHorizontal; buttonStackView.distribution = UIStackViewDistributionFillEqually; buttonStackView.alignment = UIStackViewAlignmentTop; buttonStackView.backgroundColor = RCTRedBox2BackgroundColor(); - +#else // [macOS + [dismissButton setKeyEquivalent:@"\e"]; + [_reloadButton setKeyEquivalent:@"r"]; + [_reloadButton setKeyEquivalentModifierMask:NSEventModifierFlagCommand]; + [copyButton setKeyEquivalent:@"c"]; + [copyButton setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand]; + + NSStackView *buttonStackView = [[NSStackView alloc] init]; + buttonStackView.orientation = NSUserInterfaceLayoutOrientationHorizontal; + buttonStackView.distribution = NSStackViewDistributionFillEqually; + buttonStackView.alignment = NSLayoutAttributeCenterY; + buttonStackView.wantsLayer = YES; + buttonStackView.layer.backgroundColor = RCTRedBox2BackgroundColor().CGColor; +#endif // macOS] + buttonStackView.translatesAutoresizingMaskIntoConstraints = NO; [buttonStackView addArrangedSubview:dismissButton]; [buttonStackView addArrangedSubview:_reloadButton]; [buttonStackView addArrangedSubview:copyButton]; for (NSUInteger i = 0; i < [_customButtonTitles count]; i++) { - UIButton *button = [self footerButton:_customButtonTitles[i] - accessibilityIdentifier:@"" - handler:_customButtonHandlers[i]]; + RCTUIButton *button = [self footerButton:_customButtonTitles[i] + accessibilityIdentifier:@"" + handler:_customButtonHandlers[i]]; // [macOS] [buttonStackView addArrangedSubview:button]; } - // Shadow layer above footer - buttonStackView.layer.shadowColor = [UIColor blackColor].CGColor; + buttonStackView.layer.shadowColor = [RCTUIColor blackColor].CGColor; // [macOS] buttonStackView.layer.shadowOffset = CGSizeMake(0, -2); buttonStackView.layer.shadowRadius = 2; buttonStackView.layer.shadowOpacity = 0.5; - [self.view addSubview:buttonStackView]; - CGFloat bottomInset = [self bottomSafeViewHeight]; - [NSLayoutConstraint activateConstraints:@[ [buttonStackView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], [buttonStackView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor], [buttonStackView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor], - [buttonStackView.heightAnchor constraintEqualToConstant:buttonHeight + bottomInset], + [buttonStackView.heightAnchor constraintEqualToConstant:buttonHeight + [self bottomSafeViewHeight]], ]]; - for (UIButton *btn in buttonStackView.arrangedSubviews) { - [btn.heightAnchor constraintEqualToConstant:buttonHeight].active = YES; + for (RCTPlatformView *button in buttonStackView.arrangedSubviews) { // [macOS] + [button.heightAnchor constraintEqualToConstant:buttonHeight].active = YES; } return buttonStackView; } -- (UIButton *)styledButton:(NSString *)title accessibilityIdentifier:(NSString *)accessibilityIdentifier +- (RCTUIButton *)styledButton:(NSString *)title accessibilityIdentifier:(NSString *)accessibilityIdentifier // [macOS] { - UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + RCTUIButton *button = [[RCTUIButton alloc] initWithFrame:CGRectZero]; // [macOS] + button.translatesAutoresizingMaskIntoConstraints = NO; button.accessibilityIdentifier = accessibilityIdentifier; button.titleLabel.font = [UIFont systemFontOfSize:14]; button.titleLabel.textAlignment = NSTextAlignmentCenter; button.backgroundColor = RCTRedBox2BackgroundColor(); - [button setTitle:title forState:UIControlStateNormal]; - [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - [button setTitleColor:RCTRedBox2TextColor(0.5) forState:UIControlStateHighlighted]; + [button setTitle:title forState:RCTUIControlStateNormal]; // [macOS] + [button setTitleColor:[RCTUIColor whiteColor] forState:RCTUIControlStateNormal]; // [macOS] + [button setTitleColor:RCTRedBox2TextColor(0.5) forState:RCTUIControlStateHighlighted]; // [macOS] return button; } -- (UIButton *)footerButton:(NSString *)title - accessibilityIdentifier:(NSString *)accessibilityIdentifier - selector:(SEL)selector +- (RCTUIButton *)footerButton:(NSString *)title // [macOS] + accessibilityIdentifier:(NSString *)accessibilityIdentifier + handler:(RCTRedBox2ButtonPressHandler)handler { - UIButton *button = [self styledButton:title accessibilityIdentifier:accessibilityIdentifier]; - [button addTarget:self action:selector forControlEvents:UIControlEventTouchUpInside]; - return button; -} - -- (UIButton *)footerButton:(NSString *)title - accessibilityIdentifier:(NSString *)accessibilityIdentifier - handler:(RCTRedBox2ButtonPressHandler)handler -{ - UIButton *button = [self styledButton:title accessibilityIdentifier:accessibilityIdentifier]; - [button addAction:[UIAction actionWithHandler:^(__unused UIAction *action) { - handler(); - }] - forControlEvents:UIControlEventTouchUpInside]; + RCTUIButton *button = [self styledButton:title accessibilityIdentifier:accessibilityIdentifier]; // [macOS] + [button rct_setPrimaryAction:[RCTUIAction actionWithHandler:handler]]; // [macOS] return button; } - (CGFloat)bottomSafeViewHeight { -#if TARGET_OS_MACCATALYST +#if TARGET_OS_MACCATALYST || TARGET_OS_OSX // [macOS] return 0; #else return RCTKeyWindow().safeAreaInsets.bottom; @@ -289,15 +317,19 @@ - (void)showErrorMessage:(NSString *)message [_stackTraceTableView reloadData]; if (!isRootViewControllerPresented) { +#if !TARGET_OS_OSX // [macOS] [RCTKeyWindow().rootViewController presentViewController:self animated:NO completion:nil]; +#else // [macOS + [[RCTKeyWindow() contentViewController] presentViewControllerAsSheet:self]; +#endif // macOS] } // Update all UI from _errorData (view is now guaranteed to be loaded) - _headerTitleLabel.text = _errorData.isCompileError ? @"Failed to compile" : @"Error"; + _headerTitleLabel.text = _errorData.isCompileError ? @"Failed to compile" : @"Error"; // [macOS] [_stackTraceTableView reloadData]; [_stackTraceTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] - atScrollPosition:UITableViewScrollPositionTop - animated:NO]; + atScrollPosition:RCTUITableViewScrollPositionTop + animated:NO]; // [macOS] [self startAutoRetryIfApplicable]; [self _startHMRClient]; @@ -307,7 +339,13 @@ - (void)showErrorMessage:(NSString *)message - (void)dismiss { [self stopAutoRetry]; +#if !TARGET_OS_OSX // [macOS] [self dismissViewControllerAnimated:NO completion:nil]; +#else // [macOS + if (self.presentingViewController) { + [self.presentingViewController dismissViewController:self]; + } +#endif // macOS] } - (void)reload @@ -367,7 +405,7 @@ - (void)stopAutoRetry [_autoRetryTimer invalidate]; _autoRetryTimer = nil; if (_reloadButton) { - [_reloadButton setTitle:_reloadBaseText forState:UIControlStateNormal]; + [_reloadButton setTitle:_reloadBaseText forState:RCTUIControlStateNormal]; // [macOS] } } @@ -385,7 +423,7 @@ - (void)autoRetryTick - (void)updateReloadButtonTitle { NSString *title = [NSString stringWithFormat:@"%@ (%lds)", _reloadBaseText, (long)_autoRetryCountdown]; - [_reloadButton setTitle:title forState:UIControlStateNormal]; + [_reloadButton setTitle:title forState:RCTUIControlStateNormal]; // [macOS] } - (void)copyStack @@ -405,10 +443,16 @@ - (void)copyStack [fullStackTrace appendFormat:@" %@\n", [self formatFrameSource:stackFrame]]; } } +#if !TARGET_OS_OSX // [macOS] #if !TARGET_OS_TV UIPasteboard *pb = [UIPasteboard generalPasteboard]; [pb setString:fullStackTrace]; #endif +#else // [macOS + NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; + [pasteboard clearContents]; + [pasteboard setString:fullStackTrace forType:NSPasteboardTypeString]; +#endif // macOS] } - (NSString *)formatFrameSource:(RCTJSStackFrame *)stackFrame @@ -472,12 +516,12 @@ - (NSString *)displayMessage #pragma mark - TableView DataSource & Delegate -- (NSInteger)numberOfSectionsInTableView:(__unused UITableView *)tableView +- (NSInteger)numberOfSectionsInTableView:(__unused RCTUITableView *)tableView // [macOS] { return [self visibleSectionCount]; } -- (NSInteger)tableView:(__unused UITableView *)tableView numberOfRowsInSection:(NSInteger)section +- (NSInteger)tableView:(__unused RCTUITableView *)tableView numberOfRowsInSection:(NSInteger)section // [macOS] { if ([self sectionForIndex:section] == Section::CallStack) { return static_cast(_lastStackTrace.count); @@ -485,49 +529,57 @@ - (NSInteger)tableView:(__unused UITableView *)tableView numberOfRowsInSection:( return 1; } -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +- (RCTUITableViewCell *)tableView:(RCTUITableView *)tableView // [macOS] + cellForRowAtIndexPath:(NSIndexPath *)indexPath { switch ([self sectionForIndex:indexPath.section]) { case Section::Message: { - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"msg-cell"]; + RCTUITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"msg-cell"]; // [macOS] return [self reuseCell:cell forErrorMessage:[self displayMessage]]; } case Section::CodeFrame: { - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"code-cell"]; + RCTUITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"code-cell"]; // [macOS] return [self reuseCell:cell forCodeFrame:_errorData]; } case Section::CallStack: case Section::kMaxValue: break; } - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; + RCTUITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; // [macOS] NSUInteger index = indexPath.row; RCTJSStackFrame *stackFrame = _lastStackTrace[index]; return [self reuseCell:cell forStackFrame:stackFrame]; } -- (UITableViewCell *)reuseCell:(UITableViewCell *)cell forErrorMessage:(NSString *)message +- (RCTUITableViewCell *)reuseCell:(RCTUITableViewCell *)cell forErrorMessage:(NSString *)message // [macOS] { if (cell == nullptr) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"msg-cell"]; + cell = [[RCTUITableViewCell alloc] initWithStyle:RCTUITableViewCellStyleDefault + reuseIdentifier:@"msg-cell"]; // [macOS] + cell.textLabel.hidden = YES; +#if !TARGET_OS_OSX // [macOS] cell.backgroundColor = RCTRedBox2BackgroundColor(); cell.selectionStyle = UITableViewCellSelectionStyleNone; +#else // [macOS + cell.wantsLayer = YES; + cell.layer.backgroundColor = RCTRedBox2BackgroundColor().CGColor; + cell.layer.cornerRadius = 8.0; + cell.layer.cornerCurve = kCACornerCurveContinuous; +#endif // macOS] // Error category label (e.g. "Syntax Error", "Uncaught Error") - _errorCategoryLabel = [[UILabel alloc] init]; - _errorCategoryLabel.translatesAutoresizingMaskIntoConstraints = NO; + _errorCategoryLabel = [self makeLabel]; // [macOS] + _errorCategoryLabel.tag = 101; _errorCategoryLabel.textColor = RCTRedBox2ErrorColor(); _errorCategoryLabel.font = [UIFont systemFontOfSize:21 weight:UIFontWeightBold]; _errorCategoryLabel.numberOfLines = 1; [cell.contentView addSubview:_errorCategoryLabel]; // Error message label - UILabel *messageLabel = [[UILabel alloc] init]; - messageLabel.translatesAutoresizingMaskIntoConstraints = NO; + RCTUILabel *messageLabel = [self makeLabel]; // [macOS] messageLabel.accessibilityIdentifier = @"redbox-error"; - messageLabel.textColor = [UIColor whiteColor]; + messageLabel.textColor = [RCTUIColor whiteColor]; // [macOS] messageLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium]; - messageLabel.lineBreakMode = NSLineBreakByWordWrapping; messageLabel.numberOfLines = 0; messageLabel.tag = 100; [cell.contentView addSubview:messageLabel]; @@ -544,26 +596,30 @@ - (UITableViewCell *)reuseCell:(UITableViewCell *)cell forErrorMessage:(NSString ]]; } + _errorCategoryLabel = [cell.contentView viewWithTag:101]; _errorCategoryLabel.text = _errorData.title; - UILabel *messageLabel = [cell.contentView viewWithTag:100]; + RCTUILabel *messageLabel = [cell.contentView viewWithTag:100]; // [macOS] messageLabel.text = message; return cell; } -- (UITableViewCell *)reuseCell:(UITableViewCell *)cell forStackFrame:(RCTJSStackFrame *)stackFrame +- (RCTUITableViewCell *)reuseCell:(RCTUITableViewCell *)cell forStackFrame:(RCTJSStackFrame *)stackFrame // [macOS] { if (cell == nullptr) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"]; + cell = [[RCTUITableViewCell alloc] initWithStyle:RCTUITableViewCellStyleSubtitle + reuseIdentifier:@"cell"]; // [macOS] cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:14]; cell.textLabel.lineBreakMode = NSLineBreakByCharWrapping; cell.textLabel.numberOfLines = 2; cell.detailTextLabel.font = [UIFont systemFontOfSize:12 weight:UIFontWeightLight]; cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; - cell.backgroundColor = [UIColor clearColor]; + cell.backgroundColor = [RCTUIColor clearColor]; // [macOS] +#if !TARGET_OS_OSX // [macOS] cell.selectedBackgroundView = [UIView new]; cell.selectedBackgroundView.backgroundColor = RCTRedBox2BackgroundColor(); cell.selectedBackgroundView.layer.cornerRadius = 5; +#endif // [macOS] } cell.textLabel.text = stackFrame.methodName ?: @"(unnamed method)"; @@ -577,46 +633,56 @@ - (UITableViewCell *)reuseCell:(UITableViewCell *)cell forStackFrame:(RCTJSStack cell.textLabel.textColor = RCTRedBox2TextColor(0.4); cell.detailTextLabel.textColor = RCTRedBox2TextColor(0.3); } else { - cell.textLabel.textColor = [UIColor whiteColor]; + cell.textLabel.textColor = [RCTUIColor whiteColor]; // [macOS] cell.detailTextLabel.textColor = RCTRedBox2TextColor(0.8); } return cell; } -- (UITableViewCell *)reuseCell:(UITableViewCell *)cell forCodeFrame:(RCTRedBox2ErrorData *)errorData +- (RCTUITableViewCell *)reuseCell:(RCTUITableViewCell *)cell forCodeFrame:(RCTRedBox2ErrorData *)errorData // [macOS] { if (cell == nullptr) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"code-cell"]; - cell.backgroundColor = [UIColor clearColor]; + cell = [[RCTUITableViewCell alloc] initWithStyle:RCTUITableViewCellStyleDefault + reuseIdentifier:@"code-cell"]; // [macOS] + cell.textLabel.hidden = YES; + cell.backgroundColor = [RCTUIColor clearColor]; // [macOS] +#if !TARGET_OS_OSX // [macOS] cell.selectionStyle = UITableViewCellSelectionStyleNone; +#endif // [macOS] } // Remove old subviews - for (UIView *subview in cell.contentView.subviews) { - [subview removeFromSuperview]; + for (RCTPlatformView *subview in cell.contentView.subviews) { // [macOS] + if (subview != cell.textLabel && subview != cell.detailTextLabel) { + [subview removeFromSuperview]; + } } // Code frame container with rounded corners - UIView *container = [[UIView alloc] init]; + RCTUIView *container = [[RCTUIView alloc] init]; // [macOS] container.translatesAutoresizingMaskIntoConstraints = NO; container.backgroundColor = RCTRedBox2BackgroundColor(); container.layer.cornerRadius = 3; - container.clipsToBounds = YES; + container.layer.masksToBounds = YES; [cell.contentView addSubview:container]; // Render code frame with ANSI syntax highlighting UIFont *codeFont = [UIFont fontWithName:@"Menlo-Regular" size:12]; - NSAttributedString *highlighted = [RCTRedBox2AnsiParser attributedStringFromAnsiText:errorData.codeFrame - baseFont:codeFont - baseColor:[UIColor whiteColor]]; + NSAttributedString *highlighted = + [RCTRedBox2AnsiParser attributedStringFromAnsiText:errorData.codeFrame + baseFont:codeFont + baseColor:[RCTUIColor whiteColor]]; // [macOS] - UILabel *codeLabel = [[UILabel alloc] init]; - codeLabel.translatesAutoresizingMaskIntoConstraints = NO; + RCTUILabel *codeLabel = [self makeLabel]; // [macOS] +#if !TARGET_OS_OSX // [macOS] codeLabel.attributedText = highlighted; - codeLabel.numberOfLines = 0; +#else // [macOS + codeLabel.attributedStringValue = highlighted; +#endif // macOS] codeLabel.lineBreakMode = NSLineBreakByClipping; +#if !TARGET_OS_OSX // [macOS] UIScrollView *codeScrollView = [[UIScrollView alloc] init]; codeScrollView.translatesAutoresizingMaskIntoConstraints = NO; codeScrollView.showsHorizontalScrollIndicator = YES; @@ -624,10 +690,23 @@ - (UITableViewCell *)reuseCell:(UITableViewCell *)cell forCodeFrame:(RCTRedBox2E codeScrollView.bounces = NO; [codeScrollView addSubview:codeLabel]; [container addSubview:codeScrollView]; +#else // [macOS + // Measure all source lines at their natural width, independently of the table column. + codeLabel.preferredMaxLayoutWidth = ceil(codeLabel.intrinsicContentSize.width); + NSSize codeSize = codeLabel.intrinsicContentSize; + NSScrollView *codeScrollView = [[NSScrollView alloc] init]; + codeScrollView.translatesAutoresizingMaskIntoConstraints = NO; + codeScrollView.hasHorizontalScroller = YES; + codeScrollView.hasVerticalScroller = YES; + codeScrollView.autohidesScrollers = YES; + codeScrollView.drawsBackground = NO; + codeScrollView.documentView = codeLabel; + [container addSubview:codeScrollView]; +#endif // macOS] // File name label below the code frame - UILabel *fileLabel = [[UILabel alloc] init]; - fileLabel.translatesAutoresizingMaskIntoConstraints = NO; + RCTUILabel *fileLabel = [self makeLabel]; // [macOS] + fileLabel.numberOfLines = 1; NSString *fileName = errorData.codeFrameFileName.lastPathComponent ?: errorData.codeFrameFileName; if (errorData.codeFrameRow > 0) { fileLabel.text = [NSString @@ -650,11 +729,20 @@ - (UITableViewCell *)reuseCell:(UITableViewCell *)cell forCodeFrame:(RCTRedBox2E [codeScrollView.trailingAnchor constraintEqualToAnchor:container.trailingAnchor constant:-10], [codeScrollView.bottomAnchor constraintEqualToAnchor:container.bottomAnchor constant:-10], +#if !TARGET_OS_OSX // [macOS] [codeLabel.topAnchor constraintEqualToAnchor:codeScrollView.topAnchor], [codeLabel.leadingAnchor constraintEqualToAnchor:codeScrollView.leadingAnchor], [codeLabel.trailingAnchor constraintEqualToAnchor:codeScrollView.trailingAnchor], [codeLabel.bottomAnchor constraintEqualToAnchor:codeScrollView.bottomAnchor], [codeLabel.heightAnchor constraintEqualToAnchor:codeScrollView.heightAnchor], +#else // [macOS + [codeLabel.topAnchor constraintEqualToAnchor:codeScrollView.contentView.topAnchor], + [codeLabel.leadingAnchor constraintEqualToAnchor:codeScrollView.contentView.leadingAnchor], + [codeLabel.widthAnchor constraintEqualToConstant:ceil(codeSize.width)], + [codeLabel.heightAnchor constraintEqualToConstant:ceil(codeSize.height)], + [codeScrollView.heightAnchor constraintEqualToConstant:ceil(codeSize.height) + + [NSScroller scrollerWidthForControlSize:NSControlSizeRegular scrollerStyle:NSScrollerStyleLegacy]], +#endif // macOS] [fileLabel.topAnchor constraintEqualToAnchor:container.bottomAnchor constant:10], [fileLabel.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:10], @@ -665,16 +753,21 @@ - (UITableViewCell *)reuseCell:(UITableViewCell *)cell forCodeFrame:(RCTRedBox2E return cell; } -- (CGFloat)tableView:(__unused UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +- (CGFloat)tableView:(__unused RCTUITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath // [macOS] { +#if TARGET_OS_OSX // [macOS + return RCTUITableViewAutomaticDimension; +#else // macOS] auto section = [self sectionForIndex:indexPath.section]; if (section == Section::Message || section == Section::CodeFrame) { - return UITableViewAutomaticDimension; + return RCTUITableViewAutomaticDimension; // [macOS] } return 50; +#endif // [macOS] } -- (CGFloat)tableView:(__unused UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath +- (CGFloat)tableView:(__unused RCTUITableView *)tableView // [macOS] + estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { switch ([self sectionForIndex:indexPath.section]) { case Section::Message: @@ -687,15 +780,14 @@ - (CGFloat)tableView:(__unused UITableView *)tableView estimatedHeightForRowAtIn } } -- (UIView *)sectionHeaderViewWithTitle:(NSString *)title +- (RCTPlatformView *)sectionHeaderViewWithTitle:(NSString *)title // [macOS] { - UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 38)]; - headerView.backgroundColor = [UIColor clearColor]; + RCTUIView *headerView = [[RCTUIView alloc] initWithFrame:CGRectMake(0, 0, 0, 38)]; // [macOS] + headerView.backgroundColor = [RCTUIColor clearColor]; // [macOS] - UILabel *label = [[UILabel alloc] init]; - label.translatesAutoresizingMaskIntoConstraints = NO; + RCTUILabel *label = [self makeLabel]; // [macOS] label.text = title; - label.textColor = [UIColor whiteColor]; + label.textColor = [RCTUIColor whiteColor]; // [macOS] label.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold]; [headerView addSubview:label]; @@ -708,7 +800,8 @@ - (UIView *)sectionHeaderViewWithTitle:(NSString *)title return headerView; } -- (UIView *)tableView:(__unused UITableView *)tableView viewForHeaderInSection:(NSInteger)section +- (nullable RCTPlatformView *)tableView:(__unused RCTUITableView *)tableView // [macOS] + viewForHeaderInSection:(NSInteger)section { switch ([self sectionForIndex:section]) { case Section::CodeFrame: @@ -721,13 +814,13 @@ - (UIView *)tableView:(__unused UITableView *)tableView viewForHeaderInSection:( } } -- (CGFloat)tableView:(__unused UITableView *)tableView heightForHeaderInSection:(NSInteger)section +- (CGFloat)tableView:(__unused RCTUITableView *)tableView heightForHeaderInSection:(NSInteger)section // [macOS] { auto s = [self sectionForIndex:section]; return (s == Section::CodeFrame || s == Section::CallStack) ? 38 : 0; } -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +- (void)tableView:(RCTUITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath // [macOS] { if ([self sectionForIndex:indexPath.section] == Section::CallStack) { NSUInteger row = indexPath.row; @@ -736,9 +829,9 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } [tableView deselectRowAtIndexPath:indexPath animated:YES]; } - #pragma mark - Key Commands +#if !TARGET_OS_OSX // [macOS] - (NSArray *)keyCommands { return @[ @@ -758,6 +851,7 @@ - (BOOL)canBecomeFirstResponder { return YES; } +#endif // [macOS] @end diff --git a/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIButton.h b/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIButton.h new file mode 100644 index 00000000000..4f97eacf107 --- /dev/null +++ b/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIButton.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// [macOS] + +#pragma once + +#include + +#import "RCTUIKitCompat.h" + +#if !TARGET_OS_OSX +#import +#else +#import +#endif + +NS_ASSUME_NONNULL_BEGIN + +#if !TARGET_OS_OSX + +@compatibility_alias RCTUIButton UIButton; +#define RCTUIControlStateNormal UIControlStateNormal +#define RCTUIControlStateHighlighted UIControlStateHighlighted +typedef UIControlState RCTUIControlState; + +#else // TARGET_OS_OSX [ + +typedef NS_OPTIONS(NSUInteger, RCTUIControlState) { + RCTUIControlStateNormal = 0, + RCTUIControlStateHighlighted = 1 << 0, +}; + +@interface RCTUIButtonTitleProxy : NSObject + +@property (nonatomic, strong, nullable) UIFont *font; +@property (nonatomic, assign) NSLineBreakMode lineBreakMode; +@property (nonatomic, assign) NSTextAlignment textAlignment; + +@end + +@interface RCTUIButton : NSButton + +@property (nonatomic, readonly) RCTUIButtonTitleProxy *titleLabel; +@property (nonatomic, copy, nullable) RCTUIColor *backgroundColor; + +- (void)setTitle:(nullable NSString *)title forState:(RCTUIControlState)state; +- (void)setTitleColor:(nullable RCTUIColor *)color forState:(RCTUIControlState)state; + +@end + +#endif // ] TARGET_OS_OSX + +typedef void (^RCTUIActionHandler)(void); + +@interface RCTUIAction : NSObject + ++ (instancetype)actionWithHandler:(RCTUIActionHandler)handler; +@property (nonatomic, readonly, copy) RCTUIActionHandler handler; + +@end + +@interface RCTUIButton (RCTUIAction) + +- (void)rct_setPrimaryAction:(RCTUIAction *)action; + +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIButton.m b/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIButton.m new file mode 100644 index 00000000000..d01c39f7fb4 --- /dev/null +++ b/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIButton.m @@ -0,0 +1,197 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// [macOS] + +#import "RCTUIButton.h" + +#import + +@interface RCTUIAction () + +- (instancetype)initWithHandler:(RCTUIActionHandler)handler; +- (void)invoke; + +@end + +@implementation RCTUIAction + ++ (instancetype)actionWithHandler:(RCTUIActionHandler)handler +{ + return [[self alloc] initWithHandler:handler]; +} + +- (instancetype)initWithHandler:(RCTUIActionHandler)handler +{ + if (self = [super init]) { + _handler = [handler copy]; + } + return self; +} + +- (void)invoke +{ + self.handler(); +} + +@end + +#if TARGET_OS_OSX + +@class RCTUIButton; + +@interface RCTUIButtonTitleProxy () + +@property (nonatomic, weak) RCTUIButton *button; + +- (instancetype)initWithButton:(RCTUIButton *)button; + +@end + +@interface RCTUIButton () + +- (void)updateAttributedTitles; + +@end + +@implementation RCTUIButtonTitleProxy + +- (instancetype)initWithButton:(RCTUIButton *)button +{ + if (self = [super init]) { + _button = button; + _font = button.font; + _lineBreakMode = NSLineBreakByClipping; + _textAlignment = NSTextAlignmentNatural; + } + return self; +} + +- (void)setFont:(UIFont *)font +{ + _font = font; + [self.button updateAttributedTitles]; +} + +- (void)setLineBreakMode:(NSLineBreakMode)lineBreakMode +{ + _lineBreakMode = lineBreakMode; + [self.button updateAttributedTitles]; +} + +- (void)setTextAlignment:(NSTextAlignment)textAlignment +{ + _textAlignment = textAlignment; + [self.button updateAttributedTitles]; +} + +@end + +@implementation RCTUIButton { + NSString *_normalTitle; + NSString *_highlightedTitle; + RCTUIColor *_normalTitleColor; + RCTUIColor *_highlightedTitleColor; +} + +- (instancetype)initWithFrame:(NSRect)frameRect +{ + if (self = [super initWithFrame:frameRect]) { + _titleLabel = [[RCTUIButtonTitleProxy alloc] initWithButton:self]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)coder +{ + if (self = [super initWithCoder:coder]) { + _titleLabel = [[RCTUIButtonTitleProxy alloc] initWithButton:self]; + } + return self; +} + +- (void)setTitle:(NSString *)title forState:(RCTUIControlState)state +{ + if (state == RCTUIControlStateHighlighted) { + _highlightedTitle = [title copy]; + } else { + _normalTitle = [title copy]; + } + [self updateAttributedTitles]; +} + +- (void)setTitleColor:(RCTUIColor *)color forState:(RCTUIControlState)state +{ + if (state == RCTUIControlStateHighlighted) { + _highlightedTitleColor = [color copy]; + } else { + _normalTitleColor = [color copy]; + } + [self updateAttributedTitles]; +} + +- (void)setBackgroundColor:(RCTUIColor *)backgroundColor +{ + _backgroundColor = [backgroundColor copy]; + self.wantsLayer = YES; + self.layer.backgroundColor = backgroundColor.CGColor; + self.bordered = NO; +} + +- (void)updateAttributedTitles +{ + self.attributedTitle = [self attributedTitleForTitle:_normalTitle ?: @"" + color:_normalTitleColor]; + self.attributedAlternateTitle = [self attributedTitleForTitle:_highlightedTitle ?: _normalTitle ?: @"" + color:_highlightedTitleColor ?: _normalTitleColor]; +} + +- (NSAttributedString *)attributedTitleForTitle:(NSString *)title color:(RCTUIColor *)color +{ + NSMutableDictionary *attributes = [NSMutableDictionary new]; + if (color != nil) { + attributes[NSForegroundColorAttributeName] = color; + } + if (self.titleLabel.font != nil) { + attributes[NSFontAttributeName] = self.titleLabel.font; + } + + NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; + paragraphStyle.lineBreakMode = self.titleLabel.lineBreakMode; + paragraphStyle.alignment = self.titleLabel.textAlignment; + attributes[NSParagraphStyleAttributeName] = paragraphStyle; + + return [[NSAttributedString alloc] initWithString:title attributes:attributes]; +} + +@end + +#endif + +@implementation RCTUIButton (RCTUIAction) + +- (void)rct_setPrimaryAction:(RCTUIAction *)action +{ +#if !TARGET_OS_OSX + RCTUIAction *previousAction = objc_getAssociatedObject(self, @selector(rct_setPrimaryAction:)); + if (previousAction != nil) { + [self removeTarget:previousAction action:@selector(invoke) forControlEvents:UIControlEventTouchUpInside]; + } +#endif + + objc_setAssociatedObject( + self, @selector(rct_setPrimaryAction:), action, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + +#if !TARGET_OS_OSX + [self addTarget:action action:@selector(invoke) forControlEvents:UIControlEventTouchUpInside]; +#else + self.target = action; + self.action = @selector(invoke); +#endif +} + +@end diff --git a/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIKit.h b/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIKit.h index e1a2f0ae022..7d51cf2dfe7 100644 --- a/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIKit.h +++ b/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIKit.h @@ -17,6 +17,7 @@ #import "RCTUIScrollView.h" #import "RCTUISlider.h" #import "RCTUITableView.h" +#import "RCTUIButton.h" #import "RCTUILabel.h" #import "RCTUISwitch.h" #import "RCTUIActivityIndicatorView.h" diff --git a/packages/react-native/ReactNativeApi.d.ts b/packages/react-native/ReactNativeApi.d.ts index 5f50f8431a8..ae207c5decd 100644 --- a/packages/react-native/ReactNativeApi.d.ts +++ b/packages/react-native/ReactNativeApi.d.ts @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<161f7292e15aceb30dc783edaef455a4>> * * This file was generated by scripts/js-api/build-types/index.js. */ @@ -21,20 +21,18 @@ /* eslint-disable redundant-undefined/redundant-undefined */ +import type { FocusEvent as FocusEvent_2 } from "react-native" import type { HostInstance as HostInstance_2 } from "react-native" -import { ListRenderItem } from "@react-native-macos/virtualized-lists" -import { ListRenderItemInfo } from "@react-native-macos/virtualized-lists" -import { ListViewToken } from "@react-native-macos/virtualized-lists" +import type { LayoutChangeEvent as LayoutChangeEvent_2 } from "react-native" +import type { LayoutRectangle as LayoutRectangle_2 } from "react-native" import type { PublicRootInstance as PublicRootInstance_2 } from "react-native" import type { PublicTextInstance as PublicTextInstance_2 } from "react-native" import * as React from "react" -import { ScrollToLocationParamsType } from "@react-native-macos/virtualized-lists" -import { SectionBase } from "@react-native-macos/virtualized-lists" -import type { SectionData as SectionListData } from "@react-native-macos/virtualized-lists" -import { Separators } from "@react-native-macos/virtualized-lists" -import { VirtualizedListProps } from "@react-native-macos/virtualized-lists" -import VirtualizedLists from "@react-native-macos/virtualized-lists" -import { VirtualizedSectionListProps } from "@react-native-macos/virtualized-lists" +import type { ScrollResponderType as ScrollResponderType_2 } from "react-native" +import { ScrollView as ScrollView_2 } from "react-native" +import type { ScrollViewProps as ScrollViewProps_2 } from "react-native" +import type { StyleProp as StyleProp_2 } from "react-native" +import type { ViewStyle as ViewStyle_2 } from "react-native" declare const $$AndroidSwitchNativeComponent: NativeType declare const $$AnimatedFlatList: ( props: Omit>, "ref"> & { @@ -90,6 +88,14 @@ declare const $$AnimatedView: AnimatedComponentType< React.ComponentRef > declare const $$flattenStyle: typeof flattenStyle_default +declare const $$index: { + keyExtractor: typeof keyExtractor + get FillRateHelper(): FillRateHelperT + get ViewabilityHelper(): ViewabilityHelperT + get VirtualizedList(): VirtualizedListT + get VirtualizedListContextResetter(): VirtualizedListContextResetterT + get VirtualizedSectionList(): AnyVirtualizedSectionList +} declare const $$NativeDeviceInfo: typeof NativeDeviceInfo_default declare const $$NativeDialogManagerAndroid: null | Spec | undefined declare const $$ProgressBarAndroidNativeComponent: HostComponent @@ -568,8 +574,23 @@ declare const View: typeof View_default declare const ViewNativeComponent_default: HostComponent declare const VirtualizedList: typeof VirtualizedListComponent_default declare const VirtualizedListComponent_default: VirtualizedListType +declare const VirtualizedListContext: React.Context declare const VirtualizedSectionList: typeof VirtualizedSectionList_default declare const VirtualizedSectionList_default: VirtualizedSectionListType +declare const VirtualizedSectionListComponent_default: < + ItemT, + SectionT extends SectionBase< + ItemT, + DefaultVirtualizedSectionT + > = DefaultVirtualizedSectionT, +>( + props: Omit, "ref"> & { + ref?: React.Ref<{ + getListRef(): undefined | VirtualizedList_default + scrollToLocation(params: ScrollToLocationParamsType): void + }> + }, +) => React.ReactNode declare type ____BlendMode_Internal = | "color-burn" | "color-dodge" @@ -1007,6 +1028,7 @@ declare type $$AnimatedSectionList = typeof $$AnimatedSectionList declare type $$AnimatedText = typeof $$AnimatedText declare type $$AnimatedView = typeof $$AnimatedView declare type $$flattenStyle = typeof $$flattenStyle +declare type $$index = typeof $$index declare type $$NativeDeviceInfo = typeof $$NativeDeviceInfo declare type $$NativeDialogManagerAndroid = typeof $$NativeDialogManagerAndroid declare type $$ProgressBarAndroidNativeComponent = @@ -1631,6 +1653,8 @@ declare type AnimationConfig = { readonly useNativeDriver: boolean } declare type AnyAttributeType = AttributeType +declare type AnyVirtualizedSectionList = + typeof VirtualizedSectionListComponent_default declare type AppConfig = { appKey: string component?: ComponentProvider @@ -1814,6 +1838,40 @@ declare type ButtonProps = { declare type ButtonRef = React.ComponentRef declare function cancelHeadlessTask(taskId: number, taskKey: string): void declare type Category = string +declare type CellMetricProps = { + data: VirtualizedListProps["data"] + getItem: VirtualizedListProps["getItem"] + getItemCount: VirtualizedListProps["getItemCount"] + getItemLayout?: VirtualizedListProps["getItemLayout"] + keyExtractor?: VirtualizedListProps["keyExtractor"] +} +declare type CellMetrics = { + index: number + isMounted: boolean + length: number + offset: number +} +declare type CellRegion = { + first: number + isSpacer: boolean + last: number +} +declare type CellRendererProps = { + readonly cellKey: string + readonly children: React.ReactNode + readonly index: number + readonly item: ItemT + readonly style: StyleProp_2 + readonly onFocusCapture?: (event: FocusEvent_2) => void + readonly onLayout?: (event: LayoutChangeEvent_2) => void +} +declare class CellRenderMask { + addCells(cells: { first: number; last: number }): void + constructor(numCells: number) + enumerateRegions(): ReadonlyArray + equals(other: CellRenderMask): boolean + numCells(): number +} declare type Clipboard = typeof Clipboard declare type codegenNativeCommands = typeof codegenNativeCommands declare function codegenNativeCommands_default( @@ -1864,6 +1922,28 @@ declare function configureNext( onAnimationDidFail?: OnAnimationDidFailCallback, ): void declare type ContentAvailable = 1 | null | void +declare type Context = { + readonly cellKey: string | undefined + readonly horizontal: boolean | undefined + readonly getOutermostParentListRef: () => VirtualizedList_default + readonly getScrollMetrics: () => { + contentLength: number + dOffset: number + dt: number + offset: number + timestamp: number + velocity: number + visibleLength: number + zoomScale: number + } + readonly registerAsNestedChild: ($$PARAM_0$$: { + cellKey: string + ref: VirtualizedList_default + }) => void + readonly unregisterAsNestedChild: ($$PARAM_0$$: { + ref: VirtualizedList_default + }) => void +} declare function counterEvent(eventName: EventName, value: number): void declare type create = typeof create declare type createAnimatedComponent = typeof createAnimatedComponent @@ -1986,6 +2066,10 @@ declare type DefaultSectionT = { [key: string]: any } declare type DefaultTypes = boolean | number | ReadonlyArray | string +declare type DefaultVirtualizedSectionT = { + [key: string]: any + data: any +} declare type delay = typeof delay declare interface DEPRECATED_RCTExport { readonly getConstants?: () => {} @@ -2310,6 +2394,34 @@ declare type FetchResult = { NoData: "UIBackgroundFetchResultNoData" ResultFailed: "UIBackgroundFetchResultFailed" } +declare class FillRateHelper_default { + activate(): void + static addListener(callback: ($$PARAM_0$$: FillRateInfo) => void): { + remove: () => void + } + computeBlankness( + props: CellMetricProps & { + initialNumToRender?: number + }, + cellsAroundViewport: { + first: number + last: number + }, + scrollMetrics: { + dOffset: number + offset: number + velocity: number + visibleLength: number + }, + ): number + constructor(listMetrics: ListMetricsAggregator_default) + deactivateAndFlush(): void + enabled(): boolean + static setMinSampleCount(minSampleCount: number): void + static setSampleRate(sampleRate: number): void +} +declare type FillRateHelperT = typeof FillRateHelper_default +declare type FillRateInfo = Info declare type FilterFunction = | { blur: number | string @@ -2764,6 +2876,18 @@ declare type IndeterminateProgressBarAndroidStyleAttrProp = { | "SmallInverse" } declare type IndicatorSize = "large" | "small" | number +declare class Info { + any_blank_count: number + any_blank_ms: number + any_blank_speed_sum: number + mostly_blank_count: number + mostly_blank_ms: number + pixels_blank: number + pixels_sampled: number + pixels_scrolled: number + sample_count: number + total_time_spent: number +} declare type InnerViewInstance = React.ComponentRef declare type InputAccessoryView = typeof InputAccessoryView declare type InputAccessoryViewProps = { @@ -2886,6 +3010,7 @@ declare interface IPerformanceLogger { stopTimespan(key: string, timestamp?: number, extras?: Extras): void } declare function isEnabled(): boolean +declare type Item = any declare type Keyboard = typeof Keyboard declare class KeyboardAvoidingView extends React.Component< KeyboardAvoidingViewProps, @@ -3002,6 +3127,7 @@ declare type KeyEventProps = { readonly onKeyUp?: (event: KeyUpEvent) => void readonly onKeyUpCapture?: (event: KeyUpEvent) => void } +declare function keyExtractor(item: any, index: number): string declare type KeysOfUnion = T extends any ? keyof T : never declare type KeyUpEvent = NativeSyntheticEvent declare type LayoutAnimation = typeof LayoutAnimation @@ -3088,6 +3214,57 @@ declare class LinkingImpl extends NativeEventEmitter { }>, ): Promise } +declare class ListMetricsAggregator_default { + cartesianOffset(flowRelativeOffset: number): number + flowRelativeOffset( + layout: LayoutRectangle_2, + referenceContentLength?: null | number | undefined, + ): number + getAverageCellLength(): number + getCellMetrics( + index: number, + props: CellMetricProps, + ): CellMetrics | null | undefined + getCellMetricsApprox(index: number, props: CellMetricProps): CellMetrics + getCellOffsetApprox(index: number, props: CellMetricProps): number + getContentLength(): number + getHighestMeasuredCellIndex(): number + hasContentLength(): boolean + notifyCellLayout($$PARAM_0$$: { + cellIndex: number + cellKey: string + layout: LayoutRectangle_2 + orientation: ListOrientation + }): boolean + notifyCellUnmounted(cellKey: string): void + notifyListContentLayout($$PARAM_0$$: { + layout: { + readonly height: number + readonly width: number + } + orientation: ListOrientation + }): void +} +declare type ListOrientation = { + horizontal: boolean + rtl: boolean +} +declare type ListRenderItem = ( + info: ListRenderItemInfo, +) => React.ReactNode +declare type ListRenderItemInfo = { + index: number + isSelected: boolean | undefined + item: ItemT + separators: Separators +} +declare type ListViewToken = { + index: number | undefined + isViewable: boolean + item: any + key: string + section?: any +} declare type LogBox = typeof LogBox declare type LogData = { readonly category: Category @@ -3510,6 +3687,79 @@ declare type OptionalSectionListProps = { removeClippedSubviews?: boolean renderItem?: SectionListRenderItem } +declare type OptionalVirtualizedListProps = { + CellRendererComponent?: React.ComponentType> + debug?: boolean + disableVirtualization?: boolean + extraData?: any + horizontal?: boolean + initialNumToRender?: number + initialScrollIndex?: number + inverted?: boolean + ItemSeparatorComponent?: React.ComponentType | React.JSX.Element + keyExtractor?: (item: Item, index: number) => string + ListEmptyComponent?: React.ComponentType | React.JSX.Element + ListFooterComponent?: React.ComponentType | React.JSX.Element + ListFooterComponentStyle?: StyleProp_2 + ListHeaderComponent?: React.ComponentType | React.JSX.Element + ListHeaderComponentStyle?: StyleProp_2 + ListItemComponent?: React.ComponentType | React.JSX.Element + maxToRenderPerBatch?: number + onEndReached?: (info: { distanceFromEnd: number }) => void + onEndReachedThreshold?: number + onRefresh?: () => void + onScrollToIndexFailed?: (info: { + averageItemLength: number + highestMeasuredFrameIndex: number + index: number + }) => void + onStartReached?: (info: { distanceFromStart: number }) => void + onStartReachedThreshold?: number + onViewableItemsChanged?: (info: { + changed: Array + viewableItems: Array + }) => void + persistentScrollbar?: boolean + progressViewOffset?: number + refreshControl?: React.JSX.Element + refreshing?: boolean + removeClippedSubviews?: boolean + renderItem?: ListRenderItem + updateCellsBatchingPeriod?: number + viewabilityConfig?: ViewabilityConfig + viewabilityConfigCallbackPairs?: Array + windowSize?: number + getItemLayout?: ( + data: any, + index: number, + ) => { + index: number + length: number + offset: number + } + renderScrollComponent?: (props: ScrollViewProps_2) => React.JSX.Element +} +declare type OptionalVirtualizedSectionListProps< + ItemT, + SectionT = DefaultVirtualizedSectionT, +> = { + onEndReached?: ($$PARAM_0$$: { distanceFromEnd: number }) => void + renderSectionFooter?: (info: { section: SectionT }) => null | React.ReactNode + renderSectionHeader?: (info: { section: SectionT }) => null | React.ReactNode + SectionSeparatorComponent?: React.ComponentType + stickySectionHeadersEnabled?: boolean + renderItem?: (info: { + index: number + isSelected: boolean | undefined + item: ItemT + section: SectionT + separators: { + highlight: () => void + unhighlight: () => void + updateProps: (select: "leading" | "trailing", newProps: Object) => void + } + }) => null | React.ReactNode +} declare type OrientationChangeEvent = { readonly orientation: "landscape" | "portrait" } @@ -4230,6 +4480,17 @@ declare type RequiredFlatListProps = { declare type RequiredSectionListProps = { sections: ReadonlyArray> } +declare type RequiredVirtualizedListProps = { + data?: any + getItem: (data: any, index: number) => Item | undefined + getItemCount: (data: any) => number +} +declare type RequiredVirtualizedSectionListProps< + ItemT, + SectionT = DefaultVirtualizedSectionT, +> = { + sections: ReadonlyArray> +} declare type requireNativeComponent = typeof requireNativeComponent declare type ResolvedAssetSource = { readonly height: number | undefined @@ -4374,6 +4635,13 @@ declare type ScheduleLocalNotificationDetails = } declare type ScrollEvent = NativeSyntheticEvent declare type ScrollResponderType = ScrollViewImperativeMethods +declare type ScrollToLocationParamsType = { + animated?: boolean + itemIndex: number + sectionIndex: number + viewOffset?: number + viewPosition?: number +} declare type ScrollView = typeof ScrollView declare type ScrollViewBaseProps = { readonly children?: React.ReactNode @@ -4589,6 +4857,28 @@ declare type ScrollViewStickyHeaderProps = { readonly scrollViewHeight: number | undefined readonly onLayout: (event: LayoutChangeEvent) => void } +declare type SectionBase< + SectionItemT, + SectionT = DefaultVirtualizedSectionT, +> = { + data: ReadonlyArray + ItemSeparatorComponent?: React.ComponentType | React.JSX.Element + key?: string + renderItem?: (info: { + index: number + item: SectionItemT + section: SectionListData + separators: { + highlight: () => void + unhighlight: () => void + updateProps: (select: "leading" | "trailing", newProps: Object) => void + } + }) => null | React.JSX.Element + keyExtractor?: ( + item: SectionItemT | undefined, + index?: number | undefined, + ) => string +} declare class SectionList< ItemT = any, SectionT = DefaultSectionT, @@ -4602,6 +4892,13 @@ declare class SectionList< scrollToLocation(params: ScrollToLocationParamsType): void setNativeProps(props: Object): void } +declare type SectionListData< + SectionItemT, + SectionT = DefaultVirtualizedSectionT, +> = + | (Readonly> & SectionT) + | (SectionBase & SectionT) + | SectionT declare type SectionListProps = Omit< Omit< VirtualizedSectionListProps, @@ -4625,13 +4922,18 @@ declare type SectionListRenderItem = ( declare type SectionListRenderItemInfo< ItemT, SectionT = DefaultSectionT, -> = Omit, "section"> & { +> = ListRenderItemInfo & { section: SectionListData } declare type Selection = { readonly end: number readonly start: number } +declare type Separators = { + highlight: () => void + unhighlight: () => void + updateProps: (select: "leading" | "trailing", newProps: Object) => void +} declare type sequence = typeof sequence declare function setColorScheme(colorScheme: ColorSchemeName): void declare function setComponentProviderInstrumentationHook( @@ -4898,6 +5200,35 @@ declare function startHeadlessTask( taskKey: string, data: any, ): void +declare type State = { + cellsAroundViewport: { + first: number + last: number + } + firstVisibleItemKey: string | undefined + pendingScrollUpdateCount: number + renderMask: CellRenderMask + selectedRowIndex: number +} +declare class StateSafePureComponent_default< + Props, + State extends {}, +> extends React.PureComponent { + constructor(props: Props) + setState( + partialState: + | ( + | (( + $$PARAM_0$$: State, + $$PARAM_1$$: Props, + ) => null | Pick | undefined) + | Pick + ) + | null + | undefined, + callback?: () => unknown, + ): void +} declare class StatusBar extends React.Component { static currentHeight: null | number | undefined componentDidMount(): void @@ -5710,6 +6041,55 @@ declare function View_default( ref?: React.Ref> }, ): React.ReactNode +declare type ViewabilityConfig = { + readonly itemVisiblePercentThreshold?: number + readonly minimumViewTime?: number + readonly viewAreaCoveragePercentThreshold?: number + readonly waitForInteraction?: boolean +} +declare type ViewabilityConfigCallbackPair = { + viewabilityConfig: ViewabilityConfig + onViewableItemsChanged: (info: { + changed: Array + viewableItems: Array + }) => void +} +declare class ViewabilityHelper_default { + computeViewableItems( + props: CellMetricProps, + scrollOffset: number, + viewportHeight: number, + listMetrics: ListMetricsAggregator_default, + renderRange?: { + first: number + last: number + }, + ): Array + constructor(config?: ViewabilityConfig) + dispose(): void + onUpdate( + props: CellMetricProps, + scrollOffset: number, + viewportHeight: number, + listMetrics: ListMetricsAggregator_default, + createViewToken: ( + index: number, + isViewable: boolean, + props: CellMetricProps, + ) => ListViewToken, + onViewableItemsChanged: ($$PARAM_0$$: { + changed: Array + viewableItems: Array + }) => void, + renderRange?: { + first: number + last: number + }, + ): void + recordInteraction(): void + resetViewableIndices(): void +} +declare type ViewabilityHelperT = typeof ViewabilityHelper_default declare type ViewBaseProps = { readonly children?: React.ReactNode readonly collapsable?: boolean @@ -5788,10 +6168,133 @@ declare type ViewPropsIOS = { declare type ViewStyle = ____ViewStyle_Internal declare type ViewStyleProp = ____ViewStyleProp_Internal declare type VirtualizedList = typeof VirtualizedList -declare type VirtualizedListType = typeof VirtualizedLists.VirtualizedList +declare class VirtualizedList_default extends StateSafePureComponent_default< + VirtualizedListProps, + State +> { + static contextType: typeof VirtualizedListContext + state: State + componentDidMount(): void + componentDidUpdate(prevProps: VirtualizedListProps): void + componentWillUnmount(): void + constructor(props: VirtualizedListProps) + ensureItemAtIndexIsVisible(rowIndex: number): void + flashScrollIndicators(): void + static getDerivedStateFromProps( + newProps: VirtualizedListProps, + prevState: State, + ): State + getScrollableNode(): null | number | undefined + getScrollRef(): null | React.ComponentRef | undefined + getScrollResponder(): null | ScrollResponderType_2 | undefined + hasMore(): boolean + measureLayoutRelativeToContainingList(): void + recordInteraction(): void + render(): React.ReactNode + scrollToEnd( + params?: + | null + | undefined + | { + animated?: boolean + }, + ): void + scrollToIndex(params: { + animated?: boolean + index: number + viewOffset?: number + viewPosition?: number + }): any + scrollToItem(params: { + animated?: boolean + item: Item + viewOffset?: number + viewPosition?: number + }): void + scrollToOffset(params: { animated?: boolean; offset: number }): void + selectRowAtIndex(rowIndex: number): void + setNativeProps(props: Object): void +} +declare type VirtualizedListContext = typeof VirtualizedListContext +declare function VirtualizedListContextResetter($$PARAM_0$$: { + children: React.ReactNode +}): React.ReactNode +declare type VirtualizedListContextResetterT = + typeof VirtualizedListContextResetter +declare type VirtualizedListMacOSProps = { + enableSelectionOnKeyPress?: boolean + initialSelectedIndex?: number + onSelectionChanged?: (info: { + item: Item | undefined + newSelection: number + previousSelection: number + }) => void + onSelectionEntered?: (item: Item | undefined) => void + rowIndex?: number + sectionIndex?: number +} +declare type VirtualizedListProps = Omit< + ScrollViewProps_2, + | "data" + | "getItem" + | "getItemCount" + | "enableSelectionOnKeyPress" + | "initialSelectedIndex" + | "onSelectionChanged" + | "onSelectionEntered" + | "rowIndex" + | "sectionIndex" + | "CellRendererComponent" + | "debug" + | "disableVirtualization" + | "extraData" + | "getItemLayout" + | "horizontal" + | "initialNumToRender" + | "initialScrollIndex" + | "inverted" + | "ItemSeparatorComponent" + | "keyExtractor" + | "ListEmptyComponent" + | "ListFooterComponent" + | "ListFooterComponentStyle" + | "ListHeaderComponent" + | "ListHeaderComponentStyle" + | "ListItemComponent" + | "maxToRenderPerBatch" + | "onEndReached" + | "onEndReachedThreshold" + | "onRefresh" + | "onScrollToIndexFailed" + | "onStartReached" + | "onStartReachedThreshold" + | "onViewableItemsChanged" + | "persistentScrollbar" + | "progressViewOffset" + | "refreshControl" + | "refreshing" + | "removeClippedSubviews" + | "renderItem" + | "renderScrollComponent" + | "updateCellsBatchingPeriod" + | "viewabilityConfig" + | "viewabilityConfigCallbackPairs" + | "windowSize" + | never +> & + RequiredVirtualizedListProps & + OptionalVirtualizedListProps & + VirtualizedListMacOSProps +declare type VirtualizedListT = typeof VirtualizedList_default +declare type VirtualizedListType = typeof $$index.VirtualizedList declare type VirtualizedSectionList = typeof VirtualizedSectionList -declare type VirtualizedSectionListType = - typeof VirtualizedLists.VirtualizedSectionList +declare type VirtualizedSectionListProps< + ItemT, + SectionT = DefaultVirtualizedSectionT, +> = RequiredVirtualizedSectionListProps & + OptionalVirtualizedSectionListProps & + Omit +declare type VirtualizedSectionListType = typeof $$index.VirtualizedSectionList declare enum VirtualViewMode { Hidden = 2, Prerender = 1, @@ -5907,7 +6410,7 @@ export { AlertOptions, // 39b16cfa AlertType, // 5ab91217 AndroidKeyboardEvent, // e03becc8 - Animated, // 5138836c + Animated, // c4d0ace0 AppConfig, // ce4209a7 AppRegistry, // 1d923149 AppState, // 12012be5 @@ -5957,8 +6460,8 @@ export { EventSubscription, // b8d084aa ExtendedExceptionData, // 5a6ccf5a FilterFunction, // bf24c0e3 - FlatList, // 51536750 - FlatListProps, // 1bb18ba2 + FlatList, // 53a92b42 + FlatListProps, // 19a8de31 FocusEvent, // 62fc1eb8 FontVariant, // 7c7558bb GestureResponderEvent, // 07521628 @@ -6014,9 +6517,9 @@ export { LayoutConformanceProps, // 055f03b8 LayoutRectangle, // 6601b294 Linking, // 9a6a174d - ListRenderItem, - ListRenderItemInfo, - ListViewToken, + ListRenderItem, // 3ba527db + ListRenderItemInfo, // d21a2b9b + ListViewToken, // 833d3481 LogBox, // 94d278f1 LogData, // e68f7019 MeasureInWindowOnSuccessCallback, // a285f598 @@ -6086,7 +6589,7 @@ export { ReturnKeyTypeOptions, // afd47ba3 Role, // af7b889d RootTag, // 3cd10504 - RootTagContext, // cc287c11 + RootTagContext, // 38bfc8f6 RootViewStyleProvider, // f850b4ba Runnable, // 594dd93a Runnables, // 4367c557 @@ -6094,20 +6597,20 @@ export { ScaledSize, // 07e417c7 ScrollEvent, // 05e71bb1 ScrollResponderType, // df1eec01 - ScrollToLocationParamsType, - ScrollView, // 8249b0db + ScrollToLocationParamsType, // d7ecdad1 + ScrollView, // 9c0075af ScrollViewImperativeMethods, // 49630f53 ScrollViewProps, // 897ab911 ScrollViewPropsAndroid, // 44210553 ScrollViewPropsIOS, // 1b6bf74d ScrollViewScrollToOptions, // 3313411e - SectionBase, - SectionList, // 7a83800c - SectionListData, - SectionListProps, // d2fcd6f4 - SectionListRenderItem, // c118edfb - SectionListRenderItemInfo, // bd038703 - Separators, + SectionBase, // b376bddc + SectionList, // ad3d91e2 + SectionListData, // 119baf83 + SectionListProps, // 1c9565a0 + SectionListRenderItem, // 9600767c + SectionListRenderItemInfo, // 158b913b + Separators, // 6a45f7e3 Settings, // 2be0c61e Share, // e4591b32 ShareAction, // ead1004a @@ -6132,7 +6635,7 @@ export { TaskProvider, // 266dedf2 Text, // e59e30e2 TextContentType, // 239b3ecc - TextInput, // ded60ba4 + TextInput, // ce3e1240 TextInputAndroidProps, // 3f09ce49 TextInputChangeEvent, // 3ab11bb4 TextInputContentSizeChangeEvent, // f71f8571 @@ -6168,10 +6671,10 @@ export { ViewPropsIOS, // 58ee19bf ViewStyle, // d7b4d2fe VirtualViewMode, // 6be59722 - VirtualizedList, // d4e15eaa - VirtualizedListProps, - VirtualizedSectionList, // 486a3a9d - VirtualizedSectionListProps, + VirtualizedList, // 68c7345e + VirtualizedListProps, // cf03a29a + VirtualizedSectionList, // 9fd9cd61 + VirtualizedSectionListProps, // e136f7bb WrapperComponentProvider, // 9cf3844c codegenNativeCommands, // 628a7c0a codegenNativeComponent, // 2baac257 diff --git a/packages/react-native/scripts/ios-prebuild/__tests__/hermes-test.js b/packages/react-native/scripts/ios-prebuild/__tests__/hermes-test.js index b27e352a7c0..a391bf8fc81 100644 --- a/packages/react-native/scripts/ios-prebuild/__tests__/hermes-test.js +++ b/packages/react-native/scripts/ios-prebuild/__tests__/hermes-test.js @@ -355,7 +355,9 @@ test('reuses only the matching Hermes version, flag and flavor cache', async () execFileSync.mockClear(); await prepareHermesArtifactsAsync('0.83.1', 'Debug'); expect(global.fetch).not.toHaveBeenCalled(); - expect(execFileSync.mock.calls.map(([command]) => command)).toEqual(['plutil']); + expect(execFileSync.mock.calls.map(([command]) => command)).toEqual([ + 'plutil', + ]); properties = 'HERMES_VERSION_NAME=123.4.56\nHERMES_V1_VERSION_NAME=234.5.68'; await prepareHermesArtifactsAsync('0.83.1', 'Debug'); expect(global.fetch).toHaveBeenCalledWith(releaseUrl('234.5.68'));