@wordpress/edit-site 4.3.0 → 4.4.0

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.
Files changed (47) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-editor/resizable-editor.js +2 -1
  3. package/build/components/block-editor/resizable-editor.js.map +1 -1
  4. package/build/components/editor/global-styles-renderer.js +2 -1
  5. package/build/components/editor/global-styles-renderer.js.map +1 -1
  6. package/build/components/editor/index.js +9 -5
  7. package/build/components/editor/index.js.map +1 -1
  8. package/build/components/global-styles/border-panel.js +100 -79
  9. package/build/components/global-styles/border-panel.js.map +1 -1
  10. package/build/components/global-styles/screen-block-list.js +48 -4
  11. package/build/components/global-styles/screen-block-list.js.map +1 -1
  12. package/build/components/global-styles/use-global-styles-output.js +91 -15
  13. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  14. package/build/components/global-styles/utils.js +12 -2
  15. package/build/components/global-styles/utils.js.map +1 -1
  16. package/build/components/sidebar/navigation-menu-sidebar/index.js +4 -2
  17. package/build/components/sidebar/navigation-menu-sidebar/index.js.map +1 -1
  18. package/build-module/components/block-editor/resizable-editor.js +2 -1
  19. package/build-module/components/block-editor/resizable-editor.js.map +1 -1
  20. package/build-module/components/editor/global-styles-renderer.js +2 -1
  21. package/build-module/components/editor/global-styles-renderer.js.map +1 -1
  22. package/build-module/components/editor/index.js +10 -6
  23. package/build-module/components/editor/index.js.map +1 -1
  24. package/build-module/components/global-styles/border-panel.js +103 -80
  25. package/build-module/components/global-styles/border-panel.js.map +1 -1
  26. package/build-module/components/global-styles/screen-block-list.js +47 -4
  27. package/build-module/components/global-styles/screen-block-list.js.map +1 -1
  28. package/build-module/components/global-styles/use-global-styles-output.js +87 -13
  29. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  30. package/build-module/components/global-styles/utils.js +12 -2
  31. package/build-module/components/global-styles/utils.js.map +1 -1
  32. package/build-module/components/sidebar/navigation-menu-sidebar/index.js +4 -2
  33. package/build-module/components/sidebar/navigation-menu-sidebar/index.js.map +1 -1
  34. package/build-style/style-rtl.css +41 -1
  35. package/build-style/style.css +41 -1
  36. package/package.json +29 -29
  37. package/src/components/block-editor/resizable-editor.js +6 -2
  38. package/src/components/editor/global-styles-renderer.js +2 -1
  39. package/src/components/editor/index.js +16 -5
  40. package/src/components/global-styles/border-panel.js +112 -109
  41. package/src/components/global-styles/screen-block-list.js +63 -8
  42. package/src/components/global-styles/style.scss +2 -1
  43. package/src/components/global-styles/test/use-global-styles-output.js +4 -1
  44. package/src/components/global-styles/use-global-styles-output.js +112 -17
  45. package/src/components/global-styles/utils.js +6 -0
  46. package/src/components/sidebar/navigation-menu-sidebar/index.js +4 -1
  47. package/src/components/sidebar/style.scss +50 -0
@@ -24,16 +24,14 @@ import {
24
24
  } from '@wordpress/blocks';
25
25
  import { useEffect, useState, useContext } from '@wordpress/element';
26
26
  import { getCSSRules } from '@wordpress/style-engine';
27
-
28
- /**
29
- * Internal dependencies
30
- */
27
+ import { __unstablePresetDuotoneFilter as PresetDuotoneFilter } from '@wordpress/block-editor';
31
28
 
32
29
  /**
33
30
  * Internal dependencies
34
31
  */
35
32
  import { PRESET_METADATA, ROOT_BLOCK_SELECTOR } from './utils';
36
33
  import { GlobalStylesContext } from './context';
34
+ import { useSetting } from './hooks';
37
35
 
38
36
  function compileStyleValue( uncompiledValue ) {
39
37
  const VARIABLE_REFERENCE_PREFIX = 'var:';
@@ -59,16 +57,27 @@ function compileStyleValue( uncompiledValue ) {
59
57
  function getPresetsDeclarations( blockPresets = {} ) {
60
58
  return reduce(
61
59
  PRESET_METADATA,
62
- ( declarations, { path, valueKey, cssVarInfix } ) => {
60
+ ( declarations, { path, valueKey, valueFunc, cssVarInfix } ) => {
63
61
  const presetByOrigin = get( blockPresets, path, [] );
64
62
  [ 'default', 'theme', 'custom' ].forEach( ( origin ) => {
65
63
  if ( presetByOrigin[ origin ] ) {
66
64
  presetByOrigin[ origin ].forEach( ( value ) => {
67
- declarations.push(
68
- `--wp--preset--${ cssVarInfix }--${ kebabCase(
69
- value.slug
70
- ) }: ${ value[ valueKey ] }`
71
- );
65
+ if ( valueKey ) {
66
+ declarations.push(
67
+ `--wp--preset--${ cssVarInfix }--${ kebabCase(
68
+ value.slug
69
+ ) }: ${ value[ valueKey ] }`
70
+ );
71
+ } else if (
72
+ valueFunc &&
73
+ typeof valueFunc === 'function'
74
+ ) {
75
+ declarations.push(
76
+ `--wp--preset--${ cssVarInfix }--${ kebabCase(
77
+ value.slug
78
+ ) }: ${ valueFunc( value ) }`
79
+ );
80
+ }
72
81
  } );
73
82
  }
74
83
  } );
@@ -123,6 +132,25 @@ function getPresetsClasses( blockSelector, blockPresets = {} ) {
123
132
  );
124
133
  }
125
134
 
135
+ function getPresetsSvgFilters( blockPresets = {} ) {
136
+ return PRESET_METADATA.filter(
137
+ // Duotone are the only type of filters for now.
138
+ ( metadata ) => metadata.path.at( -1 ) === 'duotone'
139
+ ).flatMap( ( metadata ) => {
140
+ const presetByOrigin = get( blockPresets, metadata.path, {} );
141
+ return [ 'default', 'theme' ]
142
+ .filter( ( origin ) => presetByOrigin[ origin ] )
143
+ .flatMap( ( origin ) =>
144
+ presetByOrigin[ origin ].map( ( preset ) => (
145
+ <PresetDuotoneFilter
146
+ preset={ preset }
147
+ key={ preset.slug }
148
+ />
149
+ ) )
150
+ );
151
+ } );
152
+ }
153
+
126
154
  function flattenTree( input = {}, prefix, token ) {
127
155
  let result = [];
128
156
  Object.keys( input ).forEach( ( key ) => {
@@ -215,7 +243,9 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => {
215
243
 
216
244
  const pickStyleKeys = ( treeToPickFrom ) =>
217
245
  pickBy( treeToPickFrom, ( value, key ) =>
218
- [ 'border', 'color', 'spacing', 'typography' ].includes( key )
246
+ [ 'border', 'color', 'spacing', 'typography', 'filter' ].includes(
247
+ key
248
+ )
219
249
  );
220
250
 
221
251
  // Top-level.
@@ -242,6 +272,7 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => {
242
272
  nodes.push( {
243
273
  styles: blockStyles,
244
274
  selector: blockSelectors[ blockName ].selector,
275
+ duotoneSelector: blockSelectors[ blockName ].duotoneSelector,
245
276
  } );
246
277
  }
247
278
 
@@ -329,13 +360,38 @@ export const toCustomProperties = ( tree, blockSelectors ) => {
329
360
  return ruleset;
330
361
  };
331
362
 
332
- export const toStyles = ( tree, blockSelectors ) => {
363
+ export const toStyles = ( tree, blockSelectors, hasBlockGapSupport ) => {
333
364
  const nodesWithStyles = getNodesWithStyles( tree, blockSelectors );
334
365
  const nodesWithSettings = getNodesWithSettings( tree, blockSelectors );
335
366
 
336
- let ruleset =
337
- '.wp-site-blocks > * { margin-top: 0; margin-bottom: 0; }.wp-site-blocks > * + * { margin-top: var( --wp--style--block-gap ); }';
338
- nodesWithStyles.forEach( ( { selector, styles } ) => {
367
+ /*
368
+ * Reset default browser margin on the root body element.
369
+ * This is set on the root selector **before** generating the ruleset
370
+ * from the `theme.json`. This is to ensure that if the `theme.json` declares
371
+ * `margin` in its `spacing` declaration for the `body` element then these
372
+ * user-generated values take precedence in the CSS cascade.
373
+ * @link https://github.com/WordPress/gutenberg/issues/36147.
374
+ */
375
+ let ruleset = 'body {margin: 0;}';
376
+ nodesWithStyles.forEach( ( { selector, duotoneSelector, styles } ) => {
377
+ const duotoneStyles = {};
378
+ if ( styles?.filter ) {
379
+ duotoneStyles.filter = styles.filter;
380
+ delete styles.filter;
381
+ }
382
+
383
+ // Process duotone styles (they use color.__experimentalDuotone selector).
384
+ if ( duotoneSelector ) {
385
+ const duotoneDeclarations = getStylesDeclarations( duotoneStyles );
386
+ if ( duotoneDeclarations.length === 0 ) {
387
+ return;
388
+ }
389
+ ruleset =
390
+ ruleset +
391
+ `${ duotoneSelector }{${ duotoneDeclarations.join( ';' ) };}`;
392
+ }
393
+
394
+ // Process the remaning block styles (they use either normal block class or __experimentalSelector).
339
395
  const declarations = getStylesDeclarations( styles );
340
396
  if ( declarations.length === 0 ) {
341
397
  return;
@@ -343,6 +399,26 @@ export const toStyles = ( tree, blockSelectors ) => {
343
399
  ruleset = ruleset + `${ selector }{${ declarations.join( ';' ) };}`;
344
400
  } );
345
401
 
402
+ /* Add alignment / layout styles */
403
+ ruleset =
404
+ ruleset +
405
+ '.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }';
406
+ ruleset =
407
+ ruleset +
408
+ '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }';
409
+ ruleset =
410
+ ruleset +
411
+ '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }';
412
+
413
+ if ( hasBlockGapSupport ) {
414
+ ruleset =
415
+ ruleset +
416
+ '.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }';
417
+ ruleset =
418
+ ruleset +
419
+ '.wp-site-blocks > * + * { margin-block-start: var( --wp--style--block-gap ); }';
420
+ }
421
+
346
422
  nodesWithSettings.forEach( ( { selector, presets } ) => {
347
423
  if ( ROOT_BLOCK_SELECTOR === selector ) {
348
424
  // Do not add extra specificity for top-level classes.
@@ -358,6 +434,13 @@ export const toStyles = ( tree, blockSelectors ) => {
358
434
  return ruleset;
359
435
  };
360
436
 
437
+ export function toSvgFilters( tree, blockSelectors ) {
438
+ const nodesWithSettings = getNodesWithSettings( tree, blockSelectors );
439
+ return nodesWithSettings.flatMap( ( { presets } ) => {
440
+ return getPresetsSvgFilters( presets );
441
+ } );
442
+ }
443
+
361
444
  const getBlockSelectors = ( blockTypes ) => {
362
445
  const result = {};
363
446
  blockTypes.forEach( ( blockType ) => {
@@ -365,9 +448,12 @@ const getBlockSelectors = ( blockTypes ) => {
365
448
  const selector =
366
449
  blockType?.supports?.__experimentalSelector ??
367
450
  '.wp-block-' + name.replace( 'core/', '' ).replace( '/', '-' );
451
+ const duotoneSelector =
452
+ blockType?.supports?.color?.__experimentalDuotone ?? null;
368
453
  result[ name ] = {
369
454
  name,
370
455
  selector,
456
+ duotoneSelector,
371
457
  };
372
458
  } );
373
459
 
@@ -377,7 +463,10 @@ const getBlockSelectors = ( blockTypes ) => {
377
463
  export function useGlobalStylesOutput() {
378
464
  const [ stylesheets, setStylesheets ] = useState( [] );
379
465
  const [ settings, setSettings ] = useState( {} );
466
+ const [ svgFilters, setSvgFilters ] = useState( {} );
380
467
  const { merged: mergedConfig } = useContext( GlobalStylesContext );
468
+ const [ blockGap ] = useSetting( 'spacing.blockGap' );
469
+ const hasBlockGapSupport = blockGap !== null;
381
470
 
382
471
  useEffect( () => {
383
472
  if ( ! mergedConfig?.styles || ! mergedConfig?.settings ) {
@@ -389,7 +478,12 @@ export function useGlobalStylesOutput() {
389
478
  mergedConfig,
390
479
  blockSelectors
391
480
  );
392
- const globalStyles = toStyles( mergedConfig, blockSelectors );
481
+ const globalStyles = toStyles(
482
+ mergedConfig,
483
+ blockSelectors,
484
+ hasBlockGapSupport
485
+ );
486
+ const filters = toSvgFilters( mergedConfig, blockSelectors );
393
487
  setStylesheets( [
394
488
  {
395
489
  css: customProperties,
@@ -401,7 +495,8 @@ export function useGlobalStylesOutput() {
401
495
  },
402
496
  ] );
403
497
  setSettings( mergedConfig.settings );
498
+ setSvgFilters( filters );
404
499
  }, [ mergedConfig ] );
405
500
 
406
- return [ stylesheets, settings ];
501
+ return [ stylesheets, settings, svgFilters, hasBlockGapSupport ];
407
502
  }
@@ -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',
@@ -16,7 +16,7 @@ export default function NavigationMenuSidebar() {
16
16
  <DefaultSidebar
17
17
  className="edit-site-navigation-menu-sidebar"
18
18
  identifier="edit-site/navigation-menu"
19
- title={ __( 'Navigation Menus' ) }
19
+ title={ __( 'Navigation' ) }
20
20
  icon={ navigation }
21
21
  closeLabel={ __( 'Close navigation menu sidebar' ) }
22
22
  panelClassName="edit-site-navigation-menu-sidebar__panel"
@@ -24,6 +24,9 @@ export default function NavigationMenuSidebar() {
24
24
  <Flex>
25
25
  <FlexBlock>
26
26
  <strong>{ __( 'Navigation Menus' ) }</strong>
27
+ <span className="edit-site-navigation-sidebar__beta">
28
+ { __( 'Beta' ) }
29
+ </span>
27
30
  </FlexBlock>
28
31
  </Flex>
29
32
  }
@@ -74,6 +74,7 @@
74
74
  padding: $grid-unit-20;
75
75
  }
76
76
 
77
+ .edit-site-navigation-sidebar__beta,
77
78
  .edit-site-global-styles-sidebar__beta {
78
79
  display: inline-flex;
79
80
  margin-left: $grid-unit-10;
@@ -86,3 +87,52 @@
86
87
  font-size: $helptext-font-size;
87
88
  line-height: 1;
88
89
  }
90
+
91
+
92
+ .edit-site-global-styles-sidebar__border-box-control__popover,
93
+ .edit-site-global-styles-sidebar__border-box-control__popover-top,
94
+ .edit-site-global-styles-sidebar__border-box-control__popover-right,
95
+ .edit-site-global-styles-sidebar__border-box-control__popover-bottom,
96
+ .edit-site-global-styles-sidebar__border-box-control__popover-left {
97
+ .components-popover__content {
98
+ width: 282px;
99
+ }
100
+ }
101
+
102
+ $split-border-control-offset: 55px;
103
+
104
+ @include break-medium() {
105
+ .edit-site-global-styles-sidebar__border-box-control__popover,
106
+ .edit-site-global-styles-sidebar__border-box-control__popover-left {
107
+ .components-popover__content {
108
+ margin-right: #{ $grid-unit-50 + $grid-unit-15 } !important;
109
+ }
110
+ }
111
+
112
+ .edit-site-global-styles-sidebar__border-box-control__popover-top,
113
+ .edit-site-global-styles-sidebar__border-box-control__popover-bottom {
114
+ .components-popover__content {
115
+ margin-right: #{ $grid-unit-50 + $grid-unit-15 + $split-border-control-offset } !important;
116
+ }
117
+ }
118
+
119
+ .edit-site-global-styles-sidebar__border-box-control__popover-right {
120
+ .components-popover__content {
121
+ margin-right: #{ $grid-unit-50 + $grid-unit-15 + ( $split-border-control-offset * 2 )} !important;
122
+ }
123
+ }
124
+
125
+ .edit-site-global-styles-sidebar__border-box-control__popover,
126
+ .edit-site-global-styles-sidebar__border-box-control__popover-top,
127
+ .edit-site-global-styles-sidebar__border-box-control__popover-right,
128
+ .edit-site-global-styles-sidebar__border-box-control__popover-bottom,
129
+ .edit-site-global-styles-sidebar__border-box-control__popover-left {
130
+ &.is-from-top .components-popover__content {
131
+ margin-top: #{ -($grid-unit-50 + $grid-unit-15) } !important;
132
+ }
133
+
134
+ &.is-from-bottom .components-popover__content {
135
+ margin-bottom: #{ -($grid-unit-50 + $grid-unit-15) } !important;
136
+ }
137
+ }
138
+ }