diff --git a/backport-changelog/7.0/10844.md b/backport-changelog/7.0/10844.md new file mode 100644 index 00000000000000..aba9dd7c89c285 --- /dev/null +++ b/backport-changelog/7.0/10844.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/10844 + +* https://github.com/WordPress/gutenberg/pull/74968 diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 29e4dfd1c33296..52192006916819 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -548,7 +548,6 @@ Add a page, link, or another item to your navigation. ([Source](https://github.c A customizable button to close overlays. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/navigation-overlay-close)) - **Name:** core/navigation-overlay-close -- **Experimental:** true - **Category:** design - **Supports:** color (background, text, ~~gradients~~), spacing (padding), typography (fontSize, lineHeight) - **Attributes:** displayMode, text diff --git a/lib/compat/wordpress-7.0/rest-api.php b/lib/compat/wordpress-7.0/rest-api.php index 285dfbc24e8df6..9bffd0971b0ba1 100644 --- a/lib/compat/wordpress-7.0/rest-api.php +++ b/lib/compat/wordpress-7.0/rest-api.php @@ -49,25 +49,23 @@ function gutenberg_modify_wp_template_part_post_type_args_7_0( $args ) { add_filter( 'register_wp_template_part_post_type_args', 'gutenberg_modify_wp_template_part_post_type_args_7_0' ); /** - * Registers the 'navigation-overlay' template part area when the experiment is enabled. + * Registers the 'navigation-overlay' template part area. * * @param array $areas Array of template part area definitions. * @return array Modified array of template part area definitions. */ -if ( gutenberg_is_experiment_enabled( 'gutenberg-customizable-navigation-overlays' ) ) { - function gutenberg_register_overlay_template_part_area( $areas ) { - $areas[] = array( - 'area' => 'navigation-overlay', - 'label' => __( 'Navigation Overlay', 'gutenberg' ), - 'description' => __( 'Custom overlay area for navigation overlays.', 'gutenberg' ), - 'icon' => 'overlay', - 'area_tag' => 'div', - ); +function gutenberg_register_overlay_template_part_area( $areas ) { + $areas[] = array( + 'area' => 'navigation-overlay', + 'label' => __( 'Navigation 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' ); + return $areas; } +add_filter( 'default_wp_template_part_areas', 'gutenberg_register_overlay_template_part_area' ); /** * Adds user global styles link relation to all theme responses. diff --git a/lib/experimental/editor-settings.php b/lib/experimental/editor-settings.php index d3cc0612e2adeb..9c90acc005c81d 100644 --- a/lib/experimental/editor-settings.php +++ b/lib/experimental/editor-settings.php @@ -31,9 +31,6 @@ function gutenberg_enable_experiments() { if ( $gutenberg_experiments && array_key_exists( 'gutenberg-content-only-inspector-fields', $gutenberg_experiments ) ) { wp_add_inline_script( 'wp-block-editor', 'window.__experimentalContentOnlyInspectorFields = true', 'before' ); } - if ( $gutenberg_experiments && array_key_exists( 'gutenberg-customizable-navigation-overlays', $gutenberg_experiments ) ) { - wp_add_inline_script( 'wp-block-editor', 'window.__experimentalNavigationOverlays = true', 'before' ); - } if ( gutenberg_is_experiment_enabled( 'active_templates' ) ) { wp_add_inline_script( 'wp-block-editor', 'window.__experimentalTemplateActivate = true', 'before' ); } diff --git a/lib/experiments-page.php b/lib/experiments-page.php index f3c5066f9e38cd..2d4149014e627f 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -197,18 +197,6 @@ function gutenberg_initialize_experiments_settings() { ) ); - add_settings_field( - 'gutenberg-customizable-navigation-overlays', - __( 'Customizable Navigation Overlays', 'gutenberg' ), - 'gutenberg_display_experiment_field', - 'gutenberg-experiments', - 'gutenberg_experiments_section', - array( - 'label' => __( 'Enables custom mobile overlay design and content control for Navigation blocks, allowing you to create flexible, professional menu experiences.', 'gutenberg' ), - 'id' => 'gutenberg-customizable-navigation-overlays', - ) - ); - add_settings_field( 'gutenberg-extensible-site-editor', __( 'Extensible Site Editor', 'gutenberg' ), diff --git a/lib/load.php b/lib/load.php index c0ef5891035584..783c3f488a7178 100644 --- a/lib/load.php +++ b/lib/load.php @@ -200,10 +200,8 @@ function gutenberg_is_experiment_enabled( $name ) { Gutenberg_Interactivity_API_Full_Page_Navigation::instance(); } -// Block patterns (only load when navigation overlays experiment is enabled). -if ( gutenberg_is_experiment_enabled( 'gutenberg-customizable-navigation-overlays' ) ) { - require __DIR__ . '/experimental/overlay-patterns.php'; -} +// Block patterns for navigation overlays. +require __DIR__ . '/overlay-patterns.php'; if ( gutenberg_is_experiment_enabled( 'gutenberg-svg-icon-registry' ) ) { require __DIR__ . '/experimental/class-wp-icons-registry.php'; diff --git a/lib/experimental/overlay-patterns.php b/lib/overlay-patterns.php similarity index 92% rename from lib/experimental/overlay-patterns.php rename to lib/overlay-patterns.php index 74e1dad99bbdb0..195999bb2fea8a 100644 --- a/lib/experimental/overlay-patterns.php +++ b/lib/overlay-patterns.php @@ -8,23 +8,27 @@ /** * Registers block patterns for navigation overlays. * - * This function adds patterns that are specific to the navigation overlays - * experiment. It runs after core patterns are registered to ensure all patterns + * This function adds patterns that are specific to navigation overlays. + * It runs after core patterns are registered to ensure all patterns * are available. * * @since 6.0.0 */ function gutenberg_register_overlay_block_patterns() { - register_block_pattern_category( - 'navigation', - array( - 'label' => _x( 'Navigation', 'Block pattern category', 'gutenberg' ), - 'description' => _x( 'Display your website navigation.', 'Block pattern category', 'gutenberg' ), - ) - ); + // Register category only if it doesn't exist in core. + $category_registry = WP_Block_Pattern_Categories_Registry::get_instance(); + if ( ! $category_registry->is_registered( 'navigation' ) ) { + register_block_pattern_category( + 'navigation', + array( + 'label' => _x( 'Navigation', 'Block pattern category', 'gutenberg' ), + 'description' => _x( 'Display your website navigation.', 'Block pattern category', 'gutenberg' ), + ) + ); + } register_block_pattern( - 'gutenberg/navigation-overlay', + 'core/navigation-overlay', array( 'title' => __( 'Navigation Overlay', 'gutenberg' ), 'description' => _x( 'A simple pattern with a navigation block and a navigation overlay close button.', 'Block pattern description', 'gutenberg' ), @@ -37,11 +41,12 @@ function gutenberg_register_overlay_block_patterns() { ', 'categories' => array( 'navigation' ), 'blockTypes' => array( 'core/template-part/navigation-overlay' ), + 'source' => 'core', ) ); register_block_pattern( - 'gutenberg/navigation-overlay-black-bg', + 'core/navigation-overlay-black-bg', array( 'title' => __( 'Overlay with black background', 'gutenberg' ), 'description' => _x( 'A navigation overlay with black background and big white text', 'Block pattern description', 'gutenberg' ), @@ -54,10 +59,11 @@ function gutenberg_register_overlay_block_patterns() { ', 'categories' => array( 'navigation' ), 'blockTypes' => array( 'core/template-part/navigation-overlay' ), + 'source' => 'core', ) ); register_block_pattern( - 'gutenberg/navigation-overlay-accent-bg', + 'core/navigation-overlay-accent-bg', array( 'title' => __( 'Overlay with orange background', 'gutenberg' ), 'description' => _x( 'A navigation overlay with orange background site title and tagline', 'Block pattern description', 'gutenberg' ), @@ -80,10 +86,11 @@ function gutenberg_register_overlay_block_patterns() { ', 'categories' => array( 'navigation' ), 'blockTypes' => array( 'core/template-part/navigation-overlay' ), + 'source' => 'core', ) ); register_block_pattern( - 'gutenberg/navigation-overlay-centered-with-extras', + 'core/navigation-overlay-centered-with-extras', array( 'title' => __( 'Overlay with site info and CTA', 'gutenberg' ), 'description' => _x( 'A navigation overlay with vertically and horizontally centered navigation, site info, and a CTA', 'Block pattern description', 'gutenberg' ), @@ -122,10 +129,11 @@ function gutenberg_register_overlay_block_patterns() { ', 'categories' => array( 'navigation' ), 'blockTypes' => array( 'core/template-part/navigation-overlay' ), + 'source' => 'core', ) ); register_block_pattern( - 'gutenberg/navigation-overlay-centered', + 'core/navigation-overlay-centered', array( 'title' => __( 'Overlay with centered navigation', 'gutenberg' ), 'description' => _x( 'A navigation overlay with vertically and horizontally centered navigation', 'Block pattern description', 'gutenberg' ), @@ -140,6 +148,7 @@ function gutenberg_register_overlay_block_patterns() { ', 'categories' => array( 'navigation' ), 'blockTypes' => array( 'core/template-part/navigation-overlay' ), + 'source' => 'core', ) ); } diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js index 0a5f8a35525eba..3de895cdefa780 100644 --- a/packages/block-library/src/index.js +++ b/packages/block-library/src/index.js @@ -266,6 +266,7 @@ const getAllBlocks = () => { tableOfContents, homeLink, logInOut, + navigationOverlayClose, termCount, termDescription, termName, @@ -291,10 +292,6 @@ const getAllBlocks = () => { blocks.push( formSubmissionNotification ); } - if ( window?.__experimentalNavigationOverlays ) { - blocks.push( navigationOverlayClose ); - } - if ( window?.__experimentalEnableBlockExperiments ) { blocks.push( playlist ); blocks.push( playlistTrack ); diff --git a/packages/block-library/src/navigation-overlay-close/block.json b/packages/block-library/src/navigation-overlay-close/block.json index e08ceff76edebc..39bf2ce75b99a0 100644 --- a/packages/block-library/src/navigation-overlay-close/block.json +++ b/packages/block-library/src/navigation-overlay-close/block.json @@ -1,6 +1,5 @@ { "$schema": "https://schemas.wp.org/trunk/block.json", - "__experimental": true, "apiVersion": 3, "name": "core/navigation-overlay-close", "title": "Navigation Overlay Close", diff --git a/packages/block-library/src/navigation/edit/index.js b/packages/block-library/src/navigation/edit/index.js index c0a05b6a9d3a21..fe74a4eee37780 100644 --- a/packages/block-library/src/navigation/edit/index.js +++ b/packages/block-library/src/navigation/edit/index.js @@ -65,8 +65,6 @@ import NavigationMenuDeleteControl from './navigation-menu-delete-control'; import useNavigationNotice from './use-navigation-notice'; import OverlayMenuPreview from './overlay-menu-preview'; import OverlayPanel from './overlay-panel'; -import OverlayVisibilityControl from './overlay-visibility-control'; -import OverlayMenuPreviewButton from './overlay-menu-preview-button'; import useConvertClassicToBlockMenu, { CLASSIC_MENU_CONVERSION_ERROR, CLASSIC_MENU_CONVERSION_PENDING, @@ -340,10 +338,6 @@ function Navigation( { const blockEditingMode = useBlockEditingMode(); - const isOverlayExperimentEnabled = - typeof window !== 'undefined' && - window.__experimentalNavigationOverlays === true; - // Preload classic menus, so that they don't suddenly pop-in when viewing // the Select Menu dropdown. const { menus: classicMenus } = useNavigationEntities(); @@ -755,7 +749,7 @@ function Navigation( { const stylingInspectorControls = ( <> - { ( ! isOverlayExperimentEnabled || hasSubmenus ) && ( + { hasSubmenus && ( { @@ -769,50 +763,6 @@ function Navigation( { } } dropdownMenuProps={ dropdownMenuProps } > - { ! isOverlayExperimentEnabled && ( - <> - { isResponsive && ( - - ) } - - overlayMenu !== 'mobile' } - label={ __( 'Overlay Visibility' ) } - onDeselect={ () => - setAttributes( { - overlayMenu: 'mobile', - } ) - } - isShownByDefault - > - - - - ) } - { hasSubmenus && ( <>

@@ -919,7 +869,7 @@ function Navigation( { ) } - { isOverlayExperimentEnabled && ! isWithinOverlay && ( + { ! isWithinOverlay && ( { } ); mockGetPatternBySlug.mockReturnValue( { - name: 'gutenberg/navigation-overlay', + name: 'core/navigation-overlay', title: 'Navigation Overlay', content: '
', @@ -199,7 +199,7 @@ describe( 'useCreateOverlayTemplatePart', () => { } ); expect( mockGetPatternBySlug ).toHaveBeenCalledWith( - 'gutenberg/navigation-overlay' + 'core/navigation-overlay' ); expect( parse ).toHaveBeenCalledWith( mockGetPatternBySlug().content, { diff --git a/packages/block-library/src/navigation/edit/use-create-overlay.js b/packages/block-library/src/navigation/edit/use-create-overlay.js index c1cafa778783f3..370bbcbe1c0580 100644 --- a/packages/block-library/src/navigation/edit/use-create-overlay.js +++ b/packages/block-library/src/navigation/edit/use-create-overlay.js @@ -27,7 +27,7 @@ export default function useCreateOverlayTemplatePart( overlayTemplateParts ) { const pattern = useSelect( ( select ) => unlock( select( blockEditorStore ) ).getPatternBySlug( - 'gutenberg/navigation-overlay' + 'core/navigation-overlay' ), [] ); diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php index c8c7384208b367..189b3d7cc11b50 100644 --- a/packages/block-library/src/navigation/index.php +++ b/packages/block-library/src/navigation/index.php @@ -72,17 +72,6 @@ class WP_Navigation_Block_Renderer { */ private static $seen_menu_names = array(); - /** - * Returns whether the navigation overlay experiment is enabled. - * - * @since 6.5.0 - * - * @return bool Returns whether the navigation overlay experiment is enabled. - */ - private static function is_overlay_experiment_enabled() { - $gutenberg_experiments = get_option( 'gutenberg-experiments' ); - return $gutenberg_experiments && array_key_exists( 'gutenberg-customizable-navigation-overlays', $gutenberg_experiments ); - } /** * Returns whether or not this is responsive navigation. @@ -652,7 +641,6 @@ private static function get_responsive_container_classes( $is_hidden_by_default, } if ( $has_custom_overlay ) { - // Only add the disable-default-overlay class if experiment is enabled AND overlay blocks actually rendered. $responsive_container_classes[] = 'disable-default-overlay'; } else { // Don't apply overlay color classes if using a custom overlay template part. @@ -693,39 +681,35 @@ private static function get_responsive_container_markup( $attributes, $inner_blo $is_hidden_by_default = isset( $attributes['overlayMenu'] ) && 'always' === $attributes['overlayMenu']; - // Set-up variables for the custom overlay experiment. - // Values are set to "off" so they don't affect the default behavior. - $is_overlay_experiment_enabled = static::is_overlay_experiment_enabled(); + // Set-up variables for custom overlays. $has_custom_overlay = false; $close_button_markup = ''; $has_custom_overlay_close_block = false; $overlay_blocks_html = ''; $custom_overlay_markup = ''; - if ( $is_overlay_experiment_enabled ) { - // Check if an overlay template part is selected and render it. - // This needs to happen before building classes so we know if overlay blocks actually exist. - if ( ! empty( $attributes['overlay'] ) ) { - // Get blocks from the overlay template part. - $overlay_blocks = static::get_overlay_blocks_from_template_part( $attributes['overlay'], $attributes ); - // Check if overlay contains a navigation-overlay-close block. - $has_custom_overlay_close_block = block_core_navigation_block_tree_has_block_type( - $overlay_blocks, - 'core/navigation-overlay-close', - array( 'core/navigation' ) // Skip navigation blocks, as they cannot contain an overlay close block - ); - // Render template part blocks directly without navigation container wrapper. - $overlay_blocks_html = static::get_template_part_blocks_html( $overlay_blocks ); - // Add Interactivity API directives to the overlay close block if present. - if ( $has_custom_overlay_close_block && $is_interactive ) { - $tags = new WP_HTML_Tag_Processor( $overlay_blocks_html ); - $overlay_blocks_html = block_core_navigation_add_directives_to_overlay_close( $tags ); - } + // Check if an overlay template part is selected and render it. + // This needs to happen before building classes so we know if overlay blocks actually exist. + if ( ! empty( $attributes['overlay'] ) ) { + // Get blocks from the overlay template part. + $overlay_blocks = static::get_overlay_blocks_from_template_part( $attributes['overlay'], $attributes ); + // Check if overlay contains a navigation-overlay-close block. + $has_custom_overlay_close_block = block_core_navigation_block_tree_has_block_type( + $overlay_blocks, + 'core/navigation-overlay-close', + array( 'core/navigation' ) // Skip navigation blocks, as they cannot contain an overlay close block + ); + // Render template part blocks directly without navigation container wrapper. + $overlay_blocks_html = static::get_template_part_blocks_html( $overlay_blocks ); + // Add Interactivity API directives to the overlay close block if present. + if ( $has_custom_overlay_close_block && $is_interactive ) { + $tags = new WP_HTML_Tag_Processor( $overlay_blocks_html ); + $overlay_blocks_html = block_core_navigation_add_directives_to_overlay_close( $tags ); } - - $has_custom_overlay = ! empty( $overlay_blocks_html ); } + $has_custom_overlay = ! empty( $overlay_blocks_html ); + $responsive_container_classes = static::get_responsive_container_classes( $is_hidden_by_default, $has_custom_overlay, $colors ); $open_button_classes = array( diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index 53d9e3852416cd..5f16e8f8d6c30a 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -40,22 +40,7 @@ import { useTemplatePartArea, } from './utils/hooks'; -const SUPPORTED_AREAS = [ 'header', 'footer' ]; - -/** - * Returns the list of supported template part areas for pattern replacement. - * Includes 'overlay' only if the navigation overlays experiment is enabled. - * - * @return {string[]} Array of supported area names. - */ -function getSupportedAreas() { - const isOverlayExperimentEnabled = - typeof window !== 'undefined' && - window.__experimentalNavigationOverlays === true; - return isOverlayExperimentEnabled - ? [ ...SUPPORTED_AREAS, 'navigation-overlay' ] - : SUPPORTED_AREAS; -} +const SUPPORTED_AREAS = [ 'header', 'footer', 'navigation-overlay' ]; function ReplaceButton( { isEntityAvailable, @@ -71,9 +56,10 @@ function ReplaceButton( { templatePartId ); const hasReplacements = !! templateParts.length; - const supportedAreas = getSupportedAreas(); const canReplace = - isEntityAvailable && hasReplacements && supportedAreas.includes( area ); + isEntityAvailable && + hasReplacements && + SUPPORTED_AREAS.includes( area ); if ( ! canReplace ) { return null; @@ -96,11 +82,10 @@ function TemplatesList( { area, clientId, isEntityAvailable, onSelect } ) { // This hook fetches patterns, so don't run it unconditionally in the main // edit function! const blockPatterns = useAlternativeBlockPatterns( area, clientId ); - const supportedAreas = getSupportedAreas(); const canReplace = isEntityAvailable && !! blockPatterns.length && - supportedAreas.includes( area ); + SUPPORTED_AREAS.includes( area ); if ( ! canReplace ) { return null; diff --git a/test/integration/fixtures/blocks/core__navigation-overlay-close.html b/test/integration/fixtures/blocks/core__navigation-overlay-close.html new file mode 100644 index 00000000000000..900aed9a53399e --- /dev/null +++ b/test/integration/fixtures/blocks/core__navigation-overlay-close.html @@ -0,0 +1 @@ + diff --git a/test/integration/fixtures/blocks/core__navigation-overlay-close.json b/test/integration/fixtures/blocks/core__navigation-overlay-close.json new file mode 100644 index 00000000000000..1dbf1ca196fa14 --- /dev/null +++ b/test/integration/fixtures/blocks/core__navigation-overlay-close.json @@ -0,0 +1,10 @@ +[ + { + "name": "core/navigation-overlay-close", + "isValid": true, + "attributes": { + "displayMode": "icon" + }, + "innerBlocks": [] + } +] diff --git a/test/integration/fixtures/blocks/core__navigation-overlay-close.parsed.json b/test/integration/fixtures/blocks/core__navigation-overlay-close.parsed.json new file mode 100644 index 00000000000000..ae1e322eec96b7 --- /dev/null +++ b/test/integration/fixtures/blocks/core__navigation-overlay-close.parsed.json @@ -0,0 +1,9 @@ +[ + { + "blockName": "core/navigation-overlay-close", + "attrs": {}, + "innerBlocks": [], + "innerHTML": "", + "innerContent": [] + } +] diff --git a/test/integration/fixtures/blocks/core__navigation-overlay-close.serialized.html b/test/integration/fixtures/blocks/core__navigation-overlay-close.serialized.html new file mode 100644 index 00000000000000..900aed9a53399e --- /dev/null +++ b/test/integration/fixtures/blocks/core__navigation-overlay-close.serialized.html @@ -0,0 +1 @@ +