From fe43dc8cf234227c77aa7172665a971904687837 Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Thu, 30 Jan 2020 04:12:14 +0100 Subject: [PATCH 01/14] Add highlighting to flame graph --- .../src/devtools/views/Profiler/ChartNode.js | 18 ++++++++++- .../views/Profiler/CommitFlamegraph.js | 32 ++++++++++++++++++- .../Profiler/CommitFlamegraphListItem.js | 21 +++++++++++- 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/ChartNode.js b/packages/react-devtools-shared/src/devtools/views/Profiler/ChartNode.js index 4a85d18fe8478..5d923a2c1f4d9 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/ChartNode.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/ChartNode.js @@ -15,9 +15,12 @@ type Props = {| color: string, height: number, isDimmed?: boolean, + isHovered?: boolean, label: string, onClick: (event: SyntheticMouseEvent<*>) => mixed, onDoubleClick?: (event: SyntheticMouseEvent<*>) => mixed, + onMouseEnter?: (event: SyntheticMouseEvent<*>) => mixed, + onMouseLeave?: (event: SyntheticMouseEvent<*>) => mixed, placeLabelAboveNode?: boolean, textStyle?: Object, width: number, @@ -31,14 +34,25 @@ export default function ChartNode({ color, height, isDimmed = false, + isHovered = false, label, onClick, onDoubleClick, + onMouseEnter, + onMouseLeave, textStyle, width, x, y, }: Props) { + + let opacity = 1; + if (isHovered) { + opacity = 0.75; + } else if (isDimmed) { + opacity = 0.5; + } + return ( {label} @@ -48,9 +62,11 @@ export default function ChartNode({ fill={color} onClick={onClick} onDoubleClick={onDoubleClick} + onMouseEnter={onMouseEnter} + onMouseLeave={onMouseLeave} className={styles.Rect} style={{ - opacity: isDimmed ? 0.5 : 1, + opacity, }} /> {width >= minWidthToDisplay && ( 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 f58d18d5c5c8f..3e64248bfe9f1 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js @@ -14,7 +14,7 @@ import {ProfilerContext} from './ProfilerContext'; import NoCommitData from './NoCommitData'; import CommitFlamegraphListItem from './CommitFlamegraphListItem'; import {scale} from './utils'; -import {StoreContext} from '../context'; +import {BridgeContext, StoreContext} from '../context'; import {SettingsContext} from '../Settings/SettingsContext'; import styles from './CommitFlamegraph.css'; @@ -93,6 +93,8 @@ type Props = {| function CommitFlamegraph({chartData, commitTree, height, width}: Props) { const {lineHeight} = useContext(SettingsContext); const {selectFiber, selectedFiberID} = useContext(ProfilerContext); + const store = useContext(StoreContext); + const bridge = useContext(BridgeContext); const selectedChartNodeIndex = useMemo(() => { if (selectedFiberID === null) { @@ -115,9 +117,37 @@ function CommitFlamegraph({chartData, commitTree, height, width}: Props) { return null; }, [chartData, selectedFiberID, selectedChartNodeIndex]); + + const highlightNativeElement = useCallback( + (id: number) => { + const element = store.getElementByID(id); + const rendererID = store.getRendererIDForElement(id); + if (element !== null && rendererID !== null) { + bridge.send('highlightNativeElement', { + displayName: element.displayName, + hideAfterTimeout: false, + id, + openNativeElementsPanel: false, + rendererID, + scrollIntoView: false, + }); + } + }, + [store, bridge], + ); + + // Highlight last hovered element. + const handleElementMouseEnter = useCallback( + id => { + highlightNativeElement(id); + }, + [ highlightNativeElement], + ); + const itemData = useMemo( () => ({ chartData, + onElementMouseEnter: handleElementMouseEnter, scaleX: scale( 0, selectedChartNode !== null 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 66d2db36962c4..c09483fe01405 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js @@ -7,7 +7,7 @@ * @flow */ -import React, {Fragment, memo, useCallback, useContext} from 'react'; +import React, {Fragment, memo, useCallback, useContext, useState} from 'react'; import {areEqual} from 'react-window'; import {barWidthThreshold} from './constants'; import {getGradientColor} from './utils'; @@ -24,8 +24,11 @@ type Props = { }; function CommitFlamegraphListItem({data, index, style}: Props) { + const [isHovered, setIsHovered] = useState(false); + const { chartData, + onElementMouseEnter, scaleX, selectedChartNode, selectedChartNodeIndex, @@ -43,6 +46,19 @@ function CommitFlamegraphListItem({data, index, style}: Props) { [selectFiber], ); + const handleMouseEnter = (id: number) => { + setIsHovered(true); + + if (id !== null) { + onElementMouseEnter(id); + } + }; + + const handleMouseLeave = (id: number) => { + setIsHovered(false); + }; + + // List items are absolutely positioned using the CSS "top" attribute. // The "left" value will always be 0. // Since height is fixed, and width is based on the node's duration, @@ -101,9 +117,12 @@ function CommitFlamegraphListItem({data, index, style}: Props) { color={color} height={lineHeight} isDimmed={index < selectedChartNodeIndex} + isHovered={isHovered} key={id} label={label} onClick={event => handleClick(event, id, name)} + onMouseEnter={() => handleMouseEnter(id)} + onMouseLeave={() => handleMouseLeave(id)} textStyle={{color: textColor}} width={nodeWidth} x={nodeOffset - selectedNodeOffset} From 0deb55586c196d25ab43bd698da05662d7bae6bb Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Thu, 30 Jan 2020 04:22:10 +0100 Subject: [PATCH 02/14] Add on mouse enter to flame graph props --- .../src/devtools/views/Profiler/CommitFlamegraph.js | 1 + .../src/devtools/views/Profiler/CommitFlamegraphListItem.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) 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 3e64248bfe9f1..a2b5ce231ca13 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js @@ -24,6 +24,7 @@ import type {CommitTree} from './types'; export type ItemData = {| chartData: ChartData, + onElementMouseEnter: (id: number) => void, scaleX: (value: number, fallbackValue: number) => number, selectedChartNode: ChartNode | null, selectedChartNodeIndex: number, 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 c09483fe01405..98b34c93ff1f8 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js @@ -58,7 +58,6 @@ function CommitFlamegraphListItem({data, index, style}: Props) { setIsHovered(false); }; - // List items are absolutely positioned using the CSS "top" attribute. // The "left" value will always be 0. // Since height is fixed, and width is based on the node's duration, From 53a84ce2a8ac84f23c78e74f43f5147a9fcf7691 Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Thu, 30 Jan 2020 04:22:37 +0100 Subject: [PATCH 03/14] Add highlighting to commit ranked profiler --- .../devtools/views/Profiler/CommitRanked.js | 32 ++++++++++++++++++- .../views/Profiler/CommitRankedListItem.js | 21 ++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) 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 f230f67359920..673d6efab7a81 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js @@ -14,7 +14,7 @@ import {ProfilerContext} from './ProfilerContext'; import NoCommitData from './NoCommitData'; import CommitRankedListItem from './CommitRankedListItem'; import {scale} from './utils'; -import {StoreContext} from '../context'; +import {BridgeContext, StoreContext} from '../context'; import {SettingsContext} from '../Settings/SettingsContext'; import styles from './CommitRanked.css'; @@ -24,6 +24,7 @@ import type {CommitTree} from './types'; export type ItemData = {| chartData: ChartData, + onElementMouseEnter: (id: number) => void, scaleX: (value: number, fallbackValue: number) => number, selectedFiberID: number | null, selectedFiberIndex: number, @@ -91,15 +92,44 @@ type Props = {| function CommitRanked({chartData, commitTree, height, width}: Props) { const {lineHeight} = useContext(SettingsContext); const {selectedFiberID, selectFiber} = useContext(ProfilerContext); + const store = useContext(StoreContext); + const bridge = useContext(BridgeContext); const selectedFiberIndex = useMemo( () => getNodeIndex(chartData, selectedFiberID), [chartData, selectedFiberID], ); + const highlightNativeElement = useCallback( + (id: number) => { + const element = store.getElementByID(id); + const rendererID = store.getRendererIDForElement(id); + if (element !== null && rendererID !== null) { + bridge.send('highlightNativeElement', { + displayName: element.displayName, + hideAfterTimeout: false, + id, + openNativeElementsPanel: false, + rendererID, + scrollIntoView: false, + }); + } + }, + [store, bridge], + ); + + // Highlight last hovered element. + const handleElementMouseEnter = useCallback( + id => { + highlightNativeElement(id); + }, + [ highlightNativeElement], + ); + const itemData = useMemo( () => ({ chartData, + onElementMouseEnter: handleElementMouseEnter, scaleX: scale(0, chartData.nodes[selectedFiberIndex].value, 0, width), selectedFiberID, selectedFiberIndex, 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 8c46e7de2730b..8f5aae0ce0c77 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js @@ -7,7 +7,7 @@ * @flow */ -import React, {memo, useCallback, useContext} from 'react'; +import React, {memo, useCallback, useContext, useState} from 'react'; import {areEqual} from 'react-window'; import {minBarWidth} from './constants'; import {getGradientColor} from './utils'; @@ -24,7 +24,9 @@ type Props = { }; function CommitRankedListItem({data, index, style}: Props) { - const {chartData, scaleX, selectedFiberIndex, selectFiber, width} = data; + const [isHovered, setIsHovered] = useState(false); + const {chartData, + onElementMouseEnter, scaleX, selectedFiberIndex, selectFiber, width} = data; const node = chartData.nodes[index]; @@ -38,6 +40,18 @@ function CommitRankedListItem({data, index, style}: Props) { [node, selectFiber], ); + const handleMouseEnter = (id: number) => { + setIsHovered(true); + + if (id !== null) { + onElementMouseEnter(id); + } + }; + + const handleMouseLeave = (id: number) => { + setIsHovered(false); + }; + // List items are absolutely positioned using the CSS "top" attribute. // The "left" value will always be 0. // Since height is fixed, and width is based on the node's duration, @@ -49,9 +63,12 @@ function CommitRankedListItem({data, index, style}: Props) { color={getGradientColor(node.value / chartData.maxValue)} height={lineHeight} isDimmed={index < selectedFiberIndex} + isHovered={isHovered} key={node.id} label={node.label} onClick={handleClick} + onMouseEnter={() => handleMouseEnter(node.id)} + onMouseLeave={() => handleMouseLeave(node. id)} width={Math.max(minBarWidth, scaleX(node.value, width))} x={0} y={top} From d539137433d172d69e3dce9c8fcbd5fb36c69743 Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Thu, 30 Jan 2020 04:25:13 +0100 Subject: [PATCH 04/14] Fix linting --- .../src/devtools/views/Profiler/ChartNode.js | 1 - .../src/devtools/views/Profiler/CommitFlamegraph.js | 5 ++--- .../src/devtools/views/Profiler/CommitRanked.js | 4 ++-- .../devtools/views/Profiler/CommitRankedListItem.js | 12 +++++++++--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/ChartNode.js b/packages/react-devtools-shared/src/devtools/views/Profiler/ChartNode.js index 5d923a2c1f4d9..5df0ceca60fcf 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/ChartNode.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/ChartNode.js @@ -45,7 +45,6 @@ export default function ChartNode({ x, y, }: Props) { - let opacity = 1; if (isHovered) { opacity = 0.75; 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 a2b5ce231ca13..00650254ef576 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js @@ -118,7 +118,6 @@ function CommitFlamegraph({chartData, commitTree, height, width}: Props) { return null; }, [chartData, selectedFiberID, selectedChartNodeIndex]); - const highlightNativeElement = useCallback( (id: number) => { const element = store.getElementByID(id); @@ -140,9 +139,9 @@ function CommitFlamegraph({chartData, commitTree, height, width}: Props) { // Highlight last hovered element. const handleElementMouseEnter = useCallback( id => { - highlightNativeElement(id); + highlightNativeElement(id); }, - [ highlightNativeElement], + [highlightNativeElement], ); const itemData = useMemo( 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 673d6efab7a81..83048bc193c45 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js @@ -121,9 +121,9 @@ function CommitRanked({chartData, commitTree, height, width}: Props) { // Highlight last hovered element. const handleElementMouseEnter = useCallback( id => { - highlightNativeElement(id); + highlightNativeElement(id); }, - [ highlightNativeElement], + [highlightNativeElement], ); const itemData = useMemo( 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 8f5aae0ce0c77..77ba47766d814 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js @@ -25,8 +25,14 @@ type Props = { function CommitRankedListItem({data, index, style}: Props) { const [isHovered, setIsHovered] = useState(false); - const {chartData, - onElementMouseEnter, scaleX, selectedFiberIndex, selectFiber, width} = data; + const { + chartData, + onElementMouseEnter, + scaleX, + selectedFiberIndex, + selectFiber, + width, + } = data; const node = chartData.nodes[index]; @@ -68,7 +74,7 @@ function CommitRankedListItem({data, index, style}: Props) { label={node.label} onClick={handleClick} onMouseEnter={() => handleMouseEnter(node.id)} - onMouseLeave={() => handleMouseLeave(node. id)} + onMouseLeave={() => handleMouseLeave(node.id)} width={Math.max(minBarWidth, scaleX(node.value, width))} x={0} y={top} From 5f66d47c8f34c8f5597a16b410b4fb08ad067ec9 Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Sun, 2 Feb 2020 18:29:44 +0100 Subject: [PATCH 05/14] Create hooks for devtools add and clear highlighting --- .../src/devtools/views/hooks.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/react-devtools-shared/src/devtools/views/hooks.js b/packages/react-devtools-shared/src/devtools/views/hooks.js index a8fb43dd61a12..3253624fd8939 100644 --- a/packages/react-devtools-shared/src/devtools/views/hooks.js +++ b/packages/react-devtools-shared/src/devtools/views/hooks.js @@ -14,12 +14,14 @@ import { useLayoutEffect, useReducer, useState, + useContext, } from 'react'; import { localStorageGetItem, localStorageSetItem, } from 'react-devtools-shared/src/storage'; import {sanitizeForParse, smartParse, smartStringify} from '../utils'; +import {BridgeContext, StoreContext} from './context'; type ACTION_RESET = {| type: 'RESET', @@ -300,3 +302,29 @@ export function useSubscription({ return state.value; } + +// provides highlighting and clearing highlights of elements based on ID +export function useNativeElementHighlighter() { + const store = useContext(StoreContext); + const bridge = useContext(BridgeContext); + + const highlightNativeElement = (id: number) => { + const element = store.getElementByID(id); + const rendererID = store.getRendererIDForElement(id); + if (element !== null && rendererID !== null) { + bridge.send('highlightNativeElement', { + displayName: element.displayName, + hideAfterTimeout: false, + id, + openNativeElementsPanel: false, + rendererID, + scrollIntoView: false, + }); + } + }; + + const clearNativeElementHighlight = () => { + bridge.send('clearNativeElementHighlight'); + }; + return {highlightNativeElement, clearNativeElementHighlight}; +} From c6bcac3e4730c34904b310d276ca83c6e1ae5f26 Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Sun, 2 Feb 2020 18:33:45 +0100 Subject: [PATCH 06/14] Use hooks for highlighting in devtools tree --- .../src/devtools/views/Components/Tree.js | 33 ++++++------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/packages/react-devtools-shared/src/devtools/views/Components/Tree.js b/packages/react-devtools-shared/src/devtools/views/Components/Tree.js index 3b6357ae8535e..4088b910526a1 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/Tree.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/Tree.js @@ -29,7 +29,7 @@ import SearchInput from './SearchInput'; import SettingsModalContextToggle from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContextToggle'; import SelectedTreeHighlight from './SelectedTreeHighlight'; import TreeFocusedContext from './TreeFocusedContext'; - +import {useNativeElementHighlighter} from '../hooks'; import styles from './Tree.css'; // Never indent more than this number of pixels (even if we have the room). @@ -66,6 +66,10 @@ export default function Tree(props: Props) { const [treeFocused, setTreeFocused] = useState(false); const {lineHeight} = useContext(SettingsContext); + const { + highlightNativeElement, + clearNativeElementHighlight, + } = useNativeElementHighlighter(); // Make sure a newly selected element is visible in the list. // This is helpful for things like the owners list and search. @@ -204,24 +208,6 @@ export default function Tree(props: Props) { [dispatch, selectedElementID], ); - const highlightNativeElement = useCallback( - (id: number) => { - const element = store.getElementByID(id); - const rendererID = store.getRendererIDForElement(id); - if (element !== null && rendererID !== null) { - bridge.send('highlightNativeElement', { - displayName: element.displayName, - hideAfterTimeout: false, - id, - openNativeElementsPanel: false, - rendererID, - scrollIntoView: false, - }); - } - }, - [store, bridge], - ); - // If we switch the selected element while using the keyboard, // start highlighting it in the DOM instead of the last hovered node. const searchRef = useRef({searchIndex, searchResults}); @@ -239,11 +225,12 @@ export default function Tree(props: Props) { if (selectedElementID !== null) { highlightNativeElement(selectedElementID); } else { - bridge.send('clearNativeElementHighlight'); + clearNativeElementHighlight() } } }, [ bridge, + clearNativeElementHighlight, isNavigatingWithKeyboard, highlightNativeElement, searchIndex, @@ -269,9 +256,9 @@ export default function Tree(props: Props) { setIsNavigatingWithKeyboard(false); }, []); - const handleMouseLeave = useCallback(() => { - bridge.send('clearNativeElementHighlight'); - }, [bridge]); + const handleMouseLeave = () => { + clearNativeElementHighlight(); + }; // Let react-window know to re-render any time the underlying tree data changes. // This includes the owner context, since it controls a filtered view of the tree. From ed6fe0685aea7eb4f8e5913aab9340c6c9b7fd4e Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Sun, 2 Feb 2020 18:36:05 +0100 Subject: [PATCH 07/14] Use element highlighter hooks in CommitRanked --- .../devtools/views/Profiler/CommitRanked.js | 39 ++++++------------- .../views/Profiler/CommitRankedListItem.js | 6 ++- 2 files changed, 16 insertions(+), 29 deletions(-) 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 83048bc193c45..4c6f46b4ac58a 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js @@ -14,8 +14,9 @@ import {ProfilerContext} from './ProfilerContext'; import NoCommitData from './NoCommitData'; import CommitRankedListItem from './CommitRankedListItem'; import {scale} from './utils'; -import {BridgeContext, StoreContext} from '../context'; +import {StoreContext} from '../context'; import {SettingsContext} from '../Settings/SettingsContext'; +import {useNativeElementHighlighter} from '../hooks'; import styles from './CommitRanked.css'; @@ -92,44 +93,28 @@ type Props = {| function CommitRanked({chartData, commitTree, height, width}: Props) { const {lineHeight} = useContext(SettingsContext); const {selectedFiberID, selectFiber} = useContext(ProfilerContext); - const store = useContext(StoreContext); - const bridge = useContext(BridgeContext); + const {highlightNativeElement, clearNativeElementHighlight} = useNativeElementHighlighter(); const selectedFiberIndex = useMemo( () => getNodeIndex(chartData, selectedFiberID), [chartData, selectedFiberID], ); - const highlightNativeElement = useCallback( - (id: number) => { - const element = store.getElementByID(id); - const rendererID = store.getRendererIDForElement(id); - if (element !== null && rendererID !== null) { - bridge.send('highlightNativeElement', { - displayName: element.displayName, - hideAfterTimeout: false, - id, - openNativeElementsPanel: false, - rendererID, - scrollIntoView: false, - }); - } - }, - [store, bridge], - ); - // Highlight last hovered element. - const handleElementMouseEnter = useCallback( - id => { - highlightNativeElement(id); - }, - [highlightNativeElement], - ); + const handleElementMouseEnter = id => { + highlightNativeElement(id); + }; + + // remove highlighting of element on mouse leave + const handleElementMouseLeave = () => { + clearNativeElementHighlight() + } const itemData = useMemo( () => ({ chartData, onElementMouseEnter: handleElementMouseEnter, + onElementMouseLeave: handleElementMouseLeave, scaleX: scale(0, chartData.nodes[selectedFiberIndex].value, 0, width), selectedFiberID, selectedFiberIndex, 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 77ba47766d814..6f3631a16a644 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js @@ -28,6 +28,7 @@ function CommitRankedListItem({data, index, style}: Props) { const { chartData, onElementMouseEnter, + onElementMouseLeave, scaleX, selectedFiberIndex, selectFiber, @@ -54,8 +55,9 @@ function CommitRankedListItem({data, index, style}: Props) { } }; - const handleMouseLeave = (id: number) => { + const handleMouseLeave = () => { setIsHovered(false); + onElementMouseLeave() }; // List items are absolutely positioned using the CSS "top" attribute. @@ -74,7 +76,7 @@ function CommitRankedListItem({data, index, style}: Props) { label={node.label} onClick={handleClick} onMouseEnter={() => handleMouseEnter(node.id)} - onMouseLeave={() => handleMouseLeave(node.id)} + onMouseLeave={handleMouseLeave} width={Math.max(minBarWidth, scaleX(node.value, width))} x={0} y={top} From c73bd21bfb131995982c0f8a8c3cbad39b9bc16c Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Sun, 2 Feb 2020 18:36:31 +0100 Subject: [PATCH 08/14] Use element highlighter hooks in FlameGraph devtools --- .../views/Profiler/CommitFlamegraph.js | 43 +++++++------------ .../Profiler/CommitFlamegraphListItem.js | 6 ++- 2 files changed, 20 insertions(+), 29 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 00650254ef576..6816b7edcf279 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js @@ -14,7 +14,8 @@ import {ProfilerContext} from './ProfilerContext'; import NoCommitData from './NoCommitData'; import CommitFlamegraphListItem from './CommitFlamegraphListItem'; import {scale} from './utils'; -import {BridgeContext, StoreContext} from '../context'; +import {useNativeElementHighlighter} from '../hooks'; +import {StoreContext} from '../context'; import {SettingsContext} from '../Settings/SettingsContext'; import styles from './CommitFlamegraph.css'; @@ -38,6 +39,7 @@ export default function CommitFlamegraphAutoSizer(_: {||}) { ProfilerContext, ); const {profilingCache} = profilerStore; + const {clearNativeElementHighlight} = useNativeElementHighlighter(); const deselectCurrentFiber = useCallback( event => { @@ -94,8 +96,10 @@ type Props = {| function CommitFlamegraph({chartData, commitTree, height, width}: Props) { const {lineHeight} = useContext(SettingsContext); const {selectFiber, selectedFiberID} = useContext(ProfilerContext); - const store = useContext(StoreContext); - const bridge = useContext(BridgeContext); + const { + highlightNativeElement, + clearNativeElementHighlight, + } = useNativeElementHighlighter(); const selectedChartNodeIndex = useMemo(() => { if (selectedFiberID === null) { @@ -118,36 +122,21 @@ function CommitFlamegraph({chartData, commitTree, height, width}: Props) { return null; }, [chartData, selectedFiberID, selectedChartNodeIndex]); - const highlightNativeElement = useCallback( - (id: number) => { - const element = store.getElementByID(id); - const rendererID = store.getRendererIDForElement(id); - if (element !== null && rendererID !== null) { - bridge.send('highlightNativeElement', { - displayName: element.displayName, - hideAfterTimeout: false, - id, - openNativeElementsPanel: false, - rendererID, - scrollIntoView: false, - }); - } - }, - [store, bridge], - ); - // Highlight last hovered element. - const handleElementMouseEnter = useCallback( - id => { - highlightNativeElement(id); - }, - [highlightNativeElement], - ); + const handleElementMouseEnter = id => { + highlightNativeElement(id); + }; + + // remove highlighting of element on mouse leave + const handleElementMouseLeave = () => { + clearNativeElementHighlight(); + }; const itemData = useMemo( () => ({ chartData, onElementMouseEnter: handleElementMouseEnter, + onElementMouseLeave: handleElementMouseLeave, scaleX: scale( 0, selectedChartNode !== null 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 98b34c93ff1f8..9f23e7475096d 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js @@ -29,6 +29,7 @@ function CommitFlamegraphListItem({data, index, style}: Props) { const { chartData, onElementMouseEnter, + onElementMouseLeave, scaleX, selectedChartNode, selectedChartNodeIndex, @@ -54,8 +55,9 @@ function CommitFlamegraphListItem({data, index, style}: Props) { } }; - const handleMouseLeave = (id: number) => { + const handleMouseLeave = () => { setIsHovered(false); + onElementMouseLeave() }; // List items are absolutely positioned using the CSS "top" attribute. @@ -121,7 +123,7 @@ function CommitFlamegraphListItem({data, index, style}: Props) { label={label} onClick={event => handleClick(event, id, name)} onMouseEnter={() => handleMouseEnter(id)} - onMouseLeave={() => handleMouseLeave(id)} + onMouseLeave={handleMouseLeave} textStyle={{color: textColor}} width={nodeWidth} x={nodeOffset - selectedNodeOffset} From 49ea1567e96fd30170e65a94f3de0e4b81eda758 Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Sun, 2 Feb 2020 18:56:28 +0100 Subject: [PATCH 09/14] Devtools: in Profiler, on mouse leave highlight the clicked element --- .../src/devtools/views/Profiler/CommitFlamegraph.js | 7 +++++-- .../src/devtools/views/Profiler/CommitRanked.js | 6 +++++- 2 files changed, 10 insertions(+), 3 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 6816b7edcf279..d03ef458c9710 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js @@ -39,7 +39,6 @@ export default function CommitFlamegraphAutoSizer(_: {||}) { ProfilerContext, ); const {profilingCache} = profilerStore; - const {clearNativeElementHighlight} = useNativeElementHighlighter(); const deselectCurrentFiber = useCallback( event => { @@ -129,7 +128,11 @@ function CommitFlamegraph({chartData, commitTree, height, width}: Props) { // remove highlighting of element on mouse leave const handleElementMouseLeave = () => { - clearNativeElementHighlight(); + if (selectedFiberID) { + highlightNativeElement(selectedFiberID); + } else { + clearNativeElementHighlight(); + } }; const itemData = useMemo( 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 4c6f46b4ac58a..14df0684a9013 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js @@ -107,7 +107,11 @@ function CommitRanked({chartData, commitTree, height, width}: Props) { // remove highlighting of element on mouse leave const handleElementMouseLeave = () => { - clearNativeElementHighlight() + if (selectedFiberID) { + highlightNativeElement(selectedFiberID); + } else { + clearNativeElementHighlight(); + } } const itemData = useMemo( From ab5b537975e64bea8d0d17c168fa4e7da0e76f72 Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Sun, 2 Feb 2020 19:13:10 +0100 Subject: [PATCH 10/14] Fix linting --- .../src/devtools/views/Components/Tree.js | 2 +- .../devtools/views/Profiler/CommitFlamegraphListItem.js | 2 +- .../src/devtools/views/Profiler/CommitRanked.js | 7 +++++-- .../src/devtools/views/Profiler/CommitRankedListItem.js | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/react-devtools-shared/src/devtools/views/Components/Tree.js b/packages/react-devtools-shared/src/devtools/views/Components/Tree.js index 4088b910526a1..cdbd5d011cadb 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/Tree.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/Tree.js @@ -225,7 +225,7 @@ export default function Tree(props: Props) { if (selectedElementID !== null) { highlightNativeElement(selectedElementID); } else { - clearNativeElementHighlight() + clearNativeElementHighlight(); } } }, [ 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 9f23e7475096d..a81d14628a155 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js @@ -57,7 +57,7 @@ function CommitFlamegraphListItem({data, index, style}: Props) { const handleMouseLeave = () => { setIsHovered(false); - onElementMouseLeave() + 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 14df0684a9013..f850029d47698 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js @@ -93,7 +93,10 @@ type Props = {| function CommitRanked({chartData, commitTree, height, width}: Props) { const {lineHeight} = useContext(SettingsContext); const {selectedFiberID, selectFiber} = useContext(ProfilerContext); - const {highlightNativeElement, clearNativeElementHighlight} = useNativeElementHighlighter(); + const { + highlightNativeElement, + clearNativeElementHighlight, + } = useNativeElementHighlighter(); const selectedFiberIndex = useMemo( () => getNodeIndex(chartData, selectedFiberID), @@ -112,7 +115,7 @@ function CommitRanked({chartData, commitTree, height, width}: Props) { } else { clearNativeElementHighlight(); } - } + }; const itemData = useMemo( () => ({ 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 6f3631a16a644..f8444c6baad42 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js @@ -57,7 +57,7 @@ function CommitRankedListItem({data, index, style}: Props) { const handleMouseLeave = () => { setIsHovered(false); - onElementMouseLeave() + onElementMouseLeave(); }; // List items are absolutely positioned using the CSS "top" attribute. From 0fd63c00f789ce5bc8de6a4cc8b24d665c14682f Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Sun, 2 Feb 2020 22:04:52 +0100 Subject: [PATCH 11/14] Add onMouseLeave flow types --- .../src/devtools/views/Profiler/CommitFlamegraph.js | 1 + .../src/devtools/views/Profiler/CommitRanked.js | 1 + 2 files changed, 2 insertions(+) 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 d03ef458c9710..eb998015869bd 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js @@ -26,6 +26,7 @@ import type {CommitTree} from './types'; export type ItemData = {| chartData: ChartData, onElementMouseEnter: (id: number) => void, + onElementMouseLeave: () => void, scaleX: (value: number, fallbackValue: number) => number, selectedChartNode: ChartNode | null, selectedChartNodeIndex: number, 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 f850029d47698..43440bd540d32 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js @@ -26,6 +26,7 @@ import type {CommitTree} from './types'; export type ItemData = {| chartData: ChartData, onElementMouseEnter: (id: number) => void, + onElementMouseLeave: () => void, scaleX: (value: number, fallbackValue: number) => number, selectedFiberID: number | null, selectedFiberIndex: number, From 2958df7695b9583b0ebf1394b2af990955633a89 Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Wed, 5 Feb 2020 01:02:46 +0100 Subject: [PATCH 12/14] Remove onMouse click highlighting --- .../src/devtools/views/Profiler/CommitFlamegraph.js | 6 +----- .../src/devtools/views/Profiler/CommitRanked.js | 6 +----- 2 files changed, 2 insertions(+), 10 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 eb998015869bd..b8e59ad635121 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js @@ -129,11 +129,7 @@ function CommitFlamegraph({chartData, commitTree, height, width}: Props) { // remove highlighting of element on mouse leave const handleElementMouseLeave = () => { - if (selectedFiberID) { - highlightNativeElement(selectedFiberID); - } else { - clearNativeElementHighlight(); - } + clearNativeElementHighlight(); }; const itemData = useMemo( 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 43440bd540d32..4ecefc44474c5 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitRanked.js @@ -111,11 +111,7 @@ function CommitRanked({chartData, commitTree, height, width}: Props) { // remove highlighting of element on mouse leave const handleElementMouseLeave = () => { - if (selectedFiberID) { - highlightNativeElement(selectedFiberID); - } else { - clearNativeElementHighlight(); - } + clearNativeElementHighlight(); }; const itemData = useMemo( From 0a24f630ac28223f81a96b8b0718228f08fb2cd3 Mon Sep 17 00:00:00 2001 From: Mojtaba Izadmehr Date: Sun, 1 Mar 2020 21:32:08 +0100 Subject: [PATCH 13/14] Merge master to highlighting --- .circleci/config.yml | 23 +- .eslintrc.js | 3 + .github/ISSUE_TEMPLATE/config.yml | 7 + .github/ISSUE_TEMPLATE/documentation.md | 13 - .github/ISSUE_TEMPLATE/question.md | 29 - CHANGELOG.md | 36 +- dangerfile.js | 2 +- fixtures/dom/src/__tests__/nested-act-test.js | 25 +- fixtures/dom/src/__tests__/wrong-act-test.js | 12 +- fixtures/dom/src/components/Header.js | 1 + .../form-state/ControlledFormFixture.js | 60 + .../components/fixtures/form-state/index.js | 60 + package.json | 11 +- .../TransformJSXToReactCreateElement-test.js | 392 -- .../__tests__/TransformJSXToReactJSX-test.js | 372 +- ...nsformJSXToReactCreateElement-test.js.snap | 213 - .../TransformJSXToReactJSX-test.js.snap | 245 + packages/babel-plugin-react-jsx/package.json | 2 +- .../src/TransformJSXToReactBabelPlugin.js | 301 +- packages/create-subscription/package.json | 2 +- .../src/createSubscription.js | 2 +- packages/eslint-plugin-react-hooks/README.md | 11 + .../ESLintRuleExhaustiveDeps-test.js | 5304 ++++++++++------- .../__tests__/ESLintRulesOfHooks-test.js | 21 +- packages/eslint-plugin-react-hooks/index.js | 4 +- .../eslint-plugin-react-hooks/package.json | 2 +- .../src/ExhaustiveDeps.js | 81 +- .../src/RulesOfHooks.js | 70 +- .../eslint-plugin-react-hooks/src/index.js | 10 + packages/jest-react/package.json | 5 +- packages/legacy-events/EventPluginHub.js | 175 - packages/legacy-events/EventPluginRegistry.js | 10 +- packages/legacy-events/EventPropagators.js | 2 +- packages/legacy-events/PluginModuleType.js | 2 +- .../legacy-events/ReactGenericBatching.js | 8 +- .../legacy-events/ReactSyntheticEventType.js | 2 +- .../legacy-events/ResponderEventPlugin.js | 16 +- .../EventPluginRegistry-test.internal.js | 2 +- packages/legacy-events/getListener.js | 74 + packages/react-art/Circle.js | 6 +- packages/react-art/Rectangle.js | 6 +- packages/react-art/Wedge.js | 6 +- packages/react-art/index.js | 6 +- packages/react-art/package.json | 5 +- packages/react-art/src/ReactART.js | 2 +- .../react-art/src/__tests__/ReactART-test.js | 23 +- packages/react-cache/src/ReactCache.js | 2 +- packages/react-debug-tools/index.js | 7 +- packages/react-debug-tools/package.json | 3 +- .../react-debug-tools/src/ReactDebugHooks.js | 16 +- .../ReactHooksInspection-test.internal.js | 5 + .../ReactHooksInspectionIntegration-test.js | 58 + packages/react-devtools-core/src/backend.js | 6 +- .../deploy.edge.html | 8 + .../react-devtools-extensions/edge/README.md | 12 + .../react-devtools-extensions/edge/build.js | 46 + .../react-devtools-extensions/edge/deploy.js | 9 + .../edge/manifest.json | 52 + .../react-devtools-extensions/edge/now.json | 5 + .../react-devtools-extensions/edge/test.js | 29 + .../react-devtools-extensions/package.json | 12 +- .../react-devtools-extensions/src/backend.js | 4 + .../src/injectGlobalHook.js | 2 +- .../react-devtools-extensions/src/main.js | 10 +- packages/react-devtools-inline/src/backend.js | 23 +- .../react-devtools-inline/src/frontend.js | 3 +- .../__tests__/inspectedElementContext-test.js | 99 + .../__tests__/legacy/inspectElement-test.js | 87 + .../src/backend/index.js | 4 + .../src/backend/utils.js | 4 + .../src/devtools/ContextMenu/ContextMenu.js | 9 +- .../devtools/ContextMenu/ContextMenuItem.js | 3 +- .../devtools/ContextMenu/useContextMenu.js | 12 +- .../src/devtools/cache.js | 3 +- .../src/devtools/views/Button.js | 2 +- .../src/devtools/views/ButtonIcon.js | 2 +- .../src/devtools/views/Components/Badge.js | 3 +- .../devtools/views/Components/Components.css | 29 +- .../devtools/views/Components/Components.js | 241 +- .../devtools/views/Components/EditableName.js | 3 +- .../views/Components/EditableValue.js | 24 +- .../src/devtools/views/Components/Element.js | 3 +- .../views/Components/ExpandCollapseToggle.js | 2 +- .../devtools/views/Components/HocBadges.js | 2 +- .../devtools/views/Components/HooksTree.js | 3 +- .../Components/InspectHostNodesToggle.js | 3 +- .../Components/InspectedElementContext.js | 3 +- .../views/Components/InspectedElementTree.js | 3 +- .../src/devtools/views/Components/KeyValue.js | 3 +- .../NativeStyleEditor/AutoSizeInput.js | 3 +- .../NativeStyleEditor/LayoutViewer.js | 2 +- .../NativeStyleEditor/StyleEditor.js | 3 +- .../Components/NativeStyleEditor/context.js | 3 +- .../Components/NativeStyleEditor/index.js | 3 +- .../views/Components/OwnersListContext.js | 3 +- .../devtools/views/Components/OwnersStack.js | 3 +- .../devtools/views/Components/SearchInput.js | 3 +- .../views/Components/SelectedElement.js | 3 +- .../views/Components/SelectedTreeHighlight.js | 3 +- .../src/devtools/views/Components/Tree.js | 3 +- .../devtools/views/Components/TreeContext.js | 3 +- .../src/devtools/views/DevTools.js | 3 +- .../src/devtools/views/ErrorBoundary.js | 3 +- .../src/devtools/views/Icon.js | 2 +- .../src/devtools/views/ModalDialog.js | 3 +- .../src/devtools/views/Profiler/ChartNode.js | 7 +- .../Profiler/ClearProfilingDataButton.js | 3 +- .../views/Profiler/CommitFlamegraph.js | 59 +- .../Profiler/CommitFlamegraphListItem.js | 21 +- .../devtools/views/Profiler/CommitRanked.js | 51 +- .../views/Profiler/CommitRankedListItem.js | 20 +- .../views/Profiler/HoveredFiberInfo.css | 36 + .../views/Profiler/HoveredFiberInfo.js | 78 + .../views/Profiler/InteractionListItem.js | 3 +- .../devtools/views/Profiler/Interactions.js | 3 +- .../devtools/views/Profiler/NoCommitData.js | 2 +- .../devtools/views/Profiler/NoInteractions.js | 2 +- .../src/devtools/views/Profiler/Profiler.js | 3 +- .../views/Profiler/ProfilerContext.js | 9 +- .../Profiler/ProfilingImportExportButtons.js | 3 +- .../devtools/views/Profiler/RecordToggle.js | 3 +- .../views/Profiler/ReloadAndProfileButton.js | 3 +- .../devtools/views/Profiler/RootSelector.js | 3 +- .../views/Profiler/SidebarCommitInfo.js | 3 +- .../views/Profiler/SidebarInteractions.js | 3 +- .../Profiler/SidebarSelectedFiberInfo.css | 21 +- .../Profiler/SidebarSelectedFiberInfo.js | 138 +- .../views/Profiler/SnapshotCommitList.js | 3 +- .../views/Profiler/SnapshotCommitListItem.js | 3 +- .../views/Profiler/SnapshotSelector.js | 3 +- .../src/devtools/views/Profiler/Tooltip.css | 24 + .../src/devtools/views/Profiler/Tooltip.js | 103 + .../devtools/views/Profiler/WhatChanged.css | 29 + .../devtools/views/Profiler/WhatChanged.js | 137 + .../src/devtools/views/Profiler/utils.js | 11 - .../src/devtools/views/ReactLogo.js | 2 +- .../views/Settings/ComponentsSettings.js | 3 +- .../views/Settings/GeneralSettings.js | 3 +- .../views/Settings/ProfilerSettings.js | 3 +- .../views/Settings/SettingsContext.js | 3 +- .../devtools/views/Settings/SettingsModal.js | 9 +- .../views/Settings/SettingsModalContext.js | 3 +- .../Settings/SettingsModalContextToggle.js | 3 +- .../src/devtools/views/TabBar.js | 3 +- .../src/devtools/views/Toggle.js | 3 +- .../views/UnsupportedVersionDialog.js | 3 +- .../views/WarnIfLegacyBackendDetected.js | 3 +- .../src/devtools/views/portaledContent.js | 2 +- .../react-window/src/createGridComponent.js | 3 +- .../react-window/src/createListComponent.js | 3 +- .../src/app/DeeplyNestedComponents/index.js | 3 +- .../src/app/EditableProps/index.js | 3 +- .../src/app/ElementTypes/index.js | 3 +- .../src/app/Hydration/index.js | 3 +- .../src/app/Iframe/index.js | 5 +- .../InspectableElements/CircularReferences.js | 2 +- .../src/app/InspectableElements/Contexts.js | 3 +- .../app/InspectableElements/CustomHooks.js | 3 +- .../app/InspectableElements/CustomObject.js | 2 +- .../InspectableElements/EdgeCaseObjects.js | 2 +- .../InspectableElements.js | 3 +- .../app/InspectableElements/NestedProps.js | 2 +- .../app/InspectableElements/SimpleValues.js | 3 +- .../UnserializableProps.js | 5 +- .../src/app/InteractionTracing/index.js | 3 +- .../src/app/PriorityLevels/index.js | 3 +- .../src/app/ReactNativeWeb/index.js | 4 +- .../src/app/SuspenseTree/index.js | 3 +- .../src/app/ToDoList/List.js | 3 +- .../src/app/ToDoList/ListItem.js | 3 +- .../src/app/Toggle/index.js | 3 +- packages/react-dom/index.classic.fb.js | 46 + packages/react-dom/index.experimental.js | 34 + packages/react-dom/index.fb.js | 14 - packages/react-dom/index.js | 8 +- packages/react-dom/index.modern.fb.js | 22 + packages/react-dom/index.stable.js | 24 + packages/react-dom/npm/testing.js | 38 + packages/react-dom/package.json | 5 +- packages/react-dom/server.browser.js | 14 +- packages/react-dom/server.js | 4 +- packages/react-dom/server.node.js | 15 +- ...-test.js => InvalidEventListeners-test.js} | 2 +- .../ReactBrowserEventEmitter-test.internal.js | 45 +- .../__tests__/ReactCompositeComponent-test.js | 37 - .../src/__tests__/ReactDOMComponent-test.js | 47 - .../src/__tests__/ReactDOMFiber-test.js | 4 +- .../src/__tests__/ReactDOMRoot-test.js | 30 + ...DOMServerPartialHydration-test.internal.js | 196 +- ...MServerSelectiveHydration-test.internal.js | 451 +- ...tDOMShorthandCSSPropertyCollision-test.js} | 3 - .../__tests__/ReactFunctionComponent-test.js | 2 +- .../src/__tests__/ReactTestUtils-test.js | 20 +- .../src/__tests__/ReactTestUtilsAct-test.js | 1 + .../renderSubtreeIntoContainer-test.js | 22 +- packages/react-dom/src/client/ReactDOM.js | 187 +- .../src/client/ReactDOMClientInjection.js | 27 +- .../react-dom/src/client/ReactDOMComponent.js | 37 +- packages/react-dom/src/client/ReactDOMFB.js | 42 - .../src/client/ReactDOMHostConfig.js | 53 +- .../react-dom/src/client/ReactDOMLegacy.js | 17 +- .../react-dom/src/client/ReactDOMOption.js | 2 +- packages/react-dom/src/client/ReactDOMRoot.js | 47 +- .../src/events/DOMEventListenerMap.js | 31 + .../src/events/DOMEventPluginOrder.js | 26 - .../src/events/DOMLegacyEventPluginSystem.js | 381 ++ .../src/events/ReactBrowserEventEmitter.js | 203 - .../src/events/ReactDOMEventListener.js | 211 +- .../src/events/ReactDOMEventReplaying.js | 50 +- .../react-dom/src/events/SelectEventPlugin.js | 11 +- .../ChangeEventPlugin-test.internal.js | 1 + ...edDOMEventResponderSystem-test.internal.js | 5 + .../src/server/ReactDOMFizzServerBrowser.js | 4 +- .../src/server/ReactDOMFizzServerNode.js | 4 +- .../src/server/ReactDOMServerBrowser.js | 5 +- .../src/server/ReactDOMServerNode.js | 5 +- .../src/server/ReactPartialRenderer.js | 2 +- .../src/server/ReactPartialRendererContext.js | 13 +- packages/react-dom/src/shared/DOMProperty.js | 2 +- .../shared/ReactControlledValuePropTypes.js | 2 +- packages/react-dom/src/shared/checkReact.js | 2 +- .../src/test-utils/ReactTestUtils.js | 473 +- .../src/test-utils/ReactTestUtilsAct.js | 2 +- .../ReactDOMUnstableNativeDependencies.js | 2 +- packages/react-dom/test-utils.js | 8 +- packages/react-dom/testing.classic.fb.js | 11 + packages/react-dom/testing.experimental.js | 11 + packages/react-dom/testing.js | 11 + packages/react-dom/testing.modern.fb.js | 11 + packages/react-dom/testing.stable.js | 11 + packages/react-dom/unstable-fizz.browser.js | 8 +- packages/react-dom/unstable-fizz.js | 4 +- packages/react-dom/unstable-fizz.node.js | 8 +- .../react-dom/unstable-native-dependencies.js | 4 +- packages/react-flight-dom-webpack/index.js | 8 +- .../server.browser.js | 9 +- packages/react-flight-dom-webpack/server.js | 4 +- .../react-flight-dom-webpack/server.node.js | 8 +- .../src/ReactFlightDOMClient.js | 6 +- .../src/ReactFlightDOMServerBrowser.js | 4 +- .../src/ReactFlightDOMServerNode.js | 4 +- packages/react-flight/index.js | 8 +- packages/react-flight/package.json | 3 +- .../react-interactions/events/context-menu.js | 4 +- packages/react-interactions/events/focus.js | 4 +- packages/react-interactions/events/hover.js | 4 +- packages/react-interactions/events/input.js | 4 +- .../react-interactions/events/keyboard.js | 4 +- .../react-interactions/events/press-legacy.js | 4 +- packages/react-interactions/events/press.js | 4 +- .../events/src/dom/ContextMenu.js | 2 +- .../events/src/dom/Focus.js | 17 +- .../events/src/dom/Hover.js | 2 +- .../events/src/dom/Input.js | 2 +- .../events/src/dom/Keyboard.js | 2 +- .../events/src/dom/Press.js | 2 +- .../events/src/dom/PressLegacy.js | 19 +- .../react-interactions/events/src/dom/Tap.js | 2 +- .../__tests__/ContextMenu-test.internal.js | 5 + .../src/dom/__tests__/Focus-test.internal.js | 5 + .../__tests__/FocusWithin-test.internal.js | 69 + .../src/dom/__tests__/Hover-test.internal.js | 5 + .../src/dom/__tests__/Input-test.internal.js | 5 + .../dom/__tests__/Keyboard-test.internal.js | 5 + .../MixedResponders-test-internal.js | 5 + .../src/dom/__tests__/Press-test.internal.js | 5 + .../__tests__/PressLegacy-test.internal.js | 28 + .../src/dom/__tests__/Tap-test.internal.js | 5 + packages/react-interactions/events/tap.js | 4 +- packages/react-is/package.json | 2 +- .../react-is/src/__tests__/ReactIs-test.js | 4 +- packages/react-native-renderer/fabric.js | 12 +- packages/react-native-renderer/index.js | 12 +- packages/react-native-renderer/package.json | 1 - .../src/NativeMethodsMixin.js | 330 - .../react-native-renderer/src/ReactFabric.js | 147 +- .../src/ReactFabricComponentTree.js | 20 +- .../src/ReactFabricEventEmitter.js | 77 +- .../src/ReactFabricHostConfig.js | 8 +- .../src/ReactNativeBridgeEventPlugin.js | 3 - .../src/ReactNativeComponent.js | 289 - .../src/ReactNativeComponentTree.js | 25 +- .../src/ReactNativeEventEmitter.js | 78 +- .../src/ReactNativeFiberHostComponent.js | 22 +- .../src/ReactNativeHostConfig.js | 9 +- .../src/ReactNativeInjectionShared.js | 9 +- .../src/ReactNativeRenderer.js | 155 +- .../src/ReactNativeTypes.js | 41 +- .../Libraries/ReactPrivate/TextInputState.js | 5 +- .../__tests__/ReactFabric-test.internal.js | 513 +- .../ReactNativeEvents-test.internal.js | 79 - .../ReactNativeMount-test.internal.js | 417 +- packages/react-noop-renderer/flight-client.js | 8 +- packages/react-noop-renderer/flight-server.js | 8 +- packages/react-noop-renderer/index.js | 8 +- packages/react-noop-renderer/package.json | 1 - packages/react-noop-renderer/persistent.js | 8 +- packages/react-noop-renderer/server.js | 8 +- packages/react-noop-renderer/src/ReactNoop.js | 33 +- .../src/ReactNoopFlightClient.js | 4 +- .../src/ReactNoopFlightServer.js | 4 +- .../src/ReactNoopPersistent.js | 33 +- .../src/ReactNoopServer.js | 4 +- .../src/createReactNoop.js | 209 +- packages/react-reconciler/index.js | 8 +- packages/react-reconciler/package.json | 5 +- packages/react-reconciler/persistent.js | 6 +- .../react-reconciler/src/ReactChildFiber.js | 69 +- .../react-reconciler/src/ReactCurrentFiber.js | 12 +- packages/react-reconciler/src/ReactFiber.js | 43 +- .../src/ReactFiberBeginWork.js | 125 +- .../src/ReactFiberClassComponent.js | 12 +- .../src/ReactFiberCommitWork.js | 282 +- .../src/ReactFiberCompleteWork.js | 8 +- .../react-reconciler/src/ReactFiberContext.js | 30 +- .../src/ReactFiberExpirationTime.js | 18 +- .../react-reconciler/src/ReactFiberHooks.js | 48 +- .../src/ReactFiberHydrationContext.js | 5 - .../src/ReactFiberReconciler.js | 200 +- .../react-reconciler/src/ReactFiberThrow.js | 3 - .../src/ReactFiberWorkLoop.js | 383 +- .../src/ReactHookEffectTags.js | 16 +- .../react-reconciler/src/ReactUpdateQueue.js | 1 - ...eactChunks-test.js => ReactBlocks-test.js} | 12 +- .../ReactExpiration-test.internal.js | 4 +- .../ReactFiberFundamental-test.internal.js | 5 + .../src/__tests__/ReactHooks-test.internal.js | 31 +- ...eactHooksWithNoopRenderer-test.internal.js | 5222 ++++++++-------- ...tIncrementalErrorHandling-test.internal.js | 61 +- .../ReactIncrementalUpdates-test.internal.js | 114 +- .../src/__tests__/ReactMemo-test.internal.js | 69 + .../src/__tests__/ReactScope-test.internal.js | 5 + ...tSuspenseWithNoopRenderer-test.internal.js | 5304 +++++++++-------- packages/react-refresh/babel.js | 7 +- packages/react-refresh/package.json | 2 +- packages/react-refresh/runtime.js | 7 +- packages/react-server/flight.js | 8 +- packages/react-server/index.js | 8 +- packages/react-server/package.json | 3 +- .../src/ReactDOMServerFormatConfig.js | 4 +- packages/react-test-renderer/index.js | 8 +- packages/react-test-renderer/npm/shallow.js | 6 +- packages/react-test-renderer/package.json | 6 +- packages/react-test-renderer/shallow.js | 8 +- .../src/ReactShallowRenderer.js | 859 --- .../src/ReactTestRenderer.js | 258 +- .../src/ReactTestRendererAct.js | 204 - .../__tests__/ReactShallowRenderer-test.js | 16 +- .../ReactShallowRendererHooks-test.js | 12 +- .../ReactShallowRendererMemo-test.js | 16 +- .../ReactTestRenderer-test.internal.js | 10 + packages/react/index.classic.fb.js | 55 + packages/react/index.experimental.js | 46 + packages/react/index.js | 76 +- packages/react/index.modern.fb.js | 54 + packages/react/index.stable.js | 39 + packages/react/package.json | 5 +- packages/react/src/React.js | 141 +- packages/react/src/ReactChildren.js | 18 +- packages/react/src/ReactElementValidator.js | 32 +- .../react/src/__tests__/ReactElement-test.js | 6 +- .../ReactElementJSX-test.internal.js | 16 +- .../ReactElementValidator-test.internal.js | 3 +- .../src/__tests__/ReactStrictMode-test.js | 4 + ...eateReactClassIntegration-test.internal.js | 74 - packages/react/src/{chunk.js => block.js} | 24 +- packages/scheduler/package.json | 2 +- .../scheduler/src/__tests__/Scheduler-test.js | 10 +- .../src/forks/SchedulerHostConfig.mock.js | 11 +- packages/shared/ReactFeatureFlags.js | 50 +- packages/shared/ReactSharedInternals.js | 4 +- packages/shared/ReactSymbols.js | 2 +- packages/shared/ReactVersion.js | 4 +- packages/shared/ReactWorkTags.js | 2 +- packages/shared/checkPropTypes.js | 80 + packages/shared/enqueueTask.js | 66 +- .../forks/ReactFeatureFlags.native-fb.js | 28 +- .../forks/ReactFeatureFlags.native-oss.js | 24 +- .../forks/ReactFeatureFlags.persistent.js | 24 +- .../forks/ReactFeatureFlags.test-renderer.js | 24 +- .../ReactFeatureFlags.test-renderer.www.js | 24 +- .../shared/forks/ReactFeatureFlags.testing.js | 59 + .../forks/ReactFeatureFlags.testing.www.js | 59 + .../shared/forks/ReactFeatureFlags.www.js | 37 +- packages/shared/forks/Scheduler.umd.js | 2 +- packages/shared/forks/SchedulerTracing.umd.js | 2 +- .../shared/forks/object-assign.inline-umd.js | 31 + packages/shared/forks/object-assign.umd.js | 2 +- packages/shared/getComponentName.js | 4 +- packages/shared/isValidElementType.js | 4 +- packages/use-subscription/package.json | 2 +- .../babel/transform-object-assign-require.js | 8 + scripts/error-codes/codes.json | 9 +- scripts/error-codes/extract-errors.js | 4 +- scripts/flow/config/flowconfig | 1 + scripts/flow/react-native-host-hooks.js | 1 - scripts/jest/config.source-persistent.js | 21 + scripts/jest/config.source.js | 21 + scripts/release/README.md | 83 +- scripts/release/ci-add-build-info-json.js | 2 +- scripts/release/ci-update-package-versions.js | 4 +- .../add-build-info-json.js | 0 .../build-artifacts.js | 0 .../confirm-automated-testing.js | 2 +- .../copy-repo-to-temp-directory.js | 0 .../npm-pack-and-unpack.js | 0 .../update-version-numbers.js | 4 +- .../{create-canary.js => create-next.js} | 14 +- .../{prepare-canary.js => prepare-next.js} | 0 .../check-out-packages.js | 4 +- ...-version.js => get-latest-next-version.js} | 4 +- .../prepare-stable-commands/parse-params.js | 2 +- .../update-stable-version-numbers.js | 10 +- scripts/release/prepare-stable.js | 4 +- .../download-error-codes-from-ci.js | 7 +- .../print-follow-up-instructions.js | 4 +- .../update-stable-version-numbers.js | 2 +- .../release/publish-commands/validate-tags.js | 8 +- .../download-build-artifacts.js | 4 +- .../print-prerelease-summary.js | 2 +- scripts/release/snapshot-test.js | 6 +- scripts/release/utils.js | 19 +- scripts/rollup/build.js | 107 +- scripts/rollup/bundles.js | 86 +- scripts/rollup/forks.js | 50 +- scripts/rollup/modules.js | 6 +- scripts/rollup/plugins/closure-plugin.js | 2 +- scripts/rollup/plugins/sizes-plugin.js | 14 +- .../rollup/plugins/strip-unused-imports.js | 2 +- .../shims/react-native/NativeMethodsMixin.js | 21 - .../shims/react-native/ReactFeatureFlags.js | 1 - scripts/rollup/validate/eslintrc.umd.js | 1 + scripts/rollup/wrappers.js | 57 +- scripts/shared/__tests__/evalToString-test.js | 5 +- scripts/shared/inlinedHostConfigs.js | 1 + scripts/tasks/version-check.js | 9 +- yarn.lock | 246 +- 437 files changed, 16619 insertions(+), 14276 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/documentation.md delete mode 100644 .github/ISSUE_TEMPLATE/question.md create mode 100644 fixtures/dom/src/components/fixtures/form-state/ControlledFormFixture.js create mode 100644 fixtures/dom/src/components/fixtures/form-state/index.js delete mode 100644 packages/babel-plugin-react-jsx/__tests__/TransformJSXToReactCreateElement-test.js delete mode 100644 packages/babel-plugin-react-jsx/__tests__/__snapshots__/TransformJSXToReactCreateElement-test.js.snap delete mode 100644 packages/legacy-events/EventPluginHub.js create mode 100644 packages/legacy-events/getListener.js create mode 100644 packages/react-devtools-extensions/deploy.edge.html create mode 100644 packages/react-devtools-extensions/edge/README.md create mode 100644 packages/react-devtools-extensions/edge/build.js create mode 100644 packages/react-devtools-extensions/edge/deploy.js create mode 100644 packages/react-devtools-extensions/edge/manifest.json create mode 100644 packages/react-devtools-extensions/edge/now.json create mode 100644 packages/react-devtools-extensions/edge/test.js create mode 100644 packages/react-devtools-shared/src/devtools/views/Profiler/HoveredFiberInfo.css create mode 100644 packages/react-devtools-shared/src/devtools/views/Profiler/HoveredFiberInfo.js create mode 100644 packages/react-devtools-shared/src/devtools/views/Profiler/Tooltip.css create mode 100644 packages/react-devtools-shared/src/devtools/views/Profiler/Tooltip.js create mode 100644 packages/react-devtools-shared/src/devtools/views/Profiler/WhatChanged.css create mode 100644 packages/react-devtools-shared/src/devtools/views/Profiler/WhatChanged.js create mode 100644 packages/react-dom/index.classic.fb.js create mode 100644 packages/react-dom/index.experimental.js delete mode 100644 packages/react-dom/index.fb.js create mode 100644 packages/react-dom/index.modern.fb.js create mode 100644 packages/react-dom/index.stable.js create mode 100644 packages/react-dom/npm/testing.js rename packages/react-dom/src/__tests__/{EventPluginHub-test.js => InvalidEventListeners-test.js} (96%) rename packages/react-dom/src/__tests__/{ReactDOMShorthandCSSPropertyCollision-test.internal.js => ReactDOMShorthandCSSPropertyCollision-test.js} (97%) delete mode 100644 packages/react-dom/src/client/ReactDOMFB.js create mode 100644 packages/react-dom/src/events/DOMEventListenerMap.js delete mode 100644 packages/react-dom/src/events/DOMEventPluginOrder.js create mode 100644 packages/react-dom/src/events/DOMLegacyEventPluginSystem.js delete mode 100644 packages/react-dom/src/events/ReactBrowserEventEmitter.js create mode 100644 packages/react-dom/testing.classic.fb.js create mode 100644 packages/react-dom/testing.experimental.js create mode 100644 packages/react-dom/testing.js create mode 100644 packages/react-dom/testing.modern.fb.js create mode 100644 packages/react-dom/testing.stable.js delete mode 100644 packages/react-native-renderer/src/NativeMethodsMixin.js delete mode 100644 packages/react-native-renderer/src/ReactNativeComponent.js rename packages/react-reconciler/src/__tests__/{ReactChunks-test.js => ReactBlocks-test.js} (95%) delete mode 100644 packages/react-test-renderer/src/ReactShallowRenderer.js delete mode 100644 packages/react-test-renderer/src/ReactTestRendererAct.js create mode 100644 packages/react/index.classic.fb.js create mode 100644 packages/react/index.experimental.js create mode 100644 packages/react/index.modern.fb.js create mode 100644 packages/react/index.stable.js delete mode 100644 packages/react/src/__tests__/createReactClassIntegration-test.internal.js rename packages/react/src/{chunk.js => block.js} (74%) create mode 100644 packages/shared/checkPropTypes.js create mode 100644 packages/shared/forks/ReactFeatureFlags.testing.js create mode 100644 packages/shared/forks/ReactFeatureFlags.testing.www.js create mode 100644 packages/shared/forks/object-assign.inline-umd.js rename scripts/release/{create-canary-commands => create-next-commands}/add-build-info-json.js (100%) rename scripts/release/{create-canary-commands => create-next-commands}/build-artifacts.js (100%) rename scripts/release/{create-canary-commands => create-next-commands}/confirm-automated-testing.js (85%) rename scripts/release/{create-canary-commands => create-next-commands}/copy-repo-to-temp-directory.js (100%) rename scripts/release/{create-canary-commands => create-next-commands}/npm-pack-and-unpack.js (100%) rename scripts/release/{create-canary-commands => create-next-commands}/update-version-numbers.js (63%) rename scripts/release/{create-canary.js => create-next.js} (67%) rename scripts/release/{prepare-canary.js => prepare-next.js} (100%) rename scripts/release/prepare-stable-commands/{get-latest-canary-version.js => get-latest-next-version.js} (59%) delete mode 100644 scripts/rollup/shims/react-native/NativeMethodsMixin.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 584f8c111327e..ea8f6458f96bb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,9 +11,9 @@ aliases: restore_cache: name: Restore node_modules cache keys: - - v1-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} - - v1-node-{{ arch }}-{{ .Branch }}- - - v1-node-{{ arch }}- + - v2-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} + - v2-node-{{ arch }}-{{ .Branch }}- + - v2-node-{{ arch }}- - &run_yarn run: name: Install Packages @@ -62,7 +62,7 @@ jobs: - *run_yarn - save_cache: name: Save node_modules cache - key: v1-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} + key: v2-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} paths: - ~/.cache/yarn @@ -141,6 +141,18 @@ jobs: RELEASE_CHANNEL: stable command: yarn test-prod --maxWorkers=2 + test_source_prod_experimental: + docker: *docker + environment: *environment + steps: + - checkout + - *restore_yarn_cache + - *run_yarn + - run: + environment: + RELEASE_CHANNEL: experimental + command: yarn test-prod --maxWorkers=2 + build: docker: *docker environment: *environment @@ -400,6 +412,9 @@ workflows: - test_source_experimental: requires: - setup + - test_source_prod_experimental: + requires: + - setup - build_experimental: requires: - setup diff --git a/.eslintrc.js b/.eslintrc.js index 74b87ab13a679..b10d30525c198 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,6 +5,8 @@ const { esNextPaths, } = require('./scripts/shared/pathsByLanguageVersion'); +const restrictedGlobals = require('confusing-browser-globals'); + const OFF = 0; const ERROR = 2; @@ -45,6 +47,7 @@ module.exports = { 'no-bitwise': OFF, 'no-inner-declarations': [ERROR, 'functions'], 'no-multi-spaces': ERROR, + 'no-restricted-globals': [ERROR].concat(restrictedGlobals), 'no-restricted-syntax': [ERROR, 'WithStatement'], 'no-shadow': ERROR, 'no-unused-expressions': ERROR, diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000000..e5bb31b2b3787 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,7 @@ +contact_links: + - name: 📃 Documentation Issue + url: https://github.com/reactjs/reactjs.org/issues/new + about: This issue tracker is not for documentation issues. Please file documentation issues here. + - name: 🤔 Questions and Help + url: https://reactjs.org/community/support.html + about: This issue tracker is not for support questions. Please refer to the React community's help and discussion forums. diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md deleted file mode 100644 index 57c380e2ac97a..0000000000000 --- a/.github/ISSUE_TEMPLATE/documentation.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -name: "📃 Documentation Issue" -about: This issue tracker is not for documentation issues. Please file documentation issues at https://github.com/reactjs/reactjs.org. -title: 'Docs: ' -labels: 'Resolution: Invalid' - ---- - -🚨 This issue tracker is not for documentation issues. 🚨 - -The React website is hosted on a separate repository. You may let the -team know about any issues with the documentation by opening an issue there: -- https://github.com/reactjs/reactjs.org/issues/new diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md deleted file mode 100644 index 0131925d2c7a3..0000000000000 --- a/.github/ISSUE_TEMPLATE/question.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: "🤔 Questions and Help" -about: This issue tracker is not for questions. Please ask questions at https://stackoverflow.com/questions/tagged/react. -title: 'Question: ' -labels: 'Resolution: Invalid, Type: Question' - ---- - -🚨 This issue tracker is not for questions. 🚨 - -As it happens, support requests that are created as issues are likely to be closed. We want to make sure you are able to find the help you seek. Please take a look at the following resources. - -## Coding Questions - -If you have a coding question related to React and React DOM, it might be better suited for Stack Overflow. It's a great place to browse through frequent questions about using React, as well as ask for help with specific questions. - -https://stackoverflow.com/questions/tagged/react - -## Talk to other React developers - -There are many online forums which are a great place for discussion about best practices and application architecture as well as the future of React. - -https://reactjs.org/community/support.html#popular-discussion-forums - -## Proposals - -If you'd like to discuss topics related to the future of React, or would like to propose a new feature or change before sending a pull request, please check out the discussions and proposals repository. - -https://github.com/reactjs/rfcs diff --git a/CHANGELOG.md b/CHANGELOG.md index e8eb19c9d8927..9dc7136ed8481 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,32 @@ -## [Unreleased] -
- - Changes that have landed in master but are not yet released. - Click to see more. - -
+## 16.13.0 (February 26, 2020) + +### React + +* Warn when a string ref is used in a manner that's not amenable to a future codemod ([@lunaruan](https://github.com/lunaruan) in [#17864](https://github.com/facebook/react/pull/17864)) +* Deprecate `React.createFactory()` ([@trueadm](https://github.com/trueadm) in [#17878](https://github.com/facebook/react/pull/17878)) + +### React DOM + +* Warn when changes in `style` may cause an unexpected collision ([@sophiebits](https://github.com/sophiebits) in [#14181](https://github.com/facebook/react/pull/14181), [#18002](https://github.com/facebook/react/pull/18002)) +* Warn when a function component is updated during another component's render phase ([@acdlite](https://github.com/acdlite) in [#17099](https://github.com/facebook/react/pull/17099)) +* Deprecate `unstable_createPortal` ([@trueadm](https://github.com/trueadm) in [#17880](https://github.com/facebook/react/pull/17880)) +* Fix `onMouseEnter` being fired on disabled buttons ([@AlfredoGJ](https://github.com/AlfredoGJ) in [#17675](https://github.com/facebook/react/pull/17675)) +* Call `shouldComponentUpdate` twice when developing in `StrictMode` ([@bvaughn](https://github.com/bvaughn) in [#17942](https://github.com/facebook/react/pull/17942)) +* Add `version` property to ReactDOM ([@ealush](https://github.com/ealush) in [#15780](https://github.com/facebook/react/pull/15780)) +* Don't call `toString()` of `dangerouslySetInnerHTML` ([@sebmarkbage](https://github.com/sebmarkbage) in [#17773](https://github.com/facebook/react/pull/17773)) +* Show component stacks in more warnings ([@gaearon](https://github.com/gaearon) in [#17922](https://github.com/facebook/react/pull/17922), [#17586](https://github.com/facebook/react/pull/17586)) + +### Concurrent Mode (Experimental) + +* Warn for problematic usages of `ReactDOM.createRoot()` ([@trueadm](https://github.com/trueadm) in [#17937](https://github.com/facebook/react/pull/17937)) +* Remove `ReactDOM.createRoot()` callback params and added warnings on usage ([@bvaughn](https://github.com/bvaughn) in [#17916](https://github.com/facebook/react/pull/17916)) +* Don't group Idle/Offscreen work with other work ([@sebmarkbage](https://github.com/sebmarkbage) in [#17456](https://github.com/facebook/react/pull/17456)) +* Adjust `SuspenseList` CPU bound heuristic ([@sebmarkbage](https://github.com/sebmarkbage) in [#17455](https://github.com/facebook/react/pull/17455)) +* Add missing event plugin priorities ([@trueadm](https://github.com/trueadm) in [#17914](https://github.com/facebook/react/pull/17914)) +* Fix `isPending` only being true when transitioning from inside an input event ([@acdlite](https://github.com/acdlite) in [#17382](https://github.com/facebook/react/pull/17382)) +* Fix `React.memo` components dropping updates when interrupted by a higher priority update ([@acdlite]((https://github.com/acdlite)) in [#18091](https://github.com/facebook/react/pull/18091)) +* Don't warn when suspending at the wrong priority ([@gaearon](https://github.com/gaearon) in [#17971](https://github.com/facebook/react/pull/17971)) +* Fix a bug with rebasing updates ([@acdlite](https://github.com/acdlite) and [@sebmarkbage](https://github.com/sebmarkbage) in [#17560](https://github.com/facebook/react/pull/17560), [#17510](https://github.com/facebook/react/pull/17510), [#17483](https://github.com/facebook/react/pull/17483), [#17480](https://github.com/facebook/react/pull/17480)) ## 16.12.0 (November 14, 2019) diff --git a/dangerfile.js b/dangerfile.js index f4624a17c173d..86e7e422a5b40 100644 --- a/dangerfile.js +++ b/dangerfile.js @@ -171,7 +171,7 @@ function git(args) { for (let i = 0; i < baseArtifactsInfo.length; i++) { const info = baseArtifactsInfo[i]; - if (info.path === 'home/circleci/project/build/bundle-sizes.json') { + if (info.path.endsWith('bundle-sizes.json')) { const resultsResponse = await fetch(info.url); previousBuildResults = await resultsResponse.json(); break; diff --git a/fixtures/dom/src/__tests__/nested-act-test.js b/fixtures/dom/src/__tests__/nested-act-test.js index a0500f47e9603..4a39a0ea98f7f 100644 --- a/fixtures/dom/src/__tests__/nested-act-test.js +++ b/fixtures/dom/src/__tests__/nested-act-test.js @@ -8,8 +8,9 @@ */ let React; -let TestUtils; +let DOMAct; let TestRenderer; +let TestAct; global.__DEV__ = process.env.NODE_ENV !== 'production'; @@ -19,8 +20,9 @@ describe('unmocked scheduler', () => { beforeEach(() => { jest.resetModules(); React = require('react'); - TestUtils = require('react-dom/test-utils'); + DOMAct = require('react-dom/test-utils').act; TestRenderer = require('react-test-renderer'); + TestAct = TestRenderer.act; }); it('flushes work only outside the outermost act() corresponding to its own renderer', () => { @@ -32,8 +34,8 @@ describe('unmocked scheduler', () => { return null; } // in legacy mode, this tests whether an act only flushes its own effects - TestRenderer.act(() => { - TestUtils.act(() => { + TestAct(() => { + DOMAct(() => { TestRenderer.create(); }); expect(log).toEqual([]); @@ -42,8 +44,8 @@ describe('unmocked scheduler', () => { log = []; // for doublechecking, we flip it inside out, and assert on the outermost - TestUtils.act(() => { - TestRenderer.act(() => { + DOMAct(() => { + TestAct(() => { TestRenderer.create(); }); expect(log).toEqual(['called']); @@ -59,8 +61,9 @@ describe('mocked scheduler', () => { require.requireActual('scheduler/unstable_mock') ); React = require('react'); - TestUtils = require('react-dom/test-utils'); + DOMAct = require('react-dom/test-utils').act; TestRenderer = require('react-test-renderer'); + TestAct = TestRenderer.act; }); afterEach(() => { @@ -76,8 +79,8 @@ describe('mocked scheduler', () => { return null; } // with a mocked scheduler, this tests whether it flushes all work only on the outermost act - TestRenderer.act(() => { - TestUtils.act(() => { + TestAct(() => { + DOMAct(() => { TestRenderer.create(); }); expect(log).toEqual([]); @@ -86,8 +89,8 @@ describe('mocked scheduler', () => { log = []; // for doublechecking, we flip it inside out, and assert on the outermost - TestUtils.act(() => { - TestRenderer.act(() => { + DOMAct(() => { + TestAct(() => { TestRenderer.create(); }); expect(log).toEqual([]); diff --git a/fixtures/dom/src/__tests__/wrong-act-test.js b/fixtures/dom/src/__tests__/wrong-act-test.js index 6c054efec1bf9..38029be9b9cae 100644 --- a/fixtures/dom/src/__tests__/wrong-act-test.js +++ b/fixtures/dom/src/__tests__/wrong-act-test.js @@ -10,9 +10,9 @@ let React; let ReactDOM; let ReactART; +let TestUtils; let ARTSVGMode; let ARTCurrentMode; -let TestUtils; let TestRenderer; let ARTTest; @@ -29,10 +29,10 @@ beforeEach(() => { jest.resetModules(); React = require('react'); ReactDOM = require('react-dom'); + TestUtils = require('react-dom/test-utils'); ReactART = require('react-art'); ARTSVGMode = require('art/modes/svg'); ARTCurrentMode = require('art/modes/current'); - TestUtils = require('react-dom/test-utils'); TestRenderer = require('react-test-renderer'); ARTCurrentMode.setCurrent(ARTSVGMode); @@ -71,7 +71,7 @@ beforeEach(() => { it("doesn't warn when you use the right act + renderer: dom", () => { TestUtils.act(() => { - TestUtils.renderIntoDocument(); + ReactDOM.render(, document.createElement('div')); }); }); @@ -99,7 +99,7 @@ it('resets correctly across renderers', () => { it('warns when using the wrong act version - test + dom: render', () => { expect(() => { TestRenderer.act(() => { - TestUtils.renderIntoDocument(); + ReactDOM.render(, document.createElement('div')); }); }).toWarnDev(["It looks like you're using the wrong act()"], { withoutStack: true, @@ -113,7 +113,7 @@ it('warns when using the wrong act version - test + dom: updates', () => { setCtr = _setCtr; return ctr; } - TestUtils.renderIntoDocument(); + ReactDOM.render(, document.createElement('div')); expect(() => { TestRenderer.act(() => { setCtr(1); @@ -159,7 +159,7 @@ it('warns when using the wrong act version - dom + test: updates', () => { it('does not warn when nesting react-act inside react-dom', () => { TestUtils.act(() => { - TestUtils.renderIntoDocument(); + ReactDOM.render(, document.createElement('div')); }); }); diff --git a/fixtures/dom/src/components/Header.js b/fixtures/dom/src/components/Header.js index 74af700e27662..77c1ecfc30da6 100644 --- a/fixtures/dom/src/components/Header.js +++ b/fixtures/dom/src/components/Header.js @@ -86,6 +86,7 @@ class Header extends React.Component { +