@wordpress/block-editor 12.3.1 → 12.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.
Files changed (102) hide show
  1. package/README.md +1 -0
  2. package/build/components/block-lock/toolbar.js +25 -6
  3. package/build/components/block-lock/toolbar.js.map +1 -1
  4. package/build/components/block-toolbar/index.js +8 -5
  5. package/build/components/block-toolbar/index.js.map +1 -1
  6. package/build/components/dimensions-tool/aspect-ratio-tool.js +99 -0
  7. package/build/components/dimensions-tool/aspect-ratio-tool.js.map +1 -0
  8. package/build/components/dimensions-tool/index.js +207 -0
  9. package/build/components/dimensions-tool/index.js.map +1 -0
  10. package/build/components/dimensions-tool/scale-tool.js +111 -0
  11. package/build/components/dimensions-tool/scale-tool.js.map +1 -0
  12. package/build/components/dimensions-tool/width-height-tool.js +125 -0
  13. package/build/components/dimensions-tool/width-height-tool.js.map +1 -0
  14. package/build/components/image-editor/aspect-ratio-dropdown.js +1 -1
  15. package/build/components/image-editor/aspect-ratio-dropdown.js.map +1 -1
  16. package/build/components/image-editor/use-save-image.js +1 -2
  17. package/build/components/image-editor/use-save-image.js.map +1 -1
  18. package/build/components/image-size-control/index.js +6 -0
  19. package/build/components/image-size-control/index.js.map +1 -1
  20. package/build/components/link-control/index.js +17 -15
  21. package/build/components/link-control/index.js.map +1 -1
  22. package/build/components/link-control/search-input.js +4 -4
  23. package/build/components/link-control/search-input.js.map +1 -1
  24. package/build/components/link-control/settings-drawer.js +2 -3
  25. package/build/components/link-control/settings-drawer.js.map +1 -1
  26. package/build/components/provider/use-block-sync.js +21 -0
  27. package/build/components/provider/use-block-sync.js.map +1 -1
  28. package/build/components/resolution-tool/index.js +55 -0
  29. package/build/components/resolution-tool/index.js.map +1 -0
  30. package/build/components/url-input/index.js +4 -2
  31. package/build/components/url-input/index.js.map +1 -1
  32. package/build/private-apis.js +7 -1
  33. package/build/private-apis.js.map +1 -1
  34. package/build/store/defaults.js +1 -0
  35. package/build/store/defaults.js.map +1 -1
  36. package/build-module/components/block-lock/toolbar.js +25 -7
  37. package/build-module/components/block-lock/toolbar.js.map +1 -1
  38. package/build-module/components/block-toolbar/index.js +8 -5
  39. package/build-module/components/block-toolbar/index.js.map +1 -1
  40. package/build-module/components/dimensions-tool/aspect-ratio-tool.js +87 -0
  41. package/build-module/components/dimensions-tool/aspect-ratio-tool.js.map +1 -0
  42. package/build-module/components/dimensions-tool/index.js +195 -0
  43. package/build-module/components/dimensions-tool/index.js.map +1 -0
  44. package/build-module/components/dimensions-tool/scale-tool.js +103 -0
  45. package/build-module/components/dimensions-tool/scale-tool.js.map +1 -0
  46. package/build-module/components/dimensions-tool/width-height-tool.js +122 -0
  47. package/build-module/components/dimensions-tool/width-height-tool.js.map +1 -0
  48. package/build-module/components/image-editor/aspect-ratio-dropdown.js +1 -1
  49. package/build-module/components/image-editor/aspect-ratio-dropdown.js.map +1 -1
  50. package/build-module/components/image-editor/use-save-image.js +1 -2
  51. package/build-module/components/image-editor/use-save-image.js.map +1 -1
  52. package/build-module/components/image-size-control/index.js +5 -0
  53. package/build-module/components/image-size-control/index.js.map +1 -1
  54. package/build-module/components/link-control/index.js +17 -15
  55. package/build-module/components/link-control/index.js.map +1 -1
  56. package/build-module/components/link-control/search-input.js +4 -4
  57. package/build-module/components/link-control/search-input.js.map +1 -1
  58. package/build-module/components/link-control/settings-drawer.js +4 -5
  59. package/build-module/components/link-control/settings-drawer.js.map +1 -1
  60. package/build-module/components/provider/use-block-sync.js +21 -0
  61. package/build-module/components/provider/use-block-sync.js.map +1 -1
  62. package/build-module/components/resolution-tool/index.js +45 -0
  63. package/build-module/components/resolution-tool/index.js.map +1 -0
  64. package/build-module/components/url-input/index.js +4 -2
  65. package/build-module/components/url-input/index.js.map +1 -1
  66. package/build-module/private-apis.js +5 -1
  67. package/build-module/private-apis.js.map +1 -1
  68. package/build-module/store/defaults.js +1 -0
  69. package/build-module/store/defaults.js.map +1 -1
  70. package/build-style/style-rtl.css +42 -46
  71. package/build-style/style.css +42 -46
  72. package/package.json +6 -5
  73. package/src/components/alignment-control/test/__snapshots__/index.js.snap +6 -6
  74. package/src/components/block-alignment-control/test/__snapshots__/index.js.snap +5 -5
  75. package/src/components/block-lock/toolbar.js +34 -6
  76. package/src/components/block-toolbar/index.js +9 -6
  77. package/src/components/block-tools/style.scss +4 -0
  78. package/src/components/dimensions-tool/aspect-ratio-tool.js +124 -0
  79. package/src/components/dimensions-tool/index.js +212 -0
  80. package/src/components/dimensions-tool/scale-tool.js +124 -0
  81. package/src/components/dimensions-tool/stories/aspect-ratio-tool.js +52 -0
  82. package/src/components/dimensions-tool/stories/index.js +54 -0
  83. package/src/components/dimensions-tool/stories/scale-tool.js +48 -0
  84. package/src/components/dimensions-tool/stories/width-height-tool.js +54 -0
  85. package/src/components/dimensions-tool/test/index.js +641 -0
  86. package/src/components/dimensions-tool/width-height-tool.js +113 -0
  87. package/src/components/image-editor/aspect-ratio-dropdown.js +1 -1
  88. package/src/components/image-editor/use-save-image.js +0 -1
  89. package/src/components/image-size-control/index.js +6 -0
  90. package/src/components/link-control/index.js +32 -28
  91. package/src/components/link-control/search-input.js +4 -3
  92. package/src/components/link-control/settings-drawer.js +6 -5
  93. package/src/components/link-control/style.scss +33 -55
  94. package/src/components/link-control/test/index.js +129 -116
  95. package/src/components/media-replace-flow/test/index.js +1 -1
  96. package/src/components/provider/test/use-block-sync.js +21 -6
  97. package/src/components/provider/use-block-sync.js +19 -0
  98. package/src/components/resolution-tool/index.js +56 -0
  99. package/src/components/resolution-tool/stories/index.js +48 -0
  100. package/src/components/url-input/index.js +2 -0
  101. package/src/private-apis.js +4 -0
  102. package/src/store/defaults.js +1 -0
@@ -328,6 +328,9 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
328
328
  .block-editor-block-contextual-toolbar.is-fixed .block-editor-block-toolbar .components-toolbar {
329
329
  border-left-color: #e0e0e0;
330
330
  }
331
+ .block-editor-block-contextual-toolbar:has(.block-editor-block-toolbar:empty) {
332
+ display: none;
333
+ }
331
334
  @media (min-width: 782px) {
332
335
  .block-editor-block-contextual-toolbar.is-fixed {
333
336
  margin-right: 64px;
@@ -1883,15 +1886,6 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
1883
1886
  .block-editor-link-control__field {
1884
1887
  margin: 16px;
1885
1888
  }
1886
- .block-editor-link-control__field > .components-base-control__field {
1887
- display: flex;
1888
- align-items: center;
1889
- }
1890
- .block-editor-link-control__field .components-base-control__label {
1891
- margin-left: 16px;
1892
- margin-bottom: 0;
1893
- min-width: 29px;
1894
- }
1895
1889
  .block-editor-link-control__field input[type=text], .block-editor-link-control__field.block-editor-url-input input[type=text].block-editor-url-input__input {
1896
1890
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
1897
1891
  padding: 6px 8px;
@@ -1903,13 +1897,14 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
1903
1897
  font-size: 16px;
1904
1898
  /* Override core line-height. To be reviewed. */
1905
1899
  line-height: normal;
1906
- width: calc(100% - 32px);
1907
1900
  display: block;
1908
- padding: 11px 16px;
1901
+ border: 1px solid #949494;
1902
+ border-radius: 2px;
1903
+ height: 40px;
1909
1904
  margin: 0;
1905
+ padding: 8px 16px;
1910
1906
  position: relative;
1911
- border: 1px solid #ddd;
1912
- border-radius: 2px;
1907
+ width: 100%;
1913
1908
  }
1914
1909
  @media (prefers-reduced-motion: reduce) {
1915
1910
  .block-editor-link-control__field input[type=text], .block-editor-link-control__field.block-editor-url-input input[type=text].block-editor-url-input__input {
@@ -1949,12 +1944,12 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
1949
1944
  flex-direction: row-reverse;
1950
1945
  justify-content: flex-start;
1951
1946
  gap: 8px;
1947
+ padding: 8px;
1952
1948
  order: 20;
1953
1949
  }
1954
1950
 
1955
1951
  .block-editor-link-control__search-results-wrapper {
1956
1952
  position: relative;
1957
- margin-top: -15px;
1958
1953
  }
1959
1954
  .block-editor-link-control__search-results-wrapper::before, .block-editor-link-control__search-results-wrapper::after {
1960
1955
  content: "";
@@ -2235,48 +2230,18 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
2235
2230
  display: flex;
2236
2231
  flex-direction: column;
2237
2232
  flex-basis: 100%;
2238
- margin-top: 16px;
2239
- padding-top: 16px;
2240
2233
  position: relative;
2241
2234
  }
2242
- .block-editor-link-control__drawer-inner::after {
2243
- content: "";
2244
- display: block;
2245
- height: 1px;
2246
- background-color: #ddd;
2247
- position: absolute;
2248
- right: -16px;
2249
- left: -16px;
2250
- top: 0;
2251
- }
2252
-
2253
- .block-editor-link-control__tools {
2254
- display: flex;
2255
- flex-wrap: wrap;
2256
- align-items: center;
2257
- justify-content: space-between;
2258
- margin: 0;
2259
- padding: 16px;
2260
- margin-top: calc(var(--wp-admin-border-width-focus) * -1);
2261
- padding-top: var(--wp-admin-border-width-focus);
2262
- overflow: hidden;
2263
- }
2264
2235
 
2265
2236
  .block-editor-link-control__unlink {
2266
2237
  padding-right: 16px;
2267
2238
  padding-left: 16px;
2268
2239
  }
2269
2240
 
2270
- .block-editor-link-control__settings {
2271
- flex: 1;
2272
- margin: 0;
2273
- }
2274
- .is-alternate .block-editor-link-control__settings {
2275
- border-top: 1px solid #1e1e1e;
2276
- }
2277
-
2278
2241
  .block-editor-link-control__setting {
2279
2242
  margin-bottom: 16px;
2243
+ flex: 1;
2244
+ padding: 8px 24px 8px 0;
2280
2245
  }
2281
2246
  .block-editor-link-control__setting input {
2282
2247
  margin-right: 0;
@@ -2285,6 +2250,37 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
2285
2250
  margin-bottom: 0;
2286
2251
  }
2287
2252
 
2253
+ .block-editor-link-control__tools {
2254
+ padding: 8px 8px 0 8px;
2255
+ margin-top: -16px;
2256
+ }
2257
+ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle {
2258
+ padding-right: 0;
2259
+ gap: 0;
2260
+ }
2261
+ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg {
2262
+ visibility: visible;
2263
+ transition: transform 0.1s ease;
2264
+ transform: rotate(-90deg);
2265
+ }
2266
+ @media (prefers-reduced-motion: reduce) {
2267
+ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg {
2268
+ transition-duration: 0s;
2269
+ transition-delay: 0s;
2270
+ }
2271
+ }
2272
+ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg {
2273
+ visibility: visible;
2274
+ transform: rotate(0deg);
2275
+ transition: transform 0.1s ease;
2276
+ }
2277
+ @media (prefers-reduced-motion: reduce) {
2278
+ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg {
2279
+ transition-duration: 0s;
2280
+ transition-delay: 0s;
2281
+ }
2282
+ }
2283
+
2288
2284
  .block-editor-link-control .block-editor-link-control__search-input .components-spinner {
2289
2285
  display: block;
2290
2286
  }
@@ -328,6 +328,9 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
328
328
  .block-editor-block-contextual-toolbar.is-fixed .block-editor-block-toolbar .components-toolbar {
329
329
  border-right-color: #e0e0e0;
330
330
  }
331
+ .block-editor-block-contextual-toolbar:has(.block-editor-block-toolbar:empty) {
332
+ display: none;
333
+ }
331
334
  @media (min-width: 782px) {
332
335
  .block-editor-block-contextual-toolbar.is-fixed {
333
336
  margin-left: 64px;
@@ -1884,15 +1887,6 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
1884
1887
  .block-editor-link-control__field {
1885
1888
  margin: 16px;
1886
1889
  }
1887
- .block-editor-link-control__field > .components-base-control__field {
1888
- display: flex;
1889
- align-items: center;
1890
- }
1891
- .block-editor-link-control__field .components-base-control__label {
1892
- margin-right: 16px;
1893
- margin-bottom: 0;
1894
- min-width: 29px;
1895
- }
1896
1890
  .block-editor-link-control__field input[type=text], .block-editor-link-control__field.block-editor-url-input input[type=text].block-editor-url-input__input {
1897
1891
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
1898
1892
  padding: 6px 8px;
@@ -1904,13 +1898,14 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
1904
1898
  font-size: 16px;
1905
1899
  /* Override core line-height. To be reviewed. */
1906
1900
  line-height: normal;
1907
- width: calc(100% - 32px);
1908
1901
  display: block;
1909
- padding: 11px 16px;
1902
+ border: 1px solid #949494;
1903
+ border-radius: 2px;
1904
+ height: 40px;
1910
1905
  margin: 0;
1906
+ padding: 8px 16px;
1911
1907
  position: relative;
1912
- border: 1px solid #ddd;
1913
- border-radius: 2px;
1908
+ width: 100%;
1914
1909
  }
1915
1910
  @media (prefers-reduced-motion: reduce) {
1916
1911
  .block-editor-link-control__field input[type=text], .block-editor-link-control__field.block-editor-url-input input[type=text].block-editor-url-input__input {
@@ -1950,12 +1945,12 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
1950
1945
  flex-direction: row-reverse;
1951
1946
  justify-content: flex-start;
1952
1947
  gap: 8px;
1948
+ padding: 8px;
1953
1949
  order: 20;
1954
1950
  }
1955
1951
 
1956
1952
  .block-editor-link-control__search-results-wrapper {
1957
1953
  position: relative;
1958
- margin-top: -15px;
1959
1954
  }
1960
1955
  .block-editor-link-control__search-results-wrapper::before, .block-editor-link-control__search-results-wrapper::after {
1961
1956
  content: "";
@@ -2236,48 +2231,18 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
2236
2231
  display: flex;
2237
2232
  flex-direction: column;
2238
2233
  flex-basis: 100%;
2239
- margin-top: 16px;
2240
- padding-top: 16px;
2241
2234
  position: relative;
2242
2235
  }
2243
- .block-editor-link-control__drawer-inner::after {
2244
- content: "";
2245
- display: block;
2246
- height: 1px;
2247
- background-color: #ddd;
2248
- position: absolute;
2249
- left: -16px;
2250
- right: -16px;
2251
- top: 0;
2252
- }
2253
-
2254
- .block-editor-link-control__tools {
2255
- display: flex;
2256
- flex-wrap: wrap;
2257
- align-items: center;
2258
- justify-content: space-between;
2259
- margin: 0;
2260
- padding: 16px;
2261
- margin-top: calc(var(--wp-admin-border-width-focus) * -1);
2262
- padding-top: var(--wp-admin-border-width-focus);
2263
- overflow: hidden;
2264
- }
2265
2236
 
2266
2237
  .block-editor-link-control__unlink {
2267
2238
  padding-left: 16px;
2268
2239
  padding-right: 16px;
2269
2240
  }
2270
2241
 
2271
- .block-editor-link-control__settings {
2272
- flex: 1;
2273
- margin: 0;
2274
- }
2275
- .is-alternate .block-editor-link-control__settings {
2276
- border-top: 1px solid #1e1e1e;
2277
- }
2278
-
2279
2242
  .block-editor-link-control__setting {
2280
2243
  margin-bottom: 16px;
2244
+ flex: 1;
2245
+ padding: 8px 0 8px 24px;
2281
2246
  }
2282
2247
  .block-editor-link-control__setting input {
2283
2248
  margin-left: 0;
@@ -2286,6 +2251,37 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
2286
2251
  margin-bottom: 0;
2287
2252
  }
2288
2253
 
2254
+ .block-editor-link-control__tools {
2255
+ padding: 8px 8px 0 8px;
2256
+ margin-top: -16px;
2257
+ }
2258
+ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle {
2259
+ padding-left: 0;
2260
+ gap: 0;
2261
+ }
2262
+ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg {
2263
+ visibility: visible;
2264
+ transition: transform 0.1s ease;
2265
+ transform: rotate(90deg);
2266
+ }
2267
+ @media (prefers-reduced-motion: reduce) {
2268
+ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg {
2269
+ transition-duration: 0s;
2270
+ transition-delay: 0s;
2271
+ }
2272
+ }
2273
+ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg {
2274
+ visibility: visible;
2275
+ transform: rotate(0deg);
2276
+ transition: transform 0.1s ease;
2277
+ }
2278
+ @media (prefers-reduced-motion: reduce) {
2279
+ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg {
2280
+ transition-duration: 0s;
2281
+ transition-delay: 0s;
2282
+ }
2283
+ }
2284
+
2289
2285
  .block-editor-link-control .block-editor-link-control__search-input .components-spinner {
2290
2286
  display: block;
2291
2287
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-editor",
3
- "version": "12.3.1",
3
+ "version": "12.3.3",
4
4
  "description": "Generic block editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -32,12 +32,13 @@
32
32
  ],
33
33
  "dependencies": {
34
34
  "@babel/runtime": "^7.16.0",
35
+ "@emotion/styled": "^11.6.0",
35
36
  "@react-spring/web": "^9.4.5",
36
37
  "@wordpress/a11y": "^3.35.1",
37
38
  "@wordpress/api-fetch": "^6.32.1",
38
39
  "@wordpress/blob": "^3.35.1",
39
40
  "@wordpress/blocks": "^12.12.1",
40
- "@wordpress/components": "^25.1.1",
41
+ "@wordpress/components": "^25.1.3",
41
42
  "@wordpress/compose": "^6.12.1",
42
43
  "@wordpress/data": "^9.5.1",
43
44
  "@wordpress/date": "^4.35.1",
@@ -48,12 +49,12 @@
48
49
  "@wordpress/hooks": "^3.35.1",
49
50
  "@wordpress/html-entities": "^3.35.1",
50
51
  "@wordpress/i18n": "^4.35.1",
51
- "@wordpress/icons": "^9.26.1",
52
+ "@wordpress/icons": "^9.26.2",
52
53
  "@wordpress/is-shallow-equal": "^4.35.1",
53
54
  "@wordpress/keyboard-shortcuts": "^4.12.1",
54
55
  "@wordpress/keycodes": "^3.35.1",
55
56
  "@wordpress/notices": "^4.3.1",
56
- "@wordpress/preferences": "^3.12.1",
57
+ "@wordpress/preferences": "^3.12.3",
57
58
  "@wordpress/private-apis": "^0.17.1",
58
59
  "@wordpress/rich-text": "^6.12.1",
59
60
  "@wordpress/shortcode": "^3.35.1",
@@ -84,5 +85,5 @@
84
85
  "publishConfig": {
85
86
  "access": "public"
86
87
  },
87
- "gitHead": "ce5639111c30763dbdf07f40eeb136ea6030ecf1"
88
+ "gitHead": "7efa7c2321a958ddfa723825a0354071435a9d43"
88
89
  }
@@ -25,7 +25,7 @@ exports[`AlignmentUI should allow custom alignment controls to be specified 1`]
25
25
  xmlns="http://www.w3.org/2000/svg"
26
26
  >
27
27
  <path
28
- d="M4 19.8h8.9v-1.5H4v1.5zm8.9-15.6H4v1.5h8.9V4.2zm-8.9 7v1.5h16v-1.5H4z"
28
+ d="M13 5.5H4V4h9v1.5Zm7 7H4V11h16v1.5Zm-7 7H4V18h9v1.5Z"
29
29
  />
30
30
  </svg>
31
31
  </button>
@@ -48,7 +48,7 @@ exports[`AlignmentUI should allow custom alignment controls to be specified 1`]
48
48
  xmlns="http://www.w3.org/2000/svg"
49
49
  >
50
50
  <path
51
- d="M16.4 4.2H7.6v1.5h8.9V4.2zM4 11.2v1.5h16v-1.5H4zm3.6 8.6h8.9v-1.5H7.6v1.5z"
51
+ d="M7.5 5.5h9V4h-9v1.5Zm-3.5 7h16V11H4v1.5Zm3.5 7h9V18h-9v1.5Z"
52
52
  />
53
53
  </svg>
54
54
  </button>
@@ -80,7 +80,7 @@ exports[`AlignmentUI should match snapshot when controls are hidden 1`] = `
80
80
  xmlns="http://www.w3.org/2000/svg"
81
81
  >
82
82
  <path
83
- d="M4 19.8h8.9v-1.5H4v1.5zm8.9-15.6H4v1.5h8.9V4.2zm-8.9 7v1.5h16v-1.5H4z"
83
+ d="M13 5.5H4V4h9v1.5Zm7 7H4V11h16v1.5Zm-7 7H4V18h9v1.5Z"
84
84
  />
85
85
  </svg>
86
86
  </button>
@@ -113,7 +113,7 @@ exports[`AlignmentUI should match snapshot when controls are visible 1`] = `
113
113
  xmlns="http://www.w3.org/2000/svg"
114
114
  >
115
115
  <path
116
- d="M4 19.8h8.9v-1.5H4v1.5zm8.9-15.6H4v1.5h8.9V4.2zm-8.9 7v1.5h16v-1.5H4z"
116
+ d="M13 5.5H4V4h9v1.5Zm7 7H4V11h16v1.5Zm-7 7H4V18h9v1.5Z"
117
117
  />
118
118
  </svg>
119
119
  </button>
@@ -136,7 +136,7 @@ exports[`AlignmentUI should match snapshot when controls are visible 1`] = `
136
136
  xmlns="http://www.w3.org/2000/svg"
137
137
  >
138
138
  <path
139
- d="M16.4 4.2H7.6v1.5h8.9V4.2zM4 11.2v1.5h16v-1.5H4zm3.6 8.6h8.9v-1.5H7.6v1.5z"
139
+ d="M7.5 5.5h9V4h-9v1.5Zm-3.5 7h16V11H4v1.5Zm3.5 7h9V18h-9v1.5Z"
140
140
  />
141
141
  </svg>
142
142
  </button>
@@ -159,7 +159,7 @@ exports[`AlignmentUI should match snapshot when controls are visible 1`] = `
159
159
  xmlns="http://www.w3.org/2000/svg"
160
160
  >
161
161
  <path
162
- d="M11.1 19.8H20v-1.5h-8.9v1.5zm0-15.6v1.5H20V4.2h-8.9zM4 12.8h16v-1.5H4v1.5z"
162
+ d="M11.111 5.5H20V4h-8.889v1.5ZM4 12.5h16V11H4v1.5Zm7.111 7H20V18h-8.889v1.5Z"
163
163
  />
164
164
  </svg>
165
165
  </button>
@@ -23,7 +23,7 @@ exports[`BlockAlignmentUI should match snapshot when controls are hidden 1`] = `
23
23
  xmlns="http://www.w3.org/2000/svg"
24
24
  >
25
25
  <path
26
- d="M4 9v6h14V9H4zm8-4.8H4v1.5h8V4.2zM4 19.8h8v-1.5H4v1.5z"
26
+ d="M5 5.5h8V4H5v1.5ZM5 20h8v-1.5H5V20ZM19 9H5v6h14V9Z"
27
27
  />
28
28
  </svg>
29
29
  </button>
@@ -55,7 +55,7 @@ exports[`BlockAlignmentUI should match snapshot when controls are visible 1`] =
55
55
  xmlns="http://www.w3.org/2000/svg"
56
56
  >
57
57
  <path
58
- d="M5 15h14V9H5v6zm0 4.8h14v-1.5H5v1.5zM5 4.2v1.5h14V4.2H5z"
58
+ d="M19 5.5H5V4h14v1.5ZM19 20H5v-1.5h14V20ZM5 9h14v6H5V9Z"
59
59
  />
60
60
  </svg>
61
61
  </button>
@@ -77,7 +77,7 @@ exports[`BlockAlignmentUI should match snapshot when controls are visible 1`] =
77
77
  xmlns="http://www.w3.org/2000/svg"
78
78
  >
79
79
  <path
80
- d="M4 9v6h14V9H4zm8-4.8H4v1.5h8V4.2zM4 19.8h8v-1.5H4v1.5z"
80
+ d="M5 5.5h8V4H5v1.5ZM5 20h8v-1.5H5V20ZM19 9H5v6h14V9Z"
81
81
  />
82
82
  </svg>
83
83
  </button>
@@ -99,7 +99,7 @@ exports[`BlockAlignmentUI should match snapshot when controls are visible 1`] =
99
99
  xmlns="http://www.w3.org/2000/svg"
100
100
  >
101
101
  <path
102
- d="M7 9v6h10V9H7zM5 19.8h14v-1.5H5v1.5zM5 4.3v1.5h14V4.3H5z"
102
+ d="M19 5.5H5V4h14v1.5ZM19 20H5v-1.5h14V20ZM7 9h10v6H7V9Z"
103
103
  />
104
104
  </svg>
105
105
  </button>
@@ -121,7 +121,7 @@ exports[`BlockAlignmentUI should match snapshot when controls are visible 1`] =
121
121
  xmlns="http://www.w3.org/2000/svg"
122
122
  >
123
123
  <path
124
- d="M6 15h14V9H6v6zm6-10.8v1.5h8V4.2h-8zm0 15.6h8v-1.5h-8v1.5z"
124
+ d="M19 5.5h-8V4h8v1.5ZM19 20h-8v-1.5h8V20ZM5 9h14v6H5V9Z"
125
125
  />
126
126
  </svg>
127
127
  </button>
@@ -3,7 +3,8 @@
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { ToolbarButton, ToolbarGroup } from '@wordpress/components';
6
- import { useReducer } from '@wordpress/element';
6
+ import { focus } from '@wordpress/dom';
7
+ import { useReducer, useRef, useEffect } from '@wordpress/element';
7
8
  import { lock } from '@wordpress/icons';
8
9
 
9
10
  /**
@@ -12,7 +13,7 @@ import { lock } from '@wordpress/icons';
12
13
  import BlockLockModal from './modal';
13
14
  import useBlockLock from './use-block-lock';
14
15
 
15
- export default function BlockLockToolbar( { clientId } ) {
16
+ export default function BlockLockToolbar( { clientId, wrapperRef } ) {
16
17
  const { canEdit, canMove, canRemove, canLock } = useBlockLock( clientId );
17
18
 
18
19
  const [ isModalOpen, toggleModal ] = useReducer(
@@ -20,11 +21,37 @@ export default function BlockLockToolbar( { clientId } ) {
20
21
  false
21
22
  );
22
23
 
23
- if ( ! canLock ) {
24
- return null;
25
- }
24
+ const lockButtonRef = useRef( null );
25
+ const isFirstRender = useRef( true );
26
+
27
+ const shouldHideBlockLockUI =
28
+ ! canLock || ( canEdit && canMove && canRemove );
29
+
30
+ // Restore focus manually on the first focusable element in the toolbar
31
+ // when the block lock modal is closed and the block is not locked anymore.
32
+ // See https://github.com/WordPress/gutenberg/issues/51447
33
+ useEffect( () => {
34
+ if ( isFirstRender.current ) {
35
+ isFirstRender.current = false;
36
+ return;
37
+ }
38
+
39
+ if ( ! isModalOpen && shouldHideBlockLockUI ) {
40
+ focus.focusable
41
+ .find( wrapperRef.current, {
42
+ sequential: false,
43
+ } )
44
+ .find(
45
+ ( element ) =>
46
+ element.tagName === 'BUTTON' &&
47
+ element !== lockButtonRef.current
48
+ )
49
+ ?.focus();
50
+ }
51
+ // wrapperRef is a reference object and should be stable
52
+ }, [ isModalOpen, shouldHideBlockLockUI, wrapperRef ] );
26
53
 
27
- if ( canEdit && canMove && canRemove ) {
54
+ if ( shouldHideBlockLockUI ) {
28
55
  return null;
29
56
  }
30
57
 
@@ -35,6 +62,7 @@ export default function BlockLockToolbar( { clientId } ) {
35
62
  icon={ lock }
36
63
  label={ __( 'Unlock' ) }
37
64
  onClick={ toggleModal }
65
+ ref={ lockButtonRef }
38
66
  />
39
67
  </ToolbarGroup>
40
68
  { isModalOpen && (
@@ -78,6 +78,8 @@ const BlockToolbar = ( { hideDragHandle } ) => {
78
78
  };
79
79
  }, [] );
80
80
 
81
+ const toolbarWrapperRef = useRef( null );
82
+
81
83
  // Handles highlighting the current block outline on hover or focus of the
82
84
  // block type toolbar area.
83
85
  const { toggleBlockHighlight } = useDispatch( blockEditorStore );
@@ -123,18 +125,19 @@ const BlockToolbar = ( { hideDragHandle } ) => {
123
125
  } );
124
126
 
125
127
  return (
126
- <div className={ classes }>
128
+ <div className={ classes } ref={ toolbarWrapperRef }>
127
129
  { ! isMultiToolbar &&
128
130
  isLargeViewport &&
129
131
  blockEditingMode === 'default' && <BlockParentSelector /> }
130
- <div ref={ nodeRef } { ...showMoversGestures }>
131
- { ( shouldShowVisualToolbar || isMultiToolbar ) &&
132
- blockEditingMode === 'default' && (
132
+ { ( shouldShowVisualToolbar || isMultiToolbar ) &&
133
+ blockEditingMode === 'default' && (
134
+ <div ref={ nodeRef } { ...showMoversGestures }>
133
135
  <ToolbarGroup className="block-editor-block-toolbar__block-controls">
134
136
  <BlockSwitcher clientIds={ blockClientIds } />
135
137
  { ! isMultiToolbar && (
136
138
  <BlockLockToolbar
137
139
  clientId={ blockClientIds[ 0 ] }
140
+ wrapperRef={ toolbarWrapperRef }
138
141
  />
139
142
  ) }
140
143
  <BlockMover
@@ -142,8 +145,8 @@ const BlockToolbar = ( { hideDragHandle } ) => {
142
145
  hideDragHandle={ hideDragHandle }
143
146
  />
144
147
  </ToolbarGroup>
145
- ) }
146
- </div>
148
+ </div>
149
+ ) }
147
150
  { shouldShowVisualToolbar && isMultiToolbar && (
148
151
  <BlockGroupToolbar />
149
152
  ) }
@@ -121,6 +121,10 @@
121
121
  }
122
122
  }
123
123
 
124
+ &:has(.block-editor-block-toolbar:empty) {
125
+ display: none;
126
+ }
127
+
124
128
  // on desktop and tablet viewports the toolbar is fixed
125
129
  // on top of interface header
126
130
 
@@ -0,0 +1,124 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ SelectControl,
6
+ __experimentalToolsPanelItem as ToolsPanelItem,
7
+ } from '@wordpress/components';
8
+ import { __, _x } from '@wordpress/i18n';
9
+
10
+ /**
11
+ * @typedef {import('@wordpress/components/build-types/select-control/types').SelectControlProps} SelectControlProps
12
+ */
13
+
14
+ /**
15
+ * @type {SelectControlProps[]}
16
+ */
17
+ export const DEFAULT_ASPECT_RATIO_OPTIONS = [
18
+ {
19
+ label: _x( 'Original', 'Aspect ratio option for dimensions control' ),
20
+ value: 'auto',
21
+ },
22
+ {
23
+ label: _x(
24
+ 'Square - 1:1',
25
+ 'Aspect ratio option for dimensions control'
26
+ ),
27
+ value: '1',
28
+ },
29
+ {
30
+ label: _x(
31
+ 'Standard - 4:3',
32
+ 'Aspect ratio option for dimensions control'
33
+ ),
34
+ value: '4/3',
35
+ },
36
+ {
37
+ label: _x(
38
+ 'Portrait - 3:4',
39
+ 'Aspect ratio option for dimensions control'
40
+ ),
41
+ value: '3/4',
42
+ },
43
+ {
44
+ label: _x(
45
+ 'Classic - 3:2',
46
+ 'Aspect ratio option for dimensions control'
47
+ ),
48
+ value: '3/2',
49
+ },
50
+ {
51
+ label: _x(
52
+ 'Classic Portrait - 2:3',
53
+ 'Aspect ratio option for dimensions control'
54
+ ),
55
+ value: '2/3',
56
+ },
57
+ {
58
+ label: _x(
59
+ 'Wide - 16:9',
60
+ 'Aspect ratio option for dimensions control'
61
+ ),
62
+ value: '16/9',
63
+ },
64
+ {
65
+ label: _x(
66
+ 'Tall - 9:16',
67
+ 'Aspect ratio option for dimensions control'
68
+ ),
69
+ value: '9/16',
70
+ },
71
+ {
72
+ label: _x( 'Custom', 'Aspect ratio option for dimensions control' ),
73
+ value: 'custom',
74
+ disabled: true,
75
+ hidden: true,
76
+ },
77
+ ];
78
+
79
+ /**
80
+ * @callback AspectRatioToolPropsOnChange
81
+ * @param {string} [value] New aspect ratio value.
82
+ * @return {void} No return.
83
+ */
84
+
85
+ /**
86
+ * @typedef {Object} AspectRatioToolProps
87
+ * @property {string} [panelId] ID of the panel this tool is associated with.
88
+ * @property {string} [value] Current aspect ratio value.
89
+ * @property {AspectRatioToolPropsOnChange} [onChange] Callback to update the aspect ratio value.
90
+ * @property {SelectControlProps[]} [options] Aspect ratio options.
91
+ * @property {string} [defaultValue] Default aspect ratio value.
92
+ * @property {boolean} [isShownByDefault] Whether the tool is shown by default.
93
+ */
94
+
95
+ export default function AspectRatioTool( {
96
+ panelId,
97
+ value,
98
+ onChange = () => {},
99
+ options = DEFAULT_ASPECT_RATIO_OPTIONS,
100
+ defaultValue = DEFAULT_ASPECT_RATIO_OPTIONS[ 0 ].value,
101
+ isShownByDefault = true,
102
+ } ) {
103
+ // Match the CSS default so if the value is used directly in CSS it will look correct in the control.
104
+ const displayValue = value ?? 'auto';
105
+
106
+ return (
107
+ <ToolsPanelItem
108
+ hasValue={ () => displayValue !== defaultValue }
109
+ label={ __( 'Aspect ratio' ) }
110
+ onDeselect={ () => onChange( undefined ) }
111
+ isShownByDefault={ isShownByDefault }
112
+ panelId={ panelId }
113
+ >
114
+ <SelectControl
115
+ label={ __( 'Aspect ratio' ) }
116
+ value={ displayValue }
117
+ options={ options }
118
+ onChange={ onChange }
119
+ size={ '__unstable-large' }
120
+ __nextHasNoMarginBottom
121
+ />
122
+ </ToolsPanelItem>
123
+ );
124
+ }