From 729334e0dd70d5315e6e0660f401ae3273593a82 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:41:37 +1000 Subject: [PATCH] Try no using blocks for color tab examples --- .../components/style-book/color-examples.tsx | 44 ++++ .../src/components/style-book/constants.ts | 21 ++ .../style-book/duotone-examples.tsx | 53 +++++ .../src/components/style-book/examples.ts | 202 ------------------ .../src/components/style-book/examples.tsx | 113 ++++++++++ .../src/components/style-book/index.js | 22 +- .../src/components/style-book/types.ts | 7 +- 7 files changed, 248 insertions(+), 214 deletions(-) create mode 100644 packages/edit-site/src/components/style-book/color-examples.tsx create mode 100644 packages/edit-site/src/components/style-book/duotone-examples.tsx delete mode 100644 packages/edit-site/src/components/style-book/examples.ts create mode 100644 packages/edit-site/src/components/style-book/examples.tsx diff --git a/packages/edit-site/src/components/style-book/color-examples.tsx b/packages/edit-site/src/components/style-book/color-examples.tsx new file mode 100644 index 00000000000000..97bdeecee32d3d --- /dev/null +++ b/packages/edit-site/src/components/style-book/color-examples.tsx @@ -0,0 +1,44 @@ +/** + * External dependencies + */ +import clsx from 'clsx'; + +/** + * WordPress dependencies + */ +import { __experimentalGrid as Grid } from '@wordpress/components'; +import { View } from '@wordpress/primitives'; +import { + getColorClassName, + __experimentalGetGradientClass, +} from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import type { Color, Gradient } from './types'; + +const ColorExamples = ( { colors, type } ): JSX.Element | null => { + if ( ! colors ) { + return null; + } + + return ( + + { colors.map( ( color: Color | Gradient ) => { + const className = + type === 'gradients' + ? __experimentalGetGradientClass( color.slug ) + : getColorClassName( 'background-color', color.slug ); + const classes = clsx( + 'edit-site-style-book__color-example', + className + ); + + return ; + } ) } + + ); +}; + +export default ColorExamples; diff --git a/packages/edit-site/src/components/style-book/constants.ts b/packages/edit-site/src/components/style-book/constants.ts index 96352844177617..05f77ab2ad1e93 100644 --- a/packages/edit-site/src/components/style-book/constants.ts +++ b/packages/edit-site/src/components/style-book/constants.ts @@ -185,6 +185,27 @@ export const STYLE_BOOK_IFRAME_STYLES = ` outline: 3px solid transparent; } + .edit-site-style-book__duotone-example > div:first-child { + display: flex; + aspect-ratio: 16 / 9; + grid-row: span 1; + grid-column: span 2; + } + .edit-site-style-book__duotone-example img { + width: 100%; + height: 100%; + object-fit: cover; + } + .edit-site-style-book__duotone-example > div:not(:first-child) { + height: 20px; + border: 1px solid #ddd; + } + + .edit-site-style-book__color-example { + height: 52px; + border: 1px solid #ddd; + } + .edit-site-style-book__examples.is-wide .edit-site-style-book__example { flex-direction: row; } diff --git a/packages/edit-site/src/components/style-book/duotone-examples.tsx b/packages/edit-site/src/components/style-book/duotone-examples.tsx new file mode 100644 index 00000000000000..7ee90e61f1c6aa --- /dev/null +++ b/packages/edit-site/src/components/style-book/duotone-examples.tsx @@ -0,0 +1,53 @@ +/** + * WordPress dependencies + */ +import { __experimentalGrid as Grid } from '@wordpress/components'; +import { View } from '@wordpress/primitives'; + +/** + * Internal dependencies + */ +import type { Duotone } from './types'; + +const DuotoneExamples = ( { duotones } ): JSX.Element | null => { + if ( ! duotones ) { + return null; + } + + return ( + + { duotones.map( ( duotone: Duotone ) => { + return ( + + + { + + { duotone.colors.map( ( color ) => { + return ( + + ); + } ) } + + ); + } ) } + + ); +}; + +export default DuotoneExamples; diff --git a/packages/edit-site/src/components/style-book/examples.ts b/packages/edit-site/src/components/style-book/examples.ts deleted file mode 100644 index 3f43d7364a612f..00000000000000 --- a/packages/edit-site/src/components/style-book/examples.ts +++ /dev/null @@ -1,202 +0,0 @@ -/** - * WordPress dependencies - */ -import { __, sprintf } from '@wordpress/i18n'; -import { - getBlockType, - getBlockTypes, - getBlockFromExample, - createBlock, -} from '@wordpress/blocks'; - -/** - * Internal dependencies - */ -import type { - Block, - BlockExample, - ColorItem, - ColorOrigin, - Duotone, - MultiOriginPalettes, -} from './types'; -import { STYLE_BOOK_COLOR_GROUPS } from './constants'; - -// Base CSS styles to be applied to color block examples. -const defaultColorExampleStyles = { - dimensions: { minHeight: '52px' }, - border: { - width: '1px', - style: 'solid', - color: '#ddd', // Match horizontal rule under sub title headings - }, -}; - -/** - * Creates an example block to demo a given color item for the Style Book. - * A color example could be for a simple color, gradient, or duotone filter. - * - * @param {ColorItem} color The color for display. - * @param {string} type Type of color e.g. color, gradient, or duotone. - * @return {Block|undefined} Example block. - */ -function getColorExample( color: ColorItem, type: string ): Block | undefined { - if ( type === 'colors' ) { - return createBlock( 'core/group', { - backgroundColor: color.slug, - style: defaultColorExampleStyles, - } ); - } - - if ( type === 'gradients' ) { - return createBlock( 'core/group', { - gradient: color.slug, - style: defaultColorExampleStyles, - } ); - } - - if ( type === 'duotones' ) { - return createBlock( - 'core/group', - { - layout: { - type: 'grid', - columnCount: 2, - minimumColumnWidth: null, - }, - style: { spacing: { blockGap: '8px' } }, - }, - [ - createBlock( 'core/image', { - sizeSlug: 'medium', - url: 'https://s.w.org/images/core/5.3/MtBlanc1.jpg', - aspectRatio: '16/9', - scale: 'cover', - style: { - layout: { columnSpan: 2, rowSpan: 1 }, - color: { - duotone: `var:preset|duotone|${ color.slug }`, - }, - }, - } ), - createBlock( 'core/group', { - style: { - ...defaultColorExampleStyles, - color: { background: ( color as Duotone ).colors[ 0 ] }, - dimensions: { minHeight: '20px' }, - }, - } ), - createBlock( 'core/group', { - style: { - ...defaultColorExampleStyles, - color: { background: ( color as Duotone ).colors[ 1 ] }, - dimensions: { minHeight: '20px' }, - }, - } ), - ] - ); - } -} - -/** - * Returns examples color examples for each origin - * e.g. Core (Default), Theme, and User. - * - * @param {MultiOriginPalettes} colors Global Styles color palettes per origin. - * @return {BlockExample[]} An array of color block examples. - */ -function getColorExamples( colors: MultiOriginPalettes ): BlockExample[] { - if ( ! colors ) { - return []; - } - - const examples: BlockExample[] = []; - - STYLE_BOOK_COLOR_GROUPS.forEach( ( group ) => { - const palette = colors[ group.type ].find( - ( origin: ColorOrigin ) => origin.slug === group.origin - ); - - if ( palette?.[ group.type ] ) { - const rowGap = group.type === 'duotones' ? '16px' : '8px'; - const example: BlockExample = { - name: group.slug, - title: group.title, - category: 'colors', - blocks: [ - createBlock( - 'core/group', - { - layout: { - type: 'grid', - columnCount: 2, - minimumColumnWidth: null, - }, - style: { - spacing: { - blockGap: { top: rowGap, left: '16px' }, - }, - }, - }, - palette[ group.type ].map( ( color: ColorItem ) => - getColorExample( color, group.type ) - ) - ), - ], - }; - examples.push( example ); - } - } ); - - return examples; -} - -/** - * Returns a list of examples for registered block types. - * - * @param {MultiOriginPalettes} colors Global styles colors grouped by origin e.g. Core, Theme, and User. - * @return {BlockExample[]} An array of block examples. - */ -export function getExamples( colors: MultiOriginPalettes ): BlockExample[] { - const nonHeadingBlockExamples = getBlockTypes() - .filter( ( blockType ) => { - const { name, example, supports } = blockType; - return ( - name !== 'core/heading' && - !! example && - supports?.inserter !== false - ); - } ) - .map( ( blockType ) => ( { - name: blockType.name, - title: blockType.title, - category: blockType.category, - blocks: getBlockFromExample( blockType.name, blockType.example ), - } ) ); - const isHeadingBlockRegistered = !! getBlockType( 'core/heading' ); - - if ( ! isHeadingBlockRegistered ) { - return nonHeadingBlockExamples; - } - - // Use our own example for the Heading block so that we can show multiple - // heading levels. - const headingsExample = { - name: 'core/heading', - title: __( 'Headings' ), - category: 'text', - blocks: [ 1, 2, 3, 4, 5, 6 ].map( ( level ) => { - return createBlock( 'core/heading', { - content: sprintf( - // translators: %d: heading level e.g: "1", "2", "3" - __( 'Heading %d' ), - level - ), - level, - } ); - } ), - }; - const colorExamples = getColorExamples( colors ); - - return [ headingsExample, ...colorExamples, ...nonHeadingBlockExamples ]; -} diff --git a/packages/edit-site/src/components/style-book/examples.tsx b/packages/edit-site/src/components/style-book/examples.tsx new file mode 100644 index 00000000000000..9f4badd99a6582 --- /dev/null +++ b/packages/edit-site/src/components/style-book/examples.tsx @@ -0,0 +1,113 @@ +/** + * WordPress dependencies + */ +import { __, sprintf } from '@wordpress/i18n'; +import { + getBlockType, + getBlockTypes, + getBlockFromExample, + createBlock, +} from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import type { BlockExample, ColorOrigin, MultiOriginPalettes } from './types'; +import ColorExamples from './color-examples'; +import DuotoneExamples from './duotone-examples'; +import { STYLE_BOOK_COLOR_GROUPS } from './constants'; + +/** + * Returns examples color examples for each origin + * e.g. Core (Default), Theme, and User. + * + * @param {MultiOriginPalettes} colors Global Styles color palettes per origin. + * @return {BlockExample[]} An array of color block examples. + */ +function getColorExamples( colors: MultiOriginPalettes ): BlockExample[] { + if ( ! colors ) { + return []; + } + + const examples: BlockExample[] = []; + + STYLE_BOOK_COLOR_GROUPS.forEach( ( group ) => { + const palette = colors[ group.type ].find( + ( origin: ColorOrigin ) => origin.slug === group.origin + ); + + if ( palette?.[ group.type ] ) { + const example: BlockExample = { + name: group.slug, + title: group.title, + category: 'colors', + }; + if ( group.type === 'duotones' ) { + example.content = ( + + ); + examples.push( example ); + } else { + example.content = ( + + ); + examples.push( example ); + } + } + } ); + + return examples; +} + +/** + * Returns a list of examples for registered block types. + * + * @param {MultiOriginPalettes} colors Global styles colors grouped by origin e.g. Core, Theme, and User. + * @return {BlockExample[]} An array of block examples. + */ +export function getExamples( colors: MultiOriginPalettes ): BlockExample[] { + const nonHeadingBlockExamples = getBlockTypes() + .filter( ( blockType ) => { + const { name, example, supports } = blockType; + return ( + name !== 'core/heading' && + !! example && + supports?.inserter !== false + ); + } ) + .map( ( blockType ) => ( { + name: blockType.name, + title: blockType.title, + category: blockType.category, + blocks: getBlockFromExample( blockType.name, blockType.example ), + } ) ); + const isHeadingBlockRegistered = !! getBlockType( 'core/heading' ); + + if ( ! isHeadingBlockRegistered ) { + return nonHeadingBlockExamples; + } + + // Use our own example for the Heading block so that we can show multiple + // heading levels. + const headingsExample = { + name: 'core/heading', + title: __( 'Headings' ), + category: 'text', + blocks: [ 1, 2, 3, 4, 5, 6 ].map( ( level ) => { + return createBlock( 'core/heading', { + content: sprintf( + // translators: %d: heading level e.g: "1", "2", "3" + __( 'Heading %d' ), + level + ), + level, + } ); + } ), + }; + const colorExamples = getColorExamples( colors ); + + return [ headingsExample, ...colorExamples, ...nonHeadingBlockExamples ]; +} diff --git a/packages/edit-site/src/components/style-book/index.js b/packages/edit-site/src/components/style-book/index.js index 8c0f1b68ce813a..14a3efe82e5e75 100644 --- a/packages/edit-site/src/components/style-book/index.js +++ b/packages/edit-site/src/components/style-book/index.js @@ -364,6 +364,7 @@ const Examples = memo( key={ example.name } id={ `example-${ example.name }` } title={ example.title } + content={ example.content } blocks={ example.blocks } isSelected={ isSelected( example.name ) } onClick={ () => { @@ -402,6 +403,7 @@ const Subcategory = ( { examples, isSelected, onSelect } ) => { key={ example.name } id={ `example-${ example.name }` } title={ example.title } + content={ example.content } blocks={ example.blocks } isSelected={ isSelected( example.name ) } onClick={ () => { @@ -412,7 +414,7 @@ const Subcategory = ( { examples, isSelected, onSelect } ) => { ); }; -const Example = ( { id, title, blocks, isSelected, onClick } ) => { +const Example = ( { id, title, blocks, isSelected, onClick, content } ) => { const originalSettings = useSelect( ( select ) => select( blockEditorStore ).getSettings(), [] @@ -457,13 +459,17 @@ const Example = ( { id, title, blocks, isSelected, onClick } ) => { aria-hidden > - - - - + { content ? ( + content + ) : ( + + + + + ) } diff --git a/packages/edit-site/src/components/style-book/types.ts b/packages/edit-site/src/components/style-book/types.ts index 651d24f94a2f6a..e7be17b17dd4df 100644 --- a/packages/edit-site/src/components/style-book/types.ts +++ b/packages/edit-site/src/components/style-book/types.ts @@ -1,4 +1,4 @@ -export type Block = { +type Block = { name: string; attributes: Record< string, unknown >; innerBlocks?: Block[]; @@ -17,7 +17,8 @@ export type BlockExample = { name: string; title: string; category: string; - blocks: Block | Block[]; + content?: JSX.Element; + blocks?: Block | Block[]; }; export type CategoryExamples = { @@ -41,8 +42,6 @@ export type Duotone = { slug: string; }; -export type ColorItem = Color | Gradient | Duotone; - export type ColorOrigin = { name: string; slug: string;