Skip to content

Commit

Permalink
navigation-menu: Implement colors selector button. (#17832)
Browse files Browse the repository at this point in the history
Summary
block-editor: expose ColorPaletteControl component
navigation-menu: improve colors-selector component
navigation-menu: compose withColors
navigation-menu: render colors selector in bar
navigation-menu: propagate withColor props
navigation-menu: apply theme styles to selection
navigation-item: populate styles to nav item
navigation-menu: apply inline styles and CSS classes
  • Loading branch information
retrofox authored and noisysocks committed Oct 22, 2019
1 parent a5c9b11 commit a25fe28
Show file tree
Hide file tree
Showing 8 changed files with 407 additions and 39 deletions.
4 changes: 4 additions & 0 deletions packages/block-editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ _Related_

Undocumented declaration.

<a name="ColorPaletteControl" href="#ColorPaletteControl">#</a> **ColorPaletteControl**

Undocumented declaration.

<a name="ContrastChecker" href="#ContrastChecker">#</a> **ContrastChecker**

Undocumented declaration.
Expand Down
1 change: 1 addition & 0 deletions packages/block-editor/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export { default as __experimentalBlockNavigationList } from './block-navigation
export { default as BlockVerticalAlignmentToolbar } from './block-vertical-alignment-toolbar';
export { default as ButtonBlockerAppender } from './button-block-appender';
export { default as ColorPalette } from './color-palette';
export { default as ColorPaletteControl } from './color-palette/control';
export { default as ContrastChecker } from './contrast-checker';
export { default as __experimentalGradientPicker } from './gradient-picker';
export { default as __experimentalGradientPickerControl } from './gradient-picker/control';
Expand Down
13 changes: 11 additions & 2 deletions packages/block-library/src/navigation-menu-item/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import { invoke } from 'lodash';
import classnames from 'classnames';

/**
* WordPress dependencies
Expand Down Expand Up @@ -84,8 +85,11 @@ function NavigationMenuItemEdit( {
</div>
);
} else {
content = attributes.label;
content = <div className="wp-block-navigation-menu-item__container">
{ attributes.label }
</div>;
}

return (
<Fragment>
<InspectorControls>
Expand Down Expand Up @@ -138,7 +142,12 @@ function NavigationMenuItemEdit( {
/>
</PanelBody>
</InspectorControls>
<div className="wp-block-navigation-menu-item">
<div className={ classnames(
'wp-block-navigation-menu-item', {
'is-editing': isSelected || isParentOfSelectedBlock,
'is-selected': isSelected,
} ) }
>
{ content }
{ ( isSelected || isParentOfSelectedBlock ) &&
<InnerBlocks
Expand Down
13 changes: 7 additions & 6 deletions packages/block-library/src/navigation-menu-item/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,16 @@ $menu-label-field-width: 140px;
}
}


.wp-block-navigation-menu-item {
font-family: $editor-font;
color: #0073af;
font-weight: bold;
font-size: $text-editor-font-size;

.wp-block-navigation-menu-item__container,
&.is-editing .editor-plain-text {
background-color: var(--background-color-menu-link);
color: var(--color-menu-link);

This comment has been minimized.

Copy link
@tellthemachines

tellthemachines Oct 23, 2019

Contributor

This is not going to work on IE; do we have a fallback in place?

}
}

.wp-block-navigation-menu-item__nofollow-external-link {
Expand All @@ -42,10 +46,7 @@ $menu-label-field-width: 140px;

// Separator
.wp-block-navigation-menu-item__separator {
margin-top: $grid-size;
margin-bottom: $grid-size;
margin-left: 0;
margin-right: 0;
margin: $grid-size 0 $grid-size;
border-top: $border-width solid $light-gray-500;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* External dependencies
*/
import classnames from 'classnames';
import { noop } from 'lodash';

/**
* WordPress dependencies
*/
import { IconButton, Dropdown, Toolbar } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { DOWN } from '@wordpress/keycodes';
import { ColorPaletteControl, ContrastChecker } from '@wordpress/block-editor';

/**
* Color Selector Icon component.
*
* @return {*} React Icon component.
*/
const ColorSelectorIcon = ( { style } ) =>
<div className="block-library-colors-selector__icon-container">
<div
className="block-library-colors-selector__state-selection wp-block-navigation-menu-item"
style={ style }
>
Aa
</div>
</div>;

/**
* Renders the Colors Selector Toolbar with the icon button.
*
* @param {Object} style - Colors style object.
* @return {*} React toggle button component.
*/
const renderToggleComponent = ( style ) => ( { onToggle, isOpen } ) => {
const openOnArrowDown = ( event ) => {
if ( ! isOpen && event.keyCode === DOWN ) {
event.preventDefault();
event.stopPropagation();
onToggle();
}
};

return (
<Toolbar>
<IconButton
className="components-icon-button components-toolbar__control block-library-colors-selector__toggle"
label={ __( 'Open Colors Selector' ) }
onClick={ onToggle }
onKeyDown={ openOnArrowDown }
icon={ <ColorSelectorIcon style={ style } /> }
/>
</Toolbar>
);
};

const renderContent = ( { backgroundColor, textColor, onColorChange = noop } ) => ( () => {
const setColor = ( attr ) => ( value ) => onColorChange( { attr, value } );

return (
<>
<div className="color-palette-controller-container">
<ColorPaletteControl
value={ backgroundColor.color }
onChange={ setColor( 'backgroundColor' ) }
label={ __( 'Background Color' ) }
/>
</div>

<div className="color-palette-controller-container">
<ColorPaletteControl
value={ textColor.color }
onChange={ setColor( 'textColor' ) }
label={ __( 'Text Color' ) }
/>
</div>

<ContrastChecker
textColor={ textColor.color }
backgroundColor={ backgroundColor.color }
isLargeText={ false }
/>
</>
);
} );

export default ( { style, className, ...colorControlProps } ) =>
<Dropdown
position="bottom right"
className={ classnames( 'block-library-colors-selector', className ) }
contentClassName="block-library-colors-selector__popover"
renderToggle={ renderToggleComponent( style ) }
renderContent={ renderContent( colorControlProps ) }
/>;
111 changes: 87 additions & 24 deletions packages/block-library/src/navigation-menu/edit.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
Expand All @@ -9,6 +14,7 @@ import {
InnerBlocks,
InspectorControls,
BlockControls,
withColors,
} from '@wordpress/block-editor';
import { withSelect } from '@wordpress/data';
import {
Expand All @@ -17,19 +23,26 @@ import {
Spinner,
Toolbar,
} from '@wordpress/components';
import { compose } from '@wordpress/compose';

import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import useBlockNavigator from './use-block-navigator';
import BlockColorsStyleSelector from './block-colors-selector';

function NavigationMenu( {
attributes,
setAttributes,
clientId,
pages,
isRequesting,
backgroundColor,
textColor,
setBackgroundColor,
setTextColor,
} ) {
const { navigatorToolbarButton, navigatorModal } = useBlockNavigator( clientId );
const defaultMenuItems = useMemo(
Expand All @@ -38,20 +51,71 @@ function NavigationMenu( {
return null;
}
return pages.map( ( page ) => {
return [ 'core/navigation-menu-item',
{ label: page.title.rendered, destination: page.permalink_template },
];
return [ 'core/navigation-menu-item', { label: page.title.rendered, destination: page.permalink_template } ];
} );
},
[ pages ]
);

const navigationMenuStyles = {};
if ( textColor.color ) {
navigationMenuStyles[ '--color-menu-link' ] = textColor.color;
}

if ( backgroundColor.color ) {
navigationMenuStyles[ '--background-color-menu-link' ] = backgroundColor.color;
}

const navigationMenuClasses = classnames(
'wp-block-navigation-menu', {
'has-text-color': textColor.color,
'has-background-color': backgroundColor.color,
}
);

/**
* Set the color type according to the given values.
* It propagate the color values into the attributes object.
* Both `backgroundColorValue` and `textColorValue` are
* using the apply inline styles.
*
* @param {Object} colorsData Arguments passed by BlockColorsStyleSelector onColorChange.
* @param {string} colorsData.attr Color attribute.
* @param {boolean} colorsData.value Color attribute value.
*/
const setColorType = ( { attr, value } ) => {
switch ( attr ) {
case 'backgroundColor':
setBackgroundColor( value );
setAttributes( { backgroundColorValue: value } );
break;

case 'textColor':
setTextColor( value );
setAttributes( { textColorValue: value } );
break;
}
};

// Set/Unset colors CSS classes.
setAttributes( {
backgroundColorCSSClass: backgroundColor.class ? backgroundColor.class : null,
textColorCSSClass: textColor.class ? textColor.class : null,
} );

return (
<Fragment>
<BlockControls>
<Toolbar>
{ navigatorToolbarButton }
</Toolbar>
<BlockColorsStyleSelector
style={ navigationMenuStyles }
className={ navigationMenuClasses }
backgroundColor={ backgroundColor }
textColor={ textColor }
onColorChange={ setColorType }
/>
</BlockControls>
{ navigatorModal }
<InspectorControls>
Expand All @@ -60,18 +124,15 @@ function NavigationMenu( {
>
<CheckboxControl
value={ attributes.automaticallyAdd }
onChange={ ( automaticallyAdd ) => {
setAttributes( { automaticallyAdd } );
} }
onChange={ ( automaticallyAdd ) => setAttributes( { automaticallyAdd } ) }
label={ __( 'Automatically add new pages' ) }
help={ __( 'Automatically add new top level pages to this menu.' ) }
/>
</PanelBody>
</InspectorControls>
<div className="wp-block-navigation-menu">
{ isRequesting &&
<Spinner />
}

<div className={ navigationMenuClasses } style={ navigationMenuStyles }>
{ isRequesting && <Spinner /> }
{ pages &&
<InnerBlocks
template={ defaultMenuItems ? defaultMenuItems : null }
Expand All @@ -84,17 +145,19 @@ function NavigationMenu( {
);
}

export default withSelect( ( select ) => {
const { getEntityRecords } = select( 'core' );
const { isResolving } = select( 'core/data' );
const filterDefaultPages = {
parent: 0,
order: 'asc',
orderby: 'id',
};
return {
pages: getEntityRecords( 'postType', 'page', filterDefaultPages ),
isRequesting: isResolving( 'core', 'getEntityRecords', [ 'postType', 'page', filterDefaultPages ] ),
};
} )( NavigationMenu );

export default compose( [
withColors( { backgroundColor: 'background-color', textColor: 'color' } ),
withSelect( ( select ) => {
const { getEntityRecords } = select( 'core' );
const { isResolving } = select( 'core/data' );
const filterDefaultPages = {
parent: 0,
order: 'asc',
orderby: 'id',
};
return {
pages: getEntityRecords( 'postType', 'page', filterDefaultPages ),
isRequesting: isResolving( 'core', 'getEntityRecords', [ 'postType', 'page', filterDefaultPages ] ),
};
} ),
] )( NavigationMenu );
Loading

0 comments on commit a25fe28

Please sign in to comment.