From d897c35ecfb7471b55e41933fd4d993b98dbf600 Mon Sep 17 00:00:00 2001 From: Nick Reiley Date: Mon, 18 May 2020 23:13:16 +0500 Subject: [PATCH] [DevTools] Add Component Highlighting to Profiler (#18745) Co-authored-by: Moji Izadmehr Co-authored-by: Brian Vaughn --- .../views/Profiler/CommitFlamegraph.js | 34 ++++++++++++--- .../Profiler/CommitFlamegraphListItem.js | 7 ++-- .../devtools/views/Profiler/CommitRanked.js | 41 ++++++++++++++++--- .../views/Profiler/CommitRankedListItem.js | 7 ++-- 4 files changed, 71 insertions(+), 18 deletions(-) diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js index 77afddbf040ee..99289ff392f31 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js @@ -16,6 +16,7 @@ import NoCommitData from './NoCommitData'; import CommitFlamegraphListItem from './CommitFlamegraphListItem'; import HoveredFiberInfo from './HoveredFiberInfo'; import {scale} from './utils'; +import {useHighlightNativeElement} from '../hooks'; import {StoreContext} from '../context'; import {SettingsContext} from '../Settings/SettingsContext'; import Tooltip from './Tooltip'; @@ -28,7 +29,8 @@ import type {CommitTree} from './types'; export type ItemData = {| chartData: ChartData, - hoverFiber: (fiberData: TooltipFiberData | null) => void, + onElementMouseEnter: (fiberData: TooltipFiberData) => void, + onElementMouseLeave: () => void, scaleX: (value: number, fallbackValue: number) => number, selectedChartNode: ChartNode | null, selectedChartNodeIndex: number, @@ -96,11 +98,16 @@ type Props = {| |}; function CommitFlamegraph({chartData, commitTree, height, width}: Props) { - const [hoveredFiberData, hoverFiber] = useState( - null, - ); + const [ + hoveredFiberData, + setHoveredFiberData, + ] = useState(null); const {lineHeight} = useContext(SettingsContext); const {selectFiber, selectedFiberID} = useContext(ProfilerContext); + const { + highlightNativeElement, + clearHighlightNativeElement, + } = useHighlightNativeElement(); const selectedChartNodeIndex = useMemo(() => { if (selectedFiberID === null) { @@ -123,10 +130,24 @@ function CommitFlamegraph({chartData, commitTree, height, width}: Props) { return null; }, [chartData, selectedFiberID, selectedChartNodeIndex]); + const handleElementMouseEnter = useCallback( + ({id, name}) => { + highlightNativeElement(id); // Highlight last hovered element. + setHoveredFiberData({id, name}); // Set hovered fiber data for tooltip + }, + [highlightNativeElement], + ); + + const handleElementMouseLeave = useCallback(() => { + clearHighlightNativeElement(); // clear highlighting of element on mouse leave + setHoveredFiberData(null); // clear hovered fiber data for tooltip + }, [clearHighlightNativeElement]); + const itemData = useMemo( () => ({ chartData, - hoverFiber, + onElementMouseEnter: handleElementMouseEnter, + onElementMouseLeave: handleElementMouseLeave, scaleX: scale( 0, selectedChartNode !== null @@ -142,7 +163,8 @@ function CommitFlamegraph({chartData, commitTree, height, width}: Props) { }), [ chartData, - hoverFiber, + handleElementMouseEnter, + handleElementMouseLeave, selectedChartNode, selectedChartNodeIndex, selectFiber, diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js index 5b94c94e2d2d8..35622433e37b5 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js @@ -28,7 +28,8 @@ type Props = { function CommitFlamegraphListItem({data, index, style}: Props) { const { chartData, - hoverFiber, + onElementMouseEnter, + onElementMouseLeave, scaleX, selectedChartNode, selectedChartNodeIndex, @@ -49,11 +50,11 @@ function CommitFlamegraphListItem({data, index, style}: Props) { const handleMouseEnter = (nodeData: ChartNodeType) => { const {id, name} = nodeData; - hoverFiber({id, name}); + onElementMouseEnter({id, name}); }; const handleMouseLeave = () => { - hoverFiber(null); + onElementMouseLeave(); }; // List items are absolutely positioned using the CSS "top" attribute. diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js index 996433dffc282..d02ac1fadd4bf 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js @@ -18,6 +18,7 @@ import HoveredFiberInfo from './HoveredFiberInfo'; import {scale} from './utils'; import {StoreContext} from '../context'; import {SettingsContext} from '../Settings/SettingsContext'; +import {useHighlightNativeElement} from '../hooks'; import Tooltip from './Tooltip'; import styles from './CommitRanked.css'; @@ -28,7 +29,8 @@ import type {CommitTree} from './types'; export type ItemData = {| chartData: ChartData, - hoverFiber: (fiberData: TooltipFiberData | null) => void, + onElementMouseEnter: (fiberData: TooltipFiberData) => void, + onElementMouseLeave: () => void, scaleX: (value: number, fallbackValue: number) => number, selectedFiberID: number | null, selectedFiberIndex: number, @@ -94,28 +96,55 @@ type Props = {| |}; function CommitRanked({chartData, commitTree, height, width}: Props) { - const [hoveredFiberData, hoverFiber] = useState( - null, - ); + const [ + hoveredFiberData, + setHoveredFiberData, + ] = useState(null); const {lineHeight} = useContext(SettingsContext); const {selectedFiberID, selectFiber} = useContext(ProfilerContext); + const { + highlightNativeElement, + clearHighlightNativeElement, + } = useHighlightNativeElement(); const selectedFiberIndex = useMemo( () => getNodeIndex(chartData, selectedFiberID), [chartData, selectedFiberID], ); + const handleElementMouseEnter = useCallback( + ({id, name}) => { + highlightNativeElement(id); // Highlight last hovered element. + setHoveredFiberData({id, name}); // Set hovered fiber data for tooltip + }, + [highlightNativeElement], + ); + + const handleElementMouseLeave = useCallback(() => { + clearHighlightNativeElement(); // clear highlighting of element on mouse leave + setHoveredFiberData(null); // clear hovered fiber data for tooltip + }, [clearHighlightNativeElement]); + const itemData = useMemo( () => ({ chartData, - hoverFiber, + onElementMouseEnter: handleElementMouseEnter, + onElementMouseLeave: handleElementMouseLeave, scaleX: scale(0, chartData.nodes[selectedFiberIndex].value, 0, width), selectedFiberID, selectedFiberIndex, selectFiber, width, }), - [chartData, selectedFiberID, selectedFiberIndex, selectFiber, width], + [ + chartData, + handleElementMouseEnter, + handleElementMouseLeave, + selectedFiberID, + selectedFiberIndex, + selectFiber, + width, + ], ); // Tooltip used to show summary of fiber info on hover diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js index 314c928cc50e9..6b92499eceb31 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js @@ -27,7 +27,8 @@ type Props = { function CommitRankedListItem({data, index, style}: Props) { const { chartData, - hoverFiber, + onElementMouseEnter, + onElementMouseLeave, scaleX, selectedFiberIndex, selectFiber, @@ -49,11 +50,11 @@ function CommitRankedListItem({data, index, style}: Props) { const handleMouseEnter = () => { const {id, name} = node; - hoverFiber({id, name}); + onElementMouseEnter({id, name}); }; const handleMouseLeave = () => { - hoverFiber(null); + onElementMouseLeave(); }; // List items are absolutely positioned using the CSS "top" attribute.