-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Try extracting Navigation Link rendering from the Navigation Block (#…
…21075) * Extract Navigation Link block rendering from Navigation Move code around with TODOs where needed Migrate away from block.json Filter out empty blocks Minor tweaks Add navigation link to core dynamic block types Temporarily comment out code in nav-link block that is coupled to nav block Minor fixes Actually render the inner blocks This is probably fine Render nav link inner blocks in a <ul> Make the Show Submenu Icon feature work using CSS Ensure default attributes work correctly on nav and nav link blocks Fix has-submenu-icon classname application in render function Make color styles inherit Move navigation link styles to the navigation link style.scss Fix & being used in base level style Remove TODO that has now been TODONE Fix PHP linting Update navigation link snapshot test Fix PHP doc block comments Co-Authored-By: Robert Anderson <[email protected]> * Render navigation-link from block.json * Migrate some navigation-link styles from navigation * Fix copy/pasted function name * Navigation: Use render_callback instead of render_block hook * Navigation: Use block context when rendering a Link * Navigation: Remove core/ prefix from context attribute names * Navigation: Remove .has-submenu-icon * Navigation: Fix failing integration test * Navigation: Fix submenu icon appearance Co-authored-by: Robert Anderson <[email protected]>
- Loading branch information
1 parent
0db58dd
commit 55d7f85
Showing
8 changed files
with
384 additions
and
275 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
<?php | ||
/** | ||
* Server-side rendering of the `core/navigation-link` block. | ||
* | ||
* @package gutenberg | ||
*/ | ||
|
||
/** | ||
* 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. | ||
* @return array Colors CSS classes and inline styles. | ||
*/ | ||
function block_core_navigation_link_build_css_colors( $context ) { | ||
$colors = array( | ||
'css_classes' => array(), | ||
'inline_styles' => '', | ||
); | ||
|
||
// Text color. | ||
$has_named_text_color = array_key_exists( 'textColor', $context ); | ||
$has_custom_text_color = array_key_exists( 'customTextColor', $context ); | ||
|
||
// If has text color. | ||
if ( $has_custom_text_color || $has_named_text_color ) { | ||
// Add has-text-color class. | ||
$colors['css_classes'][] = 'has-text-color'; | ||
} | ||
|
||
if ( $has_named_text_color ) { | ||
// Add the color class. | ||
$colors['css_classes'][] = sprintf( 'has-%s-color', $context['textColor'] ); | ||
} elseif ( $has_custom_text_color ) { | ||
// Add the custom color inline style. | ||
$colors['inline_styles'] .= sprintf( 'color: %s;', $context['customTextColor'] ); | ||
} | ||
|
||
// Background color. | ||
$has_named_background_color = array_key_exists( 'backgroundColor', $context ); | ||
$has_custom_background_color = array_key_exists( 'customBackgroundColor', $context ); | ||
|
||
// If has background color. | ||
if ( $has_custom_background_color || $has_named_background_color ) { | ||
// Add has-background class. | ||
$colors['css_classes'][] = 'has-background'; | ||
} | ||
|
||
if ( $has_named_background_color ) { | ||
// Add the background-color class. | ||
$colors['css_classes'][] = sprintf( 'has-%s-background-color', $context['backgroundColor'] ); | ||
} elseif ( $has_custom_background_color ) { | ||
// Add the custom background-color inline style. | ||
$colors['inline_styles'] .= sprintf( 'background-color: %s;', $context['customBackgroundColor'] ); | ||
} | ||
|
||
return $colors; | ||
} | ||
|
||
/** | ||
* Build an array with CSS classes and inline styles defining the font sizes | ||
* which will be applied to the navigation markup in the front-end. | ||
* | ||
* @param array $context Navigation block context. | ||
* @return array Font size CSS classes and inline styles. | ||
*/ | ||
function block_core_navigation_link_build_css_font_sizes( $context ) { | ||
// CSS classes. | ||
$font_sizes = array( | ||
'css_classes' => array(), | ||
'inline_styles' => '', | ||
); | ||
|
||
$has_named_font_size = array_key_exists( 'fontSize', $context ); | ||
$has_custom_font_size = array_key_exists( 'customFontSize', $context ); | ||
|
||
if ( $has_named_font_size ) { | ||
// Add the font size class. | ||
$font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $context['fontSize'] ); | ||
} elseif ( $has_custom_font_size ) { | ||
// Add the custom font size inline style. | ||
$font_sizes['inline_styles'] = sprintf( 'font-size: %spx;', $context['customFontSize'] ); | ||
} | ||
|
||
return $font_sizes; | ||
} | ||
|
||
/** | ||
* Returns the top-level submenu SVG chevron icon. | ||
* | ||
* @return string | ||
*/ | ||
function block_core_navigation_link_render_submenu_icon() { | ||
return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" transform="rotate(90)"><path d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/></svg>'; | ||
} | ||
|
||
/** | ||
* Renders the `core/navigation-link` block. | ||
* | ||
* @param array $attributes The block attributes. | ||
* @param array $content The saved content. | ||
* @param array $block The parsed block. | ||
* | ||
* @return string Returns the post content with the legacy widget added. | ||
*/ | ||
function render_block_core_navigation_link( $attributes, $content, $block ) { | ||
// Don't render the block's subtree if it has no label. | ||
if ( empty( $attributes['label'] ) ) { | ||
return ''; | ||
} | ||
|
||
$colors = block_core_navigation_link_build_css_colors( $block->context ); | ||
$font_sizes = block_core_navigation_link_build_css_font_sizes( $block->context ); | ||
$classes = array_merge( | ||
$colors['css_classes'], | ||
$font_sizes['css_classes'] | ||
); | ||
$classes[] = 'wp-block-navigation-link'; | ||
$style_attribute = ( $colors['inline_styles'] || $font_sizes['inline_styles'] ); | ||
|
||
$css_classes = trim( implode( ' ', $classes ) ); | ||
$has_submenu = count( $block->inner_blocks ) > 0; | ||
$is_active = ! empty( $attributes['id'] ) && ( get_the_ID() === $attributes['id'] ); | ||
|
||
$class_name = ! empty( $attributes['className'] ) ? implode( ' ', (array) $attributes['className'] ) : false; | ||
|
||
if ( false !== $class_name ) { | ||
$css_classes .= ' ' . $class_name; | ||
}; | ||
|
||
$html = '<li class="' . esc_attr( $css_classes . ( $has_submenu ? ' has-child' : '' ) ) . | ||
( $is_active ? ' current-menu-item' : '' ) . '"' . $style_attribute . '>' . | ||
'<a class="wp-block-navigation-link__content"'; | ||
|
||
// Start appending HTML attributes to anchor tag. | ||
if ( isset( $attributes['url'] ) ) { | ||
$html .= ' href="' . esc_url( $attributes['url'] ) . '"'; | ||
} | ||
|
||
if ( isset( $attributes['opensInNewTab'] ) && true === $attributes['opensInNewTab'] ) { | ||
$html .= ' target="_blank" '; | ||
} | ||
// End appending HTML attributes to anchor tag. | ||
|
||
// Start anchor tag content. | ||
$html .= '>' . | ||
// Wrap title with span to isolate it from submenu icon. | ||
'<span class="wp-block-navigation-link__label">'; | ||
|
||
if ( isset( $attributes['label'] ) ) { | ||
$html .= wp_kses( | ||
$attributes['label'], | ||
array( | ||
'code' => array(), | ||
'em' => array(), | ||
'img' => array( | ||
'scale' => array(), | ||
'class' => array(), | ||
'style' => array(), | ||
'src' => array(), | ||
'alt' => array(), | ||
), | ||
's' => array(), | ||
'span' => array( | ||
'style' => array(), | ||
), | ||
'strong' => array(), | ||
) | ||
); | ||
} | ||
|
||
$html .= '</span>'; | ||
|
||
$html .= '</a>'; | ||
// End anchor tag content. | ||
|
||
if ( $block->context['showSubmenuIcon'] && $has_submenu ) { | ||
// The submenu icon can be hidden by a CSS rule on the Navigation Block. | ||
$html .= '<span class="wp-block-navigation-link__submenu-icon">' . block_core_navigation_link_render_submenu_icon() . '</span>'; | ||
} | ||
|
||
if ( $has_submenu ) { | ||
$inner_blocks_html = ''; | ||
foreach ( $block->inner_blocks as $inner_block ) { | ||
$inner_blocks_html .= $inner_block->render(); | ||
} | ||
|
||
// TODO - classname is wrong! | ||
$html .= sprintf( | ||
'<ul class="wp-block-navigation__container">%s</ul>', | ||
$inner_blocks_html | ||
); | ||
} | ||
|
||
$html .= '</li>'; | ||
|
||
return $html; | ||
} | ||
|
||
/** | ||
* Register the navigation link block. | ||
* | ||
* @uses render_block_core_navigation() | ||
* @throws WP_Error An WP_Error exception parsing the block definition. | ||
*/ | ||
function register_block_core_navigation_link() { | ||
register_block_type_from_metadata( | ||
__DIR__ . '/navigation-link', | ||
array( | ||
'render_callback' => 'render_block_core_navigation_link', | ||
) | ||
); | ||
} | ||
add_action( 'init', 'register_block_core_navigation_link' ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
.wp-block-navigation-link { | ||
display: flex; | ||
align-items: center; | ||
position: relative; | ||
margin: 0; | ||
|
||
.wp-block-navigation__container:empty { | ||
display: none; | ||
} | ||
} | ||
|
||
.wp-block-navigation__container { | ||
// Reset the default list styles | ||
list-style: none; | ||
margin: 0; | ||
padding-left: 0; | ||
|
||
// Horizontal layout | ||
display: flex; | ||
flex-wrap: wrap; | ||
|
||
// Vertical layout | ||
|
||
.is-vertical & { | ||
display: block; | ||
} | ||
} | ||
|
||
// Styles for submenu flyout | ||
.has-child { | ||
$navigation-vertical-padding: $grid-unit-10 * 0.75; | ||
.wp-block-navigation__container { | ||
border: $border-width solid rgba(0, 0, 0, 0.15); | ||
background-color: inherit; | ||
color: inherit; | ||
position: absolute; | ||
left: 0; | ||
top: 100%; | ||
width: fit-content; | ||
z-index: 1; | ||
opacity: 0; | ||
transition: opacity 0.1s linear; | ||
visibility: hidden; | ||
|
||
> .wp-block-navigation-link { | ||
> .wp-block-navigation-link__content { | ||
flex-grow: 1; | ||
} | ||
> .wp-block-navigation-link__submenu-icon { | ||
padding-right: $grid-unit-10; | ||
} | ||
} | ||
|
||
@include break-medium { | ||
left: $grid-unit-30; | ||
|
||
// Nested submenus sit to the left on large breakpoints | ||
.wp-block-navigation__container { | ||
left: 100%; | ||
top: -1px; | ||
|
||
// Prevent the menu from disappearing when the mouse is over the gap | ||
&::before { | ||
content: ""; | ||
position: absolute; | ||
right: 100%; | ||
height: 100%; | ||
display: block; | ||
width: $grid-unit-10; | ||
background: transparent; | ||
} | ||
} | ||
|
||
.wp-block-navigation-link__submenu-icon svg { | ||
transform: rotate(0); | ||
} | ||
} | ||
} | ||
// Separating out hover and focus-within so hover works again on IE: https://davidwalsh.name/css-focus-within#comment-513401 | ||
// We will need to replace focus-within with a JS solution for IE keyboard support. | ||
&:hover { | ||
cursor: pointer; | ||
|
||
> .wp-block-navigation__container { | ||
visibility: visible; | ||
opacity: 1; | ||
display: flex; | ||
flex-direction: column; | ||
} | ||
} | ||
|
||
&:focus-within { | ||
cursor: pointer; | ||
|
||
> .wp-block-navigation__container { | ||
visibility: visible; | ||
opacity: 1; | ||
display: flex; | ||
flex-direction: column; | ||
} | ||
} | ||
} | ||
|
||
// All links | ||
.wp-block-navigation-link__content { | ||
text-decoration: none; | ||
padding: $grid-unit-10 $grid-unit-10 * 2; | ||
|
||
+ .wp-block-navigation-link__content { | ||
padding-top: 0; | ||
} | ||
.has-text-color & { | ||
color: inherit; | ||
} | ||
} | ||
|
||
.wp-block-navigation-link__label { | ||
font-family: $default-font; | ||
|
||
word-break: normal; | ||
overflow-wrap: break-word; | ||
} | ||
|
||
.wp-block-navigation-link__submenu-icon { | ||
height: inherit; | ||
padding: $grid-unit-10 * 0.75 $grid-unit-10 * 2; | ||
|
||
svg { | ||
fill: currentColor; | ||
|
||
@include break-medium { | ||
transform: rotate(90deg); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.