Skip to content

Commit a5a622e

Browse files
AlmeroSteyngaearon
authored andcommitted
a11y-doc: Adjust Focus Control to new 16.3 refs + link fixes. (#742)
* a11y-doc: Adjust Focus Control to new 16.3 refs + link fixes. * Update accessibility.md
1 parent 62638c8 commit a5a622e

1 file changed

Lines changed: 41 additions & 23 deletions

File tree

content/docs/accessibility.md

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,25 @@ we need to programmatically nudge the keyboard focus in the right direction. For
142142

143143
MDN Web Docs takes a look at this and describes how we can build [keyboard-navigable JavaScript widgets](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Keyboard-navigable_JavaScript_widgets).
144144

145-
To set focus in React, we can use [Refs to DOM elements](refs-and-the-dom.html).
145+
To set focus in React, we can use [Refs to DOM elements](/docs/refs-and-the-dom.html).
146146

147147
Using this, we first create a ref to an element in the JSX of a component class:
148148

149-
```javascript{2-3,7}
149+
```javascript{4-5,8-9,13}
150150
render() {
151+
constructor(props) {
152+
super(props);
153+
// Create a ref to store the textInput DOM element
154+
this.textInput = React.createRef();
155+
}
156+
// ...
151157
// Use the `ref` callback to store a reference to the text input DOM
152158
// element in an instance field (for example, this.textInput).
153159
return (
154160
<input
155161
type="text"
156-
ref={(input) => { this.textInput = input; }} />
162+
ref={this.textInput}
163+
/>
157164
);
158165
}
159166
```
@@ -163,33 +170,44 @@ Then we can focus it elsewhere in our component when needed:
163170
```javascript
164171
focus() {
165172
// Explicitly focus the text input using the raw DOM API
166-
this.textInput.focus();
173+
// Note: we're accessing "current" to get the DOM node
174+
this.textInput.current.focus();
167175
}
168176
```
169-
170-
Sometimes a parent component needs to set focus to an element in a child component. Although we can create [refs to class components](refs-and-the-dom.html#adding-a-ref-to-a-class-component),
171-
we need a pattern that also works with functional components and when [using refs with HOCs](higher-order-components.html#refs-arent-passed-through).
172-
To ensure that our parent component can always access the ref, we pass a callback as a prop to the child component to [expose the ref to the parent component](refs-and-the-dom.html#exposing-dom-refs-to-parent-components).
173-
174-
```js
175-
// Expose the ref with a callback prop
176-
function Field({ inputRef, ...rest }) {
177-
return <input ref={inputRef} {...rest} />;
177+
178+
Sometimes a parent component needs to set focus to an element in a child component. We can do this by [exposing DOM refs to parent components](/docs/refs-and-the-dom.html#exposing-dom-refs-to-parent-components)
179+
through a special prop on the child component that forwards the parent's ref to the child's DOM node.
180+
181+
```javascript{4,12,16}
182+
function CustomTextInput(props) {
183+
return (
184+
<div>
185+
<input ref={props.inputRef} />
186+
</div>
187+
);
178188
}
179189
180-
// Inside a parent class component's render method...
181-
<Field
182-
inputRef={(inputEl) => {
183-
// This callback gets passed through as a regular prop
184-
this.inputEl = inputEl
185-
}}
190+
class Parent extends React.Component {
191+
constructor(props) {
192+
super(props);
193+
this.inputElement = React.createRef();
194+
}
195+
render() {
196+
return (
197+
<CustomTextInput inputRef={this.inputElement} />
198+
);
199+
}
200+
}
186201
/>
187202
188203
// Now you can set focus when required.
189-
this.inputEl.focus();
204+
this.inputElement.current.focus();
190205
```
191206

192-
A great focus management example is the [react-aria-modal](https://github.com/davidtheclark/react-aria-modal). This is a relatively rare example of a fully accessible modal window. Not only does it set initial focus on
207+
When using a HOC to extend components, it is recommended to [forward the ref](/docs/forwarding-refs.html) to the wrapped component using the `forwardRef` function of React. If a third party HOC
208+
does not implement ref forwarding, the above pattern can still be used as a fallback.
209+
210+
A great focus management example is the [react-aria-modal](https://github.com/davidtheclark/react-aria-modal). This is a relatively rare example of a fully accessible modal window. Not only does it set initial focus on
193211
the cancel button (preventing the keyboard user from accidentally activating the success action) and trap keyboard focus inside the modal, it also resets focus back to the element that
194212
initially triggered the modal.
195213

@@ -203,7 +221,7 @@ initially triggered the modal.
203221
A more complex user experience should not mean a less accessible one. Whereas accessibility is most easily achieved by coding as close to HTML as possible,
204222
even the most complex widget can be coded accessibly.
205223

206-
Here we require knowledge of [ARIA Roles](https://www.w3.org/TR/wai-aria/#roles) as well as [ARIA States and Properties](https://www.w3.org/TR/wai-aria/#states_and_properties).
224+
Here we require knowledge of [ARIA Roles](https://www.w3.org/TR/wai-aria/#roles) as well as [ARIA States and Properties](https://www.w3.org/TR/wai-aria/#states_and_properties).
207225
These are toolboxes filled with HTML attributes that are fully supported in JSX and enable us to construct fully accessible, highly functional React components.
208226

209227
Each type of widget has a specific design pattern and is expected to function in a certain way by users and user agents alike:
@@ -285,7 +303,7 @@ test the technical accessibility of your HTML.
285303

286304
#### aXe, aXe-core and react-axe
287305

288-
Deque Systems offers [aXe-core](https://www.deque.com/products/axe-core/) for automated and end-to-end accessibility tests of your applications. This module includes integrations for Selenium.
306+
Deque Systems offers [aXe-core](https://github.com/dequelabs/axe-core) for automated and end-to-end accessibility tests of your applications. This module includes integrations for Selenium.
289307

290308
[The Accessibility Engine](https://www.deque.com/products/axe/) or aXe, is an accessibility inspector browser extension built on `aXe-core`.
291309

0 commit comments

Comments
 (0)