Skip to content
Draft
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
68 changes: 68 additions & 0 deletions lib/compat/wordpress-7.0/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,71 @@ function gutenberg_parse_pattern_blocks_in_block_templates( $query_result, $quer
}

add_filter( 'get_block_templates', 'gutenberg_parse_pattern_blocks_in_block_templates', 10, 3 );

/**
* Registers the 'overlay' template part area when the experiment is enabled.
*
* @param array $areas Array of template part area definitions.
* @return array Modified array of template part area definitions.
*/
function gutenberg_register_overlay_template_part_area( $areas ) {
if ( ! gutenberg_is_experiment_enabled( 'gutenberg-customizable-navigation-overlays' ) ) {
return $areas;
}

$areas[] = array(
'area' => 'overlay',
'label' => __( 'Overlay', 'gutenberg' ),
'description' => __( 'Custom overlay area for navigation overlays.', 'gutenberg' ),
'icon' => 'overlay',
'area_tag' => 'div',
);

return $areas;
}
add_filter( 'default_wp_template_part_areas', 'gutenberg_register_overlay_template_part_area' );

/**
* Registers the 'overlay' pattern category when the experiment is enabled.
*/
function gutenberg_register_overlay_pattern_category() {
if ( ! gutenberg_is_experiment_enabled( 'gutenberg-customizable-navigation-overlays' ) ) {
return;
}

register_block_pattern_category(
'overlay',
array( 'label' => __( 'Overlay', 'gutenberg' ) )
);
}
add_action( 'init', 'gutenberg_register_overlay_pattern_category' );

/**
* Registers the default overlay pattern when the experiment is enabled.
*/
function gutenberg_register_overlay_pattern() {
if ( ! gutenberg_is_experiment_enabled( 'gutenberg-customizable-navigation-overlays' ) ) {
return;
}

register_block_pattern(
'gutenberg/overlay-default',
array(
'title' => __( 'Overlay', 'gutenberg' ),
'categories' => array( 'overlay' ),
'blockTypes' => array( 'core/template-part/overlay' ),
'content' => '<!-- wp:group {"metadata":{"name":"Overlay"},"style":{"dimensions":{"minHeight":"100%"},"spacing":{"padding":{"top":"var:preset|spacing|30","bottom":"var:preset|spacing|30","left":"var:preset|spacing|30","right":"var:preset|spacing|30"}}},"layout":{"type":"constrained"}} -->
<div class="wp-block-group" style="min-height:100%;padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)"><!-- wp:group {"style":{"spacing":{"margin":{"bottom":"var:preset|spacing|40"}}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"right"}} -->
<div class="wp-block-group" style="margin-bottom:var(--wp--preset--spacing--40)"><!-- wp:overlay-close {"className":"has-text-align-left","style":{"typography":{"textAlign":"left"}}} -->
<div class="wp-block-overlay-close has-text-align-left"><button type="button" class="wp-block-overlay-close__button" aria-label="Close overlay"><span class="wp-block-overlay-close__icon">×</span></button></div>
<!-- /wp:overlay-close --></div>
<!-- /wp:group -->

<!-- wp:group {"metadata":{"name":"Overlay Content"},"style":{"spacing":{"blockGap":"var:preset|spacing|40"}},"layout":{"type":"flex","orientation":"vertical","justifyContent":"center"}} -->
<div class="wp-block-group"><!-- wp:navigation {"layout":{"type":"flex","orientation":"vertical","justifyContent":"left"}} /--></div>
<!-- /wp:group --></div>
<!-- /wp:group -->',
)
);
}
add_action( 'init', 'gutenberg_register_overlay_pattern' );
2 changes: 2 additions & 0 deletions packages/block-library/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import * as navigation from './navigation';
import * as navigationLink from './navigation-link';
import * as navigationSubmenu from './navigation-submenu';
import * as nextpage from './nextpage';
import * as overlayClose from './overlay-close';
import * as pattern from './pattern';
import * as pageList from './page-list';
import * as pageListItem from './page-list-item';
Expand Down Expand Up @@ -187,6 +188,7 @@ const getAllBlocks = () => {
missing,
more,
nextpage,
overlayClose,
pageList,
pageListItem,
pattern,
Expand Down
3 changes: 3 additions & 0 deletions packages/block-library/src/navigation/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@
"templateLock": {
"type": [ "string", "boolean" ],
"enum": [ "all", "insert", "contentOnly", false ]
},
"overlayTemplatePartId": {
"type": "string"
}
},
"providesContext": {
Expand Down
222 changes: 154 additions & 68 deletions packages/block-library/src/navigation/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
BlockControls,
} from '@wordpress/block-editor';
import { EntityProvider, store as coreStore } from '@wordpress/core-data';
import { store as editorStore } from '@wordpress/editor';

import { useDispatch, useSelect } from '@wordpress/data';
import {
Expand All @@ -43,6 +44,7 @@ import {
Notice,
ToolbarButton,
ToolbarGroup,
PanelBody,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { speak } from '@wordpress/a11y';
Expand Down Expand Up @@ -77,8 +79,11 @@ import MenuInspectorControls from './menu-inspector-controls';
import DeletedNavigationWarning from './deleted-navigation-warning';
import AccessibleDescription from './accessible-description';
import AccessibleMenuDescription from './accessible-menu-description';
import OverlaySelector from './overlay-selector';
import { unlock } from '../../lock-unlock';
import { useToolsPanelDropdownMenuProps } from '../../utils/hooks';

const TEMPLATE_PART_POST_TYPE = 'wp_template_part';
import { DEFAULT_BLOCK } from '../constants';

/**
Expand Down Expand Up @@ -262,7 +267,7 @@ function Navigation( {
} ) {
const {
openSubmenusOnClick,
overlayMenu,
overlayMenu: savedOverlayMenu,
showSubmenuIcon,
templateLock,
layout: {
Expand All @@ -272,8 +277,37 @@ function Navigation( {
} = {},
hasIcon,
icon = 'handle',
overlayTemplatePartId: savedOverlayTemplatePartId,
} = attributes;

// Check if we're inside an overlay template part
const isInOverlayTemplatePart = useSelect( ( select ) => {
const { getCurrentPostType, getCurrentPostId } = unlock(
select( editorStore )
);
const { getEditedEntityRecord } = select( coreStore );
const postType = getCurrentPostType();
const postId = getCurrentPostId();

if ( postType !== TEMPLATE_PART_POST_TYPE || ! postId ) {
return false;
}

const templatePart = getEditedEntityRecord(
'postType',
TEMPLATE_PART_POST_TYPE,
postId
);

return templatePart?.area === 'overlay';
}, [] );

// Ignore overlay attributes if we're inside an overlay template part
const overlayMenu = isInOverlayTemplatePart ? 'never' : savedOverlayMenu;
const overlayTemplatePartId = isInOverlayTemplatePart
? undefined
: savedOverlayTemplatePartId;

const ref = attributes.ref;

const setRef = useCallback(
Expand Down Expand Up @@ -641,82 +675,91 @@ function Navigation( {

const dropdownMenuProps = useToolsPanelDropdownMenuProps();

// Get navigation function for overlay template parts
const onNavigateToEntityRecord = useSelect(
( select ) =>
select( blockEditorStore ).getSettings().onNavigateToEntityRecord,
[]
);

// Check if the experiment is enabled
const isExperimentEnabled =
typeof window !== 'undefined' &&
window.__experimentalNavigationOverlays;

const stylingInspectorControls = (
<>
<InspectorControls>
{ hasSubmenuIndicatorSetting && (
<ToolsPanel
label={ __( 'Display' ) }
resetAll={ () => {
setAttributes( {
showSubmenuIcon: true,
openSubmenusOnClick: false,
overlayMenu: 'mobile',
hasIcon: true,
icon: 'handle',
} );
} }
dropdownMenuProps={ dropdownMenuProps }
>
{ isResponsive && (
<>
<Button
__next40pxDefaultSize
className={ overlayMenuPreviewClasses }
onClick={ () => {
setOverlayMenuPreview(
! overlayMenuPreview
);
} }
aria-label={ __( 'Overlay menu controls' ) }
aria-controls={ overlayMenuPreviewId }
aria-expanded={ overlayMenuPreview }
{ ! isInOverlayTemplatePart && (
<InspectorControls>
<PanelBody title={ __( 'Overlay' ) } initialOpen={ true }>
<VStack spacing={ 4 }>
{ ! isExperimentEnabled && (
<Notice
status="warning"
isDismissible={ false }
>
{ hasIcon && (
<>
<OverlayMenuIcon icon={ icon } />
<Icon icon={ close } />
</>
) }
{ ! hasIcon && (
<>
<span>{ __( 'Menu' ) }</span>
<span>{ __( 'Close' ) }</span>
</>
{ __(
'Please enable the "Customizable Navigation Overlays" experiment in Gutenberg settings to test this feature.'
) }
</Button>
{ overlayMenuPreview && (
<VStack
id={ overlayMenuPreviewId }
spacing={ 4 }
style={ {
gridColumn: 'span 2',
</Notice>
) }
{ isResponsive && (
<>
<Button
__next40pxDefaultSize
className={ overlayMenuPreviewClasses }
onClick={ () => {
setOverlayMenuPreview(
! overlayMenuPreview
);
} }
aria-label={ __(
'Overlay menu controls'
) }
aria-controls={ overlayMenuPreviewId }
aria-expanded={ overlayMenuPreview }
>
<OverlayMenuPreview
setAttributes={ setAttributes }
hasIcon={ hasIcon }
icon={ icon }
hidden={ ! overlayMenuPreview }
/>
</VStack>
) }
</>
) }
{ hasIcon && (
<>
<OverlayMenuIcon
icon={ icon }
/>
<Icon icon={ close } />
</>
) }
{ ! hasIcon && (
<>
<span>{ __( 'Menu' ) }</span>
<span>{ __( 'Close' ) }</span>
</>
) }
</Button>
{ overlayMenuPreview && (
<VStack
id={ overlayMenuPreviewId }
spacing={ 4 }
style={ {
gridColumn: 'span 2',
} }
>
<OverlayMenuPreview
setAttributes={ setAttributes }
hasIcon={ hasIcon }
icon={ icon }
hidden={ ! overlayMenuPreview }
/>
</VStack>
) }
</>
) }

<ToolsPanelItem
hasValue={ () => overlayMenu !== 'mobile' }
label={ __( 'Overlay Menu' ) }
onDeselect={ () =>
setAttributes( { overlayMenu: 'mobile' } )
}
isShownByDefault
>
<ToggleGroupControl
__next40pxDefaultSize
__nextHasNoMarginBottom
label={ __( 'Overlay Menu' ) }
aria-label={ __( 'Configure overlay menu' ) }
label={ __( 'Overlay Visibility' ) }
aria-label={ __(
'Configure overlay visibility'
) }
value={ overlayMenu }
help={ __(
'Collapses the navigation options in a menu icon opening an overlay.'
Expand All @@ -739,8 +782,45 @@ function Navigation( {
label={ __( 'Always' ) }
/>
</ToggleGroupControl>
</ToolsPanelItem>

{ /*
* Hide custom overlay controls when overlay visibility is "Off".
* Attributes are preserved (not modified) so that if the user
* toggles back to "Mobile" or "Always", their configured overlay
* will still be available.
*
* Note: PHP rendering code will need to account for this situation
* and should not render custom overlays when overlayMenu is "never",
* even if overlayTemplatePartId is set.
*/ }
{ overlayMenu !== 'never' && (
<OverlaySelector
value={ overlayTemplatePartId }
onChange={ ( newValue ) => {
setAttributes( {
overlayTemplatePartId: newValue,
} );
} }
/>
) }
</VStack>
</PanelBody>
</InspectorControls>
) }
<InspectorControls>
{ hasSubmenuIndicatorSetting && (
<ToolsPanel
label={ __( 'Display' ) }
resetAll={ () => {
setAttributes( {
showSubmenuIcon: true,
openSubmenusOnClick: false,
hasIcon: true,
icon: 'handle',
} );
} }
dropdownMenuProps={ dropdownMenuProps }
>
{ hasSubmenus && (
<>
<h3 className="wp-block-navigation__submenu-header">
Expand Down Expand Up @@ -880,6 +960,8 @@ function Navigation( {
isHiddenByDefault={ isHiddenByDefault }
overlayBackgroundColor={ overlayBackgroundColor }
overlayTextColor={ overlayTextColor }
overlayTemplatePartId={ overlayTemplatePartId }
onNavigateToEntityRecord={ onNavigateToEntityRecord }
>
<UnsavedInnerBlocks
createNavigationMenu={ createNavigationMenu }
Expand Down Expand Up @@ -1042,6 +1124,10 @@ function Navigation( {
overlayBackgroundColor
}
overlayTextColor={ overlayTextColor }
overlayTemplatePartId={ overlayTemplatePartId }
onNavigateToEntityRecord={
onNavigateToEntityRecord
}
>
{ isEntityAvailable && (
<NavigationInnerBlocks
Expand Down
Loading
Loading