📣 a11y: Better Screen Reader Announcements (#3693)

* refactor: Improve LiveAnnouncer component

The LiveAnnouncer component in the client/src/a11y/LiveAnnouncer.tsx file has been refactored to improve its functionality. The component now processes text in chunks for better performance and adds a minimum announcement delay to prevent overlapping announcements. Additionally, the component now properly clears the announcement message and ID before setting a new one. These changes enhance the accessibility and user experience of the LiveAnnouncer component.

* refactor: manage only 2 LiveAnnouncer aria-live elements, queue assertive/polite together

* refactor: use localizations for event announcements

* refactor: update minimum announcement delay in LiveAnnouncer component

* refactor: replace *`_

* chore(useContentHandler): typing

* chore: more type fixes and safely announce final message
This commit is contained in:
Danny Avila 2024-08-19 03:51:17 -04:00 committed by GitHub
parent 598e2be225
commit cebb3751c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 152 additions and 105 deletions

View file

@ -36,7 +36,7 @@ export default function useContentHandler({ setMessages, getMessages }: TUseCont
_messages
?.filter((m) => m.messageId !== messageId)
?.map((msg) => ({ ...msg, thread_id })) ?? [];
const userMessage = messages[messages.length - 1];
const userMessage = messages[messages.length - 1] as TMessage | undefined;
const { initialResponse } = submission;
@ -44,7 +44,7 @@ export default function useContentHandler({ setMessages, getMessages }: TUseCont
if (!response) {
response = {
...initialResponse,
parentMessageId: userMessage?.messageId,
parentMessageId: userMessage?.messageId ?? '',
conversationId,
messageId,
thread_id,
@ -55,7 +55,7 @@ export default function useContentHandler({ setMessages, getMessages }: TUseCont
// TODO: handle streaming for non-text
const textPart: Text | string | undefined = data[ContentTypes.TEXT];
const part: ContentPart =
textPart && typeof textPart === 'string' ? { value: textPart } : data[type];
textPart != null && typeof textPart === 'string' ? { value: textPart } : data[type];
if (type === ContentTypes.IMAGE_FILE) {
addFileToCache(queryClient, part as ImageFile & PartMetadata);