Skip to content

Commit

Permalink
fix(help-text): apply aria-live to ensure full help text is read to u…
Browse files Browse the repository at this point in the history
…ser (#4210)

* fix(help-text): apply aria-live to ensure full help text is read to user

* docs(help-text): added accessible context to examples

* docs(help-text): updated help-text docs to include accessibility information

---------

Co-authored-by: Nikki Massaro <massaro@adobe.com>
Co-authored-by: Nikki Massaro <5090492+nikkimk@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 24, 2024
1 parent 7d1f461 commit 049dc56
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 17 deletions.
99 changes: 83 additions & 16 deletions packages/help-text/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

An `<sp-help-text>` provides either an informative description or an error message that gives more context about what a user needs to input. It's commonly used in forms.

### Usage
## Usage

[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/help-text?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/help-text)
[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/help-text?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/help-text)
Expand All @@ -23,67 +23,134 @@ When looking to leverage the `HelpText` base class as a type and/or for extensio
import { HelpText } from '@spectrum-web-components/help-text';
```

## Example

Good descriptive help text includes 1-2 short sentences information such as:

- An overall description of an input field or controls
- Hints for what kind of information needs to be input or selected
- Specific formatting examples or requirements

## Sizes

<sp-tabs selected="m" auto label="Size Attribute Options">
<sp-tab value="s">Small</sp-tab>
<sp-tab-panel value="s">

```html
<sp-help-text size="s">Passwords must be at least 8 characters.</sp-help-text>
```html demo
<sp-field-label size="s" for="size-s">Password</sp-field-label>
<sp-textfield size="s" id="size-s" type="password">
<sp-help-text size="s" slot="help-text">
Create a password with at least 8 characters.
</sp-help-text>
</sp-textfield>
```

</sp-tab-panel>
<sp-tab value="m">Medium</sp-tab>
<sp-tab-panel value="m">

```html
<sp-help-text size="m">Passwords must be at least 8 characters.</sp-help-text>
```html demo
<sp-field-label size="m" for="size-m">Password</sp-field-label>
<sp-textfield size="m" id="size-m" type="password">
<sp-help-text size="m" slot="help-text">
Create a password with at least 8 characters.
</sp-help-text>
</sp-textfield>
```

</sp-tab-panel>
<sp-tab value="l">Large</sp-tab>
<sp-tab-panel value="l">

```html
<sp-help-text size="l">Passwords must be at least 8 characters.</sp-help-text>
<sp-field-label size="l" for="size-l">Password</sp-field-label>
<sp-textfield size="l" id="size-l" type="password">
<sp-help-text size="l" slot="help-text">
Create a password with at least 8 characters.
</sp-help-text>
</sp-textfield>
```

</sp-tab-panel>
<sp-tab value="xl">Extra Large</sp-tab>
<sp-tab-panel value="xl">

```html
<sp-help-text size="xl">Passwords must be at least 8 characters.</sp-help-text>
<sp-field-label size="xl" for="size-xl">Password</sp-field-label>
<sp-textfield size="xl" id="size-xl" type="password">
<sp-help-text size="xl" slot="help-text">
Create a password with at least 8 characters.
</sp-help-text>
</sp-textfield>
```

</sp-tab-panel>
</sp-tabs>

## Negative

The negative variant of `<sp-help-text>` is used to convey error messages. An error message should be different than the informative message otherwise delivers to the visitor and should show a solution for correcting the error that has been encountered.
The negative variant of `<sp-help-text>` is used to convey error messages.

Help text displays either a description (the neutral variant) or an error message (the negative variant) in the same space. When a description is present and an error is triggered, it is replaced with an error message. Once the error is resolved, the help text description reappears.

Since one gets replaced by the other, the language of the help text description and the error need to work together to convey the same messaging. The description text explains the requirements or adds supplementary context for how to successfully interact with a component. The error message text tells a user how to fix the error by re-stating the interaction requirements. Make sure that the help text description and error message include the same essential information so that it isn’t lost if one replaces the other.

Communicate error messages in a human-centered way by guiding a user and showing them a solution — don’t simply state what’s wrong and then leave them guessing as to how to resolve it. Ambiguous error messages can be frustrating and even shame-inducing for users. Also, keep in mind that something that a system may deem an error may not actually be perceived as an error to a user.

For help text, usually the error is related to something that needs to be fixed for in-line validation, so a [helpful tone](https://spectrum.adobe.com/page/voice-and-tone/#Tone) is most appropriate. For example, if someone were to miss filling out a required field that asks for their email address, write the error text like you’re offering a hint or a tip to help guide them to understand what needs to go in the missing field: “Enter your email address.”

```html
<sp-help-text variant="negative">
Create a password with at least 8 characters.
</sp-help-text>
<sp-field-label for="negative">Password</sp-field-label>
<sp-textfield id="negative" type="password" required invalid>
<sp-help-text slot="help-text">
Create a password with at least 8 characters.
</sp-help-text>
<sp-help-text variant="negative" slot="help-text-negative">
Passwords must be at least 8 characters
</sp-help-text>
</sp-textfield>
```

### Icon

When associated with content that does not supply an icon outlining the presence of an error, use the `icon` attribute to display one as part of the `<sp-help-text>` element.

```html
<sp-help-text variant="negative" icon>
Create a password with at least 8 characters.
</sp-help-text>
<sp-field-group horizontal id="fruit">
<sp-checkbox value="apple">Apple</sp-checkbox>
<sp-checkbox
value="not-a-fruit"
onchange="javascript:this.parentElement.invalid = this.checked"
>
Lettuce
</sp-checkbox>
<sp-checkbox value="strawberry" checked>Strawberry</sp-checkbox>
<sp-help-text slot="help-text">One of these is not a fruit.</sp-help-text>
<sp-help-text icon slot="negative-help-text" icon>
Choose actual fruit(s).
</sp-help-text>
</sp-field-group>
```

## Disabled

When associated to content the is disabled, use the `disabled` attribute to match the delivery of the `<sp-help-text>` element to that content.

```html
<sp-help-text disabled>Passwords must be at least 8 characters.</sp-help-text>
```html demo
<sp-field-label for="color" disabled>Color</sp-field-label>
<sp-combobox id="color" disabled>
<sp-menu-item value="red">Red</sp-menu-item>
<sp-menu-item value="green">Green</sp-menu-item>
<sp-menu-item value="blue">Blue</sp-menu-item>
<sp-help-text slot="help-text" disabled>
Choose or add at least one color.
</sp-help-text>
</sp-combobox>
```

## Accessibility

It is [not currently possible](https://w3c.github.io/webcomponents-cg/#cross-root-aria) to provide accessible ARIA references between elements in different shadow roots, so help text must be used in the `help-text` or `help-text-negative` `slot` of a `<sp-text-field>`, `<sp-field-group>`, `<sp-combobox>` or `<sp-picker>`.

To add help text to your own custom element, see [Help Text Mixin](./help-text-mixin/).
5 changes: 4 additions & 1 deletion packages/help-text/src/HelpTextManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ export class HelpTextManager {
// `pass-through-help-text-${this.instanceCount}` makes the slot effectively unreachable from
// the outside allowing the `help-text` slot to be preferred while `negative === false`.
return html`
<div id=${ifDefined(this.isInternal ? this.id : undefined)}>
<div
id=${ifDefined(this.isInternal ? this.id : undefined)}
aria-live="assertive"
>
<slot
name=${negative
? 'negative-help-text'
Expand Down

0 comments on commit 049dc56

Please sign in to comment.