Skip to content

Commit

Permalink
Some suggested a11y changes for AI integration feature (#2191)
Browse files Browse the repository at this point in the history
Co-authored-by: Dylan Staley <[email protected]>
  • Loading branch information
MelSumner and dstaley authored Oct 9, 2023
1 parent 57e5c30 commit 248a466
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 34 deletions.
6 changes: 6 additions & 0 deletions src/components/chatbox/chatbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@ const ChatBox = () => {
)}
</div>
<textarea
aria-label="Ask AI a question"
aria-describedby="user-instructions"
autoFocus
className={classNames(s.reset, s.textarea)}
spellCheck={false}
Expand All @@ -380,6 +382,9 @@ const ChatBox = () => {
placeholder="Ask a question"
disabled={isLoading}
/>
<span id="user-instructions" className="g-screen-reader-only">
The question can be 200 characters long.
</span>
<div className={s.buttonContainer}>
{isLoading ? (
<Button
Expand All @@ -406,6 +411,7 @@ const ChatBox = () => {
/* Display/100/Regular */
size={100}
weight="regular"
id="ai-disclaimer-text"
>
AI Disclaimer: Content generated by Developer AI may contain errors,
inconsistencies, or outdated information. It is provided as-is
Expand Down
14 changes: 11 additions & 3 deletions src/components/chatbox/message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,16 @@ const Markdown = lazy(() => import('./Markdown'))

const UserMessage = ({ text, image }: { text: string; image?: string }) => {
return (
<div className={classNames(s.message, s.messageUser)}>
// We want aria-live here so that when results are loaded, the user
// with a screen reader will hear "your question" + their query
// repeated back to them.
<div className={classNames(s.message, s.messageUser)} aria-live="polite">
<div className={classNames(s.avatar)}>
{image ? <img src={image} alt="user avatar" /> : null}
{/*
This avatar is presentation only, but the alt text here
results in a better screen reader experience.
*/}
{image ? <img src={image} alt="Your question:" /> : null}
</div>
<Text /* Body/200/Medium */
size={200}
Expand Down Expand Up @@ -142,7 +149,7 @@ const AssistantMessage = ({
<IconClipboard24 height={12} width={12} />
)
}
aria-label="Copy to clipboard"
aria-label="Copy results to clipboard"
text={isCopied ? 'Copied' : 'Copy'}
onClick={handleCopy}
/>
Expand Down Expand Up @@ -249,6 +256,7 @@ export const MessageList = ({ messages }: { messages: MessageType[] }) => {
conversationId={message.conversationId}
messageId={message.messageId}
showActions={shouldShowActions}
aria-live="polite"
/>
)
}
Expand Down
14 changes: 10 additions & 4 deletions src/components/command-bar/commands/chat/chat.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
* SPDX-License-Identifier: MPL-2.0
*/

.backArrow {
composes: g-focus-ring-from-box-shadow from global;
cursor: pointer;
border-radius: 5px;
.backButton {
& svg {
/*
This overrides the default svg color set in
command-bar-dialog.module.css, which allows the button's svg
element to correctly inherit the currentColor.
TODO: refactor command icons to always rely on currentColor
*/
color: unset;
}
}
26 changes: 13 additions & 13 deletions src/components/command-bar/commands/chat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ import { IconArrowLeft24 } from '@hashicorp/flight-icons/svg-react/arrow-left-24
import { CommandBarCommand } from 'components/command-bar/types'
import ChatBox from 'components/chatbox/chatbox'
import { useCommandBar } from 'components/command-bar'
import Button from 'components/button'

import s from './chat.module.css'

// An interactive Icon w/ "back" functionality
const Icon = () => {
// A button with an icon and text w/ "back" functionality
const BackButton = () => {
const { setCurrentCommand } = useCommandBar()
return (
<IconArrowLeft24
tabIndex={0}
className={s.backArrow}
aria-label="Return to search"
onKeyDown={(e) => {
if (e.key === 'Enter') {
setCurrentCommand('search')
}
}}
<Button
className={s.backButton}
color="tertiary"
size="large"
icon={<IconArrowLeft24 />}
iconPosition="leading"
text="Return to Search"
type="button"
onClick={() => {
setCurrentCommand('search')
}}
Expand All @@ -31,9 +31,9 @@ const Icon = () => {
}
const chatCommand: CommandBarCommand = {
name: 'chat',
icon: <Icon />,
icon: <BackButton />,
inputProps: {
placeholder: () => 'Return to search',
placeholder: () => 'Hide me',
},
DialogBody: ChatBox,
}
Expand Down
15 changes: 1 addition & 14 deletions src/components/command-bar/components/dialog/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,7 @@ const CommandBarDialogHeader = () => {
</div>
) : null}
<div className={s.inputWrapper}>
{currentCommand.name == 'chat' ? (
// This is a dummy element to display text
// TODO(kevinwang): make this less hacky
<div className={s.input}>
<label
className={s.label}
onClick={() => {
setCurrentCommand('search')
}}
>
Return to search
</label>
</div>
) : (
{currentCommand.name !== 'chat' && (
<input
aria-label={inputPlaceholder}
className={s.input}
Expand Down

1 comment on commit 248a466

@vercel
Copy link

@vercel vercel bot commented on 248a466 Oct 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.