Skip to content
This repository was archived by the owner on Sep 21, 2021. It is now read-only.

Commit 336f4be

Browse files
committed
Add Home and End key handler to navigate to resp first and last node.
Add a test to make sure we don't regress.
1 parent 6cca4a5 commit 336f4be

File tree

3 files changed

+137
-0
lines changed

3 files changed

+137
-0
lines changed

packages/devtools-components/src/tests/__snapshots__/tree.js.snap

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,73 @@ exports[`Tree renders as expected when navigating with arrows on unexpandable ro
677677
"
678678
`;
679679

680+
exports[`Tree renders as expected when navigating with home/end 1`] = `
681+
"
682+
▶︎ A
683+
▶︎ [M]
684+
"
685+
`;
686+
687+
exports[`Tree renders as expected when navigating with home/end 2`] = `
688+
"
689+
▶︎ [A]
690+
▶︎ M
691+
"
692+
`;
693+
694+
exports[`Tree renders as expected when navigating with home/end 3`] = `
695+
"
696+
▶︎ [A]
697+
▶︎ M
698+
"
699+
`;
700+
701+
exports[`Tree renders as expected when navigating with home/end 4`] = `
702+
"
703+
▶︎ A
704+
▶︎ [M]
705+
"
706+
`;
707+
708+
exports[`Tree renders as expected when navigating with home/end 5`] = `
709+
"
710+
▶︎ A
711+
▶︎ [M]
712+
"
713+
`;
714+
715+
exports[`Tree renders as expected when navigating with home/end 6`] = `
716+
"
717+
▶︎ A
718+
▼ [M]
719+
| ▶︎ N
720+
"
721+
`;
722+
723+
exports[`Tree renders as expected when navigating with home/end 7`] = `
724+
"
725+
▶︎ A
726+
▼ M
727+
| ▶︎ [N]
728+
"
729+
`;
730+
731+
exports[`Tree renders as expected when navigating with home/end 8`] = `
732+
"
733+
▶︎ A
734+
▼ M
735+
| ▶︎ [N]
736+
"
737+
`;
738+
739+
exports[`Tree renders as expected when navigating with home/end 9`] = `
740+
"
741+
▶︎ [A]
742+
▼ M
743+
| ▶︎ N
744+
"
745+
`;
746+
680747
exports[`Tree renders as expected when navigating with left arrows on roots 1`] = `
681748
"
682749
▶︎ A

packages/devtools-components/src/tests/tree.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,55 @@ describe("Tree", () => {
304304
expect(wrapper.find(".focused").prop("id")).toBe("key-A");
305305
});
306306

307+
it("renders as expected when navigating with home/end", () => {
308+
const wrapper = mountTree({
309+
focused: "M"
310+
});
311+
expect(formatTree(wrapper)).toMatchSnapshot();
312+
expect(wrapper.getDOMNode().getAttribute("aria-activedescendant")).toBe("key-M");
313+
expect(wrapper.find(".focused").prop("id")).toBe("key-M");
314+
315+
simulateKeyDown(wrapper, "Home");
316+
expect(formatTree(wrapper)).toMatchSnapshot();
317+
expect(wrapper.getDOMNode().getAttribute("aria-activedescendant")).toBe("key-A");
318+
expect(wrapper.find(".focused").prop("id")).toBe("key-A");
319+
320+
simulateKeyDown(wrapper, "Home");
321+
expect(formatTree(wrapper)).toMatchSnapshot();
322+
expect(wrapper.getDOMNode().getAttribute("aria-activedescendant")).toBe("key-A");
323+
expect(wrapper.find(".focused").prop("id")).toBe("key-A");
324+
325+
simulateKeyDown(wrapper, "End");
326+
expect(formatTree(wrapper)).toMatchSnapshot();
327+
expect(wrapper.getDOMNode().getAttribute("aria-activedescendant")).toBe("key-M");
328+
expect(wrapper.find(".focused").prop("id")).toBe("key-M");
329+
330+
simulateKeyDown(wrapper, "End");
331+
expect(formatTree(wrapper)).toMatchSnapshot();
332+
expect(wrapper.getDOMNode().getAttribute("aria-activedescendant")).toBe("key-M");
333+
expect(wrapper.find(".focused").prop("id")).toBe("key-M");
334+
335+
simulateKeyDown(wrapper, "ArrowRight");
336+
expect(formatTree(wrapper)).toMatchSnapshot();
337+
expect(wrapper.getDOMNode().getAttribute("aria-activedescendant")).toBe("key-M");
338+
expect(wrapper.find(".focused").prop("id")).toBe("key-M");
339+
340+
simulateKeyDown(wrapper, "End");
341+
expect(formatTree(wrapper)).toMatchSnapshot();
342+
expect(wrapper.getDOMNode().getAttribute("aria-activedescendant")).toBe("key-N");
343+
expect(wrapper.find(".focused").prop("id")).toBe("key-N");
344+
345+
simulateKeyDown(wrapper, "End");
346+
expect(formatTree(wrapper)).toMatchSnapshot();
347+
expect(wrapper.getDOMNode().getAttribute("aria-activedescendant")).toBe("key-N");
348+
expect(wrapper.find(".focused").prop("id")).toBe("key-N");
349+
350+
simulateKeyDown(wrapper, "Home");
351+
expect(formatTree(wrapper)).toMatchSnapshot();
352+
expect(wrapper.getDOMNode().getAttribute("aria-activedescendant")).toBe("key-A");
353+
expect(wrapper.find(".focused").prop("id")).toBe("key-A");
354+
});
355+
307356
it("renders as expected when navigating with arrows on unexpandable roots", () => {
308357
const wrapper = mountTree({
309358
focused: "A",

packages/devtools-components/src/tree.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,8 @@ class Tree extends Component {
357357
this._focusPrevNode = oncePerAnimationFrame(this._focusPrevNode).bind(this);
358358
this._focusNextNode = oncePerAnimationFrame(this._focusNextNode).bind(this);
359359
this._focusParentNode = oncePerAnimationFrame(this._focusParentNode).bind(this);
360+
this._focusFirstNode = oncePerAnimationFrame(this._focusFirstNode).bind(this);
361+
this._focusLastNode = oncePerAnimationFrame(this._focusLastNode).bind(this);
360362

361363
this._autoExpand = this._autoExpand.bind(this);
362364
this._preventArrowKeyScrolling = this._preventArrowKeyScrolling.bind(this);
@@ -629,6 +631,14 @@ class Tree extends Component {
629631
} else {
630632
this._focusNextNode();
631633
}
634+
return;
635+
636+
case "Home":
637+
this._focusFirstNode();
638+
return;
639+
640+
case "End":
641+
this._focusLastNode();
632642
}
633643
}
634644

@@ -705,6 +715,17 @@ class Tree extends Component {
705715
this._focus(parent, {alignTo: "top"});
706716
}
707717

718+
_focusFirstNode() {
719+
const traversal = this._dfsFromRoots();
720+
this._focus(traversal[0].item, {alignTo: "top"});
721+
}
722+
723+
_focusLastNode() {
724+
const traversal = this._dfsFromRoots();
725+
const lastIndex = traversal.length - 1;
726+
this._focus(traversal[lastIndex].item, {alignTo: "bottom"});
727+
}
728+
708729
_nodeIsExpandable(item) {
709730
return this.props.isExpandable
710731
? this.props.isExpandable(item)

0 commit comments

Comments
 (0)