Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Experimental: Enable Command Palette in admin dashboard
  • Loading branch information
t-hamano committed Aug 4, 2025
commit b2ecac71b901d326c0cd0d4e56d635aca7f5e38a
44 changes: 44 additions & 0 deletions lib/experimental/commands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
/**
* Bootstraps the Command Palette in the admin dashboard.
*
* @package Gutenberg
*/

/**
* Enqueues the assets required for the Command Palette.
*
* @global string $pagenow The name of the current admin page being viewed.
*/
function gutenberg_enqueue_command_palette_assets() {
// For now, we don't enqueue assets to the frontend. It may be available in the future.
if ( ! is_admin() ) {
return;
}

global $pagenow, $current_screen;

// The Site Editor and Post Editor already implement the Command Palette
// within the app, so do nothing on those pages.
if ( in_array( $pagenow, array( 'site-editor.php', 'post.php', 'post-new.php' ), true ) && $current_screen->is_block_editor() ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we remove it from the editors and avoid this check?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think it can be removed at the moment. See #71030 (comment) for the reason.

We can remove it if we don't use experimental settings, but personally I'd like to iterate a bit more before stabilizing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think we can follow-up with this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My explanation wasn't clear enough.

If we remove this check, we'll need to remove the command in the edit-post and edit-site to prevent duplicate registration of the command.

However, removing the command from these two packages will mean that the command won't work when the two packages are bundled into core.

However, if we can decide to ship this PR into WP 6.9, we can remove this check along with the core backport PR.

I hope I explained it well 😅

Copy link
Contributor

@youknowriad youknowriad Aug 19, 2025

Choose a reason for hiding this comment

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

However, removing the command from these two packages will mean that the command won't work when the two packages are bundled into core.

I don't understand this part, I expect the backport of the new global command and the edit-post edit-site changes to happen at the same time. (6.9)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I expect the backport of the new global command and the edit-post edit-site changes to happen at the same time. (6.9)

That's right. However, since we need to do the PHP backport and package updates at the same time, we need to do that right before WP 6.9 Beta 1, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

Nothing is stopping us from doing multiple package updates no?

Copy link
Contributor

Choose a reason for hiding this comment

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

This kind of issue of having to do php changes and package update at the same time is not new and not specific to this case. I'm not sure it's something we should be thinking about when shipping things to the Gutenberg repo. For me it's a workflow issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see, I think I might be misunderstanding 😅 I'd like to submit a follow-up PR to remove this check soon.

return;
}
Comment on lines +23 to +25
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This early return is necessary to avoid conflicts with the Command Palette UI in the post editor and site editor. For example:

However, if we can stabilize the "Command Palette everywhere" in the future, we may be able to remove the dependency on the core-commands package from the post editor and site editor packages and consolidate the core Command Palette functionality into initializeCommandPalette().


$gutenberg_experiments = get_option( 'gutenberg-experiments' );
if ( empty( $gutenberg_experiments ) || ! array_key_exists( 'gutenberg-command-palette-everywhere', $gutenberg_experiments ) ) {
return;
}

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

$inline_script = <<<JS
window.__experimentalEnableCommandPaletteEverywhere = true;
wp.coreCommands.initializeCommandPalette();
JS;

wp_add_inline_script( 'wp-core-commands', $inline_script );
}

add_action( 'admin_enqueue_scripts', 'gutenberg_enqueue_command_palette_assets' );
12 changes: 12 additions & 0 deletions lib/experiments-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ function gutenberg_initialize_experiments_settings() {
)
);

add_settings_field(
'gutenberg-command-palette-everywhere',
__( 'Command Palette: enable everywhere', 'gutenberg' ),
'gutenberg_display_experiment_field',
'gutenberg-experiments',
'gutenberg_experiments_section',
array(
'label' => __( 'Enables the Command Palette everywhere in the admin dashboard.', 'gutenberg' ),
'id' => 'gutenberg-command-palette-everywhere',
)
);

add_settings_field(
'gutenberg-media-processing',
__( 'Client-side media processing', 'gutenberg' ),
Expand Down
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/experimental/synchronization.php';
require __DIR__ . '/experimental/script-modules.php';
require __DIR__ . '/experimental/posts/load.php';
require __DIR__ . '/experimental/commands.php';

if ( gutenberg_is_experiment_enabled( 'gutenberg-no-tinymce' ) ) {
require __DIR__ . '/experimental/disable-tinymce.php';
Expand Down
4 changes: 4 additions & 0 deletions packages/core-commands/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ _This package assumes that your code will run in an **ES2015+** environment. If

<!-- START TOKEN(Autogenerated API docs) -->

### initializeCommandPalette

Initializes the Command Palette. This function does nothing unless the experimental setting is enabled.

### privateApis

Undocumented declaration.
Expand Down
43 changes: 43 additions & 0 deletions packages/core-commands/src/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,44 @@
/**
* WordPress dependencies
*/
import { createRoot, StrictMode } from '@wordpress/element';
import { privateApis as routerPrivateApis } from '@wordpress/router';
import { CommandMenu } from '@wordpress/commands';

/**
* Internal dependencies
*/
import { useAdminNavigationCommands } from './admin-navigation-commands';
import { useSiteEditorNavigationCommands } from './site-editor-navigation-commands';
import { unlock } from './lock-unlock';
export { privateApis } from './private-apis';

const { RouterProvider } = unlock( routerPrivateApis );

// Register core commands and render the Command Palette.
function CommandPalette() {
useAdminNavigationCommands();
useSiteEditorNavigationCommands();
return (
<RouterProvider pathArg="p">
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Some core commands use the useHistory hook. This routerProvider is required for these commands to work correctly.

<CommandMenu />
</RouterProvider>
);
}

/**
* Initializes the Command Palette. This function does nothing
* unless the experimental setting is enabled.
*/
export function initializeCommandPalette() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm hesitant about whether this should leave in this package or if we should have a edit-command package or something like that. I'm not sure yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree. If the direction of the Command Palette becomes clearer, we may be able to change to a more appropriate approach.

if ( ! window.__experimentalEnableCommandPaletteEverywhere ) {
return;
}
const root = document.createElement( 'div' );
document.body.appendChild( root );
createRoot( root ).render(
<StrictMode>
<CommandPalette />
</StrictMode>
);
}
2 changes: 1 addition & 1 deletion packages/router/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ export function RouterProvider( {
);
const matcher = useMemo( () => {
const ret = new RouteRecognizer();
routes.forEach( ( route ) => {
( routes ?? [] ).forEach( ( route ) => {
ret.add( [ { path: route.path, handler: route } ], {
as: route.name,
} );
Expand Down
Loading