-
Notifications
You must be signed in to change notification settings - Fork 944
Description
downshift version: "^8.1.0"
Tools used:
NVDA
Relevant code or config
import React, { forwardRef } from 'react';
import _isEmpty from 'lodash/isEmpty';
import { useSelect } from 'downshift';
import { string, arrayOf, shape, func } from 'prop-types';
import '../Dropdown.scss';
import CheckMarkIcon from '../../../resources/images/checkmark-black.svg';
import { classNames } from '../../../site/helper/utils';
const itemToString = item => {
return item ? item.title : '';
};
const Downshift = forwardRef(
(
{
className,
list,
label,
field,
disabled,
selectedValue,
handleOnChange,
errorMessage,
required,
id,
dropdownButtonClassName,
...rest
},
ref
) => {
const selectedItem = list.find(item => item.value === selectedValue?.value) || null;
const { isOpen, getToggleButtonProps, getLabelProps, getMenuProps, highlightedIndex, getItemProps } = useSelect(
{
items: list,
selectedItem,
onSelectedItemChange: ({ selectedItem }) => handleOnChange(selectedItem),
itemToString,
}
);
const showErrorMsg = !!errorMessage;
const dropdownList = (
<ul
className={classNames( className, !isOpen && 'hidden')}
{...getMenuProps()}
>
{list.map((item, index) => (
<li
key={item.value}
type="button"
className={classNames(
(selectedItem?.value === item.value || highlightedIndex === index) && 'selected'
)}
{...getItemProps({ item, index })}
data-testid={`dropdown-item-${item.value}`}
>
{item.title}
{selectedItem?.value === item.value && (
<img src={CheckMarkIcon} alt="ArrowUpIcon" width={12} height={9} />
)}
</li>
))}
</ul>
);
const dropdownButton = (
<div
tabIndex={0}
type="button"
className={dropdownButtonClassName}
disabled={disabled}
{...getToggleButtonProps({
ref,
})}
aria-required={required}
aria-invalid={!!errorMessage}
data-testid="dropdown-button"
{...rest}
id={id}
>
{!_isEmpty(selectedItem) ? (
<>
{
<label className="dd-header-title focused" {...getLabelProps()}>
{label}
</label>
}
<div className="dd-header-title" data-testid="dropdown-selected-item">
{itemToString(selectedItem)}
</div>
</>
) : (
<label className="dd-header-title placeholder" {...getLabelProps()}>
{label}
</label>
)}
</div>
);
return (
<div id={field} className={className}>
{dropdownButton}
{dropdownList}
</div>
);
}
);
Downshift.propTypes = {
list: arrayOf(
shape({
title: string,
value: string,
})
).isRequired,
selectedValue: shape({ title: string, value: string }),
handleOnChange: func.isRequired,
};
Downshift.defaultProps = {
list: [],
selectedValue: { title: '', value: '' },
};
export default Downshift;
Issue faced:
I have this dropdown used inside a Form that contains other input text boxes.
When opening form in edit mode, even though focus is not set on the dropdown, it reads out "ABC has been selected", [ABC being here the value set]
I fixed this in Voiceover by programmatically setting focus to first field in the form which happens be an input box, so that way Voiceover is now reading out the 1st focused input and isn't reading dropdown status anymore.
But on NVDA, even after this change, it is now first reading out the programmatically focused input, and again the dropdown value, even though no focus is set on dropdown.
Along with this, when i submit the form, by clicking submit button, it keeps on shouting "ABC has been selected", continuously 2-3 times, until the form is closed, even though value of dropdown hasn't changed OR the focus hasn't been set on dropdown.