mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
feat[TraceUpdateOverlay]: add iOS native component (#41563)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/41563 Changelog: [iOS][Added] - support "highlighting updates when components render" feature from React DevTools Reviewed By: javache Differential Revision: D51470012 fbshipit-source-id: ba4094ae24d14f58ad08acbb90333bbe49e043c9
This commit is contained in:
committed by
Facebook GitHub Bot
parent
fd35c1db28
commit
758e59f1d9
+4
-6
@@ -17,7 +17,6 @@ import type {Overlay} from './TraceUpdateOverlayNativeComponent';
|
||||
import UIManager from '../../ReactNative/UIManager';
|
||||
import processColor from '../../StyleSheet/processColor';
|
||||
import StyleSheet from '../../StyleSheet/StyleSheet';
|
||||
import Platform from '../../Utilities/Platform';
|
||||
import View from '../View/View';
|
||||
import TraceUpdateOverlayNativeComponent, {
|
||||
Commands,
|
||||
@@ -26,7 +25,6 @@ import * as React from 'react';
|
||||
|
||||
const {useEffect, useRef, useState} = React;
|
||||
const isNativeComponentReady =
|
||||
Platform.OS === 'android' &&
|
||||
UIManager.hasViewManagerConfig('TraceUpdateOverlay');
|
||||
|
||||
type Props = {
|
||||
@@ -39,13 +37,13 @@ export default function TraceUpdateOverlay({
|
||||
const [overlayDisabled, setOverlayDisabled] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isNativeComponentReady) {
|
||||
return;
|
||||
}
|
||||
|
||||
const drawTraceUpdates = (
|
||||
nodesToDraw: Array<{node: InstanceFromReactDevTools, color: string}> = [],
|
||||
) => {
|
||||
if (!isNativeComponentReady) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If overlay is disabled before, now it's enabled.
|
||||
setOverlayDisabled(false);
|
||||
|
||||
|
||||
+1
@@ -38,6 +38,7 @@ Class<RCTComponentViewProtocol> RCTSafeAreaViewCls(void) __attribute__((used));
|
||||
Class<RCTComponentViewProtocol> RCTScrollViewCls(void) __attribute__((used));
|
||||
Class<RCTComponentViewProtocol> RCTSwitchCls(void) __attribute__((used));
|
||||
Class<RCTComponentViewProtocol> RCTTextInputCls(void) __attribute__((used));
|
||||
Class<RCTComponentViewProtocol> RCTTraceUpdateOverlayCls(void) __attribute__((used));
|
||||
Class<RCTComponentViewProtocol> RCTUnimplementedNativeViewCls(void) __attribute__((used));
|
||||
Class<RCTComponentViewProtocol> RCTViewCls(void) __attribute__((used));
|
||||
Class<RCTComponentViewProtocol> RCTImageCls(void) __attribute__((used));
|
||||
|
||||
+1
@@ -26,6 +26,7 @@ Class<RCTComponentViewProtocol> RCTFabricComponentsProvider(const char *name) {
|
||||
{"ScrollView", RCTScrollViewCls},
|
||||
{"Switch", RCTSwitchCls},
|
||||
{"TextInput", RCTTextInputCls},
|
||||
{"TraceUpdateOverlay", RCTTraceUpdateOverlayCls},
|
||||
{"UnimplementedNativeView", RCTUnimplementedNativeViewCls},
|
||||
{"View", RCTViewCls},
|
||||
{"Image", RCTImageCls},
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTViewComponentView.h>
|
||||
|
||||
#import <react/renderer/components/rncore/RCTComponentViewHelpers.h>
|
||||
|
||||
@interface RCTTraceUpdateOverlayComponentView : RCTViewComponentView <RCTTraceUpdateOverlayViewProtocol>
|
||||
|
||||
@end
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTTraceUpdateOverlayComponentView.h"
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTLog.h>
|
||||
#import <React/RCTTraceUpdateOverlay.h>
|
||||
|
||||
#import <react/renderer/components/rncore/ComponentDescriptors.h>
|
||||
#import <react/renderer/components/rncore/EventEmitters.h>
|
||||
#import <react/renderer/components/rncore/Props.h>
|
||||
#import <react/renderer/components/rncore/RCTComponentViewHelpers.h>
|
||||
|
||||
#import "RCTFabricComponentsPlugins.h"
|
||||
|
||||
using namespace facebook::react;
|
||||
|
||||
@implementation RCTTraceUpdateOverlayComponentView {
|
||||
RCTTraceUpdateOverlay *_overlay;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
static const auto defaultProps = std::make_shared<const TraceUpdateOverlayProps>();
|
||||
_props = defaultProps;
|
||||
|
||||
_overlay = [[RCTTraceUpdateOverlay alloc] initWithFrame:self.bounds];
|
||||
|
||||
self.contentView = _overlay;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
||||
{
|
||||
return concreteComponentDescriptorProvider<TraceUpdateOverlayComponentDescriptor>();
|
||||
}
|
||||
|
||||
#pragma mark - Native commands
|
||||
|
||||
- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args
|
||||
{
|
||||
RCTTraceUpdateOverlayHandleCommand(self, commandName, args);
|
||||
}
|
||||
|
||||
- (void)draw:(NSString *)overlays
|
||||
{
|
||||
[_overlay draw:overlays];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Class<RCTComponentViewProtocol> RCTTraceUpdateOverlayCls(void)
|
||||
{
|
||||
return RCTTraceUpdateOverlayComponentView.class;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTView.h>
|
||||
|
||||
@interface RCTTraceUpdateOverlay : RCTView
|
||||
|
||||
- (void)draw:(NSString *)serializedNodes;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTTraceUpdateOverlay.h"
|
||||
|
||||
#import <React/RCTConvert.h>
|
||||
#import <React/RCTLog.h>
|
||||
#import <React/RCTUtils.h>
|
||||
|
||||
@implementation RCTTraceUpdateOverlay
|
||||
|
||||
- (void)draw:(NSString *)serializedNodes
|
||||
{
|
||||
NSArray *subViewsToRemove = [self subviews];
|
||||
for (UIView *v in subViewsToRemove) {
|
||||
[v removeFromSuperview];
|
||||
}
|
||||
|
||||
NSError *error = nil;
|
||||
id deserializedNodes = RCTJSONParse(serializedNodes, &error);
|
||||
|
||||
if (error) {
|
||||
RCTLogError(@"Failed to parse serialized nodes passed to RCTTraceUpdatesOverlay");
|
||||
return;
|
||||
}
|
||||
|
||||
if (![deserializedNodes isKindOfClass:[NSArray class]]) {
|
||||
RCTLogError(@"Expected to receive nodes as an array, got %@", NSStringFromClass([deserializedNodes class]));
|
||||
return;
|
||||
}
|
||||
|
||||
for (NSDictionary *node in deserializedNodes) {
|
||||
NSDictionary *nodeRectangle = node[@"rect"];
|
||||
NSNumber *nodeColor = node[@"color"];
|
||||
|
||||
NSNumber *x = nodeRectangle[@"left"];
|
||||
NSNumber *y = nodeRectangle[@"top"];
|
||||
NSNumber *width = nodeRectangle[@"width"];
|
||||
NSNumber *height = nodeRectangle[@"height"];
|
||||
|
||||
CGRect rect = CGRectMake(x.doubleValue, y.doubleValue, width.doubleValue, height.doubleValue);
|
||||
|
||||
UIView *box = [[UIView alloc] initWithFrame:rect];
|
||||
box.backgroundColor = [UIColor clearColor];
|
||||
|
||||
box.layer.borderWidth = 2.0f;
|
||||
box.layer.borderColor = [RCTConvert UIColor:nodeColor].CGColor;
|
||||
|
||||
[self addSubview:box];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <React/RCTViewManager.h>
|
||||
|
||||
@interface RCTTraceUpdateOverlayManager : RCTViewManager
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTTraceUpdateOverlayManager.h"
|
||||
#import "RCTTraceUpdateOverlay.h"
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
#import <React/RCTUIManager.h>
|
||||
|
||||
#import "RCTBridge.h"
|
||||
|
||||
@implementation RCTTraceUpdateOverlayManager
|
||||
|
||||
RCT_EXPORT_MODULE(TraceUpdateOverlay)
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
return [RCTTraceUpdateOverlay new];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(draw : (nonnull NSNumber *)viewTag nodes : (NSString *)serializedNodes)
|
||||
{
|
||||
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
UIView *view = viewRegistry[viewTag];
|
||||
|
||||
if ([view isKindOfClass:[RCTTraceUpdateOverlay class]]) {
|
||||
[(RCTTraceUpdateOverlay *)view draw:serializedNodes];
|
||||
} else {
|
||||
RCTLogError(@"Expected view to be RCTTraceUpdateOverlay, got %@", NSStringFromClass([view class]));
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user