From 2f94e8d228ea32dbd0faa1f7685a67b74c70420f Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Tue, 17 Oct 2023 11:17:55 +1100 Subject: [PATCH 1/6] Update docs for Custom Select props (#5776) --- docs/pages/typescript/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/pages/typescript/index.tsx b/docs/pages/typescript/index.tsx index ae1f1b4f1c..01968c279e 100644 --- a/docs/pages/typescript/index.tsx +++ b/docs/pages/typescript/index.tsx @@ -91,7 +91,12 @@ The \`actionMeta\` parameter is optional. \`ActionMeta\` is a union that is disc You can use module augmentation to add custom props to the \`Select\` prop types: ~~~jsx -declare module 'react-select/dist/declarations/src/Select' { +import type {} from 'react-select/base'; +// This import is necessary for module augmentation. +// It allows us to extend the 'Props' interface in the 'react-select/base' module +// and add our custom property 'myCustomProp' to it. + +declare module 'react-select/base' { export interface Props< Option, IsMulti extends boolean, From 884f1c42549faad7cb210169223b427ad6f0c9fd Mon Sep 17 00:00:00 2001 From: Alina Andrieieva Date: Mon, 6 Nov 2023 11:28:16 +0200 Subject: [PATCH 2/6] Accessibility - screenreader announces "blank" while reading the options (#5758) * improved a11y with aria-attribules for input, select, and option * removed console.log * fixed focusableOptionsWithIds for async select * Improved the ariaLiveMessages to announce only important information that is not included into native aria messages * added tests for aria-activedescendant, fixed calculation of focusedOptionId in constructor * added changelog * restored some aria-live for apple device * option focus messages changed * moved listbox to inner div, aria-multiselectable added * tsconfig fix * prettier fix * removed redundant 'types' from tsconfig --------- Co-authored-by: Alina Andrieieva --- .changeset/blue-kings-serve.md | 14 + package.json | 3 +- packages/react-select/src/Select.tsx | 125 ++++++- .../src/__tests__/Select.test.tsx | 317 +++++++++++++++--- .../__snapshots__/Async.test.tsx.snap | 2 + .../AsyncCreatable.test.tsx.snap | 2 + .../__snapshots__/Creatable.test.tsx.snap | 2 + .../__snapshots__/Select.test.tsx.snap | 2 + .../__snapshots__/StateManaged.test.tsx.snap | 2 + .../react-select/src/__tests__/constants.ts | 18 + .../react-select/src/accessibility/helpers.ts | 33 ++ .../react-select/src/accessibility/index.ts | 31 +- .../src/components/LiveRegion.tsx | 21 +- yarn.lock | 5 + 14 files changed, 497 insertions(+), 80 deletions(-) create mode 100644 .changeset/blue-kings-serve.md create mode 100644 packages/react-select/src/accessibility/helpers.ts diff --git a/.changeset/blue-kings-serve.md b/.changeset/blue-kings-serve.md new file mode 100644 index 0000000000..4376283c77 --- /dev/null +++ b/.changeset/blue-kings-serve.md @@ -0,0 +1,14 @@ +--- +'react-select': minor +--- + +1. Added 'aria-activedescendant' for input and functionality to calculate it; +2. Added role 'option' and 'aria-selected' for option; +3. Added role 'listbox' for menu; +4. Added tests for 'aria-activedescendant'; +5. Changes in aria-live region: + +- the instructions how to use select will be announced only one time when user focuses the input for the first time. +- instructions for menu or selected value will be announced only once after focusing them. +- removed aria-live for focused option because currently with correct aria-attributes it will be announced by screenreader natively as well as the status of this option (active or disabled). +- separated ariaContext into ariaFocused, ariaResults, ariaGuidance to avoid announcing redundant information and higlight only current change. diff --git a/package.json b/package.json index 90a96e2f70..c186787df8 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,8 @@ "jest-in-case": "^1.0.2", "prettier": "^2.2.1", "style-loader": "^0.23.1", - "typescript": "^4.1.3" + "typescript": "^4.1.3", + "user-agent-data-types": "^0.4.2" }, "scripts": { "build": "preconstruct build", diff --git a/packages/react-select/src/Select.tsx b/packages/react-select/src/Select.tsx index 16daa33094..798f6126b2 100644 --- a/packages/react-select/src/Select.tsx +++ b/packages/react-select/src/Select.tsx @@ -16,6 +16,7 @@ import LiveRegion from './components/LiveRegion'; import { createFilter, FilterOptionOption } from './filters'; import { DummyInput, ScrollManager, RequiredInput } from './internal/index'; import { AriaLiveMessages, AriaSelection } from './accessibility/index'; +import { isAppleDevice } from './accessibility/helpers'; import { classNames, @@ -329,12 +330,15 @@ interface State< inputIsHidden: boolean; isFocused: boolean; focusedOption: Option | null; + focusedOptionId: string | null; + focusableOptionsWithIds: FocusableOptionWithId