mirror of
https://github.com/hanzoai/react.git
synced 2026-09-24 17:02:27 +00:00
[DevTools] - Highlight rendered by elements on hover. (#18479)
* [DevTools] - Highlight rendered by elements on hover. * Fixed formatting issue. * DevTools - Extracted highlight logic to custom hook. Added highlight support for rendered by elements. * Removed unnecessary padding style * Removed unnecessary wrapper function. Co-authored-by: Brian Vaughn <[email protected]>
This commit is contained in:
committed by
GitHub
co-authored by
Brian Vaughn
parent
5001857d6f
commit
057a0aaf4f
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+19
-6
@@ -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 (
|
||||
<Button
|
||||
key={id}
|
||||
className={styles.OwnerButton}
|
||||
disabled={!isInStore}
|
||||
onClick={handleClick}>
|
||||
<span
|
||||
className={`${styles.Owner} ${isInStore ? '' : styles.NotInStore}`}
|
||||
title={displayName}>
|
||||
{displayName}
|
||||
onClick={handleClick}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}>
|
||||
<span className={styles.OwnerContent}>
|
||||
<span
|
||||
className={`${styles.Owner} ${isInStore ? '' : styles.NotInStore}`}
|
||||
title={displayName}>
|
||||
{displayName}
|
||||
</span>
|
||||
<Badge hocDisplayNames={hocDisplayNames} type={type} />
|
||||
</span>
|
||||
<Badge hocDisplayNames={hocDisplayNames} type={type} />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<HTMLDivElement | null>(null);
|
||||
const focusTargetRef = useRef<HTMLDivElement | null>(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.
|
||||
|
||||
@@ -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<Value>({
|
||||
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user