From 855be7927f31cf89229e954829e78e23d6a871e8 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Mon, 24 Jun 2019 19:33:54 +0200 Subject: [PATCH] Add Columns template options, support InnerBlock templateOptions (#16129) --- .../src/components/inner-blocks/README.md | 63 ++++++ .../src/components/inner-blocks/index.js | 24 ++- .../src/components/inner-blocks/style.scss | 71 +++++++ .../inner-blocks/template-picker.js | 67 +++++++ packages/block-library/src/columns/block.json | 4 - .../block-library/src/columns/deprecated.js | 34 +++- packages/block-library/src/columns/edit.js | 184 ++++++++++++++---- packages/block-library/src/columns/save.js | 4 +- .../block-library/src/columns/test/utils.js | 6 + packages/block-library/src/columns/utils.js | 4 + .../fixtures/blocks/core__columns.html | 4 +- .../fixtures/blocks/core__columns.json | 6 +- .../fixtures/blocks/core__columns.parsed.json | 8 +- .../blocks/core__columns.serialized.html | 4 +- .../blocks/core__columns__deprecated.json | 4 +- .../core__columns__deprecated.serialized.html | 4 +- packages/e2e-tests/plugins/templates.php | 2 +- .../block-hierarchy-navigation.test.js.snap | 8 +- .../__snapshots__/writing-flow.test.js.snap | 2 +- .../specs/block-hierarchy-navigation.test.js | 2 + .../e2e-tests/specs/blocks/columns.test.js | 1 + .../__snapshots__/templates.test.js.snap | 4 +- packages/e2e-tests/specs/writing-flow.test.js | 1 + .../full-content/server-registered.json | 2 +- 24 files changed, 433 insertions(+), 80 deletions(-) create mode 100644 packages/block-editor/src/components/inner-blocks/template-picker.js diff --git a/packages/block-editor/src/components/inner-blocks/README.md b/packages/block-editor/src/components/inner-blocks/README.md index ef8b015b713b5..303e24730f7fe 100644 --- a/packages/block-editor/src/components/inner-blocks/README.md +++ b/packages/block-editor/src/components/inner-blocks/README.md @@ -90,6 +90,69 @@ const TEMPLATE = [ [ 'core/columns', {}, [ The previous example creates an InnerBlocks area containing two columns one with an image and the other with a paragraph. +### `__experimentalTemplateOptions` + +* **Type:** `Array` + +To present the user with a set of template choices for the inner blocks, you may provide an array of template options. + +A template option is an object consisting of the following properties: + +- `title` (`string`): A human-readable label which describes the template. +- `icon` (`WPElement|string`): An element or [Dashicon](https://developer.wordpress.org/resource/dashicons/) slug to show as a visual approximation of the template. +- `template` (`Array`): The template to apply when the option has been selected. See [`template` documentation](#template) for more information. + +For the template placeholder selection to be displayed, you must render `InnerBlocks` with a `template` prop value of `null`. You may track this as state of your component, updating its value when receiving the selected template via `__experimentalOnSelectTemplateOption`. + +```jsx +import { useState } from '@wordpress/element'; + +const TEMPLATE_OPTIONS = [ + { + title: 'Two Columns', + icon: , + template: [ + [ 'core/column', { width: 50 } ], + [ 'core/column', { width: 50 } ], + ], + }, + { + title: 'Three Columns', + icon: , + template: [ + [ 'core/column', { width: 33.33 } ], + [ 'core/column', { width: 33.33 } ], + [ 'core/column', { width: 33.33 } ], + ], + }, +]; + +function edit() { + const [ template, setTemplate ] = useState( null ); + + return ( + + ); +} +``` + +### `__experimentalOnSelectTemplateOption` + +* **Type:** `Function` + +Callback function invoked when the user makes a template selection, used in combination with the `__experimentalTemplateOptions` props. The selected template is passed as the first and only argument. The value of the template may be `undefined` if the `__experimentalAllowTemplateOptionSkip` prop is passed to `InnerBlocks` and the user opts to skip template selection. + +### `__experimentalAllowTemplateOptionSkip` + +* **Type:** `Boolean` +* **Default:** `false` + +Whether to include a button in the template selection placeholder to allow the user to skip selection, used in combination with the `__experimentalTemplateOptions` prop. When clicked, the `__experimentalOnSelectTemplateOption` callback will be passed an `undefined` value as the template. + ### `templateInsertUpdatesSelection` * **Type:** `Boolean` * **Default:** `true` diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index 75a6731f42db5..0d1feef14ff39 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -24,6 +24,7 @@ import DefaultBlockAppender from './default-block-appender'; */ import BlockList from '../block-list'; import { withBlockEditContext } from '../block-edit/context'; +import TemplatePicker from './template-picker'; class InnerBlocks extends Component { constructor() { @@ -48,6 +49,7 @@ class InnerBlocks extends Component { if ( innerBlocks.length === 0 || this.getTemplateLock() === 'all' ) { this.synchronizeBlocksWithTemplate(); } + if ( this.state.templateInProcess ) { this.setState( { templateInProcess: false, @@ -107,20 +109,32 @@ class InnerBlocks extends Component { clientId, hasOverlay, renderAppender, + template, + __experimentalTemplateOptions: templateOptions, + __experimentalOnSelectTemplateOption: onSelectTemplateOption, + __experimentalAllowTemplateOptionSkip: allowTemplateOptionSkip, } = this.props; const { templateInProcess } = this.state; + const isPlaceholder = template === null && !! templateOptions; + const classes = classnames( 'editor-inner-blocks block-editor-inner-blocks', { - 'has-overlay': hasOverlay, + 'has-overlay': hasOverlay && ! isPlaceholder, } ); return (
{ ! templateInProcess && ( - + isPlaceholder ? + : + ) }
); diff --git a/packages/block-editor/src/components/inner-blocks/style.scss b/packages/block-editor/src/components/inner-blocks/style.scss index ff8e4b9adbe96..0f8576fd5ecf3 100644 --- a/packages/block-editor/src/components/inner-blocks/style.scss +++ b/packages/block-editor/src/components/inner-blocks/style.scss @@ -17,3 +17,74 @@ right: 0; left: 0; } + +.block-editor-inner-blocks__template-picker { + .components-placeholder__instructions { + // Defer to vertical margins applied by template picker options. + margin-bottom: 0; + } + + .components-placeholder__fieldset { + // Options will render horizontally, but the immediate children of the + // fieldset are the options and the skip button, oriented vertically. + flex-direction: column; + } + + &.has-many-options .components-placeholder__fieldset { + // Allow options to occupy a greater amount of the available space if + // many options exist. + max-width: 90%; + } +} + +.block-editor-inner-blocks__template-picker-options.block-editor-inner-blocks__template-picker-options { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + width: 100%; + margin: $grid-size-large 0; + list-style: none; + + > li { + list-style: none; + flex-basis: 100%; + flex-shrink: 1; + margin: 0 $grid-size; + max-width: 100px; + } +} + +.block-editor-inner-blocks__template-picker-option { + width: 100%; + + &.components-icon-button { + // Override default styles inherited from to center + // icon horizontally. + justify-content: center; + + &.is-default { + background-color: $white; + } + } + + &.components-button { + // Override default styles inherited from + + ) } + + ); +} + +export default InnerBlocksTemplatePicker; diff --git a/packages/block-library/src/columns/block.json b/packages/block-library/src/columns/block.json index 267aef219883e..3c22ca71fba62 100644 --- a/packages/block-library/src/columns/block.json +++ b/packages/block-library/src/columns/block.json @@ -2,10 +2,6 @@ "name": "core/columns", "category": "layout", "attributes": { - "columns": { - "type": "number", - "default": 2 - }, "verticalAlignment": { "type": "string" } diff --git a/packages/block-library/src/columns/deprecated.js b/packages/block-library/src/columns/deprecated.js index 7d3d16c770adb..56ffe5d90bc6a 100644 --- a/packages/block-library/src/columns/deprecated.js +++ b/packages/block-library/src/columns/deprecated.js @@ -1,3 +1,9 @@ +/** + * External dependencies + */ +import { omit } from 'lodash'; +import classnames from 'classnames'; + /** * WordPress dependencies */ @@ -82,7 +88,7 @@ export default [ ) ); return [ - attributes, + omit( attributes, [ 'columns' ] ), migratedInnerBlocks, ]; }, @@ -96,4 +102,30 @@ export default [ ); }, }, + { + attributes: { + columns: { + type: 'number', + default: 2, + }, + }, + migrate( attributes, innerBlocks ) { + attributes = omit( attributes, [ 'columns' ] ); + + return [ attributes, innerBlocks ]; + }, + save( { attributes } ) { + const { verticalAlignment, columns } = attributes; + + const wrapperClasses = classnames( `has-${ columns }-columns`, { + [ `are-vertically-aligned-${ verticalAlignment }` ]: verticalAlignment, + } ); + + return ( +
+ +
+ ); + }, + }, ]; diff --git a/packages/block-library/src/columns/edit.js b/packages/block-library/src/columns/edit.js index 7162562523381..d573500cd551d 100644 --- a/packages/block-library/src/columns/edit.js +++ b/packages/block-library/src/columns/edit.js @@ -2,7 +2,7 @@ * External dependencies */ import classnames from 'classnames'; -import { dropRight } from 'lodash'; +import { dropRight, times } from 'lodash'; /** * WordPress dependencies @@ -11,6 +11,8 @@ import { __ } from '@wordpress/i18n'; import { PanelBody, RangeControl, + SVG, + Path, } from '@wordpress/components'; import { InspectorControls, @@ -18,8 +20,9 @@ import { BlockControls, BlockVerticalAlignmentToolbar, } from '@wordpress/block-editor'; -import { withDispatch } from '@wordpress/data'; +import { withDispatch, useSelect } from '@wordpress/data'; import { createBlock } from '@wordpress/blocks'; +import { useState, useEffect } from '@wordpress/element'; /** * Internal dependencies @@ -43,40 +46,133 @@ import { */ const ALLOWED_BLOCKS = [ 'core/column' ]; +/** + * Template option choices for predefined columns layouts. + * + * @constant + * @type {Array} + */ +const TEMPLATE_OPTIONS = [ + { + title: __( 'Two columns; equal split' ), + icon: , + template: [ + [ 'core/column' ], + [ 'core/column' ], + ], + }, + { + title: __( 'Two columns; one-third, two-thirds split' ), + icon: , + template: [ + [ 'core/column', { width: 33.33 } ], + [ 'core/column', { width: 66.66 } ], + ], + }, + { + title: __( 'Two columns; two-thirds, one-third split' ), + icon: , + template: [ + [ 'core/column', { width: 66.66 } ], + [ 'core/column', { width: 33.33 } ], + ], + }, + { + title: __( 'Three columns; equal split' ), + icon: , + template: [ + [ 'core/column' ], + [ 'core/column' ], + [ 'core/column' ], + ], + }, + { + title: __( 'Three columns; wide center column' ), + icon: , + template: [ + [ 'core/column', { width: 25 } ], + [ 'core/column', { width: 50 } ], + [ 'core/column', { width: 25 } ], + ], + }, +]; + +/** + * Number of columns to assume for template in case the user opts to skip + * template option selection. + * + * @type {Number} + */ +const DEFAULT_COLUMNS = 2; + export function ColumnsEdit( { attributes, className, updateAlignment, updateColumns, + clientId, } ) { - const { columns, verticalAlignment } = attributes; + const { verticalAlignment } = attributes; + + const { count } = useSelect( ( select ) => { + return { + count: select( 'core/block-editor' ).getBlockCount( clientId ), + }; + } ); + const [ template, setTemplate ] = useState( getColumnsTemplate( count ) ); + const [ forceUseTemplate, setForceUseTemplate ] = useState( false ); + + // This is used to force the usage of the template even if the count doesn't match the template + // The count doesn't match the template once you use undo/redo (this is used to reset to the placeholder state). + useEffect( () => { + // Once the template is applied, reset it. + if ( forceUseTemplate ) { + setForceUseTemplate( false ); + } + }, [ forceUseTemplate ] ); - const classes = classnames( className, `has-${ columns }-columns`, { + const classes = classnames( className, { [ `are-vertically-aligned-${ verticalAlignment }` ]: verticalAlignment, } ); return ( <> - - - - - - - - + { template && ( + <> + + + updateColumns( count, value ) } + min={ 2 } + max={ 6 } + /> + + + + + + + ) }
{ + if ( nextTemplate === undefined ) { + nextTemplate = getColumnsTemplate( DEFAULT_COLUMNS ); + } + + setTemplate( nextTemplate ); + setForceUseTemplate( true ); + } } + __experimentalAllowTemplateOptionSkip + // setting the template to null when the inner blocks + // are empty allows to reset to the placeholder state. + template={ count === 0 && ! forceUseTemplate ? null : template } templateLock="all" allowedBlocks={ ALLOWED_BLOCKS } />
@@ -113,29 +209,24 @@ export default withDispatch( ( dispatch, ownProps, registry ) => ( { * Updates the column count, including necessary revisions to child Column * blocks to grant required or redistribute available space. * - * @param {number} columns New column count. + * @param {number} previousColumns Previous column count. + * @param {number} newColumns New column count. */ - updateColumns( columns ) { - const { clientId, setAttributes, attributes } = ownProps; + updateColumns( previousColumns, newColumns ) { + const { clientId } = ownProps; const { replaceInnerBlocks } = dispatch( 'core/block-editor' ); const { getBlocks } = registry.select( 'core/block-editor' ); - // Update columns count. - setAttributes( { columns } ); - let innerBlocks = getBlocks( clientId ); - if ( ! hasExplicitColumnWidths( innerBlocks ) ) { - return; - } + const hasExplicitWidths = hasExplicitColumnWidths( innerBlocks ); // Redistribute available width for existing inner blocks. - const { columns: previousColumns } = attributes; - const isAddingColumn = columns > previousColumns; + const isAddingColumn = newColumns > previousColumns; - if ( isAddingColumn ) { + if ( isAddingColumn && hasExplicitWidths ) { // If adding a new column, assign width to the new column equal to // as if it were `1 / columns` of the total available space. - const newColumnWidth = toWidthPrecision( 100 / columns ); + const newColumnWidth = toWidthPrecision( 100 / newColumns ); // Redistribute in consideration of pending block insertion as // constraining the available working width. @@ -143,18 +234,29 @@ export default withDispatch( ( dispatch, ownProps, registry ) => ( { innerBlocks = [ ...getMappedColumnWidths( innerBlocks, widths ), - createBlock( 'core/column', { - width: newColumnWidth, + ...times( newColumns - previousColumns, () => { + return createBlock( 'core/column', { + width: newColumnWidth, + } ); + } ), + ]; + } else if ( isAddingColumn ) { + innerBlocks = [ + ...innerBlocks, + ...times( newColumns - previousColumns, () => { + return createBlock( 'core/column' ); } ), ]; } else { // The removed column will be the last of the inner blocks. - innerBlocks = dropRight( innerBlocks ); + innerBlocks = dropRight( innerBlocks, previousColumns - newColumns ); - // Redistribute as if block is already removed. - const widths = getRedistributedColumnWidths( innerBlocks, 100 ); + if ( hasExplicitWidths ) { + // Redistribute as if block is already removed. + const widths = getRedistributedColumnWidths( innerBlocks, 100 ); - innerBlocks = getMappedColumnWidths( innerBlocks, widths ); + innerBlocks = getMappedColumnWidths( innerBlocks, widths ); + } } replaceInnerBlocks( clientId, innerBlocks, false ); diff --git a/packages/block-library/src/columns/save.js b/packages/block-library/src/columns/save.js index 851a4270f7a4d..8f9b8c2d67362 100644 --- a/packages/block-library/src/columns/save.js +++ b/packages/block-library/src/columns/save.js @@ -9,9 +9,9 @@ import classnames from 'classnames'; import { InnerBlocks } from '@wordpress/block-editor'; export default function save( { attributes } ) { - const { columns, verticalAlignment } = attributes; + const { verticalAlignment } = attributes; - const wrapperClasses = classnames( `has-${ columns }-columns`, { + const wrapperClasses = classnames( { [ `are-vertically-aligned-${ verticalAlignment }` ]: verticalAlignment, } ); diff --git a/packages/block-library/src/columns/test/utils.js b/packages/block-library/src/columns/test/utils.js index cb69e1740e1f3..b89a63e2e0153 100644 --- a/packages/block-library/src/columns/test/utils.js +++ b/packages/block-library/src/columns/test/utils.js @@ -24,6 +24,12 @@ describe( 'getColumnsTemplate', () => { [ 'core/column' ], ] ); } ); + + it( 'should return null if columns count is not defined', () => { + const template = getColumnsTemplate( undefined ); + + expect( template ).toBe( null ); + } ); } ); describe( 'toWidthPrecision', () => { diff --git a/packages/block-library/src/columns/utils.js b/packages/block-library/src/columns/utils.js index 0c4e4c59e9ccd..77a0b7cf4375a 100644 --- a/packages/block-library/src/columns/utils.js +++ b/packages/block-library/src/columns/utils.js @@ -12,6 +12,10 @@ import { times, findIndex, sumBy, merge, mapValues } from 'lodash'; * @return {Object[]} Columns layout configuration. */ export const getColumnsTemplate = memoize( ( columns ) => { + if ( columns === undefined ) { + return null; + } + return times( columns, () => [ 'core/column' ] ); } ); diff --git a/packages/e2e-tests/fixtures/blocks/core__columns.html b/packages/e2e-tests/fixtures/blocks/core__columns.html index bcced4e7b9f24..10316fc04d135 100644 --- a/packages/e2e-tests/fixtures/blocks/core__columns.html +++ b/packages/e2e-tests/fixtures/blocks/core__columns.html @@ -1,5 +1,5 @@ - -
+ +
diff --git a/packages/e2e-tests/fixtures/blocks/core__columns.json b/packages/e2e-tests/fixtures/blocks/core__columns.json index 2a446b72dc79d..d2c4a123741dc 100644 --- a/packages/e2e-tests/fixtures/blocks/core__columns.json +++ b/packages/e2e-tests/fixtures/blocks/core__columns.json @@ -3,9 +3,7 @@ "clientId": "_clientId_0", "name": "core/columns", "isValid": true, - "attributes": { - "columns": 3 - }, + "attributes": {}, "innerBlocks": [ { "clientId": "_clientId_0", @@ -70,6 +68,6 @@ "originalContent": "
\n\t\t\n\t\t\n\t
" } ], - "originalContent": "
\n\t\n\t\n
" + "originalContent": "
\n\t\n\t\n
" } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__columns.parsed.json b/packages/e2e-tests/fixtures/blocks/core__columns.parsed.json index 7dbde278bc08c..e3a1d3c00b0b1 100644 --- a/packages/e2e-tests/fixtures/blocks/core__columns.parsed.json +++ b/packages/e2e-tests/fixtures/blocks/core__columns.parsed.json @@ -1,9 +1,7 @@ [ { "blockName": "core/columns", - "attrs": { - "columns": 3 - }, + "attrs": {}, "innerBlocks": [ { "blockName": "core/column", @@ -70,9 +68,9 @@ ] } ], - "innerHTML": "\n
\n\t\n\t\n
\n", + "innerHTML": "\n
\n\t\n\t\n
\n", "innerContent": [ - "\n
\n\t", + "\n
\n\t", null, "\n\t", null, diff --git a/packages/e2e-tests/fixtures/blocks/core__columns.serialized.html b/packages/e2e-tests/fixtures/blocks/core__columns.serialized.html index b7472ac094fbb..47dcbe2fa6917 100644 --- a/packages/e2e-tests/fixtures/blocks/core__columns.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__columns.serialized.html @@ -1,5 +1,5 @@ - -
+ +

Column One, Paragraph One

diff --git a/packages/e2e-tests/fixtures/blocks/core__columns__deprecated.json b/packages/e2e-tests/fixtures/blocks/core__columns__deprecated.json index 6993fb5da69c4..c5ad0b8151b8e 100644 --- a/packages/e2e-tests/fixtures/blocks/core__columns__deprecated.json +++ b/packages/e2e-tests/fixtures/blocks/core__columns__deprecated.json @@ -3,9 +3,7 @@ "clientId": "_clientId_0", "name": "core/columns", "isValid": true, - "attributes": { - "columns": 3 - }, + "attributes": {}, "innerBlocks": [ { "clientId": "_clientId_0", diff --git a/packages/e2e-tests/fixtures/blocks/core__columns__deprecated.serialized.html b/packages/e2e-tests/fixtures/blocks/core__columns__deprecated.serialized.html index 88041c92cb39d..d8271e568f7af 100644 --- a/packages/e2e-tests/fixtures/blocks/core__columns__deprecated.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__columns__deprecated.serialized.html @@ -1,5 +1,5 @@ - -
+ +

Column One, Paragraph One

diff --git a/packages/e2e-tests/plugins/templates.php b/packages/e2e-tests/plugins/templates.php index b4d399905c68e..f245813dfce29 100644 --- a/packages/e2e-tests/plugins/templates.php +++ b/packages/e2e-tests/plugins/templates.php @@ -26,7 +26,7 @@ function gutenberg_test_templates_register_book_type() { array( 'core/quote' ), array( 'core/columns', - array(), + array( 'columns' => 2 ), array( array( 'core/column', diff --git a/packages/e2e-tests/specs/__snapshots__/block-hierarchy-navigation.test.js.snap b/packages/e2e-tests/specs/__snapshots__/block-hierarchy-navigation.test.js.snap index dc278255bc856..4ee1d7710bbe1 100644 --- a/packages/e2e-tests/specs/__snapshots__/block-hierarchy-navigation.test.js.snap +++ b/packages/e2e-tests/specs/__snapshots__/block-hierarchy-navigation.test.js.snap @@ -11,8 +11,8 @@ exports[`Navigating the block hierarchy should appear and function even without `; exports[`Navigating the block hierarchy should navigate block hierarchy using only the keyboard 1`] = ` -" -
+" +

First column

@@ -31,8 +31,8 @@ exports[`Navigating the block hierarchy should navigate block hierarchy using on `; exports[`Navigating the block hierarchy should navigate using the block hierarchy dropdown menu 1`] = ` -" -
+" +

First column

diff --git a/packages/e2e-tests/specs/__snapshots__/writing-flow.test.js.snap b/packages/e2e-tests/specs/__snapshots__/writing-flow.test.js.snap index 7852dacfc4174..e693daea38401 100644 --- a/packages/e2e-tests/specs/__snapshots__/writing-flow.test.js.snap +++ b/packages/e2e-tests/specs/__snapshots__/writing-flow.test.js.snap @@ -6,7 +6,7 @@ exports[`adding blocks Should navigate inner blocks with arrow keys 1`] = ` -
+

First col

diff --git a/packages/e2e-tests/specs/block-hierarchy-navigation.test.js b/packages/e2e-tests/specs/block-hierarchy-navigation.test.js index 56d1ce2c3694b..3f0e1c8c3f55c 100644 --- a/packages/e2e-tests/specs/block-hierarchy-navigation.test.js +++ b/packages/e2e-tests/specs/block-hierarchy-navigation.test.js @@ -20,6 +20,7 @@ describe( 'Navigating the block hierarchy', () => { it( 'should navigate using the block hierarchy dropdown menu', async () => { await insertBlock( 'Columns' ); + await page.click( '[aria-label="Two columns; equal split"]' ); // Add a paragraph in the first column. await pressKeyTimes( 'Tab', 5 ); // Tab to inserter. @@ -61,6 +62,7 @@ describe( 'Navigating the block hierarchy', () => { it( 'should navigate block hierarchy using only the keyboard', async () => { await insertBlock( 'Columns' ); + await page.click( '[aria-label="Two columns; equal split"]' ); // Add a paragraph in the first column. await pressKeyTimes( 'Tab', 5 ); // Tab to inserter. diff --git a/packages/e2e-tests/specs/blocks/columns.test.js b/packages/e2e-tests/specs/blocks/columns.test.js index fd061642478e7..4372f5ee6dbeb 100644 --- a/packages/e2e-tests/specs/blocks/columns.test.js +++ b/packages/e2e-tests/specs/blocks/columns.test.js @@ -16,6 +16,7 @@ describe( 'Columns', () => { it( 'restricts all blocks inside the columns block', async () => { await insertBlock( 'Columns' ); + await page.click( '[aria-label="Two columns; equal split"]' ); await page.click( '[aria-label="Block Navigation"]' ); const columnBlockMenuItem = ( await page.$x( '//button[contains(concat(" ", @class, " "), " block-editor-block-navigation__item-button ")][text()="Column"]' ) )[ 0 ]; await columnBlockMenuItem.click(); diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/templates.test.js.snap b/packages/e2e-tests/specs/plugins/__snapshots__/templates.test.js.snap index 52f4469dddeea..f089390857781 100644 --- a/packages/e2e-tests/specs/plugins/__snapshots__/templates.test.js.snap +++ b/packages/e2e-tests/specs/plugins/__snapshots__/templates.test.js.snap @@ -14,7 +14,7 @@ exports[`templates Using a CPT with a predefined template Should add a custom po -
+
\\"\\"/
@@ -40,7 +40,7 @@ exports[`templates Using a CPT with a predefined template Should respect user ed -
+
\\"\\"/
diff --git a/packages/e2e-tests/specs/writing-flow.test.js b/packages/e2e-tests/specs/writing-flow.test.js index 5bcf9869c8646..b9ac58f46fd40 100644 --- a/packages/e2e-tests/specs/writing-flow.test.js +++ b/packages/e2e-tests/specs/writing-flow.test.js @@ -28,6 +28,7 @@ describe( 'adding blocks', () => { await page.keyboard.press( 'Enter' ); await page.keyboard.type( '/columns' ); await page.keyboard.press( 'Enter' ); + await page.click( ':focus [aria-label="Two columns; equal split"]' ); await page.click( ':focus .block-editor-button-block-appender' ); await page.waitForSelector( ':focus.block-editor-inserter__search' ); await page.keyboard.type( 'Paragraph' ); diff --git a/test/integration/full-content/server-registered.json b/test/integration/full-content/server-registered.json index 49912d76c4960..3915c3edec678 100644 --- a/test/integration/full-content/server-registered.json +++ b/test/integration/full-content/server-registered.json @@ -1 +1 @@ -{"core\/archives":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/block":{"attributes":{"ref":{"type":"number"}}},"core\/calendar":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"month":{"type":"integer"},"year":{"type":"integer"}}},"core\/categories":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showHierarchy":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/latest-comments":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"commentsToShow":{"type":"number","default":5,"minimum":1,"maximum":100},"displayAvatar":{"type":"boolean","default":true},"displayDate":{"type":"boolean","default":true},"displayExcerpt":{"type":"boolean","default":true}}},"core\/latest-posts":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"categories":{"type":"string"},"postsToShow":{"type":"number","default":5},"displayPostContent":{"type":"boolean","default":false},"displayPostContentRadio":{"type":"string","default":"excerpt"},"excerptLength":{"type":"number","default":55},"displayPostDate":{"type":"boolean","default":false},"postLayout":{"type":"string","default":"list"},"columns":{"type":"number","default":3},"order":{"type":"string","default":"desc"},"orderBy":{"type":"string","default":"date"}}},"core\/legacy-widget":{"attributes":{"className":{"type":"string"},"identifier":{"type":"string"},"instance":{"type":"object"},"isCallbackWidget":{"type":"boolean"}}},"core\/rss":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"columns":{"type":"number","default":2},"blockLayout":{"type":"string","default":"list"},"feedURL":{"type":"string","default":""},"itemsToShow":{"type":"number","default":5},"displayExcerpt":{"type":"boolean","default":false},"displayAuthor":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":false},"excerptLength":{"type":"number","default":55}}},"core\/search":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"label":{"type":"string","default":"Search"},"placeholder":{"type":"string","default":""},"buttonText":{"type":"string","default":"Search"}}},"core\/shortcode":{"attributes":{"text":{"type":"string","source":"html"}}},"core\/tag-cloud":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"taxonomy":{"type":"string","default":"post_tag"},"showTagCounts":{"type":"boolean","default":false}}}} \ No newline at end of file +{"core\/archives":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/block":{"attributes":{"ref":{"type":"number"}}},"core\/calendar":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"month":{"type":"integer"},"year":{"type":"integer"}}},"core\/categories":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showHierarchy":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/latest-comments":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"commentsToShow":{"type":"number","default":5,"minimum":1,"maximum":100},"displayAvatar":{"type":"boolean","default":true},"displayDate":{"type":"boolean","default":true},"displayExcerpt":{"type":"boolean","default":true}}},"core\/latest-posts":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"categories":{"type":"string"},"postsToShow":{"type":"number","default":5},"displayPostContent":{"type":"boolean","default":false},"displayPostContentRadio":{"type":"string","default":"excerpt"},"excerptLength":{"type":"number","default":55},"displayPostDate":{"type":"boolean","default":false},"postLayout":{"type":"string","default":"list"},"columns":{"type":"number","default":3},"order":{"type":"string","default":"desc"},"orderBy":{"type":"string","default":"date"}}},"core\/legacy-widget":{"attributes":{"identifier":{"type":"string"},"instance":{"type":"object"},"isCallbackWidget":{"type":"boolean"}}},"core\/rss":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"columns":{"type":"number","default":2},"blockLayout":{"type":"string","default":"list"},"feedURL":{"type":"string","default":""},"itemsToShow":{"type":"number","default":5},"displayExcerpt":{"type":"boolean","default":false},"displayAuthor":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":false},"excerptLength":{"type":"number","default":55}}},"core\/search":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"label":{"type":"string","default":"Search"},"placeholder":{"type":"string","default":""},"buttonText":{"type":"string","default":"Search"}}},"core\/shortcode":{"attributes":{"text":{"type":"string","source":"html"}}},"core\/tag-cloud":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"taxonomy":{"type":"string","default":"post_tag"},"showTagCounts":{"type":"boolean","default":false}}}} \ No newline at end of file