From 0fac00c68cc70bb69886aa019db681ff28dc4c21 Mon Sep 17 00:00:00 2001
From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com>
Date: Fri, 27 Sep 2024 16:53:36 +1000
Subject: [PATCH 1/9] Style Book: Add color tab
---
...se-multiple-origin-colors-and-gradients.js | 6 +
.../src/components/global-styles/ui.js | 15 ++
.../src/components/style-book/constants.ts | 49 +++++-
.../src/components/style-book/examples.ts | 146 +++++++++++++++++-
.../src/components/style-book/index.js | 138 ++++++++++++++---
.../components/style-book/test/categories.js | 5 -
.../src/components/style-book/types.ts | 36 ++++-
7 files changed, 361 insertions(+), 34 deletions(-)
diff --git a/packages/block-editor/src/components/colors-gradients/use-multiple-origin-colors-and-gradients.js b/packages/block-editor/src/components/colors-gradients/use-multiple-origin-colors-and-gradients.js
index ee27960529ede3..1163492c322378 100644
--- a/packages/block-editor/src/components/colors-gradients/use-multiple-origin-colors-and-gradients.js
+++ b/packages/block-editor/src/components/colors-gradients/use-multiple-origin-colors-and-gradients.js
@@ -55,6 +55,7 @@ export default function useMultipleOriginColorsAndGradients() {
'Theme',
'Indicates this palette comes from the theme.'
),
+ slug: 'theme',
colors: themeColors,
} );
}
@@ -68,6 +69,7 @@ export default function useMultipleOriginColorsAndGradients() {
'Default',
'Indicates this palette comes from WordPress.'
),
+ slug: 'default',
colors: defaultColors,
} );
}
@@ -77,6 +79,7 @@ export default function useMultipleOriginColorsAndGradients() {
'Custom',
'Indicates this palette comes from the theme.'
),
+ slug: 'custom',
colors: customColors,
} );
}
@@ -96,6 +99,7 @@ export default function useMultipleOriginColorsAndGradients() {
'Theme',
'Indicates this palette comes from the theme.'
),
+ slug: 'theme',
gradients: themeGradients,
} );
}
@@ -109,6 +113,7 @@ export default function useMultipleOriginColorsAndGradients() {
'Default',
'Indicates this palette comes from WordPress.'
),
+ slug: 'default',
gradients: defaultGradients,
} );
}
@@ -118,6 +123,7 @@ export default function useMultipleOriginColorsAndGradients() {
'Custom',
'Indicates this palette is created by the user.'
),
+ slug: 'custom',
gradients: customGradients,
} );
}
diff --git a/packages/edit-site/src/components/global-styles/ui.js b/packages/edit-site/src/components/global-styles/ui.js
index 6cd465e237100a..4c1b00b283b06f 100644
--- a/packages/edit-site/src/components/global-styles/ui.js
+++ b/packages/edit-site/src/components/global-styles/ui.js
@@ -45,6 +45,7 @@ import ScreenCSS from './screen-css';
import ScreenRevisions from './screen-revisions';
import { unlock } from '../../lock-unlock';
import { store as editSiteStore } from '../../store';
+import { STYLE_BOOK_COLOR_GROUPS } from '../style-book/constants';
const SLOT_FILL_NAME = 'GlobalStylesMenu';
const { useGlobalStylesReset } = unlock( blockEditorPrivateApis );
@@ -191,6 +192,20 @@ function GlobalStylesStyleBook() {
)
}
onSelect={ ( blockName ) => {
+ if ( blockName === 'duotones' ) {
+ return;
+ }
+
+ if (
+ STYLE_BOOK_COLOR_GROUPS.find(
+ ( group ) => group.slug === blockName
+ )
+ ) {
+ // Go to color palettes Global Styles.
+ navigator.goTo( '/colors/palette' );
+ return;
+ }
+
// Now go to the selected block.
navigator.goTo( '/blocks/' + encodeURIComponent( blockName ) );
} }
diff --git a/packages/edit-site/src/components/style-book/constants.ts b/packages/edit-site/src/components/style-book/constants.ts
index fc06d8f1409f0d..96352844177617 100644
--- a/packages/edit-site/src/components/style-book/constants.ts
+++ b/packages/edit-site/src/components/style-book/constants.ts
@@ -6,7 +6,46 @@ import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
-import type { StyleBookCategory } from './types';
+import type { StyleBookCategory, StyleBookColorGroup } from './types';
+
+export const STYLE_BOOK_COLOR_GROUPS: StyleBookColorGroup[] = [
+ {
+ slug: 'theme-colors',
+ title: __( 'Theme Colors' ),
+ origin: 'theme',
+ type: 'colors',
+ },
+ {
+ slug: 'custom-colors',
+ title: __( 'Custom Colors' ),
+ origin: 'custom',
+ type: 'colors',
+ },
+ {
+ slug: 'custom-gradients',
+ title: __( 'Custom Gradients' ),
+ origin: 'custom', // User.
+ type: 'gradients',
+ },
+ {
+ slug: 'duotones',
+ title: __( 'Duotones' ),
+ origin: 'theme',
+ type: 'duotones',
+ },
+ {
+ slug: 'default-colors',
+ title: __( 'Default Colors' ),
+ origin: 'default',
+ type: 'colors',
+ },
+ {
+ slug: 'default-gradients',
+ title: __( 'Default Gradients' ),
+ origin: 'default',
+ type: 'gradients',
+ },
+];
export const STYLE_BOOK_THEME_SUBCATEGORIES: Omit<
StyleBookCategory,
@@ -74,7 +113,7 @@ export const STYLE_BOOK_CATEGORIES: StyleBookCategory[] = [
{
slug: 'colors',
title: __( 'Colors' ),
- blocks: [ 'custom/colors' ],
+ blocks: [],
},
{
slug: 'theme',
@@ -111,7 +150,7 @@ export const STYLE_BOOK_IFRAME_STYLES = `
.is-root-container {
display: flow-root;
}
-
+
body {
position: relative;
padding: 32px !important;
@@ -149,7 +188,7 @@ export const STYLE_BOOK_IFRAME_STYLES = `
.edit-site-style-book__examples.is-wide .edit-site-style-book__example {
flex-direction: row;
}
-
+
.edit-site-style-book__subcategory-title,
.edit-site-style-book__example-title {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
@@ -160,7 +199,7 @@ export const STYLE_BOOK_IFRAME_STYLES = `
text-align: left;
text-transform: uppercase;
}
-
+
.edit-site-style-book__subcategory-title {
font-size: 16px;
margin-bottom: 40px;
diff --git a/packages/edit-site/src/components/style-book/examples.ts b/packages/edit-site/src/components/style-book/examples.ts
index 80807b10374c68..c9be0666846670 100644
--- a/packages/edit-site/src/components/style-book/examples.ts
+++ b/packages/edit-site/src/components/style-book/examples.ts
@@ -12,21 +12,158 @@ import {
/**
* Internal dependencies
*/
-import type { BlockExample } from './types';
+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 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: '8px', 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(): BlockExample[] {
+export function getExamples( colors: MultiOriginPalettes ): BlockExample[] {
const nonHeadingBlockExamples = getBlockTypes()
.filter( ( blockType ) => {
const { name, example, supports } = blockType;
return (
name !== 'core/heading' &&
!! example &&
- supports.inserter !== false
+ supports?.inserter !== false
);
} )
.map( ( blockType ) => ( {
@@ -58,6 +195,7 @@ export function getExamples(): BlockExample[] {
} );
} ),
};
+ const colorExamples = getColorExamples( colors );
- return [ headingsExample, ...nonHeadingBlockExamples ];
+ 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 42b6e3f4fc99b6..423d45b86834e4 100644
--- a/packages/edit-site/src/components/style-book/index.js
+++ b/packages/edit-site/src/components/style-book/index.js
@@ -11,18 +11,26 @@ import {
Composite,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
-import { __, sprintf } from '@wordpress/i18n';
+import { __, _x, sprintf } from '@wordpress/i18n';
import {
BlockList,
privateApis as blockEditorPrivateApis,
store as blockEditorStore,
+ useSettings,
__unstableEditorStyles as EditorStyles,
__unstableIframe as Iframe,
+ __experimentalUseMultipleOriginColorsAndGradients as useMultipleOriginColorsAndGradients,
} from '@wordpress/block-editor';
import { privateApis as editorPrivateApis } from '@wordpress/editor';
import { useSelect } from '@wordpress/data';
import { useResizeObserver } from '@wordpress/compose';
-import { useMemo, useState, memo, useContext } from '@wordpress/element';
+import {
+ useMemo,
+ useState,
+ memo,
+ useContext,
+ useEffect,
+} from '@wordpress/element';
import { ENTER, SPACE } from '@wordpress/keycodes';
/**
@@ -51,6 +59,83 @@ function isObjectEmpty( object ) {
return ! object || Object.keys( object ).length === 0;
}
+/**
+ * Retrieves colors, gradients, and duotone filters from Global Styles.
+ * The inclusion of default (Core) palettes is controlled by the relevant
+ * theme.json property e.g. defaultPalette, defaultGradients, defaultDuotone.
+ *
+ * @return {Object} Object containing properties for each type of palette.
+ */
+function useMultiOriginPalettes() {
+ const { colors, gradients } = useMultipleOriginColorsAndGradients();
+
+ // Add duotone filters to the palettes data.
+ // TODO: Might need to include `disableCustomDuotones` setting or whatever to match colors/gradients from useMultipleOriginColorsAndGradients.
+ const [
+ shouldDisplayDefaultDuotones,
+ customDuotones,
+ themeDuotones,
+ defaultDuotones,
+ ] = useSettings(
+ 'color.defaultDuotone',
+ 'color.duotone.custom',
+ 'color.duotone.theme',
+ 'color.duotone.default'
+ );
+
+ const palettes = useMemo( () => {
+ const result = { colors, gradients, duotones: [] };
+
+ if ( themeDuotones && themeDuotones.length ) {
+ result.duotones.push( {
+ name: _x(
+ 'Theme',
+ 'Indicates this palette comes from the theme.'
+ ),
+ slug: 'theme',
+ duotones: themeDuotones,
+ } );
+ }
+
+ if (
+ shouldDisplayDefaultDuotones &&
+ defaultDuotones &&
+ defaultDuotones.length
+ ) {
+ result.duotones.push( {
+ name: _x(
+ 'Default',
+ 'Indicates this palette comes from WordPress.'
+ ),
+ slug: 'default',
+ duotones: defaultDuotones,
+ } );
+ }
+ if ( customDuotones && customDuotones.length ) {
+ result.duotones.push( {
+ name: _x(
+ 'Custom',
+ // TODO: Should the follow saying from the theme or user? It currently matches useMultipleOriginColorsAndGradients.
+ 'Indicates this palette comes from the theme.'
+ ),
+ slug: 'custom',
+ duotones: customDuotones,
+ } );
+ }
+
+ return result;
+ }, [
+ colors,
+ gradients,
+ customDuotones,
+ themeDuotones,
+ defaultDuotones,
+ shouldDisplayDefaultDuotones,
+ ] );
+
+ return palettes;
+}
+
function StyleBook( {
enableResizing = true,
isSelected,
@@ -64,7 +149,8 @@ function StyleBook( {
const [ resizeObserver, sizes ] = useResizeObserver();
const [ textColor ] = useGlobalStyle( 'color.text' );
const [ backgroundColor ] = useGlobalStyle( 'color.background' );
- const [ examples ] = useState( getExamples );
+ const colors = useMultiOriginPalettes();
+ const [ examples, setExamples ] = useState( () => getExamples( colors ) );
const tabs = useMemo(
() =>
getTopLevelStyleBookCategories().filter( ( category ) =>
@@ -74,6 +160,12 @@ function StyleBook( {
),
[ examples ]
);
+
+ // Ensure color examples are kept in sync with Global Styles palette changes.
+ useEffect( () => {
+ setExamples( getExamples( colors ) );
+ }, [ colors ] );
+
const { base: baseConfig } = useContext( GlobalStylesContext );
const mergedConfig = useMemo( () => {
@@ -217,7 +309,6 @@ const StyleBookBody = ( {
tabIndex={ 0 }
{ ...( onClick ? buttonModeProps : {} ) }
>
-
+ ) ) }
+
+
+ >
+ );
+};
+
export default StyleBook;
From 16429fbdf0f3be371db40925dcc6e513257a3e42 Mon Sep 17 00:00:00 2001
From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com>
Date: Wed, 2 Oct 2024 11:54:57 +1000
Subject: [PATCH 3/9] Revert "Try rendering only style overrides and duotone
svgs in each example"
This reverts commit eb744676097f12438478abaf0b96bd26a095cac0.
---
.../src/components/style-book/examples.ts | 3 +-
.../src/components/style-book/index.js | 41 +------------------
2 files changed, 3 insertions(+), 41 deletions(-)
diff --git a/packages/edit-site/src/components/style-book/examples.ts b/packages/edit-site/src/components/style-book/examples.ts
index 3f43d7364a612f..c9be0666846670 100644
--- a/packages/edit-site/src/components/style-book/examples.ts
+++ b/packages/edit-site/src/components/style-book/examples.ts
@@ -118,7 +118,6 @@ function getColorExamples( colors: MultiOriginPalettes ): BlockExample[] {
);
if ( palette?.[ group.type ] ) {
- const rowGap = group.type === 'duotones' ? '16px' : '8px';
const example: BlockExample = {
name: group.slug,
title: group.title,
@@ -134,7 +133,7 @@ function getColorExamples( colors: MultiOriginPalettes ): BlockExample[] {
},
style: {
spacing: {
- blockGap: { top: rowGap, left: '16px' },
+ blockGap: { top: '8px', left: '16px' },
},
},
},
diff --git a/packages/edit-site/src/components/style-book/index.js b/packages/edit-site/src/components/style-book/index.js
index 798920a41ead27..423d45b86834e4 100644
--- a/packages/edit-site/src/components/style-book/index.js
+++ b/packages/edit-site/src/components/style-book/index.js
@@ -9,7 +9,6 @@ import clsx from 'clsx';
import {
Disabled,
Composite,
- SVG,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
import { __, _x, sprintf } from '@wordpress/i18n';
@@ -310,7 +309,6 @@ const StyleBookBody = ( {
tabIndex={ 0 }
{ ...( onClick ? buttonModeProps : {} ) }
>
-
- ) ) }
-
-
- >
- );
-};
-
export default StyleBook;
From 700675d2c87a1e65cbbcb0a61a8824d5f9467664 Mon Sep 17 00:00:00 2001
From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com>
Date: Wed, 2 Oct 2024 12:11:52 +1000
Subject: [PATCH 4/9] Simplify inclusion of block support styles in style book
examples
---
.../src/components/style-book/examples.ts | 3 +-
.../src/components/style-book/index.js | 41 ++++++++-----------
2 files changed, 19 insertions(+), 25 deletions(-)
diff --git a/packages/edit-site/src/components/style-book/examples.ts b/packages/edit-site/src/components/style-book/examples.ts
index c9be0666846670..3f43d7364a612f 100644
--- a/packages/edit-site/src/components/style-book/examples.ts
+++ b/packages/edit-site/src/components/style-book/examples.ts
@@ -118,6 +118,7 @@ function getColorExamples( colors: MultiOriginPalettes ): BlockExample[] {
);
if ( palette?.[ group.type ] ) {
+ const rowGap = group.type === 'duotones' ? '16px' : '8px';
const example: BlockExample = {
name: group.slug,
title: group.title,
@@ -133,7 +134,7 @@ function getColorExamples( colors: MultiOriginPalettes ): BlockExample[] {
},
style: {
spacing: {
- blockGap: { top: '8px', left: '16px' },
+ blockGap: { top: rowGap, left: '16px' },
},
},
},
diff --git a/packages/edit-site/src/components/style-book/index.js b/packages/edit-site/src/components/style-book/index.js
index 423d45b86834e4..ac0a990758f5ad 100644
--- a/packages/edit-site/src/components/style-book/index.js
+++ b/packages/edit-site/src/components/style-book/index.js
@@ -309,6 +309,7 @@ const StyleBookBody = ( {
tabIndex={ 0 }
{ ...( onClick ? buttonModeProps : {} ) }
>
+