Skip to content
Merged
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
Fix submenu colors for imported classic menus by ensure isTopLevelLin…
…k attribute is set correctly
  • Loading branch information
talldan committed Sep 20, 2022
commit 676b4b8768d990711448eb4d4a91873957201cb6
61 changes: 39 additions & 22 deletions packages/block-library/src/navigation/menu-items-to-blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ export default function menuItemsToBlocks( menuItems ) {
* A recursive function that maps menu item nodes to blocks.
*
* @param {WPNavMenuItem[]} menuItems An array of WPNavMenuItem items.
* @param {number} level An integer representing the nesting level.
* @return {Object} Object containing innerBlocks and mapping.
*/
function mapMenuItemsToBlocks( menuItems ) {
function mapMenuItemsToBlocks( menuItems, level = 0 ) {
let mapping = {};

// The menuItem should be in menu_order sort order.
Expand All @@ -52,14 +53,22 @@ function mapMenuItemsToBlocks( menuItems ) {
return block;
}

const attributes = menuItemToBlockAttributes( menuItem );
const blockType = menuItem.children?.length
? 'core/navigation-submenu'
: 'core/navigation-link';

const attributes = menuItemToBlockAttributes(
menuItem,
blockType,
level
);

// If there are children recurse to build those nested blocks.
const {
innerBlocks: nestedBlocks = [], // alias to avoid shadowing
mapping: nestedMapping = {}, // alias to avoid shadowing
} = menuItem.children?.length
? mapMenuItemsToBlocks( menuItem.children )
? mapMenuItemsToBlocks( menuItem.children, level + 1 )
: {};

// Update parent mapping with nested mapping.
Expand All @@ -68,10 +77,6 @@ function mapMenuItemsToBlocks( menuItems ) {
...nestedMapping,
};

const blockType = menuItem.children?.length
? 'core/navigation-submenu'
: 'core/navigation-link';

// Create block with nested "innerBlocks".
const block = createBlock( blockType, attributes, nestedBlocks );

Expand Down Expand Up @@ -111,23 +116,29 @@ function mapMenuItemsToBlocks( menuItems ) {
/**
* Convert block attributes to menu item.
*
* @param {WPNavMenuItem} menuItem the menu item to be converted to block attributes.
* @param {WPNavMenuItem} menuItem the menu item to be converted to block attributes.
* @param {string} blockType The block type.
* @param {number} level An integer representing the nesting level.
* @return {Object} the block attributes converted from the WPNavMenuItem item.
*/
function menuItemToBlockAttributes( {
title: menuItemTitleField,
xfn,
classes,
// eslint-disable-next-line camelcase
attr_title,
object,
// eslint-disable-next-line camelcase
object_id,
description,
url,
type: menuItemTypeField,
target,
} ) {
function menuItemToBlockAttributes(
{
title: menuItemTitleField,
xfn,
classes,
// eslint-disable-next-line camelcase
attr_title,
object,
// eslint-disable-next-line camelcase
object_id,
description,
url,
type: menuItemTypeField,
target,
},
blockType,
level
) {
// For historical reasons, the `core/navigation-link` variation type is `tag`
// whereas WP Core expects `post_tag` as the `object` type.
// To avoid writing a block migration we perform a conversion here.
Expand Down Expand Up @@ -166,6 +177,12 @@ function menuItemToBlockAttributes( {
...( target === '_blank' && {
opensInNewTab: true,
} ),
...( blockType === 'core/navigation-submenu' && {
isTopLevelItem: level === 0,
} ),
...( blockType === 'core/navigation-link' && {
isTopLevelLink: level === 0,
} ),
Comment on lines +183 to +185
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't believe it's named differently 😭

};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,31 +189,36 @@ describe( 'converting menu items to blocks', () => {
name: 'core/navigation-submenu',
attributes: expect.objectContaining( {
label: 'Top Level',
isTopLevelItem: true,
} ),
innerBlocks: [
expect.objectContaining( {
name: 'core/navigation-link',
attributes: expect.objectContaining( {
label: 'Child 1',
isTopLevelLink: false,
} ),
innerBlocks: [],
} ),
expect.objectContaining( {
name: 'core/navigation-submenu',
attributes: expect.objectContaining( {
label: 'Child 2',
isTopLevelItem: false,
} ),
innerBlocks: [
expect.objectContaining( {
name: 'core/navigation-submenu',
attributes: expect.objectContaining( {
label: 'Sub Child',
isTopLevelItem: false,
} ),
innerBlocks: [
expect.objectContaining( {
name: 'core/navigation-link',
attributes: expect.objectContaining( {
label: 'Sub Sub Child',
isTopLevelLink: false,
} ),
innerBlocks: [],
} ),
Expand All @@ -227,6 +232,7 @@ describe( 'converting menu items to blocks', () => {
name: 'core/navigation-link',
attributes: expect.objectContaining( {
label: 'Top Level 2',
isTopLevelLink: true,
} ),
innerBlocks: [],
} ),
Expand Down