mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
feat[devtools]: display native tag for host components for Native (#32762)
Native only. Displays the native tag for Native Host components inside a badge, when user inspects the component. Only displaying will be supported for now, because in order to get native tags indexable, they should be part of the bridge operations, which is technically a breaking change that requires significantly more time investment. The text will only be shown when user hovers over the badge. 
This commit is contained in:
parent
b2f6365745
commit
f0c767e2a2
|
|
@ -808,6 +808,27 @@ function getPublicInstance(instance: HostInstance): HostInstance {
|
|||
return instance;
|
||||
}
|
||||
|
||||
function getNativeTag(instance: HostInstance): number | null {
|
||||
if (typeof instance !== 'object' || instance === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Modern. Fabric.
|
||||
if (
|
||||
instance.canonical != null &&
|
||||
typeof instance.canonical.nativeTag === 'number'
|
||||
) {
|
||||
return instance.canonical.nativeTag;
|
||||
}
|
||||
|
||||
// Legacy. Paper.
|
||||
if (typeof instance._nativeTag === 'number') {
|
||||
return instance._nativeTag;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function aquireHostInstance(
|
||||
nearestInstance: DevToolsInstance,
|
||||
hostInstance: HostInstance,
|
||||
|
|
@ -4298,6 +4319,11 @@ export function attach(
|
|||
componentLogsEntry = fiberToComponentLogsMap.get(fiber.alternate);
|
||||
}
|
||||
|
||||
let nativeTag = null;
|
||||
if (elementType === ElementTypeHostComponent) {
|
||||
nativeTag = getNativeTag(fiber.stateNode);
|
||||
}
|
||||
|
||||
return {
|
||||
id: fiberInstance.id,
|
||||
|
||||
|
|
@ -4364,6 +4390,8 @@ export function attach(
|
|||
rendererVersion: renderer.version,
|
||||
|
||||
plugins,
|
||||
|
||||
nativeTag,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -4457,6 +4485,8 @@ export function attach(
|
|||
rendererVersion: renderer.version,
|
||||
|
||||
plugins,
|
||||
|
||||
nativeTag: null,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -859,6 +859,8 @@ export function attach(
|
|||
plugins: {
|
||||
stylex: null,
|
||||
},
|
||||
|
||||
nativeTag: null,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -294,6 +294,9 @@ export type InspectedElement = {
|
|||
|
||||
// UI plugins/visualizations for the inspected element.
|
||||
plugins: Plugins,
|
||||
|
||||
// React Native only.
|
||||
nativeTag: number | null,
|
||||
};
|
||||
|
||||
export const InspectElementErrorType = 'error';
|
||||
|
|
|
|||
|
|
@ -239,6 +239,7 @@ export function convertInspectedElementBackendToFrontend(
|
|||
key,
|
||||
errors,
|
||||
warnings,
|
||||
nativeTag,
|
||||
} = inspectedElementBackend;
|
||||
|
||||
const inspectedElement: InspectedElementFrontend = {
|
||||
|
|
@ -273,6 +274,7 @@ export function convertInspectedElementBackendToFrontend(
|
|||
state: hydrateHelper(state),
|
||||
errors,
|
||||
warnings,
|
||||
nativeTag,
|
||||
};
|
||||
|
||||
return inspectedElement;
|
||||
|
|
|
|||
|
|
@ -11,21 +11,25 @@ import * as React from 'react';
|
|||
|
||||
import Badge from './Badge';
|
||||
import ForgetBadge from './ForgetBadge';
|
||||
import NativeTagBadge from './NativeTagBadge';
|
||||
|
||||
import styles from './InspectedElementBadges.css';
|
||||
|
||||
type Props = {
|
||||
hocDisplayNames: null | Array<string>,
|
||||
compiledWithForget: boolean,
|
||||
nativeTag: number | null,
|
||||
};
|
||||
|
||||
export default function InspectedElementBadges({
|
||||
hocDisplayNames,
|
||||
compiledWithForget,
|
||||
nativeTag,
|
||||
}: Props): React.Node {
|
||||
if (
|
||||
!compiledWithForget &&
|
||||
(hocDisplayNames == null || hocDisplayNames.length === 0)
|
||||
(hocDisplayNames == null || hocDisplayNames.length === 0) &&
|
||||
nativeTag === null
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -33,6 +37,7 @@ export default function InspectedElementBadges({
|
|||
return (
|
||||
<div className={styles.Root}>
|
||||
{compiledWithForget && <ForgetBadge indexable={false} />}
|
||||
{nativeTag !== null && <NativeTagBadge nativeTag={nativeTag} />}
|
||||
|
||||
{hocDisplayNames !== null &&
|
||||
hocDisplayNames.map(hocDisplayName => (
|
||||
|
|
|
|||
|
|
@ -54,8 +54,14 @@ export default function InspectedElementView({
|
|||
toggleParseHookNames,
|
||||
symbolicatedSourcePromise,
|
||||
}: Props): React.Node {
|
||||
const {owners, rendererPackageName, rendererVersion, rootType, source} =
|
||||
inspectedElement;
|
||||
const {
|
||||
owners,
|
||||
rendererPackageName,
|
||||
rendererVersion,
|
||||
rootType,
|
||||
source,
|
||||
nativeTag,
|
||||
} = inspectedElement;
|
||||
|
||||
const bridge = useContext(BridgeContext);
|
||||
const store = useContext(StoreContext);
|
||||
|
|
@ -75,6 +81,7 @@ export default function InspectedElementView({
|
|||
<InspectedElementBadges
|
||||
hocDisplayNames={element.hocDisplayNames}
|
||||
compiledWithForget={element.compiledWithForget}
|
||||
nativeTag={nativeTag}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
.Toggle {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.Toggle > span { /* targets .ToggleContent */
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.Badge {
|
||||
cursor: help;
|
||||
}
|
||||
31
packages/react-devtools-shared/src/devtools/views/Components/NativeTagBadge.js
vendored
Normal file
31
packages/react-devtools-shared/src/devtools/views/Components/NativeTagBadge.js
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* 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.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
import Badge from './Badge';
|
||||
import Toggle from '../Toggle';
|
||||
|
||||
import styles from './NativeTagBadge.css';
|
||||
|
||||
type Props = {
|
||||
nativeTag: number,
|
||||
};
|
||||
|
||||
const noop = () => {};
|
||||
const title =
|
||||
'Unique identifier for the corresponding native component. React Native only.';
|
||||
|
||||
export default function NativeTagBadge({nativeTag}: Props): React.Node {
|
||||
return (
|
||||
<Toggle onChange={noop} className={styles.Toggle} title={title}>
|
||||
<Badge className={styles.Badge}>Tag {nativeTag}</Badge>
|
||||
</Toggle>
|
||||
);
|
||||
}
|
||||
|
|
@ -259,6 +259,9 @@ export type InspectedElement = {
|
|||
|
||||
// UI plugins/visualizations for the inspected element.
|
||||
plugins: Plugins,
|
||||
|
||||
// React Native only.
|
||||
nativeTag: number | null,
|
||||
};
|
||||
|
||||
// TODO: Add profiling type
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user