Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
AlaricBaraou committed Jun 16, 2021
2 parents 9fdd3de + 6ef0144 commit 0707ce6
Showing 1 changed file with 73 additions and 78 deletions.
151 changes: 73 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,30 @@

![Imgur](https://i.imgur.com/sSAD7m7.png)

```bash
npm install @react-three/a11y
```

`@react-three/a11y` brings accessibility to webGL with easy-to-use [react-three-fiber](https://github.com/pmndrs/react-three-fiber) components:
@react-three/a11y brings accessibility to webGL with easy-to-use react-three-fiber components:

- Focus and focus indication
- Tab index and keyboard navigation
- Screen reader support and alt-text
- Roles and cursor shapes
- Descriptive links

Live demo: https://n4rzi.csb.app
You can try a [live demo here](https://n4rzi.csb.app).

# How to use
```bash
npm install @react-three/a11y
```

## Quick overview to get started

note: The full documentation can be found on the [pmndrs website](https://docs.pmnd.rs/a11y/introduction).

First, place the `A11yAnnouncer` component next to the R3F Canvas component. This is critical, because it will manage the screen-reader and help emulate focus!
### The A11yAnnouncer component

First, place the A11yAnnouncer component next to the R3F Canvas component. this componant is critical since it manage some screen-reader features.

```jsx
import { Canvas } from 'react-three-fiber'
import { Canvas } from '@react-three/fiber'
import { A11yAnnouncer } from '@react-three/a11y'

function App() {
Expand All @@ -38,35 +42,20 @@ function App() {
}
```

### Then wrap components you want to make accessible with the A11y component

To add accessibility features to your scene you'll have to wrap components you want to make focusable with the `A11y` component:

```jsx
import { A11y } from '@react-three/a11y'

[...]
<A11y>
<MyComponent />
</A11y>
```

`MyComponent` can now receive focus. More accurately, the emulated "focus" will handled at the `A11y` components which acts as a provider for children to access its state. But even if objects are focusable, nothing will be displayed or shown by default.

## Accessing the hover, focused & pressed state

For each child wrapped in the `A11y` component, you can access the `focus`, `hover` and `pressed` state like so:

```jsx
import { useA11y } from '@react-three/a11y'

function Box(props) {
const a11y = useA11y()
return (
<mesh {...props}>
<boxBufferGeometry />
<meshStandardMaterial color={a11y.hover || a11y.focus ? 'hotpink' : 'orange'} />
</mesh>
)
}
```
`MyComponent` can now receive focus. More accurately, the emulated "focus" will be handled at the `A11y` components which acts as a provider
for children to access its state. But even if objects are focusable, nothing will be displayed or shown by default.

## Call function on focus

Expand All @@ -86,35 +75,17 @@ The `actionCall` prop of `A11y` will be called each time this component gets cli

## Provide a description of the currently focused / hovered element

When using the `description` prop, the `A11y` component will provide a description to the screen reader users on focus/hover.
When using the `description` prop in combination with the `role` prop, the `A11y` component will provide a description to the screen reader users on focus/hover.
Optionally, you can also show the description to the user on hover by setting `showAltText={true}`.

```jsx
// Reads "A rotating red square" to screen readers on focus / hover
<A11y role="content" description="A rotating red square" ... />
// Reads "A bouncing blue sphere" to screen readers on focus / hover while also showing it on mouseover
<A11y role="content" description="A bouncing blue sphere" showAltText ... />
// Reads "A rotating red square" to screen readers on focus / hover while also showing it on mouseover
<A11y role="content" description="A rotating red square" showAltText ... />
// Reads "Button, open menu + (description on how to activate depending on the screen reader)" to screen readers on focus / hover
<A11y role="button" description="open menu" actionCall={()=>{someFunction()}} ... />
```

If your `A11y` component has the `role="button"`, you can use three more props:

- `activationMsg`: When the user will click/activate the "button" the screen reader will read the passed message
- `deactivationMsg`: When set, it turns your button in a togglable button. Which means it now has a on/off state. Screen readers will read the state of the button as well as the activation/disactivation messages passsed.
- `pressedDescription`: When set, it turns your button in a togglable button. Which means it now has a on/off state. This description will replace the one passed via `description` when the toggle is active.

```jsx
// Reads the description on hover/focus then will read activationMsg if clicked/pressed
<A11y role="button" description="Sends a thank you email to the team" activationMsg="Email is sending" ... />
// Reads the description on hover/focus then will read activationMsg if turned on or deactivationMsg if tuned off
<A11y
role="button"
description="This button can enable dark theme. Dark theme is off"
pressedDescription="This button can disable dark theme. Dark theme is on"
activationMsg="Dark theme enabled"
deactivationMsg="Dark theme disabled" ... />
```

## The three roles of the `A11y` component
## The four roles of the A11y component

Like in HTML, you can focus different kind of elements and expect different things depending on what you're focusing.

Expand All @@ -126,25 +97,41 @@ Like in HTML, you can focus different kind of elements and expect different thin

Uses the `default` cursor. This role is meant to provide information to screen readers or to serve as a step for a user to navigate your site using Tab for instance. It's not meant to trigger anything on click or to be activable with the Keyboard. Therefore it won't show a pointer cursor on hover.

#### Buttons
[Read more about role content](/a11y/roles/content)

#### Button

```jsx
<A11y
role="button"
activationMsg="Button activated"
deactivationMsg="Button deactivated"
pressedDescription="Button pressed" ... />
description="Send email"
activationMsg="Sending email" ... />
```

Uses the `pointer` cursor. Special attributes: `activationMsg`, `deactivationMsg` and `pressedDescription`.
Uses the `pointer` cursor. Special attributes: `activationMsg`.

This role is meant to emulate the behaviour of a button or a togglable button. It will display a cursor pointer when your cursor is over the linked 3D object. It will call a function on click but also on any kind of action that would trigger a focused button (Enter, Double-Tap, ...). It is also actionnable by user using a screen reader.

You can turn it into a button with aria-pressed by using the role togglebutton, you'll then be able to use the following propertie deactivationMsg in addition to the usual description and activationMsg properties.
[Read more about role button](https://docs.pmnd.rs/a11y/roles/button)

#### ToggleButton

By using the role togglebutton, you'll emulate a button with two state that will have the `aria-pressed` attribute.
You'll then be able to use the deactivationMsg property in addition to the usual description and activationMsg properties.

```jsx
<A11y
role="togglebutton"
description="Dark theme "
activationMsg="Switched to dark theme"
deactivationMsg="Switched to light theme" ... />
```

#### Links
Special attributes: `deactivationMsg`

[Read more about role ToggleButton](https://docs.pmnd.rs/a11y/roles/togglebutton)

#### Link

```jsx
<A11y role="link" href="https://url.com" ... />
Expand All @@ -154,33 +141,39 @@ Uses the `pointer` cursor. Special attributes: `href`.

This role is meant to emulate the behaviour of a regular html link. It should be used in combination with something that will trigger navigation on click.

```diff
- Don't forget to provide the href attribute as he is required for screen readers to read it correctly !
- It will have no effect on the navigation, it's just used as information
```
<Hint>
- Don't forget to provide the href attribute as he is required for screen readers to read it
correctly ! - It will have no effect on the navigation, it's just used as information
</Hint>

[Read more about role link](https://docs.pmnd.rs/a11y/roles/link)

## Screen Reader Support

In order to provide informations to screen reader users and use this package at its full potential, fill the `description` prop of all your `A11y` components and use the appropriate `role` prop on each of them.

### Use of section
### Use of section

For screen readears, it might be useful to provide additionnal information on how to use some unconventional UI.
You can do it by wrapping the concerned part of your code relative to this UI in the A11ySection like so.

```jsx
<A11ySection
label="Shape carousel"
description="This carousel contains 5 shapes. Use the Previous and Next buttons to cycle through all the shapes.">
[...]
label="Shape carousel"
description="This carousel contains 5 shapes. Use the Previous and Next buttons to cycle through all the shapes."
>
[...]
</A11ySection>
```

## Access user preferences

The A11yUserPreferences component i available in order to access user preferences such as
The A11yUserPreferences component is available in order to access user preferences such as

- prefers-reduced-motion
- prefers-color-scheme

Take a look at the [wiki section](https://github.com/pmndrs/react-three-a11y/wiki/Access-user-preferences) or the [demo](https://n4rzi.csb.app) to see it in action and how to use it. The demo will adapt to your system preferences.
Take a look at [the A11yUserPreferences page](https://docs.pmnd.rs/a11y/access-user-preferences) or the [demo](https://n4rzi.csb.app) to see it in action and how to use it. The demo will adapt to your system preferences.

## Additionals Features

Expand All @@ -189,15 +182,17 @@ Use a custom tabindex with for your A11y components by providing a number to the
```jsx
<A11y tabIndex={-1} ... />
```
⚠⚠⚠<br>
Avoid using tabindex values greater than 0. Doing so makes it difficult for people who rely on assistive technology to navigate and operate page content.
Instead, write the document with the elements in a logical sequence.<br>
More about the use of tabIndex on <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex">developer.mozilla.org</a>

## Next Steps

- [ ] Provide a documentation inside the IDE
- [ ] Provide more examples showing how to use it
⚠⚠⚠
<br />
Avoid using tabindex values greater than 0. Doing so makes it difficult for people who rely on
assistive technology to navigate and operate page content. Instead, write the document with the
elements in a logical sequence.
<br />
More about the use of tabIndex on{' '}
<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex">
developer.mozilla.org
</a>

### Author:

Expand Down

0 comments on commit 0707ce6

Please sign in to comment.