Skip to content

Commit

Permalink
Implemented mechanism to use classes for configured colors. (WordPres…
Browse files Browse the repository at this point in the history
…s#5273)

Implemented mechanism to use classes for configured colors instead of inline styles.
  • Loading branch information
jorgefilipecosta authored and nuzzio committed Apr 25, 2018
1 parent 2a27d83 commit bc3a2be
Show file tree
Hide file tree
Showing 12 changed files with 360 additions and 49 deletions.
2 changes: 1 addition & 1 deletion blocks/color-palette/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function ColorPalette( { colors, disableCustomColors = false, value, onCh

return (
<div className="blocks-color-palette">
{ map( colors, ( color ) => {
{ map( colors, ( { color } ) => {
const style = { color: color };
const className = classnames( 'blocks-color-palette__item', { 'is-active': value === color } );

Expand Down
2 changes: 1 addition & 1 deletion blocks/color-palette/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { shallow } from 'enzyme';
import { ColorPalette } from '../';

describe( 'ColorPalette', () => {
const colors = [ 'red', 'white', 'blue' ];
const colors = [ { name: 'red', color: 'red' }, { name: 'white', color: 'white' }, { name: 'blue', color: 'blue' } ];
const currentColor = 'red';
const onChange = jest.fn();

Expand Down
2 changes: 2 additions & 0 deletions blocks/colors/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { getColorClass } from './utils';
export { default as withColors } from './with-colors';
59 changes: 59 additions & 0 deletions blocks/colors/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* External dependencies
*/
import { find, kebabCase } from 'lodash';

/**
* Returns the color value based on an array of named colors and the namedColor or the customColor value.
*
* @param {Array} colors Array of color objects containing the "name" and "color" value as properties.
* @param {?string} namedColor A string containing the color name.
* @param {?string} customColor A string containing the customColor value.
*
* @return {?string} If namedColor is passed and the name is found in colors it returns the color for that name.
* Otherwise, the customColor parameter is returned.
*/
export const getColorValue = ( colors, namedColor, customColor ) => {
if ( namedColor ) {
const colorObj = find( colors, { name: namedColor } );
return colorObj && colorObj.color;
}
if ( customColor ) {
return customColor;
}
};

/**
* Returns a function that receives the color value and sets it using the attribute for named colors or for custom colors.
*
* @param {Array} colors Array of color objects containing the "name" and "color" value as properties.
* @param {string} colorAttributeName Name of the attribute where named colors are stored.
* @param {string} customColorAttributeName Name of the attribute where custom colors are stored.
* @param {string} setAttributes A function that receives an object with the attributes to set.
*
* @return {function} A function that receives the color value and sets the attributes necessary to correctly store it.
*/
export const setColorValue = ( colors, colorAttributeName, customColorAttributeName, setAttributes ) =>
( colorValue ) => {
const colorObj = find( colors, { color: colorValue } );
setAttributes( {
[ colorAttributeName ]: colorObj && colorObj.name ? colorObj.name : undefined,
[ customColorAttributeName ]: colorObj && colorObj.name ? undefined : colorValue,
} );
};

/**
* Returns a class based on the context a color is being used and its name.
*
* @param {string} colorContextName Context/place where color is being used e.g: background, text etc...
* @param {string} colorName Name of the color.
*
* @return {string} String with the class corresponding to the color in the provided context.
*/
export function getColorClass( colorContextName, colorName ) {
if ( ! colorContextName || ! colorName ) {
return;
}

return `has-${ kebabCase( colorName ) }-${ colorContextName }`;
}
42 changes: 42 additions & 0 deletions blocks/colors/with-colors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* External dependencies
*/
import { get } from 'lodash';

/**
* WordPress dependencies
*/
import { createHigherOrderComponent } from '@wordpress/element';

/**
* Internal dependencies
*/
import { getColorValue, getColorClass, setColorValue } from './utils';
import { withEditorSettings } from '../editor-settings';

/**
* Higher-order component, which handles color logic for class generation
* color value, retrieval and color attribute setting.
*
* @param {WPElement} WrappedComponent The wrapped component.
*
* @return {Component} Component with a new colors prop.
*/
export default createHigherOrderComponent(
withEditorSettings(
( settings, props ) => {
const colors = get( settings, [ 'colors' ], [] );
return {
initializeColor: ( { colorContext, colorAttribute, customColorAttribute } ) => ( {
value: getColorValue(
colors,
props.attributes[ colorAttribute ],
props.attributes[ customColorAttribute ]
),
class: getColorClass( colorContext, props.attributes[ colorAttribute ] ),
set: setColorValue( colors, colorAttribute, customColorAttribute, props.setAttributes ),
} ),
};
} ),
'withColors'
);
54 changes: 43 additions & 11 deletions blocks/editor-settings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,49 @@ import { createContext, createHigherOrderComponent } from '@wordpress/element';
const DEFAULT_SETTINGS = {
alignWide: false,
colors: [
'#f78da7',
'#cf2e2e',
'#ff6900',
'#fcb900',
'#7bdcb5',
'#00d084',
'#8ed1fc',
'#0693e3',
'#eee',
'#abb8c3',
'#313131',
{
name: 'pale pink',
color: '#f78da7',
},
{ name: 'vivid red',
color: '#cf2e2e',
},
{
name: 'luminous vivid orange',
color: '#ff6900',
},
{
name: 'luminous vivid amber',
color: '#fcb900',
},
{
name: 'light green cyan',
color: '#7bdcb5',
},
{
name: 'vivid green cyan',
color: '#00d084',
},
{
name: 'pale cyan blue',
color: '#8ed1fc',
},
{
name: 'vivid cyan blue',
color: '#0693e3',
},
{
name: 'very light gray',
color: '#eeeeee',
},
{
name: 'cyan bluish gray',
color: '#abb8c3',
},
{
name: 'very dark gray',
color: '#313131',
},
],

// This is current max width of the block inner area
Expand Down
1 change: 1 addition & 0 deletions blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import './hooks';
// and then stored as objects in state, from which it is then rendered for editing.
export * from './api';
export * from './autocompleters';
export * from './colors';

export { default as editorMediaUpload } from './editor-media-upload';
export { default as AlignmentToolbar } from './alignment-toolbar';
Expand Down
1 change: 1 addition & 0 deletions core-blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { deprecated } from '@wordpress/utils';
/**
* Internal dependencies
*/
import './style.scss';
import * as paragraph from './paragraph';
import * as image from './image';
import * as heading from './heading';
Expand Down
84 changes: 57 additions & 27 deletions core-blocks/paragraph/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { __ } from '@wordpress/i18n';
import {
concatChildren,
Component,
compose,
Fragment,
RawHTML,
} from '@wordpress/element';
Expand All @@ -26,6 +27,8 @@ import {
import {
createBlock,
blockAutocompleter,
getColorClass,
withColors,
userAutocompleter,
AlignmentToolbar,
BlockAlignmentToolbar,
Expand Down Expand Up @@ -128,6 +131,7 @@ class ParagraphBlock extends Component {
mergeBlocks,
onReplace,
className,
initializeColor,
fallbackBackgroundColor,
fallbackTextColor,
fallbackFontSize,
Expand All @@ -138,12 +142,20 @@ class ParagraphBlock extends Component {
content,
dropCap,
placeholder,
backgroundColor,
textColor,
width,
} = attributes;

const fontSize = this.getFontSize();
const textColor = initializeColor( {
colorContext: 'color',
colorAttribute: 'textColor',
customColorAttribute: 'customTextColor',
} );
const backgroundColor = initializeColor( {
colorContext: 'background-color',
colorAttribute: 'backgroundColor',
customColorAttribute: 'customBackgroundColor',
} );

return (
<Fragment>
Expand Down Expand Up @@ -200,22 +212,22 @@ class ParagraphBlock extends Component {
onChange={ this.toggleDropCap }
/>
</PanelBody>
<PanelColor title={ __( 'Background Color' ) } colorValue={ backgroundColor } initialOpen={ false }>
<PanelColor title={ __( 'Background Color' ) } colorValue={ backgroundColor.value } initialOpen={ false }>
<ColorPalette
value={ backgroundColor }
onChange={ ( colorValue ) => setAttributes( { backgroundColor: colorValue } ) }
value={ backgroundColor.value }
onChange={ backgroundColor.set }
/>
</PanelColor>
<PanelColor title={ __( 'Text Color' ) } colorValue={ textColor } initialOpen={ false }>
<PanelColor title={ __( 'Text Color' ) } colorValue={ textColor.value } initialOpen={ false }>
<ColorPalette
value={ textColor }
onChange={ ( colorValue ) => setAttributes( { textColor: colorValue } ) }
value={ textColor.value }
onChange={ textColor.set }
/>
</PanelColor>
<ContrastChecker
textColor={ textColor.value }
backgroundColor={ backgroundColor.value }
{ ...{
textColor,
backgroundColor,
fallbackBackgroundColor,
fallbackTextColor,
} }
Expand All @@ -232,12 +244,14 @@ class ParagraphBlock extends Component {
<RichText
tagName="p"
className={ classnames( 'wp-block-paragraph', className, {
'has-background': backgroundColor,
'has-background': backgroundColor.value,
'has-drop-cap': dropCap,
[ backgroundColor.class ]: backgroundColor.class,
[ textColor.class ]: textColor.class,
} ) }
style={ {
backgroundColor: backgroundColor,
color: textColor,
backgroundColor: backgroundColor.class ? undefined : backgroundColor.value,
color: textColor.class ? undefined : textColor.value,
fontSize: fontSize ? fontSize + 'px' : undefined,
textAlign: align,
} }
Expand Down Expand Up @@ -295,9 +309,15 @@ const schema = {
textColor: {
type: 'string',
},
customTextColor: {
type: 'string',
},
backgroundColor: {
type: 'string',
},
customBackgroundColor: {
type: 'string',
},
fontSize: {
type: 'string',
},
Expand Down Expand Up @@ -345,7 +365,7 @@ export const settings = {
fontSize: {
type: 'number',
},
}, 'customFontSize' ),
}, 'customFontSize', 'customTextColor', 'customBackgroundColor' ),
save( { attributes } ) {
const { width, align, content, dropCap, backgroundColor, textColor, fontSize } = attributes;
const className = classnames( {
Expand All @@ -363,13 +383,12 @@ export const settings = {
return <p style={ styles } className={ className ? className : undefined }>{ content }</p>;
},
migrate( attributes ) {
if ( isFinite( attributes.fontSize ) ) {
return omit( {
...attributes,
customFontSize: attributes.fontSize,
}, 'fontSize' );
}
return attributes;
return omit( {
...attributes,
customFontSize: isFinite( attributes.fontSize ) ? attributes.fontSize : undefined,
customTextColor: attributes.textColor && '#' === attributes.textColor[ 0 ] ? attributes.textColor : undefined,
customBackgroundColor: attributes.backgroundColor && '#' === attributes.backgroundColor[ 0 ] ? attributes.backgroundColor : undefined,
}, [ 'fontSize', 'textColor', 'backgroundColor' ] );
},
},
{
Expand Down Expand Up @@ -408,7 +427,10 @@ export const settings = {
}
},

edit: FallbackStyles( ParagraphBlock ),
edit: compose(
withColors,
FallbackStyles,
)( ParagraphBlock ),

save( { attributes } ) {
const {
Expand All @@ -418,21 +440,29 @@ export const settings = {
dropCap,
backgroundColor,
textColor,
customBackgroundColor,
customTextColor,
fontSize,
customFontSize,
} = attributes;

const textClass = getColorClass( 'color', textColor );
const backgroundClass = getColorClass( 'background-color', backgroundColor );
const fontSizeClass = fontSize && FONT_SIZES[ fontSize ] && `is-${ fontSize }-text`;

const className = classnames( {
[ `align${ width }` ]: width,
'has-background': backgroundColor,
'has-background': backgroundColor || customBackgroundColor,
'has-drop-cap': dropCap,
[ `is-${ fontSize }-text` ]: fontSize && FONT_SIZES[ fontSize ],
[ fontSizeClass ]: fontSizeClass,
[ textClass ]: textClass,
[ backgroundClass ]: backgroundClass,
} );

const styles = {
backgroundColor: backgroundColor,
color: textColor,
fontSize: ! fontSize && customFontSize ? customFontSize : undefined,
backgroundColor: backgroundClass ? undefined : customBackgroundColor,
color: textClass ? undefined : customTextColor,
fontSize: fontSizeClass ? undefined : customFontSize,
textAlign: align,
};

Expand Down
Loading

0 comments on commit bc3a2be

Please sign in to comment.