From 3b94038265d907c4fe671dc8d87680451eeae160 Mon Sep 17 00:00:00 2001 From: Miguel Lezama Date: Tue, 20 Aug 2024 10:08:24 -0300 Subject: [PATCH 1/7] add plugin-preview-dropdown-item --- .../plugin-preview-dropdown-item/index.js | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 packages/editor/src/components/plugin-preview-dropdown-item/index.js diff --git a/packages/editor/src/components/plugin-preview-dropdown-item/index.js b/packages/editor/src/components/plugin-preview-dropdown-item/index.js new file mode 100644 index 00000000000000..9b05a40b5c51b9 --- /dev/null +++ b/packages/editor/src/components/plugin-preview-dropdown-item/index.js @@ -0,0 +1,49 @@ +/** + * WordPress dependencies + */ +import { compose } from '@wordpress/compose'; +import { MenuItem } from '@wordpress/components'; +import { withPluginContext } from '@wordpress/plugins'; +import { ActionItem } from '@wordpress/interface'; + +/** + * Renders a menu item in the Preview dropdown, which can be used as a button or link depending on the props provided. + * The text within the component appears as the menu item label. + * + * @param {Object} props Component properties. + * @param {string} [props.href] When `href` is provided, the menu item is rendered as an anchor instead of a button. It corresponds to the `href` attribute of the anchor. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The icon to be rendered to the left of the menu item label. Can be a Dashicon slug or an SVG WP element. + * @param {Function} [props.onClick] The callback function to be executed when the user clicks the menu item. + * @param {...*} [props.other] Any additional props are passed through to the underlying MenuItem component. + * + * @example + * ```jsx + * import { __ } from '@wordpress/i18n'; + * import { PreviewDropdownMenuItem } from './preview-dropdown-menu-item'; + * import { external } from '@wordpress/icons'; + * + * function onPreviewClick() { + * // Handle preview action + * } + * + * const ExternalPreviewMenuItem = () => ( + * + * { __( 'Preview in new tab' ) } + * + * ); + * ``` + * + * @return {Component} The rendered menu item component. + */ +export default compose( + withPluginContext( ( context, ownProps ) => { + return { + as: ownProps.as ?? MenuItem, + icon: ownProps.icon || context.icon, + name: 'core/plugin-preview-dropdown-menu', + }; + } ) +)( ActionItem ); From f30edafd82a10230eff8cf685629f2c5ffbe13ad Mon Sep 17 00:00:00 2001 From: Miguel Lezama Date: Tue, 20 Aug 2024 10:12:14 -0300 Subject: [PATCH 2/7] Add slot --- packages/editor/src/components/preview-dropdown/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/editor/src/components/preview-dropdown/index.js b/packages/editor/src/components/preview-dropdown/index.js index 6554f7c0228a77..6cb87b674cf6b9 100644 --- a/packages/editor/src/components/preview-dropdown/index.js +++ b/packages/editor/src/components/preview-dropdown/index.js @@ -22,6 +22,7 @@ import { store as coreStore } from '@wordpress/core-data'; import { useEffect, useRef } from '@wordpress/element'; import { store as preferencesStore } from '@wordpress/preferences'; import { store as blockEditorStore } from '@wordpress/block-editor'; +import { ActionItem } from '@wordpress/interface'; /** * Internal dependencies @@ -206,6 +207,11 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) { /> ) } + ) } From 290072b3857fe4f5ac6446b92c6046059a8a11ce Mon Sep 17 00:00:00 2001 From: Miguel Lezama Date: Tue, 20 Aug 2024 10:17:05 -0300 Subject: [PATCH 3/7] export PluginPreviewDropdownItem --- packages/editor/README.md | 34 +++++++++++++++++++++++++ packages/editor/src/components/index.js | 1 + 2 files changed, 35 insertions(+) diff --git a/packages/editor/README.md b/packages/editor/README.md index 89ea15ef378495..97537c261b9e6b 100644 --- a/packages/editor/README.md +++ b/packages/editor/README.md @@ -862,6 +862,40 @@ _Returns_ - `Component`: The component to be rendered. +### PluginPreviewDropdownItem + +Renders a menu item in the Preview dropdown, which can be used as a button or link depending on the props provided. The text within the component appears as the menu item label. + +_Usage_ + +```jsx +import { __ } from '@wordpress/i18n'; +import { PreviewDropdownMenuItem } from './preview-dropdown-menu-item'; +import { external } from '@wordpress/icons'; + +function onPreviewClick() { + // Handle preview action +} + +const ExternalPreviewMenuItem = () => ( + + { __( 'Preview in new tab' ) } + +); +``` + +_Parameters_ + +- _props_ `Object`: Component properties. +- _props.href_ `[string]`: When `href` is provided, the menu item is rendered as an anchor instead of a button. It corresponds to the `href` attribute of the anchor. +- _props.icon_ `[WPBlockTypeIconRender]`: The icon to be rendered to the left of the menu item label. Can be a Dashicon slug or an SVG WP element. +- _props.onClick_ `[Function]`: The callback function to be executed when the user clicks the menu item. +- _props.other_ `[...*]`: Any additional props are passed through to the underlying MenuItem component. + +_Returns_ + +- `Component`: The rendered menu item component. + ### PluginSidebar Renders a sidebar when activated. The contents within the `PluginSidebar` will appear as content within the sidebar. It also automatically renders a corresponding `PluginSidebarMenuItem` component when `isPinnable` flag is set to `true`. If you wish to display the sidebar, you can with use the `PluginSidebarMoreMenuItem` component or the `wp.data.dispatch` API: diff --git a/packages/editor/src/components/index.js b/packages/editor/src/components/index.js index 91dcc883d661b2..71dd41bb3ef7ac 100644 --- a/packages/editor/src/components/index.js +++ b/packages/editor/src/components/index.js @@ -32,6 +32,7 @@ export { default as PluginMoreMenuItem } from './plugin-more-menu-item'; export { default as PluginPostPublishPanel } from './plugin-post-publish-panel'; export { default as PluginPostStatusInfo } from './plugin-post-status-info'; export { default as PluginPrePublishPanel } from './plugin-pre-publish-panel'; +export { default as PluginPreviewDropdownItem } from './plugin-preview-dropdown-item'; export { default as PluginSidebar } from './plugin-sidebar'; export { default as PluginSidebarMoreMenuItem } from './plugin-sidebar-more-menu-item'; export { default as PostTemplatePanel } from './post-template/panel'; From 095e3aa42d6857cac3684ed81ae2b7794387bed3 Mon Sep 17 00:00:00 2001 From: Miguel Lezama Date: Wed, 28 Aug 2024 10:23:32 -0300 Subject: [PATCH 4/7] add registerPlugin example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Greg Ziółkowski --- .../src/components/plugin-preview-dropdown-item/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/editor/src/components/plugin-preview-dropdown-item/index.js b/packages/editor/src/components/plugin-preview-dropdown-item/index.js index 9b05a40b5c51b9..43b4177c69e445 100644 --- a/packages/editor/src/components/plugin-preview-dropdown-item/index.js +++ b/packages/editor/src/components/plugin-preview-dropdown-item/index.js @@ -34,6 +34,9 @@ import { ActionItem } from '@wordpress/interface'; * { __( 'Preview in new tab' ) } * * ); + * registerPlugin( 'external-preview-menu-item', { + * render: ExternalPreviewMenuItem, + * } ); * ``` * * @return {Component} The rendered menu item component. From 6b926ab18e7ad6ac1d5d93c69fbaa383a0c31790 Mon Sep 17 00:00:00 2001 From: Miguel Lezama Date: Fri, 30 Aug 2024 10:12:21 -0300 Subject: [PATCH 5/7] example import from @wordpress/editor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Greg Ziółkowski --- .../editor/src/components/plugin-preview-dropdown-item/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor/src/components/plugin-preview-dropdown-item/index.js b/packages/editor/src/components/plugin-preview-dropdown-item/index.js index 43b4177c69e445..f38e1dd1da5cb0 100644 --- a/packages/editor/src/components/plugin-preview-dropdown-item/index.js +++ b/packages/editor/src/components/plugin-preview-dropdown-item/index.js @@ -19,7 +19,7 @@ import { ActionItem } from '@wordpress/interface'; * @example * ```jsx * import { __ } from '@wordpress/i18n'; - * import { PreviewDropdownMenuItem } from './preview-dropdown-menu-item'; + * import { PluginPreviewMenuItem } from '@wordpress/editor'; * import { external } from '@wordpress/icons'; * * function onPreviewClick() { From 1a975c8997c5a57b20f26a58900e3eee5cf917df Mon Sep 17 00:00:00 2001 From: Miguel Lezama Date: Fri, 30 Aug 2024 11:09:19 -0300 Subject: [PATCH 6/7] rename to PluginPreviewMenuItem --- packages/editor/README.md | 7 +++++-- packages/editor/src/components/index.js | 2 +- .../index.js | 2 +- packages/editor/src/components/preview-dropdown/index.js | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) rename packages/editor/src/components/{plugin-preview-dropdown-item => plugin-preview-menu-item}/index.js (97%) diff --git a/packages/editor/README.md b/packages/editor/README.md index 97537c261b9e6b..ebd4af31e287d8 100644 --- a/packages/editor/README.md +++ b/packages/editor/README.md @@ -862,7 +862,7 @@ _Returns_ - `Component`: The component to be rendered. -### PluginPreviewDropdownItem +### PluginPreviewMenuItem Renders a menu item in the Preview dropdown, which can be used as a button or link depending on the props provided. The text within the component appears as the menu item label. @@ -870,7 +870,7 @@ _Usage_ ```jsx import { __ } from '@wordpress/i18n'; -import { PreviewDropdownMenuItem } from './preview-dropdown-menu-item'; +import { PluginPreviewMenuItem } from '@wordpress/editor'; import { external } from '@wordpress/icons'; function onPreviewClick() { @@ -882,6 +882,9 @@ const ExternalPreviewMenuItem = () => ( { __( 'Preview in new tab' ) } ); +registerPlugin( 'external-preview-menu-item', { + render: ExternalPreviewMenuItem, +} ); ``` _Parameters_ diff --git a/packages/editor/src/components/index.js b/packages/editor/src/components/index.js index 71dd41bb3ef7ac..b42566aac653be 100644 --- a/packages/editor/src/components/index.js +++ b/packages/editor/src/components/index.js @@ -32,7 +32,7 @@ export { default as PluginMoreMenuItem } from './plugin-more-menu-item'; export { default as PluginPostPublishPanel } from './plugin-post-publish-panel'; export { default as PluginPostStatusInfo } from './plugin-post-status-info'; export { default as PluginPrePublishPanel } from './plugin-pre-publish-panel'; -export { default as PluginPreviewDropdownItem } from './plugin-preview-dropdown-item'; +export { default as PluginPreviewMenuItem } from './plugin-preview-menu-item'; export { default as PluginSidebar } from './plugin-sidebar'; export { default as PluginSidebarMoreMenuItem } from './plugin-sidebar-more-menu-item'; export { default as PostTemplatePanel } from './post-template/panel'; diff --git a/packages/editor/src/components/plugin-preview-dropdown-item/index.js b/packages/editor/src/components/plugin-preview-menu-item/index.js similarity index 97% rename from packages/editor/src/components/plugin-preview-dropdown-item/index.js rename to packages/editor/src/components/plugin-preview-menu-item/index.js index f38e1dd1da5cb0..422248e17b88e1 100644 --- a/packages/editor/src/components/plugin-preview-dropdown-item/index.js +++ b/packages/editor/src/components/plugin-preview-menu-item/index.js @@ -46,7 +46,7 @@ export default compose( return { as: ownProps.as ?? MenuItem, icon: ownProps.icon || context.icon, - name: 'core/plugin-preview-dropdown-menu', + name: 'core/plugin-preview-menu', }; } ) )( ActionItem ); diff --git a/packages/editor/src/components/preview-dropdown/index.js b/packages/editor/src/components/preview-dropdown/index.js index 6cb87b674cf6b9..cecf579029a229 100644 --- a/packages/editor/src/components/preview-dropdown/index.js +++ b/packages/editor/src/components/preview-dropdown/index.js @@ -208,7 +208,7 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) { ) } From bf99ae09acfa06f8dde861f4b345e572d02523f0 Mon Sep 17 00:00:00 2001 From: Miguel Lezama Date: Fri, 30 Aug 2024 12:04:25 -0300 Subject: [PATCH 7/7] add tests tests --- packages/e2e-tests/plugins/plugins-api.php | 13 ++++++++++++ .../plugins/plugins-api/preview-menu.js | 14 +++++++++++++ .../specs/editor/plugins/plugins-api.spec.js | 21 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 packages/e2e-tests/plugins/plugins-api/preview-menu.js diff --git a/packages/e2e-tests/plugins/plugins-api.php b/packages/e2e-tests/plugins/plugins-api.php index fb8054924cebb0..10e35f16226f2a 100644 --- a/packages/e2e-tests/plugins/plugins-api.php +++ b/packages/e2e-tests/plugins/plugins-api.php @@ -86,6 +86,19 @@ function enqueue_plugins_api_plugin_scripts() { filemtime( plugin_dir_path( __FILE__ ) . 'plugins-api/document-setting.js' ), true ); + + wp_enqueue_script( + 'gutenberg-test-plugins-api-preview-menu', + plugins_url( 'plugins-api/preview-menu.js', __FILE__ ), + array( + 'wp-editor', + 'wp-element', + 'wp-i18n', + 'wp-plugins', + ), + filemtime( plugin_dir_path( __FILE__ ) . 'plugins-api/preview-menu.js' ), + true + ); } add_action( 'init', 'enqueue_plugins_api_plugin_scripts' ); diff --git a/packages/e2e-tests/plugins/plugins-api/preview-menu.js b/packages/e2e-tests/plugins/plugins-api/preview-menu.js new file mode 100644 index 00000000000000..1aa53b2e8509ac --- /dev/null +++ b/packages/e2e-tests/plugins/plugins-api/preview-menu.js @@ -0,0 +1,14 @@ +( function () { + const { __ } = wp.i18n; + const { registerPlugin } = wp.plugins; + const PluginPreviewMenuItem = wp.editor.PluginPreviewMenuItem; + const el = wp.element.createElement; + + function CustomPreviewMenuItem() { + return el( PluginPreviewMenuItem, {}, __( 'Custom Preview' ) ); + } + + registerPlugin( 'custom-preview-menu-item', { + render: CustomPreviewMenuItem, + } ); +} )(); diff --git a/test/e2e/specs/editor/plugins/plugins-api.spec.js b/test/e2e/specs/editor/plugins/plugins-api.spec.js index c71b49e3c4d815..c7f3a655e14240 100644 --- a/test/e2e/specs/editor/plugins/plugins-api.spec.js +++ b/test/e2e/specs/editor/plugins/plugins-api.spec.js @@ -230,4 +230,25 @@ test.describe( 'Plugins API', () => { ).toBeVisible(); } ); } ); + + test.describe( 'Preview Menu Item', () => { + test( 'Should render and interact with PluginPreviewMenuItem', async ( { + page, + } ) => { + await page + .getByRole( 'region', { name: 'Editor top bar' } ) + .locator( '.editor-preview-dropdown__toggle' ) + .click(); + + const customPreviewItem = page.getByRole( 'menuitem', { + name: 'Custom Preview', + } ); + + await expect( customPreviewItem ).toBeVisible(); + + await customPreviewItem.click(); + + await expect( customPreviewItem ).toBeHidden(); + } ); + } ); } );