diff --git a/packages/app-mobile/components/action-button.js b/packages/app-mobile/components/action-button.js index 02173dc3b5..d31db8ed71 100644 --- a/packages/app-mobile/components/action-button.js +++ b/packages/app-mobile/components/action-button.js @@ -60,12 +60,31 @@ class ActionButtonComponent extends React.Component { renderIconMultiStates() { const button = this.props.buttons[this.state.buttonIndex]; - return ; + + return ; } renderIcon() { const mainButton = this.props.mainButton ? this.props.mainButton : {}; - return mainButton.icon ? : ; + const iconName = mainButton.icon ?? 'md-add'; + + // Icons don't have alt text by default. We need to add it: + const iconTitle = mainButton.title ?? _('Add new'); + + // TODO: If the button toggles a sub-menu, state whether the submenu is open + // or closed. + + return ( + + ); } render() { @@ -99,8 +118,14 @@ class ActionButtonComponent extends React.Component { const buttonTitle = button.title ? button.title : ''; const key = `${buttonTitle.replace(/\s/g, '_')}_${button.icon}`; buttonComps.push( + // TODO: By default, ReactNativeActionButton also adds a title, which is focusable + // by the screen reader. As such, each item currently is double-focusable - + ); } diff --git a/packages/app-mobile/components/checkbox.js b/packages/app-mobile/components/checkbox.js index 9e2bdcfe8a..b6919841dc 100644 --- a/packages/app-mobile/components/checkbox.js +++ b/packages/app-mobile/components/checkbox.js @@ -61,7 +61,14 @@ class Checkbox extends Component { // if (style.display) thStyle.display = style.display; return ( - this.onPress()} style={thStyle}> + this.onPress()} + style={thStyle} + accessibilityRole="checkbox" + accessibilityState={{ + checked: this.state.checked, + }} + accessibilityLabel={this.props.accessibilityLabel ?? ''}> ); diff --git a/packages/app-mobile/components/note-item.js b/packages/app-mobile/components/note-item.js index c853599001..f6d8dab3bd 100644 --- a/packages/app-mobile/components/note-item.js +++ b/packages/app-mobile/components/note-item.js @@ -6,6 +6,7 @@ const { Checkbox } = require('./checkbox.js'); const Note = require('@joplin/lib/models/Note').default; const time = require('@joplin/lib/time').default; const { themeStyle } = require('./global-style.js'); +const { _ } = require('@joplin/lib/locale'); class NoteItemComponent extends Component { constructor() { @@ -128,13 +129,20 @@ class NoteItemComponent extends Component { const selectionWrapperStyle = isSelected ? this.styles().selectionWrapperSelected : this.styles().selectionWrapper; + const noteTitle = Note.displayTitle(note); + return ( this.onPress()} onLongPress={() => this.onLongPress()} activeOpacity={0.5}> - this.todoCheckbox_change(checked)} /> - {Note.displayTitle(note)} + this.todoCheckbox_change(checked)} + accessibilityLabel={_('to-do: %s', noteTitle)} + /> + {noteTitle} diff --git a/packages/app-mobile/components/screen-header.js b/packages/app-mobile/components/screen-header.js index f194d0698f..3a1c668973 100644 --- a/packages/app-mobile/components/screen-header.js +++ b/packages/app-mobile/components/screen-header.js @@ -225,7 +225,12 @@ class ScreenHeaderComponent extends React.PureComponent { render() { function sideMenuButton(styles, onPress) { return ( - + @@ -235,9 +240,18 @@ class ScreenHeaderComponent extends React.PureComponent { function backButton(styles, onPress, disabled) { return ( - + - + ); @@ -249,7 +263,14 @@ class ScreenHeaderComponent extends React.PureComponent { const icon = disabled ? : ; return ( - + {icon} ); @@ -262,7 +283,11 @@ class ScreenHeaderComponent extends React.PureComponent { const viewStyle = options.disabled ? this.styles().iconButtonDisabled : this.styles().iconButton; return ( - + {icon} ); @@ -287,7 +312,11 @@ class ScreenHeaderComponent extends React.PureComponent { function selectAllButton(styles, onPress) { return ( - + @@ -297,7 +326,11 @@ class ScreenHeaderComponent extends React.PureComponent { function searchButton(styles, onPress) { return ( - + @@ -307,7 +340,15 @@ class ScreenHeaderComponent extends React.PureComponent { function deleteButton(styles, onPress, disabled) { return ( - + @@ -317,7 +358,15 @@ class ScreenHeaderComponent extends React.PureComponent { function duplicateButton(styles, onPress, disabled) { return ( - + @@ -327,7 +376,11 @@ class ScreenHeaderComponent extends React.PureComponent { function sortButton(styles, onPress) { return ( - + diff --git a/packages/app-mobile/components/side-menu-content.js b/packages/app-mobile/components/side-menu-content.js index 120a21cee1..54a43605c9 100644 --- a/packages/app-mobile/components/side-menu-content.js +++ b/packages/app-mobile/components/side-menu-content.js @@ -250,7 +250,8 @@ class SideMenuContentComponent extends Component { let iconWrapper = null; - const iconName = this.props.collapsedFolderIds.indexOf(folder.id) >= 0 ? 'chevron-down' : 'chevron-up'; + const collapsed = this.props.collapsedFolderIds.indexOf(folder.id) >= 0; + const iconName = collapsed ? 'chevron-down' : 'chevron-up'; const iconComp = ; iconWrapper = !hasChildren ? null : ( @@ -260,6 +261,9 @@ class SideMenuContentComponent extends Component { onPress={() => { if (hasChildren) this.folder_togglePress(folder); }} + + accessibilityLabel={collapsed ? _('Expand folder') : _('Collapse folder')} + accessibilityRole="togglebutton" > {iconComp}