Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to toggle keyboard shortcuts on/off #69353

Draft
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions docs/reference-guides/data/data-core-keyboard-shortcuts.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,39 @@ Namespace: `core/keyboard-shortcuts`.

<!-- START TOKEN(Autogenerated selectors|../../../packages/keyboard-shortcuts/src/store/selectors.js) -->

### areShortcutsEnabled

Returns whether keyboard shortcuts are enabled.

_Usage_

```js
import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts';
import { useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';

const ExampleComponent = () => {
const shortcutsEnabled = useSelect(
( select ) => select( keyboardShortcutsStore ).areShortcutsEnabled(),
[]
);

return shortcutsEnabled ? (
<div>{ __( 'Shortcuts enabled.' ) }</div>
) : (
<div>{ __( 'Shortcuts disabled.' ) }</div>
);
};
```

_Parameters_

- _state_ `Object`: Global state.

_Returns_

- `boolean`: Whether shortcuts are enabled.

### getAllShortcutKeyCombinations

Returns the shortcuts that include aliases for a given shortcut name.
Expand Down Expand Up @@ -394,6 +427,18 @@ _Returns_

- `Object`: action.

### toggleShortcutsEnabled

Returns an action object used to toggle keyboard shortcuts on or off.

_Parameters_

- _areShortcutsEnabled_ `boolean`: True to enable shortcuts, false to disable.

_Returns_

- `Object`: action.

### unregisterShortcut

Returns an action object used to unregister a keyboard shortcut.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import clsx from 'clsx';
/**
* WordPress dependencies
*/
import { Modal } from '@wordpress/components';
import { Modal, ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import {
useShortcut,
Expand Down Expand Up @@ -104,6 +104,13 @@ function KeyboardShortcutHelpModal() {
openModal( KEYBOARD_SHORTCUT_HELP_MODAL_NAME );
}
};

const { toggleShortcutsEnabled } = useDispatch( keyboardShortcutsStore );
const shortcutsEnabled = useSelect(
( select ) => select( keyboardShortcutsStore ).areShortcutsEnabled(),
[]
);

useShortcut( 'core/editor/keyboard-shortcuts', toggleModal );

if ( ! isModalActive ) {
Expand All @@ -117,6 +124,22 @@ function KeyboardShortcutHelpModal() {
closeButtonLabel={ __( 'Close' ) }
onRequestClose={ toggleModal }
>
<div className="editor-keyboard-shortcut-help-modal__toggle">
<ToggleControl
__nextHasNoMarginBottom
label={ __( 'Enable keyboard shortcuts' ) }
checked={ shortcutsEnabled }
onChange={ () =>
toggleShortcutsEnabled( ! shortcutsEnabled )
}
help={
shortcutsEnabled
? __( 'Keyboard shortcuts are enabled.' )
: __( 'Keyboard shortcuts are disabled.' )
}
/>
</div>

<ShortcutSection
className="editor-keyboard-shortcut-help-modal__main-shortcuts"
shortcuts={ [ 'core/editor/keyboard-shortcuts' ] }
Expand Down
11 changes: 9 additions & 2 deletions packages/keyboard-shortcuts/src/hooks/use-shortcut.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
* WordPress dependencies
*/
import { useContext, useEffect, useRef } from '@wordpress/element';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import useShortcutEventMatch from './use-shortcut-event-match';
import { context } from '../context';
import { store as keyboardShortcutsStore } from '../store';

/**
* Attach a keyboard shortcut handler.
Expand All @@ -26,12 +28,17 @@ export default function useShortcut(
const isMatch = useShortcutEventMatch();
const callbackRef = useRef();

const areShortcutsEnabled = useSelect(
( select ) => select( keyboardShortcutsStore ).areShortcutsEnabled(),
[]
);

useEffect( () => {
callbackRef.current = callback;
}, [ callback ] );

useEffect( () => {
if ( isDisabled ) {
if ( isDisabled || ! areShortcutsEnabled ) {
return;
}

Expand All @@ -45,5 +52,5 @@ export default function useShortcut(
return () => {
shortcuts.delete( _callback );
};
}, [ name, isDisabled, shortcuts ] );
}, [ name, isDisabled, shortcuts, areShortcutsEnabled ] );
}
14 changes: 14 additions & 0 deletions packages/keyboard-shortcuts/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,17 @@ export function unregisterShortcut( name ) {
name,
};
}

/**
* Returns an action object used to toggle keyboard shortcuts on or off.
*
* @param {boolean} areShortcutsEnabled True to enable shortcuts, false to disable.
*
* @return {Object} action.
*/
export function toggleShortcutsEnabled( areShortcutsEnabled ) {
return {
type: 'TOGGLE_SHORTCUTS_ENABLED',
areShortcutsEnabled,
};
}
29 changes: 27 additions & 2 deletions packages/keyboard-shortcuts/src/store/reducer.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* WordPress dependencies
*/
import { combineReducers } from '@wordpress/data';

/**
* Reducer returning the registered shortcuts
*
Expand All @@ -6,7 +11,7 @@
*
* @return {Object} Updated state.
*/
function reducer( state = {}, action ) {
function registeredShortcuts( state = {}, action ) {
switch ( action.type ) {
case 'REGISTER_SHORTCUT':
return {
Expand All @@ -26,4 +31,24 @@ function reducer( state = {}, action ) {
return state;
}

export default reducer;
/**
* Reducer returning whether shortcuts are enabled.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {boolean} Updated state.
*/
function shortcutsEnabled( state = true, action ) {
switch ( action.type ) {
case 'TOGGLE_SHORTCUTS_ENABLED':
return action.areShortcutsEnabled;
}

return state;
}

export default combineReducers( {
registeredShortcuts,
shortcutsEnabled,
} );
53 changes: 45 additions & 8 deletions packages/keyboard-shortcuts/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ function getKeyCombinationRepresentation( shortcut, representation ) {
* @return {WPShortcutKeyCombination?} Key combination.
*/
export function getShortcutKeyCombination( state, name ) {
return state[ name ] ? state[ name ].keyCombination : null;
return state.registeredShortcuts[ name ]
? state.registeredShortcuts[ name ].keyCombination
: null;
}

/**
Expand Down Expand Up @@ -175,7 +177,9 @@ export function getShortcutRepresentation(
* @return {?string} Shortcut description.
*/
export function getShortcutDescription( state, name ) {
return state[ name ] ? state[ name ].description : null;
return state.registeredShortcuts[ name ]
? state.registeredShortcuts[ name ].description
: null;
}

/**
Expand Down Expand Up @@ -225,8 +229,9 @@ export function getShortcutDescription( state, name ) {
* @return {WPShortcutKeyCombination[]} Key combinations.
*/
export function getShortcutAliases( state, name ) {
return state[ name ] && state[ name ].aliases
? state[ name ].aliases
return state.registeredShortcuts[ name ] &&
state.registeredShortcuts[ name ].aliases
? state.registeredShortcuts[ name ].aliases
: EMPTY_ARRAY;
}

Expand Down Expand Up @@ -286,7 +291,7 @@ export const getAllShortcutKeyCombinations = createSelector(
...getShortcutAliases( state, name ),
].filter( Boolean );
},
( state, name ) => [ state[ name ] ]
( state, name ) => [ state.registeredShortcuts[ name ] ]
);

/**
Expand Down Expand Up @@ -345,7 +350,7 @@ export const getAllShortcutRawKeyCombinations = createSelector(
getKeyCombinationRepresentation( combination, 'raw' )
);
},
( state, name ) => [ state[ name ] ]
( state, name ) => [ state.registeredShortcuts[ name ] ]
);

/**
Expand Down Expand Up @@ -383,9 +388,41 @@ export const getAllShortcutRawKeyCombinations = createSelector(
*/
export const getCategoryShortcuts = createSelector(
( state, categoryName ) => {
return Object.entries( state )
return Object.entries( state.registeredShortcuts )
.filter( ( [ , shortcut ] ) => shortcut.category === categoryName )
.map( ( [ name ] ) => name );
},
( state ) => [ state ]
( state ) => [ state.registeredShortcuts ]
);

/**
* Returns whether keyboard shortcuts are enabled.
*
* @param {Object} state Global state.
*
* @example
*
*```js
* import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts';
* import { useSelect } from '@wordpress/data';
* import { __ } from '@wordpress/i18n';
*
* const ExampleComponent = () => {
* const shortcutsEnabled = useSelect(
* ( select ) =>
* select( keyboardShortcutsStore ).areShortcutsEnabled(),
* []
* );
*
* return shortcutsEnabled ? (
* <div>{ __( 'Shortcuts enabled.' ) }</div>
* ) : (
* <div>{ __( 'Shortcuts disabled.' ) }</div>
* );
* };
*```
* @return {boolean} Whether shortcuts are enabled.
*/
export function areShortcutsEnabled( state ) {
return state.shortcutsEnabled;
}
Loading