@samitouri / QOS-React-2 / commits / ca7eb3c829

Changed highlight-on-search behavior to use TreeContext

Brian Vaughn committed Apr 12, 2019 at 18:14 UTC ca7eb3c8293665fbff1b1f1fb49778dbb861efef
3 files changed +37 -50
src/devtools/views/Components/Element.js
+2 -2
@@ -44,7 +44,7 @@ export default function ElementView({ data, index, style }: Props) {
44 const {
45 lastScrolledIDRef,
46 treeFocused,
47 - isUsingKeyboardOrSearch,
47 + isNavigatingWithKeyboard,
48 onElementMouseEnter,
49 } = data;
50 const id = element === null ? null : element.id;
@@ -122,7 +122,7 @@ export default function ElementView({ data, index, style }: Props) {
122 className = treeFocused
123 ? styles.SelectedElement
124 : styles.InactiveSelectedElement;
125 - } else if (isHovered && !isUsingKeyboardOrSearch) {
125 + } else if (isHovered && !isNavigatingWithKeyboard) {
126 className = styles.HoveredElement;
127 }
128
src/devtools/views/Components/SearchInput.js
+8 -27
@@ -8,12 +8,9 @@ import Icon from '../Icon';
8
9 import styles from './SearchInput.css';
10
11 -type Props = {|
12 - onSearchInteraction: () => void,
13 -|};
11 +type Props = {||};
12
13 export default function SearchInput(props: Props) {
16 - const { onSearchInteraction } = props;
14 const {
15 goToNextSearchResult,
16 goToPreviousSearchResult,
@@ -28,17 +25,10 @@ export default function SearchInput(props: Props) {
25 const inputRef = useRef<HTMLInputElement | null>(null);
26
27 const handleTextChange = useCallback(
31 - ({ currentTarget }) => {
32 - setSearchText(currentTarget.value);
33 - onSearchInteraction();
34 - },
35 - [setSearchText, onSearchInteraction]
28 + ({ currentTarget }) => setSearchText(currentTarget.value),
29 + [setSearchText]
30 );
37 -
38 - const resetSearch = useCallback(() => {
39 - setSearchText('');
40 - onSearchInteraction();
41 - }, [setSearchText, onSearchInteraction]);
31 + const resetSearch = useCallback(() => setSearchText(''), [setSearchText]);
32
33 const handleKeyDown = useCallback(
34 event => {
@@ -46,29 +36,26 @@ export default function SearchInput(props: Props) {
36 switch (event.key) {
37 case 'ArrowDown':
38 selectNextElementInTree();
49 - onSearchInteraction();
39 event.preventDefault();
40 break;
41 case 'ArrowUp':
42 selectPreviousElementInTree();
54 - onSearchInteraction();
43 event.preventDefault();
44 break;
45 default:
46 break;
47 }
48 },
61 - [selectNextElementInTree, selectPreviousElementInTree, onSearchInteraction]
49 + [selectNextElementInTree, selectPreviousElementInTree]
50 );
51
52 const handleInputKeyPress = useCallback(
53 ({ key }) => {
54 if (key === 'Enter') {
55 goToNextSearchResult();
68 - onSearchInteraction();
56 }
57 },
71 - [goToNextSearchResult, onSearchInteraction]
58 + [goToNextSearchResult]
59 );
60
61 // Auto-focus search input
@@ -119,10 +106,7 @@ export default function SearchInput(props: Props) {
106 <Button
107 className={styles.IconButton}
108 disabled={!searchText}
122 - onClick={() => {
123 - goToPreviousSearchResult();
124 - onSearchInteraction();
125 - }}
109 + onClick={goToPreviousSearchResult}
110 title="Scroll to previous search result"
111 >
112 <ButtonIcon type="up" />
@@ -130,10 +114,7 @@ export default function SearchInput(props: Props) {
114 <Button
115 className={styles.IconButton}
116 disabled={!searchText}
133 - onClick={() => {
134 - goToNextSearchResult();
135 - onSearchInteraction();
136 - }}
117 + onClick={goToNextSearchResult}
118 title="Scroll to next search result"
119 >
120 <ButtonIcon type="down" />
src/devtools/views/Components/Tree.js
+27 -21
@@ -27,7 +27,7 @@ export type ItemData = {|
27 baseDepth: number,
28 numElements: number,
29 getElementAtIndex: (index: number) => Element | null,
30 - isUsingKeyboardOrSearch: boolean,
30 + isNavigatingWithKeyboard: boolean,
31 lastScrolledIDRef: { current: number | null },
32 onElementMouseEnter: (id: number) => void,
33 treeFocused: boolean,
@@ -41,6 +41,8 @@ export default function Tree(props: Props) {
41 getElementAtIndex,
42 numElements,
43 ownerStack,
44 + searchIndex,
45 + searchResults,
46 selectedElementID,
47 selectedElementIndex,
48 selectChildElementInTree,
@@ -52,7 +54,9 @@ export default function Tree(props: Props) {
54 } = useContext(TreeContext);
55 const bridge = useContext(BridgeContext);
56 const store = useContext(StoreContext);
55 - const [isUsingKeyboardOrSearch, setIsUsingKeyboardOrSearch] = useState(false);
57 + const [isNavigatingWithKeyboard, setIsNavigatingWithKeyboard] = useState(
58 + false
59 + );
60 // $FlowFixMe https://github.com/facebook/flow/issues/7341
61 const listRef = useRef<FixedSizeList<ItemData> | null>(null);
62 const treeRef = useRef<HTMLDivElement | null>(null);
@@ -144,7 +148,7 @@ export default function Tree(props: Props) {
148 default:
149 return;
150 }
147 - setIsUsingKeyboardOrSearch(true);
151 + setIsNavigatingWithKeyboard(true);
152 };
153
154 // It's important to listen to the ownerDocument to support the browser extension.
@@ -210,8 +214,18 @@ export default function Tree(props: Props) {
214
215 // If we switch the selected element while using the keyboard,
216 // start highlighting it in the DOM instead of the last hovered node.
217 + const searchRef = useRef({ searchIndex, searchResults });
218 useEffect(() => {
214 - if (isUsingKeyboardOrSearch) {
219 + let didSelectNewSearchResult = false;
220 + if (
221 + searchRef.current.searchIndex !== searchIndex ||
222 + searchRef.current.searchResults !== searchResults
223 + ) {
224 + searchRef.current.searchIndex = searchIndex;
225 + searchRef.current.searchResults = searchResults;
226 + didSelectNewSearchResult = true;
227 + }
228 + if (isNavigatingWithKeyboard || didSelectNewSearchResult) {
229 if (selectedElementID !== null) {
230 highlightElementInDOM(selectedElementID);
231 } else {
@@ -220,8 +234,10 @@ export default function Tree(props: Props) {
234 }
235 }, [
236 bridge,
223 - isUsingKeyboardOrSearch,
237 + isNavigatingWithKeyboard,
238 highlightElementInDOM,
239 + searchIndex,
240 + searchResults,
241 selectedElementID,
242 ]);
243
@@ -230,29 +246,23 @@ export default function Tree(props: Props) {
246 id => {
247 // Ignore hover while we're navigating with keyboard.
248 // This avoids flicker from the hovered nodes under the mouse.
233 - if (!isUsingKeyboardOrSearch) {
249 + if (!isNavigatingWithKeyboard) {
250 highlightElementInDOM(id);
251 }
252 },
237 - [isUsingKeyboardOrSearch, highlightElementInDOM]
253 + [isNavigatingWithKeyboard, highlightElementInDOM]
254 );
255
256 const handleMouseMove = useCallback(() => {
257 // We started using the mouse again.
258 // This will enable hover styles in individual rows.
243 - setIsUsingKeyboardOrSearch(false);
259 + setIsNavigatingWithKeyboard(false);
260 }, []);
261
262 const handleMouseLeave = useCallback(() => {
263 bridge.send('clearHighlightedElementInDOM');
264 }, [bridge]);
265
250 - const handleSearchInteraction = useCallback(() => {
251 - // We started navigating using search.
252 - // This will disable hover styles and start highlighting DOM elements.
253 - setIsUsingKeyboardOrSearch(true);
254 - }, []);
255 -
266 // Let react-window know to re-render any time the underlying tree data changes.
267 // This includes the owner context, since it controls a filtered view of the tree.
268 const itemData = useMemo<ItemData>(
@@ -260,7 +270,7 @@ export default function Tree(props: Props) {
270 baseDepth,
271 numElements,
272 getElementAtIndex,
263 - isUsingKeyboardOrSearch,
273 + isNavigatingWithKeyboard,
274 onElementMouseEnter: handleElementMouseEnter,
275 lastScrolledIDRef,
276 treeFocused,
@@ -269,7 +279,7 @@ export default function Tree(props: Props) {
279 baseDepth,
280 numElements,
281 getElementAtIndex,
272 - isUsingKeyboardOrSearch,
282 + isNavigatingWithKeyboard,
283 handleElementMouseEnter,
284 lastScrolledIDRef,
285 treeFocused,
@@ -279,11 +289,7 @@ export default function Tree(props: Props) {
289 return (
290 <div className={styles.Tree} ref={treeRef}>
291 <div className={styles.SearchInput}>
282 - {ownerStack.length > 0 ? (
283 - <OwnersStack />
284 - ) : (
285 - <SearchInput onSearchInteraction={handleSearchInteraction} />
286 - )}
292 + {ownerStack.length > 0 ? <OwnersStack /> : <SearchInput />}
293 <InspectHostNodesToggle />
294 </div>
295 <div