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 = () => (