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;