diff --git a/src/devtools/store.js b/src/devtools/store.js
index 511812430d..988bcc92a6 100644
--- a/src/devtools/store.js
+++ b/src/devtools/store.js
@@ -118,7 +118,7 @@ export default class Store extends EventEmitter {
}
}
- return ((currentElement: any): Element);
+ return ((currentElement: any): Element) || null;
}
getElementIDAtIndex(index: number): number | null {
@@ -141,7 +141,7 @@ export default class Store extends EventEmitter {
getIndexOfElementID(id: number): number | null {
const element = this.getElementByID(id);
- if (element === null) {
+ if (element === null || element.parentID === 0) {
return null;
}
diff --git a/src/devtools/views/SearchInput.js b/src/devtools/views/SearchInput.js
index b5bc2c5767..103858138d 100644
--- a/src/devtools/views/SearchInput.js
+++ b/src/devtools/views/SearchInput.js
@@ -31,6 +31,16 @@ export default function SearchInput(props: Props) {
setSearchText('');
}, [setSearchText]);
+ const handleKeyDown = useCallback(event => {
+ if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') {
+ // It's convenient for up/down arrow keys to change the selected element when focused on the search input.
+ // But e.g. left/right arrow keys should move the text cursor.
+ // For now just block everything except for up/down arrow keys.
+ // TODO Revisit this approach.
+ event.stopPropagation();
+ }
+ }, []);
+
const handleInputKeyPress = useCallback(
({ key }) => {
if (key === 'Enter') {
@@ -62,8 +72,9 @@ export default function SearchInput(props: Props) {
| null>(null);
@@ -51,6 +52,14 @@ export default function Tree(props: Props) {
selectNextElementInTree();
event.preventDefault();
break;
+ case 'ArrowLeft':
+ console.log('LEFT');
+ selectParentElementInTree();
+ break;
+ case 'ArrowRight':
+ selectNextElementInTree();
+ event.preventDefault();
+ break;
case 'ArrowUp':
selectPreviousElementInTree();
event.preventDefault();
@@ -63,7 +72,11 @@ export default function Tree(props: Props) {
return () => {
window.removeEventListener('keydown', handleKeyDown);
};
- }, [selectNextElementInTree, selectPreviousElementInTree]);
+ }, [
+ selectNextElementInTree,
+ selectParentElementInTree,
+ selectPreviousElementInTree,
+ ]);
// 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/src/devtools/views/TreeContext.js b/src/devtools/views/TreeContext.js
index 66b4b1b088..715eee3cbf 100644
--- a/src/devtools/views/TreeContext.js
+++ b/src/devtools/views/TreeContext.js
@@ -41,6 +41,7 @@ type Context = {|
selectElementAtIndex(index: number): void,
selectElementByID(id: number | null): void,
selectNextElementInTree(): void,
+ selectParentElementInTree(): void,
selectPreviousElementInTree(): void,
// Search
@@ -91,6 +92,7 @@ type Action = {|
| 'SELECT_ELEMENT_AT_INDEX'
| 'SELECT_ELEMENT_BY_ID'
| 'SELECT_NEXT_ELEMENT_IN_TREE'
+ | 'SELECT_PARENT_ELEMENT_IN_TREE'
| 'SELECT_PREVIOUS_ELEMENT_IN_TREE'
| 'SELECT_OWNER'
| 'SET_SEARCH_TEXT',
@@ -138,6 +140,17 @@ function reduceTreeState(store: Store, state: State, action: Action): State {
selectedElementIndex++;
}
break;
+ case 'SELECT_PARENT_ELEMENT_IN_TREE':
+ if (selectedElementIndex !== null) {
+ const selectedElement = store.getElementAtIndex(
+ ((selectedElementIndex: any): number)
+ );
+ if (selectedElement !== null && selectedElement.parentID !== null) {
+ selectedElementIndex =
+ store.getIndexOfElementID(selectedElement.parentID) || 0;
+ }
+ }
+ break;
case 'SELECT_PREVIOUS_ELEMENT_IN_TREE':
if (selectedElementIndex !== null && selectedElementIndex > 0) {
selectedElementIndex--;
@@ -502,6 +515,7 @@ function TreeContextController({ children, viewElementSource }: Props) {
case 'SELECT_ELEMENT_AT_INDEX':
case 'SELECT_ELEMENT_BY_ID':
case 'SELECT_NEXT_ELEMENT_IN_TREE':
+ case 'SELECT_PARENT_ELEMENT_IN_TREE':
case 'SELECT_PREVIOUS_ELEMENT_IN_TREE':
case 'SELECT_OWNER':
case 'SET_SEARCH_TEXT':
@@ -572,6 +586,10 @@ function TreeContextController({ children, viewElementSource }: Props) {
() => dispatch({ type: 'SELECT_NEXT_ELEMENT_IN_TREE' }),
[dispatch]
);
+ const selectParentElementInTree = useCallback(
+ () => dispatch({ type: 'SELECT_PARENT_ELEMENT_IN_TREE' }),
+ [dispatch]
+ );
const selectPreviousElementInTree = useCallback(
() => dispatch({ type: 'SELECT_PREVIOUS_ELEMENT_IN_TREE' }),
[dispatch]
@@ -592,6 +610,7 @@ function TreeContextController({ children, viewElementSource }: Props) {
selectElementByID,
selectElementAtIndex,
selectNextElementInTree,
+ selectParentElementInTree,
selectPreviousElementInTree,
// Search
@@ -619,6 +638,7 @@ function TreeContextController({ children, viewElementSource }: Props) {
selectElementAtIndex,
selectElementByID,
selectNextElementInTree,
+ selectParentElementInTree,
selectOwner,
selectPreviousElementInTree,
setSearchText,