Accessibility is a core consideration when building user interfaces. Ensure that all interactive elements are reachable through keyboard navigation, particularly using the Tab key.
The following elements are focusable by default:
Buttons
Inputs
Links
Refer to the Accessibility Statement for more details about ongoing efforts to improve user experience.
Working with forms
Rocket.Chat uses the react-hook-form library alongside visual components to build forms. While visual design is important, following accessibility best practices ensures forms remain usable for all users.
Labelling an input correctly
A common accessibility issue is failing to associate a label with its corresponding input. Always use the for attribute (or htmlFor in React) to properly 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 large applications, maintaining unique string IDs can be difficult. Use useUniqueId from @rocket.chat/fuselage-hooks to generate stable, unique identifiers for your inputs.
Adding description to an input
Some inputs may require additional context to help users understand what information is expected. Providing only visual guidance is not sufficient, assistive technologies must also be able to access this information.
Use the aria-describedby attribute to associate descriptive text with an input so screen readers can properly announce it.
// 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>Making an input required
When an input is mandatory, communicate this clearly to all users, including those relying on assistive technologies. Proper labeling and descriptive hints help ensure the requirement is understood.
// 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>