Adds inspectable event components + props

[Flare] Adds inspectable event components + props
This commit is contained in:
Dominic Gannaway
2019-05-23 09:17:37 -07:00
committed by Brian Vaughn
parent e4aa3c5b33
commit 779fd167ff
7 changed files with 144 additions and 0 deletions
@@ -17,6 +17,7 @@ export function print(inspectedElement, serialize, indent) {
id: inspectedElement.id,
owners: inspectedElement.owners,
context: inspectedElement.context,
events: inspectedElement.events,
hooks: inspectedElement.hooks,
props: inspectedElement.props,
state: inspectedElement.state,
+23
View File
@@ -478,6 +478,10 @@ export function attach(
case EVENT_TARGET_TOUCH_HIT_STRING:
return 'TouchHitTarget';
default:
const displayName = elementType.displayName;
if (displayName !== undefined) {
return displayName;
}
return 'EventTarget';
}
case ForwardRef:
@@ -1833,6 +1837,23 @@ export function attach(
const isTimedOutSuspense =
tag === SuspenseComponent && memoizedState !== null;
let events = null;
let node = fiber;
while (node !== null) {
if (node.tag === EventComponent) {
if (events === null) {
events = [];
}
const eventComponentInstance = node.stateNode;
const currentFiber = eventComponentInstance.currentFiber;
events.push({
props: eventComponentInstance.props,
displayName: currentFiber.type.displayName,
});
}
node = node.return;
}
return {
id,
@@ -1858,6 +1879,7 @@ export function attach(
// Inspectable properties.
// TODO Review sanitization approach for the below inspectable values.
context,
events,
hooks: usesHooks
? inspectHooksOfFiber(fiber, (renderer.currentDispatcherRef: any))
: null,
@@ -1879,6 +1901,7 @@ export function attach(
}
// TODO Review sanitization approach for the below inspectable values.
result.context = cleanForBridge(result.context);
result.events = cleanForBridge(result.events);
result.hooks = cleanForBridge(result.hooks);
result.props = cleanForBridge(result.props);
result.state = cleanForBridge(result.state);
@@ -0,0 +1,27 @@
.EventsTree {
padding: 0.25rem;
border-top: 1px solid var(--color-border);
}
.EventsTree:first-of-type {
border-top: none;
}
.HeaderRow {
display: flex;
align-items: center;
}
.Header {
flex: 1 1;
font-family: var(--font-family-sans);
}
.NameValueRow {
display: flex;
}
.Empty {
color: var(--color-dimmer);
font-style: italic;
padding-left: 0.75rem;
}
@@ -0,0 +1,88 @@
import { copy } from 'clipboard-js';
import React, { useCallback, useState } from 'react';
import styles from './EventsTree.css';
import Button from '../Button';
import ButtonIcon from '../ButtonIcon';
import KeyValue from './KeyValue';
import ExpandCollapseToggle from './ExpandCollapseToggle';
import { serializeDataForCopy } from '../utils';
type Props = {|
events: Object,
|};
function EventsTreeView({ events }: Props) {
const handleCopy = useCallback(() => copy(serializeDataForCopy(events)), [
events,
]);
return (
<div className={styles.EventsTree}>
<div className={styles.HeaderRow}>
<div className={styles.Header}>events</div>
{
<Button onClick={handleCopy} title="Copy to clipboard">
<ButtonIcon type="copy" />
</Button>
}
</div>
<InnerEventsTreeView events={events} />
</div>
);
}
function InnerEventsTreeView({ events }: Props) {
return events.map((event, index) => (
<EventComponentView
key={index}
displayName={event.displayName}
props={event.props}
/>
));
}
type EventComponentViewProps = {|
displayName: string,
props: null | Object,
|};
function EventComponentView({ displayName, props }: EventComponentViewProps) {
const [isOpen, setIsOpen] = useState(false);
let eventComponentProps = null;
// eslint-disable-next-line no-unused-vars
let children;
if (props !== null) {
// We don't want children, so extract it out
({ children, ...eventComponentProps } = props);
}
return (
<div>
<div className={styles.NameValueRow}>
<ExpandCollapseToggle isOpen={isOpen} setIsOpen={setIsOpen} />
<span onClick={() => {}} className={styles.Name}>
{displayName}
</span>
</div>
<div className={styles.Children} hidden={!isOpen}>
{eventComponentProps === null && (
<div className={styles.Empty}>None</div>
)}
{eventComponentProps !== null &&
Object.keys((eventComponentProps: any)).map(name => (
<KeyValue
key={name}
depth={1}
name={name}
path={[name]}
value={(eventComponentProps: any)[name]}
/>
))}
</div>
</div>
);
}
// $FlowFixMe
export default React.memo(EventsTreeView);
@@ -90,6 +90,7 @@ function InspectedElementContextController({ children }: Props) {
inspectedElement = (({
...inspectedElement,
context: hydrateHelper(inspectedElement.context),
events: hydrateHelper(inspectedElement.events),
hooks: hydrateHelper(inspectedElement.hooks),
props: hydrateHelper(inspectedElement.props),
state: hydrateHelper(inspectedElement.state),
@@ -6,6 +6,7 @@ import { BridgeContext, StoreContext } from '../context';
import Button from '../Button';
import ButtonIcon from '../ButtonIcon';
import HooksTree from './HooksTree';
import EventsTree from './EventsTree';
import { ModalDialogContext } from '../ModalDialog';
import InspectedElementTree from './InspectedElementTree';
import { InspectedElementContext } from './InspectedElementContext';
@@ -221,6 +222,7 @@ function InspectedElementView({
canEditHooks,
canToggleSuspense,
context,
events,
hooks,
owners,
props,
@@ -297,6 +299,7 @@ function InspectedElementView({
data={context}
overrideValueFn={overrideContextFn}
/>
{events !== null && events.length > 0 && <EventsTree events={events} />}
{ownerID === null && owners !== null && owners.length > 0 && (
<div className={styles.Owners}>
+1
View File
@@ -59,6 +59,7 @@ export type InspectedElement = {|
// Inspectable properties.
context: Object | null,
events: Object | null,
hooks: Object | null,
props: Object | null,
state: Object | null,