Skip to content

Commit

Permalink
Add a function to register a block style variation (#7997)
Browse files Browse the repository at this point in the history
* Add a function to register a block style variation

* Improve JSDocs for registerBlockStyle

* Rename registerBlockStyleVariation to registerBlockStyle and export it

* Use template strings
  • Loading branch information
youknowriad authored Jul 26, 2018
1 parent aac31cb commit d5f2d79
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/blocks/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export {
getChildBlockNames,
hasChildBlocks,
unstable__bootstrapServerSideBlockDefinitions, // eslint-disable-line camelcase
registerBlockStyle,
} from './registration';
export {
isUnmodifiedDefaultBlock,
Expand Down
28 changes: 25 additions & 3 deletions packages/blocks/src/api/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { get, isFunction, some } from 'lodash';
/**
* WordPress dependencies
*/
import { applyFilters } from '@wordpress/hooks';
import { applyFilters, addFilter } from '@wordpress/hooks';
import { select, dispatch } from '@wordpress/data';

/**
Expand Down Expand Up @@ -312,7 +312,7 @@ export function isSharedBlock( blockOrType ) {
/**
* Returns an array with the child blocks of a given block.
*
* @param {string} blockName Block type name.
* @param {string} blockName Name of block (example: “latest-posts”).
*
* @return {Array} Array of child block names.
*/
Expand All @@ -323,10 +323,32 @@ export const getChildBlockNames = ( blockName ) => {
/**
* Returns a boolean indicating if a block has child blocks or not.
*
* @param {string} blockName Block type name.
* @param {string} blockName Name of block (example: “latest-posts”).
*
* @return {boolean} True if a block contains child blocks and false otherwise.
*/
export const hasChildBlocks = ( blockName ) => {
return select( 'core/blocks' ).hasChildBlocks( blockName );
};

/**
* Registers a new block style variation for the given block.
*
* @param {string} blockName Name of block (example: “core/latest-posts”).
* @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user.
*/
export const registerBlockStyle = ( blockName, styleVariation ) => {
addFilter( 'blocks.registerBlockType', `${ blockName }/${ styleVariation.name }`, ( settings, name ) => {
if ( blockName !== name ) {
return settings;
}

return {
...settings,
styles: [
...get( settings, [ 'styles' ], [] ),
styleVariation,
],
};
} );
};
32 changes: 32 additions & 0 deletions packages/blocks/src/api/test/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
hasBlockSupport,
isSharedBlock,
unstable__bootstrapServerSideBlockDefinitions, // eslint-disable-line camelcase
registerBlockStyle,
} from '../registration';

describe( 'blocks', () => {
Expand Down Expand Up @@ -595,4 +596,35 @@ describe( 'blocks', () => {
expect( isSharedBlock( block ) ).toBe( false );
} );
} );

describe( 'registerBlockStyle', () => {
afterEach( () => {
removeFilter( 'blocks.registerBlockType', 'my-plugin/block-without-styles/big' );
removeFilter( 'blocks.registerBlockType', 'my-plugin/block-without-styles/small' );
} );

it( 'should add styles', () => {
registerBlockStyle( 'my-plugin/block-without-styles', { name: 'big', label: 'Big style' } );
const settings = registerBlockType( 'my-plugin/block-without-styles', defaultBlockSettings );

expect( settings.styles ).toEqual( [
{ name: 'big', label: 'Big style' },
] );
} );

it( 'should accumulate styles', () => {
registerBlockStyle( 'my-plugin/block-without-styles', { name: 'small', label: 'Small style' } );
registerBlockStyle( 'my-plugin/block-without-styles', { name: 'big', label: 'Big style' } );
const settings = registerBlockType( 'my-plugin/block-without-styles', {
...defaultBlockSettings,
styles: [ { name: 'normal', label: 'Normal style' } ],
} );

expect( settings.styles ).toEqual( [
{ name: 'normal', label: 'Normal style' },
{ name: 'small', label: 'Small style' },
{ name: 'big', label: 'Big style' },
] );
} );
} );
} );

0 comments on commit d5f2d79

Please sign in to comment.