Skip to content

Commit

Permalink
Adding logic for aria-invalid depending on error message
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas-Neuhauser committed Dec 12, 2024
1 parent 2104e1e commit 9d0e41b
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
27 changes: 27 additions & 0 deletions packages/ui-components/src/components/UIComboBox/UIComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,27 @@ export class UIComboBox extends React.Component<UIComboBoxProps, UIComboBoxState
this.onScrollToItem = this.onScrollToItem.bind(this);
this.setFocus = this.setFocus.bind(this);
this.onRenderIcon = this.onRenderIcon.bind(this);
this.updateAriaInvalid = this.updateAriaInvalid.bind(this);

initializeComponentRef(this);

this.state = {};
}

/**
* Called when component did initialize.
*/
componentDidMount(): void {
this.updateAriaInvalid();
}

/**
* Called when component is rerendered.
*/
componentDidUpdate(): void {
this.updateAriaInvalid();
}

/**
*
* @param {UIComboBoxProps} nextProps
Expand All @@ -165,6 +180,18 @@ export class UIComboBox extends React.Component<UIComboBoxProps, UIComboBoxState
return true;
}

/**
* This is a workaround for FluentUI not handling aria-invalid correctly for a ComboBox.
* For the time being we add logic here to set aria-invalid based on the presence of
* an errorMessage.
*/
private updateAriaInvalid(): void {
const htmlInputField = this.comboboxDomRef.current?.getElementsByClassName('ms-ComboBox-Input').item(0);
if (htmlInputField) {
htmlInputField.ariaInvalid = this.props.errorMessage !== undefined ? 'true' : 'false';
}
}

/**
* Updates hidden options.
*
Expand Down
43 changes: 42 additions & 1 deletion packages/ui-components/stories/UICombobox.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,47 @@ export const MultiSelectSearchHighlight = (): JSX.Element => {
);
};

export const DynamicError = () => {
const [selectedKey, setSelectedKey] = React.useState<string | number>('OK');
const selectOptions = [
{
key: 'OK',
text: 'No Error Message'
},
{
key: 'ERROR',
text: 'With Error Message'
}
];

function onCbChange(
event: React.FormEvent<IComboBox>,
option?: IComboBoxOption | undefined,
index?: number | undefined,
value?: string | undefined
) {
if (option) {
setSelectedKey(option.key);
}
}

return (
<div style={{ width: '300px' }}>
<UIComboBox
options={selectOptions}
label="Dynamic Validation Error"
highlight={true}
allowFreeform={true}
useComboBoxAsMenuMinWidth={true}
autoComplete="on"
selectedKey={selectedKey}
onChange={onCbChange}
errorMessage={selectedKey === 'OK' ? undefined : 'Error Message'}
/>
</div>
);
};

export const Messages = (): JSX.Element => (
<div style={{ width: '300px' }}>
<UIComboBox
Expand All @@ -163,7 +204,7 @@ export const Messages = (): JSX.Element => (
allowFreeform={true}
useComboBoxAsMenuMinWidth={true}
autoComplete="on"
errorMessage="Dummy Error"
errorMessage={'Dummy Error'}
/>
<UIComboBox
options={data}
Expand Down

0 comments on commit 9d0e41b

Please sign in to comment.