@wordpress/block-editor 10.0.4 → 10.0.6

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 (50) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +40 -0
  3. package/build/components/block-inspector/index.js +3 -4
  4. package/build/components/block-inspector/index.js.map +1 -1
  5. package/build/components/block-list/block.js +72 -14
  6. package/build/components/block-list/block.js.map +1 -1
  7. package/build/components/font-sizes/fluid-utils.js +208 -0
  8. package/build/components/font-sizes/fluid-utils.js.map +1 -0
  9. package/build/components/font-sizes/index.js +8 -0
  10. package/build/components/font-sizes/index.js.map +1 -1
  11. package/build/components/inserter/search-items.js +2 -17
  12. package/build/components/inserter/search-items.js.map +1 -1
  13. package/build/hooks/font-size.js +60 -0
  14. package/build/hooks/font-size.js.map +1 -1
  15. package/build/hooks/margin.js +4 -4
  16. package/build/hooks/margin.js.map +1 -1
  17. package/build/hooks/use-typography-props.js +17 -3
  18. package/build/hooks/use-typography-props.js.map +1 -1
  19. package/build-module/components/block-inspector/index.js +3 -4
  20. package/build-module/components/block-inspector/index.js.map +1 -1
  21. package/build-module/components/block-list/block.js +72 -14
  22. package/build-module/components/block-list/block.js.map +1 -1
  23. package/build-module/components/font-sizes/fluid-utils.js +197 -0
  24. package/build-module/components/font-sizes/fluid-utils.js.map +1 -0
  25. package/build-module/components/font-sizes/index.js +1 -0
  26. package/build-module/components/font-sizes/index.js.map +1 -1
  27. package/build-module/components/inserter/search-items.js +3 -17
  28. package/build-module/components/inserter/search-items.js.map +1 -1
  29. package/build-module/hooks/font-size.js +59 -1
  30. package/build-module/hooks/font-size.js.map +1 -1
  31. package/build-module/hooks/margin.js +4 -4
  32. package/build-module/hooks/margin.js.map +1 -1
  33. package/build-module/hooks/use-typography-props.js +17 -4
  34. package/build-module/hooks/use-typography-props.js.map +1 -1
  35. package/build-style/style-rtl.css +61 -106
  36. package/build-style/style.css +61 -106
  37. package/package.json +3 -4
  38. package/src/components/block-inspector/index.js +4 -7
  39. package/src/components/block-list/block.js +111 -7
  40. package/src/components/block-list/style.scss +85 -133
  41. package/src/components/button-block-appender/style.scss +3 -1
  42. package/src/components/font-sizes/fluid-utils.js +221 -0
  43. package/src/components/font-sizes/index.js +1 -0
  44. package/src/components/font-sizes/test/fluid-utils.js +168 -0
  45. package/src/components/inserter/search-items.js +3 -15
  46. package/src/components/inserter/test/search-items.js +4 -0
  47. package/src/hooks/font-size.js +75 -0
  48. package/src/hooks/margin.js +4 -4
  49. package/src/hooks/test/use-typography-props.js +22 -0
  50. package/src/hooks/use-typography-props.js +18 -3
@@ -296,7 +296,7 @@ const applyWithSelect = withSelect( ( select, { clientId, rootClientId } ) => {
296
296
  };
297
297
  } );
298
298
 
299
- const applyWithDispatch = withDispatch( ( dispatch, ownProps, { select } ) => {
299
+ const applyWithDispatch = withDispatch( ( dispatch, ownProps, registry ) => {
300
300
  const {
301
301
  updateBlockAttributes,
302
302
  insertBlocks,
@@ -304,6 +304,9 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, { select } ) => {
304
304
  replaceBlocks,
305
305
  toggleSelection,
306
306
  __unstableMarkLastChangeAsPersistent,
307
+ moveBlocksToPosition,
308
+ removeBlock,
309
+ selectBlock,
307
310
  } = dispatch( blockEditorStore );
308
311
 
309
312
  // Do not add new properties here, use `useDispatch` instead to avoid
@@ -311,7 +314,7 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, { select } ) => {
311
314
  return {
312
315
  setAttributes( newAttributes ) {
313
316
  const { getMultiSelectedBlockClientIds } =
314
- select( blockEditorStore );
317
+ registry.select( blockEditorStore );
315
318
  const multiSelectedBlockClientIds =
316
319
  getMultiSelectedBlockClientIds();
317
320
  const { clientId } = ownProps;
@@ -327,26 +330,124 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, { select } ) => {
327
330
  },
328
331
  onInsertBlocksAfter( blocks ) {
329
332
  const { clientId, rootClientId } = ownProps;
330
- const { getBlockIndex } = select( blockEditorStore );
333
+ const { getBlockIndex } = registry.select( blockEditorStore );
331
334
  const index = getBlockIndex( clientId );
332
335
  insertBlocks( blocks, index + 1, rootClientId );
333
336
  },
334
337
  onMerge( forward ) {
335
338
  const { clientId, rootClientId } = ownProps;
336
- const { getPreviousBlockClientId, getNextBlockClientId, getBlock } =
337
- select( blockEditorStore );
339
+ const {
340
+ getPreviousBlockClientId,
341
+ getNextBlockClientId,
342
+ getBlock,
343
+ getBlockAttributes,
344
+ getBlockName,
345
+ getBlockOrder,
346
+ } = registry.select( blockEditorStore );
338
347
 
348
+ // For `Delete` or forward merge, we should do the exact same thing
349
+ // as `Backspace`, but from the other block.
339
350
  if ( forward ) {
351
+ if ( rootClientId ) {
352
+ const nextRootClientId =
353
+ getNextBlockClientId( rootClientId );
354
+
355
+ if ( nextRootClientId ) {
356
+ // If there is a block that follows with the same parent
357
+ // block name and the same attributes, merge the inner
358
+ // blocks.
359
+ if (
360
+ getBlockName( rootClientId ) ===
361
+ getBlockName( nextRootClientId )
362
+ ) {
363
+ const rootAttributes =
364
+ getBlockAttributes( rootClientId );
365
+ const previousRootAttributes =
366
+ getBlockAttributes( nextRootClientId );
367
+
368
+ if (
369
+ Object.keys( rootAttributes ).every(
370
+ ( key ) =>
371
+ rootAttributes[ key ] ===
372
+ previousRootAttributes[ key ]
373
+ )
374
+ ) {
375
+ registry.batch( () => {
376
+ moveBlocksToPosition(
377
+ getBlockOrder( nextRootClientId ),
378
+ nextRootClientId,
379
+ rootClientId
380
+ );
381
+ removeBlock( nextRootClientId, false );
382
+ } );
383
+ return;
384
+ }
385
+ } else {
386
+ mergeBlocks( rootClientId, nextRootClientId );
387
+ return;
388
+ }
389
+ }
390
+ }
391
+
340
392
  const nextBlockClientId = getNextBlockClientId( clientId );
341
- if ( nextBlockClientId ) {
393
+
394
+ if ( ! nextBlockClientId ) {
395
+ return;
396
+ }
397
+
398
+ // Check if it's possibile to "unwrap" the following block
399
+ // before trying to merge.
400
+ const replacement = switchToBlockType(
401
+ getBlock( nextBlockClientId ),
402
+ '*'
403
+ );
404
+
405
+ if ( replacement && replacement.length ) {
406
+ replaceBlocks( nextBlockClientId, replacement );
407
+ } else {
342
408
  mergeBlocks( clientId, nextBlockClientId );
343
409
  }
344
410
  } else {
345
411
  const previousBlockClientId =
346
412
  getPreviousBlockClientId( clientId );
413
+
347
414
  if ( previousBlockClientId ) {
348
415
  mergeBlocks( previousBlockClientId, clientId );
349
416
  } else if ( rootClientId ) {
417
+ const previousRootClientId =
418
+ getPreviousBlockClientId( rootClientId );
419
+
420
+ // If there is a preceding block with the same parent block
421
+ // name and the same attributes, merge the inner blocks.
422
+ if (
423
+ previousRootClientId &&
424
+ getBlockName( rootClientId ) ===
425
+ getBlockName( previousRootClientId )
426
+ ) {
427
+ const rootAttributes =
428
+ getBlockAttributes( rootClientId );
429
+ const previousRootAttributes =
430
+ getBlockAttributes( previousRootClientId );
431
+
432
+ if (
433
+ Object.keys( rootAttributes ).every(
434
+ ( key ) =>
435
+ rootAttributes[ key ] ===
436
+ previousRootAttributes[ key ]
437
+ )
438
+ ) {
439
+ registry.batch( () => {
440
+ moveBlocksToPosition(
441
+ getBlockOrder( rootClientId ),
442
+ rootClientId,
443
+ previousRootClientId
444
+ );
445
+ removeBlock( rootClientId, false );
446
+ } );
447
+ return;
448
+ }
449
+ }
450
+
350
451
  // Attempt to "unwrap" the block contents when there's no
351
452
  // preceding block to merge with.
352
453
  const replacement = switchToBlockType(
@@ -354,7 +455,10 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, { select } ) => {
354
455
  '*'
355
456
  );
356
457
  if ( replacement && replacement.length ) {
357
- replaceBlocks( rootClientId, replacement, 0 );
458
+ registry.batch( () => {
459
+ replaceBlocks( rootClientId, replacement );
460
+ selectBlock( replacement[ 0 ].clientId, 0 );
461
+ } );
358
462
  }
359
463
  }
360
464
  }
@@ -8,8 +8,19 @@
8
8
  * Cross-Block Selection
9
9
  */
10
10
 
11
+ @keyframes selection-overlay__fade-in-animation {
12
+ from {
13
+ opacity: 0;
14
+ }
15
+ to {
16
+ opacity: 0.4;
17
+ }
18
+ }
19
+
11
20
  // Note to developers refactoring this, please test navigation mode, and
12
21
  // multi selection and hovering the block switcher to highlight the block.
22
+ // Also be sure to test partial selections in Safari, as it draws the
23
+ // selection marker with an entirely different model than Blink.
13
24
  .block-editor-block-list__layout {
14
25
  position: relative;
15
26
 
@@ -19,63 +30,88 @@
19
30
  background: transparent;
20
31
  }
21
32
 
22
- // The primary indicator of selection in text is the native selection marker.
23
- // When selecting multiple blocks, we provide an additional selection indicator.
24
- .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected),
25
- .block-editor-block-list__block.is-highlighted,
26
- .block-editor-block-list__block.is-highlighted ~ .is-multi-selected {
33
+ .has-multi-selection &::selection {
34
+ background: transparent;
35
+ }
36
+
37
+ // Block multi selection
38
+ .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected) {
39
+ // Hide the native selection indicator, for the selection, and children.
40
+ &::selection,
41
+ & ::selection {
42
+ background: transparent;
43
+ }
44
+
45
+ // Draw a spot color overlay.
27
46
  &::after {
28
- // Show selection borders around every non-nested block's actual footprint.
47
+ content: "";
29
48
  position: absolute;
30
49
  z-index: 1;
31
50
  pointer-events: none;
32
- content: "";
33
51
  top: $border-width;
52
+ right: $border-width;
34
53
  bottom: $border-width;
35
54
  left: $border-width;
36
- right: $border-width;
55
+ background: var(--wp-admin-theme-color);
56
+ opacity: 0.4;
37
57
 
38
- // Everything else.
39
- box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
40
- border-radius: $radius-block-ui - $border-width; // Border is outset, so subtract the width to achieve correct radius.
58
+ // Animate.
59
+ animation: selection-overlay__fade-in-animation 0.1s ease-out;
60
+ animation-fill-mode: forwards;
61
+ @include reduce-motion("animation");
41
62
 
42
- // Windows High Contrast mode will show this outline.
63
+ // Show outline in high contrast mode.
43
64
  outline: 2px solid transparent;
44
-
45
- // Show a lighter color for dark themes.
46
- .is-dark-theme & {
47
- box-shadow: 0 0 0 $border-width $dark-theme-focus;
48
- }
49
- }
50
-
51
- // Provide exceptions for placeholders.
52
- .components-placeholder,
53
- .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected) {
54
- ::selection {
55
- background: transparent;
56
- }
57
65
  }
58
66
  }
59
67
 
60
- // Hide the selection indicator on .block-editor-block-list__layout, else Safari will show it stacked.
61
- .has-multi-selection &::selection {
62
- background: transparent;
63
- }
68
+ // Block highlight, and navigation mode, not focus.
69
+ // By not using a pseudo element, we can limit ourselves to only
70
+ // using ::after, leaving ::before free. Otherwise, highlight + multi-select
71
+ // would require the opacity-changing overlay to be on ::before.
72
+ .block-editor-block-list__block.is-highlighted,
73
+ .block-editor-block-list__block.is-highlighted ~ .is-multi-selected,
74
+ &.is-navigate-mode .block-editor-block-list__block.is-selected,
75
+ & .is-block-moving-mode.block-editor-block-list__block.has-child-selected {
76
+ border-radius: $radius-block-ui;
77
+ box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
64
78
 
65
- .block-editor-block-list__block.is-highlighted::after {
66
- box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
67
- outline: $border-width solid transparent;
79
+ // Show outline in high contrast mode.
80
+ outline: 2px solid transparent;
68
81
  }
69
82
 
70
- &.is-navigate-mode .block-editor-block-list__block.is-selected::after,
71
- & .is-block-moving-mode.block-editor-block-list__block.has-child-selected {
72
- box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
73
- outline: 2px solid transparent;
83
+ // Block focus.
84
+ .block-editor-block-list__block:not([contenteditable]):focus {
85
+ outline: none;
86
+
87
+ // We're using a pseudo element to overflow placeholder borders
88
+ // and any border inside the block itself.
89
+ &::after {
90
+ content: "";
91
+ position: absolute;
92
+ z-index: 1;
93
+ pointer-events: none;
94
+ top: $border-width;
95
+ right: $border-width;
96
+ bottom: $border-width;
97
+ left: $border-width;
98
+ box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
99
+ border-radius: $radius-block-ui - $border-width; // Border is outset, so subtract the width to achieve correct radius.
100
+ outline: 2px solid transparent; // This shows up in Windows High Contrast Mode.
101
+
102
+ // Show a light color for dark themes.
103
+ .is-dark-theme & {
104
+ box-shadow: 0 0 0 var(--wp-admin-border-width-focus) $dark-theme-focus;
105
+ }
106
+ }
74
107
  }
75
108
 
109
+ // Moving blocks using keyboard (Ellipsis > Move).
76
110
  & .is-block-moving-mode.block-editor-block-list__block.is-selected {
111
+ box-shadow: none;
112
+ outline: none;
77
113
 
78
- &::before {
114
+ &::after {
79
115
  content: "";
80
116
  position: absolute;
81
117
  z-index: 0;
@@ -90,14 +126,10 @@
90
126
  border-radius: $radius-block-ui;
91
127
  border-top: 4px solid $gray-400;
92
128
  }
93
-
94
- &::after {
95
- content: none;
96
- }
97
129
  }
98
130
 
99
131
  & .is-block-moving-mode.can-insert-moving-block.block-editor-block-list__block.is-selected {
100
- &::before {
132
+ &::after {
101
133
  border-color: var(--wp-admin-theme-color);
102
134
  }
103
135
  }
@@ -134,29 +166,16 @@
134
166
  }
135
167
 
136
168
  .block-editor-block-list__layout .block-editor-block-list__block {
169
+ // With `position: static`, Safari marks a full-width selection rectangle, including margins.
170
+ // With `position: relative`, Safari marks an inline selection rectangle, similar to that of
171
+ // Blink based browsers, but it also does "crop" the marker, which can result in a small line
172
+ // from the preceeding paragraph showing, which is effectively the above selection bleeding in.
173
+ // We choose relative, as that matches the multi-selection, which is limited to the block footprint.
137
174
  position: relative;
138
175
 
139
176
  // Re-enable text-selection on editable blocks.
140
177
  user-select: text;
141
178
 
142
- // Hide the select style pseudo element as otherwise it gets shwon as "selected" in Safari.
143
- &.is-partially-selected::after {
144
- // By positioning this pseudo element outside the boundaries of the parent block,
145
- // when partially selected it hides the pseudo element selection in Safari.
146
- top: -0.5px;
147
- right: -0.5px;
148
- bottom: -0.5px;
149
- left: -0.5px;
150
- }
151
-
152
- &.is-highlighted::after,
153
- &.is-highlighted ~ .is-multi-selected::after {
154
- top: 0;
155
- right: 0;
156
- bottom: 0;
157
- left: 0;
158
- }
159
-
160
179
  // Break long strings of text without spaces so they don't overflow the block.
161
180
  overflow-wrap: break-word;
162
181
 
@@ -167,7 +186,6 @@
167
186
  /**
168
187
  * Notices
169
188
  */
170
-
171
189
  .components-placeholder .components-with-notices-ui {
172
190
  margin: -10px 0 12px 0;
173
191
  }
@@ -186,56 +204,6 @@
186
204
  }
187
205
  }
188
206
 
189
-
190
- /**
191
- * Block Layout
192
- */
193
-
194
- // Navigate mode & Focused wrapper.
195
- // We're using a pseudo element to overflow placeholder borders
196
- // and any border inside the block itself.
197
- &:not([contenteditable]):focus {
198
- outline: none;
199
-
200
- &::after {
201
- position: absolute;
202
- z-index: 1;
203
- pointer-events: none;
204
- content: "";
205
- top: $border-width;
206
- bottom: $border-width;
207
- left: $border-width;
208
- right: $border-width;
209
-
210
- // 2px outside.
211
- box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
212
- border-radius: $radius-block-ui - $border-width; // Border is outset, so subtract the width to achieve correct radius.
213
- outline: 2px solid transparent; // This shows up in Windows High Contrast Mode.
214
-
215
- // Show a light color for dark themes.
216
- .is-dark-theme & {
217
- box-shadow: 0 0 0 var(--wp-admin-border-width-focus) $dark-theme-focus;
218
- }
219
- }
220
- }
221
-
222
- /**
223
- * Block styles and alignments
224
- */
225
- &::after {
226
- content: "";
227
- pointer-events: none;
228
- position: absolute;
229
- top: 0;
230
- right: 0;
231
- bottom: 0;
232
- left: 0;
233
- border-radius: $radius-block-ui;
234
- box-shadow: 0 0 0 0 transparent;
235
- transition: box-shadow 0.1s linear;
236
- @include reduce-motion("transition");
237
- }
238
-
239
207
  // Warnings
240
208
  &.has-warning {
241
209
  min-height: $grid-unit-60;
@@ -282,7 +250,7 @@
282
250
  }
283
251
  }
284
252
 
285
- // Reusable blocks parent borer.
253
+ // Reusable blocks parent border.
286
254
  &.is-reusable.has-child-selected::after {
287
255
  box-shadow: 0 0 0 1px var(--wp-admin-theme-color);
288
256
  }
@@ -296,16 +264,8 @@
296
264
  .is-outline-mode .block-editor-block-list__block:not(.remove-outline) {
297
265
  &.is-hovered {
298
266
  cursor: default;
299
-
300
- &::after {
301
- top: $border-width;
302
- left: $border-width;
303
- right: $border-width;
304
- bottom: $border-width;
305
- box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color);
306
- // Border is outset, so subtract the width to achieve correct radius.
307
- border-radius: $radius-block-ui - $border-width;
308
- }
267
+ box-shadow: inset 0 0 0 $border-width var(--wp-admin-theme-color);
268
+ border-radius: $radius-block-ui;
309
269
  }
310
270
 
311
271
  &.is-selected {
@@ -315,19 +275,11 @@
315
275
  cursor: unset;
316
276
  }
317
277
 
318
- &::after {
319
- box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); // Selected not focussed.
320
- top: $border-width;
321
- left: $border-width;
322
- right: $border-width;
323
- bottom: $border-width;
324
- border-radius: $radius-block-ui - $border-width; // Border is outset, so subtract the width to achieve correct radius.
325
- }
278
+ box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); // Selected not focussed.
279
+ border-radius: $radius-block-ui;
326
280
 
327
281
  &:focus {
328
- &::after {
329
- box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
330
- }
282
+ box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
331
283
  }
332
284
  }
333
285
  }
@@ -35,7 +35,9 @@
35
35
  // When the appender shows up in empty container blocks, such as Group and Columns, add an extra click state.
36
36
  .block-list-appender:only-child {
37
37
  .is-layout-constrained.block-editor-block-list__block:not(.is-selected) > &,
38
- .is-layout-flow.block-editor-block-list__block:not(.is-selected) > & {
38
+ .is-layout-flow.block-editor-block-list__block:not(.is-selected) > &,
39
+ .is-layout-constrained.block-editor-block-list__block:not(.is-selected) > .block-editor-block-list__layout > &,
40
+ .is-layout-flow.block-editor-block-list__block:not(.is-selected) > .block-editor-block-list__layout > & {
39
41
  pointer-events: none;
40
42
 
41
43
  &::after {