diff --git a/assets/css/amp-editor-story-blocks.css b/assets/css/amp-editor-story-blocks.css
index 3ddca086414..65d285abd81 100644
--- a/assets/css/amp-editor-story-blocks.css
+++ b/assets/css/amp-editor-story-blocks.css
@@ -1,3 +1,33 @@
+/*------------------------------------------------------------------
+[Table of contents]
+
+ 1. Style story pages wrapper
+ 2. Selected state
+ 2.1 Selected label
+ 3. Story page dimensions
+ 4. Layers stacking
+ 4.1 Hide layers above
+ 4.2 Blur layers above
+ 4.3 Stroke text for legibility.
+ 5. Layers Styling
+ 5.1 Thirds Layer
+ 5.2 Fill layer
+ 5.3 CTA layer
+ 6. Inserter customisations.
+ 6.1 Ghosted page inserter
+ 7. Block navigator
+ 8. Shame
+ 8.1 Gutenberg - Warning div not clickable
+
+-------------------------------------------------------------------*/
+
+
+/*
+ * 1. Style story pages wrapper.
+ * - Add thicker border around the pages
+ * - Change background to light gray
+ */
+
div[data-type="amp/amp-story-page"] {
border: 10px solid #eff0f1;
}
@@ -12,19 +42,62 @@ div[data-type="amp/amp-story-page"]::after {
background: #eff0f1;
}
+.editor-block-list__layout div[data-type="amp/amp-story-page"] .components-placeholder.wp-block-image {
+ background: #f9f9f9;
+}
+
+/*
+ * 2. Selected state outlines.
+ * Change default gray selected highlights into blue,
+ * as gray was not visible in a multi-layer setup.
+ */
+
.editor-block-list__layout div[data-type="amp/amp-story-page"].is-selected > .editor-block-list__block-edit::before {
outline: 1px solid #007cba;
}
+.amp-grid-template .editor-block-list__layout .editor-block-list__block.is-selected > .editor-block-list__block-edit::before,
+.amp-grid-template .editor-block-list__layout .editor-block-list__block.is-typing > .editor-block-list__block-edit::before,
+div[data-type="amp/amp-story-cta-layer"] .editor-block-list__layout .editor-block-list__block.is-selected > .editor-block-list__block-edit::before
+{
+ outline: 1px solid #007cba;
+}
+
+div[data-type="amp/amp-story-page"] > div > div > .is-selected-parent > .editor-inner-blocks > .editor-block-list__layout > .is-selected > .editor-block-list__block-edit::before {
+ outline: 1px solid #007cba;
+}
+
+/* Remove one default outline as it was unnecessary with the above implementation. */
+
+.editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit::before {
+ outline: none;
+}
+
+/*
+ * 2.1 Selected label
+ * Show label while the layer is selected
+ */
+
+ .post-type-amp_story .editor-block-list__breadcrumb {
+ z-index: 6;
+ pointer-events: none;
+ }
+
+ .post-type-amp_story .editor-block-list__block:hover .editor-block-list__breadcrumb .components-toolbar {
+ opacity: 1;
+ animation: none;
+ }
+
+/*
+ * 3. Story page dimensions.
+ * Fix the page editor size to the ratio of the stories.
+ */
+
.editor-block-list__layout div[data-type="amp/amp-story-page"] {
padding: 0;
margin: 60px auto 0;
}
-.editor-block-list__layout div[data-type="amp/amp-story-page"] .components-placeholder.wp-block-image {
- background: #f9f9f9;
-}
-
@media (min-width: 600px) {
div[data-type="amp/amp-story-page"] .editor-block-list__block {
margin: 0;
@@ -32,14 +105,6 @@ div[data-type="amp/amp-story-page"]::after {
}
}
-.components-popover.editor-inserter__amp .components-popover__content {
- height: 200px;
-}
-
-.editor-inserter__popover .amp-story-has-cta-layer .editor-block-list-item-amp-amp-story-cta-layer {
- opacity: 0.5;
-}
-
div[data-type="amp/amp-story-page"],
div[data-type="amp/amp-story-page"] .editor-inner-blocks .editor-block-list__layout:first-of-type {
margin: auto;
@@ -50,14 +115,19 @@ div[data-type="amp/amp-story-page"] .editor-inner-blocks .editor-block-list__lay
div[data-type="amp/amp-story-page"] .editor-block-list__layout > .block-list-appender {
width: 316px;
-
}
+/* Also override needed core inline styles. */
+
.editor-block-list__layout div[data-type="amp/amp-story-cta-layer"] .editor-inner-blocks .editor-block-list__layout {
min-height: initial !important;
}
-/* Make layer be exactly on top of each other */
+/*
+ * 4. Layers stacking.
+ * Setup on top of each other layering on the story children.
+ */
+
.editor-block-list__layout div[data-type="amp/amp-story-page"].editor-block-list__block:first-child .editor-block-list__block-edit {
margin: 0;
}
@@ -77,6 +147,10 @@ div[data-type="amp/amp-story-page"] .editor-inner-blocks .editor-block-list__lay
width: 100%;
}
+.editor-block-list__layout div[data-amp-selected="parent"] {
+ z-index: 1;
+}
+
.amp-grid-template .editor-block-list__layout:first-of-type {
display: grid;
padding: 68px 32px 32px;
@@ -95,13 +169,84 @@ div[data-type="amp/amp-story-page"] .editor-inner-blocks .editor-block-list__lay
box-sizing: border-box;
}
-.amp-grid-template .editor-block-list__layout .editor-block-list__block.is-selected > .editor-block-list__block-edit::before,
-.amp-grid-template .editor-block-list__layout .editor-block-list__block.is-typing > .editor-block-list__block-edit::before,
-div[data-type="amp/amp-story-cta-layer"] .editor-block-list__layout .editor-block-list__block.is-selected > .editor-block-list__block-edit::before
-{
- outline: 1px solid #007cba;
+.amp-grid-template-horizontal .editor-block-list__layout:first-of-type {
+ grid-auto-flow: column !important;
+ grid-template-rows: 100% !important;
+ -ms-flex-line-pack: stretch;
+ align-content: stretch;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: start;
+ grid-gap: 16px;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: start;
+}
+
+.amp-grid-template-vertical .editor-block-list__layout:first-of-type {
+ grid-auto-flow: row;
+ grid-template-columns: 100%;
+ align-content: start;
+ grid-gap: 16px;
+ -webkit-box-pack: stretch;
+ -ms-flex-pack: stretch;
+ justify-content: stretch;
+ justify-items: start;
}
+.amp-grid-template-vertical .editor-block-list__block {
+ width: 100%;
+}
+
+/*
+ * 4.1 Hide layers above
+ * Hide elements above the currently selected layer.
+ */
+
+.editor-block-list__layout div[data-amp-type="grid"]:not(.is-selected):not(.is-selected-parent) .editor-block-list__block {
+ z-index: 0;
+}
+
+.editor-block-list__layout div[data-amp-type="grid"]:not(.is-selected):not(.is-selected-parent) .editor-block-list__block p[data-is-placeholder-visible="true"] ~ p {
+ display: none;
+}
+
+.editor-block-list__layout div[data-amp-type="grid"].is-selected ~ div[data-amp-type="grid"],
+.editor-block-list__layout div[data-amp-type="grid"][data-amp-selected="parent"] ~ div[data-amp-type="grid"],
+.editor-block-list__layout div[data-amp-type="grid"].is-selected ~ div[data-type="amp/amp-story-cta-layer"],
+.editor-block-list__layout div[data-amp-type="grid"][data-amp-selected="parent"] ~ div[data-type="amp/amp-story-cta-layer"]{
+ display: none;
+}
+
+/*
+ * 4.2 Blur layers above
+ * Layers - Blur and fade out the layers beneath the currently selected layer.
+ */
+
+.editor-block-list__layout > div {
+ transition: .3s;
+ transition-property: opacity, filter;
+}
+
+div[data-type="amp/amp-story-page"] > div > div > .is-selected-parent > .editor-inner-blocks > .editor-block-list__layout > .wp-block {
+ opacity: 0.3;
+ filter: blur(8px);
+ -webkit-filter: blur(8px);
+}
+
+div[data-type="amp/amp-story-page"] > div > div > .is-selected-parent > .editor-inner-blocks > .editor-block-list__layout > div[data-amp-selected="parent"],
+div[data-type="amp/amp-story-page"] > div > div > .is-selected-parent > .editor-inner-blocks > .editor-block-list__layout > .is-selected {
+ opacity: 1;
+ filter: none;
+ -webkit-filter: none;
+}
+
+/*
+ * 4.3 Stroke text for legibility.
+ * Add white stroke to text in layers in order to be legible
+ * while editing on top of varying colored background.
+ */
+
.amp-grid-template .editor-block-list__layout .editor-block-list__block.is-selected > .editor-block-list__block-edit .editor-rich-text,
.amp-grid-template .editor-block-list__layout .editor-block-list__block.is-typing > .editor-block-list__block-edit .editor-rich-text {
text-shadow:
@@ -129,34 +274,13 @@ div[data-type="amp/amp-story-cta-layer"] .editor-block-list__layout .editor-bloc
0.05em 0.05em rgba( 255, 255, 255, 0.8 );
}
-.amp-grid-template-horizontal .editor-block-list__layout:first-of-type {
- grid-auto-flow: column !important;
- grid-template-rows: 100% !important;
- -ms-flex-line-pack: stretch;
- align-content: stretch;
- -webkit-box-align: start;
- -ms-flex-align: start;
- align-items: start;
- grid-gap: 16px;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- justify-content: start;
-}
-
-.amp-grid-template-vertical .editor-block-list__layout:first-of-type {
- grid-auto-flow: row;
- grid-template-columns: 100%;
- align-content: start;
- grid-gap: 16px;
- -webkit-box-pack: stretch;
- -ms-flex-pack: stretch;
- justify-content: stretch;
- justify-items: start;
-}
+/*
+ * 5. Layers Styling
+ */
-.amp-grid-template-vertical .editor-block-list__block {
- width: 100%;
-}
+/*
+ * 5.1 Thirds layer.
+ */
.amp-grid-template-thirds .editor-block-list__layout:first-of-type {
grid-template-rows: 1fr 1fr 1fr;
@@ -175,6 +299,10 @@ div[data-amp-position="lower-third"] {
grid-area: lower-third / lower-third / lower-third / lower-third;
}
+/*
+ * 5.2 Fill layer.
+ * Style the fill image & fill video type layers.
+ */
.amp-grid-template-fill .editor-block-list__layout > :first-child {
bottom: 0;
@@ -221,10 +349,19 @@ div[data-amp-position="lower-third"] {
height: 533px !important;
}
+div[data-amp-type="grid"] .block-library-image__resizer {
+ max-width: 318px !important;
+ max-height: 533px !important;
+}
+
.amp-grid-template-fill > :not(:first-child) {
display: none;
}
+/*
+ * 5.3 CTA layer.
+ */
+
.editor-block-list__layout div[data-type="amp/amp-story-cta-layer"] {
position: absolute;
height: 20%;
@@ -240,118 +377,24 @@ div[data-amp-position="lower-third"] {
height: auto !important;
}
-.editor-block-list__layout > div {
- transition: .3s;
- transition-property: opacity, filter;
-}
-
-div[data-amp-type="grid"] .block-library-image__resizer {
- max-width: 318px !important;
- max-height: 533px !important;
-}
-
-.editor-block-list__layout div[data-amp-type="grid"]:not(.is-selected):not(.is-selected-parent) .editor-block-list__block {
- z-index: 0;
-}
-
-.editor-block-list__layout div[data-amp-type="grid"]:not(.is-selected):not(.is-selected-parent) .editor-block-list__block p[data-is-placeholder-visible="true"] ~ p {
- display: none;
-}
-
-.editor-block-list__layout div[data-amp-type="grid"].is-selected ~ div[data-amp-type="grid"],
-.editor-block-list__layout div[data-amp-type="grid"][data-amp-selected="parent"] ~ div[data-amp-type="grid"],
-.editor-block-list__layout div[data-amp-type="grid"].is-selected ~ div[data-type="amp/amp-story-cta-layer"],
-.editor-block-list__layout div[data-amp-type="grid"][data-amp-selected="parent"] ~ div[data-type="amp/amp-story-cta-layer"]{
- display: none;
-}
-
-div[data-type="amp/amp-story-page"] > div > div > .is-selected-parent > .editor-inner-blocks > .editor-block-list__layout > .wp-block {
- opacity: 0.3;
- filter: blur(8px);
- -webkit-filter: blur(8px);
-}
-
-div[data-type="amp/amp-story-page"] > div > div > .is-selected-parent > .editor-inner-blocks > .editor-block-list__layout > div[data-amp-selected="parent"],
-div[data-type="amp/amp-story-page"] > div > div > .is-selected-parent > .editor-inner-blocks > .editor-block-list__layout > .is-selected {
- opacity: 1;
- filter: none;
- -webkit-filter: none;
-}
-
-div[data-type="amp/amp-story-page"] > div > div > .is-selected-parent > .editor-inner-blocks > .editor-block-list__layout > .is-selected > .editor-block-list__block-edit::before {
- outline: 1px solid #007cba;
-}
-
-.edit-post-visual-editor .editor-block-list__block ul.editor-selectors {
- position: absolute;
- right: -155px;
- bottom: 0;
- width: 120px;
- z-index: 80;
- list-style-type: none;
- padding: 0;
- margin: 0;
-}
-
-.editor-selectors .component-editor__selector button {
- background: no-repeat left top;
- padding-left: 37px;
- height: 40px;
- margin: 1px 0 1px 4px;
-}
-
-.editor-selectors .component-editor__selector .components-button:focus {
- box-shadow: none;
-}
-
-.editor-selectors .component-editor__selector.template-fill button {
- background-image: url( '../images/grid-fill-inactive.svg' );
-}
-
-.editor-selectors .component-editor__selector.template-fill.is-selected button {
- background-image: url( '../images/grid-fill-active.svg' );
-}
-
-.editor-selectors .component-editor__selector.template-horizontal button {
- background-image: url( '../images/grid-horizontal-inactive.svg' );
-}
-
-.editor-selectors .component-editor__selector.template-horizontal.is-selected button {
- background-image: url( '../images/grid-horizontal-active.svg' );
-}
-
-.editor-selectors .component-editor__selector.template-vertical button {
- background-image: url( '../images/grid-vertical-inactive.svg' );
-}
-
-.editor-selectors .component-editor__selector.template-vertical.is-selected button {
- background-image: url( '../images/grid-vertical-active.svg' );
-}
-
-.editor-selectors .component-editor__selector.template-thirds button {
- background-image: url( '../images/grid-thirds-inactive.svg' );
-}
-
-.editor-selectors .component-editor__selector.template-thirds.is-selected button {
- background-image: url( '../images/grid-thirds-active.svg' );
-}
+/*
+ * 6. Inserter customisations.
+ */
-.editor-selectors .component-editor__selector.page-selector button {
- background-image: url( '../images/page-inactive.svg' );
-}
-
-.editor-selectors .component-editor__selector.page-selector.is-selected button {
- background-image: url( '../images/page-active.svg' );
-}
-
-.editor-selectors .component-editor__selector button {
- cursor: pointer;
+ .components-popover.editor-inserter__amp .components-popover__content {
+ height: 200px;
}
-.post-type-amp_story .components-range-control__number {
- width: 60px;
+/* Fade out CTA Layer in inserter when it's already present */
+.editor-inserter__popover .amp-story-has-cta-layer .editor-block-list-item-amp-amp-story-cta-layer {
+ opacity: 0.5;
}
+/*
+ * 6.1 Ghosted page inserter
+ * Change the last inserter into a ghosted page.
+ * Shame disclaimer: long selectors needed because the classes are quite common.
+ */
.post-type-amp_story .editor-default-block-appender {
max-width: 318px;
@@ -374,8 +417,7 @@ div[data-type="amp/amp-story-page"] > div > div > .is-selected-parent > .editor-
opacity: 1;
}
-.post-type-amp_story .editor-writing-flow > div > div > .editor-block-list__layout > .block-list-appender .components-button
-
+.post-type-amp_story .editor-writing-flow > div > div > .editor-block-list__layout > .block-list-appender .components-button,
.post-type-amp_story .editor-writing-flow > div > div > .editor-block-list__layout > .editor-block-list__block[data-type="core/paragraph"] .editor-block-list__insertion-point-inserter .components-icon-button,
.post-type-amp_story .editor-writing-flow > div > div > .editor-block-list__layout > .block-list-appender .components-button {
background-color: #FAFAFA;
@@ -405,7 +447,154 @@ div[data-type="amp/amp-story-page"] > div > div > .is-selected-parent > .editor-
display: none;
}
-/* Fixes Gutenberg bug where an extra wrapping div is causing no pointer events on the notice layer. */
+/*
+ * 7. Block navigator
+ * Hides the toggler and shows the navigator by default on large screens.
+ */
+
+@media( max-width: 960px) {
+ .editor-block-list__block-edit > div > .editor-selectors {
+ display: none;
+ }
+}
+
+@media (min-width: 961px) {
+ .post-type-amp_story .editor-post-title__input {
+ text-align: center;
+ }
+
+ .post-type-amp_story .editor-writing-flow > div > div > .editor-block-list__layout {
+ padding-left: 15px;
+ padding-right: 15px;
+ }
+
+ .post-type-amp_story .editor-writing-flow > div > div {
+ display: grid;
+ }
+
+ .post-type-amp_story .editor-writing-flow > div > div::before {
+ content: '';
+ grid-column: 1 / 1;
+ grid-row: 1 / 2;
+ }
+
+ .post-type-amp_story .editor-writing-flow > div > div > div:first-child {
+ grid-column: 2 / 2;
+ grid-row: 1 / 1;
+ }
+
+ .post-type-amp_story .editor-writing-flow > div > div > .editor-block-list__layout {
+ grid-column: 2 / 2;
+ grid-row: 2 / 2;
+ }
+
+ .components-icon-button.editor-block-navigation {
+ display: none;
+ }
+
+ #amp-root-navigation {
+ position: absolute;
+ left: 5px;
+ top: 182px;
+ width: 300px;
+ z-index: 80;
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+ }
+
+ #amp-root-navigation .editor-inserter__toggle::after {
+ content: 'Add Layer';
+ }
+
+ .post-type-amp_story #amp-root-navigation .components-popover:not(.is-mobile).is-center .components-popover__content {
+ transform: translateX( -13% );
+ }
+
+ .post-type-amp_story.folded #amp-root-navigation .components-popover:not(.is-mobile):not(.is-middle).is-right .components-popover__content {
+ margin-left: -50px;
+ }
+
+ /*
+ Legend of the magic numbers:
+ Sidebar
+ Expanded - 160px wide
+ Folded - 36px wide
+ Settings
+ Shown - 280px wide
+ Content - 383px (including 15px padding)
+ Block Navigation - <= 300px
+ */
+
+ /* Navigator in the context of the open sidebar, settings hidden. */
+ .post-type-amp_story .edit-post-layout #amp-root-navigation {
+ max-width: calc( 100vw - 160px - 383px );
+ }
+
+ .post-type-amp_story .edit-post-layout .editor-writing-flow > div > div {
+ grid-template-columns: auto minmax( 368px, calc( 100vw - 160px - 315px ) );
+ }
+
+ /* Navigator in the context of minimum available space - open sidebar, settings shown. */
+ .post-type-amp_story .edit-post-layout.is-sidebar-opened #amp-root-navigation {
+ max-width: calc( 100vw - 280px - 160px - 383px );
+ }
+
+ .post-type-amp_story .edit-post-layout.is-sidebar-opened .editor-writing-flow > div > div {
+ grid-template-columns: auto minmax( 368px, calc( 100vw - 280px - 160px - 315px ) );
+ }
+
+ /* Navigator in the context of folded sidebar, settings hidden. */
+ .post-type-amp_story.folded #amp-root-navigation {
+ max-width: calc( 100vw - 36px - 383px );
+ }
+
+ .post-type-amp_story.folded .edit-post-visual-editor .editor-writing-flow > div > div {
+ grid-template-columns: auto minmax( 368px, calc( 100vw - 36px - 315px ) );
+ }
+
+ /* Navigator in the context of folded sidebar, settings shown. */
+ .post-type-amp_story.folded .edit-post-layout.is-sidebar-opened #amp-root-navigation {
+ max-width: calc( 100vw - 36px - 280px - 383px );
+ }
+
+ .post-type-amp_story.folded .edit-post-layout.is-sidebar-opened .editor-writing-flow > div > div {
+ grid-template-columns: auto minmax( 368px, calc( 100vw - 36px - 280px - 315px ) );
+ }
+
+ #amp-root-navigation .editor-block-navigation__list {
+ list-style-type: none;
+ }
+
+ #amp-root-navigation .components-icon-button .dashicon {
+ margin-right: 5px;
+ }
+
+ .editor-selectors .component-editor__selector button {
+ background: no-repeat left top;
+ padding-left: 37px;
+ height: 40px;
+ margin: 1px 0 1px 4px;
+ }
+
+ .editor-selectors .component-editor__selector .components-button:focus {
+ box-shadow: none;
+ }
+
+ .post-type-amp_story .components-range-control__number {
+ width: 60px;
+ }
+}
+
+/*
+ * 8. Shame
+ */
+
+/*
+ * 8.1 Gutenberg - Warning div not clickable
+ * Fixes Gutenberg bug where an extra wrapping div is causing no pointer events on the notice layer.
+ */
+
.post-type-amp_story .editor-block-list__layout .editor-block-list__block.has-warning .editor-block-list__block-edit > :not(.editor-warning) {
pointer-events: all;
}
@@ -414,6 +603,4 @@ div[data-type="amp/amp-story-page"] > div > div > .is-selected-parent > .editor-
pointer-events: none;
}
-.editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit::before {
- outline: none;
-}
+
diff --git a/blocks/amp-story/amp-story-page.js b/blocks/amp-story/amp-story-page.js
index 67001b3c16c..7ad3eb45fe9 100644
--- a/blocks/amp-story/amp-story-page.js
+++ b/blocks/amp-story/amp-story-page.js
@@ -1,5 +1,7 @@
+/* global ReactDOM */
+
import uuid from 'uuid/v4';
-import BlockSelector from './block-selector';
+import BlockNavigation from './block-navigation';
import {
BLOCK_ICONS,
maybeIsSelectedParentClass
@@ -12,9 +14,12 @@ const {
const {
InnerBlocks,
PanelColorSettings,
- InspectorControls
+ InspectorControls,
+ Inserter
} = wp.editor;
+const { Component } = wp.element;
+
const ALLOWED_BLOCKS = [
'amp/amp-story-grid-layer-vertical',
'amp/amp-story-grid-layer-fill',
@@ -22,6 +27,12 @@ const ALLOWED_BLOCKS = [
'amp/amp-story-cta-layer'
];
+const {
+ hasSelectedInnerBlock,
+ getSelectedBlockClientId,
+ getBlockIndex
+} = wp.data.select( 'core/editor' );
+
const TEMPLATE = [
[ 'amp/amp-story-grid-layer-background-image' ],
[
@@ -46,8 +57,6 @@ export default registerBlockType(
title: __( 'Page', 'amp' ),
category: 'layout',
icon: BLOCK_ICONS[ 'amp/amp-story-page' ],
-
- // @todo Enforce that the amp-story-page can only be a root-level block; Using `parent: []` does not work, and it causes the inserter to be disabled entirely.
attributes: {
id: {
type: 'string',
@@ -73,37 +82,75 @@ export default registerBlockType(
* https://github.com/ampproject/amphtml/blob/87fe1d02f902be97b596b36ec3421592c83d241e/extensions/amp-story/validator-amp-story.protoascii#L146-L171
* */
- edit( props ) {
- const { setAttributes, attributes } = props;
- const onChangeBackgroundColor = newBackgroundColor => {
- setAttributes( { backgroundColor: newBackgroundColor } );
- };
+ edit: class extends Component {
+ constructor( props ) {
+ // Call parent constructor.
+ super( props );
- // If the page ID is not set, add one.
- if ( ! attributes.id ) {
- setAttributes( { id: uuid() } );
+ if ( ! props.attributes.id ) {
+ this.props.setAttributes( { id: uuid() } );
+ }
}
- return [
-
{ __( 'Block Navigation' ) }
+ { hasHierarchy && ( ++ { __( 'No blocks created yet.' ) } +
+ ) } +