diff --git a/packages/app-desktop/gui/HelpButton.tsx b/packages/app-desktop/gui/HelpButton.tsx index 7dbb13df4..d1b8aa4ab 100644 --- a/packages/app-desktop/gui/HelpButton.tsx +++ b/packages/app-desktop/gui/HelpButton.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; const { connect } = require('react-redux'); import { themeStyle } from '@joplin/lib/theme'; import { AppState } from '../app.reducer'; +import { _ } from '@joplin/lib/locale'; interface Props { tip: string; @@ -10,6 +11,9 @@ interface Props { themeId: number; // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied style: any; + + 'aria-controls'?: string; + 'aria-expanded'?: string; } class HelpButtonComponent extends React.Component { @@ -29,11 +33,21 @@ class HelpButtonComponent extends React.Component { const helpIconStyle = { flex: 0, width: 16, height: 16, marginLeft: 10 }; // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const extraProps: any = {}; - if (this.props.tip) extraProps['data-tip'] = this.props.tip; + if (this.props.tip) { + extraProps['data-tip'] = this.props.tip; + extraProps['aria-description'] = this.props.tip; + } return ( - - - + ); } } diff --git a/packages/app-desktop/gui/ItemList.tsx b/packages/app-desktop/gui/ItemList.tsx index 9baa3e334..0ffd582a1 100644 --- a/packages/app-desktop/gui/ItemList.tsx +++ b/packages/app-desktop/gui/ItemList.tsx @@ -10,6 +10,10 @@ interface Props { itemRenderer: (item: ItemType, index: number)=> React.JSX.Element; className?: string; onItemDrop?: DragEventHandler; + + id?: string; + role?: string; + 'aria-label'?: string; } interface State { @@ -164,7 +168,20 @@ class ItemList extends React.Component, State> { if (this.props.className) classes.push(this.props.className); return ( -
+
{itemComps}
); diff --git a/packages/app-desktop/gui/styles/flat-button.scss b/packages/app-desktop/gui/styles/flat-button.scss new file mode 100644 index 000000000..5620e71d6 --- /dev/null +++ b/packages/app-desktop/gui/styles/flat-button.scss @@ -0,0 +1,7 @@ + +.flat-button { + border: none; + background: transparent; + color: inherit; + padding: 0; +} diff --git a/packages/app-desktop/gui/styles/help-text.scss b/packages/app-desktop/gui/styles/help-text.scss new file mode 100644 index 000000000..0c45f5075 --- /dev/null +++ b/packages/app-desktop/gui/styles/help-text.scss @@ -0,0 +1,12 @@ + +.help-text { + color: var(--joplin-color); + line-height: var(--joplin-line-height); + font-family: var(--joplin-font-family); + font-size: var(--joplin-font-size); + margin-bottom: 10px; + + &[hidden] { + display: none; + } +} diff --git a/packages/app-desktop/gui/styles/index.scss b/packages/app-desktop/gui/styles/index.scss index 6c5eb1d2a..71a4d1665 100644 --- a/packages/app-desktop/gui/styles/index.scss +++ b/packages/app-desktop/gui/styles/index.scss @@ -2,5 +2,7 @@ @use './dialog-modal-layer.scss'; @use './user-webview-dialog.scss'; @use './prompt-dialog.scss'; +@use './flat-button.scss'; +@use './help-text.scss'; @use './toolbar-button.scss'; @use './editor-toolbar.scss'; diff --git a/packages/app-desktop/plugins/GotoAnything.tsx b/packages/app-desktop/plugins/GotoAnything.tsx index 94614411a..7ee3f7f32 100644 --- a/packages/app-desktop/plugins/GotoAnything.tsx +++ b/packages/app-desktop/plugins/GotoAnything.tsx @@ -93,9 +93,13 @@ const getContentMarkupLanguageAndBody = (result: GotoAnythingSearchResult, notes // result, we use this function - which returns either the item_id, if present, // or the note ID. const getResultId = (result: GotoAnythingSearchResult) => { - return result.item_id ? result.item_id : result.id; + // This ID used as a DOM ID for accessibility purposes, so it is prefixed to prevent + // name collisions. + return `goto-anything-result-${result.item_id ? result.item_id : result.id}`; }; +const itemListId = 'goto-anything-item-list'; + class GotoAnything { // eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied @@ -192,7 +196,6 @@ class DialogComponent extends React.PureComponent { borderBottomColor: theme.dividerColor, boxSizing: 'border-box', }, - help: { ...theme.textStyle, marginBottom: 10 }, inputHelpWrapper: { display: 'flex', flexDirection: 'row', alignItems: 'center' }, }; @@ -530,10 +533,11 @@ class DialogComponent extends React.PureComponent { }); } - public renderItem(item: GotoAnythingSearchResult) { + public renderItem(item: GotoAnythingSearchResult, index: number) { const theme = themeStyle(this.props.themeId); const style = this.style(); - const isSelected = getResultId(item) === this.state.selectedItemId; + const resultId = getResultId(item); + const isSelected = resultId === this.state.selectedItemId; const rowStyle = isSelected ? style.rowSelected : style.row; const titleHtml = item.fragments ? `${item.title}` @@ -541,12 +545,25 @@ class DialogComponent extends React.PureComponent { const fragmentsHtml = !item.fragments ? null : surroundKeywords(this.state.keywords, item.fragments, ``, '', { escapeHtml: true }); - const folderIcon = ; + const folderIcon = ; const pathComp = !item.path ? null :
{folderIcon} {item.path}
; const fragmentComp = !fragmentsHtml ? null :
; return ( -
+
{fragmentComp} {pathComp} @@ -619,6 +636,9 @@ class DialogComponent extends React.PureComponent { return ( { public render() { const style = this.style(); - const helpComp = !this.state.showHelp ? null :
{_('Type a note title or part of its content to jump to it. Or type # followed by a tag name, or @ followed by a notebook name. Or type : to search for commands.')}
; + const helpTextId = 'goto-anything-help-text'; + const helpComp = ( + + ); return ( - + {helpComp}
- - + +
{this.renderList()}