Skip to content

Commit

Permalink
TinyMCE per block: Adding transform block API (#204)
Browse files Browse the repository at this point in the history
- I implemented text,quote,heading transformations for now
  • Loading branch information
youknowriad authored Mar 8, 2017
1 parent 6f64aa1 commit 8dc70e0
Show file tree
Hide file tree
Showing 23 changed files with 267 additions and 74 deletions.
1 change: 1 addition & 0 deletions tinymce-per-block/src/assets/stylesheets/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
@import '~renderers/block/block-list/style';
@import '~renderers/html/html-editor/style';
@import '~controls/editable-format-toolbar/style';
@import '~controls/transform-block-toolbar/style';
@import '~inserter/style';

* {
Expand Down
7 changes: 5 additions & 2 deletions tinymce-per-block/src/blocks/embed-block/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default class EmbedBlockForm extends Component {

render() {
const { block, isSelected, change, moveCursorUp, moveCursorDown,
remove, focusConfig, focus, moveBlockUp, moveBlockDown, appendBlock } = this.props;
remove, focusConfig, focus, moveBlockUp, moveBlockDown, appendBlock, unselect } = this.props;

const removePrevious = () => {
if ( ! block.url ) {
Expand Down Expand Up @@ -81,7 +81,10 @@ export default class EmbedBlockForm extends Component {
moveCursorDown={ moveCursorDown }
splitValue={ splitValue }
value={ block.caption }
onChange={ ( value ) => change( { caption: value } ) }
onChange={ ( value ) => {
change( { caption: value } );
unselect();
} }
placeholder="Write caption"
focusConfig={ focusConfig }
onFocusChange={ focus }
Expand Down
8 changes: 6 additions & 2 deletions tinymce-per-block/src/blocks/heading-block/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import InlineTextBlockForm from '../inline-text-block/form';
import EditableFormatToolbar from 'controls/editable-format-toolbar';
import BlockArrangement from 'controls/block-arrangement';
import TransformBlockToolbar from 'controls/transform-block-toolbar';

export default class HeadingBlockForm extends Component {
bindForm = ( ref ) => {
Expand All @@ -32,7 +33,7 @@ export default class HeadingBlockForm extends Component {
};

render() {
const { block, isSelected, moveBlockUp, moveBlockDown } = this.props;
const { block, isSelected, moveBlockUp, moveBlockDown, select, transform } = this.props;
const sizes = [
{ id: 'h1', icon: EditorHeading1Icon },
{ id: 'h2', icon: EditorHeading2Icon },
Expand All @@ -45,6 +46,9 @@ export default class HeadingBlockForm extends Component {
moveBlockUp={ moveBlockUp } moveBlockDown={ moveBlockDown } /> }
{ isSelected && (
<div className="block-list__block-controls">
<div className="block-list__block-controls-group">
<TransformBlockToolbar blockType="heading" onTransform={ transform } />
</div>
<div className="block-list__block-controls-group">
{ sizes.map( ( { id, icon: Icon } ) =>
<button
Expand All @@ -64,7 +68,7 @@ export default class HeadingBlockForm extends Component {
</div>
</div>
) }
<div className={ `heading-block__form ${ block.size }` }>
<div className={ `heading-block__form ${ block.size }` } onClick={ select }>
<InlineTextBlockForm
ref={ this.bindForm }
{ ...this.props }
Expand Down
22 changes: 15 additions & 7 deletions tinymce-per-block/src/blocks/heading-block/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import { EditorHeadingIcon } from 'dashicons';
*/
import form from './form';

const createHeadingBlockWithContent = ( content = '' ) => {
return {
blockType: 'heading',
size: 'h2',
content
};
};

registerBlock( 'heading', {
title: 'Heading',
form: form,
Expand Down Expand Up @@ -40,11 +48,11 @@ registerBlock( 'heading', {
rawContent
};
},
create: () => {
return {
blockType: 'heading',
content: '',
size: 'h2'
};
}
create: createHeadingBlockWithContent,
transformations: [
{
blocks: [ 'text', 'quote' ],
transform: ( block ) => createHeadingBlockWithContent( block.content )
}
]
} );
5 changes: 3 additions & 2 deletions tinymce-per-block/src/blocks/html-block/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default class HtmlBlockForm extends Component {

render() {
const { block, isSelected, change, moveCursorUp, moveCursorDown, appendBlock,
mergeWithPrevious, remove, focusConfig, focus, moveBlockUp, moveBlockDown } = this.props;
mergeWithPrevious, remove, focusConfig, focus, moveBlockUp, moveBlockDown, select, unselect } = this.props;
const splitValue = ( left, right ) => {
change( { content: left } );
if ( right ) {
Expand Down Expand Up @@ -72,7 +72,7 @@ export default class HtmlBlockForm extends Component {
</div>
</div>
) }
<div className="html-block__form" style={ style }>
<div className="html-block__form" style={ style } onClick={ select }>
<EditableComponent
ref={ this.bindEditable }
content={ block.content }
Expand All @@ -85,6 +85,7 @@ export default class HtmlBlockForm extends Component {
onChange={ ( value ) => change( { content: value } ) }
focusConfig={ focusConfig }
onFocusChange={ focus }
onType={ unselect }
/>
</div>
</div>
Expand Down
43 changes: 24 additions & 19 deletions tinymce-per-block/src/blocks/image-block/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default class ImageBlockForm extends Component {

render() {
const { block, change, moveCursorDown, moveCursorUp, remove, appendBlock,
isSelected, focusConfig, focus, moveBlockUp, moveBlockDown } = this.props;
isSelected, focusConfig, focus, moveBlockUp, moveBlockDown, select, unselect } = this.props;
const removePrevious = () => {
if ( ! block.caption ) {
remove();
Expand All @@ -45,25 +45,30 @@ export default class ImageBlockForm extends Component {
</div>
</div>
}
<img
src={ block.src }
className="image-block__display"
onClick={ () => {
! focusConfig && focus();
} }
/>
<div className="image-block__caption">
<EnhancedInputComponent
moveCursorUp={ moveCursorUp }
removePrevious={ removePrevious }
moveCursorDown={ moveCursorDown }
splitValue={ splitValue }
value={ block.caption }
onChange={ ( value ) => change( { caption: value } ) }
placeholder="Write caption"
focusConfig={ focusConfig }
onFocusChange={ focus }
<div onClick={ select }>
<img
src={ block.src }
className="image-block__display"
onClick={ () => {
! focusConfig && focus();
} }
/>
<div className="image-block__caption">
<EnhancedInputComponent
moveCursorUp={ moveCursorUp }
removePrevious={ removePrevious }
moveCursorDown={ moveCursorDown }
splitValue={ splitValue }
value={ block.caption }
onChange={ ( value ) => {
change( { caption: value } );
unselect();
} }
placeholder="Write caption"
focusConfig={ focusConfig }
onFocusChange={ focus }
/>
</div>
</div>
</div>
);
Expand Down
3 changes: 2 additions & 1 deletion tinymce-per-block/src/blocks/inline-text-block/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class InlineTextBlockForm extends Component {

render() {
const { block, change, moveCursorUp, moveCursorDown, appendBlock,
mergeWithPrevious, remove, setToolbarState, focus, focusConfig } = this.props;
mergeWithPrevious, remove, setToolbarState, focus, focusConfig, unselect } = this.props;

const splitValue = ( left, right ) => {
change( { content: left } );
Expand Down Expand Up @@ -65,6 +65,7 @@ export default class InlineTextBlockForm extends Component {
setToolbarState={ setToolbarState }
focusConfig={ focusConfig }
onFocusChange={ focus }
onType={ unselect }
inline
single
/>
Expand Down
18 changes: 13 additions & 5 deletions tinymce-per-block/src/blocks/quote-block/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
*/
import { createElement, Component } from 'wp-elements';

import { EditableComponent, EnhancedInputComponent } from 'wp-blocks';
import { serialize } from 'serializers/block';
import { parse } from 'parsers/block';
/**
* Internal dependencies
*/
import { EditableComponent } from 'wp-blocks';
import EditableFormatToolbar from 'controls/editable-format-toolbar';
import BlockArrangement from 'controls/block-arrangement';
import TransformBlockToolbar from 'controls/transform-block-toolbar';

export default class QuoteBlockForm extends Component {
bindContent = ( ref ) => {
Expand Down Expand Up @@ -59,7 +61,7 @@ export default class QuoteBlockForm extends Component {
render() {
const { block, change, moveCursorUp, moveCursorDown, remove,
mergeWithPrevious, appendBlock, isSelected, focusConfig, focus,
moveBlockUp, moveBlockDown } = this.props;
moveBlockUp, moveBlockDown, select, unselect, transform } = this.props;
const splitValue = ( left, right ) => {
change( { cite: left } );
appendBlock( {
Expand All @@ -78,13 +80,17 @@ export default class QuoteBlockForm extends Component {
moveBlockUp={ moveBlockUp } moveBlockDown={ moveBlockDown } /> }
{ isSelected &&
<div className="block-list__block-controls">
<div className="block-list__block-controls-group">
<TransformBlockToolbar blockType="quote" onTransform={ transform } />
</div>

<div className="block-list__block-controls-group">
<EditableFormatToolbar editable={ focusInput === 'content' ? this.content : this.cite } ref={ this.bindFormatToolbar } />
</div>
</div>
}

<div className="quote-block__form">
<div className="quote-block__form" onClick={ select }>
<div className="quote-block__content">
<EditableComponent
ref={ this.bindContent }
Expand All @@ -97,6 +103,7 @@ export default class QuoteBlockForm extends Component {
setToolbarState={ focusInput === 'content' ? this.setToolbarState : undefined }
focusConfig={ focusInput === 'content' ? focusConfig : null }
onFocusChange={ ( config ) => focus( Object.assign( { input: 'content' }, config ) ) }
onType={ unselect }
inline
/>
</div>
Expand All @@ -113,6 +120,7 @@ export default class QuoteBlockForm extends Component {
setToolbarState={ focusInput === 'cite' ? this.setToolbarState : undefined }
focusConfig={ focusInput === 'cite' ? focusConfig : null }
onFocusChange={ ( config ) => focus( Object.assign( { input: 'cite' }, config ) ) }
onType={ unselect }
inline
single
/>
Expand Down
22 changes: 15 additions & 7 deletions tinymce-per-block/src/blocks/quote-block/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ import {
*/
import form from './form';

const createQuoteBlockWithContent = ( content = '' ) => {
return {
blockType: 'quote',
cite: '',
content
};
};

registerBlock( 'quote', {
title: 'Quote',
form: form,
Expand Down Expand Up @@ -55,11 +63,11 @@ registerBlock( 'quote', {
rawContent
};
},
create: () => {
return {
blockType: 'quote',
cite: '',
content: ''
};
}
create: createQuoteBlockWithContent,
transformations: [
{
blocks: [ 'text', 'heading' ],
transform: ( block ) => createQuoteBlockWithContent( block.content )
}
]
} );
9 changes: 7 additions & 2 deletions tinymce-per-block/src/blocks/text-block/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { createElement, Component } from 'wp-elements';
import EditableFormatToolbar from 'controls/editable-format-toolbar';
import AlignmentToolbar from 'controls/alignment-toolbar';
import BlockArrangement from 'controls/block-arrangement';
import TransformBlockToolbar from 'controls/transform-block-toolbar';
import InlineTextBlockForm from 'blocks/inline-text-block/form';
import InserterButton from 'inserter/button';

Expand All @@ -28,7 +29,7 @@ export default class TextBlockForm extends Component {
};

render() {
const { block, isSelected, focusConfig, moveBlockUp, moveBlockDown, replace } = this.props;
const { block, isSelected, focusConfig, moveBlockUp, moveBlockDown, replace, select, transform } = this.props;
const selectedTextAlign = block.align || 'left';
const style = {
textAlign: selectedTextAlign
Expand All @@ -40,6 +41,10 @@ export default class TextBlockForm extends Component {
moveBlockUp={ moveBlockUp } moveBlockDown={ moveBlockDown } /> }
{ isSelected &&
<div className="block-list__block-controls">
<div className="block-list__block-controls-group">
<TransformBlockToolbar blockType="text" onTransform={ transform } />
</div>

<div className="block-list__block-controls-group">
<AlignmentToolbar value={ block.align } onChange={ this.setAlignment } />
</div>
Expand All @@ -50,7 +55,7 @@ export default class TextBlockForm extends Component {
</div>
}

<div className="text-block__form" style={ style }>
<div className="text-block__form" style={ style } onClick={ select }>
{ ! block.content.trim() && ! isSelected && focusConfig &&
<InserterButton onAdd={ ( id ) => replace( id ) } />
}
Expand Down
22 changes: 15 additions & 7 deletions tinymce-per-block/src/blocks/text-block/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import { EditorParagraphIcon } from 'dashicons';
*/
import form from './form';

const createTextBlockWithContent = ( content = '' ) => {
return {
blockType: 'text',
align: 'no-align',
content
};
};

registerBlock( 'text', {
title: 'Text',
form: form,
Expand Down Expand Up @@ -44,11 +52,11 @@ registerBlock( 'text', {
rawContent
};
},
create: () => {
return {
blockType: 'text',
content: '',
align: 'no-align'
};
}
create: () => createTextBlockWithContent,
transformations: [
{
blocks: [ 'heading', 'quote' ],
transform: ( block ) => createTextBlockWithContent( block.content )
}
]
} );
12 changes: 2 additions & 10 deletions tinymce-per-block/src/controls/block-arrangement.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,14 @@ import { ArrowDownAlt2Icon, ArrowUpAlt2Icon } from 'dashicons';
export default function BlockArrangement( { block, moveBlockUp, moveBlockDown } ) {
const blockDefinition = getBlock( block.blockType );
const Icon = blockDefinition.icon;
const onMoveUp = ( event ) => {
event.stopPropagation();
moveBlockUp();
};
const onMoveDown = ( event ) => {
event.stopPropagation();
moveBlockDown();
};

return (
<div className="block-list__block-arrangement">
<div className="block-list__movement-controls">
<button className="block-list__block-arrange-control" onClick={ onMoveUp }>
<button className="block-list__block-arrange-control" onClick={ moveBlockUp }>
<ArrowUpAlt2Icon />
</button>
<button className="block-list__block-arrange-control" onClick={ onMoveDown }>
<button className="block-list__block-arrange-control" onClick={ moveBlockDown }>
<ArrowDownAlt2Icon />
</button>
</div>
Expand Down
Loading

0 comments on commit 8dc70e0

Please sign in to comment.