diff --git a/packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.css b/packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.css
index d1bb28f19706e..eaf5ac4a33a3c 100644
--- a/packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.css
+++ b/packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.css
@@ -82,7 +82,6 @@
.Owner {
border-radius: 0.25rem;
padding: 0.125rem 0.25rem;
- cursor: pointer;
background: none;
border: none;
display: block;
@@ -107,12 +106,23 @@
}
.OwnerButton {
+ cursor: pointer;
+ width: 100%;
+ padding: 0;
+}
+
+.OwnerContent {
display: flex;
align-items: center;
- margin-left: 0.5rem;
- padding: 0;
+ padding-left: 1rem;
+ width: 100%;
+ border-radius: 0.25rem;
+}
+
+.OwnerContent:hover {
+ background-color: var(--color-background-hover);
}
.ContextMenuIcon {
margin-right: 0.5rem;
-}
\ No newline at end of file
+}
diff --git a/packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.js b/packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.js
index f65b8e0a777e5..5424d35039cb3 100644
--- a/packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.js
+++ b/packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.js
@@ -26,6 +26,7 @@ import ViewElementSourceContext from './ViewElementSourceContext';
import NativeStyleEditor from './NativeStyleEditor';
import Toggle from '../Toggle';
import Badge from './Badge';
+import {useHighlightNativeElement} from '../hooks';
import {
ComponentFilterElementType,
ElementTypeClass,
@@ -522,6 +523,10 @@ function OwnerView({
type,
}: OwnerViewProps) {
const dispatch = useContext(TreeDispatcherContext);
+ const {
+ highlightNativeElement,
+ clearHighlightNativeElement,
+ } = useHighlightNativeElement();
const handleClick = useCallback(
() =>
@@ -532,18 +537,26 @@ function OwnerView({
[dispatch, id],
);
+ const onMouseEnter = () => highlightNativeElement(id);
+
+ const onMouseLeave = clearHighlightNativeElement;
+
return (
);
}
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 43114cd4d9659..dc0d5bb3dd630 100644
--- a/packages/react-devtools-shared/src/devtools/views/Components/Tree.js
+++ b/packages/react-devtools-shared/src/devtools/views/Components/Tree.js
@@ -30,6 +30,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 {useHighlightNativeElement} from '../hooks';
import styles from './Tree.css';
@@ -61,6 +62,10 @@ export default function Tree(props: Props) {
const [isNavigatingWithKeyboard, setIsNavigatingWithKeyboard] = useState(
false,
);
+ const {
+ highlightNativeElement,
+ clearHighlightNativeElement,
+ } = useHighlightNativeElement();
const treeRef = useRef(null);
const focusTargetRef = useRef(null);
@@ -205,24 +210,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});
@@ -240,7 +227,7 @@ export default function Tree(props: Props) {
if (selectedElementID !== null) {
highlightNativeElement(selectedElementID);
} else {
- bridge.send('clearNativeElementHighlight');
+ clearHighlightNativeElement();
}
}
}, [
@@ -270,9 +257,7 @@ export default function Tree(props: Props) {
setIsNavigatingWithKeyboard(false);
}, []);
- const handleMouseLeave = useCallback(() => {
- bridge.send('clearNativeElementHighlight');
- }, [bridge]);
+ const handleMouseLeave = clearHighlightNativeElement;
// 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.
diff --git a/packages/react-devtools-shared/src/devtools/views/hooks.js b/packages/react-devtools-shared/src/devtools/views/hooks.js
index cace5451df589..3af0ceaeb29ad 100644
--- a/packages/react-devtools-shared/src/devtools/views/hooks.js
+++ b/packages/react-devtools-shared/src/devtools/views/hooks.js
@@ -14,11 +14,13 @@ import {
useLayoutEffect,
useReducer,
useState,
+ useContext,
} from 'react';
import {
localStorageGetItem,
localStorageSetItem,
} from 'react-devtools-shared/src/storage';
+import {StoreContext, BridgeContext} from './context';
import {sanitizeForParse, smartParse, smartStringify} from '../utils';
type ACTION_RESET = {|
@@ -301,3 +303,35 @@ export function useSubscription({
return state.value;
}
+
+export function useHighlightNativeElement() {
+ const bridge = useContext(BridgeContext);
+ const store = useContext(StoreContext);
+
+ 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],
+ );
+
+ const clearHighlightNativeElement = useCallback(() => {
+ bridge.send('clearNativeElementHighlight');
+ }, [bridge]);
+
+ return {
+ highlightNativeElement,
+ clearHighlightNativeElement,
+ };
+}