diff --git a/docs/designers-developers/developers/slotfills/README.md b/docs/designers-developers/developers/slotfills/README.md index 3ab5536f55f82..d04e17931a78c 100644 --- a/docs/designers-developers/developers/slotfills/README.md +++ b/docs/designers-developers/developers/slotfills/README.md @@ -49,9 +49,7 @@ export const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' ); const PluginPostStatusInfo = ( { children, className } ) => ( - - { children } - + { children } ); @@ -97,12 +95,17 @@ const PostStatus = ( { isOpened, onTogglePanel } ) => ( There are currently eight available SlotFills in the `edit-post` package. Please refer to the individual items below for usage and example details: -* [MainDashboardButton](/docs/designers-developers/developers/slotfills/main-dashboard-button.md) -* [PluginBlockSettingsMenuItem](/docs/designers-developers/developers/slotfills/plugin-block-settings-menu-item.md) -* [PluginDocumentSettingPanel](/docs/designers-developers/developers/slotfills/plugin-document-setting-panel.md) -* [PluginMoreMenuItem](/docs/designers-developers/developers/slotfills/plugin-more-menu-item.md) -* [PluginPostPublishPanel](/docs/designers-developers/developers/slotfills/plugin-post-publish-panel.md) -* [PluginPostStatusInfo](/docs/designers-developers/developers/slotfills/plugin-post-status-info.md) -* [PluginPrePublishPanel](/docs/designers-developers/developers/slotfills/plugin-pre-publish-panel.md) -* [PluginSidebar](/docs/designers-developers/developers/slotfills/plugin-sidebar.md) -* [PluginSidebarMoreMenuItem](/docs/designers-developers/developers/slotfills/plugin-sidebar-more-menu-item.md) +- [MainDashboardButton](/docs/designers-developers/developers/slotfills/main-dashboard-button.md) +- [PluginBlockSettingsMenuItem](/docs/designers-developers/developers/slotfills/plugin-block-settings-menu-item.md) +- [PluginDocumentSettingPanel](/docs/designers-developers/developers/slotfills/plugin-document-setting-panel.md) +- [PluginMoreMenuItem](/docs/designers-developers/developers/slotfills/plugin-more-menu-item.md) +- [PluginPostPublishPanel](/docs/designers-developers/developers/slotfills/plugin-post-publish-panel.md) +- [PluginPostStatusInfo](/docs/designers-developers/developers/slotfills/plugin-post-status-info.md) +- [PluginPrePublishPanel](/docs/designers-developers/developers/slotfills/plugin-pre-publish-panel.md) +- [PluginSidebar](/docs/designers-developers/developers/slotfills/plugin-sidebar.md) +- [PluginSidebarMoreMenuItem](/docs/designers-developers/developers/slotfills/plugin-sidebar-more-menu-item.md) + +There are currently two available SlotFills in the `block-editor` package: + +- [PluginPreview](/docs/designers-developers/developers/slotfills/plugin-preview.md) +- [PluginPreviewMenuItem](/docs/designers-developers/developers/slotfills/plugin-preview-menu-item.md) diff --git a/docs/designers-developers/developers/slotfills/plugin-preview-menu-item.md b/docs/designers-developers/developers/slotfills/plugin-preview-menu-item.md new file mode 100644 index 0000000000000..8ff1e899114a8 --- /dev/null +++ b/docs/designers-developers/developers/slotfills/plugin-preview-menu-item.md @@ -0,0 +1,37 @@ +# PluginPreviewMenuItem + +This is designed to be used alongside the PluginPreview. + +- PluginPreviewMenuItem: Adds a menu item to the "Preview" menu. +- PluginPreview: Renders the main content area when that menu item is chosen. + +Each of these takes 2 props, `previewId`, and `children`. + +- `previewId` - A string that serves as an internal identifier for your + preview. Must match across PluginPreviewMenuItem and PluginPreview. +- `children` - What gets rendered in that spot. + +## Example + +```js +import { registerPlugin } from '@wordpress/plugins'; +import { PluginPreview, PluginPreviewMenuItem } from '@wordpress/block-editor'; +import { Fragment } from '@wordpress/element'; + +const PluginPreviewTest = () => ( + + + Custom Preview 1 Menu Text + + +
+

Custom Preview 1 Content

+
+
+
+); + +registerPlugin( 'plugin-preview-test', { + render: PluginPreviewTest, +} ); +``` diff --git a/docs/designers-developers/developers/slotfills/plugin-preview.md b/docs/designers-developers/developers/slotfills/plugin-preview.md new file mode 100644 index 0000000000000..021df443584c1 --- /dev/null +++ b/docs/designers-developers/developers/slotfills/plugin-preview.md @@ -0,0 +1,37 @@ +# PluginPreview + +This is designed to be used alongside the PluginPreviewMenuItem. + +- PluginPreviewMenuItem: Adds a menu item to the "Preview" menu. +- PluginPreview: Renders the main content area when that menu item is chosen. + +Each of these takes 2 props, `previewId`, and `children`. + +- `previewId` - A string that serves as an internal identifier for your + preview. Must match across PluginPreviewMenuItem and PluginPreview. +- `children` - What gets rendered in that spot. + +## Example + +```js +import { registerPlugin } from '@wordpress/plugins'; +import { PluginPreview, PluginPreviewMenuItem } from '@wordpress/block-editor'; +import { Fragment } from '@wordpress/element'; + +const PluginPreviewTest = () => ( + + + Custom Preview 1 Menu Text + + +
+

Custom Preview 1 Content

+
+
+
+); + +registerPlugin( 'plugin-preview-test', { + render: PluginPreviewTest, +} ); +``` diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 705eb7c414889..377cc9e9c7027 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -238,6 +238,10 @@ Undocumented declaration. Undocumented declaration. +# **coreDeviceTypes** + +Undocumented declaration. + # **createCustomColorsHOC** A higher-order component factory for creating a 'withCustomColors' HOC, which handles color logic @@ -451,6 +455,30 @@ _Related_ - +# **PluginPreview** + +Component used by a plugin to define the contents of a "custom +preview". The children of this component will be displayed in the main editor +screen when this "custom preview" is chosen from the preview menu. + +_Parameters_ + +- _props_ `Object`: Component properties. +- _props.previewId_ `string`: The internal name of this custom preview. Must match the _previewId_ given to `PluginPreviewMenuItem`. +- _props.children_ `WPElement`: Children to be rendered. + +# **PluginPreviewMenuItem** + +Component used by a plugin to define the contents of a menu item that +selects a "custom preview". The children of this component will be displayed +inside the preview menu. Typically a single string is good enough. + +_Parameters_ + +- _props_ `Object`: Component properties. +- _props.previewId_ `string`: The internal name of this custom preview. Must match the _previewId_ given to `PluginPreview`. +- _props.children_ `WPElement`: Children to be rendered. + # **PreserveScrollInReorder** Undocumented declaration. diff --git a/packages/block-editor/src/components/preview-options/index.js b/packages/block-editor/src/components/preview-options/index.js index 122c85d852d0d..ab60cdcb6fb45 100644 --- a/packages/block-editor/src/components/preview-options/index.js +++ b/packages/block-editor/src/components/preview-options/index.js @@ -7,10 +7,24 @@ import classnames from 'classnames'; * WordPress dependencies */ import { useViewportMatch } from '@wordpress/compose'; -import { DropdownMenu, MenuGroup, MenuItem } from '@wordpress/components'; +import { DropdownMenu, MenuGroup, MenuItem, Slot } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { check } from '@wordpress/icons'; +/* + * coreDeviceTypes: An array of strings. The strings returned represent + * deviceType values that belong to the core system. When the deviceType, + * returned by `__experimentalGetPreviewDeviceType()`, is one of these values, + * the built in VisualEditor is responsible for rendering a preview of that + * type. + + * When the deviceType is something other than one of the coreDeviceTypes, we are + * rendering a custom deviceType registered by the and + * components, and defer to a filled by the plugin to + * draw the preview. + */ +export const coreDeviceTypes = [ 'Desktop', 'Tablet', 'Mobile' ]; + export default function PreviewOptions( { children, className, @@ -67,6 +81,15 @@ export default function PreviewOptions( { { __( 'Mobile' ) } + + + { ( fills ) => + ! fills || fills.length === 0 ? null : ( + { fills } + ) + } + + { children } ) } diff --git a/packages/block-editor/src/components/preview-options/plugin-preview-menu-item/index.js b/packages/block-editor/src/components/preview-options/plugin-preview-menu-item/index.js new file mode 100644 index 0000000000000..538cb217d47b9 --- /dev/null +++ b/packages/block-editor/src/components/preview-options/plugin-preview-menu-item/index.js @@ -0,0 +1,54 @@ +/** + * WordPress dependencies + */ +import { Fill, MenuItem } from '@wordpress/components'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { check } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import { coreDeviceTypes } from '../index'; + +/** + * Component used by a plugin to define the contents of a menu item that + * selects a "custom preview". The children of this component will be displayed + * inside the preview menu. Typically a single string is good enough. + * + * @param {Object} props Component properties. + * @param {string} props.previewId The internal name of this custom preview. Must match the _previewId_ given to `PluginPreview`. + * @param {WPElement} props.children Children to be rendered. + */ +export default function PluginPreviewMenuItem( { + children, + previewId, + ...props +} ) { + const { + __experimentalSetPreviewDeviceType: setPreviewDeviceType, + } = useDispatch( 'core/edit-post' ); + + const { deviceType } = useSelect( + ( select ) => ( { + deviceType: select( + 'core/edit-post' + ).__experimentalGetPreviewDeviceType(), + } ), + [] + ); + + if ( coreDeviceTypes.includes( previewId ) ) { + return null; + } + + return ( + + setPreviewDeviceType( previewId ) } + icon={ deviceType === previewId && check } + > + { children } + + + ); +} diff --git a/packages/block-editor/src/components/preview-options/plugin-preview/index.js b/packages/block-editor/src/components/preview-options/plugin-preview/index.js new file mode 100644 index 0000000000000..02025afd19ee0 --- /dev/null +++ b/packages/block-editor/src/components/preview-options/plugin-preview/index.js @@ -0,0 +1,24 @@ +/** + * WordPress dependencies + */ +import { Fill } from '@wordpress/components'; + +/** + * Component used by a plugin to define the contents of a "custom + * preview". The children of this component will be displayed in the main editor + * screen when this "custom preview" is chosen from the preview menu. + * + * @param {Object} props Component properties. + * @param {string} props.previewId The internal name of this custom preview. Must match the _previewId_ given to `PluginPreviewMenuItem`. + * @param {WPElement} props.children Children to be rendered. + */ +export default function PluginPreview( { children, previewId, ...props } ) { + return ( + + { children } + + ); +} diff --git a/packages/block-editor/src/index.js b/packages/block-editor/src/index.js index add6f5a5f9910..8d54971d0cfa8 100644 --- a/packages/block-editor/src/index.js +++ b/packages/block-editor/src/index.js @@ -16,3 +16,6 @@ export * from './components'; export * from './utils'; export { storeConfig } from './store'; export { SETTINGS_DEFAULTS } from './store/defaults'; +export { default as PluginPreviewMenuItem } from './components/preview-options/plugin-preview-menu-item'; +export { default as PluginPreview } from './components/preview-options/plugin-preview'; +export { coreDeviceTypes } from './components/preview-options'; diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index f7b2384e787b7..eb94c58e5695f 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -39,7 +39,7 @@ import { close } from '@wordpress/icons'; * Internal dependencies */ import TextEditor from '../text-editor'; -import VisualEditor from '../visual-editor'; +import VisualEditorOrPluginPreview from '../visual-editor/visual-editor-or-plugin-preview'; import EditPostKeyboardShortcuts from '../keyboard-shortcuts'; import KeyboardShortcutHelpModal from '../keyboard-shortcut-help-modal'; import ManageBlocksModal from '../manage-blocks-modal'; @@ -250,7 +250,7 @@ function Layout() { ) } { isRichEditingEnabled && mode === 'visual' && ( - + ) }
diff --git a/packages/edit-post/src/components/visual-editor/visual-editor-or-plugin-preview.js b/packages/edit-post/src/components/visual-editor/visual-editor-or-plugin-preview.js new file mode 100644 index 0000000000000..14dd9695cb98c --- /dev/null +++ b/packages/edit-post/src/components/visual-editor/visual-editor-or-plugin-preview.js @@ -0,0 +1,25 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { Slot } from '@wordpress/components'; +import { coreDeviceTypes } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import VisualEditor from './index'; + +function VisualEditorOrPluginPreview() { + const deviceType = useSelect( ( select ) => { + return select( 'core/edit-post' ).__experimentalGetPreviewDeviceType(); + }, [] ); + + if ( ! coreDeviceTypes.includes( deviceType ) ) { + return ( + + ); + } + return ; +} +export default VisualEditorOrPluginPreview;