Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[react-interactions] Add DO_NOT_USE to Scope methods #17835

Merged
merged 1 commit into from
Jan 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm removing this document as we really don't want people to be actively using any of these APIs right now.

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