Support toggling Suspense from within owners list
Brian Vaughn committed
Jun 12, 2019 at 15:13 UTC
f6ec82553de20e39576e5a46a70205c4ad4b0df6
3 files changed
+216
-4
src/__tests__/__snapshots__/treeContext-test.js.snap
+153
@@ -1,5 +1,158 @@
1
// Jest Snapshot v1, https://goo.gl/fbAQLP
2
3
+exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 0: mount 1`] = `
4
+[root]
5
+ ▾ <Parent>
6
+ ▾ <Suspense>
7
+ ▾ <Child>
8
+ ▾ <Suspense>
9
+ <Grandchild>
10
+`;
11
+
12
+exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 1: initial state 1`] = `
13
+Object {
14
+ "inspectedElementID": null,
15
+ "numElements": 5,
16
+ "ownerFlatTree": null,
17
+ "ownerID": null,
18
+ "searchIndex": null,
19
+ "searchResults": Array [],
20
+ "searchText": "",
21
+ "selectedElementID": null,
22
+ "selectedElementIndex": null,
23
+}
24
+`;
25
+
26
+exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 2: child owners tree 1`] = `
27
+Object {
28
+ "inspectedElementID": 4,
29
+ "numElements": 3,
30
+ "ownerFlatTree": Array [
31
+ Object {
32
+ "children": Array [
33
+ 5,
34
+ ],
35
+ "depth": 0,
36
+ "displayName": "Child",
37
+ "hocDisplayNames": null,
38
+ "id": 4,
39
+ "isCollapsed": false,
40
+ "key": null,
41
+ "ownerID": 2,
42
+ "parentID": 3,
43
+ "type": 5,
44
+ "weight": 3,
45
+ },
46
+ Object {
47
+ "children": Array [
48
+ 6,
49
+ ],
50
+ "depth": 1,
51
+ "displayName": "Suspense",
52
+ "hocDisplayNames": null,
53
+ "id": 5,
54
+ "isCollapsed": false,
55
+ "key": null,
56
+ "ownerID": 4,
57
+ "parentID": 4,
58
+ "type": 12,
59
+ "weight": 2,
60
+ },
61
+ Object {
62
+ "children": Array [],
63
+ "depth": 2,
64
+ "displayName": "Grandchild",
65
+ "hocDisplayNames": null,
66
+ "id": 6,
67
+ "isCollapsed": false,
68
+ "key": null,
69
+ "ownerID": 4,
70
+ "parentID": 5,
71
+ "type": 5,
72
+ "weight": 1,
73
+ },
74
+ ],
75
+ "ownerID": 4,
76
+ "searchIndex": null,
77
+ "searchResults": Array [],
78
+ "searchText": "",
79
+ "selectedElementID": 4,
80
+ "selectedElementIndex": 0,
81
+}
82
+`;
83
+
84
+exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 3: child owners tree 1`] = `
85
+Object {
86
+ "inspectedElementID": 5,
87
+ "numElements": 3,
88
+ "ownerFlatTree": Array [
89
+ Object {
90
+ "children": Array [
91
+ 5,
92
+ ],
93
+ "depth": 0,
94
+ "displayName": "Child",
95
+ "hocDisplayNames": null,
96
+ "id": 4,
97
+ "isCollapsed": false,
98
+ "key": null,
99
+ "ownerID": 2,
100
+ "parentID": 3,
101
+ "type": 5,
102
+ "weight": 3,
103
+ },
104
+ Object {
105
+ "children": Array [
106
+ 6,
107
+ ],
108
+ "depth": 1,
109
+ "displayName": "Suspense",
110
+ "hocDisplayNames": null,
111
+ "id": 5,
112
+ "isCollapsed": false,
113
+ "key": null,
114
+ "ownerID": 4,
115
+ "parentID": 4,
116
+ "type": 12,
117
+ "weight": 2,
118
+ },
119
+ Object {
120
+ "children": Array [],
121
+ "depth": 2,
122
+ "displayName": "Grandchild",
123
+ "hocDisplayNames": null,
124
+ "id": 6,
125
+ "isCollapsed": false,
126
+ "key": null,
127
+ "ownerID": 4,
128
+ "parentID": 5,
129
+ "type": 5,
130
+ "weight": 1,
131
+ },
132
+ ],
133
+ "ownerID": 4,
134
+ "searchIndex": null,
135
+ "searchResults": Array [],
136
+ "searchText": "",
137
+ "selectedElementID": 5,
138
+ "selectedElementIndex": 1,
139
+}
140
+`;
141
+
142
+exports[`TreeListContext owners state should exit the owners list if an element outside the list is selected: 4: main tree 1`] = `
143
+Object {
144
+ "inspectedElementID": 5,
145
+ "numElements": 5,
146
+ "ownerFlatTree": null,
147
+ "ownerID": null,
148
+ "searchIndex": null,
149
+ "searchResults": Array [],
150
+ "searchText": "",
151
+ "selectedElementID": 5,
152
+ "selectedElementIndex": 1,
153
+}
154
+`;
155
+
156
exports[`TreeListContext owners state should exit the owners list if the current owner is unmounted: 0: mount 1`] = `
157
[root]
158
▾ <Parent>
src/__tests__/treeContext-test.js
+47
@@ -546,5 +546,52 @@ describe('TreeListContext', () => {
546
547
done();
548
});
549
+
550
+ // This tests ensures support for toggling Suspense boundaries outside of the active owners list.
551
+ it('should exit the owners list if an element outside the list is selected', () => {
552
+ const Grandchild = () => null;
553
+ const Child = () => (
554
+ <React.Suspense fallback="Loading">
555
+ <Grandchild />
556
+ </React.Suspense>
557
+ );
558
+ const Parent = () => (
559
+ <React.Suspense fallback="Loading">
560
+ <Child />
561
+ </React.Suspense>
562
+ );
563
+
564
+ const container = document.createElement('div');
565
+ utils.act(() => ReactDOM.render(<Parent />, container));
566
+
567
+ expect(store).toMatchSnapshot('0: mount');
568
+
569
+ let renderer;
570
+ utils.act(() => (renderer = TestRenderer.create(<Contexts />)));
571
+ expect(state).toMatchSnapshot('1: initial state');
572
+
573
+ const outerSuspenseID = ((store.getElementIDAtIndex(1): any): number);
574
+ const childID = ((store.getElementIDAtIndex(2): any): number);
575
+ const innerSuspenseID = ((store.getElementIDAtIndex(3): any): number);
576
+ const grandchildID = ((store.getElementIDAtIndex(4): any): number);
577
+
578
+ utils.act(() => dispatch({ type: 'SELECT_OWNER', payload: childID }));
579
+ utils.act(() => renderer.update(<Contexts />));
580
+ expect(state).toMatchSnapshot('2: child owners tree');
581
+
582
+ // Toggling a Suspense boundary inside of the flat list should update selected index
583
+ utils.act(() =>
584
+ dispatch({ type: 'SELECT_ELEMENT_BY_ID', payload: innerSuspenseID })
585
+ );
586
+ utils.act(() => renderer.update(<Contexts />));
587
+ expect(state).toMatchSnapshot('3: child owners tree');
588
+
589
+ // Toggling a Suspense boundary outside of the flat list should exit owners list and update index
590
+ utils.act(() =>
591
+ dispatch({ type: 'SELECT_ELEMENT_BY_ID', payload: outerSuspenseID })
592
+ );
593
+ utils.act(() => renderer.update(<Contexts />));
594
+ expect(state).toMatchSnapshot('4: main tree');
595
+ });
596
});
597
});
src/devtools/views/Components/TreeContext.js
+16
-4
@@ -488,10 +488,22 @@ function reduceOwnersState(store: Store, state: State, action: Action): State {
488
case 'SELECT_ELEMENT_BY_ID':
489
if (ownerFlatTree !== null) {
490
const payload = (action: ACTION_SELECT_ELEMENT_BY_ID).payload;
491
- selectedElementIndex =
492
- payload === null
493
- ? null
494
- : ownerFlatTree.findIndex(element => element.id === payload);
491
+ if (payload === null) {
492
+ selectedElementIndex = null;
493
+ } else {
494
+ selectedElementIndex = ownerFlatTree.findIndex(
495
+ element => element.id === payload
496
+ );
497
+
498
+ // If the selected element is outside of the current owners list,
499
+ // exit the list and select the element in the main tree.
500
+ // This supports features like toggling Suspense.
501
+ if (selectedElementIndex !== null && selectedElementIndex < 0) {
502
+ ownerID = null;
503
+ ownerFlatTree = null;
504
+ selectedElementIndex = store.getIndexOfElementID(payload);
505
+ }
506
+ }
507
}
508
break;
509
case 'SELECT_NEXT_ELEMENT_IN_TREE':