diff --git a/core-blocks/index.js b/core-blocks/index.js
index 6782e3c5b6ef69..35a2c3fe709d8b 100644
--- a/core-blocks/index.js
+++ b/core-blocks/index.js
@@ -26,6 +26,9 @@ import * as coverImage from './cover-image';
import * as embed from './embed';
import * as file from './file';
import * as freeform from './freeform';
+import * as halfMediaText from './layout-half-media-text';
+import * as halfMediaTextContent from './layout-half-media-text/content-area';
+import * as halfMediaTextMedia from './layout-half-media-text/media-area';
import * as html from './html';
import * as latestPosts from './latest-posts';
import * as list from './list';
@@ -68,6 +71,9 @@ export const registerCoreBlocks = () => {
...embed.others,
file,
freeform,
+ halfMediaText,
+ halfMediaTextContent,
+ halfMediaTextMedia,
html,
latestPosts,
more,
diff --git a/core-blocks/layout-half-media-text/content-area.js b/core-blocks/layout-half-media-text/content-area.js
new file mode 100644
index 00000000000000..2ca90c8138d12a
--- /dev/null
+++ b/core-blocks/layout-half-media-text/content-area.js
@@ -0,0 +1,46 @@
+/**
+ * WordPress dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { InnerBlocks } from '@wordpress/editor';
+
+/**
+ * Internal dependencies
+ */
+import './style.scss';
+import './editor.scss';
+
+export const name = 'core/half-media-content-area';
+
+const ALLOWED_BLOCKS = [ 'core/button', 'core/paragraph', 'core/heading' ];
+
+export const settings = {
+ attributes: {},
+
+ title: __( 'Content Area' ),
+
+ parent: [ 'core/half-media' ],
+
+ icon: 'format-image',
+
+ category: 'common',
+
+ edit() {
+ return (
+
+
+
+ );
+ },
+
+ save() {
+ return
;
+ },
+};
diff --git a/core-blocks/layout-half-media-text/editor.scss b/core-blocks/layout-half-media-text/editor.scss
new file mode 100644
index 00000000000000..cd1af3ff4f1a58
--- /dev/null
+++ b/core-blocks/layout-half-media-text/editor.scss
@@ -0,0 +1,27 @@
+.half-media__media .block-alignment-toolbar {
+ display: none;
+}
+
+.half-media {
+ display: block;
+}
+
+.half-media > .editor-inner-blocks > .editor-block-list__layout {
+ display: flex;
+ > [data-type="core/half-media-media-area"],
+ > [data-type="core/half-media-content-area"] {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ width: 0;
+ .editor-block-list__block-edit {
+ flex-basis: 100%;
+ }
+ }
+ > [data-type="core/half-media-content-area"] > .editor-block-list__block-edit {
+ display: flex;
+ }
+}
+
+
+
diff --git a/core-blocks/layout-half-media-text/index.js b/core-blocks/layout-half-media-text/index.js
new file mode 100644
index 00000000000000..f61c424c546d61
--- /dev/null
+++ b/core-blocks/layout-half-media-text/index.js
@@ -0,0 +1,52 @@
+/**
+ * WordPress dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import {
+ InnerBlocks,
+} from '@wordpress/editor';
+
+/**
+ * Internal dependencies
+ */
+import './style.scss';
+import './editor.scss';
+
+export const name = 'core/half-media';
+
+export const settings = {
+ title: __( 'Half Media' ),
+
+ icon: 'columns',
+
+ category: 'layout',
+
+ attributes: {
+ },
+
+ supports: {
+ align: [ 'wide', 'full' ],
+ },
+
+ edit() {
+ return (
+
+
+
+ );
+ },
+
+ save() {
+ return (
+
+
+
+ );
+ },
+};
diff --git a/core-blocks/layout-half-media-text/media-area.js b/core-blocks/layout-half-media-text/media-area.js
new file mode 100644
index 00000000000000..64225086d1c6a7
--- /dev/null
+++ b/core-blocks/layout-half-media-text/media-area.js
@@ -0,0 +1,62 @@
+/**
+ * WordPress dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { InnerBlocks, BlockPlaceholder } from '@wordpress/editor';
+import { withSelect } from '@wordpress/data';
+
+/**
+ * Internal dependencies
+ */
+import './style.scss';
+import './editor.scss';
+
+export const name = 'core/half-media-media-area';
+const ALLOWED_BLOCKS = [
+ 'core/image',
+ 'core/video',
+ 'core-embed/flickr',
+ 'core-embed/youtube',
+ 'core-embed/vimeo',
+ 'core-embed/videopress',
+];
+
+export const settings = {
+ attributes: {},
+
+ title: __( 'Media Area' ),
+
+ parent: [ 'core/half-media' ],
+
+ icon: 'format-image',
+
+ category: 'common',
+
+ edit: withSelect( ( select, { id } ) => {
+ const { getBlockOrder } = select( 'core/editor' );
+ const blocksInside = getBlockOrder( id );
+ return {
+ hasInnerBlocks: blocksInside && blocksInside.length > 0,
+ };
+ } )(
+ ( { id, hasInnerBlocks } ) => {
+ return (
+
+
+ { ! hasInnerBlocks && (
+
+ ) }
+
+ );
+ }
+ ),
+
+ save() {
+ return
;
+ },
+};
diff --git a/core-blocks/layout-half-media-text/style.scss b/core-blocks/layout-half-media-text/style.scss
new file mode 100644
index 00000000000000..7cd0205e674eee
--- /dev/null
+++ b/core-blocks/layout-half-media-text/style.scss
@@ -0,0 +1,29 @@
+.layout-column-2 {
+
+}
+
+.half-image__content-area {
+ margin-left: 28px;
+}
+
+.half-media {
+ display: flex;
+}
+
+.half-media__content {
+ flex: 1;
+ word-break: break-word;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ padding: 5px;
+}
+
+.half-media__media {
+ flex: 1;
+ padding: 5px;
+}
+
+.half-media__content {
+
+}
diff --git a/editor/components/block-alignment-toolbar/index.js b/editor/components/block-alignment-toolbar/index.js
index 6477611dcd7b85..68e4e0a7d21b2d 100644
--- a/editor/components/block-alignment-toolbar/index.js
+++ b/editor/components/block-alignment-toolbar/index.js
@@ -42,6 +42,7 @@ export function BlockAlignmentToolbar( { value, onChange, controls = DEFAULT_CON
return (
{
return {
diff --git a/editor/components/block-alignment-toolbar/test/__snapshots__/index.js.snap b/editor/components/block-alignment-toolbar/test/__snapshots__/index.js.snap
index 273ad8f56496ee..d04e0d031cb350 100644
--- a/editor/components/block-alignment-toolbar/test/__snapshots__/index.js.snap
+++ b/editor/components/block-alignment-toolbar/test/__snapshots__/index.js.snap
@@ -2,6 +2,7 @@
exports[`BlockAlignmentToolbar should match snapshot 1`] = `
+
+
+ );
+ }
+}
+
+export default BlockPlaceholder;
diff --git a/editor/components/index.js b/editor/components/index.js
index 0ae4fbc914cfb9..a7c3afa6e47534 100644
--- a/editor/components/index.js
+++ b/editor/components/index.js
@@ -7,6 +7,7 @@ export { default as BlockControls } from './block-controls';
export { default as BlockEdit } from './block-edit';
export { default as BlockFormatControls } from './block-format-controls';
export { default as BlockIcon } from './block-icon';
+export { default as BlockPlaceholder } from './block-placeholder';
export { default as ColorPalette } from './color-palette';
export { default as withColorContext } from './color-palette/with-color-context';
export * from './colors';
diff --git a/editor/components/inserter/index.js b/editor/components/inserter/index.js
index e20c95c2033001..c9a9b2a10926ad 100644
--- a/editor/components/inserter/index.js
+++ b/editor/components/inserter/index.js
@@ -79,14 +79,16 @@ class Inserter extends Component {
}
export default compose( [
- withSelect( ( select ) => {
+ withSelect( ( select, { insertionPoint } ) => {
const {
getEditedPostAttribute,
getBlockInsertionPoint,
getSelectedBlock,
getInserterItems,
} = select( 'core/editor' );
- const insertionPoint = getBlockInsertionPoint();
+ if ( ! insertionPoint ) {
+ insertionPoint = getBlockInsertionPoint();
+ }
const { rootUID } = insertionPoint;
return {
title: getEditedPostAttribute( 'title' ),