Skip to content

Commit

Permalink
Separator block: refactor to use color block supports to allow alpha …
Browse files Browse the repository at this point in the history
…channel opacity to be set(#38428)

Co-authored-by: Glen Davies <[email protected]>
Co-authored-by: ramonjd <[email protected]>
  • Loading branch information
3 people authored Mar 21, 2022
1 parent 3d07bf6 commit c9e1159
Show file tree
Hide file tree
Showing 38 changed files with 455 additions and 75 deletions.
4 changes: 2 additions & 2 deletions docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -698,8 +698,8 @@ Create a break between ideas or sections with a horizontal separator. ([Source](

- **Name:** core/separator
- **Category:** design
- **Supports:** align (center, full, wide), anchor
- **Attributes:** color, customColor
- **Supports:** align (center, full, wide), anchor, color (background, gradients, ~~text~~)
- **Attributes:** opacity

## Shortcode

Expand Down
19 changes: 13 additions & 6 deletions packages/block-library/src/separator/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@
"keywords": [ "horizontal-line", "hr", "divider" ],
"textdomain": "default",
"attributes": {
"color": {
"type": "string"
},
"customColor": {
"type": "string"
"opacity": {
"type": "string",
"default": "alpha-channel"
}
},
"supports": {
"anchor": true,
"align": [ "center", "wide", "full" ]
"align": [ "center", "wide", "full" ],
"color": {
"__experimentalSkipSerialization": true,
"gradients": true,
"background": true,
"text": false,
"__experimentalDefaultControls": {
"background": true
}
}
},
"styles": [
{ "name": "default", "label": "Default", "isDefault": true },
Expand Down
57 changes: 57 additions & 0 deletions packages/block-library/src/separator/deprecated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* External dependencies
*/
import classnames from 'classnames';
import { omit } from 'lodash';

/**
* WordPress dependencies
*/
import { getColorClassName, useBlockProps } from '@wordpress/block-editor';

const v1 = {
attributes: {
color: {
type: 'string',
},
customColor: {
type: 'string',
},
},
save( { attributes } ) {
const { color, customColor } = attributes;

// the hr support changing color using border-color, since border-color
// is not yet supported in the color palette, we use background-color
const backgroundClass = getColorClassName( 'background-color', color );
// the dots styles uses text for the dots, to change those dots color is
// using color, not backgroundColor
const colorClass = getColorClassName( 'color', color );

const className = classnames( {
'has-text-color has-background': color || customColor,
[ backgroundClass ]: backgroundClass,
[ colorClass ]: colorClass,
} );

const style = {
backgroundColor: backgroundClass ? undefined : customColor,
color: colorClass ? undefined : customColor,
};

return <hr { ...useBlockProps.save( { className, style } ) } />;
},
migrate( attributes ) {
const { color, customColor } = attributes;
return {
...omit( attributes, [ 'color', 'customColor' ] ),
backgroundColor: color ? color : undefined,
opacity: 'css',
style: customColor
? { color: { background: customColor } }
: undefined,
};
},
};

export default [ v1 ];
6 changes: 6 additions & 0 deletions packages/block-library/src/separator/deprecated.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.wp-block-separator {
// V1 version of the block expects a default opactiy of 0.4 to be set.
&.has-css-opacity {
opacity: 0.4;
}
}
50 changes: 36 additions & 14 deletions packages/block-library/src/separator/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,52 @@ import classnames from 'classnames';
* WordPress dependencies
*/
import { HorizontalRule } from '@wordpress/components';
import { withColors, useBlockProps } from '@wordpress/block-editor';
import {
useBlockProps,
getColorClassName,
__experimentalUseColorProps as useColorProps,
} from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import SeparatorSettings from './separator-settings';
import useDeprecatedOpacity from './use-deprecated-opacity';

export default function SeparatorEdit( { attributes, setAttributes } ) {
const { backgroundColor, opacity, style } = attributes;
const colorProps = useColorProps( attributes );
const currentColor = colorProps?.style?.backgroundColor;
const hasCustomColor = !! style?.color?.background;

useDeprecatedOpacity( opacity, currentColor, setAttributes );

// The dots styles uses text for the dots, to change those dots color is
// using color, not backgroundColor.
const colorClass = getColorClassName( 'color', backgroundColor );

const className = classnames(
{
'has-text-color': backgroundColor || currentColor,
[ colorClass ]: colorClass,
'has-css-opacity': opacity === 'css',
'has-alpha-channel-opacity': opacity === 'alpha-channel',
},
colorProps.classname
);

const styles = {
color: currentColor,
backgroundColor: currentColor,
};

function SeparatorEdit( { color, setColor, className } ) {
return (
<>
<HorizontalRule
{ ...useBlockProps( {
className: classnames( className, {
'has-background': color.color,
[ color.class ]: color.class,
} ),
style: {
backgroundColor: color.color,
color: color.color,
},
className,
style: hasCustomColor ? styles : undefined,
} ) }
/>
<SeparatorSettings color={ color } setColor={ setColor } />
</>
);
}

export default withColors( 'color', { textColor: 'color' } )( SeparatorEdit );
6 changes: 6 additions & 0 deletions packages/block-library/src/separator/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@
// Prevent margin collapsing so the area to select the separator is bigger.
padding-top: 0.1px;
padding-bottom: 0.1px;

// This is also set in style.scss, but needs a higher specificity in editor
// due to the way that color block supports adds additional background color styles.
&.wp-block-separator.is-style-dots {
background: none !important;
}
}
2 changes: 2 additions & 0 deletions packages/block-library/src/separator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import edit from './edit';
import metadata from './block.json';
import save from './save';
import transforms from './transforms';
import deprecated from './deprecated';

const { name } = metadata;

Expand All @@ -26,4 +27,5 @@ export const settings = {
transforms,
edit,
save,
deprecated,
};
36 changes: 22 additions & 14 deletions packages/block-library/src/separator/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,36 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { getColorClassName, useBlockProps } from '@wordpress/block-editor';
import {
getColorClassName,
useBlockProps,
__experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
} from '@wordpress/block-editor';

export default function separatorSave( { attributes } ) {
const { color, customColor } = attributes;

const { backgroundColor, style, opacity } = attributes;
const customColor = style?.color?.background;
const colorProps = getColorClassesAndStyles( attributes );
// The hr support changing color using border-color, since border-color
// is not yet supported in the color palette, we use background-color.
const backgroundClass = getColorClassName( 'background-color', color );

// The dots styles uses text for the dots, to change those dots color is
// using color, not backgroundColor.
const colorClass = getColorClassName( 'color', color );
const colorClass = getColorClassName( 'color', backgroundColor );

const className = classnames( {
'has-text-color has-background': color || customColor,
[ backgroundClass ]: backgroundClass,
[ colorClass ]: colorClass,
} );
const className = classnames(
{
'has-text-color': backgroundColor || customColor,
[ colorClass ]: colorClass,
'has-css-opacity': opacity === 'css',
'has-alpha-channel-opacity': opacity === 'alpha-channel',
},
colorProps.className
);

const style = {
backgroundColor: backgroundClass ? undefined : customColor,
const styles = {
backgroundColor: colorProps?.style?.backgroundColor,
color: colorClass ? undefined : customColor,
};

return <hr { ...useBlockProps.save( { className, style } ) } />;
return <hr { ...useBlockProps.save( { className, style: styles } ) } />;
}
24 changes: 0 additions & 24 deletions packages/block-library/src/separator/separator-settings.js

This file was deleted.

113 changes: 113 additions & 0 deletions packages/block-library/src/separator/test/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* External dependencies
*/
import { render } from '@testing-library/react';

/**
* WordPress dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import SeparatorEdit from '../edit';

jest.mock( '@wordpress/block-editor', () => ( {
...jest.requireActual( '@wordpress/block-editor' ),
useBlockProps: jest.fn(),
} ) );

const defaultAttributes = {
backgroundColor: undefined,
opacity: 'alpha-channel',
style: {},
className: '',
};
const defaultProps = {
attributes: defaultAttributes,
setAttributes: jest.fn(),
};

describe( 'Separator block edit method', () => {
beforeEach( () => {
useBlockProps.mockClear();
} );

test( 'should add the has-alpha-channel-opacity class and no inline styles by default', () => {
render( <SeparatorEdit { ...defaultProps } /> );
expect( useBlockProps ).toHaveBeenCalledWith( {
className: 'has-alpha-channel-opacity',
style: undefined,
} );
} );

test( 'should add has-css-opacity class and no inline styles for deprecated block with no color specified', () => {
const props = {
...defaultProps,
attributes: { ...defaultAttributes, opacity: 'css' },
};
render( <SeparatorEdit { ...props } /> );
expect( useBlockProps ).toHaveBeenCalledWith( {
className: 'has-css-opacity',
style: undefined,
} );
} );

test( 'should add inline background style for block without dots style selected and custom color specified', () => {
const props = {
...defaultProps,
attributes: {
...defaultAttributes,
style: { color: { background: '#ff0000' } },
},
};
render( <SeparatorEdit { ...props } /> );
expect( useBlockProps ).toHaveBeenCalledWith( {
// For backwards compatibility the has-text-color class is also added even though it is only needed for
// is-style-dots as this class was always added to v1 blocks, so may be expected by themes and plugins.
className: 'has-text-color has-alpha-channel-opacity',
style: {
backgroundColor: '#ff0000',
color: '#ff0000',
},
} );
} );

test( 'should add inline color style for block with dots style selected and custom color specified', () => {
const props = {
...defaultProps,
attributes: {
...defaultAttributes,
className: 'is-style-dots',
style: { color: { background: '#ff0000' } },
},
};
render( <SeparatorEdit { ...props } /> );
expect( useBlockProps ).toHaveBeenCalledWith( {
className: 'has-text-color has-alpha-channel-opacity',
style: {
backgroundColor: '#ff0000',
color: '#ff0000',
},
} );
} );

test( 'should add color class when color from palette specified', () => {
const props = {
...defaultProps,
attributes: {
...defaultAttributes,
backgroundColor: 'banana',
},
};
render( <SeparatorEdit { ...props } /> );
// Note that only the manual addition of the text color class can be checked as the
// background color classes are added by useBlockProps which has to be mocked.
expect( useBlockProps ).toHaveBeenCalledWith( {
className:
'has-text-color has-banana-color has-alpha-channel-opacity',
style: undefined,
} );
} );
} );
Loading

0 comments on commit c9e1159

Please sign in to comment.