Some best practices for code thinking about a11y
In general, we encourage our team while developing to make sure that all focusable elements are accessible through tab navigation. There are a few elements that are focusable by default:
- Buttons
- Inputs
- Links
Currently, we use react-hook-form
library together with your visual components to help us build our forms on Rocket.Chat. But in order to achieve a good experience beyond visuals we should have some practices in mind to build accessible forms.
One of the most common issues of a11y is not adding the proper label for an input. In order to add a label to the input, make sure to use for
attribute to connect them.
// All React Components mentioned are part of fuselage
<form >
<Field>
<FieldLabel htmlFor='myInputId'>My Label</FieldLabel>
<FieldRow>
<TextInput id='myInputId' />
</FieldRow>
</Field>
</form>
In huge applications, it is hard to maintain unique IDs with strings, so you can use useUniqueId
provided from @rocket.chat/fuselage-hooks
to generate unique IDs and use them on your inputs
Some inputs are not clear about what information should be entered or its necessary to give more information about it. Visually it's not enough, we have to tell screen readers that information as well, so we can take advantage of aria-describedby
to add that.
// All React Components mentioned are part of fuselage
<form >
<Field>
<FieldLabel htmlFor='myInputId'>My Label</FieldLabel>
<FieldRow>
<TextInput id='myInputId' aria-describedby='myInputId-hint'>
</FieldRow>
<FieldHint id='myInputId-hint'>This information is super important to be found by screen readers</FieldHint>
</Field>
</form>
Some inputs are not clear about what information should be entered or its necessary to give more information about it. Visually it's not enough, we have to tell screen readers that information as well, so we can take advantage of aria-describedby
to add that.
// All React Components mentioned are part of fuselage
<form >
<Field>
<FieldLabel htmlFor='myInputId'>My Label</FieldLabel>
<FieldRow>
<TextInput id='myInputId' aria-describedby='myInputId-hint'>
</FieldRow>
<FieldHint id='myInputId-hint'>This information is super important to be found by screen readers</FieldHint>
</Field>
</form>
// Consider all components as part of fuselage package
// Controller is provided by react-hook-form
import { Controller } from 'react-hook-form'
import { TextInput } from @rocket.chat/fuselage
<form >
<TextInput />
</form>
We already use Playwright to run visual testing and we encourage you to add some a11y violation testing as well