Skip to content

Commit

Permalink
Desktop: Improve keyboard shortcuts screen accessibility
Browse files Browse the repository at this point in the history
  • Loading branch information
personalizedrefrigerator committed Oct 18, 2024
1 parent 9edcd4e commit bb151cd
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 12 deletions.
25 changes: 15 additions & 10 deletions packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export const KeymapConfigScreen = ({ themeId }: KeymapConfigScreenProps) => {
const [keymapItems, keymapError, overrideKeymapItems, setAccelerator, resetAccelerator] = useKeymap();
const [recorderError, setRecorderError] = useState<Error>(null);
const [editing, enableEditing, disableEditing] = useCommandStatus();
const [hovering, enableHovering, disableHovering] = useCommandStatus();

const handleSave = (event: { commandName: string; accelerator: string }) => {
const { commandName, accelerator } = event;
Expand Down Expand Up @@ -96,11 +95,13 @@ export const KeymapConfigScreen = ({ themeId }: KeymapConfigScreenProps) => {

const renderStatus = (commandName: string) => {
if (editing[commandName]) {
return (recorderError && <i className="fa fa-exclamation-triangle" title={recorderError.message} />);
} else if (hovering[commandName]) {
return (<i className="fa fa-pen" />);
} else {
if (recorderError) {
return <i className="fa fa-exclamation-triangle" role='img' aria-label={recorderError.message} title={recorderError.message} />;
}
return null;
} else {
const editLabel = _('Change shortcut for "%s"', getLabel(commandName));
return <i className="fa fa-pen" role='img' aria-label={editLabel} title={editLabel}/>;
}
};

Expand All @@ -118,10 +119,8 @@ export const KeymapConfigScreen = ({ themeId }: KeymapConfigScreenProps) => {

const renderKeymapRow = ({ command, accelerator }: KeymapItem) => {
const handleClick = () => enableEditing(command);
const handleMouseEnter = () => enableHovering(command);
const handleMouseLeave = () => disableHovering(command);
const cellContent =
<div style={styles.tableCell} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
<div style={styles.tableCell} className='keymap-shortcut-row-content'>
{editing[command] ?
<ShortcutRecorder
onSave={handleSave}
Expand All @@ -139,9 +138,15 @@ export const KeymapConfigScreen = ({ themeId }: KeymapConfigScreenProps) => {
}
</div>
}
<div style={styles.tableCellStatus} onClick={handleClick}>
<button
className={`flat-button edit ${recorderError ? '-error' : ''} ${editing[command] ? '-editing' : ''}`}
style={styles.tableCellStatus}
aria-live={recorderError ? 'polite' : null}
data-tip={recorderError?.message}
onClick={handleClick}
>
{renderStatus(command)}
</div>
</button>
</div>;

return (
Expand Down
18 changes: 16 additions & 2 deletions packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ export const ShortcutRecorder = ({ onSave, onReset, onCancel, onError, initialAc
}, [accelerator]);

const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {
// Shift-tab and tab are needed for navigating the shortcuts screen with the keyboard. Do not
// .preventDefault.
if (event.code === 'Tab' && !event.metaKey && !event.altKey && !event.ctrlKey) {
return;
}

event.preventDefault();
const newAccelerator = keymapService.domToElectronAccelerator(event);

Expand All @@ -60,14 +66,22 @@ export const ShortcutRecorder = ({ onSave, onReset, onCancel, onError, initialAc
}
};

const hintText = _('Press the shortcut and then press ENTER. Or, press BACKSPACE to clear the shortcut.');
const placeholderText = _('Press the shortcut');

return (
<div style={styles.recorderContainer}>
<input
value={accelerator}
placeholder={_('Press the shortcut')}
aria-label={accelerator ? accelerator : placeholderText}
placeholder={placeholderText}
title={hintText}
aria-description={hintText}
aria-invalid={accelerator && !saveAllowed}
aria-live='polite'

onKeyDown={handleKeyDown}
style={styles.recorderInput}
title={_('Press the shortcut and then press ENTER. Or, press BACKSPACE to clear the shortcut.')}
readOnly
autoFocus
/>
Expand Down
1 change: 1 addition & 0 deletions packages/app-desktop/gui/KeymapConfig/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@use "./styles/keymap-shortcut-row-content.scss";
2 changes: 2 additions & 0 deletions packages/app-desktop/gui/KeymapConfig/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ export default function styles(themeId: number) {
tableCellStatus: {
height: '100%',
alignSelf: 'center',
border: 'none',
background: 'transparent',
},
kbd: {
fontFamily: 'sans-serif',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

.keymap-shortcut-row-content {
> .edit {
opacity: 0;

&:focus-visible, &.-editing {
opacity: 1;
}
}

&:hover > .edit {
opacity: 1;
}
}
1 change: 1 addition & 0 deletions packages/app-desktop/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
@use 'gui/TrashNotification/style.scss' as trash-notification;
@use 'gui/Sidebar/style.scss' as sidebar-styles;
@use 'gui/NoteEditor/style.scss' as note-editor-styles;
@use 'gui/KeymapConfig/style.scss' as keymap-styles;
@use 'services/plugins/styles/index.scss' as plugins-styles;
@use 'gui/styles/index.scss' as gui-styles;
@use 'main.scss' as main;

0 comments on commit bb151cd

Please sign in to comment.