Skip to content

Commit

Permalink
[react-interactions] Add DO_NOT_USE to Scope methods (#17835)
Browse files Browse the repository at this point in the history
  • Loading branch information
trueadm authored Jan 15, 2020
1 parent 8aefb19 commit b6173e6
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 157 deletions.
63 changes: 0 additions & 63 deletions packages/react-interactions/accessibility/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,74 +14,11 @@ can be found [here](./docs).

Note: React Scopes require the internal React flag `enableScopeAPI`.

When creating a scope, a query function is required. The query function is used
when collecting host nodes that match the criteria of the query function.

```jsx
// This query function only matches host nodes that have the type of "div"
const queryFunction = (type: string, props: Object): boolean => {
if (type === 'div') {
return true;
}
return false;
};

// Create the scope with the queryFunction above
const DivOnlyScope = React.unstable_createScope(queryFunction);

// We can now use this in our components. We need to attach
// a ref so we can get the matching host nodes.
function MyComponent(props) {
const divOnlyScope = useRef(null);
return (
<DivOnlyScope ref={divOnlyScope}>
<div>DIV 1</div>
<div>DIV 2</div>
<div>DIV 3</div>
</DivOnlyScope>
);
}

// Using the ref, we can get the host nodes via getAllNodes()
const divs = divOnlyScope.current.getAllNodes();

// [<div>DIV 1</div>, <div>DIV 2</div>, <div>DIV 3</div>]
console.log(divs);
```

## React Scope Interface

Scopes require a `ref` to access the internal interface of a particular scope.
The internal interface (`ReactScopeInterface`) exposes the following scope API:

### getChildren: () => null | Array<ReactScopeInterface>

Returns an array of all child `ReactScopeInterface` nodes that are
of scopes of the same type. Returns `null` if there are no child scope nodes.

### getChildrenFromRoot: () => null | Array<ReactScopeInterface>

Similar to `getChildren`, except this applies the same traversal from the root of the
React internal tree instead of from the scope node position.

### getParent: () => null | ReactScopeInterface

Returns the parent `ReactScopeInterface` of the scope node or `null` if none exists.

### getProps: () => Object

Returns the current `props` object of the scope node.

### getAllNodes: () => null | Array<HTMLElement>

Returns an array of all child host nodes that successfully match when queried using the
query function passed to the scope. Returns `null` if there are no matching host nodes.

### getFirstNode: () => null | HTMLElement

Returns the first child host node that successfully matches when queried using the
query function passed to the scope. Returns `null` if there is no matching host node.

### containsNode: (node: HTMLElement) => boolean

Returns `true` or `false` depending on if the given `HTMLElement` is a descendant
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function FocusableNodeCollector(props) {
const scope = scopeRef.current;

if (scope) {
const tabFocusableNodes = scope.queryAllNodes(tabbableScopeQuery);
const tabFocusableNodes = scope.DO_NOT_USE_queryAllNodes(tabbableScopeQuery);
if (tabFocusableNodes && props.onFocusableNodes) {
props.onFocusableNodes(tabFocusableNodes);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default function FocusContain({
disabled !== true &&
!scope.containsNode(document.activeElement)
) {
const fistElem = scope.queryFirstNode(scopeQuery);
const fistElem = scope.DO_NOT_USE_queryFirstNode(scopeQuery);
if (fistElem !== null) {
fistElem.focus();
}
Expand Down
20 changes: 11 additions & 9 deletions packages/react-interactions/accessibility/src/FocusGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function focusGroupItem(
cell: ReactScopeMethods,
event: KeyboardEvent,
): void {
const firstScopedNode = cell.queryFirstNode(scopeQuery);
const firstScopedNode = cell.DO_NOT_USE_queryFirstNode(scopeQuery);
if (firstScopedNode !== null) {
firstScopedNode.focus();
event.preventDefault();
Expand All @@ -46,7 +46,7 @@ function getPreviousGroupItem(
group: ReactScopeMethods,
currentItem: ReactScopeMethods,
): null | ReactScopeMethods {
const items = group.getChildren();
const items = group.DO_NOT_USE_getChildren();
if (items !== null) {
const currentItemIndex = items.indexOf(currentItem);
const wrap = getGroupProps(currentItem).wrap;
Expand All @@ -63,7 +63,7 @@ function getNextGroupItem(
group: ReactScopeMethods,
currentItem: ReactScopeMethods,
): null | ReactScopeMethods {
const items = group.getChildren();
const items = group.DO_NOT_USE_getChildren();
if (items !== null) {
const currentItemIndex = items.indexOf(currentItem);
const wrap = getGroupProps(currentItem).wrap;
Expand All @@ -78,9 +78,9 @@ function getNextGroupItem(
}

function getGroupProps(currentCell: ReactScopeMethods): Object {
const group = currentCell.getParent();
const group = currentCell.DO_NOT_USE_getParent();
if (group !== null) {
const groupProps = group.getProps();
const groupProps = group.DO_NOT_USE_getProps();
if (groupProps && groupProps.type === 'group') {
return groupProps;
}
Expand Down Expand Up @@ -125,19 +125,21 @@ export function createFocusGroup(
onKeyDown(event: KeyboardEvent): void {
const currentItem = scopeRef.current;
if (currentItem !== null) {
const group = currentItem.getParent();
const groupProps = group && group.getProps();
const group = currentItem.DO_NOT_USE_getParent();
const groupProps = group && group.DO_NOT_USE_getProps();
if (group !== null && groupProps.type === 'group') {
const portrait = groupProps.portrait;
const key = event.key;

if (key === 'Tab') {
const tabScopeQuery = getGroupProps(currentItem).tabScopeQuery;
if (tabScopeQuery) {
const groupScope = currentItem.getParent();
const groupScope = currentItem.DO_NOT_USE_getParent();
if (groupScope) {
const activeNode = document.activeElement;
const nodes = groupScope.queryAllNodes(tabScopeQuery);
const nodes = groupScope.DO_NOT_USE_queryAllNodes(
tabScopeQuery,
);
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
if (node !== activeNode) {
Expand Down
6 changes: 3 additions & 3 deletions packages/react-interactions/accessibility/src/FocusManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function focusFirst(
scopeQuery: (type: string | Object, props: Object) => boolean,
scope: ReactScopeMethods,
): void {
const firstNode = scope.queryFirstNode(scopeQuery);
const firstNode = scope.DO_NOT_USE_queryFirstNode(scopeQuery);
if (firstNode) {
focusElem(firstNode);
}
Expand Down Expand Up @@ -101,7 +101,7 @@ export function focusPrevious(
export function getNextScope(
scope: ReactScopeMethods,
): null | ReactScopeMethods {
const allScopes = scope.getChildrenFromRoot();
const allScopes = scope.DO_NOT_USE_getChildrenFromRoot();
if (allScopes === null) {
return null;
}
Expand All @@ -115,7 +115,7 @@ export function getNextScope(
export function getPreviousScope(
scope: ReactScopeMethods,
): null | ReactScopeMethods {
const allScopes = scope.getChildrenFromRoot();
const allScopes = scope.DO_NOT_USE_getChildrenFromRoot();
if (allScopes === null) {
return null;
}
Expand Down
48 changes: 25 additions & 23 deletions packages/react-interactions/accessibility/src/FocusTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function focusScope(
cell: ReactScopeMethods,
event?: KeyboardEvent,
): void {
const firstScopedNode = cell.queryFirstNode(scopeQuery);
const firstScopedNode = cell.DO_NOT_USE_queryFirstNode(scopeQuery);
if (firstScopedNode !== null) {
firstScopedNode.focus();
if (event) {
Expand All @@ -58,13 +58,13 @@ function focusCellByColumnIndex(
columnIndex: number,
event?: KeyboardEvent,
): void {
const cells = row.getChildren();
const cells = row.DO_NOT_USE_getChildren();
if (cells !== null) {
let colSize = 0;
for (let i = 0; i < cells.length; i++) {
const cell = cells[i];
if (cell) {
colSize += cell.getProps().colSpan || 1;
colSize += cell.DO_NOT_USE_getProps().colSpan || 1;
if (colSize > columnIndex) {
focusScope(scopeQuery, cell, event);
return;
Expand All @@ -84,7 +84,7 @@ function getCellIndexes(
if (cell === currentCell) {
return [i, i + totalColSpan];
}
const colSpan = cell.getProps().colSpan;
const colSpan = cell.DO_NOT_USE_getProps().colSpan;
if (colSpan) {
totalColSpan += colSpan - 1;
}
Expand All @@ -93,9 +93,9 @@ function getCellIndexes(
}

function getRowCells(currentCell: ReactScopeMethods) {
const row = currentCell.getParent();
if (row !== null && row.getProps().type === 'row') {
const cells = row.getChildren();
const row = currentCell.DO_NOT_USE_getParent();
if (row !== null && row.DO_NOT_USE_getProps().type === 'row') {
const cells = row.DO_NOT_USE_getChildren();
if (cells !== null) {
const [rowIndex, rowIndexWithColSpan] = getCellIndexes(
cells,
Expand All @@ -108,11 +108,11 @@ function getRowCells(currentCell: ReactScopeMethods) {
}

function getRows(currentCell: ReactScopeMethods) {
const row = currentCell.getParent();
if (row !== null && row.getProps().type === 'row') {
const table = row.getParent();
if (table !== null && table.getProps().type === 'table') {
const rows = table.getChildren();
const row = currentCell.DO_NOT_USE_getParent();
if (row !== null && row.DO_NOT_USE_getProps().type === 'row') {
const table = row.DO_NOT_USE_getParent();
if (table !== null && table.DO_NOT_USE_getProps().type === 'table') {
const rows = table.DO_NOT_USE_getChildren();
if (rows !== null) {
const columnIndex = rows.indexOf(row);
return [rows, columnIndex];
Expand All @@ -127,11 +127,11 @@ function triggerNavigateOut(
direction: 'left' | 'right' | 'up' | 'down',
event,
): void {
const row = currentCell.getParent();
if (row !== null && row.getProps().type === 'row') {
const table = row.getParent();
const row = currentCell.DO_NOT_USE_getParent();
if (row !== null && row.DO_NOT_USE_getProps().type === 'row') {
const table = row.DO_NOT_USE_getParent();
if (table !== null) {
const props = table.getProps();
const props = table.DO_NOT_USE_getProps();
const onKeyboardOut = props.onKeyboardOut;
if (props.type === 'table' && typeof onKeyboardOut === 'function') {
onKeyboardOut(direction, event);
Expand All @@ -143,11 +143,11 @@ function triggerNavigateOut(
}
function getTableProps(currentCell: ReactScopeMethods): Object {
const row = currentCell.getParent();
if (row !== null && row.getProps().type === 'row') {
const table = row.getParent();
const row = currentCell.DO_NOT_USE_getParent();
if (row !== null && row.DO_NOT_USE_getProps().type === 'row') {
const table = row.DO_NOT_USE_getParent();
if (table !== null) {
return table.getProps();
return table.DO_NOT_USE_getProps();
}
}
return {};
Expand Down Expand Up @@ -207,12 +207,14 @@ export function createFocusTable(
if (key === 'Tab') {
const tabScopeQuery = getTableProps(currentCell).tabScopeQuery;
if (tabScopeQuery) {
const rowScope = currentCell.getParent();
const rowScope = currentCell.DO_NOT_USE_getParent();
if (rowScope) {
const tableScope = rowScope.getParent();
const tableScope = rowScope.DO_NOT_USE_getParent();
if (tableScope) {
const activeNode = document.activeElement;
const nodes = tableScope.queryAllNodes(tabScopeQuery);
const nodes = tableScope.DO_NOT_USE_queryAllNodes(
tabScopeQuery,
);
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
if (node !== activeNode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('TabbableScopeQuery', () => {
container = null;
});

it('queryAllNodes() works as intended', () => {
it('DO_NOT_USE_queryAllNodes() works as intended', () => {
const scopeRef = React.createRef();
const nodeRefA = React.createRef();
const nodeRefB = React.createRef();
Expand All @@ -60,7 +60,7 @@ describe('TabbableScopeQuery', () => {
}

ReactDOM.render(<Test />, container);
let nodes = scopeRef.current.queryAllNodes(tabbableScopeQuery);
let nodes = scopeRef.current.DO_NOT_USE_queryAllNodes(tabbableScopeQuery);
expect(nodes).toEqual([
nodeRefA.current,
nodeRefB.current,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function getTabbableNodes(
number,
null | HTMLElement,
] {
const tabbableNodes = scope.queryAllNodes(scopeQuery);
const tabbableNodes = scope.DO_NOT_USE_queryAllNodes(scopeQuery);
if (tabbableNodes === null || tabbableNodes.length === 0) {
return [null, null, null, 0, null];
}
Expand Down
Loading

0 comments on commit b6173e6

Please sign in to comment.