diff --git a/packages/edit-post/src/components/header/index.js b/packages/edit-post/src/components/header/index.js index 42ae532aa2cfc9..7dca19d07f57a5 100644 --- a/packages/edit-post/src/components/header/index.js +++ b/packages/edit-post/src/components/header/index.js @@ -94,10 +94,7 @@ function Header() { aria-expanded={ isEditorSidebarOpened } shortcut={ shortcut } /> - + diff --git a/packages/edit-post/src/components/header/plugin-more-menu-item/test/__snapshots__/index.js.snap b/packages/edit-post/src/components/header/plugin-more-menu-item/test/__snapshots__/index.js.snap deleted file mode 100644 index 44ebe7ba7b2138..00000000000000 --- a/packages/edit-post/src/components/header/plugin-more-menu-item/test/__snapshots__/index.js.snap +++ /dev/null @@ -1,42 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PluginMoreMenuItem renders menu item as button properly 1`] = ` -
- -
- -
-
-`; diff --git a/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js b/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js index c8bf2ba0e958cd..2ed29f7f8d8c39 100644 --- a/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js +++ b/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { ComplementaryArea } from '@wordpress/interface'; +import { ComplementaryAreaMoreMenuItem } from '@wordpress/interface'; /** * Renders a menu item in `Plugins` group in `More Menu` drop down, @@ -55,6 +55,6 @@ import { ComplementaryArea } from '@wordpress/interface'; export default function PluginSidebarMoreMenuItem( props ) { return ( - + ); } diff --git a/packages/edit-post/src/components/sidebar/settings-sidebar/index.js b/packages/edit-post/src/components/sidebar/settings-sidebar/index.js index 4a408b1b63f350..de4d1e482bf984 100644 --- a/packages/edit-post/src/components/sidebar/settings-sidebar/index.js +++ b/packages/edit-post/src/components/sidebar/settings-sidebar/index.js @@ -36,7 +36,7 @@ const SettingsSidebar = () => { } return ( } closeLabel={ __( 'Close settings' ) } headerClassName="edit-post-sidebar__panel-tabs" diff --git a/packages/edit-site/src/components/header/index.js b/packages/edit-site/src/components/header/index.js index faca6a41a2cd69..867dc74ed1d15e 100644 --- a/packages/edit-site/src/components/header/index.js +++ b/packages/edit-site/src/components/header/index.js @@ -8,7 +8,6 @@ import { Inserter, } from '@wordpress/block-editor'; import { PinnedItems } from '@wordpress/interface'; -import { Button } from '@wordpress/components'; /** * Internal dependencies @@ -75,10 +74,7 @@ export default function Header() {
- +
diff --git a/packages/edit-site/src/components/sidebar/index.js b/packages/edit-site/src/components/sidebar/index.js index 093a86d4c8fec5..72e2333a32b181 100644 --- a/packages/edit-site/src/components/sidebar/index.js +++ b/packages/edit-site/src/components/sidebar/index.js @@ -2,7 +2,10 @@ * WordPress dependencies */ import { createSlotFill } from '@wordpress/components'; -import { ComplementaryArea } from '@wordpress/interface'; +import { + ComplementaryArea, + ComplementaryAreaMoreMenuItem, +} from '@wordpress/interface'; import { __ } from '@wordpress/i18n'; import { cog, pencil } from '@wordpress/icons'; @@ -15,19 +18,19 @@ const DefaultSidebar = ( { areaId, title, icon, children } ) => { <> { children } - { title } - +
); }; diff --git a/packages/interface/src/components/action-item/README.md b/packages/interface/src/components/action-item/README.md index 1d7b1b467fbf99..52f1f4fc816395 100644 --- a/packages/interface/src/components/action-item/README.md +++ b/packages/interface/src/components/action-item/README.md @@ -49,3 +49,10 @@ Callback function executed when a click on the item happens. - Type: `Function` - Required: no +### as + +The component that is going to be used to render a the action item. If the component is not passed it defaults to the component specified on the slot. + +- Type: `Array` +- Required: no + diff --git a/packages/interface/src/components/action-item/index.js b/packages/interface/src/components/action-item/index.js index 6399bd457291fe..f4c32e166463a7 100644 --- a/packages/interface/src/components/action-item/index.js +++ b/packages/interface/src/components/action-item/index.js @@ -31,11 +31,12 @@ function ActionItemSlot( { ); } -function ActionItem( { name, onClick, ...props } ) { +function ActionItem( { name, as, onClick, ...props } ) { return ( { ( fillProps ) => { - const { onClick: fpOnClick, as: Item } = fillProps; + const { onClick: fpOnClick, as: fpAs } = fillProps; + const Item = as || fpAs || Button; return ( { + return { + icon: ownProps.icon || context.icon, + identifier: + ownProps.identifier || `${ context.name }/${ ownProps.name }`, + }; +} ); diff --git a/packages/interface/src/components/complementary-area-header/index.js b/packages/interface/src/components/complementary-area-header/index.js index b5918b8cc7fee8..71ee4bb80f880b 100644 --- a/packages/interface/src/components/complementary-area-header/index.js +++ b/packages/interface/src/components/complementary-area-header/index.js @@ -11,7 +11,7 @@ import { close } from '@wordpress/icons'; /** * Internal dependencies */ -import { ComplementaryAreaToggle } from '../complementary-area'; +import ComplementaryAreaToggle from '../complementary-area-toggle'; const ComplementaryAreaHeader = ( { smallScreenTitle, diff --git a/packages/interface/src/components/complementary-area-more-menu-item/README.md b/packages/interface/src/components/complementary-area-more-menu-item/README.md new file mode 100644 index 00000000000000..57f06919e4eb12 --- /dev/null +++ b/packages/interface/src/components/complementary-area-more-menu-item/README.md @@ -0,0 +1,44 @@ +ComplementaryAreaMoreMenuItem +============================= + +Renders an item in the more menu that allows toggling a complementary area. +Props not referenced here are passed to the component used to render the menu item. + +### scope + +The scope of the complementary area e.g: "core/edit-post", "core/edit-site", "myplugin/custom-screen-a", + +- Type: `String` +- Required: Yes + +### identifier + +Identifier of the complementary area. The string is saved on the store and allows to identify which of the sidebars is active. + +- Type: `String` +- Required: No +- Default: Concatenation of `name` of the plugin extracted from the context (when available) with the `targe` of the sidebar passed as a property. + +### target + +Name of the complementary area. The name of the complementarity area is concatenated with the name of the plugin to form the identifier of the complementary area. The name of the plugin is extracted from the plugin context where the sidebar is rendered. If there is no plugin context available or there is a need to specify a custom identifier, please use the `identifier` property instead. + +- Type: `String` +- Required: No + +### selectedIcon + +An icon to use when the complementary area is open e.g: a check mark. +If the prop is not passed the icon of the complementary area or of the plugin is used. + + +- Type: `Element` +- Required: no + +### as + +A component used to render the item. +Defaults to what was specified in the slot for menu items but specific component can be used. + +- Type: `Component` +- Required: no diff --git a/packages/interface/src/components/complementary-area-more-menu-item/index.js b/packages/interface/src/components/complementary-area-more-menu-item/index.js new file mode 100644 index 00000000000000..39573a88fba206 --- /dev/null +++ b/packages/interface/src/components/complementary-area-more-menu-item/index.js @@ -0,0 +1,33 @@ +/** + * WordPress dependencies + */ +import { check } from '@wordpress/icons'; +/** + * Internal dependencies + */ +import ComplementaryAreaToggle from '../complementary-area-toggle'; +import ActionItem from '../action-item'; + +export default function ComplementaryAreaMoreMenuItem( { + scope, + target, + ...props +} ) { + return ( + { + return ( + + ); + } } + role="menuitemcheckbox" + selectedIcon={ check } + name={ target } + scope={ scope } + { ...props } + /> + ); +} diff --git a/packages/interface/src/components/complementary-area-toggle/README.md b/packages/interface/src/components/complementary-area-toggle/README.md new file mode 100644 index 00000000000000..d884a2af19010f --- /dev/null +++ b/packages/interface/src/components/complementary-area-toggle/README.md @@ -0,0 +1,46 @@ +ComplementaryAreaToggle +============================= + +`ComplementaryArea.Toggle` is a component used to render a UI allowing the toggle (open/close) a complementary area. + +## Props + +### scope + +The scope of the complementary area e.g: "core/edit-post", "core/edit-site", "myplugin/custom-screen-a", + +- Type: `String` +- Required: Yes + +### identifier + +Identifier of the complementary area. + +- Type: `String` +- Required: No +- Default: Concatenation of `name` of the plugin extracted from the context (when available) with the "name" of the sidebar passed as a property. + +### name + +Name of the complementary area. The name of the complementarity area is concatenated with the name of the plugin to form the identifier of the complementary area. The name of the plugin is extracted from the plugin context where the sidebar is rendered. If there is no plugin context available or there is a need to specify a custom identifier, please use the `identifier` property instead. + +- Type: `String` +- Required: No + + +### selectedIcon + +An icon to use when the complementary area is open e.g: a check mark. +If the prop is not passed the icon of the complementary area or of the plugin is used. + + +- Type: `Element` +- Required: no + +### as + +A component used to render the toggle. +Defaults to and `Button` can be changed to `MenuItem`or a custom component for example. + +- Type: `Component` +- Required: no diff --git a/packages/interface/src/components/complementary-area-toggle/index.js b/packages/interface/src/components/complementary-area-toggle/index.js new file mode 100644 index 00000000000000..d75d367697751d --- /dev/null +++ b/packages/interface/src/components/complementary-area-toggle/index.js @@ -0,0 +1,51 @@ +/** + * External dependencies + */ +import { omit } from 'lodash'; + +/** + * WordPress dependencies + */ +import { Button } from '@wordpress/components'; +import { useDispatch, useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import complementaryAreaContext from '../complementary-area-context'; + +function ComplementaryAreaToggle( { + as = Button, + scope, + identifier, + icon, + selectedIcon, + ...props +} ) { + const ComponentToUse = as; + const isSelected = useSelect( + ( select ) => + select( 'core/interface' ).getActiveComplementaryArea( scope ) === + identifier, + [ identifier ] + ); + const { enableComplementaryArea, disableComplementaryArea } = useDispatch( + 'core/interface' + ); + return ( + { + if ( isSelected ) { + disableComplementaryArea( scope ); + } else { + enableComplementaryArea( scope, identifier ); + } + } } + { ...omit( props, [ 'name' ] ) } + /> + ); +} + +export default complementaryAreaContext( ComplementaryAreaToggle ); diff --git a/packages/interface/src/components/complementary-area/README.md b/packages/interface/src/components/complementary-area/README.md index 88716219b683fc..4c77bef3fee29d 100644 --- a/packages/interface/src/components/complementary-area/README.md +++ b/packages/interface/src/components/complementary-area/README.md @@ -25,7 +25,7 @@ Label of the button that allows to close the complementary area. - Required: No - Default: "Close plugin" -### complementaryAreaIdentifier +### identifier Identifier of the complementary area. The string is saved on the store and allows to identify which of the sidebars is active. @@ -57,7 +57,7 @@ The icon to render. ### name -Name of the complementary area. The name of the complementarity area is concatenated with the name of the plugin to form the identifier of the complementary area. The name of the plugin is extracted from the plugin context where the sidebar is rendered. If there is no plugin context available or there is a need to specify a custom identifier, please use the `complementaryAreaIdentifier` property instead. +Name of the complementary area. The name of the complementarity area is concatenated with the name of the plugin to form the identifier of the complementary area. The name of the plugin is extracted from the plugin context where the sidebar is rendered. If there is no plugin context available or there is a need to specify a custom identifier, please use the `identifier` property instead. - Type: `String` - Required: No @@ -112,81 +112,3 @@ The scope of the complementary area e.g: "core/edit-post", "core/edit-site", "my - Type: `String` - Required: Yes - - - -ComplementaryArea.Toggle -============================= - -`ComplementaryArea.Toggle` is a component used to render a UI allowing the toggle (open/close) a complementary area. - -## Props - -### scope - -The scope of the complementary area e.g: "core/edit-post", "core/edit-site", "myplugin/custom-screen-a", - -- Type: `String` -- Required: Yes - -### complementaryAreaIdentifier - -Identifier of the complementary area. - -- Type: `String` -- Required: No -- Default: Concatenation of `name` of the plugin extracted from the context (when available) with the "name" of the sidebar passed as a property. - -### name - -Name of the complementary area. The name of the complementarity area is concatenated with the name of the plugin to form the identifier of the complementary area. The name of the plugin is extracted from the plugin context where the sidebar is rendered. If there is no plugin context available or there is a need to specify a custom identifier, please use the `complementaryAreaIdentifier` property instead. - -- Type: `String` -- Required: No - - -### selectedIcon - -An icon to use when the complementary area is open e.g: a check mark. -If the prop is not passed the icon of the complementary area or of the plugin is used. - - -- Type: `Element` -- Required: no - -### as - -A component used to render the toggle. -Defaults to and `Button` can be changed to `MenuItem`or a custom component for example. - -- Type: `Component` -- Required: no - - -ComplementaryArea.MoreMenuItem -============================= - -Renders an item in the more menu that allows toggling a complementary area. -Props not referenced here are passed to the component used to render the menu item. - -### scope - -The scope of the complementary area e.g: "core/edit-post", "core/edit-site", "myplugin/custom-screen-a", - -- Type: `String` -- Required: Yes - -### complementaryAreaIdentifier - -Identifier of the complementary area. The string is saved on the store and allows to identify which of the sidebars is active. - -- Type: `String` -- Required: No -- Default: Concatenation of `name` of the plugin extracted from the context (when available) with the `targe` of the sidebar passed as a property. - -### target - -Name of the complementary area. The name of the complementarity area is concatenated with the name of the plugin to form the identifier of the complementary area. The name of the plugin is extracted from the plugin context where the sidebar is rendered. If there is no plugin context available or there is a need to specify a custom identifier, please use the `complementaryAreaIdentifier` property instead. - -- Type: `String` -- Required: No diff --git a/packages/interface/src/components/complementary-area/index.js b/packages/interface/src/components/complementary-area/index.js index c9acc8be2a2500..ef55d24020a754 100644 --- a/packages/interface/src/components/complementary-area/index.js +++ b/packages/interface/src/components/complementary-area/index.js @@ -2,7 +2,6 @@ * External dependencies */ import classnames from 'classnames'; -import { omit } from 'lodash'; /** * WordPress dependencies @@ -10,15 +9,15 @@ import { omit } from 'lodash'; import { Animate, Button, Panel, Slot, Fill } from '@wordpress/components'; import { useDispatch, useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; -import { withPluginContext } from '@wordpress/plugins'; -import { check, starEmpty, starFilled } from '@wordpress/icons'; +import { starEmpty, starFilled } from '@wordpress/icons'; /** * Internal dependencies */ import ComplementaryAreaHeader from '../complementary-area-header'; +import ComplementaryAreaToggle from '../complementary-area-toggle'; +import complementaryAreaContext from '../complementary-area-context'; import PinnedItems from '../pinned-items'; -import ActionItem from '../action-item'; function ComplementaryAreaSlot( { scope, ...props } ) { return ; @@ -34,80 +33,11 @@ function ComplementaryAreaFill( { scope, children, className } ) { ); } -const complementaryAreaContext = withPluginContext( ( context, ownProps ) => { - return { - icon: ownProps.icon || context.icon, - complementaryAreaIdentifier: - ownProps.complementaryAreaIdentifier || - `${ context.name }/${ ownProps.name }`, - }; -} ); - -export function ComplementaryAreaToggleInner( { - as = Button, - scope, - complementaryAreaIdentifier, - icon, - selectedIcon, - ...props -} ) { - const ComponentToUse = as; - const isSelected = useSelect( - ( select ) => - select( 'core/interface' ).getActiveComplementaryArea( scope ) === - complementaryAreaIdentifier, - [ complementaryAreaIdentifier ] - ); - const { enableComplementaryArea, disableComplementaryArea } = useDispatch( - 'core/interface' - ); - return ( - { - if ( isSelected ) { - disableComplementaryArea( scope ); - } else { - enableComplementaryArea( - scope, - complementaryAreaIdentifier - ); - } - } } - { ...omit( props, [ 'name' ] ) } - /> - ); -} - -export const ComplementaryAreaToggle = complementaryAreaContext( - ComplementaryAreaToggleInner -); -function ComplementaryAreaMoreMenuItem( { scope, target, ...props } ) { - return ( - { - return ( - - ); - } } - role="menuitemcheckbox" - selectedIcon={ check } - name={ target } - scope={ scope } - { ...props } - /> - ); -} - function ComplementaryArea( { children, className, closeLabel = __( 'Close plugin' ), - complementaryAreaIdentifier, + identifier, header, headerClassName, icon, @@ -124,29 +54,26 @@ function ComplementaryArea( { 'core/interface' ); return { - isActive: - getActiveComplementaryArea( scope ) === - complementaryAreaIdentifier, - isPinned: isItemPinned( scope, complementaryAreaIdentifier ), + isActive: getActiveComplementaryArea( scope ) === identifier, + isPinned: isItemPinned( scope, identifier ), }; }, - [ complementaryAreaIdentifier, scope ] + [ identifier, scope ] ); const { pinItem, unpinItem } = useDispatch( 'core/interface' ); return ( <> { isPinned && ( - { - return ; - } } - isPressed={ isActive } - aria-expanded={ isActive } - label={ title } - icon={ icon } - /> + + + ) } { isActive && ( { header || ( @@ -184,7 +111,7 @@ function ComplementaryArea( { onClick={ () => ( isPinned ? unpinItem : pinItem )( scope, - complementaryAreaIdentifier + identifier ) } isPressed={ isPinned } @@ -204,7 +131,5 @@ function ComplementaryArea( { const ComplementaryAreaWrapped = complementaryAreaContext( ComplementaryArea ); ComplementaryAreaWrapped.Slot = ComplementaryAreaSlot; -ComplementaryAreaWrapped.Toggle = ComplementaryAreaToggle; -ComplementaryAreaWrapped.MoreMenuItem = ComplementaryAreaMoreMenuItem; export default ComplementaryAreaWrapped; diff --git a/packages/interface/src/components/index.js b/packages/interface/src/components/index.js index 04fefecb5b302c..971b42522ae3c4 100644 --- a/packages/interface/src/components/index.js +++ b/packages/interface/src/components/index.js @@ -1,4 +1,5 @@ export { default as ComplementaryArea } from './complementary-area'; +export { default as ComplementaryAreaMoreMenuItem } from './complementary-area-more-menu-item'; export { default as FullscreenMode } from './fullscreen-mode'; export { default as InterfaceSkeleton } from './interface-skeleton'; export { default as PinnedItems } from './pinned-items'; diff --git a/packages/interface/src/components/pinned-items/index.js b/packages/interface/src/components/pinned-items/index.js index 7be401f2f7866b..59fc70003095bb 100644 --- a/packages/interface/src/components/pinned-items/index.js +++ b/packages/interface/src/components/pinned-items/index.js @@ -1,24 +1,34 @@ /** * External dependencies */ +import { isEmpty } from 'lodash'; import classnames from 'classnames'; /** - * Internal dependencies + * WordPress dependencies */ -import ActionItem from '../action-item'; +import { Slot, Fill } from '@wordpress/components'; function PinnedItems( { scope, ...props } ) { - return ; + return ; } function PinnedItemsSlot( { scope, className, ...props } ) { return ( - + + { ( fills ) => + ! isEmpty( fills ) && ( +
+ { fills } +
+ ) + } +
); }