Skip to content

Commit

Permalink
Switch color block support and global styles to use ToolsPanel
Browse files Browse the repository at this point in the history
Add color inspector controls slot and update color ToolsPanel use
  • Loading branch information
aaronrobertshaw committed Oct 21, 2021
1 parent a0c59f2 commit 23b288b
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 18 deletions.
5 changes: 5 additions & 0 deletions packages/block-editor/src/components/block-inspector/index.js
Expand Up @@ -129,6 +129,11 @@ const BlockInspectorSingleBlock = ( {
</div>
) }
<InspectorControls.Slot bubblesVirtually={ bubblesVirtually } />
<InspectorControls.Slot
__experimentalGroup="color"
bubblesVirtually={ bubblesVirtually }
label={ __( 'Color' ) }
/>
<InspectorControls.Slot
__experimentalGroup="dimensions"
bubblesVirtually={ bubblesVirtually }
Expand Down
Expand Up @@ -5,13 +5,15 @@ import { createSlotFill } from '@wordpress/components';

const InspectorControlsDefault = createSlotFill( 'InspectorControls' );
const InspectorControlsAdvanced = createSlotFill( 'InspectorAdvancedControls' );
const InspectorControlsColor = createSlotFill( 'InspectorControlsColor' );
const InspectorControlsDimensions = createSlotFill(
'InspectorControlsDimensions'
);

const groups = {
default: InspectorControlsDefault,
advanced: InspectorControlsAdvanced,
color: InspectorControlsColor,
dimensions: InspectorControlsDimensions,
};

Expand Down
56 changes: 40 additions & 16 deletions packages/block-editor/src/hooks/color-panel.js
Expand Up @@ -2,14 +2,15 @@
* WordPress dependencies
*/
import { useState, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { __experimentalToolsPanelItem as ToolsPanelItem } from '@wordpress/components';

/**
* Internal dependencies
*/
import PanelColorGradientSettings from '../components/colors-gradients/panel-color-gradient-settings';
import ContrastChecker from '../components/contrast-checker';
import ColorGradientControl from '../components/colors-gradients/control';
import InspectorControls from '../components/inspector-controls';
import useSetting from '../components/use-setting';
import { __unstableUseBlockRef as useBlockRef } from '../components/block-list/use-block-props/use-block-refs';

function getComputedStyle( node ) {
Expand All @@ -20,12 +21,16 @@ export default function ColorPanel( {
settings,
clientId,
enableContrastChecking = true,
showTitle = true,
} ) {
const [ detectedBackgroundColor, setDetectedBackgroundColor ] = useState();
const [ detectedColor, setDetectedColor ] = useState();
const ref = useBlockRef( clientId );

const colors = useSetting( 'color.palette' );
const gradients = useSetting( 'color.gradients' );
const disableCustomColors = ! useSetting( 'color.custom' );
const disableCustomGradients = ! useSetting( 'color.customGradient' );

useEffect( () => {
if ( ! enableContrastChecking ) {
return;
Expand Down Expand Up @@ -54,20 +59,39 @@ export default function ColorPanel( {
} );

return (
<InspectorControls>
<PanelColorGradientSettings
title={ __( 'Color' ) }
initialOpen={ false }
settings={ settings }
showTitle={ showTitle }
>
{ enableContrastChecking && (
<ContrastChecker
backgroundColor={ detectedBackgroundColor }
textColor={ detectedColor }
<InspectorControls __experimentalGroup="color">
{ settings.map( ( setting, index ) => (
<ToolsPanelItem
key={ index }
hasValue={ setting.hasValue }
label={ setting.label }
onDeselect={ setting.onDeselect }
isShownByDefault={ setting.isShownByDefault }
resetAllFilter={ setting.resetAllFilter }
panelId={ clientId }
>
<ColorGradientControl
{ ...{
colors,
gradients,
disableCustomColors,
disableCustomGradients,
clearable: false,
label: setting.label,
onColorChange: setting.onColorChange,
onGradientChange: setting.onGradientChange,
colorValue: setting.colorValue,
gradientValue: setting.gradientValue,
} }
/>
) }
</PanelColorGradientSettings>
</ToolsPanelItem>
) ) }
{ enableContrastChecking && (
<ContrastChecker
backgroundColor={ detectedBackgroundColor }
textColor={ detectedColor }
/>
) }
</InspectorControls>
);
}
143 changes: 141 additions & 2 deletions packages/block-editor/src/hooks/color.js
Expand Up @@ -78,6 +78,125 @@ const hasTextColorSupport = ( blockType ) => {
return colorSupport && colorSupport.text !== false;
};

/**
* Checks whether a color has been set either with a named preset color in
* a top level block attribute or as a custom value within the style attribute
* object.
*
* @param {string} name Name of the color to check.
* @return {boolean} Whether or not a color has a value.
*/
const hasColor = ( name ) => ( props ) => {
if ( name === 'background' ) {
return (
!! props.attributes.backgroundColor ||
!! props.attributes.style?.color?.background ||
!! props.attributes.gradient ||
!! props.attributes.style?.color?.gradient
);
}

if ( name === 'link' ) {
return !! props.attributes.style?.elements?.link?.color?.text;
}

return (
!! props.attributes[ `${ name }Color` ] ||
!! props.attributes.style?.color?.[ name ]
);
};

/**
* Clears a single color property from a style object.
*
* @param {Array} path Path to color property to clear within styles object.
* @param {Object} style Block attributes style object.
* @return {Object} Styles with the color property omitted.
*/
const clearColorFromStyles = ( path, style ) =>
cleanEmptyObject( immutableSet( style, path, undefined ) );

/**
* Resets the block attributes for text color.
*
* @param {Object} props Current block props.
* @param {Object} props.attributes Block attributes.
* @param {Function} props.setAttributes Block's setAttributes prop used to apply reset.
*/
const resetTextColor = ( { attributes, setAttributes } ) => {
setAttributes( {
textColor: undefined,
style: clearColorFromStyles( [ 'color', 'text' ], attributes.style ),
} );
};

/**
* Clears text color related properties from supplied attributes.
*
* @param {Object} attributes Block attributes.
* @return {Object} Update block attributes with text color properties omitted.
*/
const resetAllTextFilter = ( attributes ) => ( {
textColor: undefined,
style: clearColorFromStyles( [ 'color', 'text' ], attributes.style ),
} );

/**
* Resets the block attributes for link color.
*
* @param {Object} props Current block props.
* @param {Object} props.attributes Block attributes.
* @param {Function} props.setAttributes Block's setAttributes prop used to apply reset.
*/
const resetLinkColor = ( { attributes, setAttributes } ) => {
const path = [ 'elements', 'link', 'color', 'text' ];
setAttributes( { style: clearColorFromStyles( path, attributes.style ) } );
};

/**
* Clears link color related properties from supplied attributes.
*
* @param {Object} attributes Block attributes.
* @return {Object} Update block attributes with link color properties omitted.
*/
const resetAllLinkFilter = ( attributes ) => ( {
style: clearColorFromStyles(
[ 'elements', 'link', 'color', 'text' ],
attributes.style
),
} );

/**
* Clears all background color related properties including gradients from
* supplied block attributes.
*
* @param {Object} attributes Block attributes.
* @return {Object} Block attributes with background and gradient omitted.
*/
const clearBackgroundAndGradient = ( attributes ) => ( {
backgroundColor: undefined,
gradient: undefined,
style: {
...attributes.style,
color: {
...attributes.style?.color,
background: undefined,
gradient: undefined,
},
},
} );

/**
* Resets the block attributes for both background color and gradient.
*
* @param {Object} props Current block props.
* @param {Object} props.attributes Block attributes.
* @param {Function} props.setAttributes Block's setAttributes prop used to apply reset.
*/
const resetBackgroundAndGradient = ( { attributes, setAttributes } ) => {
setAttributes( clearBackgroundAndGradient( attributes ) );
};

/**
* Filters registered block settings, extending attributes to include
* `backgroundColor` and `textColor` attribute.
Expand Down Expand Up @@ -137,7 +256,7 @@ export function addSaveProps( props, blockType, attributes ) {

const hasGradient = hasGradientSupport( blockType );

// I'd have prefered to avoid the "style" attribute usage here
// I'd have preferred to avoid the "style" attribute usage here
const { backgroundColor, textColor, gradient, style } = attributes;

const backgroundClass = getColorClassName(
Expand Down Expand Up @@ -169,7 +288,7 @@ export function addSaveProps( props, blockType, attributes ) {
}

/**
* Filters registered block settings to extand the block edit wrapper
* Filters registered block settings to extend the block edit wrapper
* to apply the desired styles and classnames properly.
*
* @param {Object} settings Original block settings.
Expand Down Expand Up @@ -346,6 +465,11 @@ export function ColorEdit( props ) {
props.setAttributes( { style: newStyle } );
};

const defaultColorControls = getBlockSupport( props.name, [
COLOR_SUPPORT_KEY,
'__experimentalDefaultControls',
] );

return (
<ColorPanel
enableContrastChecking={
Expand All @@ -364,6 +488,10 @@ export function ColorEdit( props ) {
textColor,
style?.color?.text
).color,
isShownByDefault: defaultColorControls?.text,
hasValue: () => hasColor( 'text' )( props ),
onDeselect: () => resetTextColor( props ),
resetAllFilter: resetAllTextFilter,
},
]
: [] ),
Expand All @@ -383,6 +511,13 @@ export function ColorEdit( props ) {
onGradientChange: hasGradientColor
? onChangeGradient
: undefined,
isShownByDefault:
defaultColorControls?.background,
hasValue: () =>
hasColor( 'background' )( props ),
onDeselect: () =>
resetBackgroundAndGradient( props ),
resetAllFilter: clearBackgroundAndGradient,
},
]
: [] ),
Expand All @@ -397,6 +532,10 @@ export function ColorEdit( props ) {
),
clearable: !! style?.elements?.link?.color
?.text,
isShownByDefault: defaultColorControls?.link,
hasValue: () => hasColor( 'link' )( props ),
onDeselect: () => resetLinkColor( props ),
resetAllFilter: resetAllLinkFilter,
},
]
: [] ),
Expand Down
29 changes: 29 additions & 0 deletions packages/block-editor/src/hooks/color.scss
@@ -0,0 +1,29 @@
.color-block-support-panel {
.components-base-control__label {
display: flex;
align-items: center;
}

.components-circular-option-picker__swatches {
display: grid;
grid-template-columns: repeat(6, 28px);
margin-right: 0;
margin-bottom: $grid-unit-10;
row-gap: $grid-unit-15;
justify-content: space-between;
}

.components-circular-option-picker__option-wrapper,
.components-angle-picker-control {
margin: 0;
}

.components-notice__content,
.components-circular-option-picker__dropdown-link-action {
margin-right: 0;
}

.block-editor-contrast-checker {
grid-column: span 2;
}
}
1 change: 1 addition & 0 deletions packages/block-editor/src/style.scss
Expand Up @@ -56,6 +56,7 @@
@import "./hooks/anchor.scss";
@import "./hooks/layout.scss";
@import "./hooks/border.scss";
@import "./hooks/color.scss";

@import "./components/block-toolbar/style.scss";
@import "./components/inserter/style.scss";
Expand Down

0 comments on commit 23b288b

Please sign in to comment.