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

Editor: Add extensibility to PreviewOptions v2 #64644

Merged
merged 7 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
34 changes: 34 additions & 0 deletions packages/editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => (
<PreviewDropdownMenuItem icon={ external } onClick={ onPreviewClick }>
{ __( 'Preview in new tab' ) }
</PreviewDropdownMenuItem>
);
```

_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:
Expand Down
1 change: 1 addition & 0 deletions packages/editor/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
lezama marked this conversation as resolved.
Show resolved Hide resolved
* import { external } from '@wordpress/icons';
*
* function onPreviewClick() {
* // Handle preview action
* }
*
* const ExternalPreviewMenuItem = () => (
* <PreviewDropdownMenuItem
* icon={ external }
* onClick={ onPreviewClick }
* >
* { __( 'Preview in new tab' ) }
* </PreviewDropdownMenuItem>
* );
* ```
lezama marked this conversation as resolved.
Show resolved Hide resolved
*
* @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 );
Copy link
Member

Choose a reason for hiding this comment

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

We can probably drop the withPluginContext. It's only here for icon context, and as @simison noted, there's no need for inheriting icons just yet.

Copy link
Member

Choose a reason for hiding this comment

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

The note mentioned above for clarity:

Hesitant allowing custom icons yet, but not a strong opinion. Mostly thinking that later we want to allow multi-selections with check mark, and it's hard to tell how the icon API then should look like in that scenario.

It's all supported out of the box for the PluginMoreMenuItem:

Screenshot 2024-08-28 at 09 04 51

Whenever, the sidebar is selected, it's reflected in the menu with the checkmark icon ✔️. Let's not limit the options that are supported out of the box like the icon that get inherited for all fills. That's the part that makes the More Menu item behave as a checkbox:

<ComplementaryAreaMoreMenuItem
// Menu item is marked with unstable prop for backward compatibility.
// @see https://github.com/WordPress/gutenberg/issues/14457
__unstableExplicitMenuItem
scope="core"
{ ...props }
/>
);

role="menuitemcheckbox"
selectedIcon={ check }

Copy link
Member

Choose a reason for hiding this comment

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

Then, if we want to keep the icon from the plugin context, let's use the usePluginContext hook instead of compose and withPluginContext.

Copy link
Member

Choose a reason for hiding this comment

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

If usePluginContext exist, then it would be so much more up to recent React standards 😄

6 changes: 6 additions & 0 deletions packages/editor/src/components/preview-dropdown/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -206,6 +207,11 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
/>
</MenuGroup>
) }
<ActionItem.Slot
name="core/plugin-preview-dropdown-menu"
as={ MenuGroup }
fillProps={ { onClick: onClose } }
/>
</>
) }
</DropdownMenu>
Expand Down
Loading