Skip to content

Commit

Permalink
fix(combobox): invalid and warn text should be read by screenreaders (#…
Browse files Browse the repository at this point in the history
…15954)

* fix(combobox): invalid and warn text should be read by screenreaders

* fix(combobox): update variable name

* fix(combobox): prefer invalidText over warnText over helperText

* fix(combobox): remove duplicate proptype
  • Loading branch information
tay1orjones authored Mar 20, 2024
1 parent b60cb78 commit 80c75e2
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 13 deletions.
27 changes: 17 additions & 10 deletions packages/react/src/components/ComboBox/ComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,9 @@ const ComboBox = forwardRef(
const titleClasses = cx(`${prefix}--label`, {
[`${prefix}--label--disabled`]: disabled,
});
const comboBoxHelperId = !helperText
? undefined
: `combobox-helper-text-${comboBoxInstanceId}`;
const helperTextId = `combobox-helper-text-${comboBoxInstanceId}`;
const warnTextId = `combobox-warn-text-${comboBoxInstanceId}`;
const invalidTextId = `combobox-invalid-text-${comboBoxInstanceId}`;
const helperClasses = cx(`${prefix}--form__helper-text`, {
[`${prefix}--form__helper-text--disabled`]: disabled,
});
Expand Down Expand Up @@ -666,6 +666,15 @@ const ComboBox = forwardRef(
}
: {};

// The input should be described by the appropriate message text id
// when both the message is supplied *and* when the component is in
// the matching state (invalid, warn, etc).
const ariaDescribedBy =
(invalid && invalidText && invalidTextId) ||
(warn && warnText && warnTextId) ||
(helperText && !isFluid && helperTextId) ||
undefined;

return (
<div className={wrapperClasses}>
{titleText && (
Expand All @@ -680,11 +689,13 @@ const ComboBox = forwardRef(
disabled={disabled}
invalid={invalid}
invalidText={invalidText}
invalidTextId={invalidTextId}
isOpen={isOpen}
light={light}
size={size}
warn={warn}
warnText={warnText}>
warnText={warnText}
warnTextId={warnTextId}>
<div className={`${prefix}--list-box__field`}>
<input
role="combobox"
Expand All @@ -703,11 +714,7 @@ const ComboBox = forwardRef(
{...readOnlyEventHandlers}
readOnly={readOnly}
ref={mergeRefs(textInput, ref)}
aria-describedby={
helperText && !invalid && !warn && !isFluid
? comboBoxHelperId
: undefined
}
aria-describedby={ariaDescribedBy}
/>
{invalid && (
<WarningFilled
Expand Down Expand Up @@ -786,7 +793,7 @@ const ComboBox = forwardRef(
</ListBox.Menu>
</ListBox>
{helperText && !invalid && !warn && !isFluid && (
<Text as="div" id={comboBoxHelperId} className={helperClasses}>
<Text as="div" id={helperTextId} className={helperClasses}>
{helperText}
</Text>
)}
Expand Down
32 changes: 29 additions & 3 deletions packages/react/src/components/ListBox/ListBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ export interface ListBoxProps
*/
invalidText?: React.ReactNode;

/**
* Specify the id to be applied to the element containing the invalid text
*/
invalidTextId?: string;

/**
* Specify if the control should render open
*/
Expand Down Expand Up @@ -78,6 +83,11 @@ export interface ListBoxProps
* Provide the text that is displayed when the control is in warning state
*/
warnText?: React.ReactNode;

/**
* Specify the id to be applied to the element containing the warn text
*/
warnTextId?: string;
}

export type ListBoxComponent = ForwardRefReturn<HTMLDivElement, ListBoxProps>;
Expand All @@ -95,8 +105,10 @@ const ListBox: ListBoxComponent = React.forwardRef(function ListBox(
size,
invalid,
invalidText,
invalidTextId,
warn,
warnText,
warnTextId,
light,
isOpen,
...rest
Expand Down Expand Up @@ -132,10 +144,14 @@ const ListBox: ListBoxComponent = React.forwardRef(function ListBox(
</div>
{isFluid && <hr className={`${prefix}--list-box__divider`} />}
{invalid ? (
<div className={`${prefix}--form-requirement`}>{invalidText}</div>
<div className={`${prefix}--form-requirement`} id={invalidTextId}>
{invalidText}
</div>
) : null}
{showWarning ? (
<div className={`${prefix}--form-requirement`}>{warnText}</div>
<div className={`${prefix}--form-requirement`} id={warnTextId}>
{warnText}
</div>
) : null}
</>
);
Expand Down Expand Up @@ -168,6 +184,11 @@ ListBox.propTypes = {
*/
invalidText: PropTypes.node,

/**
* Specify the id to be applied to the element containing the invalid text
*/
invalidTextId: PropTypes.string,

/**
* Specify if the control should render open
*/
Expand Down Expand Up @@ -202,7 +223,12 @@ ListBox.propTypes = {
/**
* Provide the text that is displayed when the control is in warning state
*/
warnText: PropTypes.node,
warnText: PropTypes.string,

/**
* Specify the id to be applied to the element containing the warn text
*/
warnTextId: PropTypes.string,
};

export default ListBox;

0 comments on commit 80c75e2

Please sign in to comment.