Skip to content

Commit

Permalink
fix(a11y): combobox - aria-describedby error is not associated initia…
Browse files Browse the repository at this point in the history
…lly (#1318)

- CDE-794 A11y Clarity Combobox > aria-describedby error is not
associated initially when the combobox is touched and loses focus.

## PR Checklist

Please check if your PR fulfills the following requirements:

- [ ] Tests for the changes have been added (for bug fixes / features)
- [x] Docs have been added / updated (for bug fixes / features)
- [ ] If applicable, have a visual design approval

## PR Type

What kind of change does this PR introduce?

<!-- Please check the one that applies to this PR using "x". -->

- [x] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Documentation content changes
- [ ] Other... Please describe:

## What is the current behavior?
The Combobox has `required` attribute added to the template.
Once the Combobox is touched and loses focus (click outside without
selecting any option), the required error validation is triggered and
the error message appears on the screen, however the id of the error
container is not associated to `aria-describeby` of the Combobox input
at this time.
Hence the screen reader does not read out the error.

<!-- Please describe the current behavior that you are modifying, or
link to a relevant issue. -->

Issue Number: [CDE-794](https://jira.eng.vmware.com/browse/CDE-794)

## What is the new behavior?
The id of the error container will be added to the `aria-describeby` of
the Combobox input if a required error occurs.
The screen reader will read out the error.

## Does this PR introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this PR contains a breaking change, please describe the impact
and migration path for existing applications below. -->

## Other information
Updated the Combobox story in Storybook to demo this fix.

---------

Co-authored-by: Andrea Fernandes <andreaf1@vmware.com>
Co-authored-by: GitHub <noreply@github.com>
  • Loading branch information
3 people authored Mar 15, 2024
1 parent bdcb46a commit 066c764
Show file tree
Hide file tree
Showing 10 changed files with 30 additions and 0 deletions.
27 changes: 27 additions & 0 deletions .storybook/stories/combobox/combobox.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export default {
// story helpers
elements: { control: { disable: true }, table: { disable: true } },
optionCount: { control: { type: 'number', min: 1, max: elements.length } },
updateOn: { defaultValue: 'change', control: { type: 'radio', options: ['change', 'blur', 'submit'] } },
},
args: {
// outputs
Expand All @@ -58,6 +59,9 @@ export default {
optionCount: elements.length,
content: 'Option',
controlDisabled: false,
controlRequired: false,
controlHelper: false,
updateOn: 'change',
elements,
singleModel: 'Am',
multiModel: ['Am', 'As', 'Ba'],
Expand All @@ -73,12 +77,14 @@ const ComboboxTemplate: StoryFn = args => ({
[id]="id"
[clrMulti]="clrMulti"
[ngModel]="clrMulti ? multiModel : singleModel"
[ngModelOptions]="{ updateOn: updateOn }"
[placeholder]="placeholder"
(clrInputChange)="clrInputChange($event)"
(clrOpenChange)="clrOpenChange($event)"
(clrSelectionChange)="clrSelectionChange($event)"
[disabled]="controlDisabled"
name="combo"
[required]="controlRequired"
>
<ng-container *clrOptionSelected="let selected">
{{selected}}
Expand All @@ -87,6 +93,8 @@ const ComboboxTemplate: StoryFn = args => ({
<clr-option *clrOptionItems="let element of elements; let i = index" [clrValue]="element.symbol">{{element.name}}</clr-option>
</clr-options>
</clr-combobox>
<clr-control-helper *ngIf="controlHelper">Helper text</clr-control-helper>
<clr-control-error *ngIf="controlRequired">There was an error</clr-control-error>
</clr-combobox-container>
`,
props: { ...args },
Expand Down Expand Up @@ -132,3 +140,22 @@ export const MultiSelectionDisabled: StoryObj = {
controlDisabled: true,
},
};

export const SingleSelectionRequired: StoryObj = {
render: ComboboxTemplate,
args: {
singleModel: '',
controlHelper: true,
controlRequired: true,
},
};

export const MultiSelectionRequired: StoryObj = {
render: ComboboxTemplate,
args: {
multiModel: [],
clrMulti: true,
controlHelper: true,
controlRequired: true,
},
};
3 changes: 3 additions & 0 deletions projects/angular/src/forms/combobox/combobox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ export class ClrCombobox<T>

onBlur() {
this.onTouchedCallback();
if (this.control.control.updateOn === 'change' && this.control.control?.errors?.required) {
this.updateControlValue();
}
if (this.control.control.updateOn === 'blur') {
this.control.control.updateValueAndValidity();
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 066c764

Please sign in to comment.