diff --git a/index.php b/index.php index ba63aa04e575d..139ba71466e6d 100644 --- a/index.php +++ b/index.php @@ -79,7 +79,7 @@ function gutenberg_scripts_and_styles( $hook ) { function the_gutenberg_project() { ?>
-
+
{ + return el( 'div', null, + el( 'div', { contentEditable: true }, + wp.blocks.createBlockElement( blocks[ 1 ] ) + ), + el( InserterButton, { onClick: toggleInserter, opened: inserter.opened } ) + ); +}; + +export default Editor; diff --git a/modules/editor/editor/index.js b/modules/editor/editor/index.js new file mode 100644 index 0000000000000..4b05fbad8c417 --- /dev/null +++ b/modules/editor/editor/index.js @@ -0,0 +1,41 @@ +/** + * Internal dependencies + */ +import EditorComponent from './editor'; + +const el = wp.element.createElement; + +export default class Editor { + constructor( id, settings ) { + this.toggleInserter = this.toggleInserter.bind( this ); + this.id = id; + this.settings = settings; + this.state = { + inserter: { opened: false }, + blocks: wp.blocks.parse( settings.content ) + }; + console.log( this.state.blocks ); // eslint-disable-line no-console + this.render(); + } + + setState( newState ) { + this.state = Object.assign( {}, this.state, newState ); + this.render(); + } + + toggleInserter() { + this.setState( { + inserter: { opened: ! this.state.inserter.opened } + } ); + } + + render() { + wp.element.render( + el( EditorComponent, { + state: this.state, + toggleInserter: this.toggleInserter + } ), + document.getElementById( this.id ) + ); + } +} diff --git a/modules/editor/inserter/button.js b/modules/editor/inserter/button.js new file mode 100644 index 0000000000000..d3f1eb38b172f --- /dev/null +++ b/modules/editor/inserter/button.js @@ -0,0 +1,17 @@ +/** + * Internal dependencies + */ +import Inserter from './'; + +const el = wp.element.createElement; + +const InserterButton = ( { opened, onClick } ) => { + return el( 'div', { className: 'inserter__button' }, + el( 'a', { className: 'inserter__button-toggle', onClick }, + el( 'span', { className: 'dashicons dashicons-plus' } ) + ), + opened && el( Inserter ) + ); +}; + +export default InserterButton; diff --git a/modules/editor/inserter/index.js b/modules/editor/inserter/index.js new file mode 100644 index 0000000000000..dd486099f0a40 --- /dev/null +++ b/modules/editor/inserter/index.js @@ -0,0 +1,22 @@ +const el = wp.element.createElement; + +const Inserter = () => { + const blocks = wp.blocks.getBlocks(); + + return el( 'div', { className: 'inserter' }, + el( 'div', { className: 'inserter__arrow' } ), + el( 'div', { className: 'inserter__content' }, + el( 'div', { className: 'inserter__category-blocks' }, + blocks.map( ( { slug, title, icon } ) => ( + el( 'div', { key: slug, className: 'inserter__block' }, + el( 'span', { className: 'dashicons dashicons-' + icon } ), + title + ) + ) ) + ) + ), + el( 'input', { className: 'inserter__search', type: 'search', placeholder: 'Search...' } ) + ); +}; + +export default Inserter; diff --git a/modules/editor/inserter/style.scss b/modules/editor/inserter/style.scss new file mode 100644 index 0000000000000..e247f9754e43f --- /dev/null +++ b/modules/editor/inserter/style.scss @@ -0,0 +1,136 @@ +.inserter__button { + display: inline-block; + position: relative; + background: none; + border: none; + padding: 0; + margin-top: 20px; +} + +.inserter__button-toggle { + display: inline-block; + color: #87919d; + cursor: pointer; + border-radius: 12px; + border: 2px solid #87919d; + width: 24px; + height: 24px; + padding: 0; + margin: 0; + + .dashicons { + padding: 1px 0; + } + + &:hover { + color: #12181e; + border-color: #12181e; + } +} + +.inserter { + width: 280px; + box-shadow: 0px 3px 20px rgba( 18, 24, 30, .1 ), 0px 1px 3px rgba( 18, 24, 30, .1 ); + border: 1px solid #e0e5e9; + position: absolute; + left: -130px; + bottom: 40px; + background: #fff; +} + +.inserter__arrow { + border: 10px dashed #e0e5e9; + height: 0; + line-height: 0; + position: absolute; + width: 0; + z-index: 1; + bottom: -10px; + left: 50%; + margin-left: -10px; + border-top-style: solid; + border-bottom: none; + border-left-color: transparent; + border-right-color: transparent; + + &:before { + bottom: 2px; + border: 10px solid white; + content: " "; + position: absolute; + left: 50%; + margin-left: -10px; + border-top-style: solid; + border-bottom: none; + border-left-color: transparent; + border-right-color: transparent; + } +} + +.inserter__content { + max-height: 180px; + overflow: auto; + + &:focus { + outline: none; + } +} + +.inserter__search { + display: block; + width: 100%; + border: none; + margin: 0; + border-top: 1px solid #e0e5e9; + padding: 8px 16px; + font-size: 13px; + + &:focus { + outline: none; + } +} + +.inserter__category-blocks { + display: flex; + flex-flow: row wrap; +} + +.inserter__block { + display: flex; + width: 50%; + color: #86909B; + padding: 8px; + font-size: 11px; + align-items: center; + cursor: pointer; + border: 1px solid transparent; + + &:hover { + background: #f8f9f9; + border: 1px solid #6d7882; + position: relative; + } + + &.is-active { + background: #eef0f0; + border: 1px solid #6d7882; + position: relative; + color: #3e444c; + } + + .dashicons { + color: #191e23; + margin-right: 8px; + } +} + +.inserter__separator { + background: rgb(247,248,249); + display: block; + padding: 2px 12px; + letter-spacing: 1px; + text-transform: uppercase; + font-size: 11px; + font-weight: 500; + color: #9ea7af; +}