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

[react-ui] FocusGrid -> ReactFocusTable + tweaks and fixes (#16806)

Dominic Gannaway committed Sep 17, 2019 at 19:22 UTC f40ceb0010eaddab8cad94c67189837c495a5b57
6 files changed +482 -283
packages/react-reconciler/src/ReactFiberScope.js
+4
@@ -143,6 +143,10 @@ export function createScopeMethods(
143 }
144 return null;
145 },
146 + getProps(): Object {
147 + const currentFiber = ((instance.fiber: any): Fiber);
148 + return currentFiber.memoizedProps;
149 + },
150 getScopedNodes(): null | Array<Object> {
151 const currentFiber = ((instance.fiber: any): Fiber);
152 const child = currentFiber.child;
packages/react-ui/accessibility/src/FocusGrid.js deleted
-131
@@ -1,131 +0,0 @@
1 -/**
2 - * Copyright (c) Facebook, Inc. and its affiliates.
3 - *
4 - * This source code is licensed under the MIT license found in the
5 - * LICENSE file in the root directory of this source tree.
6 - *
7 - * @flow
8 - */
9 -
10 -import type {KeyboardEvent} from 'react-ui/events/keyboard';
11 -
12 -import React from 'react';
13 -import {tabFocusableImpl} from './TabbableScope';
14 -import {useKeyboard} from 'react-ui/events/keyboard';
15 -
16 -type GridComponentProps = {
17 - children: React.Node,
18 -};
19 -
20 -const {useRef} = React;
21 -
22 -function focusCell(cell) {
23 - const tabbableNodes = cell.getScopedNodes();
24 - if (tabbableNodes !== null && tabbableNodes.length > 0) {
25 - tabbableNodes[0].focus();
26 - }
27 -}
28 -
29 -function focusCellByRowIndex(row, rowIndex) {
30 - const cells = row.getChildren();
31 - const cell = cells[rowIndex];
32 - if (cell) {
33 - focusCell(cell);
34 - }
35 -}
36 -
37 -function getRowCells(currentCell) {
38 - const row = currentCell.getParent();
39 - if (parent !== null) {
40 - const cells = row.getChildren();
41 - const rowIndex = cells.indexOf(currentCell);
42 - return [cells, rowIndex];
43 - }
44 - return [null, 0];
45 -}
46 -
47 -function getColumns(currentCell) {
48 - const row = currentCell.getParent();
49 - if (parent !== null) {
50 - const grid = row.getParent();
51 - const columns = grid.getChildren();
52 - const columnIndex = columns.indexOf(row);
53 - return [columns, columnIndex];
54 - }
55 - return [null, 0];
56 -}
57 -
58 -export function createFocusGrid(): Array<React.Component> {
59 - const GridScope = React.unstable_createScope(tabFocusableImpl);
60 -
61 - function GridContainer({children}): GridComponentProps {
62 - return <GridScope>{children}</GridScope>;
63 - }
64 -
65 - function GridRow({children}): GridComponentProps {
66 - return <GridScope>{children}</GridScope>;
67 - }
68 -
69 - function GridCell({children}): GridComponentProps {
70 - const scopeRef = useRef(null);
71 - const keyboard = useKeyboard({
72 - onKeyDown(event: KeyboardEvent): boolean {
73 - const currentCell = scopeRef.current;
74 - switch (event.key) {
75 - case 'UpArrow': {
76 - const [cells, rowIndex] = getRowCells(currentCell);
77 - if (cells !== null) {
78 - const [columns, columnIndex] = getColumns(currentCell);
79 - if (columns !== null) {
80 - if (columnIndex > 0) {
81 - const column = columns[columnIndex - 1];
82 - focusCellByRowIndex(column, rowIndex);
83 - }
84 - }
85 - }
86 - return false;
87 - }
88 - case 'DownArrow': {
89 - const [cells, rowIndex] = getRowCells(currentCell);
90 - if (cells !== null) {
91 - const [columns, columnIndex] = getColumns(currentCell);
92 - if (columns !== null) {
93 - if (columnIndex !== -1 && columnIndex !== columns.length - 1) {
94 - const column = columns[columnIndex + 1];
95 - focusCellByRowIndex(column, rowIndex);
96 - }
97 - }
98 - }
99 - return false;
100 - }
101 - case 'LeftArrow': {
102 - const [cells, rowIndex] = getRowCells(currentCell);
103 - if (cells !== null) {
104 - if (rowIndex > 0) {
105 - focusCell(cells[rowIndex - 1]);
106 - }
107 - }
108 - return false;
109 - }
110 - case 'RightArrow': {
111 - const [cells, rowIndex] = getRowCells(currentCell);
112 - if (cells !== null) {
113 - if (rowIndex !== -1 && rowIndex !== cells.length - 1) {
114 - focusCell(cells[rowIndex + 1]);
115 - }
116 - }
117 - return false;
118 - }
119 - }
120 - return true;
121 - },
122 - });
123 - return (
124 - <GridScope listeners={keyboard} ref={scopeRef}>
125 - {children}
126 - </GridScope>
127 - );
128 - }
129 -
130 - return [GridContainer, GridRow, GridCell];
131 -}
packages/react-ui/accessibility/src/ReactFocusTable.js new
+220
@@ -0,0 +1,220 @@
1 +/**
2 + * Copyright (c) Facebook, Inc. and its affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow
8 + */
9 +
10 +import type {ReactScopeMethods} from 'shared/ReactTypes';
11 +import type {KeyboardEvent} from 'react-ui/events/keyboard';
12 +
13 +import React from 'react';
14 +import {tabFocusableImpl} from './TabbableScope';
15 +import {useKeyboard} from 'react-ui/events/keyboard';
16 +
17 +type FocusCellProps = {
18 + children?: React.Node,
19 +};
20 +
21 +type FocusRowProps = {
22 + children: React.Node,
23 +};
24 +
25 +type FocusTableProps = {|
26 + children: React.Node,
27 + id?: string,
28 + onKeyboardOut?: (
29 + direction: 'left' | 'right' | 'up' | 'down',
30 + focusTableByID: (id: string) => void,
31 + ) => void,
32 +|};
33 +
34 +const {useRef} = React;
35 +
36 +export function focusFirstCellOnTable(table: ReactScopeMethods): void {
37 + const rows = table.getChildren();
38 + if (rows !== null) {
39 + const firstRow = rows[0];
40 + if (firstRow !== null) {
41 + const cells = firstRow.getChildren();
42 + if (cells !== null) {
43 + const firstCell = cells[0];
44 + if (firstCell !== null) {
45 + const tabbableNodes = firstCell.getScopedNodes();
46 + if (tabbableNodes !== null) {
47 + const firstElem = tabbableNodes[0];
48 + if (firstElem !== null) {
49 + firstElem.focus();
50 + }
51 + }
52 + }
53 + }
54 + }
55 + }
56 +}
57 +
58 +function focusCell(cell: ReactScopeMethods): void {
59 + const tabbableNodes = cell.getScopedNodes();
60 + if (tabbableNodes !== null && tabbableNodes.length > 0) {
61 + tabbableNodes[0].focus();
62 + }
63 +}
64 +
65 +function focusCellByRowIndex(row: ReactScopeMethods, rowIndex: number): void {
66 + const cells = row.getChildren();
67 + if (cells !== null) {
68 + const cell = cells[rowIndex];
69 + if (cell) {
70 + focusCell(cell);
71 + }
72 + }
73 +}
74 +
75 +function getRowCells(currentCell: ReactScopeMethods) {
76 + const row = currentCell.getParent();
77 + if (row !== null && row.getProps().type === 'row') {
78 + const cells = row.getChildren();
79 + if (cells !== null) {
80 + const rowIndex = cells.indexOf(currentCell);
81 + return [cells, rowIndex];
82 + }
83 + }
84 + return [null, 0];
85 +}
86 +
87 +function getRows(currentCell: ReactScopeMethods) {
88 + const row = currentCell.getParent();
89 + if (row !== null && row.getProps().type === 'row') {
90 + const table = row.getParent();
91 + if (table !== null && table.getProps().type === 'table') {
92 + const rows = table.getChildren();
93 + if (rows !== null) {
94 + const columnIndex = rows.indexOf(row);
95 + return [rows, columnIndex];
96 + }
97 + }
98 + }
99 + return [null, 0];
100 +}
101 +
102 +function triggerNavigateOut(
103 + currentCell: ReactScopeMethods,
104 + direction: 'left' | 'right' | 'up' | 'down',
105 +): void {
106 + const row = currentCell.getParent();
107 + if (row !== null && row.getProps().type === 'row') {
108 + const table = row.getParent();
109 + if (table !== null) {
110 + const props = table.getProps();
111 + const onKeyboardOut = props.onKeyboardOut;
112 + if (props.type === 'table' && typeof onKeyboardOut === 'function') {
113 + const focusTableByID = (id: string) => {
114 + const topLevelTables = table.getChildrenFromRoot();
115 + if (topLevelTables !== null) {
116 + for (let i = 0; i < topLevelTables.length; i++) {
117 + const topLevelTable = topLevelTables[i];
118 + if (topLevelTable.getProps().id === id) {
119 + focusFirstCellOnTable(topLevelTable);
120 + return;
121 + }
122 + }
123 + }
124 + };
125 + onKeyboardOut(direction, focusTableByID);
126 + }
127 + }
128 + }
129 +}
130 +
131 +export function createFocusTable(): Array<React.Component> {
132 + const TableScope = React.unstable_createScope(tabFocusableImpl);
133 +
134 + function Table({children, onKeyboardOut, id}): FocusTableProps {
135 + return (
136 + <TableScope type="table" onKeyboardOut={onKeyboardOut} id={id}>
137 + {children}
138 + </TableScope>
139 + );
140 + }
141 +
142 + function Row({children}): FocusRowProps {
143 + return <TableScope type="row">{children}</TableScope>;
144 + }
145 +
146 + function Cell({children}): FocusCellProps {
147 + const scopeRef = useRef(null);
148 + const keyboard = useKeyboard({
149 + onKeyDown(event: KeyboardEvent): boolean {
150 + const currentCell = scopeRef.current;
151 + switch (event.key) {
152 + case 'UpArrow': {
153 + const [cells, rowIndex] = getRowCells(currentCell);
154 + if (cells !== null) {
155 + const [columns, columnIndex] = getRows(currentCell);
156 + if (columns !== null) {
157 + if (columnIndex > 0) {
158 + const column = columns[columnIndex - 1];
159 + focusCellByRowIndex(column, rowIndex);
160 + } else if (columnIndex === 0) {
161 + triggerNavigateOut(currentCell, 'up');
162 + }
163 + }
164 + }
165 + return false;
166 + }
167 + case 'DownArrow': {
168 + const [cells, rowIndex] = getRowCells(currentCell);
169 + if (cells !== null) {
170 + const [columns, columnIndex] = getRows(currentCell);
171 + if (columns !== null) {
172 + if (columnIndex !== -1) {
173 + if (columnIndex === columns.length - 1) {
174 + triggerNavigateOut(currentCell, 'down');
175 + } else {
176 + const column = columns[columnIndex + 1];
177 + focusCellByRowIndex(column, rowIndex);
178 + }
179 + }
180 + }
181 + }
182 + return false;
183 + }
184 + case 'LeftArrow': {
185 + const [cells, rowIndex] = getRowCells(currentCell);
186 + if (cells !== null) {
187 + if (rowIndex > 0) {
188 + focusCell(cells[rowIndex - 1]);
189 + } else if (rowIndex === 0) {
190 + triggerNavigateOut(currentCell, 'left');
191 + }
192 + }
193 + return false;
194 + }
195 + case 'RightArrow': {
196 + const [cells, rowIndex] = getRowCells(currentCell);
197 + if (cells !== null) {
198 + if (rowIndex !== -1) {
199 + if (rowIndex === cells.length - 1) {
200 + triggerNavigateOut(currentCell, 'right');
201 + } else {
202 + focusCell(cells[rowIndex + 1]);
203 + }
204 + }
205 + }
206 + return false;
207 + }
208 + }
209 + return true;
210 + },
211 + });
212 + return (
213 + <TableScope listeners={keyboard} ref={scopeRef} type="cell">
214 + {children}
215 + </TableScope>
216 + );
217 + }
218 +
219 + return [Table, Row, Cell];
220 +}
packages/react-ui/accessibility/src/__tests__/FocusGrid-test.internal.js deleted
-152
@@ -1,152 +0,0 @@
1 -/**
2 - * Copyright (c) Facebook, Inc. and its affiliates.
3 - *
4 - * This source code is licensed under the MIT license found in the
5 - * LICENSE file in the root directory of this source tree.
6 - *
7 - * @flow
8 - */
9 -
10 -import {createEventTarget} from 'react-ui/events/src/dom/testing-library';
11 -
12 -let React;
13 -let ReactFeatureFlags;
14 -let createFocusGrid;
15 -
16 -describe('TabFocusController', () => {
17 - beforeEach(() => {
18 - jest.resetModules();
19 - ReactFeatureFlags = require('shared/ReactFeatureFlags');
20 - ReactFeatureFlags.enableScopeAPI = true;
21 - ReactFeatureFlags.enableFlareAPI = true;
22 - createFocusGrid = require('../FocusGrid').createFocusGrid;
23 - React = require('react');
24 - });
25 -
26 - describe('ReactDOM', () => {
27 - let ReactDOM;
28 - let container;
29 -
30 - beforeEach(() => {
31 - ReactDOM = require('react-dom');
32 - container = document.createElement('div');
33 - document.body.appendChild(container);
34 - });
35 -
36 - afterEach(() => {
37 - document.body.removeChild(container);
38 - container = null;
39 - });
40 -
41 - it('handles tab operations', () => {
42 - const [
43 - FocusGridContainer,
44 - FocusGridRow,
45 - FocusGridCell,
46 - ] = createFocusGrid();
47 - const firstButtonRef = React.createRef();
48 -
49 - const Test = () => (
50 - <FocusGridContainer>
51 - <table>
52 - <tbody>
53 - <FocusGridRow>
54 - <tr>
55 - <FocusGridCell>
56 - <td>
57 - <button ref={firstButtonRef}>A1</button>
58 - </td>
59 - </FocusGridCell>
60 - <FocusGridCell>
61 - <td>
62 - <button>A2</button>
63 - </td>
64 - </FocusGridCell>
65 - <FocusGridCell>
66 - <td>
67 - <button>A3</button>
68 - </td>
69 - </FocusGridCell>
70 - </tr>
71 - </FocusGridRow>
72 - <FocusGridRow>
73 - <tr>
74 - <FocusGridCell>
75 - <td>
76 - <button>B1</button>
77 - </td>
78 - </FocusGridCell>
79 - <FocusGridCell>
80 - <td>
81 - <button>B2</button>
82 - </td>
83 - </FocusGridCell>
84 - <FocusGridCell>
85 - <td>
86 - <button>B3</button>
87 - </td>
88 - </FocusGridCell>
89 - </tr>
90 - </FocusGridRow>
91 - <FocusGridRow>
92 - <tr>
93 - <FocusGridCell>
94 - <td>
95 - <button>C1</button>
96 - </td>
97 - </FocusGridCell>
98 - <FocusGridCell>
99 - <td>
100 - <button>C2</button>
101 - </td>
102 - </FocusGridCell>
103 - <FocusGridCell>
104 - <td>
105 - <button>C3</button>
106 - </td>
107 - </FocusGridCell>
108 - </tr>
109 - </FocusGridRow>
110 - </tbody>
111 - </table>
112 - </FocusGridContainer>
113 - );
114 -
115 - ReactDOM.render(<Test />, container);
116 - const a1 = createEventTarget(firstButtonRef.current);
117 - a1.focus();
118 - a1.keydown({
119 - key: 'RightArrow',
120 - });
121 - expect(document.activeElement.textContent).toBe('A2');
122 -
123 - const a2 = createEventTarget(document.activeElement);
124 - a2.keydown({
125 - key: 'DownArrow',
126 - });
127 - expect(document.activeElement.textContent).toBe('B2');
128 -
129 - const b2 = createEventTarget(document.activeElement);
130 - b2.keydown({
131 - key: 'LeftArrow',
132 - });
133 - expect(document.activeElement.textContent).toBe('B1');
134 -
135 - const b1 = createEventTarget(document.activeElement);
136 - b1.keydown({
137 - key: 'DownArrow',
138 - });
139 - expect(document.activeElement.textContent).toBe('C1');
140 -
141 - const c1 = createEventTarget(document.activeElement);
142 - c1.keydown({
143 - key: 'DownArrow',
144 - });
145 - expect(document.activeElement.textContent).toBe('C1');
146 - c1.keydown({
147 - key: 'UpArrow',
148 - });
149 - expect(document.activeElement.textContent).toBe('B1');
150 - });
151 - });
152 -});
packages/react-ui/accessibility/src/__tests__/ReactFocusTable-test.internal.js new
+257
@@ -0,0 +1,257 @@
1 +/**
2 + * Copyright (c) Facebook, Inc. and its affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow
8 + */
9 +
10 +import {createEventTarget} from 'react-ui/events/src/dom/testing-library';
11 +
12 +let React;
13 +let ReactFeatureFlags;
14 +let createFocusTable;
15 +
16 +describe('ReactFocusTable', () => {
17 + beforeEach(() => {
18 + jest.resetModules();
19 + ReactFeatureFlags = require('shared/ReactFeatureFlags');
20 + ReactFeatureFlags.enableScopeAPI = true;
21 + ReactFeatureFlags.enableFlareAPI = true;
22 + createFocusTable = require('../ReactFocusTable').createFocusTable;
23 + React = require('react');
24 + });
25 +
26 + describe('ReactDOM', () => {
27 + let ReactDOM;
28 + let container;
29 +
30 + beforeEach(() => {
31 + ReactDOM = require('react-dom');
32 + container = document.createElement('div');
33 + document.body.appendChild(container);
34 + });
35 +
36 + afterEach(() => {
37 + document.body.removeChild(container);
38 + container = null;
39 + });
40 +
41 + function createFocusTableComponent() {
42 + const [FocusTable, FocusTableRow, FocusTableCell] = createFocusTable();
43 +
44 + return ({onKeyboardOut, id}) => (
45 + <FocusTable onKeyboardOut={onKeyboardOut} id={id}>
46 + <table>
47 + <tbody>
48 + <FocusTableRow>
49 + <tr>
50 + <FocusTableCell>
51 + <td>
52 + <button>A1</button>
53 + </td>
54 + </FocusTableCell>
55 + <FocusTableCell>
56 + <td>
57 + <button>A2</button>
58 + </td>
59 + </FocusTableCell>
60 + <FocusTableCell>
61 + <td>
62 + <button>A3</button>
63 + </td>
64 + </FocusTableCell>
65 + </tr>
66 + </FocusTableRow>
67 + <FocusTableRow>
68 + <tr>
69 + <FocusTableCell>
70 + <td>
71 + <button>B1</button>
72 + </td>
73 + </FocusTableCell>
74 + <FocusTableCell>
75 + <td>
76 + <button>B2</button>
77 + </td>
78 + </FocusTableCell>
79 + <FocusTableCell>
80 + <td>
81 + <button>B3</button>
82 + </td>
83 + </FocusTableCell>
84 + </tr>
85 + </FocusTableRow>
86 + <FocusTableRow>
87 + <tr>
88 + <FocusTableCell>
89 + <td>
90 + <button>C1</button>
91 + </td>
92 + </FocusTableCell>
93 + <FocusTableCell>
94 + <td>
95 + <button>C2</button>
96 + </td>
97 + </FocusTableCell>
98 + <FocusTableCell>
99 + <td>
100 + <button>C3</button>
101 + </td>
102 + </FocusTableCell>
103 + </tr>
104 + </FocusTableRow>
105 + </tbody>
106 + </table>
107 + </FocusTable>
108 + );
109 + }
110 +
111 + it('handles keyboard arrow operations', () => {
112 + const Test = createFocusTableComponent();
113 +
114 + ReactDOM.render(<Test />, container);
115 + const buttons = document.querySelectorAll('button');
116 + const a1 = createEventTarget(buttons[0]);
117 + a1.focus();
118 + a1.keydown({
119 + key: 'RightArrow',
120 + });
121 + expect(document.activeElement.textContent).toBe('A2');
122 +
123 + const a2 = createEventTarget(document.activeElement);
124 + a2.keydown({
125 + key: 'DownArrow',
126 + });
127 + expect(document.activeElement.textContent).toBe('B2');
128 +
129 + const b2 = createEventTarget(document.activeElement);
130 + b2.keydown({
131 + key: 'LeftArrow',
132 + });
133 + expect(document.activeElement.textContent).toBe('B1');
134 +
135 + const b1 = createEventTarget(document.activeElement);
136 + b1.keydown({
137 + key: 'DownArrow',
138 + });
139 + expect(document.activeElement.textContent).toBe('C1');
140 +
141 + const c1 = createEventTarget(document.activeElement);
142 + c1.keydown({
143 + key: 'DownArrow',
144 + });
145 + expect(document.activeElement.textContent).toBe('C1');
146 + c1.keydown({
147 + key: 'UpArrow',
148 + });
149 + expect(document.activeElement.textContent).toBe('B1');
150 + });
151 +
152 + it('handles keyboard arrow operations between tables', () => {
153 + const leftSidebarRef = React.createRef();
154 + const FocusTable = createFocusTableComponent();
155 +
156 + function Test() {
157 + return (
158 + <div>
159 + <h1>Title</h1>
160 + <aside ref={leftSidebarRef}>
161 + <h2>Left Sidebar</h2>
162 + <FocusTable
163 + id="left-sidebar"
164 + onKeyboardOut={(direction, focusTableByID) => {
165 + if (direction === 'right') {
166 + focusTableByID('content');
167 + }
168 + }}
169 + />
170 + </aside>
171 + <section>
172 + <h2>Content</h2>
173 + <FocusTable
174 + id="content"
175 + onKeyboardOut={(direction, focusTableByID) => {
176 + if (direction === 'right') {
177 + focusTableByID('right-sidebar');
178 + } else if (direction === 'left') {
179 + focusTableByID('left-sidebar');
180 + }
181 + }}
182 + />
183 + </section>
184 + <aside>
185 + <h2>Right Sidebar</h2>
186 + <FocusTable
187 + id="right-sidebar"
188 + onKeyboardOut={(direction, focusTableByID) => {
189 + if (direction === 'left') {
190 + focusTableByID('content');
191 + }
192 + }}
193 + />
194 + </aside>
195 + </div>
196 + );
197 + }
198 +
199 + ReactDOM.render(<Test />, container);
200 + const buttons = document.querySelectorAll('button');
201 + let a1 = createEventTarget(buttons[0]);
202 + a1.focus();
203 + a1.keydown({
204 + key: 'RightArrow',
205 + });
206 + expect(document.activeElement.textContent).toBe('A2');
207 +
208 + let a2 = createEventTarget(document.activeElement);
209 + a2.keydown({
210 + key: 'RightArrow',
211 + });
212 + expect(document.activeElement.textContent).toBe('A3');
213 +
214 + let a3 = createEventTarget(document.activeElement);
215 + a3.keydown({
216 + key: 'RightArrow',
217 + });
218 + expect(document.activeElement.textContent).toBe('A1');
219 +
220 + a1 = createEventTarget(document.activeElement);
221 + a1.keydown({
222 + key: 'RightArrow',
223 + });
224 + expect(document.activeElement.textContent).toBe('A2');
225 +
226 + a2 = createEventTarget(document.activeElement);
227 + a2.keydown({
228 + key: 'RightArrow',
229 + });
230 + expect(document.activeElement.textContent).toBe('A3');
231 +
232 + a3 = createEventTarget(document.activeElement);
233 + a3.keydown({
234 + key: 'RightArrow',
235 + });
236 + expect(document.activeElement.textContent).toBe('A1');
237 +
238 + a1 = createEventTarget(document.activeElement);
239 + a1.keydown({
240 + key: 'RightArrow',
241 + });
242 + expect(document.activeElement.textContent).toBe('A2');
243 +
244 + a2 = createEventTarget(document.activeElement);
245 + a2.keydown({
246 + key: 'RightArrow',
247 + });
248 + expect(document.activeElement.textContent).toBe('A3');
249 +
250 + a3 = createEventTarget(document.activeElement);
251 + a3.keydown({
252 + key: 'RightArrow',
253 + });
254 + expect(document.activeElement.textContent).toBe('A3');
255 + });
256 + });
257 +});
packages/shared/ReactTypes.js
+1
@@ -168,6 +168,7 @@ export type ReactScopeMethods = {|
168 getChildren(): null | Array<ReactScopeMethods>,
169 getChildrenFromRoot(): null | Array<ReactScopeMethods>,
170 getParent(): null | ReactScopeMethods,
171 + getProps(): Object,
172 getScopedNodes(): null | Array<Object>,
173 |};
174