-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First pass at continuing work on extending preview menu in editors. The work is entirely copied from #36119, which includes work from #31984 Tony Arcangelini <tony@arcangelini.com> Piotr Delawski <piotr.delawski@gmail.com>
- Loading branch information
Showing
5 changed files
with
221 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
packages/interface/src/components/plugin-preview/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { | ||
__experimentalUseSlot as useSlot, | ||
createSlotFill, | ||
MenuItem, | ||
MenuGroup, | ||
Fill, | ||
} from '@wordpress/components'; | ||
import { check } from '@wordpress/icons'; | ||
|
||
const { Fill: PluginPreviewMenuFill, Slot: PluginPreviewMenuSlot } = | ||
createSlotFill( 'PluginPreviewMenu' ); | ||
|
||
/** | ||
* Component used to define a custom preview menu item and optional content. | ||
* | ||
* The children of this component will be displayed in the main area of the | ||
* block editor, instead of the `VisualEditor` component. | ||
* | ||
* The wrapper expects a function that returns an element. The `VisualEditor` | ||
* component is fed in as a prop to be used. | ||
* | ||
* The `title` and `icon` are used to populate the Preview menu item. | ||
* | ||
* @param {Object} props Component properties. | ||
* @param {WPElement} props.children Preview content. | ||
* @param {WPIcon} props.icon Menu item icon to be rendered. | ||
* @param {string} props.name A unique name of the custom preview. | ||
* @param {Function} props.onClick Menu item click handler, e.g. for previews | ||
* that provide no content (`children`). | ||
* @param {Function} props.wrapper Wrapper for visual editor content. | ||
* @param {string} props.title Menu item title. | ||
*/ | ||
function PluginPreview( { | ||
children, | ||
icon, | ||
name, | ||
onClick, | ||
title, | ||
wrapper, | ||
...props | ||
} ) { | ||
if ( ! name || ( ! children && ! wrapper ) ) { | ||
name = 'Desktop'; | ||
} | ||
|
||
return ( | ||
<> | ||
<PluginPreviewMenuFill> | ||
{ ( { deviceType, setDeviceType } ) => ( | ||
<MenuItem | ||
className={ name } | ||
onClick={ ( ...args ) => { | ||
setDeviceType( name ); | ||
if ( onClick ) { | ||
onClick( ...args ); | ||
} | ||
} } | ||
icon={ icon || ( deviceType === name && check ) } | ||
{ ...props } | ||
> | ||
{ title } | ||
</MenuItem> | ||
) } | ||
</PluginPreviewMenuFill> | ||
|
||
{ children ? ( | ||
<Fill name={ `PluginPreview/${ name }` } { ...props }> | ||
{ children } | ||
</Fill> | ||
) : ( | ||
typeof wrapper === 'function' && ( | ||
<Fill name={ `PluginPreview/${ name }` } { ...props }> | ||
{ ( { previewContent } ) => wrapper( previewContent ) } | ||
</Fill> | ||
) | ||
) } | ||
</> | ||
); | ||
} | ||
|
||
function PluginPreviewSlot( { devices, ...props } ) { | ||
const slot = useSlot( PluginPreviewMenuSlot.__unstableName ); | ||
const hasFills = Boolean( slot.fills && slot.fills.length ); | ||
|
||
if ( ! hasFills ) { | ||
return null; | ||
} | ||
|
||
function checkForDeviceNames( fill ) { | ||
const { className } = fill[ 0 ].props; | ||
if ( devices.includes( className ) ) { | ||
return; | ||
} | ||
return fill; | ||
} | ||
|
||
return ( | ||
<MenuGroup> | ||
<PluginPreviewMenuSlot { ...props }> | ||
{ ( fills ) => <>{ fills.filter( checkForDeviceNames ) }</> } | ||
</PluginPreviewMenuSlot> | ||
</MenuGroup> | ||
); | ||
} | ||
|
||
PluginPreview.Slot = PluginPreviewSlot; | ||
|
||
export default PluginPreview; |