From a2a2db0451e532647e55d398ce82b866dc92d994 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Wed, 12 Jun 2024 14:39:19 -0400 Subject: [PATCH 1/7] feat: Hide decorative AI assistant icon from screen readers Focusing this description-less, decorative image provide little value for users. --- src/components/icons/assistant.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/icons/assistant.tsx b/src/components/icons/assistant.tsx index 7e62853c7..ea885b105 100644 --- a/src/components/icons/assistant.tsx +++ b/src/components/icons/assistant.tsx @@ -1,10 +1,16 @@ +import { ReactSVG, SVGProps } from 'react'; + interface AssistantIconProps { size?: number; } -export function AssistantIcon( { size = 14 }: AssistantIconProps ) { +export function AssistantIcon( { + size = 14, + 'aria-hidden': ariaHidden, +}: AssistantIconProps & SVGProps< ReactSVG > ) { return ( Date: Thu, 13 Jun 2024 11:24:35 -0400 Subject: [PATCH 2/7] feat: Communicate message author to screen readers Navigating individual lines of text from a back-and-forth conversation is difficult and overwhelming when there are not discernible, navigable grouping or message author labels. --- src/components/content-tab-assistant.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/content-tab-assistant.tsx b/src/components/content-tab-assistant.tsx index c2bcdc9e7..1e7a4878d 100644 --- a/src/components/content-tab-assistant.tsx +++ b/src/components/content-tab-assistant.tsx @@ -149,6 +149,8 @@ export const Message = ( { children, isUser, className }: MessageProps ) => { ); }; + const authorLabel = isUser ? __( 'Your message' ) : __( 'Studio Assistant' ); + return (
{ ) } >
Date: Thu, 13 Jun 2024 11:50:59 -0400 Subject: [PATCH 3/7] feat: Announce incoming assistant messages Improve assistant chat experience while using assistive technologies. --- src/components/content-tab-assistant.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/components/content-tab-assistant.tsx b/src/components/content-tab-assistant.tsx index 1e7a4878d..0995abc68 100644 --- a/src/components/content-tab-assistant.tsx +++ b/src/components/content-tab-assistant.tsx @@ -1,9 +1,10 @@ +import { speak } from '@wordpress/a11y'; import { Spinner } from '@wordpress/components'; import { createInterpolateElement } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Icon, external, copy } from '@wordpress/icons'; import { useI18n } from '@wordpress/react-i18n'; -import React, { useState, useEffect, useRef, memo } from 'react'; +import React, { useState, useEffect, useRef, memo, useMemo } from 'react'; import Markdown, { ExtraProps } from 'react-markdown'; import { useAssistant, Message as MessageType } from '../hooks/use-assistant'; import { useAssistantApi } from '../hooks/use-assistant-api'; @@ -287,6 +288,16 @@ export function ContentTabAssistant( { selectedSite }: ContentTabAssistantProps } }, [ messages ] ); + const latestAssistantMessage = useMemo( + () => messages.filter( ( message ) => message.role === 'assistant' ).pop(), + [ messages ] + ); + useEffect( () => { + if ( latestAssistantMessage ) { + speak( `New message, Studio Assistant, ${ latestAssistantMessage.content }` ); + } + }, [ latestAssistantMessage ] ); + const disabled = isOffline || ! isAuthenticated; return ( From 4e77ceb2a54eafc79982dfd403239b2877249888 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 13 Jun 2024 13:48:44 -0400 Subject: [PATCH 4/7] fix: Assistant message labels exclude Markdown syntax Labeling the element with raw Markdown resulted in announcing disorienting syntax characters. --- src/components/content-tab-assistant.tsx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/components/content-tab-assistant.tsx b/src/components/content-tab-assistant.tsx index 0995abc68..9ea907e28 100644 --- a/src/components/content-tab-assistant.tsx +++ b/src/components/content-tab-assistant.tsx @@ -21,6 +21,7 @@ interface ContentTabAssistantProps { } interface MessageProps { + id: string; children: React.ReactNode; isUser: boolean; className?: string; @@ -86,7 +87,7 @@ const ActionButton = ( { ); }; -export const Message = ( { children, isUser, className }: MessageProps ) => { +export const Message = ( { children, id, isUser, className }: MessageProps ) => { const [ cliOutput, setCliOutput ] = useState< string | null >( null ); const [ cliStatus, setCliStatus ] = useState< 'success' | 'error' | null >( null ); const [ cliTime, setCliTime ] = useState< string | null >( null ); @@ -150,8 +151,6 @@ export const Message = ( { children, isUser, className }: MessageProps ) => { ); }; - const authorLabel = isUser ? __( 'Your message' ) : __( 'Studio Assistant' ); - return (
{ ) } >
+
+ + { isUser ? __( 'Your message' ) : __( 'Studio Assistant' ) }, + +
{ typeof children === 'string' ? (
{ children } @@ -189,12 +195,12 @@ const AuthenticatedView = memo( } ) => ( <> { messages.map( ( message, index ) => ( - + { message.content } ) ) } { isAssistantThinking && ( - + ) } From 36fdeb2fc8ec375c03085db72950c7bbea1618a7 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 13 Jun 2024 13:49:41 -0400 Subject: [PATCH 5/7] feat: Communicate the active assistant "thinking" to screen readers Without a label, there is no indication that the assistant is actively working to answer a message. --- src/components/assistant-thinking.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/assistant-thinking.tsx b/src/components/assistant-thinking.tsx index 9181d8c43..991ee0399 100644 --- a/src/components/assistant-thinking.tsx +++ b/src/components/assistant-thinking.tsx @@ -1,6 +1,8 @@ +import { __ } from '@wordpress/i18n'; + export function MessageThinking() { return ( -
+
Date: Thu, 13 Jun 2024 14:45:49 -0400 Subject: [PATCH 6/7] Revert "feat: Announce incoming assistant messages" This reverts commit 996b5f7629382b2389355c7afec6ebb00f006acb. --- src/components/content-tab-assistant.tsx | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/components/content-tab-assistant.tsx b/src/components/content-tab-assistant.tsx index 9ea907e28..be400a2b2 100644 --- a/src/components/content-tab-assistant.tsx +++ b/src/components/content-tab-assistant.tsx @@ -1,10 +1,9 @@ -import { speak } from '@wordpress/a11y'; import { Spinner } from '@wordpress/components'; import { createInterpolateElement } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Icon, external, copy } from '@wordpress/icons'; import { useI18n } from '@wordpress/react-i18n'; -import React, { useState, useEffect, useRef, memo, useMemo } from 'react'; +import React, { useState, useEffect, useRef, memo } from 'react'; import Markdown, { ExtraProps } from 'react-markdown'; import { useAssistant, Message as MessageType } from '../hooks/use-assistant'; import { useAssistantApi } from '../hooks/use-assistant-api'; @@ -294,16 +293,6 @@ export function ContentTabAssistant( { selectedSite }: ContentTabAssistantProps } }, [ messages ] ); - const latestAssistantMessage = useMemo( - () => messages.filter( ( message ) => message.role === 'assistant' ).pop(), - [ messages ] - ); - useEffect( () => { - if ( latestAssistantMessage ) { - speak( `New message, Studio Assistant, ${ latestAssistantMessage.content }` ); - } - }, [ latestAssistantMessage ] ); - const disabled = isOffline || ! isAuthenticated; return ( From 61daf0a12f80e86dbdd7afc0df793943c0fe0257 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 13 Jun 2024 14:47:41 -0400 Subject: [PATCH 7/7] fix: Add ID to unauthenticated message Ensure correct ARIA labels are read for the unauthenticated message. --- src/components/content-tab-assistant.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/content-tab-assistant.tsx b/src/components/content-tab-assistant.tsx index be400a2b2..32775ff21 100644 --- a/src/components/content-tab-assistant.tsx +++ b/src/components/content-tab-assistant.tsx @@ -208,7 +208,7 @@ const AuthenticatedView = memo( ); const UnauthenticatedView = ( { onAuthenticate }: { onAuthenticate: () => void } ) => ( - +
{ __( 'Hold up!' ) }
{ __( 'You need to log in to your WordPress.com account to use the assistant.' ) }