Skip to content

Commit

Permalink
Add color inspector controls slot and update color ToolsPanel use
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw committed Sep 16, 2021
1 parent 6d9bcf5 commit 3b1875d
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 95 deletions.
5 changes: 5 additions & 0 deletions packages/block-editor/src/components/block-inspector/index.js
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
71 changes: 31 additions & 40 deletions packages/block-editor/src/hooks/color-panel.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useState, useEffect } from '@wordpress/element';
import {
__experimentalToolsPanel as ToolsPanel,
__experimentalToolsPanelItem as ToolsPanelItem,
} from '@wordpress/components';
import { __experimentalToolsPanelItem as ToolsPanelItem } from '@wordpress/components';

/**
* Internal dependencies
Expand All @@ -24,7 +20,6 @@ function getComputedStyle( node ) {
export default function ColorPanel( {
settings,
clientId,
resetAll,
enableContrastChecking = true,
} ) {
const [ detectedBackgroundColor, setDetectedBackgroundColor ] = useState();
Expand Down Expand Up @@ -64,41 +59,37 @@ export default function ColorPanel( {
} );

return (
<InspectorControls>
<ToolsPanel
label={ __( 'Color options' ) }
header={ __( 'Color' ) }
resetAll={ resetAll }
>
{ settings.map( ( setting, index ) => (
<ToolsPanelItem
key={ index }
hasValue={ setting.hasValue }
label={ setting.label }
onDeselect={ setting.onDeselect }
isShownByDefault={ setting.isShownByDefault }
>
<ColorGradientControl
{ ...{
colors,
gradients,
disableCustomColors,
disableCustomGradients,
clearable: false,
label: setting.label,
onColorChange: setting.onColorChange,
colorValue: setting.colorValue,
} }
/>
</ToolsPanelItem>
) ) }
{ 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,
colorValue: setting.colorValue,
} }
/>
) }
</ToolsPanel>
</ToolsPanelItem>
) ) }
{ enableContrastChecking && (
<ContrastChecker
backgroundColor={ detectedBackgroundColor }
textColor={ detectedColor }
/>
) }
</InspectorControls>
);
}
135 changes: 85 additions & 50 deletions packages/block-editor/src/hooks/color.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,54 +96,105 @@ const hasColor = ( name ) => ( props ) => {
);
}

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

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

/**
* Resets the block attributes for both background color and gradient.
* 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 resetBackgroundAndGradient = ( { attributes, setAttributes } ) => {
const { style } = attributes;

const resetTextColor = ( { attributes, setAttributes } ) => {
setAttributes( {
backgroundColor: undefined,
gradient: undefined,
style: cleanEmptyObject( {
...style,
color: {
...style?.color,
background: undefined,
gradient: undefined,
},
} ),
textColor: undefined,
style: clearColorFromStyles( [ 'color', 'text' ], attributes.style ),
} );
};

/**
* Resets a color by setting is corresponding attributes to undefined.
* Clears text color related properties from supplied attributes.
*
* @param {string} name Name of the color to clear.
* @param {Object} attributes Block attributes.
* @return {Object} Update block attributes with text color properties omitted.
*/
const resetColor = ( name ) => ( { attributes, setAttributes } ) => {
const { style } = attributes;
const resetAllTextFilter = ( attributes ) => ( {
textColor: undefined,
style: clearColorFromStyles( [ 'color', 'text' ], attributes.style ),
} );

setAttributes( {
[ `${ name }Color` ]: undefined,
style: cleanEmptyObject( {
...style,
color: {
...style?.color,
[ name ]: undefined,
},
} ),
} );
/**
* 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 ) );
};

/**
Expand Down Expand Up @@ -284,7 +335,7 @@ function immutableSet( object, path, value ) {
* @return {WPElement} Color edit element.
*/
export function ColorEdit( props ) {
const { name: blockName, attributes, setAttributes } = props;
const { name: blockName, attributes } = props;
const solids = useSetting( 'color.palette' ) || EMPTY_ARRAY;
const gradients = useSetting( 'color.gradients' ) || EMPTY_ARRAY;
const areCustomSolidsEnabled = useSetting( 'color.custom' );
Expand Down Expand Up @@ -419,32 +470,13 @@ export function ColorEdit( props ) {
'__experimentalDefaultControls',
] );

const resetAll = () => {
const newStyle = immutableSet(
{
...localAttributes.current.style,
color: undefined,
},
[ 'elements', 'link', 'color', 'text' ],
undefined
);

setAttributes( {
backgroundColor: undefined,
gradient: undefined,
textColor: undefined,
style: newStyle,
} );
};

return (
<ColorPanel
enableContrastChecking={
// Turn on contrast checker for web only since it's not supported on mobile yet.
Platform.OS === 'web' && ! gradient && ! style?.color?.gradient
}
clientId={ props.clientId }
resetAll={ resetAll }
settings={ [
...( hasTextColor
? [
Expand All @@ -458,7 +490,8 @@ export function ColorEdit( props ) {
).color,
isShownByDefault: defaultColorControls?.text,
hasValue: () => hasColor( 'text' )( props ),
onDeselect: () => resetColor( 'text' )( props ),
onDeselect: () => resetTextColor( props ),
resetAllFilter: resetAllTextFilter,
},
]
: [] ),
Expand All @@ -484,6 +517,7 @@ export function ColorEdit( props ) {
hasColor( 'background' )( props ),
onDeselect: () =>
resetBackgroundAndGradient( props ),
resetAllFilter: clearBackgroundAndGradient,
},
]
: [] ),
Expand All @@ -500,7 +534,8 @@ export function ColorEdit( props ) {
?.text,
isShownByDefault: defaultColorControls?.link,
hasValue: () => hasColor( 'link' )( props ),
onDeselect: () => resetColor( 'link' )( props ),
onDeselect: () => resetLinkColor( props ),
resetAllFilter: resetAllLinkFilter,
},
]
: [] ),
Expand Down
4 changes: 4 additions & 0 deletions packages/components/src/tools-panel/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export const ToolsPanel = css`
&:empty {
display: none;
}
> div {
grid-column: span 2;
}
}
> div {
Expand Down
6 changes: 1 addition & 5 deletions packages/edit-site/src/components/sidebar/color-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,7 @@ export default function ColorPanel( {
};

return (
<ToolsPanel
label={ __( 'Color options' ) }
header={ __( 'Color' ) }
resetAll={ resetAll }
>
<ToolsPanel label={ __( 'Color' ) } resetAll={ resetAll }>
{ settings.map( ( setting, index ) => (
<ToolsPanelItem
key={ index }
Expand Down

0 comments on commit 3b1875d

Please sign in to comment.