1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-11-23 22:36:32 +02:00

Desktop: Accessibility: Add a new shortcut to set focus to editor toolbar (#11764)

This commit is contained in:
pedr
2025-02-07 17:41:22 -03:00
committed by GitHub
parent f5d168b16a
commit 1230e1b30c
12 changed files with 64 additions and 5 deletions

View File

@@ -272,6 +272,7 @@ packages/app-desktop/gui/NoteEditor/WarningBanner/BannerContent.js
packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.js packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js
packages/app-desktop/gui/NoteEditor/commands/focusElementToolbar.js
packages/app-desktop/gui/NoteEditor/commands/index.js packages/app-desktop/gui/NoteEditor/commands/index.js
packages/app-desktop/gui/NoteEditor/commands/pasteAsText.js packages/app-desktop/gui/NoteEditor/commands/pasteAsText.js
packages/app-desktop/gui/NoteEditor/commands/showLocalSearch.js packages/app-desktop/gui/NoteEditor/commands/showLocalSearch.js

1
.gitignore vendored
View File

@@ -247,6 +247,7 @@ packages/app-desktop/gui/NoteEditor/WarningBanner/BannerContent.js
packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.js packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js
packages/app-desktop/gui/NoteEditor/commands/focusElementToolbar.js
packages/app-desktop/gui/NoteEditor/commands/index.js packages/app-desktop/gui/NoteEditor/commands/index.js
packages/app-desktop/gui/NoteEditor/commands/pasteAsText.js packages/app-desktop/gui/NoteEditor/commands/pasteAsText.js
packages/app-desktop/gui/NoteEditor/commands/showLocalSearch.js packages/app-desktop/gui/NoteEditor/commands/showLocalSearch.js

View File

@@ -16,6 +16,7 @@ export const runtime = (): CommandRuntime => {
if (target === 'noteList') return CommandService.instance().execute('focusElementNoteList'); if (target === 'noteList') return CommandService.instance().execute('focusElementNoteList');
if (target === 'sideBar') return CommandService.instance().execute('focusElementSideBar'); if (target === 'sideBar') return CommandService.instance().execute('focusElementSideBar');
if (target === 'noteTitle') return CommandService.instance().execute('focusElementNoteTitle', options); if (target === 'noteTitle') return CommandService.instance().execute('focusElementNoteTitle', options);
if (target === 'toolbar') return CommandService.instance().execute('focusElementToolbar', options);
throw new Error(`Invalid focus target: ${target}`); throw new Error(`Invalid focus target: ${target}`);
}, },
}; };

View File

@@ -479,6 +479,7 @@ function useMenu(props: Props) {
menuItemDic.focusElementNoteList, menuItemDic.focusElementNoteList,
menuItemDic.focusElementNoteTitle, menuItemDic.focusElementNoteTitle,
menuItemDic.focusElementNoteBody, menuItemDic.focusElementNoteBody,
menuItemDic.focusElementToolbar,
]; ];
const importItems = []; const importItems = [];

View File

@@ -32,6 +32,7 @@ function Toolbar(props: ToolbarProps) {
const styles = styles_(props); const styles = styles_(props);
return ( return (
<ToolbarBase <ToolbarBase
id="CodeMirrorToolbar"
style={styles.root} style={styles.root}
scrollable={true} scrollable={true}
items={props.toolbarButtonInfos} items={props.toolbarButtonInfos}

View File

@@ -0,0 +1,36 @@
import { CommandRuntime, CommandDeclaration } from '@joplin/lib/services/CommandService';
import { _ } from '@joplin/lib/locale';
import { focus } from '@joplin/lib/utils/focusHandler';
import { WindowCommandDependencies } from '../utils/types';
export const declaration: CommandDeclaration = {
name: 'focusElementToolbar',
label: () => _('Toolbar'),
parentLabel: () => _('Focus'),
};
export const runtime = (dependencies: WindowCommandDependencies): CommandRuntime => {
return {
execute: async () => {
if (!dependencies || !dependencies.containerRef || !dependencies.containerRef.current) return;
const firstButtonOnRTEToolbar = dependencies.containerRef.current.querySelector(
'.tox-toolbar__group button',
);
if (firstButtonOnRTEToolbar) {
focus('focusElementToolbar', firstButtonOnRTEToolbar);
return;
}
const firstButtonOnMarkdownToolbar = dependencies.containerRef.current.querySelector(
'#CodeMirrorToolbar .button:not(.disabled)',
);
if (firstButtonOnMarkdownToolbar) {
focus('focusElementToolbar', firstButtonOnMarkdownToolbar);
}
},
};
};

View File

@@ -1,6 +1,7 @@
// AUTO-GENERATED using `gulp buildScriptIndexes` // AUTO-GENERATED using `gulp buildScriptIndexes`
import * as focusElementNoteBody from './focusElementNoteBody'; import * as focusElementNoteBody from './focusElementNoteBody';
import * as focusElementNoteTitle from './focusElementNoteTitle'; import * as focusElementNoteTitle from './focusElementNoteTitle';
import * as focusElementToolbar from './focusElementToolbar';
import * as pasteAsText from './pasteAsText'; import * as pasteAsText from './pasteAsText';
import * as showLocalSearch from './showLocalSearch'; import * as showLocalSearch from './showLocalSearch';
import * as showRevisions from './showRevisions'; import * as showRevisions from './showRevisions';
@@ -8,6 +9,7 @@ import * as showRevisions from './showRevisions';
const index: any[] = [ const index: any[] = [
focusElementNoteBody, focusElementNoteBody,
focusElementNoteTitle, focusElementNoteTitle,
focusElementToolbar,
pasteAsText, pasteAsText,
showLocalSearch, showLocalSearch,
showRevisions, showRevisions,

View File

@@ -11,6 +11,8 @@ import { ParseOptions } from '@joplin/lib/HtmlToMd';
import { ScrollStrategy } from '@joplin/editor/CodeMirror/CodeMirrorControl'; import { ScrollStrategy } from '@joplin/editor/CodeMirror/CodeMirrorControl';
import { MarkupToHtmlOptions } from '../../hooks/useMarkupToHtml'; import { MarkupToHtmlOptions } from '../../hooks/useMarkupToHtml';
import { ScrollbarSize } from '@joplin/lib/models/settings/builtInMetadata'; import { ScrollbarSize } from '@joplin/lib/models/settings/builtInMetadata';
import { RefObject, SetStateAction } from 'react';
import * as React from 'react';
export interface AllAssetsOptions { export interface AllAssetsOptions {
contentMaxWidthTarget?: string; contentMaxWidthTarget?: string;
@@ -272,3 +274,11 @@ export interface ScrollToTextValue {
element: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'strong' | 'ul'; element: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'strong' | 'ul';
scrollStrategy?: ScrollStrategy; scrollStrategy?: ScrollStrategy;
} }
export interface WindowCommandDependencies {
setShowLocalSearch: React.Dispatch<SetStateAction<boolean>>;
noteSearchBarRef: RefObject<HTMLInputElement>;
editorRef: RefObject<NoteBodyEditorRef>;
titleInputRef: RefObject<HTMLInputElement>;
containerRef: RefObject<HTMLDivElement|null>;
}

View File

@@ -1,5 +1,5 @@
import { RefObject, useEffect } from 'react'; import { RefObject, Dispatch, SetStateAction, useEffect } from 'react';
import { NoteBodyEditorRef, OnChangeEvent, ScrollOptionTypes } from './types'; import { WindowCommandDependencies, NoteBodyEditorRef, OnChangeEvent, ScrollOptionTypes } from './types';
import editorCommandDeclarations, { enabledCondition } from '../editorCommandDeclarations'; import editorCommandDeclarations, { enabledCondition } from '../editorCommandDeclarations';
import CommandService, { CommandDeclaration, CommandRuntime, CommandContext, RegisteredRuntime } from '@joplin/lib/services/CommandService'; import CommandService, { CommandDeclaration, CommandRuntime, CommandContext, RegisteredRuntime } from '@joplin/lib/services/CommandService';
import time from '@joplin/lib/time'; import time from '@joplin/lib/time';
@@ -10,14 +10,14 @@ const commandsWithDependencies = [
require('../commands/showLocalSearch'), require('../commands/showLocalSearch'),
require('../commands/focusElementNoteTitle'), require('../commands/focusElementNoteTitle'),
require('../commands/focusElementNoteBody'), require('../commands/focusElementNoteBody'),
require('../commands/focusElementToolbar'),
require('../commands/pasteAsText'), require('../commands/pasteAsText'),
]; ];
type OnBodyChange = (event: OnChangeEvent)=> void; type OnBodyChange = (event: OnChangeEvent)=> void;
interface HookDependencies { interface HookDependencies {
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied setShowLocalSearch: Dispatch<SetStateAction<boolean>>;
setShowLocalSearch: Function;
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied // eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
dispatch: Function; dispatch: Function;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
@@ -93,11 +93,12 @@ export default function useWindowCommandHandler(dependencies: HookDependencies)
)); ));
} }
const dependencies = { const dependencies: WindowCommandDependencies = {
editorRef, editorRef,
setShowLocalSearch, setShowLocalSearch,
noteSearchBarRef, noteSearchBarRef,
titleInputRef, titleInputRef,
containerRef,
}; };
for (const command of commandsWithDependencies) { for (const command of commandsWithDependencies) {

View File

@@ -15,6 +15,7 @@ interface Props {
items: ToolbarItem[]; items: ToolbarItem[];
disabled: boolean; disabled: boolean;
'aria-label': string; 'aria-label': string;
id?: string;
} }
const getItemType = (item: ToolbarItem) => { const getItemType = (item: ToolbarItem) => {
@@ -181,6 +182,7 @@ const ToolbarBaseComponent: React.FC<Props> = props => {
className={`editor-toolbar ${props.scrollable ? '-scrollable' : ''}`} className={`editor-toolbar ${props.scrollable ? '-scrollable' : ''}`}
style={props.style} style={props.style}
id={props.id ?? undefined}
role='toolbar' role='toolbar'
aria-label={props['aria-label']} aria-label={props['aria-label']}

View File

@@ -7,6 +7,7 @@ export default function() {
'focusElementNoteList', 'focusElementNoteList',
'focusElementNoteTitle', 'focusElementNoteTitle',
'focusElementSideBar', 'focusElementSideBar',
'focusElementToolbar',
'focusSearch', 'focusSearch',
'historyBackward', 'historyBackward',
'historyForward', 'historyForward',

View File

@@ -38,6 +38,7 @@ const defaultKeymapItems = {
{ accelerator: 'Shift+Cmd+L', command: 'focusElementNoteList' }, { accelerator: 'Shift+Cmd+L', command: 'focusElementNoteList' },
{ accelerator: 'Shift+Cmd+N', command: 'focusElementNoteTitle' }, { accelerator: 'Shift+Cmd+N', command: 'focusElementNoteTitle' },
{ accelerator: 'Shift+Cmd+B', command: 'focusElementNoteBody' }, { accelerator: 'Shift+Cmd+B', command: 'focusElementNoteBody' },
{ accelerator: 'Shift+Cmd+O', command: 'focusElementToolbar' },
{ accelerator: 'Option+Cmd+S', command: 'toggleSideBar' }, { accelerator: 'Option+Cmd+S', command: 'toggleSideBar' },
{ accelerator: 'Option+Cmd+L', command: 'toggleNoteList' }, { accelerator: 'Option+Cmd+L', command: 'toggleNoteList' },
{ accelerator: 'Cmd+L', command: 'toggleVisiblePanes' }, { accelerator: 'Cmd+L', command: 'toggleVisiblePanes' },
@@ -86,6 +87,7 @@ const defaultKeymapItems = {
{ accelerator: 'Ctrl+Shift+L', command: 'focusElementNoteList' }, { accelerator: 'Ctrl+Shift+L', command: 'focusElementNoteList' },
{ accelerator: 'Ctrl+Shift+N', command: 'focusElementNoteTitle' }, { accelerator: 'Ctrl+Shift+N', command: 'focusElementNoteTitle' },
{ accelerator: 'Ctrl+Shift+B', command: 'focusElementNoteBody' }, { accelerator: 'Ctrl+Shift+B', command: 'focusElementNoteBody' },
{ accelerator: 'Ctrl+Shift+O', command: 'focusElementToolbar' },
{ accelerator: 'F10', command: 'toggleSideBar' }, { accelerator: 'F10', command: 'toggleSideBar' },
{ accelerator: 'Ctrl+Shift+M', command: 'toggleMenuBar' }, { accelerator: 'Ctrl+Shift+M', command: 'toggleMenuBar' },
{ accelerator: 'F11', command: 'toggleNoteList' }, { accelerator: 'F11', command: 'toggleNoteList' },