Skip to content

Commit

Permalink
Combo Box - Adding title and Improved aria-activedescendant for acces…
Browse files Browse the repository at this point in the history
…sibility (microsoft#3738)

* added aria-autocomplete; added title; added activedescendant with focus item

* added comments in combobox

* removed autocomplete value for now

* cleaned up code

* added change files

* fixed for id for label to point to the input element

* updated changes with aria-autocomplete

* fixed lint problem; updated test snap file

* fixed aria autocomplete to have the correct logic in if check

* simplified code and changed priority of title values

* addressed lint problems and updated test

* updated title to only use title attribute for combobox
  • Loading branch information
chang47 authored and Chris Mohr committed Apr 17, 2018
1 parent 47fcfbf commit d257157
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "Combox box: added accessibility changes added a title and changed activedescendant to use focused element",
"type": "patch"
}
],
"packageName": "office-ui-fabric-react",
"email": "chiechan@microsoft.com"
}
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> {
buttonIconProps,
styles: customStyles,
theme,
title
} = this.props;
let { isOpen, selectedIndex, focused, suggestedDisplayValue } = this.state;
this._currentVisibleValue = this._getVisibleValue();
Expand All @@ -295,7 +296,7 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> {
return (
<div {...divProps } ref='root' className={ this._classNames.container }>
{ label && (
<Label id={ id + '-label' } disabled={ disabled } required={ required } htmlFor={ id } className={ this._classNames.label }>{ label }</Label>
<Label id={ id + '-label' } disabled={ disabled } required={ required } htmlFor={ id + '-input' } className={ this._classNames.label }>{ label }</Label>
) }
<div
ref={ this._resolveRef('_comboBoxWrapper') }
Expand All @@ -315,21 +316,22 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> {
onClick={ this._onBaseAutofillClick }
onInputValueChange={ this._onInputChange }
aria-expanded={ isOpen }
aria-autocomplete={ (!disabled && autoComplete === 'on') }
aria-autocomplete={ this._getAriaAutoCompleteValue() }
role='combobox'
aria-readonly={ ((allowFreeform || disabled) ? null : 'true') }
readOnly={ disabled || !allowFreeform }
aria-labelledby={ (label && (id + '-label')) }
aria-label={ ((ariaLabel && !label) && ariaLabel) }
aria-describedby={ (id + '-option') }
aria-activedescendant={ (isOpen && (selectedIndex as number) >= 0 ? (id + '-list' + selectedIndex) : null) }
aria-activedescendant={ this._getAriaActiveDescentValue() }
aria-disabled={ disabled }
aria-owns={ (id + '-list') }
spellCheck={ false }
defaultVisibleValue={ this._currentVisibleValue }
suggestedDisplayValue={ suggestedDisplayValue }
updateValueInWillReceiveProps={ this._onUpdateValueInAutoFillWillReceiveProps }
shouldSelectFullInputValueInComponentDidUpdate={ this._onShouldSelectFullInputValueInAutoFillComponentDidUpdate }
title={ title }
/>
<IconButton
className={ 'ms-ComboBox-CaretDown-button' }
Expand Down Expand Up @@ -1540,4 +1542,26 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> {

return getOptionStyles(this.props.theme!, customStylesForAllOptions, customStylesForCurrentOption);
}

/**
* Get the aria-activedescendant value for the comboxbox.
* @returns the id of the current focused combo item, otherwise the id of the currently selected element, null otherwise
*/
private _getAriaActiveDescentValue(): string | null {
let descendantText = (this.state.isOpen && (this.state.selectedIndex as number) >= 0 ? (this._id + '-list' + this.state.selectedIndex) : null);
if (this.state.isOpen && this.state.focused && this.state.currentPendingValueValidIndex !== -1) {
descendantText = (this._id + '-list' + this.state.currentPendingValueValidIndex);
}
return descendantText;
}

/**
* Get the aria autocomplete value for the Combobox
* @returns 'inline' if auto-complete automatically dynamic, 'both' if we have a list of possible values to pick from and can
* dynamically populate input, and 'none' if auto-complete is not enabled as we can't give user inputs.
*/
private _getAriaAutoCompleteValue(): string {
let autoComplete = !this.props.disabled && this.props.autoComplete === 'on';
return autoComplete ? (this.props.allowFreeform ? 'inline' : 'both') : 'none';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ exports[`ComboBox Renders ComboBox correctly 1`] = `
>
<input
aria-activedescendant={null}
aria-autocomplete={true}
aria-autocomplete="both"
aria-describedby="ComboBox0-option"
aria-disabled={undefined}
aria-expanded={false}
Expand Down Expand Up @@ -114,6 +114,7 @@ exports[`ComboBox Renders ComboBox correctly 1`] = `
readOnly={true}
role="combobox"
spellCheck={false}
title={undefined}
type="text"
value=""
/>
Expand Down

0 comments on commit d257157

Please sign in to comment.