add aria-labels to elements for screen readers (#1106)

This commit is contained in:
KDSBrowne 2023-01-15 06:16:06 -05:00 committed by GitHub
parent 60728e069a
commit 6f87ff022a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 136 additions and 24 deletions

View file

@ -89,6 +89,7 @@ export function ToolButtonWithTooltip({
isToolLocked={isLocked && rest.isActive}
onDoubleClick={handleDoubleClick}
onKeyDown={handleKeyDown}
aria-label={label[0].toUpperCase() + label.slice(1)}
/>
</Tooltip>
)

View file

@ -189,7 +189,7 @@ export function ActionButton() {
return (
<DropdownMenu.Root dir="ltr" onOpenChange={handleMenuOpenChange}>
<DropdownMenu.Trigger dir="ltr" asChild id="TD-Tools-Dots">
<ToolButton variant="circle">
<ToolButton aria-label={intl.formatMessage({ id: 'shape.options' })} variant="circle">
<DotsHorizontalIcon />
</ToolButton>
</DropdownMenu.Trigger>
@ -197,12 +197,20 @@ export function ActionButton() {
<>
<ButtonsRow>
<Tooltip label={intl.formatMessage({ id: 'duplicate' })} kbd={`#D`} id="TD-Tools-Copy">
<ToolButton disabled={!hasSelection} onClick={handleDuplicate}>
<ToolButton
aria-label={intl.formatMessage({ id: 'duplicate' })}
disabled={!hasSelection}
onClick={handleDuplicate}
>
<CopyIcon />
</ToolButton>
</Tooltip>
<Tooltip label={intl.formatMessage({ id: 'rotate' })} id="TD-Tools-Rotate">
<ToolButton disabled={!hasSelection} onClick={handleRotate}>
<ToolButton
aria-label={intl.formatMessage({ id: 'rotate' })}
disabled={!hasSelection}
onClick={handleRotate}
>
<RotateCounterClockwiseIcon />
</ToolButton>
</Tooltip>
@ -211,7 +219,11 @@ export function ActionButton() {
kbd={`#L`}
id="TD-Tools-Lock"
>
<ToolButton disabled={!hasSelection} onClick={handleToggleLocked}>
<ToolButton
aria-label={intl.formatMessage({ id: isAllLocked ? 'unlock' : 'lock' })}
disabled={!hasSelection}
onClick={handleToggleLocked}
>
{isAllLocked ? <LockClosedIcon /> : <LockOpen1Icon />}
</ToolButton>
</Tooltip>
@ -221,12 +233,19 @@ export function ActionButton() {
})}
id="TD-Tools-AspectRatio"
>
<ToolButton disabled={!hasSelection} onClick={handleToggleAspectRatio}>
<ToolButton
aria-label={intl.formatMessage({
id: isAllAspectLocked ? 'unlock.aspect.ratio' : 'lock.aspect.ratio',
})}
disabled={!hasSelection}
onClick={handleToggleAspectRatio}
>
{isAllAspectLocked ? <AspectRatioIcon /> : <BoxIcon />}
</ToolButton>
</Tooltip>
<Tooltip label={intl.formatMessage({ id: 'group' })} kbd={`#G`} id="TD-Tools-Group">
<ToolButton
aria-label={intl.formatMessage({ id: 'group' })}
disabled={!hasSelection || (!isAllGrouped && !hasMultipleSelection)}
onClick={handleGroup}
>
@ -240,7 +259,11 @@ export function ActionButton() {
kbd={`#⇧[`}
id="TD-Tools-PinBottom"
>
<ToolButton disabled={!hasSelection} onClick={handleMoveToBack}>
<ToolButton
aria-label={intl.formatMessage({ id: 'move.to.back' })}
disabled={!hasSelection}
onClick={handleMoveToBack}
>
<PinBottomIcon />
</ToolButton>
</Tooltip>
@ -249,7 +272,11 @@ export function ActionButton() {
kbd={`#[`}
id="TD-Tools-ArrowDown"
>
<ToolButton disabled={!hasSelection} onClick={handleMoveBackward}>
<ToolButton
aria-label={intl.formatMessage({ id: 'move.backward' })}
disabled={!hasSelection}
onClick={handleMoveBackward}
>
<ArrowDownIcon />
</ToolButton>
</Tooltip>
@ -258,7 +285,11 @@ export function ActionButton() {
kbd={`#]`}
id="TD-Tools-ArrowUp"
>
<ToolButton disabled={!hasSelection} onClick={handleMoveForward}>
<ToolButton
aria-label={intl.formatMessage({ id: 'move.forward' })}
disabled={!hasSelection}
onClick={handleMoveForward}
>
<ArrowUpIcon />
</ToolButton>
</Tooltip>
@ -267,12 +298,20 @@ export function ActionButton() {
kbd={`#⇧]`}
id="TD-Tools-PinTop"
>
<ToolButton disabled={!hasSelection} onClick={handleMoveToFront}>
<ToolButton
aria-label={intl.formatMessage({ id: 'move.to.front' })}
disabled={!hasSelection}
onClick={handleMoveToFront}
>
<PinTopIcon />
</ToolButton>
</Tooltip>
<Tooltip label={intl.formatMessage({ id: 'reset.angle' })} id="TD-Tools-ResetAngle">
<ToolButton disabled={!hasSelection} onClick={handleResetAngle}>
<ToolButton
aria-label={intl.formatMessage({ id: 'reset.angle' })}
disabled={!hasSelection}
onClick={handleResetAngle}
>
<AngleIcon />
</ToolButton>
</Tooltip>
@ -280,7 +319,11 @@ export function ActionButton() {
<Divider />
<ButtonsRow>
<Tooltip label={intl.formatMessage({ id: 'align.left' })} id="TD-Tools-AlignLeft">
<ToolButton disabled={!hasTwoOrMore} onClick={alignLeft}>
<ToolButton
aria-label={intl.formatMessage({ id: 'align.left' })}
disabled={!hasTwoOrMore}
onClick={alignLeft}
>
<AlignLeftIcon />
</ToolButton>
</Tooltip>
@ -288,12 +331,20 @@ export function ActionButton() {
label={intl.formatMessage({ id: 'align.center.x' })}
id="TD-Tools-AlignCenterHorizontal"
>
<ToolButton disabled={!hasTwoOrMore} onClick={alignCenterHorizontal}>
<ToolButton
aria-label={intl.formatMessage({ id: 'align.center.x' })}
disabled={!hasTwoOrMore}
onClick={alignCenterHorizontal}
>
<AlignCenterHorizontallyIcon />
</ToolButton>
</Tooltip>
<Tooltip label={intl.formatMessage({ id: 'align.right' })} id="TD-Tools-AlignRight">
<ToolButton disabled={!hasTwoOrMore} onClick={alignRight}>
<ToolButton
aria-label={intl.formatMessage({ id: 'align.right' })}
disabled={!hasTwoOrMore}
onClick={alignRight}
>
<AlignRightIcon />
</ToolButton>
</Tooltip>
@ -301,7 +352,11 @@ export function ActionButton() {
label={intl.formatMessage({ id: 'stretch.x' })}
id="TD-Tools-StretchHorizontal"
>
<ToolButton disabled={!hasTwoOrMore} onClick={stretchHorizontally}>
<ToolButton
aria-label={intl.formatMessage({ id: 'stretch.x' })}
disabled={!hasTwoOrMore}
onClick={stretchHorizontally}
>
<StretchHorizontallyIcon />
</ToolButton>
</Tooltip>
@ -309,14 +364,22 @@ export function ActionButton() {
label={intl.formatMessage({ id: 'distribute.x' })}
id="TD-Tools-SpaceEvenlyHorizontal"
>
<ToolButton disabled={!hasThreeOrMore} onClick={distributeHorizontally}>
<ToolButton
aria-label={intl.formatMessage({ id: 'distribute.x' })}
disabled={!hasThreeOrMore}
onClick={distributeHorizontally}
>
<SpaceEvenlyHorizontallyIcon />
</ToolButton>
</Tooltip>
</ButtonsRow>
<ButtonsRow>
<Tooltip label={intl.formatMessage({ id: 'align.top' })} id="TD-Tools-AlignTop">
<ToolButton disabled={!hasTwoOrMore} onClick={alignTop}>
<ToolButton
aria-label={intl.formatMessage({ id: 'align.top' })}
disabled={!hasTwoOrMore}
onClick={alignTop}
>
<AlignTopIcon />
</ToolButton>
</Tooltip>
@ -324,17 +387,29 @@ export function ActionButton() {
label={intl.formatMessage({ id: 'align.center.y' })}
id="TD-Tools-AlignCenterVertical"
>
<ToolButton disabled={!hasTwoOrMore} onClick={alignCenterVertical}>
<ToolButton
aria-label={intl.formatMessage({ id: 'align.center.y' })}
disabled={!hasTwoOrMore}
onClick={alignCenterVertical}
>
<AlignCenterVerticallyIcon />
</ToolButton>
</Tooltip>
<Tooltip label={intl.formatMessage({ id: 'align.bottom' })} id="TD-Tools-AlignBottom">
<ToolButton disabled={!hasTwoOrMore} onClick={alignBottom}>
<ToolButton
aria-label={intl.formatMessage({ id: 'align.bottom' })}
disabled={!hasTwoOrMore}
onClick={alignBottom}
>
<AlignBottomIcon />
</ToolButton>
</Tooltip>
<Tooltip label={intl.formatMessage({ id: 'stretch.y' })} id="TD-Tools-StretchVertical">
<ToolButton disabled={!hasTwoOrMore} onClick={stretchVertically}>
<ToolButton
aria-label={intl.formatMessage({ id: 'stretch.y' })}
disabled={!hasTwoOrMore}
onClick={stretchVertically}
>
<StretchVerticallyIcon />
</ToolButton>
</Tooltip>
@ -342,7 +417,11 @@ export function ActionButton() {
label={intl.formatMessage({ id: 'distribute.y' })}
id="TD-Tools-SpaceEvenlyVertical"
>
<ToolButton disabled={!hasThreeOrMore} onClick={distributeVertically}>
<ToolButton
aria-label={intl.formatMessage({ id: 'distribute.y' })}
disabled={!hasThreeOrMore}
onClick={distributeVertically}
>
<SpaceEvenlyVerticallyIcon />
</ToolButton>
</Tooltip>

View file

@ -21,7 +21,12 @@ export function DeleteButton() {
return (
<Tooltip label={intl.formatMessage({ id: 'delete' })} kbd="⌫" id="TD-Delete">
<ToolButton variant="circle" disabled={!hasSelection} onSelect={handleDelete}>
<ToolButton
aria-label={intl.formatMessage({ id: 'delete' })}
variant="circle"
disabled={!hasSelection}
onSelect={handleDelete}
>
<TrashIcon />
</ToolButton>
</Tooltip>

View file

@ -84,6 +84,7 @@ export const ShapesMenu = React.memo(function ShapesMenu({
isToolLocked={isActive && isToolLocked}
isActive={isActive}
onKeyDown={handleKeyDown}
aria-label={intl.formatMessage({ id: 'shapes' })}
>
{shapeShapeIcons[lastActiveTool]}
</ToolButton>
@ -99,6 +100,7 @@ export const ShapesMenu = React.memo(function ShapesMenu({
>
<DropdownMenu.Item asChild>
<ToolButton
aria-label={intl.formatMessage({ id: shape })}
variant="primary"
onClick={() => {
app.selectTool(shape)

View file

@ -6,7 +6,7 @@ import {
TextAlignRightIcon,
} from '@radix-ui/react-icons'
import * as React from 'react'
import { FormattedMessage } from 'react-intl'
import { FormattedMessage, useIntl } from 'react-intl'
import { Divider } from '~components/Primitives/Divider'
import { DMCheckboxItem, DMContent, DMRadioItem } from '~components/Primitives/DropdownMenu'
import { ToolButton } from '~components/Primitives/ToolButton'
@ -105,6 +105,8 @@ const optionsSelector = (s: TDSnapshot) => {
export const StyleMenu = React.memo(function ColorMenu() {
const app = useTldrawApp()
const intl = useIntl()
const theme = app.useStore(themeSelector)
const keepOpen = app.useStore(keepOpenSelector)
@ -194,7 +196,7 @@ export const StyleMenu = React.memo(function ColorMenu() {
modal={false}
>
<DropdownMenu.Trigger asChild id="TD-Styles">
<ToolButton variant="text">
<ToolButton aria-label={intl.formatMessage({ id: 'styles' })} variant="text">
<FormattedMessage id="styles" />
<OverlapIcons
style={{
@ -229,6 +231,7 @@ export const StyleMenu = React.memo(function ColorMenu() {
variant="icon"
isActive={displayedStyle.color === style}
onClick={() => app.style({ color: style as ColorStyle })}
aria-label={intl.formatMessage({ id: style })}
>
<CircleIcon
size={18}
@ -262,6 +265,7 @@ export const StyleMenu = React.memo(function ColorMenu() {
onSelect={preventEvent}
bp={breakpoints}
id={`TD-Styles-Dash-${style}`}
aria-label={intl.formatMessage({ id: style })}
>
{DASH_ICONS[style as DashStyle]}
</DMRadioItem>
@ -279,6 +283,7 @@ export const StyleMenu = React.memo(function ColorMenu() {
onSelect={preventEvent}
bp={breakpoints}
id={`TD-Styles-Dash-${sizeStyle}`}
aria-label={intl.formatMessage({ id: sizeStyle })}
>
{SIZE_ICONS[sizeStyle as SizeStyle]}
</DMRadioItem>

View file

@ -52,6 +52,8 @@
"new.page": "New Page",
"page.name": "Page Name",
"duplicate": "Duplicate",
"shape.options": "Shape Options",
"shapes": "Shapes",
"cancel": "Cancel",
"copy.invite.link": "Copy Invite Link",
"copy.readonly.link": "Copy ReadOnly Link",
@ -124,5 +126,23 @@
"dialog.no": "No",
"dialog.yes": "Yes",
"enter.file.name": "Enter file name",
"tldraw-beta": "Try the new tldraw"
"tldraw-beta": "Try the new tldraw",
"white": "White",
"lightGray": "Light gray",
"gray": "Gray",
"black": "Black",
"green": "Green",
"cyan": "Cyan",
"blue": "Blue",
"indigo": "Indigo",
"violet": "Violet",
"red": "Red",
"orange": "Orange",
"yellow": "Yellow",
"solid": "Solid",
"dashed": "Dashed",
"dotted": "Dotted",
"small": "Small",
"medium": "Medium",
"large": "Large"
}