@wordpress/edit-site 4.3.0 → 4.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/block-editor/resizable-editor.js +2 -1
- package/build/components/block-editor/resizable-editor.js.map +1 -1
- package/build/components/editor/global-styles-renderer.js +2 -1
- package/build/components/editor/global-styles-renderer.js.map +1 -1
- package/build/components/editor/index.js +9 -5
- package/build/components/editor/index.js.map +1 -1
- package/build/components/global-styles/screen-block-list.js +48 -4
- package/build/components/global-styles/screen-block-list.js.map +1 -1
- package/build/components/global-styles/use-global-styles-output.js +74 -9
- package/build/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build/components/global-styles/utils.js +12 -2
- package/build/components/global-styles/utils.js.map +1 -1
- package/build-module/components/block-editor/resizable-editor.js +2 -1
- package/build-module/components/block-editor/resizable-editor.js.map +1 -1
- package/build-module/components/editor/global-styles-renderer.js +2 -1
- package/build-module/components/editor/global-styles-renderer.js.map +1 -1
- package/build-module/components/editor/index.js +10 -6
- package/build-module/components/editor/index.js.map +1 -1
- package/build-module/components/global-styles/screen-block-list.js +47 -4
- package/build-module/components/global-styles/screen-block-list.js.map +1 -1
- package/build-module/components/global-styles/use-global-styles-output.js +71 -7
- package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build-module/components/global-styles/utils.js +12 -2
- package/build-module/components/global-styles/utils.js.map +1 -1
- package/build-style/style-rtl.css +2 -1
- package/build-style/style.css +2 -1
- package/package.json +29 -29
- package/src/components/block-editor/resizable-editor.js +6 -2
- package/src/components/editor/global-styles-renderer.js +2 -1
- package/src/components/editor/index.js +16 -5
- package/src/components/global-styles/screen-block-list.js +63 -8
- package/src/components/global-styles/style.scss +2 -1
- package/src/components/global-styles/test/use-global-styles-output.js +3 -1
- package/src/components/global-styles/use-global-styles-output.js +83 -11
- package/src/components/global-styles/utils.js +6 -0
|
@@ -5,7 +5,11 @@ import { useEffect, useState, useMemo, useCallback } from '@wordpress/element';
|
|
|
5
5
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
6
6
|
import { Popover, Button, Notice } from '@wordpress/components';
|
|
7
7
|
import { EntityProvider, store as coreStore } from '@wordpress/core-data';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
BlockContextProvider,
|
|
10
|
+
BlockBreadcrumb,
|
|
11
|
+
BlockStyles,
|
|
12
|
+
} from '@wordpress/block-editor';
|
|
9
13
|
import {
|
|
10
14
|
InterfaceSkeleton,
|
|
11
15
|
ComplementaryArea,
|
|
@@ -43,7 +47,6 @@ import { GlobalStylesProvider } from '../global-styles/global-styles-provider';
|
|
|
43
47
|
import useTitle from '../routes/use-title';
|
|
44
48
|
|
|
45
49
|
const interfaceLabels = {
|
|
46
|
-
secondarySidebar: __( 'Block Library' ),
|
|
47
50
|
drawer: __( 'Navigation Sidebar' ),
|
|
48
51
|
};
|
|
49
52
|
|
|
@@ -176,11 +179,15 @@ function Editor( { onError } ) {
|
|
|
176
179
|
templateType !== undefined &&
|
|
177
180
|
entityId !== undefined;
|
|
178
181
|
|
|
182
|
+
const secondarySidebarLabel = isListViewOpen
|
|
183
|
+
? __( 'List View' )
|
|
184
|
+
: __( 'Block Library' );
|
|
185
|
+
|
|
179
186
|
const secondarySidebar = () => {
|
|
180
|
-
if ( isInserterOpen ) {
|
|
187
|
+
if ( editorMode === 'visual' && isInserterOpen ) {
|
|
181
188
|
return <InserterSidebar />;
|
|
182
189
|
}
|
|
183
|
-
if ( isListViewOpen ) {
|
|
190
|
+
if ( editorMode === 'visual' && isListViewOpen ) {
|
|
184
191
|
return <ListViewSidebar />;
|
|
185
192
|
}
|
|
186
193
|
return null;
|
|
@@ -208,7 +215,10 @@ function Editor( { onError } ) {
|
|
|
208
215
|
<KeyboardShortcuts.Register />
|
|
209
216
|
<SidebarComplementaryAreaFills />
|
|
210
217
|
<InterfaceSkeleton
|
|
211
|
-
labels={
|
|
218
|
+
labels={ {
|
|
219
|
+
...interfaceLabels,
|
|
220
|
+
secondarySidebar: secondarySidebarLabel,
|
|
221
|
+
} }
|
|
212
222
|
className={
|
|
213
223
|
showIconLabels &&
|
|
214
224
|
'show-icon-labels'
|
|
@@ -236,6 +246,7 @@ function Editor( { onError } ) {
|
|
|
236
246
|
content={
|
|
237
247
|
<>
|
|
238
248
|
<EditorNotices />
|
|
249
|
+
<BlockStyles.Slot scope="core/block-inspector" />
|
|
239
250
|
{ editorMode === 'visual' &&
|
|
240
251
|
template && (
|
|
241
252
|
<BlockEditor
|
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { store as blocksStore } from '@wordpress/blocks';
|
|
5
|
-
import {
|
|
6
|
-
import { __ } from '@wordpress/i18n';
|
|
5
|
+
import { __, sprintf, _n } from '@wordpress/i18n';
|
|
7
6
|
import {
|
|
8
7
|
FlexItem,
|
|
8
|
+
SearchControl,
|
|
9
9
|
__experimentalHStack as HStack,
|
|
10
10
|
} from '@wordpress/components';
|
|
11
|
+
import { useSelect } from '@wordpress/data';
|
|
12
|
+
import { useState, useMemo, useEffect, useRef } from '@wordpress/element';
|
|
11
13
|
import { BlockIcon } from '@wordpress/block-editor';
|
|
14
|
+
import { useDebounce } from '@wordpress/compose';
|
|
15
|
+
import { speak } from '@wordpress/a11y';
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
18
|
* Internal dependencies
|
|
@@ -68,6 +72,45 @@ function BlockMenuItem( { block } ) {
|
|
|
68
72
|
|
|
69
73
|
function ScreenBlockList() {
|
|
70
74
|
const sortedBlockTypes = useSortedBlockTypes();
|
|
75
|
+
const [ filterValue, setFilterValue ] = useState( '' );
|
|
76
|
+
const debouncedSpeak = useDebounce( speak, 500 );
|
|
77
|
+
const isMatchingSearchTerm = useSelect(
|
|
78
|
+
( select ) => select( blocksStore ).isMatchingSearchTerm,
|
|
79
|
+
[]
|
|
80
|
+
);
|
|
81
|
+
const filteredBlockTypes = useMemo( () => {
|
|
82
|
+
if ( ! filterValue ) {
|
|
83
|
+
return sortedBlockTypes;
|
|
84
|
+
}
|
|
85
|
+
return sortedBlockTypes.filter( ( blockType ) =>
|
|
86
|
+
isMatchingSearchTerm( blockType, filterValue )
|
|
87
|
+
);
|
|
88
|
+
}, [ filterValue, sortedBlockTypes, isMatchingSearchTerm ] );
|
|
89
|
+
|
|
90
|
+
const blockTypesListRef = useRef();
|
|
91
|
+
|
|
92
|
+
// Announce search results on change
|
|
93
|
+
useEffect( () => {
|
|
94
|
+
if ( ! filterValue ) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// We extract the results from the wrapper div's `ref` because
|
|
98
|
+
// filtered items can contain items that will eventually not
|
|
99
|
+
// render and there is no reliable way to detect when a child
|
|
100
|
+
// will return `null`.
|
|
101
|
+
// TODO: We should find a better way of handling this as it's
|
|
102
|
+
// fragile and depends on the number of rendered elements of `BlockMenuItem`,
|
|
103
|
+
// which is now one.
|
|
104
|
+
// @see https://github.com/WordPress/gutenberg/pull/39117#discussion_r816022116
|
|
105
|
+
const count = blockTypesListRef.current.childElementCount;
|
|
106
|
+
const resultsFoundMessage = sprintf(
|
|
107
|
+
/* translators: %d: number of results. */
|
|
108
|
+
_n( '%d result found.', '%d results found.', count ),
|
|
109
|
+
count
|
|
110
|
+
);
|
|
111
|
+
debouncedSpeak( resultsFoundMessage, count );
|
|
112
|
+
}, [ filterValue, debouncedSpeak ] );
|
|
113
|
+
|
|
71
114
|
return (
|
|
72
115
|
<>
|
|
73
116
|
<ScreenHeader
|
|
@@ -76,12 +119,24 @@ function ScreenBlockList() {
|
|
|
76
119
|
'Customize the appearance of specific blocks and for the whole site.'
|
|
77
120
|
) }
|
|
78
121
|
/>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
122
|
+
<SearchControl
|
|
123
|
+
className="edit-site-block-types-search"
|
|
124
|
+
onChange={ setFilterValue }
|
|
125
|
+
value={ filterValue }
|
|
126
|
+
label={ __( 'Search for blocks' ) }
|
|
127
|
+
placeholder={ __( 'Search' ) }
|
|
128
|
+
/>
|
|
129
|
+
<div
|
|
130
|
+
ref={ blockTypesListRef }
|
|
131
|
+
className="edit-site-block-types-item-list"
|
|
132
|
+
>
|
|
133
|
+
{ filteredBlockTypes.map( ( block ) => (
|
|
134
|
+
<BlockMenuItem
|
|
135
|
+
block={ block }
|
|
136
|
+
key={ 'menu-itemblock-' + block.name }
|
|
137
|
+
/>
|
|
138
|
+
) ) }
|
|
139
|
+
</div>
|
|
85
140
|
</>
|
|
86
141
|
);
|
|
87
142
|
}
|
|
@@ -377,7 +377,9 @@ describe( 'global styles renderer', () => {
|
|
|
377
377
|
};
|
|
378
378
|
|
|
379
379
|
expect( toStyles( tree, blockSelectors ) ).toEqual(
|
|
380
|
-
'
|
|
380
|
+
'body {margin: 0;}' +
|
|
381
|
+
'body{background-color: red;margin: 10px;padding: 10px;}h1{font-size: 42px;}.wp-block-group{margin-top: 10px;margin-right: 20px;margin-bottom: 30px;margin-left: 40px;padding-top: 11px;padding-right: 22px;padding-bottom: 33px;padding-left: 44px;}h1,h2,h3,h4,h5,h6{color: orange;}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color: hotpink;}' +
|
|
382
|
+
'.has-white-color{color: var(--wp--preset--color--white) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}h1.has-blue-color,h2.has-blue-color,h3.has-blue-color,h4.has-blue-color,h5.has-blue-color,h6.has-blue-color{color: var(--wp--preset--color--blue) !important;}h1.has-blue-background-color,h2.has-blue-background-color,h3.has-blue-background-color,h4.has-blue-background-color,h5.has-blue-background-color,h6.has-blue-background-color{background-color: var(--wp--preset--color--blue) !important;}h1.has-blue-border-color,h2.has-blue-border-color,h3.has-blue-border-color,h4.has-blue-border-color,h5.has-blue-border-color,h6.has-blue-border-color{border-color: var(--wp--preset--color--blue) !important;}'
|
|
381
383
|
);
|
|
382
384
|
} );
|
|
383
385
|
} );
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
} from '@wordpress/blocks';
|
|
25
25
|
import { useEffect, useState, useContext } from '@wordpress/element';
|
|
26
26
|
import { getCSSRules } from '@wordpress/style-engine';
|
|
27
|
+
import { __unstablePresetDuotoneFilter as PresetDuotoneFilter } from '@wordpress/block-editor';
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Internal dependencies
|
|
@@ -59,16 +60,27 @@ function compileStyleValue( uncompiledValue ) {
|
|
|
59
60
|
function getPresetsDeclarations( blockPresets = {} ) {
|
|
60
61
|
return reduce(
|
|
61
62
|
PRESET_METADATA,
|
|
62
|
-
( declarations, { path, valueKey, cssVarInfix } ) => {
|
|
63
|
+
( declarations, { path, valueKey, valueFunc, cssVarInfix } ) => {
|
|
63
64
|
const presetByOrigin = get( blockPresets, path, [] );
|
|
64
65
|
[ 'default', 'theme', 'custom' ].forEach( ( origin ) => {
|
|
65
66
|
if ( presetByOrigin[ origin ] ) {
|
|
66
67
|
presetByOrigin[ origin ].forEach( ( value ) => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
if ( valueKey ) {
|
|
69
|
+
declarations.push(
|
|
70
|
+
`--wp--preset--${ cssVarInfix }--${ kebabCase(
|
|
71
|
+
value.slug
|
|
72
|
+
) }: ${ value[ valueKey ] }`
|
|
73
|
+
);
|
|
74
|
+
} else if (
|
|
75
|
+
valueFunc &&
|
|
76
|
+
typeof valueFunc === 'function'
|
|
77
|
+
) {
|
|
78
|
+
declarations.push(
|
|
79
|
+
`--wp--preset--${ cssVarInfix }--${ kebabCase(
|
|
80
|
+
value.slug
|
|
81
|
+
) }: ${ valueFunc( value ) }`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
72
84
|
} );
|
|
73
85
|
}
|
|
74
86
|
} );
|
|
@@ -123,6 +135,25 @@ function getPresetsClasses( blockSelector, blockPresets = {} ) {
|
|
|
123
135
|
);
|
|
124
136
|
}
|
|
125
137
|
|
|
138
|
+
function getPresetsSvgFilters( blockPresets = {} ) {
|
|
139
|
+
return PRESET_METADATA.filter(
|
|
140
|
+
// Duotone are the only type of filters for now.
|
|
141
|
+
( metadata ) => metadata.path.at( -1 ) === 'duotone'
|
|
142
|
+
).flatMap( ( metadata ) => {
|
|
143
|
+
const presetByOrigin = get( blockPresets, metadata.path, {} );
|
|
144
|
+
return [ 'default', 'theme' ]
|
|
145
|
+
.filter( ( origin ) => presetByOrigin[ origin ] )
|
|
146
|
+
.flatMap( ( origin ) =>
|
|
147
|
+
presetByOrigin[ origin ].map( ( preset ) => (
|
|
148
|
+
<PresetDuotoneFilter
|
|
149
|
+
preset={ preset }
|
|
150
|
+
key={ preset.slug }
|
|
151
|
+
/>
|
|
152
|
+
) )
|
|
153
|
+
);
|
|
154
|
+
} );
|
|
155
|
+
}
|
|
156
|
+
|
|
126
157
|
function flattenTree( input = {}, prefix, token ) {
|
|
127
158
|
let result = [];
|
|
128
159
|
Object.keys( input ).forEach( ( key ) => {
|
|
@@ -215,7 +246,9 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => {
|
|
|
215
246
|
|
|
216
247
|
const pickStyleKeys = ( treeToPickFrom ) =>
|
|
217
248
|
pickBy( treeToPickFrom, ( value, key ) =>
|
|
218
|
-
[ 'border', 'color', 'spacing', 'typography' ].includes(
|
|
249
|
+
[ 'border', 'color', 'spacing', 'typography', 'filter' ].includes(
|
|
250
|
+
key
|
|
251
|
+
)
|
|
219
252
|
);
|
|
220
253
|
|
|
221
254
|
// Top-level.
|
|
@@ -242,6 +275,7 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => {
|
|
|
242
275
|
nodes.push( {
|
|
243
276
|
styles: blockStyles,
|
|
244
277
|
selector: blockSelectors[ blockName ].selector,
|
|
278
|
+
duotoneSelector: blockSelectors[ blockName ].duotoneSelector,
|
|
245
279
|
} );
|
|
246
280
|
}
|
|
247
281
|
|
|
@@ -333,9 +367,34 @@ export const toStyles = ( tree, blockSelectors ) => {
|
|
|
333
367
|
const nodesWithStyles = getNodesWithStyles( tree, blockSelectors );
|
|
334
368
|
const nodesWithSettings = getNodesWithSettings( tree, blockSelectors );
|
|
335
369
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
370
|
+
/*
|
|
371
|
+
* Reset default browser margin on the root body element.
|
|
372
|
+
* This is set on the root selector **before** generating the ruleset
|
|
373
|
+
* from the `theme.json`. This is to ensure that if the `theme.json` declares
|
|
374
|
+
* `margin` in its `spacing` declaration for the `body` element then these
|
|
375
|
+
* user-generated values take precedence in the CSS cascade.
|
|
376
|
+
* @link https://github.com/WordPress/gutenberg/issues/36147.
|
|
377
|
+
*/
|
|
378
|
+
let ruleset = 'body {margin: 0;}';
|
|
379
|
+
nodesWithStyles.forEach( ( { selector, duotoneSelector, styles } ) => {
|
|
380
|
+
const duotoneStyles = {};
|
|
381
|
+
if ( styles?.filter ) {
|
|
382
|
+
duotoneStyles.filter = styles.filter;
|
|
383
|
+
delete styles.filter;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Process duotone styles (they use color.__experimentalDuotone selector).
|
|
387
|
+
if ( duotoneSelector ) {
|
|
388
|
+
const duotoneDeclarations = getStylesDeclarations( duotoneStyles );
|
|
389
|
+
if ( duotoneDeclarations.length === 0 ) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
ruleset =
|
|
393
|
+
ruleset +
|
|
394
|
+
`${ duotoneSelector }{${ duotoneDeclarations.join( ';' ) };}`;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Process the remaning block styles (they use either normal block class or __experimentalSelector).
|
|
339
398
|
const declarations = getStylesDeclarations( styles );
|
|
340
399
|
if ( declarations.length === 0 ) {
|
|
341
400
|
return;
|
|
@@ -358,6 +417,13 @@ export const toStyles = ( tree, blockSelectors ) => {
|
|
|
358
417
|
return ruleset;
|
|
359
418
|
};
|
|
360
419
|
|
|
420
|
+
export function toSvgFilters( tree, blockSelectors ) {
|
|
421
|
+
const nodesWithSettings = getNodesWithSettings( tree, blockSelectors );
|
|
422
|
+
return nodesWithSettings.flatMap( ( { presets } ) => {
|
|
423
|
+
return getPresetsSvgFilters( presets );
|
|
424
|
+
} );
|
|
425
|
+
}
|
|
426
|
+
|
|
361
427
|
const getBlockSelectors = ( blockTypes ) => {
|
|
362
428
|
const result = {};
|
|
363
429
|
blockTypes.forEach( ( blockType ) => {
|
|
@@ -365,9 +431,12 @@ const getBlockSelectors = ( blockTypes ) => {
|
|
|
365
431
|
const selector =
|
|
366
432
|
blockType?.supports?.__experimentalSelector ??
|
|
367
433
|
'.wp-block-' + name.replace( 'core/', '' ).replace( '/', '-' );
|
|
434
|
+
const duotoneSelector =
|
|
435
|
+
blockType?.supports?.color?.__experimentalDuotone ?? null;
|
|
368
436
|
result[ name ] = {
|
|
369
437
|
name,
|
|
370
438
|
selector,
|
|
439
|
+
duotoneSelector,
|
|
371
440
|
};
|
|
372
441
|
} );
|
|
373
442
|
|
|
@@ -377,6 +446,7 @@ const getBlockSelectors = ( blockTypes ) => {
|
|
|
377
446
|
export function useGlobalStylesOutput() {
|
|
378
447
|
const [ stylesheets, setStylesheets ] = useState( [] );
|
|
379
448
|
const [ settings, setSettings ] = useState( {} );
|
|
449
|
+
const [ svgFilters, setSvgFilters ] = useState( {} );
|
|
380
450
|
const { merged: mergedConfig } = useContext( GlobalStylesContext );
|
|
381
451
|
|
|
382
452
|
useEffect( () => {
|
|
@@ -390,6 +460,7 @@ export function useGlobalStylesOutput() {
|
|
|
390
460
|
blockSelectors
|
|
391
461
|
);
|
|
392
462
|
const globalStyles = toStyles( mergedConfig, blockSelectors );
|
|
463
|
+
const filters = toSvgFilters( mergedConfig, blockSelectors );
|
|
393
464
|
setStylesheets( [
|
|
394
465
|
{
|
|
395
466
|
css: customProperties,
|
|
@@ -401,7 +472,8 @@ export function useGlobalStylesOutput() {
|
|
|
401
472
|
},
|
|
402
473
|
] );
|
|
403
474
|
setSettings( mergedConfig.settings );
|
|
475
|
+
setSvgFilters( filters );
|
|
404
476
|
}, [ mergedConfig ] );
|
|
405
477
|
|
|
406
|
-
return [ stylesheets, settings ];
|
|
478
|
+
return [ stylesheets, settings, svgFilters ];
|
|
407
479
|
}
|
|
@@ -49,6 +49,12 @@ export const PRESET_METADATA = [
|
|
|
49
49
|
},
|
|
50
50
|
],
|
|
51
51
|
},
|
|
52
|
+
{
|
|
53
|
+
path: [ 'color', 'duotone' ],
|
|
54
|
+
cssVarInfix: 'duotone',
|
|
55
|
+
valueFunc: ( { slug } ) => `url( '#wp-duotone-${ slug }' )`,
|
|
56
|
+
classes: [],
|
|
57
|
+
},
|
|
52
58
|
{
|
|
53
59
|
path: [ 'typography', 'fontSizes' ],
|
|
54
60
|
valueKey: 'size',
|