diff --git a/packages/docs/page-config/ui-elements/toast/index.ts b/packages/docs/page-config/ui-elements/toast/index.ts index 287a59b291..5d6c9a47eb 100644 --- a/packages/docs/page-config/ui-elements/toast/index.ts +++ b/packages/docs/page-config/ui-elements/toast/index.ts @@ -90,6 +90,10 @@ export default definePageConfig({ description: "You can set custom onClick event to handle the click on button." }), + block.subtitle("Accessibility"), + block.paragraph("Toasts are intended to be small interruptions to your vistiors or users, it's wrap with an [aria-live](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions)[[target=_blank]] region, so that changes to live regions are automatically announced by screen reader without needding to move the user's focus or otherwise interrupt the user. If the conveying messages is important, you should not add the [role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles)[[target=_blank]] attribute that can either be [alert](https://w3c.github.io/aria/#alert)[[target=_blank]] or [alertdialog](https://w3c.github.io/aria/#alertdialog)[[target=_blank]] depending on `closeable` prop, [aria-live](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions)[[target=_blank]] will be computed and set to `assertive`. if messages is not important, you should manually set the [role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles)[[target=_blank]] attribute to [status](https://w3c.github.io/aria/#status)[[target=_blank]], and [aria-live](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions)[[target=_blank]] should be computed to `polite`."), + block.paragraph("Note that the live region needs to be present in the markup before the toast is generated or updated. If you dynamically generate both at the same time and inject them into the page, they will generally not be announced by assistive technologies."), + block.subtitle("API"), block.api("VaToast", apiDescription, apiOptions), diff --git a/packages/ui/src/components/va-toast/VaToast.vue b/packages/ui/src/components/va-toast/VaToast.vue index 65e1572677..ed24ba07ae 100644 --- a/packages/ui/src/components/va-toast/VaToast.vue +++ b/packages/ui/src/components/va-toast/VaToast.vue @@ -3,7 +3,9 @@
>, default: undefined }, }, setup (props, { emit }) { const rootElement = shallowRef() @@ -112,6 +117,14 @@ export default defineComponent({ color: textColorComputed.value, })) + const computedAriaLive = computed(() => { + if (props.role === 'status') { + return 'polite' + } else { + return 'assertive' + } + }) + const computedMessage = computed(() => (typeof props.message === 'function') ? props.message() : props.message) const destroyElement = () => { @@ -159,6 +172,7 @@ export default defineComponent({ visible, toastClasses, toastStyles, + computedAriaLive, computedMessage, onToastClick, onToastClose, diff --git a/packages/ui/src/utils/types/prop-type.ts b/packages/ui/src/utils/types/prop-type.ts index 96873c327d..c30b8f3446 100644 --- a/packages/ui/src/utils/types/prop-type.ts +++ b/packages/ui/src/utils/types/prop-type.ts @@ -1,7 +1,7 @@ import type { PropType } from 'vue' /** This will accept any string, but will suggest all strings from `T`. Used for better IDE support in component props. */ -type StringWithAutocomplete = T | (string & Record) +export type StringWithAutocomplete = T | (string & Record) // Make sure to make StringType as generic to prevent type unwrapping /**