Skip to content

Commit

Permalink
Navigation Block: Add Color Options for Submenus (#31149)
Browse files Browse the repository at this point in the history
Closes #29963

Co-authored-by: Marcus Kazmierczak <[email protected]>
Co-authored-by: jasmussen <[email protected]>
  • Loading branch information
3 people authored Jul 12, 2021
1 parent dc1821f commit e7566c7
Show file tree
Hide file tree
Showing 12 changed files with 504 additions and 99 deletions.
7 changes: 7 additions & 0 deletions packages/block-library/src/navigation-link/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,20 @@
},
"kind": {
"type": "string"
},
"isTopLevelLink": {
"type": "boolean"
}
},
"usesContext": [
"textColor",
"customTextColor",
"backgroundColor",
"customBackgroundColor",
"overlayTextColor",
"customOverlayTextColor",
"overlayBackgroundColor",
"customOverlayBackgroundColor",
"fontSize",
"customFontSize",
"showSubmenuIcon",
Expand Down
102 changes: 95 additions & 7 deletions packages/block-library/src/navigation-link/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
__experimentalLinkControl as LinkControl,
useBlockProps,
store as blockEditorStore,
getColorClassName,
} from '@wordpress/block-editor';
import { isURL, prependHTTP, safeDecodeURI } from '@wordpress/url';
import {
Expand Down Expand Up @@ -133,6 +134,61 @@ function getSuggestionsQuery( type, kind ) {
}
}

/**
* Determine the colors for a menu.
*
* Order of priority is:
* 1: Overlay custom colors (if submenu)
* 2: Overlay theme colors (if submenu)
* 3: Custom colors
* 4: Theme colors
* 5: Global styles
*
* @param {Object} context
* @param {boolean} isSubMenu
*/
function getColors( context, isSubMenu ) {
const {
textColor,
customTextColor,
backgroundColor,
customBackgroundColor,
overlayTextColor,
customOverlayTextColor,
overlayBackgroundColor,
customOverlayBackgroundColor,
style,
} = context;

const colors = {};

if ( isSubMenu && !! customOverlayTextColor ) {
colors.customTextColor = customOverlayTextColor;
} else if ( isSubMenu && !! overlayTextColor ) {
colors.textColor = overlayTextColor;
} else if ( !! customTextColor ) {
colors.customTextColor = customTextColor;
} else if ( !! textColor ) {
colors.textColor = textColor;
} else if ( !! style?.color?.text ) {
colors.customTextColor = style.color.text;
}

if ( isSubMenu && !! customOverlayBackgroundColor ) {
colors.customBackgroundColor = customOverlayBackgroundColor;
} else if ( isSubMenu && !! overlayBackgroundColor ) {
colors.backgroundColor = overlayBackgroundColor;
} else if ( !! customBackgroundColor ) {
colors.customBackgroundColor = customBackgroundColor;
} else if ( !! backgroundColor ) {
colors.backgroundColor = backgroundColor;
} else if ( !! style?.color?.background ) {
colors.customTextColor = style.color.background;
}

return colors;
}

/**
* @typedef {'post-type'|'custom'|'taxonomy'|'post-type-archive'} WPNavigationLinkKind
*/
Expand Down Expand Up @@ -234,7 +290,7 @@ export default function NavigationLinkEdit( {
url,
opensInNewTab,
};
const { textColor, backgroundColor, style, showSubmenuIcon } = context;
const { showSubmenuIcon } = context;
const { saveEntityRecord } = useDispatch( coreStore );
const { insertBlock } = useDispatch( blockEditorStore );
const [ isLinkOpen, setIsLinkOpen ] = useState( false );
Expand All @@ -245,6 +301,7 @@ export default function NavigationLinkEdit( {

const {
isAtMaxNesting,
isTopLevelLink,
isParentOfSelectedBlock,
isImmediateParentOfSelectedBlock,
hasDescendants,
Expand All @@ -270,6 +327,8 @@ export default function NavigationLinkEdit( {
isAtMaxNesting:
getBlockParentsByBlockName( clientId, name ).length >=
MAX_NESTING,
isTopLevelLink:
getBlockParentsByBlockName( clientId, name ).length === 0,
isParentOfSelectedBlock: hasSelectedInnerBlock(
clientId,
true
Expand All @@ -296,6 +355,9 @@ export default function NavigationLinkEdit( {
[ clientId ]
);

// Store the colors from context as attributes for rendering
useEffect( () => setAttributes( { isTopLevelLink } ), [ isTopLevelLink ] );

/**
* Insert a link block when submenu is added.
*/
Expand Down Expand Up @@ -381,33 +443,59 @@ export default function NavigationLinkEdit( {
};
}

const {
textColor,
customTextColor,
backgroundColor,
customBackgroundColor,
} = getColors( context, ! isTopLevelLink );

const blockProps = useBlockProps( {
ref: listItemRef,
className: classnames( {
'is-editing': isSelected || isParentOfSelectedBlock,
'is-dragging-within': isDraggingWithin,
'has-link': !! url,
'has-child': hasDescendants,
'has-text-color': !! textColor || !! style?.color?.text,
[ `has-${ textColor }-color` ]: !! textColor,
'has-background': !! backgroundColor || !! style?.color?.background,
[ `has-${ backgroundColor }-background-color` ]: !! backgroundColor,
'has-text-color': !! textColor || !! customTextColor,
[ getColorClassName( 'color', textColor ) ]: !! textColor,
'has-background': !! backgroundColor || customBackgroundColor,
[ getColorClassName(
'background-color',
backgroundColor
) ]: !! backgroundColor,
} ),
style: {
color: style?.color?.text,
backgroundColor: style?.color?.background,
color: ! textColor && customTextColor,
backgroundColor: ! backgroundColor && customBackgroundColor,
},
} );

if ( ! url ) {
blockProps.onClick = () => setIsLinkOpen( true );
}

// Always use overlay colors for submenus
const innerBlocksColors = getColors( context, true );
const innerBlocksProps = useInnerBlocksProps(
{
className: classnames( 'wp-block-navigation-link__container', {
'is-parent-of-selected-block': isParentOfSelectedBlock,
'has-text-color': !! (
innerBlocksColors.textColor ||
innerBlocksColors.customTextColor
),
[ `has-${ innerBlocksColors.textColor }-color` ]: !! innerBlocksColors.textColor,
'has-background': !! (
innerBlocksColors.backgroundColor ||
innerBlocksColors.customBackgroundColor
),
[ `has-${ innerBlocksColors.backgroundColor }-background-color` ]: !! innerBlocksColors.backgroundColor,
} ),
style: {
color: innerBlocksColors.customTextColor,
backgroundColor: innerBlocksColors.customBackgroundColor,
},
},
{
allowedBlocks: ALLOWED_BLOCKS,
Expand Down
69 changes: 44 additions & 25 deletions packages/block-library/src/navigation-link/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,68 @@
* Build an array with CSS classes and inline styles defining the colors
* which will be applied to the navigation markup in the front-end.
*
* @param array $context Navigation block context.
* @param array $context Navigation block context.
* @param array $attributes Block attributes.
* @return array Colors CSS classes and inline styles.
*/
function block_core_navigation_link_build_css_colors( $context ) {
function block_core_navigation_link_build_css_colors( $context, $attributes ) {
$colors = array(
'css_classes' => array(),
'inline_styles' => '',
);

// Text color.
$has_named_text_color = array_key_exists( 'textColor', $context );
$has_custom_text_color = isset( $context['style']['color']['text'] );
$is_sub_menu = isset( $attributes['isTopLevelLink'] ) ? ( ! $attributes['isTopLevelLink'] ) : false;

// If has text color.
if ( $has_custom_text_color || $has_named_text_color ) {
// Add has-text-color class.
$colors['css_classes'][] = 'has-text-color';
// Text color.
$named_text_color = null;
$custom_text_color = null;

if ( $is_sub_menu && array_key_exists( 'customOverlayTextColor', $context ) ) {
$custom_text_color = $context['customOverlayTextColor'];
} elseif ( $is_sub_menu && array_key_exists( 'overlayTextColor', $context ) ) {
$named_text_color = $context['overlayTextColor'];
} elseif ( array_key_exists( 'customTextColor', $context ) ) {
$custom_text_color = $context['customTextColor'];
} elseif ( array_key_exists( 'textColor', $context ) ) {
$named_text_color = $context['textColor'];
} elseif ( isset( $context['style']['color']['text'] ) ) {
$custom_text_color = $context['style']['color']['text'];
}

if ( $has_named_text_color ) {
// If has text color.
if ( ! is_null( $named_text_color ) ) {
// Add the color class.
$colors['css_classes'][] = sprintf( 'has-%s-color', $context['textColor'] );
} elseif ( $has_custom_text_color ) {
array_push( $colors['css_classes'], 'has-text-color', sprintf( 'has-%s-color', $named_text_color ) );
} elseif ( ! is_null( $custom_text_color ) ) {
// Add the custom color inline style.
$colors['inline_styles'] .= sprintf( 'color: %s;', $context['style']['color']['text'] );
$colors['css_classes'][] = 'has-text-color';
$colors['inline_styles'] .= sprintf( 'color: %s;', $custom_text_color );
}

// Background color.
$has_named_background_color = array_key_exists( 'backgroundColor', $context );
$has_custom_background_color = isset( $context['style']['color']['background'] );

// If has background color.
if ( $has_custom_background_color || $has_named_background_color ) {
// Add has-background class.
$colors['css_classes'][] = 'has-background';
$named_background_color = null;
$custom_background_color = null;

if ( $is_sub_menu && array_key_exists( 'customOverlayBackgroundColor', $context ) ) {
$custom_background_color = $context['customOverlayBackgroundColor'];
} elseif ( $is_sub_menu && array_key_exists( 'overlayBackgroundColor', $context ) ) {
$named_background_color = $context['overlayBackgroundColor'];
} elseif ( array_key_exists( 'customBackgroundColor', $context ) ) {
$custom_background_color = $context['customBackgroundColor'];
} elseif ( array_key_exists( 'backgroundColor', $context ) ) {
$named_background_color = $context['backgroundColor'];
} elseif ( isset( $context['style']['color']['background'] ) ) {
$custom_background_color = $context['style']['color']['background'];
}

if ( $has_named_background_color ) {
// If has background color.
if ( ! is_null( $named_background_color ) ) {
// Add the background-color class.
$colors['css_classes'][] = sprintf( 'has-%s-background-color', $context['backgroundColor'] );
} elseif ( $has_custom_background_color ) {
array_push( $colors['css_classes'], 'has-background', sprintf( 'has-%s-background-color', $named_background_color ) );
} elseif ( ! is_null( $custom_background_color ) ) {
// Add the custom background-color inline style.
$colors['inline_styles'] .= sprintf( 'background-color: %s;', $context['style']['color']['background'] );
$colors['css_classes'][] = 'has-background';
$colors['inline_styles'] .= sprintf( 'background-color: %s;', $custom_background_color );
}

return $colors;
Expand Down Expand Up @@ -121,7 +140,7 @@ function render_block_core_navigation_link( $attributes, $content, $block ) {
return '';
}

$colors = block_core_navigation_link_build_css_colors( $block->context );
$colors = block_core_navigation_link_build_css_colors( $block->context, $attributes );
$font_sizes = block_core_navigation_link_build_css_font_sizes( $block->context );
$classes = array_merge(
$colors['css_classes'],
Expand Down
19 changes: 17 additions & 2 deletions packages/block-library/src/navigation/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,29 @@
},
"__unstableLocation": {
"type": "string"
},
"overlayBackgroundColor": {
"type": "string"
},
"customOverlayBackgroundColor": {
"type": "string"
},
"overlayTextColor": {
"type": "string"
},
"customOverlayTextColor": {
"type": "string"
}
},
"providesContext": {
"textColor": "textColor",
"customTextColor": "customTextColor",
"backgroundColor": "backgroundColor",
"customBackgroundColor": "customBackgroundColor",
"overlayTextColor": "overlayTextColor",
"customOverlayTextColor": "customOverlayTextColor",
"overlayBackgroundColor": "overlayBackgroundColor",
"customOverlayBackgroundColor": "customOverlayBackgroundColor",
"fontSize": "fontSize",
"customFontSize": "customFontSize",
"showSubmenuIcon": "showSubmenuIcon",
Expand All @@ -67,8 +83,7 @@
"__experimentalTextTransform": true,
"__experimentalFontFamily": true,
"__experimentalTextDecoration": true
},
"color": true
}
},
"viewScript": "file:./view.min.js",
"editorStyle": "wp-block-navigation-editor",
Expand Down
Loading

0 comments on commit e7566c7

Please sign in to comment.