Skip to content

Commit

Permalink
Allow Preview menu to be extendible by plugins: WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mreishus committed Sep 21, 2020
1 parent 9ef9f2c commit f238cfe
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 15 deletions.
27 changes: 15 additions & 12 deletions docs/designers-developers/developers/slotfills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ export const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' );

const PluginPostStatusInfo = ( { children, className } ) => (
<Fill>
<PanelRow className={ className }>
{ children }
</PanelRow>
<PanelRow className={ className }>{ children }</PanelRow>
</Fill>
);

Expand Down Expand Up @@ -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)
Original file line number Diff line number Diff line change
@@ -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, `deviceName`, and `children`.

- `deviceName` - 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 = () => (
<Fragment>
<PluginPreviewMenuItem deviceName="preview-custom-1">
Custom Preview 1 Menu Text
</PluginPreviewMenuItem>
<PluginPreview deviceName="preview-custom-1">
<div>
<h4>Custom Preview 1 Content</h4>
</div>
</PluginPreview>
</Fragment>
);

registerPlugin( 'plugin-preview-test', {
render: PluginPreviewTest,
} );
```
37 changes: 37 additions & 0 deletions docs/designers-developers/developers/slotfills/plugin-preview.md
Original file line number Diff line number Diff line change
@@ -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, `deviceName`, and `children`.

- `deviceName` - 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 = () => (
<Fragment>
<PluginPreviewMenuItem deviceName="preview-custom-1">
Custom Preview 1 Menu Text
</PluginPreviewMenuItem>
<PluginPreview deviceName="preview-custom-1">
<div>
<h4>Custom Preview 1 Content</h4>
</div>
</PluginPreview>
</Fragment>
);

registerPlugin( 'plugin-preview-test', {
render: PluginPreviewTest,
} );
```
36 changes: 36 additions & 0 deletions packages/block-editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,18 @@ Undocumented declaration.

Undocumented declaration.

<a name="coreDeviceTypes" href="#coreDeviceTypes">#</a> **coreDeviceTypes**

This is 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 <PluginPreviewMenuItem /> and
<PluginPreview /> components, and defer to a <Slot /> filled by the plugin to
draw the preview.

<a name="createCustomColorsHOC" href="#createCustomColorsHOC">#</a> **createCustomColorsHOC**

A higher-order component factory for creating a 'withCustomColors' HOC, which handles color logic
Expand Down Expand Up @@ -447,6 +459,30 @@ _Related_

- <https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/plain-text/README.md>

<a name="PluginPreview" href="#PluginPreview">#</a> **PluginPreview**

React 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.deviceName_ `string`: The internal name of this custom preview. Must
match the _deviceName_ given to `PluginPreviewMenuItem`.
- _props.children_ `WPElement`: Children to be rendered.

<a name="PluginPreviewMenuItem" href="#PluginPreviewMenuItem">#</a> **PluginPreviewMenuItem**

React 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.

- _props_ `Object`: Component properties.
- _props.deviceName_ `string`: The internal name of this custom preview. Must
match the _deviceName_ given to `PluginPreview`.
- _props.children_ `WPElement`: Children to be rendered.

<a name="PreserveScrollInReorder" href="#PreserveScrollInReorder">#</a> **PreserveScrollInReorder**

Undocumented declaration.
Expand Down
13 changes: 12 additions & 1 deletion packages/block-editor/src/components/preview-options/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ 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';

export const coreDeviceTypes = [ 'Desktop', 'Tablet', 'Mobile' ];

export default function PreviewOptions( {
children,
className,
Expand Down Expand Up @@ -67,6 +69,15 @@ export default function PreviewOptions( {
{ __( 'Mobile' ) }
</MenuItem>
</MenuGroup>

<Slot name="core/block-editor/plugin-preview-menu">
{ ( fills ) =>
! fills || fills.length === 0 ? null : (
<MenuGroup>{ fills }</MenuGroup>
)
}
</Slot>

{ children }
</>
) }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* 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';

export default function PluginPreviewMenuItem( {
children,
deviceName,
...props
} ) {
const {
__experimentalSetPreviewDeviceType: setPreviewDeviceType,
} = useDispatch( 'core/edit-post' );

const { deviceType } = useSelect(
( select ) => ( {
deviceType: select(
'core/edit-post'
).__experimentalGetPreviewDeviceType(),
} ),
[]
);

if ( coreDeviceTypes.includes( deviceName ) ) {
return null;
}

return (
<Fill name="core/block-editor/plugin-preview-menu" { ...props }>
<MenuItem
onClick={ () => setPreviewDeviceType( deviceName ) }
icon={ deviceType === deviceName && check }
>
{ children }
</MenuItem>
</Fill>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* WordPress dependencies
*/
import { Fill } from '@wordpress/components';

export default function PluginPreview( { children, deviceName, ...props } ) {
return (
<Fill
name={ 'core/block-editor/plugin-preview/' + deviceName }
{ ...props }
>
{ children }
</Fill>
);
}
3 changes: 3 additions & 0 deletions packages/block-editor/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
4 changes: 2 additions & 2 deletions packages/edit-post/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -246,7 +246,7 @@ function Layout() {
<TextEditor />
) }
{ isRichEditingEnabled && mode === 'visual' && (
<VisualEditor />
<VisualEditorOrPluginPreview />
) }
<div className="edit-post-layout__metaboxes">
<MetaBoxes location="normal" />
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
<Slot name={ 'core/block-editor/plugin-preview/' + deviceType } />
);
}
return <VisualEditor />;
}
export default VisualEditorOrPluginPreview;

0 comments on commit f238cfe

Please sign in to comment.