Skip to content

Commit 566116e

Browse files
committed
fix: Fix Multiselect selected a11y issue
1 parent 0f8232f commit 566116e

File tree

6 files changed

+21
-5
lines changed

6 files changed

+21
-5
lines changed

src/internal/components/options-list/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export interface OptionsListProps extends BaseComponentProps {
4444
decreaseBlockMargin?: boolean;
4545
embedded?: boolean;
4646
stickyItemBlockSize?: number | null;
47+
isMultiSelect?: boolean;
4748
}
4849

4950
const BOTTOM_TRIGGER_OFFSET = 80;
@@ -78,6 +79,7 @@ const OptionsList = (
7879
ariaDescribedby,
7980
embedded,
8081
stickyItemBlockSize,
82+
isMultiSelect,
8183
...restProps
8284
}: OptionsListProps,
8385
ref: React.Ref<HTMLDivElement>
@@ -127,6 +129,7 @@ const OptionsList = (
127129
aria-label={ariaLabel}
128130
aria-labelledby={ariaLabelledby}
129131
aria-describedby={ariaDescribedby}
132+
aria-multiselectable={role === 'listbox' && isMultiSelect ? true : undefined}
130133
>
131134
{open && children}
132135
</Tag>

src/internal/components/selectable-item/interfaces.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ export type SelectableItemProps = BaseComponentProps & {
2828
sticky?: boolean;
2929
afterHeader?: boolean;
3030
withScrollbar?: boolean;
31-
} & ({ ariaSelected?: boolean; ariaChecked?: never } | { ariaSelected?: never; ariaChecked?: boolean | 'mixed' });
31+
} & (
32+
| { ariaSelected?: boolean; ariaChecked?: never }
33+
| { ariaSelected?: never | boolean; ariaChecked?: boolean | 'mixed' }
34+
);
3235

3336
export interface ItemDataAttributes {
3437
'data-group-index'?: string;

src/multiselect/internal.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ const InternalMultiselect = React.forwardRef(
197197
screenReaderContent={multiselectProps.announcement}
198198
highlightType={multiselectProps.highlightType}
199199
firstOptionSticky={hasFilteredOptions && enableSelectAll}
200+
isMultiSelect={true}
200201
/>
201202
</Dropdown>
202203

src/select/parts/multiselect-item.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ const MultiSelectItem = (
159159
return (
160160
<SelectableItem
161161
disableContentStyling={!!renderResult}
162+
ariaSelected={!!selected}
162163
ariaChecked={isParent && indeterminate ? 'mixed' : Boolean(selected)}
163164
selected={selected}
164165
isNextSelected={isNextSelected}

src/select/parts/plain-list.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export interface SelectListProps {
2929
useInteractiveGroups?: boolean;
3030
screenReaderContent?: string;
3131
firstOptionSticky?: boolean;
32+
isMultiSelect?: boolean;
3233
renderOption?: SelectProps.SelectOptionItemRenderer | MultiselectProps.MultiselectOptionItemRenderer;
3334
}
3435

@@ -49,6 +50,7 @@ const PlainList = (
4950
useInteractiveGroups,
5051
screenReaderContent,
5152
firstOptionSticky,
53+
isMultiSelect,
5254
renderOption,
5355
}: SelectListProps,
5456
ref: React.Ref<SelectListProps.SelectListRef>
@@ -87,7 +89,12 @@ const PlainList = (
8789
const withScrollbar = !!width && width.inner < width.outer;
8890

8991
return (
90-
<OptionsList {...menuProps} ref={mergedRef} stickyItemBlockSize={stickyOptionBlockSize}>
92+
<OptionsList
93+
{...menuProps}
94+
ref={mergedRef}
95+
stickyItemBlockSize={stickyOptionBlockSize}
96+
isMultiSelect={isMultiSelect}
97+
>
9198
{renderOptions({
9299
renderOption,
93100
options: filteredOptions,

src/select/parts/virtual-list.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const VirtualListOpen = forwardRef(
3232
useInteractiveGroups,
3333
screenReaderContent,
3434
firstOptionSticky,
35+
isMultiSelect,
3536
renderOption,
3637
}: SelectListProps,
3738
ref: React.Ref<SelectListProps.SelectListRef>
@@ -106,7 +107,7 @@ const VirtualListOpen = forwardRef(
106107
});
107108

108109
return (
109-
<OptionsList {...menuProps} stickyItemBlockSize={stickySize} ref={menuRef}>
110+
<OptionsList {...menuProps} stickyItemBlockSize={stickySize} ref={menuRef} isMultiSelect={isMultiSelect}>
110111
{finalOptions}
111112
<div
112113
aria-hidden="true"
@@ -125,10 +126,10 @@ const VirtualListOpen = forwardRef(
125126
);
126127

127128
const VirtualListClosed = forwardRef(
128-
({ menuProps, listBottom }: SelectListProps, ref: React.Ref<SelectListProps.SelectListRef>) => {
129+
({ menuProps, listBottom, isMultiSelect }: SelectListProps, ref: React.Ref<SelectListProps.SelectListRef>) => {
129130
useImperativeHandle(ref, () => () => {}, []);
130131
return (
131-
<OptionsList {...menuProps} ref={menuProps.ref}>
132+
<OptionsList {...menuProps} ref={menuProps.ref} isMultiSelect={isMultiSelect}>
132133
{listBottom ? (
133134
<div role="option" className={styles['list-bottom']}>
134135
{listBottom}

0 commit comments

Comments
 (0)