Skip to content

Commit

Permalink
Desktop: Accessibility: Add missing labels and role information to se…
Browse files Browse the repository at this point in the history
…veral controls (#10788)
  • Loading branch information
personalizedrefrigerator authored Jul 28, 2024
1 parent 6d92e98 commit b108bf7
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 24 deletions.
28 changes: 20 additions & 8 deletions packages/app-desktop/gui/NotePropertiesDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
textDecoration: 'none',
backgroundColor: theme.backgroundColor,
padding: '.14em',
display: 'flex',
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
marginLeft: '0.5em',
Expand Down Expand Up @@ -281,11 +281,13 @@ class NotePropertiesDialog extends React.Component<Props, State> {
public createNoteField(key: keyof FormNote, value: any) {
const styles = this.styles(this.props.themeId);
const theme = themeStyle(this.props.themeId);
const labelComp = <label style={{ ...theme.textStyle, ...theme.controlBoxLabel }}>{this.formatLabel(key)}</label>;
const labelText = this.formatLabel(key);
const labelComp = <label role='rowheader' style={{ ...theme.textStyle, ...theme.controlBoxLabel }}>{labelText}</label>;
let controlComp = null;
let editComp = null;
let editCompHandler = null;
let editCompIcon = null;
let editComDescription = null;

// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const onKeyDown = (event: any) => {
Expand Down Expand Up @@ -320,6 +322,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
void this.saveProperty();
};
editCompIcon = 'fa-save';
editComDescription = _('Save changes');
} else {
controlComp = (
<input
Expand Down Expand Up @@ -374,28 +377,35 @@ class NotePropertiesDialog extends React.Component<Props, State> {
this.editPropertyButtonClick(key, value);
};
editCompIcon = 'fa-edit';
editComDescription = _('Edit');
}

// Add the copy icon and the 'copy on click' event
if (key === 'id') {
editCompIcon = 'fa-copy';
editCompHandler = () => clipboard.writeText(value);
editComDescription = _('Copy');
}
}

if (editCompHandler && !this.isReadOnly()) {
editComp = (
<a href="#" onClick={editCompHandler} style={styles.editPropertyButton}>
<a
href="#"
onClick={editCompHandler}
style={styles.editPropertyButton}
aria-label={editComDescription}
title={editComDescription}
>
<i className={`fas ${editCompIcon}`} aria-hidden="true"></i>
</a>
);
}

return (
<div key={key} style={theme.controlBox} className="note-property-box">
<div role='row' key={key} style={theme.controlBox} className="note-property-box">
{labelComp}
{controlComp}
{editComp}
<span role='cell'>{controlComp} {editComp}</span>
</div>
);
}
Expand Down Expand Up @@ -439,8 +449,10 @@ class NotePropertiesDialog extends React.Component<Props, State> {
return (
<div style={theme.dialogModalLayer}>
<div style={theme.dialogBox}>
<div style={theme.dialogTitle}>{_('Note properties')}</div>
<div>{noteComps}</div>
<div style={theme.dialogTitle} id='note-properties-dialog-title'>{_('Note properties')}</div>
<div role='table' aria-labelledby='note-properties-dialog-title'>
{noteComps}
</div>
<DialogButtonRow themeId={this.props.themeId} okButtonShow={!this.isReadOnly()} okButtonRef={this.okButton} onClick={this.buttonRow_click}/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import * as React from 'react';

import { FolderIcon, FolderIconType } from '@joplin/lib/services/database/types';
import ExpandLink from './ExpandLink';
import { StyledListItem, StyledListItemAnchor, StyledNoteCount, StyledShareIcon, StyledSpanFix } from '../styles';
import { StyledListItem, StyledListItemAnchor, StyledShareIcon, StyledSpanFix } from '../styles';
import { ItemClickListener, ItemContextMenuListener, ItemDragListener } from '../types';
import FolderIconBox from '../../FolderIconBox';
import { getTrashFolderIcon, getTrashFolderId } from '@joplin/lib/services/trash';
import Folder from '@joplin/lib/models/Folder';
import { ModelType } from '@joplin/lib/BaseModel';
import { _ } from '@joplin/lib/locale';
import NoteCount from './NoteCount';

const renderFolderIcon = (folderIcon: FolderIcon) => {
if (!folderIcon) {
Expand Down Expand Up @@ -47,8 +49,8 @@ interface FolderItemProps {
function FolderItem(props: FolderItemProps) {
const { hasChildren, showFolderIcon, isExpanded, parentId, depth, selected, folderId, folderTitle, folderIcon, noteCount, onFolderDragStart_, onFolderDragOver_, onFolderDrop_, itemContextMenu, folderItem_click, onFolderToggleClick_, shareId } = props;

const noteCountComp = noteCount ? <StyledNoteCount className="note-count-label">{noteCount}</StyledNoteCount> : null;
const shareIcon = shareId && !parentId ? <StyledShareIcon className="fas fa-share-alt"></StyledShareIcon> : null;
const shareTitle = _('Shared');
const shareIcon = shareId && !parentId ? <StyledShareIcon aria-label={shareTitle} title={shareTitle} className="fas fa-share-alt"/> : null;
const draggable = ![getTrashFolderId(), Folder.conflictFolderId()].includes(folderId);

const doRenderFolderIcon = () => {
Expand All @@ -69,6 +71,7 @@ function FolderItem(props: FolderItemProps) {
isConflictFolder={folderId === Folder.conflictFolderId()}
href="#"
selected={selected}
aria-selected={selected}
shareId={shareId}
data-id={folderId}
data-type={ModelType.Folder}
Expand All @@ -80,7 +83,7 @@ function FolderItem(props: FolderItemProps) {
onDoubleClick={onFolderToggleClick_}
>
{doRenderFolderIcon()}<StyledSpanFix className="title">{folderTitle}</StyledSpanFix>
{shareIcon} {noteCountComp}
{shareIcon} <NoteCount count={noteCount}/>
</StyledListItemAnchor>
</StyledListItem>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const HeaderItem: React.FC<Props> = props => {
tabIndex={0}
ref={props.anchorRef}
>
<StyledHeaderIcon className={item.iconName}/>
<StyledHeaderIcon aria-label='' className={item.iconName}/>
<StyledHeaderLabel>{item.label}</StyledHeaderLabel>
</StyledHeader>
{ item.onPlusButtonClick && addButton }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { StyledNoteCount } from '../styles';
import { _n } from '@joplin/lib/locale';


interface Props {
Expand All @@ -8,7 +8,8 @@ interface Props {

const NoteCount: React.FC<Props> = props => {
const count = props.count;
return count ? <StyledNoteCount className="note-count-label">{count}</StyledNoteCount> : null;
const title = _n('Contains %d note', 'Contains %d notes', count, count);
return count ? <div role='note' aria-label={title} title={title} className="note-count-label">{count}</div> : null;
};

export default NoteCount;
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ const TagItem = (props: Props) => {
}, [props.onClick, tag]);

return (
<StyledListItem selected={selected}
<StyledListItem
selected={selected}
className={`list-item-container ${selected ? 'selected' : ''}`}
onDrop={props.onTagDrop}
data-tag-id={tag.id}
aria-selected={selected}
>
<EmptyExpandLink/>
<StyledListItemAnchor
Expand Down
1 change: 1 addition & 0 deletions packages/app-desktop/gui/Sidebar/style.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@use 'styles/folder-and-tag-list.scss';
@use 'styles/note-count-label.scss';
@use 'styles/sidebar-expand-icon.scss';
@use 'styles/sidebar-expand-link.scss';
@use 'styles/sidebar-header-container.scss';
Expand Down
6 changes: 0 additions & 6 deletions packages/app-desktop/gui/Sidebar/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,6 @@ export const StyledShareIcon = styled.i`
margin-left: 8px;
`;

export const StyledNoteCount = styled.div`
color: ${(props: StyleProps) => props.theme.colorFaded2};
padding-left: 8px;
user-select: none;
`;

export const StyledSynchronizeButton = styled(Button)`
width: 100%;
`;
Expand Down
6 changes: 6 additions & 0 deletions packages/app-desktop/gui/Sidebar/styles/note-count-label.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

.note-count-label {
color: var(--joplin-color-faded2);
padding-left: 8px;
user-select: none;
}
8 changes: 7 additions & 1 deletion packages/app-desktop/gui/ToolbarButton/ToolbarButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,22 @@ export default function ToolbarButton(props: Props) {
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis' };
const disabled = !isEnabled;
return (
<StyledRoot
className={classes.join(' ')}
disabled={!isEnabled}
title={tooltip}
href="#"
hasTitle={!!title}
onClick={() => {
if (isEnabled && onClick) onClick();
}}

// At least on MacOS, the disabled HTML prop isn't sufficient for the screen reader
// to read the element as disable. For this, aria-disabled is necessary.
disabled={disabled}
aria-disabled={!isEnabled}
role='button'
>
{icon}
<span style={style}>{title}</span>
Expand Down
6 changes: 5 additions & 1 deletion packages/app-desktop/gui/lib/SearchInput/SearchInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export interface OnChangeEvent {

export default function(props: Props) {
const iconName = !props.searchStarted ? CommandService.instance().iconName('search') : 'fa fa-times';
const iconLabel = !props.searchStarted ? _('Search') : _('Clear search');

// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const onChange = useCallback((event: any) => {
Expand All @@ -79,7 +80,10 @@ export default function(props: Props) {
spellCheck={false}
disabled={props.disabled}
/>
<SearchButton onClick={props.onSearchButtonClick}>
<SearchButton
aria-label={iconLabel}
onClick={props.onSearchButtonClick}
>
<SearchButtonIcon className={iconName}/>
</SearchButton>
</Root>
Expand Down
1 change: 1 addition & 0 deletions packages/app-desktop/gui/note-viewer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html>
<head id="joplin-container-root-head">
<meta charset="UTF-8">
<title>Note viewer</title>

<style>
body {
Expand Down

0 comments on commit b108bf7

Please sign in to comment.