Skip to content

Commit

Permalink
Convert list block to component with bound controls
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Jun 7, 2017
1 parent 6ecd6a8 commit ab8523b
Showing 1 changed file with 122 additions and 86 deletions.
208 changes: 122 additions & 86 deletions blocks/library/list/index.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,22 @@
/**
* WordPress dependencies
*/
import { switchChildrenNodeName } from 'element';
import { Component, createElement, switchChildrenNodeName } from 'element';
import { find } from 'lodash';
import { __ } from 'i18n';

/**
* Internal dependencies
*/
import './style.scss';
import { registerBlockType, query as hpq, createBlock } from '../../api';
import Editable from '../../editable';
import BlockControls from '../../block-controls';

const { children, prop } = hpq;

function execCommand( command ) {
return ( { editor } ) => {
if ( editor ) {
editor.execCommand( command );
}
};
}

function listIsActive( listType ) {
return ( { nodeName = 'OL', internalListType } ) => {
return listType === ( internalListType ? internalListType : nodeName );
};
}

function listSetType( listType, editorCommand ) {
return ( { internalListType, editor }, setAttributes ) => {
if ( internalListType ) {
// only change list types, don't toggle off internal lists
if ( internalListType !== listType ) {
if ( editor ) {
editor.execCommand( editorCommand );
}
}
} else {
setAttributes( { nodeName: listType } );
}
};
}

function findInternalListType( { parents } ) {
const list = find( parents, ( node ) => node.nodeName === 'UL' || node.nodeName === 'OL' );
return list ? list.nodeName : null;
}

registerBlockType( 'core/list', {
title: wp.i18n.__( 'List' ),
title: __( 'List' ),
icon: 'editor-ul',
category: 'common',

Expand All @@ -57,31 +25,6 @@ registerBlockType( 'core/list', {
values: children( 'ol,ul' ),
},

controls: [
{
icon: 'editor-ul',
title: wp.i18n.__( 'Convert to unordered' ),
isActive: listIsActive( 'UL' ),
onClick: listSetType( 'UL', 'InsertUnorderedList' ),
},
{
icon: 'editor-ol',
title: wp.i18n.__( 'Convert to ordered' ),
isActive: listIsActive( 'OL' ),
onClick: listSetType( 'OL', 'InsertOrderedList' ),
},
{
icon: 'editor-outdent',
title: wp.i18n.__( 'Outdent list item' ),
onClick: execCommand( 'Outdent' ),
},
{
icon: 'editor-indent',
title: wp.i18n.__( 'Indent list item' ),
onClick: execCommand( 'Indent' ),
},
],

transforms: {
from: [
{
Expand All @@ -108,36 +51,129 @@ registerBlockType( 'core/list', {
],
},

edit( { attributes, setAttributes, focus, setFocus } ) {
const { nodeName = 'OL', values = [] } = attributes;
return (
<Editable
tagName={ nodeName.toLowerCase() }
getSettings={ ( settings ) => ( {
...settings,
plugins: ( settings.plugins || [] ).concat( 'lists' ),
lists_indent_on_tab: false,
} ) }
onSetup={ ( editor ) => {
editor.on( 'nodeChange', ( nodeInfo ) => {
setAttributes( { internalListType: findInternalListType( nodeInfo ) } );
} );
setAttributes( { editor } );
} }
onChange={ ( nextValues ) => {
setAttributes( { values: nextValues } );
} }
value={ values }
focus={ focus }
onFocus={ setFocus }
className="blocks-list" />
);
edit: class extends Component {
constructor() {
super( ...arguments );

this.setupEditor = this.setupEditor.bind( this );
this.getEditorSettings = this.getEditorSettings.bind( this );
this.setNextValues = this.setNextValues.bind( this );

this.state = {
internalListType: null,
};
}

isListActive( listType ) {
const { internalListType } = this.state;
const { nodeName = 'OL' } = this.props.attributes;

return listType === ( internalListType ? internalListType : nodeName );
}

findInternalListType( { parents } ) {
const list = find( parents, ( node ) => node.nodeName === 'UL' || node.nodeName === 'OL' );
return list ? list.nodeName : null;
}

setupEditor( editor ) {
editor.on( 'nodeChange', ( nodeInfo ) => {
this.setState( {
internalListType: this.findInternalListType( nodeInfo ),
} );
} );

this.editor = editor;
}

createSetListType( type, command ) {
return () => {
const { setAttributes } = this.props;
const { internalListType } = this.state;
if ( internalListType ) {
// only change list types, don't toggle off internal lists
if ( internalListType !== type && this.editor ) {
this.editor.execCommand( command );
}
} else {
setAttributes( { nodeName: type } );
}
};
}

createExecCommand( command ) {
return () => {
if ( this.editor ) {
this.editor.execCommand( command );
}
};
}

getEditorSettings( settings ) {
return {
...settings,
plugins: ( settings.plugins || [] ).concat( 'lists' ),
lists_indent_on_tab: false,
};
}

setNextValues( nextValues ) {
this.props.setAttributes( { values: nextValues } );
}

render() {
const { attributes, focus, setFocus } = this.props;
const { nodeName = 'OL', values = [] } = attributes;

return [
focus && (
<BlockControls
key="controls"
controls={ [
{
icon: 'editor-ul',
title: __( 'Convert to unordered' ),
isActive: this.isListActive( 'UL' ),
onClick: this.createSetListType( 'UL', 'InsertUnorderedList' ),
},
{
icon: 'editor-ol',
title: __( 'Convert to ordered' ),
isActive: this.isListActive( 'OL' ),
onClick: this.createSetListType( 'OL', 'InsertOrderedList' ),
},
{
icon: 'editor-outdent',
title: __( 'Outdent list item' ),
onClick: this.createExecCommand( 'Outdent' ),
},
{
icon: 'editor-indent',
title: __( 'Indent list item' ),
onClick: this.createExecCommand( 'Indent' ),
},
] }
/>
),
<Editable
key="editable"
tagName={ nodeName.toLowerCase() }
getSettings={ this.getEditorSettings }
onSetup={ this.setupEditor }
onChange={ this.setNextValues }
value={ values }
focus={ focus }
onFocus={ setFocus }
className="blocks-list"
/>,
];
}
},

save( { attributes } ) {
const { nodeName = 'OL', values = [] } = attributes;

return wp.element.createElement(
return createElement(
nodeName.toLowerCase(),
null,
values
Expand Down

0 comments on commit ab8523b

Please sign in to comment.