From 856765d4fcae12cc3750fe21f4dd8ff8a38b3881 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Thu, 28 Apr 2022 12:01:21 +1000 Subject: [PATCH 01/22] Returning inline styles by default. --- packages/block-editor/src/hooks/style.js | 5 +---- .../global-styles/use-global-styles-output.js | 5 +---- packages/style-engine/src/index.ts | 9 ++++++--- packages/style-engine/src/styles/utils.ts | 4 ++-- packages/style-engine/src/test/index.js | 10 +++++++++- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index d8b8ad6771a07a..400ebd0a84263f 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -97,11 +97,8 @@ export function getInlineStyles( styles = {} ) { // The goal is to move everything to server side generated engine styles // This is temporary as we absorb more and more styles into the engine. - const extraRules = getCSSRules( styles, { selector: 'self' } ); + const extraRules = getCSSRules( styles ); extraRules.forEach( ( rule ) => { - if ( rule.selector !== 'self' ) { - throw "This style can't be added as inline style"; - } output[ rule.key ] = rule.value; } ); diff --git a/packages/edit-site/src/components/global-styles/use-global-styles-output.js b/packages/edit-site/src/components/global-styles/use-global-styles-output.js index e477faa83a024c..0be47a7000b539 100644 --- a/packages/edit-site/src/components/global-styles/use-global-styles-output.js +++ b/packages/edit-site/src/components/global-styles/use-global-styles-output.js @@ -220,11 +220,8 @@ function getStylesDeclarations( blockStyles = {} ) { // The goal is to move everything to server side generated engine styles // This is temporary as we absorb more and more styles into the engine. - const extraRules = getCSSRules( blockStyles, { selector: 'self' } ); + const extraRules = getCSSRules( blockStyles ); extraRules.forEach( ( rule ) => { - if ( rule.selector !== 'self' ) { - throw "This style can't be added as inline style"; - } const cssProperty = rule.key.startsWith( '--' ) ? rule.key : kebabCase( rule.key ); diff --git a/packages/style-engine/src/index.ts b/packages/style-engine/src/index.ts index 8117e27892140e..9386931bc127ef 100644 --- a/packages/style-engine/src/index.ts +++ b/packages/style-engine/src/index.ts @@ -27,20 +27,23 @@ export function generate( style: Style, options: StyleOptions ): string { const groupedRules = groupBy( rules, 'selector' ); const selectorRules = Object.keys( groupedRules ).reduce( ( acc: string[], subSelector: string ) => { + const hasSelector = subSelector !== 'undefined'; + const prefix = hasSelector ? `${ subSelector } { ` : ''; + const suffix = subSelector !== 'undefined' ? ' }' : ''; acc.push( - `${ subSelector } { ${ groupedRules[ subSelector ] + `${ prefix }${ groupedRules[ subSelector ] .map( ( rule: GeneratedCSSRule ) => `${ kebabCase( rule.key ) }: ${ rule.value };` ) - .join( ' ' ) } }` + .join( ' ' ) }${ suffix }` ); return acc; }, [] ); - return selectorRules.join( '\n' ); + return selectorRules.join( '' ); } /** diff --git a/packages/style-engine/src/styles/utils.ts b/packages/style-engine/src/styles/utils.ts index 5455901e49d1a6..628b4e91b6e0c7 100644 --- a/packages/style-engine/src/styles/utils.ts +++ b/packages/style-engine/src/styles/utils.ts @@ -22,7 +22,7 @@ export function generateBoxRules( const rules: GeneratedCSSRule[] = []; if ( typeof boxStyle === 'string' ) { rules.push( { - selector: options.selector, + selector: options?.selector, key: ruleKey, value: boxStyle, } ); @@ -32,7 +32,7 @@ export function generateBoxRules( const value: string | undefined = get( boxStyle, [ side ] ); if ( value ) { acc.push( { - selector: options.selector, + selector: options?.selector, key: `${ ruleKey }${ upperFirst( side ) }`, value, } ); diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js index bf1ab73566f52d..df4a664a829409 100644 --- a/packages/style-engine/src/test/index.js +++ b/packages/style-engine/src/test/index.js @@ -8,7 +8,15 @@ describe( 'generate', () => { expect( generate( {}, '.some-selector' ) ).toEqual( '' ); } ); - it( 'should generate spacing styles', () => { + it( 'should generate inline styles where there is no selector', () => { + expect( + generate( { + spacing: { padding: '10px', margin: '12px' }, + } ) + ).toEqual( 'margin: 12px; padding: 10px;' ); + } ); + + it( 'should generate styles with an optional selector', () => { expect( generate( { From e096ef09fd495bc8836dd67bbd7793aee401aadd Mon Sep 17 00:00:00 2001 From: ramonjd Date: Thu, 28 Apr 2022 12:22:13 +1000 Subject: [PATCH 02/22] Adding some dev notes for later brain --- packages/block-editor/src/hooks/style.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index 400ebd0a84263f..d81a22a323fd7a 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -237,6 +237,12 @@ export function addSaveProps( } } ); + // @TODO + // Experimental notes: + // Maybe the style engine could do the classname work of `addSaveProps` in packages/block-editor/src/hooks/color.js here? + // And addSaveProps in packages/block-editor/src/hooks/font-family.js + // And add it to props.className? + props.style = { ...getInlineStyles( style ), ...props.style, From db3efea5588c570d668dca84fc955e53d6e5d189 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Thu, 28 Apr 2022 20:54:39 +1000 Subject: [PATCH 03/22] Adding a couple of typography styles Updating tests Refactor styles directory --- packages/blocks/src/api/constants.js | 2 ++ packages/style-engine/src/styles/index.ts | 6 ++-- .../style-engine/src/styles/spacing/index.ts | 7 ++++ .../src/styles/{ => spacing}/margin.ts | 4 +-- .../src/styles/{ => spacing}/padding.ts | 4 +-- .../src/styles/typography/fontSize.ts | 32 +++++++++++++++++++ .../src/styles/typography/index.ts | 7 ++++ .../src/styles/typography/lineHeight.ts | 32 +++++++++++++++++++ packages/style-engine/src/test/index.js | 6 +++- 9 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 packages/style-engine/src/styles/spacing/index.ts rename packages/style-engine/src/styles/{ => spacing}/margin.ts (71%) rename packages/style-engine/src/styles/{ => spacing}/padding.ts (71%) create mode 100644 packages/style-engine/src/styles/typography/fontSize.ts create mode 100644 packages/style-engine/src/styles/typography/index.ts create mode 100644 packages/style-engine/src/styles/typography/lineHeight.ts diff --git a/packages/blocks/src/api/constants.js b/packages/blocks/src/api/constants.js index c583b53d96c0a5..976955ae0fc49f 100644 --- a/packages/blocks/src/api/constants.js +++ b/packages/blocks/src/api/constants.js @@ -119,6 +119,7 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { fontSize: { value: [ 'typography', 'fontSize' ], support: [ 'typography', 'fontSize' ], + useEngine: true, }, fontStyle: { value: [ 'typography', 'fontStyle' ], @@ -131,6 +132,7 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { lineHeight: { value: [ 'typography', 'lineHeight' ], support: [ 'typography', 'lineHeight' ], + useEngine: true, }, margin: { value: [ 'spacing', 'margin' ], diff --git a/packages/style-engine/src/styles/index.ts b/packages/style-engine/src/styles/index.ts index f7c87a8c7a29b3..50b35bbcc3f38b 100644 --- a/packages/style-engine/src/styles/index.ts +++ b/packages/style-engine/src/styles/index.ts @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import padding from './padding'; -import margin from './margin'; +import spacing from './spacing'; +import typography from './typography'; -export const styleDefinitions = [ margin, padding ]; +export const styleDefinitions = [ ...spacing, ...typography ]; diff --git a/packages/style-engine/src/styles/spacing/index.ts b/packages/style-engine/src/styles/spacing/index.ts new file mode 100644 index 00000000000000..4f6121951b0bf2 --- /dev/null +++ b/packages/style-engine/src/styles/spacing/index.ts @@ -0,0 +1,7 @@ +/** + * Internal dependencies + */ +import padding from './padding'; +import margin from './margin'; + +export default [ margin, padding ]; diff --git a/packages/style-engine/src/styles/margin.ts b/packages/style-engine/src/styles/spacing/margin.ts similarity index 71% rename from packages/style-engine/src/styles/margin.ts rename to packages/style-engine/src/styles/spacing/margin.ts index 2ead5da23f1e7b..c8492c378954fd 100644 --- a/packages/style-engine/src/styles/margin.ts +++ b/packages/style-engine/src/styles/spacing/margin.ts @@ -1,8 +1,8 @@ /** * Internal dependencies */ -import type { Style, StyleOptions } from '../types'; -import { generateBoxRules } from './utils'; +import type { Style, StyleOptions } from '../../types'; +import { generateBoxRules } from '../utils'; const margin = { name: 'margin', diff --git a/packages/style-engine/src/styles/padding.ts b/packages/style-engine/src/styles/spacing/padding.ts similarity index 71% rename from packages/style-engine/src/styles/padding.ts rename to packages/style-engine/src/styles/spacing/padding.ts index 94b268de35604a..a5a3227030e073 100644 --- a/packages/style-engine/src/styles/padding.ts +++ b/packages/style-engine/src/styles/spacing/padding.ts @@ -1,8 +1,8 @@ /** * Internal dependencies */ -import type { Style, StyleOptions } from '../types'; -import { generateBoxRules } from './utils'; +import type { Style, StyleOptions } from '../../types'; +import { generateBoxRules } from '../utils'; const padding = { name: 'padding', diff --git a/packages/style-engine/src/styles/typography/fontSize.ts b/packages/style-engine/src/styles/typography/fontSize.ts new file mode 100644 index 00000000000000..c241569257a05a --- /dev/null +++ b/packages/style-engine/src/styles/typography/fontSize.ts @@ -0,0 +1,32 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import type { Style, StyleOptions } from '../../types'; + +const fontSize = { + name: 'fontSize', + generate: ( style: Style, options: StyleOptions ) => { + const styleValue: string | undefined = get( + style, + [ 'typography', 'fontSize' ], + null + ); + + return styleValue + ? [ + { + selector: options?.selector, + key: 'font-size', + value: styleValue, + }, + ] + : []; + }, +}; + +export default fontSize; diff --git a/packages/style-engine/src/styles/typography/index.ts b/packages/style-engine/src/styles/typography/index.ts new file mode 100644 index 00000000000000..3a4d401021ae3b --- /dev/null +++ b/packages/style-engine/src/styles/typography/index.ts @@ -0,0 +1,7 @@ +/** + * Internal dependencies + */ +import fontSize from './fontSize'; +import lineHeight from './lineHeight'; + +export default [ fontSize, lineHeight ]; diff --git a/packages/style-engine/src/styles/typography/lineHeight.ts b/packages/style-engine/src/styles/typography/lineHeight.ts new file mode 100644 index 00000000000000..3f52a61ae5502f --- /dev/null +++ b/packages/style-engine/src/styles/typography/lineHeight.ts @@ -0,0 +1,32 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import type { Style, StyleOptions } from '../../types'; + +const lineHeight = { + name: 'lineHeight', + generate: ( style: Style, options: StyleOptions ) => { + const styleValue: string | undefined = get( + style, + [ 'typography', 'lineHeight' ], + null + ); + + return styleValue + ? [ + { + selector: options?.selector, + key: 'line-height', + value: styleValue, + }, + ] + : []; + }, +}; + +export default lineHeight; diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js index df4a664a829409..c2f2cf0c0e0150 100644 --- a/packages/style-engine/src/test/index.js +++ b/packages/style-engine/src/test/index.js @@ -40,13 +40,17 @@ describe( 'generate', () => { left: '14px', }, }, + typography: { + fontSize: '2.2rem', + lineHeight: '3.3', + }, }, { selector: '.some-selector', } ) ).toEqual( - '.some-selector { margin-top: 11px; margin-right: 12px; margin-bottom: 13px; margin-left: 14px; padding-top: 10px; padding-bottom: 5px; }' + '.some-selector { margin-top: 11px; margin-right: 12px; margin-bottom: 13px; margin-left: 14px; padding-top: 10px; padding-bottom: 5px; font-size: 2.2rem; line-height: 3.3; }' ); } ); } ); From 467d86afb13492e085d13bcd2ae1c1ff73ac0fea Mon Sep 17 00:00:00 2001 From: ramonjd Date: Fri, 29 Apr 2022 10:11:19 +1000 Subject: [PATCH 04/22] Adding text decoration Fixing camel case style prop name --- packages/blocks/src/api/constants.js | 1 + .../src/styles/typography/fontSize.ts | 2 +- .../src/styles/typography/index.ts | 3 +- .../src/styles/typography/lineHeight.ts | 2 +- .../src/styles/typography/textDecoration.ts | 32 +++++++++++++++++++ 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 packages/style-engine/src/styles/typography/textDecoration.ts diff --git a/packages/blocks/src/api/constants.js b/packages/blocks/src/api/constants.js index 976955ae0fc49f..d16cadc0b74d03 100644 --- a/packages/blocks/src/api/constants.js +++ b/packages/blocks/src/api/constants.js @@ -159,6 +159,7 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { textDecoration: { value: [ 'typography', 'textDecoration' ], support: [ 'typography', '__experimentalTextDecoration' ], + useEngine: true, }, textTransform: { value: [ 'typography', 'textTransform' ], diff --git a/packages/style-engine/src/styles/typography/fontSize.ts b/packages/style-engine/src/styles/typography/fontSize.ts index c241569257a05a..574b69c63beb19 100644 --- a/packages/style-engine/src/styles/typography/fontSize.ts +++ b/packages/style-engine/src/styles/typography/fontSize.ts @@ -21,7 +21,7 @@ const fontSize = { ? [ { selector: options?.selector, - key: 'font-size', + key: 'fontSize', value: styleValue, }, ] diff --git a/packages/style-engine/src/styles/typography/index.ts b/packages/style-engine/src/styles/typography/index.ts index 3a4d401021ae3b..298f16dff00f9d 100644 --- a/packages/style-engine/src/styles/typography/index.ts +++ b/packages/style-engine/src/styles/typography/index.ts @@ -3,5 +3,6 @@ */ import fontSize from './fontSize'; import lineHeight from './lineHeight'; +import textDecoration from './textDecoration'; -export default [ fontSize, lineHeight ]; +export default [ fontSize, lineHeight, textDecoration ]; diff --git a/packages/style-engine/src/styles/typography/lineHeight.ts b/packages/style-engine/src/styles/typography/lineHeight.ts index 3f52a61ae5502f..2602696a0e0229 100644 --- a/packages/style-engine/src/styles/typography/lineHeight.ts +++ b/packages/style-engine/src/styles/typography/lineHeight.ts @@ -21,7 +21,7 @@ const lineHeight = { ? [ { selector: options?.selector, - key: 'line-height', + key: 'lineHeight', value: styleValue, }, ] diff --git a/packages/style-engine/src/styles/typography/textDecoration.ts b/packages/style-engine/src/styles/typography/textDecoration.ts new file mode 100644 index 00000000000000..850f67121dadfd --- /dev/null +++ b/packages/style-engine/src/styles/typography/textDecoration.ts @@ -0,0 +1,32 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import type { Style, StyleOptions } from '../../types'; + +const textDecoration = { + name: 'lineHeight', + generate: ( style: Style, options: StyleOptions ) => { + const styleValue: string | undefined = get( + style, + [ 'typography', 'textDecoration' ], + null + ); + + return styleValue + ? [ + { + selector: options?.selector, + key: 'textDecoration', + value: styleValue, + }, + ] + : []; + }, +}; + +export default textDecoration; From def54bd65670a8beb39e4f5964e0f13e0513bc7c Mon Sep 17 00:00:00 2001 From: ramonjd Date: Mon, 2 May 2022 14:53:21 +1000 Subject: [PATCH 05/22] Adding typography properties letterSpacing.ts and textTransform.ts --- .../src/styles/typography/index.ts | 10 +++++- .../src/styles/typography/letterSpacing.ts | 32 +++++++++++++++++++ .../src/styles/typography/textDecoration.ts | 2 +- .../src/styles/typography/textTransform.ts | 32 +++++++++++++++++++ packages/style-engine/src/test/index.js | 5 ++- 5 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 packages/style-engine/src/styles/typography/letterSpacing.ts create mode 100644 packages/style-engine/src/styles/typography/textTransform.ts diff --git a/packages/style-engine/src/styles/typography/index.ts b/packages/style-engine/src/styles/typography/index.ts index 298f16dff00f9d..13a04e90f980f1 100644 --- a/packages/style-engine/src/styles/typography/index.ts +++ b/packages/style-engine/src/styles/typography/index.ts @@ -4,5 +4,13 @@ import fontSize from './fontSize'; import lineHeight from './lineHeight'; import textDecoration from './textDecoration'; +import textTransform from './textTransform'; +import letterSpacing from './letterSpacing'; -export default [ fontSize, lineHeight, textDecoration ]; +export default [ + fontSize, + letterSpacing, + lineHeight, + textDecoration, + textTransform, +]; diff --git a/packages/style-engine/src/styles/typography/letterSpacing.ts b/packages/style-engine/src/styles/typography/letterSpacing.ts new file mode 100644 index 00000000000000..cf53e16feb3d95 --- /dev/null +++ b/packages/style-engine/src/styles/typography/letterSpacing.ts @@ -0,0 +1,32 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import type { Style, StyleOptions } from '../../types'; + +const letterSpacing = { + name: 'letterSpacing', + generate: ( style: Style, options: StyleOptions ) => { + const styleValue: string | undefined = get( + style, + [ 'typography', 'letterSpacing' ], + null + ); + + return styleValue + ? [ + { + selector: options?.selector, + key: 'letterSpacing', + value: styleValue, + }, + ] + : []; + }, +}; + +export default letterSpacing; diff --git a/packages/style-engine/src/styles/typography/textDecoration.ts b/packages/style-engine/src/styles/typography/textDecoration.ts index 850f67121dadfd..64f46ecf5c4d67 100644 --- a/packages/style-engine/src/styles/typography/textDecoration.ts +++ b/packages/style-engine/src/styles/typography/textDecoration.ts @@ -9,7 +9,7 @@ import { get } from 'lodash'; import type { Style, StyleOptions } from '../../types'; const textDecoration = { - name: 'lineHeight', + name: 'textDecoration', generate: ( style: Style, options: StyleOptions ) => { const styleValue: string | undefined = get( style, diff --git a/packages/style-engine/src/styles/typography/textTransform.ts b/packages/style-engine/src/styles/typography/textTransform.ts new file mode 100644 index 00000000000000..41c74d55e7d791 --- /dev/null +++ b/packages/style-engine/src/styles/typography/textTransform.ts @@ -0,0 +1,32 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import type { Style, StyleOptions } from '../../types'; + +const textTransform = { + name: 'textTransform', + generate: ( style: Style, options: StyleOptions ) => { + const styleValue: string | undefined = get( + style, + [ 'typography', 'textTransform' ], + null + ); + + return styleValue + ? [ + { + selector: options?.selector, + key: 'textTransform', + value: styleValue, + }, + ] + : []; + }, +}; + +export default textTransform; diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js index c2f2cf0c0e0150..84d6735c0c7bc7 100644 --- a/packages/style-engine/src/test/index.js +++ b/packages/style-engine/src/test/index.js @@ -43,6 +43,9 @@ describe( 'generate', () => { typography: { fontSize: '2.2rem', lineHeight: '3.3', + textDecoration: 'line-through', + letterSpacing: '12px', + textTransform: 'uppercase', }, }, { @@ -50,7 +53,7 @@ describe( 'generate', () => { } ) ).toEqual( - '.some-selector { margin-top: 11px; margin-right: 12px; margin-bottom: 13px; margin-left: 14px; padding-top: 10px; padding-bottom: 5px; font-size: 2.2rem; line-height: 3.3; }' + '.some-selector { margin-top: 11px; margin-right: 12px; margin-bottom: 13px; margin-left: 14px; padding-top: 10px; padding-bottom: 5px; font-size: 2.2rem; letter-spacing: 12px; line-height: 3.3; text-decoration: line-through; text-transform: uppercase; }' ); } ); } ); From ce1204ddaecc58b02b7a7e792e92e5050ec69021 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Mon, 2 May 2022 15:00:31 +1000 Subject: [PATCH 06/22] Adding color.text and typography.fontWeight --- .../style-engine/src/styles/color/index.ts | 6 ++++ .../style-engine/src/styles/color/text.ts | 32 +++++++++++++++++++ packages/style-engine/src/styles/index.ts | 3 +- .../src/styles/typography/fontWeight.ts | 32 +++++++++++++++++++ .../src/styles/typography/index.ts | 2 ++ packages/style-engine/src/test/index.js | 3 +- packages/style-engine/src/types.ts | 3 ++ 7 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 packages/style-engine/src/styles/color/index.ts create mode 100644 packages/style-engine/src/styles/color/text.ts create mode 100644 packages/style-engine/src/styles/typography/fontWeight.ts diff --git a/packages/style-engine/src/styles/color/index.ts b/packages/style-engine/src/styles/color/index.ts new file mode 100644 index 00000000000000..2e548a7cb8209d --- /dev/null +++ b/packages/style-engine/src/styles/color/index.ts @@ -0,0 +1,6 @@ +/** + * Internal dependencies + */ +import text from './text'; + +export default [ text ]; diff --git a/packages/style-engine/src/styles/color/text.ts b/packages/style-engine/src/styles/color/text.ts new file mode 100644 index 00000000000000..a6d37ae82a8ce4 --- /dev/null +++ b/packages/style-engine/src/styles/color/text.ts @@ -0,0 +1,32 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import type { Style, StyleOptions } from '../../types'; + +const text = { + name: 'text', + generate: ( style: Style, options: StyleOptions ) => { + const styleValue: string | undefined = get( + style, + [ 'color', 'text' ], + null + ); + + return styleValue + ? [ + { + selector: options?.selector, + key: 'color', + value: styleValue, + }, + ] + : []; + }, +}; + +export default text; diff --git a/packages/style-engine/src/styles/index.ts b/packages/style-engine/src/styles/index.ts index 50b35bbcc3f38b..79f1c43d8d33f7 100644 --- a/packages/style-engine/src/styles/index.ts +++ b/packages/style-engine/src/styles/index.ts @@ -1,7 +1,8 @@ /** * Internal dependencies */ +import color from './color'; import spacing from './spacing'; import typography from './typography'; -export const styleDefinitions = [ ...spacing, ...typography ]; +export const styleDefinitions = [ ...color, ...spacing, ...typography ]; diff --git a/packages/style-engine/src/styles/typography/fontWeight.ts b/packages/style-engine/src/styles/typography/fontWeight.ts new file mode 100644 index 00000000000000..e6a542c538fad4 --- /dev/null +++ b/packages/style-engine/src/styles/typography/fontWeight.ts @@ -0,0 +1,32 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import type { Style, StyleOptions } from '../../types'; + +const fontWeight = { + name: 'fontWeight', + generate: ( style: Style, options: StyleOptions ) => { + const styleValue: string | undefined = get( + style, + [ 'typography', 'fontWeight' ], + null + ); + + return styleValue + ? [ + { + selector: options?.selector, + key: 'fontWeight', + value: styleValue, + }, + ] + : []; + }, +}; + +export default fontWeight; diff --git a/packages/style-engine/src/styles/typography/index.ts b/packages/style-engine/src/styles/typography/index.ts index 13a04e90f980f1..8b7cb5419a72bb 100644 --- a/packages/style-engine/src/styles/typography/index.ts +++ b/packages/style-engine/src/styles/typography/index.ts @@ -2,6 +2,7 @@ * Internal dependencies */ import fontSize from './fontSize'; +import fontWeight from './fontWeight'; import lineHeight from './lineHeight'; import textDecoration from './textDecoration'; import textTransform from './textTransform'; @@ -9,6 +10,7 @@ import letterSpacing from './letterSpacing'; export default [ fontSize, + fontWeight, letterSpacing, lineHeight, textDecoration, diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js index 84d6735c0c7bc7..a07cbc2af980b1 100644 --- a/packages/style-engine/src/test/index.js +++ b/packages/style-engine/src/test/index.js @@ -12,8 +12,9 @@ describe( 'generate', () => { expect( generate( { spacing: { padding: '10px', margin: '12px' }, + color: { text: '#381515' }, } ) - ).toEqual( 'margin: 12px; padding: 10px;' ); + ).toEqual( 'color: #381515; margin: 12px; padding: 10px;' ); } ); it( 'should generate styles with an optional selector', () => { diff --git a/packages/style-engine/src/types.ts b/packages/style-engine/src/types.ts index 48bd9a0d8e5c6e..82be652ce1db73 100644 --- a/packages/style-engine/src/types.ts +++ b/packages/style-engine/src/types.ts @@ -26,6 +26,9 @@ export interface Style { textDecoration?: CSSProperties[ 'textDecoration' ]; textTransform?: CSSProperties[ 'textTransform' ]; }; + color?: { + text?: CSSProperties[ 'color' ]; + }; } export type StyleOptions = { From 10679010c92d047ef37433bde064ebb63ad5bdb4 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Tue, 3 May 2022 13:09:35 +1000 Subject: [PATCH 07/22] Refactor generic rule generator --- packages/blocks/src/api/constants.js | 4 + .../style-engine/src/styles/color/index.ts | 10 ++- .../style-engine/src/styles/color/text.ts | 32 -------- .../src/styles/typography/fontSize.ts | 32 -------- .../src/styles/typography/fontWeight.ts | 32 -------- .../src/styles/typography/index.ts | 80 +++++++++++++++++-- .../src/styles/typography/letterSpacing.ts | 32 -------- .../src/styles/typography/lineHeight.ts | 32 -------- .../src/styles/typography/textDecoration.ts | 32 -------- .../src/styles/typography/textTransform.ts | 32 -------- packages/style-engine/src/styles/utils.ts | 19 +++++ 11 files changed, 106 insertions(+), 231 deletions(-) delete mode 100644 packages/style-engine/src/styles/color/text.ts delete mode 100644 packages/style-engine/src/styles/typography/fontSize.ts delete mode 100644 packages/style-engine/src/styles/typography/fontWeight.ts delete mode 100644 packages/style-engine/src/styles/typography/letterSpacing.ts delete mode 100644 packages/style-engine/src/styles/typography/lineHeight.ts delete mode 100644 packages/style-engine/src/styles/typography/textDecoration.ts delete mode 100644 packages/style-engine/src/styles/typography/textTransform.ts diff --git a/packages/blocks/src/api/constants.js b/packages/blocks/src/api/constants.js index d16cadc0b74d03..0a9cae8cbfb060 100644 --- a/packages/blocks/src/api/constants.js +++ b/packages/blocks/src/api/constants.js @@ -103,6 +103,7 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { value: [ 'color', 'text' ], support: [ 'color', 'text' ], requiresOptOut: true, + useEngine: true, }, filter: { value: [ 'filter', 'duotone' ], @@ -128,6 +129,7 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { fontWeight: { value: [ 'typography', 'fontWeight' ], support: [ 'typography', '__experimentalFontWeight' ], + useEngine: true, }, lineHeight: { value: [ 'typography', 'lineHeight' ], @@ -164,10 +166,12 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { textTransform: { value: [ 'typography', 'textTransform' ], support: [ 'typography', '__experimentalTextTransform' ], + useEngine: true, }, letterSpacing: { value: [ 'typography', 'letterSpacing' ], support: [ 'typography', '__experimentalLetterSpacing' ], + useEngine: true, }, '--wp--style--block-gap': { value: [ 'spacing', 'blockGap' ], diff --git a/packages/style-engine/src/styles/color/index.ts b/packages/style-engine/src/styles/color/index.ts index 2e548a7cb8209d..aa34be4cf7ad46 100644 --- a/packages/style-engine/src/styles/color/index.ts +++ b/packages/style-engine/src/styles/color/index.ts @@ -1,6 +1,14 @@ /** * Internal dependencies */ -import text from './text'; +import type { Style, StyleOptions } from '../../types'; +import { generateRule } from '../utils'; + +const text = { + name: 'text', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( style, [ 'color', 'text' ], 'color', options ); + }, +}; export default [ text ]; diff --git a/packages/style-engine/src/styles/color/text.ts b/packages/style-engine/src/styles/color/text.ts deleted file mode 100644 index a6d37ae82a8ce4..00000000000000 --- a/packages/style-engine/src/styles/color/text.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - -/** - * Internal dependencies - */ -import type { Style, StyleOptions } from '../../types'; - -const text = { - name: 'text', - generate: ( style: Style, options: StyleOptions ) => { - const styleValue: string | undefined = get( - style, - [ 'color', 'text' ], - null - ); - - return styleValue - ? [ - { - selector: options?.selector, - key: 'color', - value: styleValue, - }, - ] - : []; - }, -}; - -export default text; diff --git a/packages/style-engine/src/styles/typography/fontSize.ts b/packages/style-engine/src/styles/typography/fontSize.ts deleted file mode 100644 index 574b69c63beb19..00000000000000 --- a/packages/style-engine/src/styles/typography/fontSize.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - -/** - * Internal dependencies - */ -import type { Style, StyleOptions } from '../../types'; - -const fontSize = { - name: 'fontSize', - generate: ( style: Style, options: StyleOptions ) => { - const styleValue: string | undefined = get( - style, - [ 'typography', 'fontSize' ], - null - ); - - return styleValue - ? [ - { - selector: options?.selector, - key: 'fontSize', - value: styleValue, - }, - ] - : []; - }, -}; - -export default fontSize; diff --git a/packages/style-engine/src/styles/typography/fontWeight.ts b/packages/style-engine/src/styles/typography/fontWeight.ts deleted file mode 100644 index e6a542c538fad4..00000000000000 --- a/packages/style-engine/src/styles/typography/fontWeight.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - -/** - * Internal dependencies - */ -import type { Style, StyleOptions } from '../../types'; - -const fontWeight = { - name: 'fontWeight', - generate: ( style: Style, options: StyleOptions ) => { - const styleValue: string | undefined = get( - style, - [ 'typography', 'fontWeight' ], - null - ); - - return styleValue - ? [ - { - selector: options?.selector, - key: 'fontWeight', - value: styleValue, - }, - ] - : []; - }, -}; - -export default fontWeight; diff --git a/packages/style-engine/src/styles/typography/index.ts b/packages/style-engine/src/styles/typography/index.ts index 8b7cb5419a72bb..7c74da86b466fd 100644 --- a/packages/style-engine/src/styles/typography/index.ts +++ b/packages/style-engine/src/styles/typography/index.ts @@ -1,12 +1,80 @@ /** * Internal dependencies */ -import fontSize from './fontSize'; -import fontWeight from './fontWeight'; -import lineHeight from './lineHeight'; -import textDecoration from './textDecoration'; -import textTransform from './textTransform'; -import letterSpacing from './letterSpacing'; +import type { Style, StyleOptions } from '../../types'; +import { generateRule } from '../utils'; + +const fontSize = { + name: 'fontSize', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( + style, + [ 'typography', 'fontSize' ], + 'fontSize', + options + ); + }, +}; + +const fontWeight = { + name: 'fontSize', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( + style, + [ 'typography', 'fontWeight' ], + 'fontWeight', + options + ); + }, +}; + +const letterSpacing = { + name: 'letterSpacing', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( + style, + [ 'typography', 'letterSpacing' ], + 'letterSpacing', + options + ); + }, +}; + +const lineHeight = { + name: 'letterSpacing', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( + style, + [ 'typography', 'lineHeight' ], + 'lineHeight', + options + ); + }, +}; + +const textDecoration = { + name: 'textDecoration', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( + style, + [ 'typography', 'textDecoration' ], + 'textDecoration', + options + ); + }, +}; + +const textTransform = { + name: 'textTransform', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( + style, + [ 'typography', 'textTransform' ], + 'textTransform', + options + ); + }, +}; export default [ fontSize, diff --git a/packages/style-engine/src/styles/typography/letterSpacing.ts b/packages/style-engine/src/styles/typography/letterSpacing.ts deleted file mode 100644 index cf53e16feb3d95..00000000000000 --- a/packages/style-engine/src/styles/typography/letterSpacing.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - -/** - * Internal dependencies - */ -import type { Style, StyleOptions } from '../../types'; - -const letterSpacing = { - name: 'letterSpacing', - generate: ( style: Style, options: StyleOptions ) => { - const styleValue: string | undefined = get( - style, - [ 'typography', 'letterSpacing' ], - null - ); - - return styleValue - ? [ - { - selector: options?.selector, - key: 'letterSpacing', - value: styleValue, - }, - ] - : []; - }, -}; - -export default letterSpacing; diff --git a/packages/style-engine/src/styles/typography/lineHeight.ts b/packages/style-engine/src/styles/typography/lineHeight.ts deleted file mode 100644 index 2602696a0e0229..00000000000000 --- a/packages/style-engine/src/styles/typography/lineHeight.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - -/** - * Internal dependencies - */ -import type { Style, StyleOptions } from '../../types'; - -const lineHeight = { - name: 'lineHeight', - generate: ( style: Style, options: StyleOptions ) => { - const styleValue: string | undefined = get( - style, - [ 'typography', 'lineHeight' ], - null - ); - - return styleValue - ? [ - { - selector: options?.selector, - key: 'lineHeight', - value: styleValue, - }, - ] - : []; - }, -}; - -export default lineHeight; diff --git a/packages/style-engine/src/styles/typography/textDecoration.ts b/packages/style-engine/src/styles/typography/textDecoration.ts deleted file mode 100644 index 64f46ecf5c4d67..00000000000000 --- a/packages/style-engine/src/styles/typography/textDecoration.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - -/** - * Internal dependencies - */ -import type { Style, StyleOptions } from '../../types'; - -const textDecoration = { - name: 'textDecoration', - generate: ( style: Style, options: StyleOptions ) => { - const styleValue: string | undefined = get( - style, - [ 'typography', 'textDecoration' ], - null - ); - - return styleValue - ? [ - { - selector: options?.selector, - key: 'textDecoration', - value: styleValue, - }, - ] - : []; - }, -}; - -export default textDecoration; diff --git a/packages/style-engine/src/styles/typography/textTransform.ts b/packages/style-engine/src/styles/typography/textTransform.ts deleted file mode 100644 index 41c74d55e7d791..00000000000000 --- a/packages/style-engine/src/styles/typography/textTransform.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - -/** - * Internal dependencies - */ -import type { Style, StyleOptions } from '../../types'; - -const textTransform = { - name: 'textTransform', - generate: ( style: Style, options: StyleOptions ) => { - const styleValue: string | undefined = get( - style, - [ 'typography', 'textTransform' ], - null - ); - - return styleValue - ? [ - { - selector: options?.selector, - key: 'textTransform', - value: styleValue, - }, - ] - : []; - }, -}; - -export default textTransform; diff --git a/packages/style-engine/src/styles/utils.ts b/packages/style-engine/src/styles/utils.ts index 628b4e91b6e0c7..77eba28a185b7a 100644 --- a/packages/style-engine/src/styles/utils.ts +++ b/packages/style-engine/src/styles/utils.ts @@ -8,6 +8,25 @@ import { get, upperFirst } from 'lodash'; */ import type { GeneratedCSSRule, Style, Box, StyleOptions } from '../types'; +export function generateRule( + style: Style, + path: string[], + cssProperty: string, + options: StyleOptions +) { + const styleValue: string | undefined = get( style, path, null ); + + return styleValue + ? [ + { + selector: options?.selector, + key: cssProperty, + value: styleValue, + }, + ] + : []; +} + export function generateBoxRules( style: Style, options: StyleOptions, From c77f3be4ac28f8fb4d7f1bd6328a94aa3bb22d49 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Tue, 3 May 2022 15:49:44 +1000 Subject: [PATCH 08/22] Experiment: adding classname generator --- packages/style-engine/README.md | 12 +++++ packages/style-engine/src/index.ts | 19 +++++++- .../src/styles/color/background.ts | 44 +++++++++++++++++ .../style-engine/src/styles/color/gradient.ts | 44 +++++++++++++++++ .../style-engine/src/styles/color/index.ts | 14 ++---- .../style-engine/src/styles/color/text.ts | 39 +++++++++++++++ packages/style-engine/src/styles/utils.ts | 17 ++++++- packages/style-engine/src/test/index.js | 47 +++++++++++++++++-- packages/style-engine/src/types.ts | 1 + 9 files changed, 221 insertions(+), 16 deletions(-) create mode 100644 packages/style-engine/src/styles/color/background.ts create mode 100644 packages/style-engine/src/styles/color/gradient.ts create mode 100644 packages/style-engine/src/styles/color/text.ts diff --git a/packages/style-engine/README.md b/packages/style-engine/README.md index 612097cc497350..139f67638bfc27 100644 --- a/packages/style-engine/README.md +++ b/packages/style-engine/README.md @@ -44,6 +44,18 @@ _Returns_ - `string`: generated stylesheet. +### getClassnames + +Returns an array of classnames. + +_Parameters_ + +- _style_ `Style`: Style object. + +_Returns_ + +- `string[]`: string\[] An array of classnames. + ### getCSSRules Returns a JSON representation of the generated CSS rules. diff --git a/packages/style-engine/src/index.ts b/packages/style-engine/src/index.ts index 9386931bc127ef..1e927df5d8fa26 100644 --- a/packages/style-engine/src/index.ts +++ b/packages/style-engine/src/index.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { groupBy, kebabCase } from 'lodash'; +import { groupBy, kebabCase, uniq } from 'lodash'; /** * Internal dependencies @@ -65,3 +65,20 @@ export function getCSSRules( return rules; } + +/** + * Returns an array of classnames. + * + * @param style Style object. + * + * @return string[] An array of classnames. + */ +export function getClassnames( style: Style ): string[] { + const classNames: string[] = []; + styleDefinitions.forEach( ( definition: StyleDefinition ) => { + if ( typeof definition.getClassNames === 'function' ) { + classNames.push( ...definition.getClassNames( style ) ); + } + } ); + return uniq( classNames ); +} diff --git a/packages/style-engine/src/styles/color/background.ts b/packages/style-engine/src/styles/color/background.ts new file mode 100644 index 00000000000000..3f2a2b4abb04c6 --- /dev/null +++ b/packages/style-engine/src/styles/color/background.ts @@ -0,0 +1,44 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import type { Style, StyleOptions } from '../../types'; +import { generateRule, getSlugFromPreset } from '../utils'; + +const text = { + name: 'background', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( + style, + [ 'color', 'background' ], + 'backgroundColor', + options + ); + }, + getClassNames: ( style: Style ) => { + const classNames = []; + const styleValue: string | undefined = get( style, [ + 'color', + 'background', + ] ); + + if ( styleValue ) { + const slug = getSlugFromPreset( styleValue, 'color' ); + if ( slug ) { + classNames.push( `has-${ slug }-background-color` ); + } + // Primary color classes must come before the `has-text-color`, + // `has-background` and `has-link-color` classes to maintain backwards + // compatibility and avoid block invalidations. + classNames.push( 'has-background' ); + } + + return classNames; + }, +}; + +export default text; diff --git a/packages/style-engine/src/styles/color/gradient.ts b/packages/style-engine/src/styles/color/gradient.ts new file mode 100644 index 00000000000000..c6c07a440629a1 --- /dev/null +++ b/packages/style-engine/src/styles/color/gradient.ts @@ -0,0 +1,44 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import type { Style, StyleOptions } from '../../types'; +import { generateRule, getSlugFromPreset } from '../utils'; + +const text = { + name: 'gradient', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( + style, + [ 'color', 'gradient' ], + 'gradient', + options + ); + }, + getClassNames: ( style: Style ) => { + const classNames = []; + const styleValue: string | undefined = get( style, [ + 'color', + 'gradient', + ] ); + + if ( styleValue ) { + const slug = getSlugFromPreset( styleValue, 'gradient' ); + if ( slug ) { + classNames.push( `has-${ slug }-gradient-background` ); + } + // Primary color classes must come before the `has-text-color`, + // `has-background` and `has-link-color` classes to maintain backwards + // compatibility and avoid block invalidations. + classNames.push( 'has-background' ); + } + + return classNames; + }, +}; + +export default text; diff --git a/packages/style-engine/src/styles/color/index.ts b/packages/style-engine/src/styles/color/index.ts index aa34be4cf7ad46..0f8ab94a67dd78 100644 --- a/packages/style-engine/src/styles/color/index.ts +++ b/packages/style-engine/src/styles/color/index.ts @@ -1,14 +1,8 @@ /** * Internal dependencies */ -import type { Style, StyleOptions } from '../../types'; -import { generateRule } from '../utils'; +import background from './background'; +import gradient from './gradient'; +import text from './text'; -const text = { - name: 'text', - generate: ( style: Style, options: StyleOptions ) => { - return generateRule( style, [ 'color', 'text' ], 'color', options ); - }, -}; - -export default [ text ]; +export default [ background, gradient, text ]; diff --git a/packages/style-engine/src/styles/color/text.ts b/packages/style-engine/src/styles/color/text.ts new file mode 100644 index 00000000000000..8598b61ad8c51c --- /dev/null +++ b/packages/style-engine/src/styles/color/text.ts @@ -0,0 +1,39 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import type { Style, StyleOptions } from '../../types'; +import { generateRule, getSlugFromPreset } from '../utils'; + +const text = { + name: 'text', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( style, [ 'color', 'text' ], 'color', options ); + }, + getClassNames: ( style: Style ) => { + const classNames = []; + const styleValue: string | undefined = get( style, [ + 'color', + 'text', + ] ); + + if ( styleValue ) { + const slug = getSlugFromPreset( styleValue, 'color' ); + if ( slug ) { + classNames.push( `has-${ slug }-color` ); + } + // Primary color classes must come before the `has-text-color`, + // `has-background` and `has-link-color` classes to maintain backwards + // compatibility and avoid block invalidations. + classNames.push( 'has-text-color' ); + } + + return classNames; + }, +}; + +export default text; diff --git a/packages/style-engine/src/styles/utils.ts b/packages/style-engine/src/styles/utils.ts index 77eba28a185b7a..9a66e32dab9446 100644 --- a/packages/style-engine/src/styles/utils.ts +++ b/packages/style-engine/src/styles/utils.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { get, upperFirst } from 'lodash'; +import { get, kebabCase, upperFirst } from 'lodash'; /** * Internal dependencies @@ -14,7 +14,7 @@ export function generateRule( cssProperty: string, options: StyleOptions ) { - const styleValue: string | undefined = get( style, path, null ); + const styleValue: string | undefined = get( style, path ); return styleValue ? [ @@ -65,3 +65,16 @@ export function generateBoxRules( return rules; } + +export function getSlugFromPreset( + styleValue: string, + styleContext: string +): string | null { + if ( ! styleValue ) { + return null; + } + + const presetValues = styleValue.split( `var:preset|${ styleContext }|` ); + + return presetValues[ 1 ] ? kebabCase( presetValues[ 1 ] ) : null; +} diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js index a07cbc2af980b1..784ddef67a7b89 100644 --- a/packages/style-engine/src/test/index.js +++ b/packages/style-engine/src/test/index.js @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { getCSSRules, generate } from '../index'; +import { getCSSRules, generate, getClassnames } from '../index'; describe( 'generate', () => { it( 'should generate empty style', () => { @@ -12,9 +12,16 @@ describe( 'generate', () => { expect( generate( { spacing: { padding: '10px', margin: '12px' }, - color: { text: '#381515' }, + color: { + text: '#f1f1f1', + background: '#222222', + gradient: + 'linear-gradient(135deg,rgb(6,147,227) 0%,rgb(143,47,47) 49%,rgb(155,81,224) 100%)', + }, } ) - ).toEqual( 'color: #381515; margin: 12px; padding: 10px;' ); + ).toEqual( + 'background-color: #222222; gradient: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(143,47,47) 49%,rgb(155,81,224) 100%); color: #f1f1f1; margin: 12px; padding: 10px;' + ); } ); it( 'should generate styles with an optional selector', () => { @@ -145,3 +152,37 @@ describe( 'getCSSRules', () => { ] ); } ); } ); + +describe( 'getClassnames', () => { + it( 'should return an empty classnames array', () => { + expect( getClassnames( {} ) ).toEqual( [] ); + } ); + + it( 'should generate classnames for eligible custom styles', () => { + expect( + getClassnames( { + spacing: { padding: '10px', margin: '12px' }, + color: { text: '#381515', background: '#000000' }, + } ) + ).toEqual( [ 'has-background', 'has-text-color' ] ); + } ); + + it( 'should generate classnames for eligible preset values', () => { + expect( + getClassnames( { + spacing: { padding: '10px', margin: '12px' }, + color: { + text: 'var:preset|color|whiteAsShow', + background: 'var:preset|color|mustardPickles', + gradient: 'var:preset|gradient|hairyOrange', + }, + } ) + ).toEqual( [ + 'has-mustard-pickles-background-color', + 'has-background', + 'has-hairy-orange-gradient-background', + 'has-white-as-show-color', + 'has-text-color', + ] ); + } ); +} ); diff --git a/packages/style-engine/src/types.ts b/packages/style-engine/src/types.ts index 82be652ce1db73..3d8ee21b895e33 100644 --- a/packages/style-engine/src/types.ts +++ b/packages/style-engine/src/types.ts @@ -51,4 +51,5 @@ export type GeneratedCSSRule = { export interface StyleDefinition { name: string; generate: ( style: Style, options: StyleOptions ) => GeneratedCSSRule[]; + getClassNames?: ( style: Style ) => string[]; } From ac06d20a161eb4f878b000f42e00ab56a12926a4 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Wed, 4 May 2022 17:30:54 +1000 Subject: [PATCH 09/22] Fixing bonkers typos because I copy and paste like I just don't care. It's my PR and I'll fail if I want to. Preferencing `uniq` for new Set() spread Updating tests. --- packages/style-engine/src/index.ts | 5 +++-- .../style-engine/src/styles/color/background.ts | 14 +++----------- .../style-engine/src/styles/color/gradient.ts | 16 ++++------------ packages/style-engine/src/styles/color/text.ts | 11 +---------- packages/style-engine/src/styles/utils.ts | 4 ++-- packages/style-engine/src/test/index.js | 2 +- packages/style-engine/src/types.ts | 2 ++ 7 files changed, 16 insertions(+), 38 deletions(-) diff --git a/packages/style-engine/src/index.ts b/packages/style-engine/src/index.ts index 1e927df5d8fa26..c6df60e50570c9 100644 --- a/packages/style-engine/src/index.ts +++ b/packages/style-engine/src/index.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { groupBy, kebabCase, uniq } from 'lodash'; +import { groupBy, kebabCase } from 'lodash'; /** * Internal dependencies @@ -80,5 +80,6 @@ export function getClassnames( style: Style ): string[] { classNames.push( ...definition.getClassNames( style ) ); } } ); - return uniq( classNames ); + + return [ ...new Set( classNames ) ]; } diff --git a/packages/style-engine/src/styles/color/background.ts b/packages/style-engine/src/styles/color/background.ts index 3f2a2b4abb04c6..7a8dd267ef3922 100644 --- a/packages/style-engine/src/styles/color/background.ts +++ b/packages/style-engine/src/styles/color/background.ts @@ -1,15 +1,10 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - /** * Internal dependencies */ import type { Style, StyleOptions } from '../../types'; import { generateRule, getSlugFromPreset } from '../utils'; -const text = { +const background = { name: 'background', generate: ( style: Style, options: StyleOptions ) => { return generateRule( @@ -21,10 +16,7 @@ const text = { }, getClassNames: ( style: Style ) => { const classNames = []; - const styleValue: string | undefined = get( style, [ - 'color', - 'background', - ] ); + const styleValue: string | undefined = style?.color?.background; if ( styleValue ) { const slug = getSlugFromPreset( styleValue, 'color' ); @@ -41,4 +33,4 @@ const text = { }, }; -export default text; +export default background; diff --git a/packages/style-engine/src/styles/color/gradient.ts b/packages/style-engine/src/styles/color/gradient.ts index c6c07a440629a1..f25c22e42556a3 100644 --- a/packages/style-engine/src/styles/color/gradient.ts +++ b/packages/style-engine/src/styles/color/gradient.ts @@ -1,30 +1,22 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - /** * Internal dependencies */ import type { Style, StyleOptions } from '../../types'; import { generateRule, getSlugFromPreset } from '../utils'; -const text = { +const gradient = { name: 'gradient', generate: ( style: Style, options: StyleOptions ) => { return generateRule( style, [ 'color', 'gradient' ], - 'gradient', + 'background', options ); }, getClassNames: ( style: Style ) => { const classNames = []; - const styleValue: string | undefined = get( style, [ - 'color', - 'gradient', - ] ); + const styleValue: string | number | undefined = style?.color?.gradient; if ( styleValue ) { const slug = getSlugFromPreset( styleValue, 'gradient' ); @@ -41,4 +33,4 @@ const text = { }, }; -export default text; +export default gradient; diff --git a/packages/style-engine/src/styles/color/text.ts b/packages/style-engine/src/styles/color/text.ts index 8598b61ad8c51c..b3909f80f07d80 100644 --- a/packages/style-engine/src/styles/color/text.ts +++ b/packages/style-engine/src/styles/color/text.ts @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - /** * Internal dependencies */ @@ -16,11 +11,7 @@ const text = { }, getClassNames: ( style: Style ) => { const classNames = []; - const styleValue: string | undefined = get( style, [ - 'color', - 'text', - ] ); - + const styleValue: string | undefined = style?.color?.text; if ( styleValue ) { const slug = getSlugFromPreset( styleValue, 'color' ); if ( slug ) { diff --git a/packages/style-engine/src/styles/utils.ts b/packages/style-engine/src/styles/utils.ts index 9a66e32dab9446..1aff6581c6c67f 100644 --- a/packages/style-engine/src/styles/utils.ts +++ b/packages/style-engine/src/styles/utils.ts @@ -67,10 +67,10 @@ export function generateBoxRules( } export function getSlugFromPreset( - styleValue: string, + styleValue: string | number | undefined, styleContext: string ): string | null { - if ( ! styleValue ) { + if ( typeof styleValue !== 'string' ) { return null; } diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js index 784ddef67a7b89..948ccfe4f395e9 100644 --- a/packages/style-engine/src/test/index.js +++ b/packages/style-engine/src/test/index.js @@ -20,7 +20,7 @@ describe( 'generate', () => { }, } ) ).toEqual( - 'background-color: #222222; gradient: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(143,47,47) 49%,rgb(155,81,224) 100%); color: #f1f1f1; margin: 12px; padding: 10px;' + 'background-color: #222222; background: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(143,47,47) 49%,rgb(155,81,224) 100%); color: #f1f1f1; margin: 12px; padding: 10px;' ); } ); diff --git a/packages/style-engine/src/types.ts b/packages/style-engine/src/types.ts index 3d8ee21b895e33..f4d7262ee37a9f 100644 --- a/packages/style-engine/src/types.ts +++ b/packages/style-engine/src/types.ts @@ -28,6 +28,8 @@ export interface Style { }; color?: { text?: CSSProperties[ 'color' ]; + background?: CSSProperties[ 'backgroundColor' ]; + gradient?: CSSProperties[ 'background' ]; }; } From 5c779847b1b213ebcef891e9e3220ef2bfebef04 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Wed, 4 May 2022 19:19:20 +1000 Subject: [PATCH 10/22] Enable style engine for backgroundColor --- packages/blocks/src/api/constants.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/blocks/src/api/constants.js b/packages/blocks/src/api/constants.js index 0a9cae8cbfb060..a95c7fee1e5457 100644 --- a/packages/blocks/src/api/constants.js +++ b/packages/blocks/src/api/constants.js @@ -28,6 +28,7 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { value: [ 'color', 'background' ], support: [ 'color', 'background' ], requiresOptOut: true, + useEngine: true, }, borderColor: { value: [ 'border', 'color' ], From c012938f6394f948429ac7add40b170208e4e502 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Wed, 4 May 2022 19:37:08 +1000 Subject: [PATCH 11/22] Regenerate pullquote fixture since the style engine changes the order of the inline styles rules. Nothing major. --- .../blocks/core__pullquote__custom-colors.serialized.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/fixtures/blocks/core__pullquote__custom-colors.serialized.html b/test/integration/fixtures/blocks/core__pullquote__custom-colors.serialized.html index 3427b0ff08798b..ba577c8f5c2a77 100644 --- a/test/integration/fixtures/blocks/core__pullquote__custom-colors.serialized.html +++ b/test/integration/fixtures/blocks/core__pullquote__custom-colors.serialized.html @@ -1,3 +1,3 @@ -

pullquote

citation
+

pullquote

citation
From 0832750aae207c2bd477ebf11f35759740fe5319 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Fri, 6 May 2022 12:12:24 +1000 Subject: [PATCH 12/22] Add constants Updated inline docs Making the generateRule signature the same as generateBoxRules --- packages/blocks/src/api/constants.js | 1 - .../src/styles/color/background.ts | 4 +- .../style-engine/src/styles/color/gradient.ts | 4 +- .../style-engine/src/styles/color/index.ts | 3 +- .../style-engine/src/styles/color/text.ts | 2 +- packages/style-engine/src/styles/constants.ts | 3 ++ .../src/styles/typography/index.ts | 24 +++++------ packages/style-engine/src/styles/utils.ts | 42 +++++++++++++++++-- 8 files changed, 59 insertions(+), 24 deletions(-) create mode 100644 packages/style-engine/src/styles/constants.ts diff --git a/packages/blocks/src/api/constants.js b/packages/blocks/src/api/constants.js index a95c7fee1e5457..2212abc8515547 100644 --- a/packages/blocks/src/api/constants.js +++ b/packages/blocks/src/api/constants.js @@ -104,7 +104,6 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { value: [ 'color', 'text' ], support: [ 'color', 'text' ], requiresOptOut: true, - useEngine: true, }, filter: { value: [ 'filter', 'duotone' ], diff --git a/packages/style-engine/src/styles/color/background.ts b/packages/style-engine/src/styles/color/background.ts index 7a8dd267ef3922..7fe1d75f99da94 100644 --- a/packages/style-engine/src/styles/color/background.ts +++ b/packages/style-engine/src/styles/color/background.ts @@ -9,9 +9,9 @@ const background = { generate: ( style: Style, options: StyleOptions ) => { return generateRule( style, + options, [ 'color', 'background' ], - 'backgroundColor', - options + 'backgroundColor' ); }, getClassNames: ( style: Style ) => { diff --git a/packages/style-engine/src/styles/color/gradient.ts b/packages/style-engine/src/styles/color/gradient.ts index f25c22e42556a3..70acbc019079da 100644 --- a/packages/style-engine/src/styles/color/gradient.ts +++ b/packages/style-engine/src/styles/color/gradient.ts @@ -9,9 +9,9 @@ const gradient = { generate: ( style: Style, options: StyleOptions ) => { return generateRule( style, + options, [ 'color', 'gradient' ], - 'background', - options + 'background' ); }, getClassNames: ( style: Style ) => { diff --git a/packages/style-engine/src/styles/color/index.ts b/packages/style-engine/src/styles/color/index.ts index 0f8ab94a67dd78..e30c58760b1775 100644 --- a/packages/style-engine/src/styles/color/index.ts +++ b/packages/style-engine/src/styles/color/index.ts @@ -3,6 +3,5 @@ */ import background from './background'; import gradient from './gradient'; -import text from './text'; -export default [ background, gradient, text ]; +export default [ background, gradient ]; diff --git a/packages/style-engine/src/styles/color/text.ts b/packages/style-engine/src/styles/color/text.ts index b3909f80f07d80..95a93695be5753 100644 --- a/packages/style-engine/src/styles/color/text.ts +++ b/packages/style-engine/src/styles/color/text.ts @@ -7,7 +7,7 @@ import { generateRule, getSlugFromPreset } from '../utils'; const text = { name: 'text', generate: ( style: Style, options: StyleOptions ) => { - return generateRule( style, [ 'color', 'text' ], 'color', options ); + return generateRule( style, options, [ 'color', 'text' ], 'color' ); }, getClassNames: ( style: Style ) => { const classNames = []; diff --git a/packages/style-engine/src/styles/constants.ts b/packages/style-engine/src/styles/constants.ts new file mode 100644 index 00000000000000..9df0cf255568e8 --- /dev/null +++ b/packages/style-engine/src/styles/constants.ts @@ -0,0 +1,3 @@ +export const VARIABLE_REFERENCE_PREFIX = 'var:'; +export const VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE = '|'; +export const VARIABLE_PATH_SEPARATOR_TOKEN_STYLE = '--'; diff --git a/packages/style-engine/src/styles/typography/index.ts b/packages/style-engine/src/styles/typography/index.ts index 7c74da86b466fd..e6e65433b8d69c 100644 --- a/packages/style-engine/src/styles/typography/index.ts +++ b/packages/style-engine/src/styles/typography/index.ts @@ -9,9 +9,9 @@ const fontSize = { generate: ( style: Style, options: StyleOptions ) => { return generateRule( style, + options, [ 'typography', 'fontSize' ], - 'fontSize', - options + 'fontSize' ); }, }; @@ -21,9 +21,9 @@ const fontWeight = { generate: ( style: Style, options: StyleOptions ) => { return generateRule( style, + options, [ 'typography', 'fontWeight' ], - 'fontWeight', - options + 'fontWeight' ); }, }; @@ -33,9 +33,9 @@ const letterSpacing = { generate: ( style: Style, options: StyleOptions ) => { return generateRule( style, + options, [ 'typography', 'letterSpacing' ], - 'letterSpacing', - options + 'letterSpacing' ); }, }; @@ -45,9 +45,9 @@ const lineHeight = { generate: ( style: Style, options: StyleOptions ) => { return generateRule( style, + options, [ 'typography', 'lineHeight' ], - 'lineHeight', - options + 'lineHeight' ); }, }; @@ -57,9 +57,9 @@ const textDecoration = { generate: ( style: Style, options: StyleOptions ) => { return generateRule( style, + options, [ 'typography', 'textDecoration' ], - 'textDecoration', - options + 'textDecoration' ); }, }; @@ -69,9 +69,9 @@ const textTransform = { generate: ( style: Style, options: StyleOptions ) => { return generateRule( style, + options, [ 'typography', 'textTransform' ], - 'textTransform', - options + 'textTransform' ); }, }; diff --git a/packages/style-engine/src/styles/utils.ts b/packages/style-engine/src/styles/utils.ts index 1aff6581c6c67f..4172325f8c2b29 100644 --- a/packages/style-engine/src/styles/utils.ts +++ b/packages/style-engine/src/styles/utils.ts @@ -7,12 +7,26 @@ import { get, kebabCase, upperFirst } from 'lodash'; * Internal dependencies */ import type { GeneratedCSSRule, Style, Box, StyleOptions } from '../types'; +import { + VARIABLE_REFERENCE_PREFIX, + VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE, +} from './constants'; +/** + * Returns a JSON representation of the generated CSS rules. + * + * @param style Style object. + * @param options Options object with settings to adjust how the styles are generated. + * @param path An array of strings representing the path to the style value in the style object. + * @param ruleKey A CSS property key. + * + * @return GeneratedCSSRule[] CSS rules. + */ export function generateRule( style: Style, + options: StyleOptions, path: string[], - cssProperty: string, - options: StyleOptions + ruleKey: string ) { const styleValue: string | undefined = get( style, path ); @@ -20,13 +34,23 @@ export function generateRule( ? [ { selector: options?.selector, - key: cssProperty, + key: ruleKey, value: styleValue, }, ] : []; } +/** + * Returns a JSON representation of the generated CSS rules taking into account box model properties, top, right, bottom, left. + * + * @param style Style object. + * @param options Options object with settings to adjust how the styles are generated. + * @param path An array of strings representing the path to the style value in the style object. + * @param ruleKey A CSS property key. + * + * @return GeneratedCSSRule[] CSS rules. + */ export function generateBoxRules( style: Style, options: StyleOptions, @@ -66,6 +90,14 @@ export function generateBoxRules( return rules; } +/** + * Returns a slug from a style value following the pattern `var:preset|styleContext|slug`. + * + * @param styleValue A raw style value. + * @param styleContext A style context to parse + * + * @return generated styles. + */ export function getSlugFromPreset( styleValue: string | number | undefined, styleContext: string @@ -74,7 +106,9 @@ export function getSlugFromPreset( return null; } - const presetValues = styleValue.split( `var:preset|${ styleContext }|` ); + const presetValues = styleValue.split( + `${ VARIABLE_REFERENCE_PREFIX }preset${ VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE }${ styleContext }${ VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE }` + ); return presetValues[ 1 ] ? kebabCase( presetValues[ 1 ] ) : null; } From c78f5d098521ce3daf4a4a1e19bb715d9f33a8c1 Mon Sep 17 00:00:00 2001 From: Ramon Date: Thu, 5 May 2022 16:03:42 +1000 Subject: [PATCH 13/22] Update packages/style-engine/src/index.ts Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> --- packages/style-engine/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/style-engine/src/index.ts b/packages/style-engine/src/index.ts index c6df60e50570c9..6ecec865404f3b 100644 --- a/packages/style-engine/src/index.ts +++ b/packages/style-engine/src/index.ts @@ -71,7 +71,7 @@ export function getCSSRules( * * @param style Style object. * - * @return string[] An array of classnames. + * @return An array of classnames. */ export function getClassnames( style: Style ): string[] { const classNames: string[] = []; From 695cd341416aede402978d51645a31a7aa45f96f Mon Sep 17 00:00:00 2001 From: ramonjd Date: Fri, 6 May 2022 12:20:42 +1000 Subject: [PATCH 14/22] Refactoring generate method to split inline and selector logic Removing styles color text support because we haven't yet come up a with a way to deal with link color styles for elements. We need to reconcile the way we generate text colors with link css var colors and the logic in hooks/style.js Add constants Updated inline docs Making the generateRule signature the same as generateBoxRules --- packages/style-engine/README.md | 2 +- packages/style-engine/src/index.ts | 19 +++++++++++++------ packages/style-engine/src/test/index.js | 6 ++---- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/style-engine/README.md b/packages/style-engine/README.md index 139f67638bfc27..63abaa8f2783d8 100644 --- a/packages/style-engine/README.md +++ b/packages/style-engine/README.md @@ -54,7 +54,7 @@ _Parameters_ _Returns_ -- `string[]`: string\[] An array of classnames. +- `string[]`: An array of classnames. ### getCSSRules diff --git a/packages/style-engine/src/index.ts b/packages/style-engine/src/index.ts index 6ecec865404f3b..62a7cac23b2bc9 100644 --- a/packages/style-engine/src/index.ts +++ b/packages/style-engine/src/index.ts @@ -24,26 +24,33 @@ import { styleDefinitions } from './styles'; */ export function generate( style: Style, options: StyleOptions ): string { const rules = getCSSRules( style, options ); + + // If no selector is provided, treat generated rules as inline styles to be returned as a single string. + if ( ! options?.selector ) { + const inlineRules: string[] = []; + rules.forEach( ( rule ) => { + inlineRules.push( `${ kebabCase( rule.key ) }: ${ rule.value };` ); + } ); + return inlineRules.join( ' ' ); + } + const groupedRules = groupBy( rules, 'selector' ); const selectorRules = Object.keys( groupedRules ).reduce( ( acc: string[], subSelector: string ) => { - const hasSelector = subSelector !== 'undefined'; - const prefix = hasSelector ? `${ subSelector } { ` : ''; - const suffix = subSelector !== 'undefined' ? ' }' : ''; acc.push( - `${ prefix }${ groupedRules[ subSelector ] + `${ subSelector } { ${ groupedRules[ subSelector ] .map( ( rule: GeneratedCSSRule ) => `${ kebabCase( rule.key ) }: ${ rule.value };` ) - .join( ' ' ) }${ suffix }` + .join( ' ' ) } }` ); return acc; }, [] ); - return selectorRules.join( '' ); + return selectorRules.join( '\n' ); } /** diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js index 948ccfe4f395e9..f7649344b52c43 100644 --- a/packages/style-engine/src/test/index.js +++ b/packages/style-engine/src/test/index.js @@ -20,7 +20,7 @@ describe( 'generate', () => { }, } ) ).toEqual( - 'background-color: #222222; background: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(143,47,47) 49%,rgb(155,81,224) 100%); color: #f1f1f1; margin: 12px; padding: 10px;' + 'background-color: #222222; background: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(143,47,47) 49%,rgb(155,81,224) 100%); margin: 12px; padding: 10px;' ); } ); @@ -164,7 +164,7 @@ describe( 'getClassnames', () => { spacing: { padding: '10px', margin: '12px' }, color: { text: '#381515', background: '#000000' }, } ) - ).toEqual( [ 'has-background', 'has-text-color' ] ); + ).toEqual( [ 'has-background' ] ); } ); it( 'should generate classnames for eligible preset values', () => { @@ -181,8 +181,6 @@ describe( 'getClassnames', () => { 'has-mustard-pickles-background-color', 'has-background', 'has-hairy-orange-gradient-background', - 'has-white-as-show-color', - 'has-text-color', ] ); } ); } ); From 8922ec00f03a182c138f4be147511ce73f39ff77 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Fri, 6 May 2022 12:23:44 +1000 Subject: [PATCH 15/22] Remove TODO comment. It's something we can do in the future, but it doesn't need to pollute the codebase. --- packages/block-editor/src/hooks/style.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index d81a22a323fd7a..400ebd0a84263f 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -237,12 +237,6 @@ export function addSaveProps( } } ); - // @TODO - // Experimental notes: - // Maybe the style engine could do the classname work of `addSaveProps` in packages/block-editor/src/hooks/color.js here? - // And addSaveProps in packages/block-editor/src/hooks/font-family.js - // And add it to props.className? - props.style = { ...getInlineStyles( style ), ...props.style, From bdb1fb1303095858ba85a860e557851e45c1a6ef Mon Sep 17 00:00:00 2001 From: ramonjd Date: Fri, 6 May 2022 13:08:27 +1000 Subject: [PATCH 16/22] Reinstating color and now parsing style value for `var:`, whereby we'd return CSS vars all the time. --- packages/blocks/src/api/constants.js | 1 + .../style-engine/src/styles/color/index.ts | 3 ++- packages/style-engine/src/styles/utils.ts | 21 ++++++++++++++++++- packages/style-engine/src/test/index.js | 6 ++++-- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/packages/blocks/src/api/constants.js b/packages/blocks/src/api/constants.js index 2212abc8515547..a95c7fee1e5457 100644 --- a/packages/blocks/src/api/constants.js +++ b/packages/blocks/src/api/constants.js @@ -104,6 +104,7 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { value: [ 'color', 'text' ], support: [ 'color', 'text' ], requiresOptOut: true, + useEngine: true, }, filter: { value: [ 'filter', 'duotone' ], diff --git a/packages/style-engine/src/styles/color/index.ts b/packages/style-engine/src/styles/color/index.ts index e30c58760b1775..0f8ab94a67dd78 100644 --- a/packages/style-engine/src/styles/color/index.ts +++ b/packages/style-engine/src/styles/color/index.ts @@ -3,5 +3,6 @@ */ import background from './background'; import gradient from './gradient'; +import text from './text'; -export default [ background, gradient ]; +export default [ background, gradient, text ]; diff --git a/packages/style-engine/src/styles/utils.ts b/packages/style-engine/src/styles/utils.ts index 4172325f8c2b29..d90f228ebfcd97 100644 --- a/packages/style-engine/src/styles/utils.ts +++ b/packages/style-engine/src/styles/utils.ts @@ -10,6 +10,7 @@ import type { GeneratedCSSRule, Style, Box, StyleOptions } from '../types'; import { VARIABLE_REFERENCE_PREFIX, VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE, + VARIABLE_PATH_SEPARATOR_TOKEN_STYLE, } from './constants'; /** @@ -35,7 +36,7 @@ export function generateRule( { selector: options?.selector, key: ruleKey, - value: styleValue, + value: getCSSVarFromStyleValue( styleValue ), }, ] : []; @@ -112,3 +113,21 @@ export function getSlugFromPreset( return presetValues[ 1 ] ? kebabCase( presetValues[ 1 ] ) : null; } + +/** + * Returns a CSS var value from incoming style value following the pattern `var:description|context|slug`. + * + * @param styleValue A raw style value. + * + * @return string A CSS var value. + */ +export function getCSSVarFromStyleValue( styleValue: string ): string { + if ( styleValue.startsWith( VARIABLE_REFERENCE_PREFIX ) ) { + const variable = styleValue + .slice( VARIABLE_REFERENCE_PREFIX.length ) + .split( VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE ) + .join( VARIABLE_PATH_SEPARATOR_TOKEN_STYLE ); + return `var(--wp--${ variable })`; + } + return styleValue; +} diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js index f7649344b52c43..948ccfe4f395e9 100644 --- a/packages/style-engine/src/test/index.js +++ b/packages/style-engine/src/test/index.js @@ -20,7 +20,7 @@ describe( 'generate', () => { }, } ) ).toEqual( - 'background-color: #222222; background: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(143,47,47) 49%,rgb(155,81,224) 100%); margin: 12px; padding: 10px;' + 'background-color: #222222; background: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(143,47,47) 49%,rgb(155,81,224) 100%); color: #f1f1f1; margin: 12px; padding: 10px;' ); } ); @@ -164,7 +164,7 @@ describe( 'getClassnames', () => { spacing: { padding: '10px', margin: '12px' }, color: { text: '#381515', background: '#000000' }, } ) - ).toEqual( [ 'has-background' ] ); + ).toEqual( [ 'has-background', 'has-text-color' ] ); } ); it( 'should generate classnames for eligible preset values', () => { @@ -181,6 +181,8 @@ describe( 'getClassnames', () => { 'has-mustard-pickles-background-color', 'has-background', 'has-hairy-orange-gradient-background', + 'has-white-as-show-color', + 'has-text-color', ] ); } ); } ); From 864413e0405b7f7ac9d473207f76796ce28f4f63 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Fri, 6 May 2022 13:52:52 +1000 Subject: [PATCH 17/22] A bit of defensive coding to check for a string type --- packages/style-engine/src/styles/utils.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/style-engine/src/styles/utils.ts b/packages/style-engine/src/styles/utils.ts index d90f228ebfcd97..1c23ef4478f94a 100644 --- a/packages/style-engine/src/styles/utils.ts +++ b/packages/style-engine/src/styles/utils.ts @@ -122,7 +122,10 @@ export function getSlugFromPreset( * @return string A CSS var value. */ export function getCSSVarFromStyleValue( styleValue: string ): string { - if ( styleValue.startsWith( VARIABLE_REFERENCE_PREFIX ) ) { + if ( + typeof styleValue === 'string' && + styleValue.startsWith( VARIABLE_REFERENCE_PREFIX ) + ) { const variable = styleValue .slice( VARIABLE_REFERENCE_PREFIX.length ) .split( VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE ) From 2b5c94985ec08c2c478161ba40148d60fe6fa24e Mon Sep 17 00:00:00 2001 From: ramonjd Date: Mon, 9 May 2022 13:33:06 +1000 Subject: [PATCH 18/22] Testing out generating block color classnames using the style engine. --- packages/block-editor/src/hooks/color.js | 66 +++++++++---------- packages/style-engine/src/index.ts | 4 +- .../style-engine/src/styles/elements/index.ts | 20 ++++++ packages/style-engine/src/styles/index.ts | 8 ++- packages/style-engine/src/types.ts | 9 ++- 5 files changed, 70 insertions(+), 37 deletions(-) create mode 100644 packages/style-engine/src/styles/elements/index.ts diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js index b02b9f2bfbbad6..13c8b84d423d74 100644 --- a/packages/block-editor/src/hooks/color.js +++ b/packages/block-editor/src/hooks/color.js @@ -17,12 +17,10 @@ import { createHigherOrderComponent } from '@wordpress/compose'; * Internal dependencies */ import { - getColorClassName, getColorObjectByColorValue, getColorObjectByAttributeValues, } from '../components/colors'; import { - __experimentalGetGradientClass, getGradientValueBySlug, getGradientSlugByValue, } from '../components/gradients'; @@ -34,6 +32,7 @@ import { } from './utils'; import ColorPanel from './color-panel'; import useSetting from '../components/use-setting'; +import { getClassnames } from '@wordpress/style-engine'; export const COLOR_SUPPORT_KEY = 'color'; @@ -252,52 +251,51 @@ export function addSaveProps( props, blockType, attributes ) { return props; } - const hasGradient = hasGradientSupport( blockType ); - // I'd have preferred to avoid the "style" attribute usage here const { backgroundColor, textColor, gradient, style } = attributes; const shouldSerialize = ( feature ) => ! shouldSkipSerialization( blockType, COLOR_SUPPORT_KEY, feature ); + const colorStyles = {}; + // Primary color classes must come before the `has-text-color`, // `has-background` and `has-link-color` classes to maintain backwards // compatibility and avoid block invalidations. - const textClass = shouldSerialize( 'text' ) - ? getColorClassName( 'color', textColor ) - : undefined; - - const gradientClass = shouldSerialize( 'gradients' ) - ? __experimentalGetGradientClass( gradient ) - : undefined; + if ( textColor && shouldSerialize( 'text' ) ) { + colorStyles.text = `var:preset|color|${ textColor }`; + } - const backgroundClass = shouldSerialize( 'background' ) - ? getColorClassName( 'background-color', backgroundColor ) - : undefined; + if ( + gradient && + shouldSerialize( 'gradients' ) && + hasGradientSupport( blockType ) + ) { + colorStyles.gradient = `var:preset|gradient|${ gradient }`; + } - const serializeHasBackground = - shouldSerialize( 'background' ) || shouldSerialize( 'gradients' ); - const hasBackground = - backgroundColor || - style?.color?.background || - ( hasGradient && ( gradient || style?.color?.gradient ) ); + if ( backgroundColor && shouldSerialize( 'background' ) ) { + colorStyles.background = `var:preset|color|${ backgroundColor }`; + } const newClassName = classnames( props.className, - textClass, - gradientClass, - { - // Don't apply the background class if there's a custom gradient. - [ backgroundClass ]: - ( ! hasGradient || ! style?.color?.gradient ) && - !! backgroundClass, - 'has-text-color': - shouldSerialize( 'text' ) && - ( textColor || style?.color?.text ), - 'has-background': serializeHasBackground && hasBackground, - 'has-link-color': - shouldSerialize( 'link' ) && style?.elements?.link?.color, - } + ...getClassnames( { + ...style, + color: { + ...colorStyles, + }, + elements: { + ...style?.elements, + link: { + color: { + text: shouldSerialize( 'link' ) + ? style?.elements?.link?.color + : undefined, + }, + }, + }, + } ) ); props.className = newClassName ? newClassName : undefined; diff --git a/packages/style-engine/src/index.ts b/packages/style-engine/src/index.ts index 62a7cac23b2bc9..c0b313501b9046 100644 --- a/packages/style-engine/src/index.ts +++ b/packages/style-engine/src/index.ts @@ -67,7 +67,9 @@ export function getCSSRules( ): GeneratedCSSRule[] { const rules: GeneratedCSSRule[] = []; styleDefinitions.forEach( ( definition: StyleDefinition ) => { - rules.push( ...definition.generate( style, options ) ); + if ( typeof definition.generate === 'function' ) { + rules.push( ...definition.generate( style, options ) ); + } } ); return rules; diff --git a/packages/style-engine/src/styles/elements/index.ts b/packages/style-engine/src/styles/elements/index.ts new file mode 100644 index 00000000000000..13e07aa7a63b67 --- /dev/null +++ b/packages/style-engine/src/styles/elements/index.ts @@ -0,0 +1,20 @@ +/** + * Internal dependencies + */ +import type { Style } from '../../types'; + +const link = { + name: 'link', + getClassNames: ( style: Style ) => { + const classNames = []; + const styleValue: string | undefined = + style?.elements?.link?.color?.text; + if ( styleValue ) { + classNames.push( 'has-link-color' ); + } + + return classNames; + }, +}; + +export default [ link ]; diff --git a/packages/style-engine/src/styles/index.ts b/packages/style-engine/src/styles/index.ts index 79f1c43d8d33f7..db56b35f8803e9 100644 --- a/packages/style-engine/src/styles/index.ts +++ b/packages/style-engine/src/styles/index.ts @@ -2,7 +2,13 @@ * Internal dependencies */ import color from './color'; +import elements from './elements'; import spacing from './spacing'; import typography from './typography'; -export const styleDefinitions = [ ...color, ...spacing, ...typography ]; +export const styleDefinitions = [ + ...color, + ...elements, + ...spacing, + ...typography, +]; diff --git a/packages/style-engine/src/types.ts b/packages/style-engine/src/types.ts index f4d7262ee37a9f..9f60b1b0f6fc03 100644 --- a/packages/style-engine/src/types.ts +++ b/packages/style-engine/src/types.ts @@ -31,6 +31,13 @@ export interface Style { background?: CSSProperties[ 'backgroundColor' ]; gradient?: CSSProperties[ 'background' ]; }; + elements?: { + link?: { + color?: { + text?: CSSProperties[ 'color' ]; + }; + }; + }; } export type StyleOptions = { @@ -52,6 +59,6 @@ export type GeneratedCSSRule = { export interface StyleDefinition { name: string; - generate: ( style: Style, options: StyleOptions ) => GeneratedCSSRule[]; + generate?: ( style: Style, options: StyleOptions ) => GeneratedCSSRule[]; getClassNames?: ( style: Style ) => string[]; } From 676936a98a0ea0d57f62a8cca6aec46f74a47ac1 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Mon, 9 May 2022 15:21:30 +1000 Subject: [PATCH 19/22] Also passing the style color value to `getClassnames` so it will add the generic class name if required. Regenerating fixtures due to the re-ordering of color classnames. --- packages/block-editor/src/hooks/color.js | 22 ++++++++++--------- .../style-engine/src/styles/color/index.ts | 2 +- packages/style-engine/src/test/index.js | 10 ++++----- .../core__button__squared.serialized.html | 2 +- .../fixtures/blocks/core__post-terms.json | 2 +- ...__pullquote__custom-colors.serialized.html | 2 +- ...e__pullquote__deprecated-4.serialized.html | 2 +- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js index 13c8b84d423d74..18f00c5c683687 100644 --- a/packages/block-editor/src/hooks/color.js +++ b/packages/block-editor/src/hooks/color.js @@ -262,20 +262,22 @@ export function addSaveProps( props, blockType, attributes ) { // Primary color classes must come before the `has-text-color`, // `has-background` and `has-link-color` classes to maintain backwards // compatibility and avoid block invalidations. - if ( textColor && shouldSerialize( 'text' ) ) { - colorStyles.text = `var:preset|color|${ textColor }`; + if ( shouldSerialize( 'text' ) ) { + colorStyles.text = textColor + ? `var:preset|color|${ textColor }` + : style?.color?.text; } - if ( - gradient && - shouldSerialize( 'gradients' ) && - hasGradientSupport( blockType ) - ) { - colorStyles.gradient = `var:preset|gradient|${ gradient }`; + if ( shouldSerialize( 'gradients' ) && hasGradientSupport( blockType ) ) { + colorStyles.gradient = gradient + ? `var:preset|gradient|${ gradient }` + : style?.color?.gradient; } - if ( backgroundColor && shouldSerialize( 'background' ) ) { - colorStyles.background = `var:preset|color|${ backgroundColor }`; + if ( shouldSerialize( 'background' ) ) { + colorStyles.background = backgroundColor + ? `var:preset|color|${ backgroundColor }` + : style?.color?.background; } const newClassName = classnames( diff --git a/packages/style-engine/src/styles/color/index.ts b/packages/style-engine/src/styles/color/index.ts index 0f8ab94a67dd78..15db28d726a806 100644 --- a/packages/style-engine/src/styles/color/index.ts +++ b/packages/style-engine/src/styles/color/index.ts @@ -5,4 +5,4 @@ import background from './background'; import gradient from './gradient'; import text from './text'; -export default [ background, gradient, text ]; +export default [ text, gradient, background ]; diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js index 948ccfe4f395e9..68e32bc04f4584 100644 --- a/packages/style-engine/src/test/index.js +++ b/packages/style-engine/src/test/index.js @@ -20,7 +20,7 @@ describe( 'generate', () => { }, } ) ).toEqual( - 'background-color: #222222; background: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(143,47,47) 49%,rgb(155,81,224) 100%); color: #f1f1f1; margin: 12px; padding: 10px;' + 'color: #f1f1f1; background: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(143,47,47) 49%,rgb(155,81,224) 100%); background-color: #222222; margin: 12px; padding: 10px;' ); } ); @@ -164,7 +164,7 @@ describe( 'getClassnames', () => { spacing: { padding: '10px', margin: '12px' }, color: { text: '#381515', background: '#000000' }, } ) - ).toEqual( [ 'has-background', 'has-text-color' ] ); + ).toEqual( [ 'has-text-color', 'has-background' ] ); } ); it( 'should generate classnames for eligible preset values', () => { @@ -178,11 +178,11 @@ describe( 'getClassnames', () => { }, } ) ).toEqual( [ - 'has-mustard-pickles-background-color', - 'has-background', - 'has-hairy-orange-gradient-background', 'has-white-as-show-color', 'has-text-color', + 'has-hairy-orange-gradient-background', + 'has-background', + 'has-mustard-pickles-background-color', ] ); } ); } ); diff --git a/test/integration/fixtures/blocks/core__button__squared.serialized.html b/test/integration/fixtures/blocks/core__button__squared.serialized.html index 29e7fed15a510c..ec83bb66b4971b 100644 --- a/test/integration/fixtures/blocks/core__button__squared.serialized.html +++ b/test/integration/fixtures/blocks/core__button__squared.serialized.html @@ -1,3 +1,3 @@ - + diff --git a/test/integration/fixtures/blocks/core__post-terms.json b/test/integration/fixtures/blocks/core__post-terms.json index f3b9bd3b4828f2..6cddf3d6043d9f 100644 --- a/test/integration/fixtures/blocks/core__post-terms.json +++ b/test/integration/fixtures/blocks/core__post-terms.json @@ -3,8 +3,8 @@ "name": "core/post-terms", "isValid": true, "attributes": { - "prefix": "", "separator": ", ", + "prefix": "", "suffix": "" }, "innerBlocks": [] diff --git a/test/integration/fixtures/blocks/core__pullquote__custom-colors.serialized.html b/test/integration/fixtures/blocks/core__pullquote__custom-colors.serialized.html index ba577c8f5c2a77..d6b9f285fdecb3 100644 --- a/test/integration/fixtures/blocks/core__pullquote__custom-colors.serialized.html +++ b/test/integration/fixtures/blocks/core__pullquote__custom-colors.serialized.html @@ -1,3 +1,3 @@ -

pullquote

citation
+

pullquote

citation
diff --git a/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html b/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html index a780d8fa0ae009..30b3d6071c74d8 100644 --- a/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html +++ b/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html @@ -1,3 +1,3 @@ -

pullquote

before block supports
+

pullquote

before block supports
From 53ac842095352143d4292391552b9f5503f742d6 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Tue, 10 May 2022 12:59:41 +1000 Subject: [PATCH 20/22] Reverting `getClassnames`. It's a bigger change and should be looked at in another PR. --- packages/block-editor/src/hooks/color.js | 68 +++++------ packages/style-engine/README.md | 12 -- packages/style-engine/src/index.ts | 18 --- .../src/styles/color/background.ts | 19 +-- .../style-engine/src/styles/color/gradient.ts | 19 +-- .../style-engine/src/styles/color/text.ts | 18 +-- .../style-engine/src/styles/elements/index.ts | 20 ---- packages/style-engine/src/styles/index.ts | 8 +- .../src/styles/typography/index.ts | 27 ++++- packages/style-engine/src/test/index.js | 109 ++++++++++++------ .../fixtures/blocks/core__post-terms.json | 2 +- ...e__pullquote__deprecated-4.serialized.html | 4 +- 12 files changed, 140 insertions(+), 184 deletions(-) delete mode 100644 packages/style-engine/src/styles/elements/index.ts diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js index 18f00c5c683687..b02b9f2bfbbad6 100644 --- a/packages/block-editor/src/hooks/color.js +++ b/packages/block-editor/src/hooks/color.js @@ -17,10 +17,12 @@ import { createHigherOrderComponent } from '@wordpress/compose'; * Internal dependencies */ import { + getColorClassName, getColorObjectByColorValue, getColorObjectByAttributeValues, } from '../components/colors'; import { + __experimentalGetGradientClass, getGradientValueBySlug, getGradientSlugByValue, } from '../components/gradients'; @@ -32,7 +34,6 @@ import { } from './utils'; import ColorPanel from './color-panel'; import useSetting from '../components/use-setting'; -import { getClassnames } from '@wordpress/style-engine'; export const COLOR_SUPPORT_KEY = 'color'; @@ -251,53 +252,52 @@ export function addSaveProps( props, blockType, attributes ) { return props; } + const hasGradient = hasGradientSupport( blockType ); + // I'd have preferred to avoid the "style" attribute usage here const { backgroundColor, textColor, gradient, style } = attributes; const shouldSerialize = ( feature ) => ! shouldSkipSerialization( blockType, COLOR_SUPPORT_KEY, feature ); - const colorStyles = {}; - // Primary color classes must come before the `has-text-color`, // `has-background` and `has-link-color` classes to maintain backwards // compatibility and avoid block invalidations. - if ( shouldSerialize( 'text' ) ) { - colorStyles.text = textColor - ? `var:preset|color|${ textColor }` - : style?.color?.text; - } + const textClass = shouldSerialize( 'text' ) + ? getColorClassName( 'color', textColor ) + : undefined; - if ( shouldSerialize( 'gradients' ) && hasGradientSupport( blockType ) ) { - colorStyles.gradient = gradient - ? `var:preset|gradient|${ gradient }` - : style?.color?.gradient; - } + const gradientClass = shouldSerialize( 'gradients' ) + ? __experimentalGetGradientClass( gradient ) + : undefined; - if ( shouldSerialize( 'background' ) ) { - colorStyles.background = backgroundColor - ? `var:preset|color|${ backgroundColor }` - : style?.color?.background; - } + const backgroundClass = shouldSerialize( 'background' ) + ? getColorClassName( 'background-color', backgroundColor ) + : undefined; + + const serializeHasBackground = + shouldSerialize( 'background' ) || shouldSerialize( 'gradients' ); + const hasBackground = + backgroundColor || + style?.color?.background || + ( hasGradient && ( gradient || style?.color?.gradient ) ); const newClassName = classnames( props.className, - ...getClassnames( { - ...style, - color: { - ...colorStyles, - }, - elements: { - ...style?.elements, - link: { - color: { - text: shouldSerialize( 'link' ) - ? style?.elements?.link?.color - : undefined, - }, - }, - }, - } ) + textClass, + gradientClass, + { + // Don't apply the background class if there's a custom gradient. + [ backgroundClass ]: + ( ! hasGradient || ! style?.color?.gradient ) && + !! backgroundClass, + 'has-text-color': + shouldSerialize( 'text' ) && + ( textColor || style?.color?.text ), + 'has-background': serializeHasBackground && hasBackground, + 'has-link-color': + shouldSerialize( 'link' ) && style?.elements?.link?.color, + } ); props.className = newClassName ? newClassName : undefined; diff --git a/packages/style-engine/README.md b/packages/style-engine/README.md index 63abaa8f2783d8..612097cc497350 100644 --- a/packages/style-engine/README.md +++ b/packages/style-engine/README.md @@ -44,18 +44,6 @@ _Returns_ - `string`: generated stylesheet. -### getClassnames - -Returns an array of classnames. - -_Parameters_ - -- _style_ `Style`: Style object. - -_Returns_ - -- `string[]`: An array of classnames. - ### getCSSRules Returns a JSON representation of the generated CSS rules. diff --git a/packages/style-engine/src/index.ts b/packages/style-engine/src/index.ts index c0b313501b9046..c78dd753834b6d 100644 --- a/packages/style-engine/src/index.ts +++ b/packages/style-engine/src/index.ts @@ -74,21 +74,3 @@ export function getCSSRules( return rules; } - -/** - * Returns an array of classnames. - * - * @param style Style object. - * - * @return An array of classnames. - */ -export function getClassnames( style: Style ): string[] { - const classNames: string[] = []; - styleDefinitions.forEach( ( definition: StyleDefinition ) => { - if ( typeof definition.getClassNames === 'function' ) { - classNames.push( ...definition.getClassNames( style ) ); - } - } ); - - return [ ...new Set( classNames ) ]; -} diff --git a/packages/style-engine/src/styles/color/background.ts b/packages/style-engine/src/styles/color/background.ts index 7fe1d75f99da94..0df422bae7d58a 100644 --- a/packages/style-engine/src/styles/color/background.ts +++ b/packages/style-engine/src/styles/color/background.ts @@ -2,7 +2,7 @@ * Internal dependencies */ import type { Style, StyleOptions } from '../../types'; -import { generateRule, getSlugFromPreset } from '../utils'; +import { generateRule } from '../utils'; const background = { name: 'background', @@ -14,23 +14,6 @@ const background = { 'backgroundColor' ); }, - getClassNames: ( style: Style ) => { - const classNames = []; - const styleValue: string | undefined = style?.color?.background; - - if ( styleValue ) { - const slug = getSlugFromPreset( styleValue, 'color' ); - if ( slug ) { - classNames.push( `has-${ slug }-background-color` ); - } - // Primary color classes must come before the `has-text-color`, - // `has-background` and `has-link-color` classes to maintain backwards - // compatibility and avoid block invalidations. - classNames.push( 'has-background' ); - } - - return classNames; - }, }; export default background; diff --git a/packages/style-engine/src/styles/color/gradient.ts b/packages/style-engine/src/styles/color/gradient.ts index 70acbc019079da..4cc0aecffbe632 100644 --- a/packages/style-engine/src/styles/color/gradient.ts +++ b/packages/style-engine/src/styles/color/gradient.ts @@ -2,7 +2,7 @@ * Internal dependencies */ import type { Style, StyleOptions } from '../../types'; -import { generateRule, getSlugFromPreset } from '../utils'; +import { generateRule } from '../utils'; const gradient = { name: 'gradient', @@ -14,23 +14,6 @@ const gradient = { 'background' ); }, - getClassNames: ( style: Style ) => { - const classNames = []; - const styleValue: string | number | undefined = style?.color?.gradient; - - if ( styleValue ) { - const slug = getSlugFromPreset( styleValue, 'gradient' ); - if ( slug ) { - classNames.push( `has-${ slug }-gradient-background` ); - } - // Primary color classes must come before the `has-text-color`, - // `has-background` and `has-link-color` classes to maintain backwards - // compatibility and avoid block invalidations. - classNames.push( 'has-background' ); - } - - return classNames; - }, }; export default gradient; diff --git a/packages/style-engine/src/styles/color/text.ts b/packages/style-engine/src/styles/color/text.ts index 95a93695be5753..e1a6bb3d99b5eb 100644 --- a/packages/style-engine/src/styles/color/text.ts +++ b/packages/style-engine/src/styles/color/text.ts @@ -2,29 +2,13 @@ * Internal dependencies */ import type { Style, StyleOptions } from '../../types'; -import { generateRule, getSlugFromPreset } from '../utils'; +import { generateRule } from '../utils'; const text = { name: 'text', generate: ( style: Style, options: StyleOptions ) => { return generateRule( style, options, [ 'color', 'text' ], 'color' ); }, - getClassNames: ( style: Style ) => { - const classNames = []; - const styleValue: string | undefined = style?.color?.text; - if ( styleValue ) { - const slug = getSlugFromPreset( styleValue, 'color' ); - if ( slug ) { - classNames.push( `has-${ slug }-color` ); - } - // Primary color classes must come before the `has-text-color`, - // `has-background` and `has-link-color` classes to maintain backwards - // compatibility and avoid block invalidations. - classNames.push( 'has-text-color' ); - } - - return classNames; - }, }; export default text; diff --git a/packages/style-engine/src/styles/elements/index.ts b/packages/style-engine/src/styles/elements/index.ts deleted file mode 100644 index 13e07aa7a63b67..00000000000000 --- a/packages/style-engine/src/styles/elements/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Internal dependencies - */ -import type { Style } from '../../types'; - -const link = { - name: 'link', - getClassNames: ( style: Style ) => { - const classNames = []; - const styleValue: string | undefined = - style?.elements?.link?.color?.text; - if ( styleValue ) { - classNames.push( 'has-link-color' ); - } - - return classNames; - }, -}; - -export default [ link ]; diff --git a/packages/style-engine/src/styles/index.ts b/packages/style-engine/src/styles/index.ts index db56b35f8803e9..79f1c43d8d33f7 100644 --- a/packages/style-engine/src/styles/index.ts +++ b/packages/style-engine/src/styles/index.ts @@ -2,13 +2,7 @@ * Internal dependencies */ import color from './color'; -import elements from './elements'; import spacing from './spacing'; import typography from './typography'; -export const styleDefinitions = [ - ...color, - ...elements, - ...spacing, - ...typography, -]; +export const styleDefinitions = [ ...color, ...spacing, ...typography ]; diff --git a/packages/style-engine/src/styles/typography/index.ts b/packages/style-engine/src/styles/typography/index.ts index e6e65433b8d69c..31f09bdbb9ba73 100644 --- a/packages/style-engine/src/styles/typography/index.ts +++ b/packages/style-engine/src/styles/typography/index.ts @@ -4,6 +4,17 @@ import type { Style, StyleOptions } from '../../types'; import { generateRule } from '../utils'; +const fontFamily = { + name: 'fontFamily', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( + style, + options, + [ 'typography', 'fontFamily' ], + 'fontFamily' + ); + }, +}; const fontSize = { name: 'fontSize', generate: ( style: Style, options: StyleOptions ) => { @@ -16,8 +27,20 @@ const fontSize = { }, }; +const fontStyle = { + name: 'fontStyle', + generate: ( style: Style, options: StyleOptions ) => { + return generateRule( + style, + options, + [ 'typography', 'fontStyle' ], + 'fontStyle' + ); + }, +}; + const fontWeight = { - name: 'fontSize', + name: 'fontWeight', generate: ( style: Style, options: StyleOptions ) => { return generateRule( style, @@ -77,7 +100,9 @@ const textTransform = { }; export default [ + fontFamily, fontSize, + fontStyle, fontWeight, letterSpacing, lineHeight, diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js index 68e32bc04f4584..076475ef248af0 100644 --- a/packages/style-engine/src/test/index.js +++ b/packages/style-engine/src/test/index.js @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { getCSSRules, generate, getClassnames } from '../index'; +import { getCSSRules, generate } from '../index'; describe( 'generate', () => { it( 'should generate empty style', () => { @@ -39,6 +39,10 @@ describe( 'generate', () => { expect( generate( { + color: { + text: '#cccccc', + background: '#111111', + }, spacing: { padding: { top: '10px', bottom: '5px' }, margin: { @@ -50,6 +54,9 @@ describe( 'generate', () => { }, typography: { fontSize: '2.2rem', + fontStyle: 'italic', + fontWeight: '800', + fontFamily: "'Helvetica Neue',sans-serif", lineHeight: '3.3', textDecoration: 'line-through', letterSpacing: '12px', @@ -61,7 +68,7 @@ describe( 'generate', () => { } ) ).toEqual( - '.some-selector { margin-top: 11px; margin-right: 12px; margin-bottom: 13px; margin-left: 14px; padding-top: 10px; padding-bottom: 5px; font-size: 2.2rem; letter-spacing: 12px; line-height: 3.3; text-decoration: line-through; text-transform: uppercase; }' + ".some-selector { color: #cccccc; background-color: #111111; margin-top: 11px; margin-right: 12px; margin-bottom: 13px; margin-left: 14px; padding-top: 10px; padding-bottom: 5px; font-family: 'Helvetica Neue',sans-serif; font-size: 2.2rem; font-style: italic; font-weight: 800; letter-spacing: 12px; line-height: 3.3; text-decoration: line-through; text-transform: uppercase; }" ); } ); } ); @@ -119,16 +126,40 @@ describe( 'getCSSRules', () => { expect( getCSSRules( { + color: { + text: '#dddddd', + background: '#555555', + }, spacing: { padding: { top: '10px', bottom: '5px' }, margin: { right: '2em', left: '1vw' }, }, + typography: { + fontSize: '2.2rem', + fontStyle: 'italic', + fontWeight: '800', + fontFamily: "'Helvetica Neue',sans-serif", + lineHeight: '3.3', + textDecoration: 'line-through', + letterSpacing: '12px', + textTransform: 'uppercase', + }, }, { selector: '.some-selector', } ) ).toEqual( [ + { + selector: '.some-selector', + key: 'color', + value: '#dddddd', + }, + { + selector: '.some-selector', + key: 'backgroundColor', + value: '#555555', + }, { selector: '.some-selector', key: 'marginRight', @@ -149,40 +180,46 @@ describe( 'getCSSRules', () => { key: 'paddingBottom', value: '5px', }, - ] ); - } ); -} ); - -describe( 'getClassnames', () => { - it( 'should return an empty classnames array', () => { - expect( getClassnames( {} ) ).toEqual( [] ); - } ); - - it( 'should generate classnames for eligible custom styles', () => { - expect( - getClassnames( { - spacing: { padding: '10px', margin: '12px' }, - color: { text: '#381515', background: '#000000' }, - } ) - ).toEqual( [ 'has-text-color', 'has-background' ] ); - } ); - - it( 'should generate classnames for eligible preset values', () => { - expect( - getClassnames( { - spacing: { padding: '10px', margin: '12px' }, - color: { - text: 'var:preset|color|whiteAsShow', - background: 'var:preset|color|mustardPickles', - gradient: 'var:preset|gradient|hairyOrange', - }, - } ) - ).toEqual( [ - 'has-white-as-show-color', - 'has-text-color', - 'has-hairy-orange-gradient-background', - 'has-background', - 'has-mustard-pickles-background-color', + { + key: 'fontFamily', + selector: '.some-selector', + value: "'Helvetica Neue',sans-serif", + }, + { + key: 'fontSize', + selector: '.some-selector', + value: '2.2rem', + }, + { + key: 'fontStyle', + selector: '.some-selector', + value: 'italic', + }, + { + key: 'fontWeight', + selector: '.some-selector', + value: '800', + }, + { + key: 'letterSpacing', + selector: '.some-selector', + value: '12px', + }, + { + key: 'lineHeight', + selector: '.some-selector', + value: '3.3', + }, + { + key: 'textDecoration', + selector: '.some-selector', + value: 'line-through', + }, + { + key: 'textTransform', + selector: '.some-selector', + value: 'uppercase', + }, ] ); } ); } ); diff --git a/test/integration/fixtures/blocks/core__post-terms.json b/test/integration/fixtures/blocks/core__post-terms.json index 6cddf3d6043d9f..f3b9bd3b4828f2 100644 --- a/test/integration/fixtures/blocks/core__post-terms.json +++ b/test/integration/fixtures/blocks/core__post-terms.json @@ -3,8 +3,8 @@ "name": "core/post-terms", "isValid": true, "attributes": { - "separator": ", ", "prefix": "", + "separator": ", ", "suffix": "" }, "innerBlocks": [] diff --git a/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html b/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html index 30b3d6071c74d8..a821f0b1f982e3 100644 --- a/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html +++ b/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html @@ -1,3 +1,3 @@ - -

pullquote

before block supports
+ +

pullquote

before block supports
From 41dbe149df99c97efa4906100d76e1e5f4119df1 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Tue, 10 May 2022 13:09:45 +1000 Subject: [PATCH 21/22] Fix typo in fixture --- .../blocks/core__pullquote__deprecated-4.serialized.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html b/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html index a821f0b1f982e3..a780d8fa0ae009 100644 --- a/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html +++ b/test/integration/fixtures/blocks/core__pullquote__deprecated-4.serialized.html @@ -1,3 +1,3 @@ - +

pullquote

before block supports
From c090f5575851a0007ab7fb8a23cebb6ece2bab7d Mon Sep 17 00:00:00 2001 From: ramonjd Date: Tue, 17 May 2022 19:30:58 +1000 Subject: [PATCH 22/22] Flag fontStyle with useEngine: true so that it uses the style engine. Remove the handler for fontFamily to reflect the current situation in the editor whereby no custom fontFamily style values are expected. Removed unused function `getSlugFromPreset` Added tests for elements.link.color.text preset style values. --- packages/blocks/src/api/constants.js | 1 + .../src/styles/typography/index.ts | 12 --------- packages/style-engine/src/styles/utils.ts | 25 +------------------ packages/style-engine/src/test/index.js | 17 ++++++++----- 4 files changed, 13 insertions(+), 42 deletions(-) diff --git a/packages/blocks/src/api/constants.js b/packages/blocks/src/api/constants.js index a95c7fee1e5457..a5ed771d72d2fa 100644 --- a/packages/blocks/src/api/constants.js +++ b/packages/blocks/src/api/constants.js @@ -126,6 +126,7 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { fontStyle: { value: [ 'typography', 'fontStyle' ], support: [ 'typography', '__experimentalFontStyle' ], + useEngine: true, }, fontWeight: { value: [ 'typography', 'fontWeight' ], diff --git a/packages/style-engine/src/styles/typography/index.ts b/packages/style-engine/src/styles/typography/index.ts index 31f09bdbb9ba73..70e32b23cafe73 100644 --- a/packages/style-engine/src/styles/typography/index.ts +++ b/packages/style-engine/src/styles/typography/index.ts @@ -4,17 +4,6 @@ import type { Style, StyleOptions } from '../../types'; import { generateRule } from '../utils'; -const fontFamily = { - name: 'fontFamily', - generate: ( style: Style, options: StyleOptions ) => { - return generateRule( - style, - options, - [ 'typography', 'fontFamily' ], - 'fontFamily' - ); - }, -}; const fontSize = { name: 'fontSize', generate: ( style: Style, options: StyleOptions ) => { @@ -100,7 +89,6 @@ const textTransform = { }; export default [ - fontFamily, fontSize, fontStyle, fontWeight, diff --git a/packages/style-engine/src/styles/utils.ts b/packages/style-engine/src/styles/utils.ts index 1c23ef4478f94a..928d923c86821f 100644 --- a/packages/style-engine/src/styles/utils.ts +++ b/packages/style-engine/src/styles/utils.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { get, kebabCase, upperFirst } from 'lodash'; +import { get, upperFirst } from 'lodash'; /** * Internal dependencies @@ -91,29 +91,6 @@ export function generateBoxRules( return rules; } -/** - * Returns a slug from a style value following the pattern `var:preset|styleContext|slug`. - * - * @param styleValue A raw style value. - * @param styleContext A style context to parse - * - * @return generated styles. - */ -export function getSlugFromPreset( - styleValue: string | number | undefined, - styleContext: string -): string | null { - if ( typeof styleValue !== 'string' ) { - return null; - } - - const presetValues = styleValue.split( - `${ VARIABLE_REFERENCE_PREFIX }preset${ VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE }${ styleContext }${ VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE }` - ); - - return presetValues[ 1 ] ? kebabCase( presetValues[ 1 ] ) : null; -} - /** * Returns a CSS var value from incoming style value following the pattern `var:description|context|slug`. * diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js index 076475ef248af0..ad2acd401056b0 100644 --- a/packages/style-engine/src/test/index.js +++ b/packages/style-engine/src/test/index.js @@ -68,9 +68,19 @@ describe( 'generate', () => { } ) ).toEqual( - ".some-selector { color: #cccccc; background-color: #111111; margin-top: 11px; margin-right: 12px; margin-bottom: 13px; margin-left: 14px; padding-top: 10px; padding-bottom: 5px; font-family: 'Helvetica Neue',sans-serif; font-size: 2.2rem; font-style: italic; font-weight: 800; letter-spacing: 12px; line-height: 3.3; text-decoration: line-through; text-transform: uppercase; }" + '.some-selector { color: #cccccc; background-color: #111111; margin-top: 11px; margin-right: 12px; margin-bottom: 13px; margin-left: 14px; padding-top: 10px; padding-bottom: 5px; font-size: 2.2rem; font-style: italic; font-weight: 800; letter-spacing: 12px; line-height: 3.3; text-decoration: line-through; text-transform: uppercase; }' ); } ); + + it( 'should parse preset values (use for elements.link.color.text)', () => { + expect( + generate( { + color: { + text: 'var:preset|color|ham-sandwich', + }, + } ) + ).toEqual( 'color: var(--wp--preset--color--ham-sandwich);' ); + } ); } ); describe( 'getCSSRules', () => { @@ -180,11 +190,6 @@ describe( 'getCSSRules', () => { key: 'paddingBottom', value: '5px', }, - { - key: 'fontFamily', - selector: '.some-selector', - value: "'Helvetica Neue',sans-serif", - }, { key: 'fontSize', selector: '.some-selector',