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

Initial POC for Navigation Overlay as template part #47116

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
190 changes: 94 additions & 96 deletions packages/block-library/src/navigation/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import { useInnerBlocks } from './use-inner-blocks';
import { detectColors } from './utils';
import ManageMenusButton from './manage-menus-button';
import MenuInspectorControls from './menu-inspector-controls';
import OverlayTemplatePartSelector from './overlay-template-part-selector';

function Navigation( {
attributes,
Expand Down Expand Up @@ -201,8 +202,7 @@ function Navigation( {
__unstableMarkNextChangeAsNotPersistent,
} = useDispatch( blockEditorStore );

const [ isResponsiveMenuOpen, setResponsiveMenuVisibility ] =
useState( false );
const [ isResponsiveMenuOpen ] = useState( false );

const [ overlayMenuPreview, setOverlayMenuPreview ] = useState( false );

Expand Down Expand Up @@ -553,94 +553,96 @@ function Navigation( {
const stylingInspectorControls = (
<>
<InspectorControls>
{ hasSubmenuIndicatorSetting && (
<PanelBody title={ __( 'Display' ) }>
{ isResponsive && (
<>
<Button
className={ overlayMenuPreviewClasses }
onClick={ () => {
setOverlayMenuPreview(
! overlayMenuPreview
);
} }
>
{ hasIcon && (
<>
<OverlayMenuIcon icon={ icon } />
<Icon icon={ close } />
</>
) }
{ ! hasIcon && (
<>
<span>{ __( 'Menu' ) }</span>
<span>{ __( 'Close' ) }</span>
</>
) }
</Button>
{ overlayMenuPreview && (
<OverlayMenuPreview
setAttributes={ setAttributes }
hasIcon={ hasIcon }
icon={ icon }
/>
) }
</>
<PanelBody title={ __( 'Overlay' ) }>
<ToggleGroupControl
label={ __( 'Configure overlay menu' ) }
value={ overlayMenu }
help={ __(
'Collapses the navigation options in a menu icon opening an overlay.'
) }
<h3>{ __( 'Overlay Menu' ) }</h3>
<ToggleGroupControl
label={ __( 'Configure overlay menu' ) }
value={ overlayMenu }
help={ __(
'Collapses the navigation options in a menu icon opening an overlay.'
) }
onChange={ ( value ) =>
setAttributes( { overlayMenu: value } )
}
isBlock
hideLabelFromVision
>
<ToggleGroupControlOption
value="never"
label={ __( 'Off' ) }
/>
<ToggleGroupControlOption
value="mobile"
label={ __( 'Mobile' ) }
/>
<ToggleGroupControlOption
value="always"
label={ __( 'Always' ) }
/>
</ToggleGroupControl>
{ hasSubmenus && (
<>
<h3>{ __( 'Submenus' ) }</h3>
<ToggleControl
checked={ openSubmenusOnClick }
onChange={ ( value ) => {
setAttributes( {
openSubmenusOnClick: value,
...( value && {
showSubmenuIcon: true,
} ), // Make sure arrows are shown when we toggle this on.
} );
} }
label={ __( 'Open on click' ) }
/>

<ToggleControl
checked={ showSubmenuIcon }
onChange={ ( value ) => {
setAttributes( {
showSubmenuIcon: value,
} );
} }
disabled={ attributes.openSubmenusOnClick }
label={ __( 'Show arrow' ) }
onChange={ ( value ) =>
setAttributes( { overlayMenu: value } )
}
isBlock
hideLabelFromVision
>
<ToggleGroupControlOption
value="never"
label={ __( 'Off' ) }
/>
<ToggleGroupControlOption
value="mobile"
label={ __( 'Mobile' ) }
/>
<ToggleGroupControlOption
value="always"
label={ __( 'Always' ) }
/>
</ToggleGroupControl>
{ isResponsive && (
<>
<Button
className={ overlayMenuPreviewClasses }
onClick={ () => {
setOverlayMenuPreview(
! overlayMenuPreview
);
} }
>
{ hasIcon && (
<>
<OverlayMenuIcon icon={ icon } />
<Icon icon={ close } />
</>
) }
{ ! hasIcon && (
<>
<span>{ __( 'Menu' ) }</span>
<span>{ __( 'Close' ) }</span>
</>
) }
</Button>
{ overlayMenuPreview && (
<OverlayMenuPreview
setAttributes={ setAttributes }
hasIcon={ hasIcon }
icon={ icon }
/>
</>
) }
) }
</>
) }
{ navigationMenu && (
<OverlayTemplatePartSelector
attributes={ attributes }
setAttributes={ setAttributes }
currentMenuId={ navigationMenu?.id }
/>
) }
</PanelBody>
{ hasSubmenuIndicatorSetting && hasSubmenus && (
<PanelBody title={ __( 'Submenus' ) }>
<ToggleControl
checked={ openSubmenusOnClick }
onChange={ ( value ) => {
setAttributes( {
openSubmenusOnClick: value,
...( value && {
showSubmenuIcon: true,
} ), // Make sure arrows are shown when we toggle this on.
} );
} }
label={ __( 'Open on click' ) }
/>
<ToggleControl
checked={ showSubmenuIcon }
onChange={ ( value ) => {
setAttributes( {
showSubmenuIcon: value,
} );
} }
disabled={ attributes.openSubmenusOnClick }
label={ __( 'Show arrow' ) }
/>
</PanelBody>
) }
</InspectorControls>
Expand All @@ -664,13 +666,13 @@ function Navigation( {
},
{
colorValue: overlayTextColor.color,
label: __( 'Submenu & overlay text' ),
label: __( 'Submenu text' ),
onColorChange: setOverlayTextColor,
resetAllFilter: () => setOverlayTextColor(),
},
{
colorValue: overlayBackgroundColor.color,
label: __( 'Submenu & overlay background' ),
label: __( 'Submenu background' ),
onColorChange: setOverlayBackgroundColor,
resetAllFilter: () =>
setOverlayBackgroundColor(),
Expand Down Expand Up @@ -732,14 +734,12 @@ function Navigation( {
{ stylingInspectorControls }
<ResponsiveWrapper
id={ clientId }
onToggle={ setResponsiveMenuVisibility }
currentMenuId={ navigationMenu?.id }
isOpen={ isResponsiveMenuOpen }
hasIcon={ hasIcon }
icon={ icon }
isResponsive={ 'never' !== overlayMenu }
isHiddenByDefault={ 'always' === overlayMenu }
overlayBackgroundColor={ overlayBackgroundColor }
overlayTextColor={ overlayTextColor }
>
<UnsavedInnerBlocks
createNavigationMenu={ createNavigationMenu }
Expand Down Expand Up @@ -889,15 +889,13 @@ function Navigation( {
<TagName { ...blockProps }>
<ResponsiveWrapper
id={ clientId }
onToggle={ setResponsiveMenuVisibility }
currentMenuId={ navigationMenu?.id }
label={ __( 'Menu' ) }
hasIcon={ hasIcon }
icon={ icon }
isOpen={ isResponsiveMenuOpen }
isResponsive={ isResponsive }
isHiddenByDefault={ 'always' === overlayMenu }
overlayBackgroundColor={ overlayBackgroundColor }
overlayTextColor={ overlayTextColor }
>
{ isEntityAvailable && (
<NavigationInnerBlocks
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* WordPress dependencies
*/
import { Button } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { store as coreStore, useEntityProp } from '@wordpress/core-data';
import { useDispatch, useSelect } from '@wordpress/data';
import { addQueryArgs } from '@wordpress/url';

/**
* Internal dependencies
*/
import useNavigationEntities from '../use-navigation-entities';

function OverlayTemplatePartSelector( { currentMenuId } ) {
const { saveEntityRecord } = useDispatch( coreStore );
const menuSlug = 'navigation-overlay-' + currentMenuId;
const { theme } = useNavigationEntities();
const activeTheme = theme[ 0 ].stylesheet;
const templatePartId = activeTheme + '//' + menuSlug;

// Find a template part that matches the menu.
const { hasTemplatePart } = useSelect( ( select ) => {
const { getEntityRecord } = select( coreStore );
const part = getEntityRecord(
'postType',
'wp_template_part',
templatePartId
);
return {
hasTemplatePart: part ? true : false,
};
}, [] );

const menuName = useEntityProp(
'postType',
'wp_navigation',
'title',
currentMenuId
);

const overlayName = sprintf(
// translators: %s: The name of the menu.
__( 'Navigation Overlay for %s' ),
menuName[ 0 ]
);

async function createOverlayTemplatePart() {
const newTemplatePart = await saveEntityRecord(
'postType',
'wp_template_part',
{
slug: 'navigation-overlay-' + currentMenuId,
title: overlayName,
content:
'<!-- wp:group {"align":"full","layout":{"type":"constrained"}} --><div class="wp-block-group alignfull"><!-- wp:navigation {"overlayMenu":"never"} /--></div><!-- /wp:group -->',
}
);
return newTemplatePart;
}

return (
<>
{ ! hasTemplatePart && (
<Button
variant="link"
onClick={ () => {
createOverlayTemplatePart();
} }
>
{ __( 'Create Overlay' ) }
</Button>
) }
{ hasTemplatePart && (
<Button
variant="link"
href={ addQueryArgs( 'site-editor.php', {
postType: 'wp_template_part',
postId: templatePartId,
canvas: 'edit',
} ) }
>
{ __( 'Edit Overlay' ) }
</Button>
) }
</>
);
}

export default OverlayTemplatePartSelector;
Loading