Skip to content

Commit

Permalink
Block editor: Extract BLockPatternPicker component
Browse files Browse the repository at this point in the history
  • Loading branch information
gziolo committed Nov 6, 2019
1 parent 3dc84aa commit c659e2e
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,22 @@ import classnames from 'classnames';
import { __ } from '@wordpress/i18n';
import { Button, IconButton, Placeholder } from '@wordpress/components';

function InnerBlocksTemplatePicker( {
options,
function BlockPatternPicker( {
icon = 'layout',
label = __( 'Choose pattern' ),
instructions = __( 'Select a pattern to start with.' ),
patterns,
onSelect,
allowSkip,
} ) {
const classes = classnames( 'block-editor-inner-blocks__template-picker', {
'has-many-options': options.length > 4,
const classes = classnames( 'block-editor-block-pattern-picker', {
'has-many-patterns': patterns.length > 4,
} );

const instructions = allowSkip ?
__( 'Select a layout to start with, or make one yourself.' ) :
__( 'Select a layout to start with.' );

return (
<Placeholder
icon="layout"
label={ __( 'Choose Layout' ) }
icon={ icon }
label={ label }
instructions={ instructions }
className={ classes }
>
Expand All @@ -36,23 +35,23 @@ function InnerBlocksTemplatePicker( {
*/
/* eslint-disable jsx-a11y/no-redundant-roles */
}
<ul className="block-editor-inner-blocks__template-picker-options" role="list">
{ options.map( ( templateOption ) => (
<li key={ templateOption.name }>
<ul className="block-editor-block-pattern-picker__patterns" role="list">
{ patterns.map( ( pattern ) => (
<li key={ pattern.name }>
<IconButton
isLarge
icon={ templateOption.icon }
icon={ pattern.icon }
size={ 48 }
onClick={ () => onSelect( templateOption.innerBlocks ) }
className="block-editor-inner-blocks__template-picker-option"
label={ templateOption.label }
onClick={ () => onSelect( pattern.innerBlocks ) }
className="block-editor-block-pattern-picker__pattern"
label={ pattern.label }
/>
</li>
) ) }
</ul>
{ /* eslint-enable jsx-a11y/no-redundant-roles */ }
{ allowSkip && (
<div className="block-editor-inner-blocks__template-picker-skip">
<div className="block-editor-block-pattern-picker__skip">
<Button
isLink
onClick={ () => onSelect( undefined ) }
Expand All @@ -65,4 +64,4 @@ function InnerBlocksTemplatePicker( {
);
}

export default InnerBlocksTemplatePicker;
export default BlockPatternPicker;
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
.block-editor-block-pattern-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-patterns .components-placeholder__fieldset {
// Allow options to occupy a greater amount of the available space if
// many options exist.
max-width: 90%;
}
}

.block-editor-block-pattern-picker__patterns.block-editor-block-pattern-picker__patterns {
display: flex;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
margin: $grid-size-small 0;
list-style: none;

> li {
list-style: none;
margin: $grid-size;
flex-shrink: 1;
max-width: 100px;
}

.block-editor-block-pattern-picker__pattern {
padding: $grid-size;
}
}

.block-editor-block-pattern-picker__pattern {
width: 100%;

&.components-icon-button {
// Override default styles inherited from <IconButton /> to center
// icon horizontally.
justify-content: center;

&.is-default {
background-color: $white;
}
}

&.components-button {
// Override default styles inherited from <Button /> to allow button
// to grow vertically.
height: auto;
padding: 0;
}

&::before {
// Use `padding-bottom` trick to style element as perfect square.
content: "";
padding-bottom: 100%;
}

&:first-child {
margin-left: 0;
}

&:last-child {
margin-right: 0;
}
}
1 change: 1 addition & 0 deletions packages/block-editor/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { default as BlockFormatControls } from './block-format-controls';
export { default as BlockIcon } from './block-icon';
export { default as BlockNavigationDropdown } from './block-navigation/dropdown';
export { default as __experimentalBlockNavigationList } from './block-navigation/list';
export { default as __experimentalBlockPatternPicker } from './block-pattern-picker';
export { default as BlockVerticalAlignmentToolbar } from './block-vertical-alignment-toolbar';
export { default as ButtonBlockerAppender } from './button-block-appender';
export { default as ColorPalette } from './color-palette';
Expand Down
39 changes: 21 additions & 18 deletions packages/block-editor/src/components/inner-blocks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,36 +90,39 @@ 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`
### `__experimentalPatterns`

* **Type:** `Array<Object>`

To present the user with a set of template choices for the inner blocks, you may provide an array of template options.
To present the user with a set of template choices for the inner blocks, you may provide an array of patterns.

A template option is an object consisting of the following properties:
A pattern 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<Array>`): The template to apply when the option has been selected. See [`template` documentation](#template) for more information.
- `name` (`string`): A machine-readable unique name of the pattern.
- `label` (`string`): A human-readable label which describes the pattern.
- `icon` (`WPElement|string`): An element or [Dashicon](https://developer.wordpress.org/resource/dashicons/) slug to show as a visual approximation of the pattern.
- `innerBlocks` (`Array<Array>`): The configuration of inner blocks to apply when the pattern 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`.
For the patterns picker 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 `__experimentalOnSelectPattern`.

```jsx
import { useState } from '@wordpress/element';

const TEMPLATE_OPTIONS = [
const PATTERNS = [
{
title: 'Two Columns',
name: 'two-columns',
label: 'Two Columns',
icon: <svg />,
template: [
innerBlocks: [
[ 'core/column', { width: 50 } ],
[ 'core/column', { width: 50 } ],
],
},
{
title: 'Three Columns',
name: 'three-columns',
label: 'Three Columns',
icon: <svg />,
template: [
innerBlocks: [
[ 'core/column', { width: 33.33 } ],
[ 'core/column', { width: 33.33 } ],
[ 'core/column', { width: 33.33 } ],
Expand All @@ -133,25 +136,25 @@ function edit() {
return (
<InnerBlocks
template={ template }
__experimentalTemplateOptions={ TEMPLATE_OPTIONS }
__experimentalOnSelectTemplateOption={ setTemplate }
__experimentalPatterns={ PATTERNS }
__experimentalOnSelectPattern={ setTemplate }
/>
);
}
```

### `__experimentalOnSelectTemplateOption`
### `__experimentalOnSelectPattern`

* **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.
Callback function invoked when the user makes a pattern selection, used in combination with the `__experimentalPatterns` props. The selected pattern is passed as the first and only argument. The value of the pattern may be `undefined` if the `__experimentalAllowPatternSkip` prop is passed to `InnerBlocks` and the user opts to skip pattern selection.

### `__experimentalAllowTemplateOptionSkip`
### `__experimentalAllowPatternSkip`

* **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.
Whether to include a button in the pattern selection placeholder to allow the user to skip selection, used in combination with the `__experimentalPatterns` prop. When clicked, the `__experimentalOnSelectPattern` callback will be passed an `undefined` value as the pattern.

### `templateInsertUpdatesSelection`
* **Type:** `Boolean`
Expand Down
18 changes: 9 additions & 9 deletions packages/block-editor/src/components/inner-blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import DefaultBlockAppender from './default-block-appender';
* Internal dependencies
*/
import BlockList from '../block-list';
import BlockPatternPicker from '../block-pattern-picker';
import { withBlockEditContext } from '../block-edit/context';
import TemplatePicker from './template-picker';

class InnerBlocks extends Component {
constructor() {
Expand Down Expand Up @@ -108,13 +108,13 @@ class InnerBlocks extends Component {
renderAppender,
template,
__experimentalMoverDirection: moverDirection,
__experimentalTemplateOptions: templateOptions,
__experimentalOnSelectTemplateOption: onSelectTemplateOption,
__experimentalAllowTemplateOptionSkip: allowTemplateOptionSkip,
__experimentalPatterns: patterns,
__experimentalOnSelectPattern: onSelectPattern,
__experimentalAllowPatternSkip: allowPatternSkip,
} = this.props;
const { templateInProcess } = this.state;

const isPlaceholder = template === null && !! templateOptions;
const isPlaceholder = template === null && !! patterns;

const classes = classnames( 'editor-inner-blocks block-editor-inner-blocks', {
'has-overlay': isSmallScreen && ( hasOverlay && ! isPlaceholder ), // Temporary click-through disable on desktop.
Expand All @@ -124,10 +124,10 @@ class InnerBlocks extends Component {
<div className={ classes }>
{ ! templateInProcess && (
isPlaceholder ?
<TemplatePicker
options={ templateOptions }
onSelect={ onSelectTemplateOption }
allowSkip={ allowTemplateOptionSkip }
<BlockPatternPicker
patterns={ patterns }
onSelect={ onSelectPattern }
allowSkip={ allowPatternSkip }
/> :
<BlockList
rootClientId={ clientId }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,11 @@ class InnerBlocks extends Component {
clientId,
renderAppender,
template,
__experimentalTemplateOptions: templateOptions,
__experimentalPatterns: patterns,
} = this.props;
const { templateInProcess } = this.state;

const isPlaceholder = template === null && !! templateOptions;
const isPlaceholder = template === null && !! patterns;

return (
<>
Expand Down
75 changes: 0 additions & 75 deletions packages/block-editor/src/components/inner-blocks/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,78 +17,3 @@
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;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
margin: $grid-size-small 0;
list-style: none;

> li {
list-style: none;
margin: $grid-size;
flex-shrink: 1;
max-width: 100px;
}

.block-editor-inner-blocks__template-picker-option {
padding: $grid-size;
}
}

.block-editor-inner-blocks__template-picker-option {
width: 100%;

&.components-icon-button {
// Override default styles inherited from <IconButton /> to center
// icon horizontally.
justify-content: center;

&.is-default {
background-color: $white;
}
}

&.components-button {
// Override default styles inherited from <Button /> to allow button
// to grow vertically.
height: auto;
padding: 0;
}

&::before {
// Use `padding-bottom` trick to style element as perfect square.
content: "";
padding-bottom: 100%;
}

&:first-child {
margin-left: 0;
}

&:last-child {
margin-right: 0;
}
}
1 change: 1 addition & 0 deletions packages/block-editor/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@import "./components/block-compare/style.scss";
@import "./components/block-mover/style.scss";
@import "./components/block-navigation/style.scss";
@import "./components/block-pattern-picker/style.scss";
@import "./components/block-preview/style.scss";
@import "./components/block-settings-menu/style.scss";
@import "./components/block-styles/style.scss";
Expand Down
6 changes: 3 additions & 3 deletions packages/block-library/src/columns/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ export function ColumnsEdit( {
) }
<div className={ classes }>
<InnerBlocks
__experimentalTemplateOptions={ patterns }
__experimentalOnSelectTemplateOption={ ( nextTemplate = defaultPattern.innerBlocks ) => {
__experimentalPatterns={ patterns }
__experimentalOnSelectPattern={ ( nextTemplate = defaultPattern.innerBlocks ) => {
setTemplate( nextTemplate );
setForceUseTemplate( true );
} }
__experimentalAllowTemplateOptionSkip
__experimentalAllowPatternSkip
template={ showTemplateSelector ? null : template }
templateLock="all"
allowedBlocks={ ALLOWED_BLOCKS } />
Expand Down
Empty file.

0 comments on commit c659e2e

Please sign in to comment.