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

Enable the command palette feature everywhere in WordPress #54515

Open
wants to merge 11 commits into
base: trunk
Choose a base branch
from
22 changes: 22 additions & 0 deletions lib/experimental/commands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* Experiment to enable Command Palette everywhere in WordPress.
*
* @package gutenberg
*/

/**
* Enqueue the command palette everywhere in WordPress.
*
* @package gutenberg
*/
function gutenberg_enqueue_commands() {
if ( ! is_user_logged_in() ) {
return;
}

wp_enqueue_style( 'wp-commands' );
wp_enqueue_script( 'wp-core-commands' );
}

add_action( 'wp_print_scripts', 'gutenberg_enqueue_commands', 1 );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably move this to lib/wordpress-6.4 (or 6.5) depending on when the PR lands.

1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/compat/wordpress-6.4/script-loader.php';

// Experimental features.
require __DIR__ . '/experimental/commands.php';
require __DIR__ . '/experimental/block-editor-settings-mobile.php';
require __DIR__ . '/experimental/blocks.php';
require __DIR__ . '/experimental/navigation-theme-opt-in.php';
Expand Down
57 changes: 21 additions & 36 deletions packages/commands/src/components/command-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ import {
TextHighlight,
__experimentalHStack as HStack,
} from '@wordpress/components';
import {
store as keyboardShortcutsStore,
useShortcut,
} from '@wordpress/keyboard-shortcuts';
import { Icon, search as inputIcon } from '@wordpress/icons';

/**
Expand Down Expand Up @@ -187,45 +183,34 @@ function CommandInput( { isOpen, search, setSearch } ) {
* @ignore
*/
export function CommandMenu() {
const { registerShortcut } = useDispatch( keyboardShortcutsStore );
const [ search, setSearch ] = useState( '' );
const isOpen = useSelect(
( select ) => select( commandsStore ).isOpen(),
[]
);
const isOpenRef = useRef( false );
const isOpen = useSelect( ( select ) => {
return ( isOpenRef.current = select( commandsStore ).isOpen() );
}, [] );
const { open, close } = useDispatch( commandsStore );
const [ loaders, setLoaders ] = useState( {} );

useEffect( () => {
registerShortcut( {
name: 'core/commands',
category: 'global',
description: __( 'Open the command palette.' ),
keyCombination: {
modifier: 'primary',
character: 'k',
},
} );
}, [ registerShortcut ] );
const handleUserKeyPress = ( e ) => {
if ( e.metaKey && e.key === 'k' ) {
jonathanbardo marked this conversation as resolved.
Show resolved Hide resolved
// Prevent the Save dialog to open
e.preventDefault();

useShortcut(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should still use the useShortcut for several reasons: cross browser, cross platform and the ability to edit the shortcode programmatically.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@youknowriad I pulled the latest trunk changes and now the hooks works as expected. So I reverted the file in 0096521

'core/commands',
/** @type {import('react').KeyboardEventHandler} */
( event ) => {
// Bails to avoid obscuring the effect of the preceding handler(s).
if ( event.defaultPrevented ) return;

event.preventDefault();
if ( isOpen ) {
close();
} else {
open();
if ( isOpenRef.current ) {
close();
} else {
open();
}
}
},
{
bindGlobal: true,
}
);
};

document.addEventListener( 'keydown', handleUserKeyPress );

return () => {
document.removeEventListener( 'keydown', handleUserKeyPress );
};
}, [ close, open ] );
jonathanbardo marked this conversation as resolved.
Show resolved Hide resolved

const setLoader = useCallback(
( name, value ) =>
Expand Down
36 changes: 35 additions & 1 deletion packages/core-commands/src/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,35 @@
export { privateApis } from './private-apis';
/**
* Internal dependencies
*/
import { unlock } from './lock-unlock';
import { privateApis } from './private-apis';
export { privateApis };

/**
* WordPress dependencies
*/
import { createRoot } from '@wordpress/element';
import { CommandMenu } from '@wordpress/commands';
import { privateApis as routerPrivateApis } from '@wordpress/router';

const { useCommands } = unlock( privateApis );
const { RouterProvider } = unlock( routerPrivateApis );

const mountPoint = document.createElement( 'div' );
mountPoint.id = 'wp-commands';

document.body.appendChild( mountPoint );

const root = createRoot( mountPoint );

function CommandMenuWrapper() {
useCommands();

return (
<RouterProvider>
<CommandMenu />
</RouterProvider>
);
}

root.render( <CommandMenuWrapper /> );
5 changes: 1 addition & 4 deletions packages/edit-post/src/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { useMemo } from '@wordpress/element';
import { SlotFillProvider } from '@wordpress/components';
import { store as coreStore } from '@wordpress/core-data';
import { store as preferencesStore } from '@wordpress/preferences';
import { CommandMenu } from '@wordpress/commands';
// eslint-disable-next-line no-unused-vars
import { privateApis as coreCommandsPrivateApis } from '@wordpress/core-commands';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's not used, just remove it no?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@youknowriad yes I tried that but it didn't work. It needs the import to work or the commands do not get loaded at all. Not sure how to explain it still.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in 2873f18


/**
Expand All @@ -26,10 +26,8 @@ import { unlock } from './lock-unlock';
import useCommonCommands from './hooks/commands/use-common-commands';

const { ExperimentalEditorProvider } = unlock( editorPrivateApis );
const { useCommands } = unlock( coreCommandsPrivateApis );

function Editor( { postId, postType, settings, initialEdits, ...props } ) {
useCommands();
useCommonCommands();
const {
hasFixedToolbar,
Expand Down Expand Up @@ -165,7 +163,6 @@ function Editor( { postId, postType, settings, initialEdits, ...props } ) {
{ ...props }
>
<ErrorBoundary>
<CommandMenu />
<EditorInitialization postId={ postId } />
<Layout />
</ErrorBoundary>
Expand Down
9 changes: 2 additions & 7 deletions packages/edit-site/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,14 @@ import { __ } from '@wordpress/i18n';
import { useState, useRef } from '@wordpress/element';
import { NavigableRegion } from '@wordpress/interface';
import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts';
import {
CommandMenu,
privateApis as commandsPrivateApis,
} from '@wordpress/commands';
import { privateApis as commandsPrivateApis } from '@wordpress/commands';
import { store as preferencesStore } from '@wordpress/preferences';
import {
privateApis as blockEditorPrivateApis,
useBlockCommands,
} from '@wordpress/block-editor';
import { privateApis as routerPrivateApis } from '@wordpress/router';
// eslint-disable-next-line no-unused-vars
import { privateApis as coreCommandsPrivateApis } from '@wordpress/core-commands';

/**
Expand All @@ -55,7 +53,6 @@ import { useEditModeCommands } from '../../hooks/commands/use-edit-mode-commands
import PageMain from '../page-main';
import { useIsSiteEditorLoading } from './hooks';

const { useCommands } = unlock( coreCommandsPrivateApis );
const { useCommandContext } = unlock( commandsPrivateApis );
const { useLocation } = unlock( routerPrivateApis );
const { useGlobalStyle } = unlock( blockEditorPrivateApis );
Expand All @@ -66,7 +63,6 @@ export default function Layout() {
// This ensures the edited entity id and type are initialized properly.
useInitEditedEntityFromURL();
useSyncCanvasModeWithURL();
useCommands();
useEditModeCommands();
useCommonCommands();
useBlockCommands();
Expand Down Expand Up @@ -168,7 +164,6 @@ export default function Layout() {

return (
<>
<CommandMenu />
<KeyboardShortcutsRegister />
<KeyboardShortcutsGlobal />
{ fullResizer }
Expand Down
Loading