diff --git a/packages/react/src/Button/Button.docs.json b/packages/react/src/Button/Button.docs.json
index 91707c4c7bd..907548e9f51 100644
--- a/packages/react/src/Button/Button.docs.json
+++ b/packages/react/src/Button/Button.docs.json
@@ -73,6 +73,12 @@
{
"id": "components-button-features--loading-trigger"
},
+ {
+ "id": "components-button-examples--loading-status-announcement-successful"
+ },
+ {
+ "id": "components-button-examples--loading-status-announcement-error"
+ },
{
"id": "components-button-features--label-wrap"
},
@@ -135,12 +141,13 @@
{
"name": "loading",
"type": "boolean",
- "description": "When true, the button is in a loading state."
+ "description": "When true, the button is in a loading state. A spinner replaces the button's content and the button automatically announces its loading state to screen readers through a built-in, visually hidden live region. Do not add your own separate `aria-live` loading message for the button, as that would cause a duplicate announcement."
},
{
"name": "loadingAnnouncement",
"type": "string",
- "description": "The content to announce to screen readers when loading. This requires `loading` prop to be true"
+ "defaultValue": "'Loading'",
+ "description": "The text announced to screen readers through the built-in, visually hidden live region when the button enters its loading state. Requires the `loading` prop to be true."
},
{
"name": "ref",
diff --git a/packages/react/src/Button/Button.examples.stories.tsx b/packages/react/src/Button/Button.examples.stories.tsx
index b3401ef6577..27506ef52ee 100644
--- a/packages/react/src/Button/Button.examples.stories.tsx
+++ b/packages/react/src/Button/Button.examples.stories.tsx
@@ -43,6 +43,14 @@ export const LoadingStatusAnnouncementSuccessful = () => {
>
)
}
+LoadingStatusAnnouncementSuccessful.parameters = {
+ docs: {
+ description: {
+ story:
+ 'While `loading` is set, the button announces its loading state for you through its built-in live region, so you should not add a separate loading announcement. Announcing the *result* of the action is still your responsibility — here, a polite `AriaStatus` live region announces "Export completed" once the action resolves successfully.',
+ },
+ },
+}
export const LoadingStatusAnnouncementError = () => {
const [loading, setLoading] = React.useState(false)
@@ -81,3 +89,11 @@ export const LoadingStatusAnnouncementError = () => {
>
)
}
+LoadingStatusAnnouncementError.parameters = {
+ docs: {
+ description: {
+ story:
+ 'The button handles the loading announcement for you, so you only need to announce the outcome. Here, an assertive `AriaAlert` surfaces an error `Banner` when the action fails.',
+ },
+ },
+}
diff --git a/packages/react/src/Button/Button.features.stories.tsx b/packages/react/src/Button/Button.features.stories.tsx
index 0b7d3da149b..cac3d8d733c 100644
--- a/packages/react/src/Button/Button.features.stories.tsx
+++ b/packages/react/src/Button/Button.features.stories.tsx
@@ -154,12 +154,28 @@ export const Medium = () =>
export const Large = () =>
export const Loading = () =>
+Loading.parameters = {
+ docs: {
+ description: {
+ story:
+ 'When `loading` is set, the button automatically renders a visually hidden live region that announces "Loading" to screen readers. Because this announcement is built in, do not add your own separate `aria-live` loading message for the button — doing so would cause a duplicate announcement.',
+ },
+ },
+}
export const LoadingCustomAnnouncement = () => (
)
+LoadingCustomAnnouncement.parameters = {
+ docs: {
+ description: {
+ story:
+ 'Use the `loadingAnnouncement` prop to customize the text announced to screen readers when the button enters its loading state. This replaces the default "Loading" announcement.',
+ },
+ },
+}
export const LoadingWithLeadingVisual = () => (