Skip to content

Commit 633d509

Browse files
committed
Improve things drastically
1 parent a930a64 commit 633d509

File tree

3 files changed

+137
-59
lines changed

3 files changed

+137
-59
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"@wordpress/style-engine": "^0.11.0",
3939
"bytes": "^3.1.2",
4040
"classnames": "^2.3.2",
41+
"colord": "^2.9.3",
4142
"react-router-dom": "^6.20.1"
4243
}
4344
}

src/OnboardingSPA/utils/global-styles/use-global-styles-output.js

Lines changed: 73 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* External dependencies
33
*/
44
// eslint-disable-next-line import/no-extraneous-dependencies
5-
import { get, kebabCase, reduce } from 'lodash';
5+
import { kebabCase } from 'lodash';
66
/**
77
* WordPress dependencies
88
*/
@@ -14,8 +14,6 @@ import {
1414
} from '@wordpress/blocks';
1515
import { getCSSRules, getCSSValueFromRawStyle } from '@wordpress/style-engine';
1616
import {
17-
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
18-
__unstablePresetDuotoneFilter as PresetDuotoneFilter,
1917
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
2018
__experimentalGetGapCSSValue as getGapCSSValue,
2119
} from '@wordpress/block-editor';
@@ -25,6 +23,7 @@ import {
2523
import {
2624
appendToSelector,
2725
getBlockStyleVariationSelector,
26+
getDuotoneFilter,
2827
getResolvedValue,
2928
getValueFromObjectPath,
3029
LAYOUT_DEFINITIONS,
@@ -63,27 +62,35 @@ const BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS = {
6362
* @return {Array<Object>} An array of style declarations.
6463
*/
6564
function getPresetsDeclarations( blockPresets = {}, mergedSettings ) {
66-
return reduce(
67-
PRESET_METADATA,
65+
return PRESET_METADATA.reduce(
6866
( declarations, { path, valueKey, valueFunc, cssVarInfix } ) => {
69-
const presetByOrigin = get( blockPresets, path, [] );
70-
if ( presetByOrigin && Array.isArray( presetByOrigin ) ) {
71-
presetByOrigin.forEach( ( value ) => {
72-
if ( valueKey && ! valueFunc ) {
73-
declarations.push(
74-
`--wp--preset--${ cssVarInfix }--${ kebabCase(
75-
value.slug
76-
) }: ${ value[ valueKey ] }`
77-
);
78-
} else if ( valueFunc && typeof valueFunc === 'function' ) {
79-
declarations.push(
80-
`--wp--preset--${ cssVarInfix }--${ kebabCase(
81-
value.slug
82-
) }: ${ valueFunc( value, mergedSettings ) }`
83-
);
84-
}
85-
} );
86-
}
67+
const presetByOrigin = getValueFromObjectPath(
68+
blockPresets,
69+
path,
70+
[]
71+
);
72+
[ 'default', 'theme', 'custom' ].forEach( ( origin ) => {
73+
if ( presetByOrigin[ origin ] ) {
74+
presetByOrigin[ origin ].forEach( ( value ) => {
75+
if ( valueKey && ! valueFunc ) {
76+
declarations.push(
77+
`--wp--preset--${ cssVarInfix }--${ kebabCase(
78+
value.slug
79+
) }: ${ value[ valueKey ] }`
80+
);
81+
} else if (
82+
valueFunc &&
83+
typeof valueFunc === 'function'
84+
) {
85+
declarations.push(
86+
`--wp--preset--${ cssVarInfix }--${ kebabCase(
87+
value.slug
88+
) }: ${ valueFunc( value, mergedSettings ) }`
89+
);
90+
}
91+
} );
92+
}
93+
} );
8794

8895
return declarations;
8996
},
@@ -98,7 +105,7 @@ function getPresetsDeclarations( blockPresets = {}, mergedSettings ) {
98105
* @param {Object} blockPresets
99106
* @return {string} CSS declarations for the preset classes.
100107
*/
101-
function getPresetsClasses( blockSelector, blockPresets = {} ) {
108+
function getPresetsClasses( blockSelector = '*', blockPresets = {} ) {
102109
return PRESET_METADATA.reduce(
103110
( declarations, { path, cssVarInfix, classes } ) => {
104111
if ( ! classes ) {
@@ -110,26 +117,28 @@ function getPresetsClasses( blockSelector, blockPresets = {} ) {
110117
path,
111118
[]
112119
);
113-
if ( presetByOrigin && Array.isArray( presetByOrigin ) ) {
114-
presetByOrigin.forEach( ( { slug } ) => {
115-
classes.forEach( ( { classSuffix, propertyName } ) => {
116-
const classSelectorToUse = `.has-${ kebabCase(
117-
slug
118-
) }-${ classSuffix }`;
119-
const selectorToUse = blockSelector
120-
.split( ',' ) // Selector can be "h1, h2, h3"
121-
.map(
122-
( selector ) =>
123-
`${ selector }${ classSelectorToUse }`
124-
)
125-
.join( ',' );
126-
const value = `var(--wp--preset--${ cssVarInfix }--${ kebabCase(
127-
slug
128-
) })`;
129-
declarations += `${ selectorToUse }{${ propertyName }: ${ value } !important;}`;
120+
[ 'default', 'theme', 'custom' ].forEach( ( origin ) => {
121+
if ( presetByOrigin[ origin ] ) {
122+
presetByOrigin[ origin ].forEach( ( { slug } ) => {
123+
classes.forEach( ( { classSuffix, propertyName } ) => {
124+
const classSelectorToUse = `.has-${ kebabCase(
125+
slug
126+
) }-${ classSuffix }`;
127+
const selectorToUse = blockSelector
128+
.split( ',' ) // Selector can be "h1, h2, h3"
129+
.map(
130+
( selector ) =>
131+
`${ selector }${ classSelectorToUse }`
132+
)
133+
.join( ',' );
134+
const value = `var(--wp--preset--${ cssVarInfix }--${ kebabCase(
135+
slug
136+
) })`;
137+
declarations += `${ selectorToUse }{${ propertyName }: ${ value } !important;}`;
138+
} );
130139
} );
131-
} );
132-
}
140+
}
141+
} );
133142
return declarations;
134143
},
135144
''
@@ -149,13 +158,14 @@ function getPresetsSvgFilters( blockPresets = {} ) {
149158
return [ 'default', 'theme' ]
150159
.filter( ( origin ) => presetByOrigin[ origin ] )
151160
.flatMap( ( origin ) =>
152-
presetByOrigin[ origin ].map( ( preset ) => (
153-
<PresetDuotoneFilter
154-
preset={ preset }
155-
key={ preset.slug }
156-
/>
157-
) )
158-
);
161+
presetByOrigin[ origin ].map( ( preset ) =>
162+
getDuotoneFilter(
163+
`wp-duotone-${ preset.slug }`,
164+
preset.colors
165+
)
166+
)
167+
)
168+
.join( '' );
159169
} );
160170
}
161171

@@ -291,7 +301,7 @@ const getFeatureDeclarations = ( selectors, styles ) => {
291301
*
292302
* @param {Object} tree A theme.json tree containing layout definitions.
293303
*
294-
* @param {boolean} disableRootPadding
304+
* @param {boolean} disableRootPadding Whether to force disable the root padding styles.
295305
* @return {Array} An array of style declarations.
296306
*/
297307
export function getStylesDeclarations(
@@ -302,16 +312,19 @@ export function getStylesDeclarations(
302312
disableRootPadding = false
303313
) {
304314
const isRoot = ROOT_BLOCK_SELECTOR === selector;
305-
const output = reduce(
306-
STYLE_PROPERTY,
307-
( declarations, { value, properties, rootOnly }, key ) => {
315+
const output = Object.entries( STYLE_PROPERTY ).reduce(
316+
(
317+
declarations,
318+
[ key, { value, properties, useEngine, rootOnly } ]
319+
) => {
308320
if ( rootOnly && ! isRoot ) {
309321
return declarations;
310322
}
311323
const pathToValue = value;
312-
if ( pathToValue[ 0 ] === 'elements' ) {
324+
if ( pathToValue[ 0 ] === 'elements' || useEngine ) {
313325
return declarations;
314326
}
327+
315328
const styleValue = getValueFromObjectPath(
316329
blockStyles,
317330
pathToValue
@@ -449,7 +462,7 @@ export function getStylesDeclarations(
449462
* in theme.json, and outputting common layout styles, and specific blockGap values.
450463
*
451464
* @param {Object} props
452-
* @param {Object} props.layoutDefinitions A theme.json tree containing layout definitions.
465+
* @param {Object} props.layoutDefinitions Layout definitions, keyed by layout type.
453466
* @param {Object} props.style A style object containing spacing values.
454467
* @param {string} props.selector Selector used to group together layout styling rules.
455468
* @param {boolean} props.hasBlockGapSupport Whether or not the theme opts-in to blockGap support.
@@ -636,9 +649,9 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => {
636649
}
637650

638651
Object.entries( ELEMENTS ).forEach( ( [ name, selector ] ) => {
639-
if ( tree.styles?.elements[ name ] ) {
652+
if ( tree.styles?.elements?.[ name ] ) {
640653
nodes.push( {
641-
styles: tree.styles?.elements[ name ],
654+
styles: tree.styles?.elements?.[ name ],
642655
selector,
643656
// Top level elements that don't use a class name should not receive the
644657
// `:root :where()` wrapper to maintain backwards compatibility.
@@ -864,7 +877,7 @@ export const toCustomProperties = ( tree, blockSelectors ) => {
864877
}
865878

866879
if ( declarations.length > 0 ) {
867-
ruleset = ruleset + `${ selector }{${ declarations.join( ';' ) };}`;
880+
ruleset += `${ selector }{${ declarations.join( ';' ) };}`;
868881
}
869882
} );
870883

@@ -1240,6 +1253,7 @@ export const getBlockSelectors = ( blockTypes, storedPreviewSettings ) => {
12401253

12411254
if ( blockStyleVariationArray.length !== 0 ) {
12421255
blockStyleVariationArray?.forEach( ( variation ) => {
1256+
// eslint-disable-next-line no-unused-vars
12431257
Object.entries( variation ).forEach( ( [ key, value ] ) => {
12441258
const variationSuffix = blockType?.apiVersion
12451259
? `--${ blockType?.apiVersion }`

src/OnboardingSPA/utils/global-styles/utils.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44
// eslint-disable-next-line import/no-extraneous-dependencies
55
import { get, find } from 'lodash';
6+
import { colord } from 'colord';
67
import { getCSSValueFromRawStyle } from '@wordpress/style-engine';
78

89
/**
@@ -781,3 +782,65 @@ export function getResolvedValue( ruleValue, tree ) {
781782

782783
return resolvedValue;
783784
}
785+
786+
/**
787+
* Convert a list of colors to an object of R, G, and B values.
788+
*
789+
* @param {string[]} colors Array of RBG color strings.
790+
*
791+
* @return {Object} R, G, and B values.
792+
*/
793+
export function getValuesFromColors( colors = [] ) {
794+
const values = { r: [], g: [], b: [], a: [] };
795+
796+
colors.forEach( ( color ) => {
797+
const rgbColor = colord( color ).toRgb();
798+
values.r.push( rgbColor.r / 255 );
799+
values.g.push( rgbColor.g / 255 );
800+
values.b.push( rgbColor.b / 255 );
801+
values.a.push( rgbColor.a );
802+
} );
803+
804+
return values;
805+
}
806+
/**
807+
* The SVG part of the duotone filter.
808+
*
809+
* @param {string} id Unique id for this duotone filter.
810+
* @param {string[]} colors Color strings from dark to light.
811+
*
812+
* @return {string} Duotone SVG.
813+
*/
814+
export function getDuotoneFilter( id, colors ) {
815+
const values = getValuesFromColors( colors );
816+
return `
817+
<svg
818+
xmlns:xlink="http://www.w3.org/1999/xlink"
819+
viewBox="0 0 0 0"
820+
width="0"
821+
height="0"
822+
focusable="false"
823+
role="none"
824+
aria-hidden="true"
825+
style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;"
826+
>
827+
<defs>
828+
<filter id="${ id }">
829+
<!--
830+
Use sRGB instead of linearRGB so transparency looks correct.
831+
Use perceptual brightness to convert to grayscale.
832+
-->
833+
<feColorMatrix color-interpolation-filters="sRGB" type="matrix" values=" .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 "></feColorMatrix>
834+
<!-- Use sRGB instead of linearRGB to be consistent with how CSS gradients work. -->
835+
<feComponentTransfer color-interpolation-filters="sRGB">
836+
<feFuncR type="table" tableValues="${ values.r.join( ' ' ) }"></feFuncR>
837+
<feFuncG type="table" tableValues="${ values.g.join( ' ' ) }"></feFuncG>
838+
<feFuncB type="table" tableValues="${ values.b.join( ' ' ) }"></feFuncB>
839+
<feFuncA type="table" tableValues="${ values.a.join( ' ' ) }"></feFuncA>
840+
</feComponentTransfer>
841+
<!-- Re-mask the image with the original transparency since the feColorMatrix above loses that information. -->
842+
<feComposite in2="SourceGraphic" operator="in"></feComposite>
843+
</filter>
844+
</defs>
845+
</svg>`;
846+
}

0 commit comments

Comments
 (0)