Skip to content

Commit

Permalink
Blocks: Introduce block definitions and implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad committed May 14, 2018
1 parent 09e2da3 commit 32a6a17
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 6 deletions.
16 changes: 14 additions & 2 deletions blocks/api/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* External dependencies
*/
import { get, isFunction, some } from 'lodash';
import { get, isFunction, some, pick, omit, mapValues } from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -137,7 +137,19 @@ export function registerBlockType( name, settings ) {
settings.icon = 'block-default';
}

dispatch( 'core/blocks' ).addBlockTypes( settings );
const blockTypeDefinition = omit( settings, [ 'transforms', 'edit', 'save', 'icon', 'getEditWrapperProps' ] );
blockTypeDefinition.attributes = mapValues(
settings.attributes,
( attribute ) => pick( attribute, [ 'type', 'default' ] )
);
const blockTypeImplementation = pick( settings, [ 'name', 'transforms', 'edit', 'save', 'icon', 'getEditWrapperProps' ] );
blockTypeImplementation.attributes = mapValues(
settings.attributes,
( attribute ) => omit( attribute, [ 'type', 'default' ] )
);

dispatch( 'core/blocks' ).addBlockTypes( blockTypeDefinition );
dispatch( 'core/blocks' ).implementBlockTypes( blockTypeImplementation );

return settings;
}
Expand Down
14 changes: 14 additions & 0 deletions blocks/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ export function addBlockTypes( blockTypes ) {
};
}

/**
* Returns an action object used in signalling that block types have been added.
*
* @param {Array|Object} implementations Block types implementations.
*
* @return {Object} Action object.
*/
export function implementBlockTypes( implementations ) {
return {
type: 'IMPLEMENT_BLOCK_TYPES',
implementations: castArray( implementations ),
};
}

/**
* Returns an action object used to remove a registered block type.
*
Expand Down
23 changes: 23 additions & 0 deletions blocks/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,28 @@ export function blockTypes( state = {}, action ) {
return state;
}

/**
* Reducer managing the block type implementations
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
export function implementations( state = {}, action ) {
switch ( action.type ) {
case 'IMPLEMENT_BLOCK_TYPES':
return {
...state,
...keyBy( action.implementations, 'name' ),
};
case 'REMOVE_BLOCK_TYPES':
return omit( state, action.names );
}

return state;
}

/**
* Higher-order Reducer creating a reducer keeping track of given block name.
*
Expand Down Expand Up @@ -91,6 +113,7 @@ export function categories( state = DEFAULT_CATEGORIES, action ) {

export default combineReducers( {
blockTypes,
implementations,
defaultBlockName,
fallbackBlockName,
categories,
Expand Down
33 changes: 29 additions & 4 deletions blocks/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import createSelector from 'rememo';
import { mapValues, compact } from 'lodash';

/**
* Returns all the available block types.
Expand All @@ -11,9 +12,10 @@ import createSelector from 'rememo';
* @return {Array} Block Types.
*/
export const getBlockTypes = createSelector(
( state ) => Object.values( state.blockTypes ),
( state ) => compact( Object.values( state.blockTypes ).map( ( { name } ) => getBlockType( state, name ) ) ),
( state ) => [
state.blockTypes,
state.implementations,
]
);

Expand All @@ -25,9 +27,32 @@ export const getBlockTypes = createSelector(
*
* @return {Object?} Block Type.
*/
export function getBlockType( state, name ) {
return state.blockTypes[ name ];
}
export const getBlockType = createSelector(
( state, name ) => {
const blockTypeDefinition = state.blockTypes[ name ];
const blockTypeImplementation = state.implementations[ name ];

if ( ! blockTypeDefinition || ! blockTypeImplementation ) {
return null;
}

return {
...blockTypeDefinition,
...blockTypeImplementation,
attributes: mapValues( blockTypeDefinition.attributes, ( attribute, key ) => {
const implementationAttribute = blockTypeImplementation.attributes ? blockTypeImplementation.attributes[ key ] : {};
return {
...attribute,
...implementationAttribute,
};
} ),
};
},
( state ) => [
state.blockTypes,
state.implementations,
]
);

/**
* Returns all the available categories.
Expand Down

0 comments on commit 32a6a17

Please sign in to comment.