diff --git a/.changeset/calm-listboxes-notice.md b/.changeset/calm-listboxes-notice.md
new file mode 100644
index 0000000000..4379cb9873
--- /dev/null
+++ b/.changeset/calm-listboxes-notice.md
@@ -0,0 +1,5 @@
+---
+'react-select': patch
+---
+
+Fix loading and empty menu notices to satisfy listbox ARIA required children.
diff --git a/packages/react-select/src/Select.tsx b/packages/react-select/src/Select.tsx
index 146d084e20..abb6099bea 100644
--- a/packages/react-select/src/Select.tsx
+++ b/packages/react-select/src/Select.tsx
@@ -2056,11 +2056,25 @@ export default class Select<
} else if (isLoading) {
const message = loadingMessage({ inputValue });
if (message === null) return null;
- menuUI = {message};
+ menuUI = (
+
+ {message}
+
+ );
} else {
const message = noOptionsMessage({ inputValue });
if (message === null) return null;
- menuUI = {message};
+ menuUI = (
+
+ {message}
+
+ );
}
const menuPlacementProps = {
minMenuHeight,
diff --git a/packages/react-select/src/__tests__/Select.test.tsx b/packages/react-select/src/__tests__/Select.test.tsx
index 0313149095..5244c36969 100644
--- a/packages/react-select/src/__tests__/Select.test.tsx
+++ b/packages/react-select/src/__tests__/Select.test.tsx
@@ -1,5 +1,5 @@
import React, { KeyboardEvent } from 'react';
-import { render, fireEvent, EventType } from '@testing-library/react';
+import { render, fireEvent, EventType, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import cases from 'jest-in-case';
@@ -418,6 +418,26 @@ cases(
}
);
+test('no options message is rendered as a disabled option', () => {
+ const { getByRole } = render(
+
+ );
+ const notice = within(getByRole('listbox')).getByRole('option');
+
+ expect(notice).toHaveTextContent('No options');
+ expect(notice).toHaveAttribute('aria-disabled', 'true');
+});
+
+test('loading message is rendered as a disabled option', () => {
+ const { getByRole } = render(
+
+ );
+ const notice = within(getByRole('listbox')).getByRole('option');
+
+ expect(notice).toHaveTextContent('Loading...');
+ expect(notice).toHaveAttribute('aria-disabled', 'true');
+});
+
cases(
'value prop',
({ props, expectedValue }) => {