@wordpress/block-editor 8.6.0 → 9.2.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 (466) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +5 -2
  3. package/build/components/block-alignment-control/constants.js +48 -0
  4. package/build/components/block-alignment-control/constants.js.map +1 -0
  5. package/build/components/block-alignment-control/ui.js +9 -40
  6. package/build/components/block-alignment-control/ui.js.map +1 -1
  7. package/build/components/block-alignment-control/ui.native.js +92 -0
  8. package/build/components/block-alignment-control/ui.native.js.map +1 -0
  9. package/build/components/block-alignment-matrix-control/index.js +1 -6
  10. package/build/components/block-alignment-matrix-control/index.js.map +1 -1
  11. package/build/components/block-content-overlay/index.js +4 -82
  12. package/build/components/block-content-overlay/index.js.map +1 -1
  13. package/build/components/block-draggable/draggable-chip.native.js +65 -0
  14. package/build/components/block-draggable/draggable-chip.native.js.map +1 -0
  15. package/build/components/block-draggable/dropping-insertion-point.native.js +157 -0
  16. package/build/components/block-draggable/dropping-insertion-point.native.js.map +1 -0
  17. package/build/components/block-draggable/index.native.js +488 -0
  18. package/build/components/block-draggable/index.native.js.map +1 -0
  19. package/build/components/block-draggable/use-scroll-when-dragging.native.js +130 -0
  20. package/build/components/block-draggable/use-scroll-when-dragging.native.js.map +1 -0
  21. package/build/components/block-list/block-list-context.native.js +195 -0
  22. package/build/components/block-list/block-list-context.native.js.map +1 -0
  23. package/build/components/block-list/block-list-item-cell.native.js +67 -0
  24. package/build/components/block-list/block-list-item-cell.native.js.map +1 -0
  25. package/build/components/block-list/block-list-item.native.js +12 -9
  26. package/build/components/block-list/block-list-item.native.js.map +1 -1
  27. package/build/components/block-list/block.native.js +27 -5
  28. package/build/components/block-list/block.native.js.map +1 -1
  29. package/build/components/block-list/index.js +34 -32
  30. package/build/components/block-list/index.js.map +1 -1
  31. package/build/components/block-list/index.native.js +75 -23
  32. package/build/components/block-list/index.native.js.map +1 -1
  33. package/build/components/block-list/use-block-props/index.js +8 -4
  34. package/build/components/block-list/use-block-props/index.js.map +1 -1
  35. package/build/components/block-list/use-block-props/use-block-class-names.js +1 -7
  36. package/build/components/block-list/use-block-props/use-block-class-names.js.map +1 -1
  37. package/build/components/block-list/use-in-between-inserter.js +1 -1
  38. package/build/components/block-list/use-in-between-inserter.js.map +1 -1
  39. package/build/components/block-mobile-toolbar/index.native.js +10 -3
  40. package/build/components/block-mobile-toolbar/index.native.js.map +1 -1
  41. package/build/components/block-mover/index.native.js +17 -4
  42. package/build/components/block-mover/index.native.js.map +1 -1
  43. package/build/components/block-navigation/dropdown.js +11 -5
  44. package/build/components/block-navigation/dropdown.js.map +1 -1
  45. package/build/components/block-popover/inbetween.js +19 -8
  46. package/build/components/block-popover/inbetween.js.map +1 -1
  47. package/build/components/block-popover/index.js +20 -16
  48. package/build/components/block-popover/index.js.map +1 -1
  49. package/build/components/block-preview/index.js +1 -1
  50. package/build/components/block-preview/index.js.map +1 -1
  51. package/build/components/block-tools/block-selection-button.js +1 -0
  52. package/build/components/block-tools/block-selection-button.js.map +1 -1
  53. package/build/components/block-tools/selected-block-popover.js +1 -29
  54. package/build/components/block-tools/selected-block-popover.js.map +1 -1
  55. package/build/components/block-variation-transforms/index.js +16 -2
  56. package/build/components/block-variation-transforms/index.js.map +1 -1
  57. package/build/components/border-radius-control/input-controls.js +10 -3
  58. package/build/components/border-radius-control/input-controls.js.map +1 -1
  59. package/build/components/color-style-selector/index.js +9 -0
  60. package/build/components/color-style-selector/index.js.map +1 -1
  61. package/build/components/colors-gradients/dropdown.js +122 -41
  62. package/build/components/colors-gradients/dropdown.js.map +1 -1
  63. package/build/components/colors-gradients/panel-color-gradient-settings.js +35 -60
  64. package/build/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  65. package/build/components/convert-to-group-buttons/toolbar.js +22 -5
  66. package/build/components/convert-to-group-buttons/toolbar.js.map +1 -1
  67. package/build/components/iframe/index.js +51 -50
  68. package/build/components/iframe/index.js.map +1 -1
  69. package/build/components/image-editor/use-save-image.js +3 -1
  70. package/build/components/image-editor/use-save-image.js.map +1 -1
  71. package/build/components/index.js +14 -23
  72. package/build/components/index.js.map +1 -1
  73. package/build/components/inserter/index.js +21 -7
  74. package/build/components/inserter/index.js.map +1 -1
  75. package/build/components/inserter/index.native.js +2 -2
  76. package/build/components/inserter/index.native.js.map +1 -1
  77. package/build/components/inserter/quick-inserter.js +4 -5
  78. package/build/components/inserter/quick-inserter.js.map +1 -1
  79. package/build/components/link-control/constants.js +11 -1
  80. package/build/components/link-control/constants.js.map +1 -1
  81. package/build/components/link-control/search-results.js +4 -3
  82. package/build/components/link-control/search-results.js.map +1 -1
  83. package/build/components/link-control/use-search-handler.js +4 -4
  84. package/build/components/link-control/use-search-handler.js.map +1 -1
  85. package/build/components/list-view/block.js +15 -15
  86. package/build/components/list-view/block.js.map +1 -1
  87. package/build/components/list-view/branch.js +9 -13
  88. package/build/components/list-view/branch.js.map +1 -1
  89. package/build/components/list-view/context.js +1 -4
  90. package/build/components/list-view/context.js.map +1 -1
  91. package/build/components/list-view/drop-indicator.js +0 -1
  92. package/build/components/list-view/drop-indicator.js.map +1 -1
  93. package/build/components/list-view/index.js +15 -32
  94. package/build/components/list-view/index.js.map +1 -1
  95. package/build/components/media-placeholder/index.js +0 -2
  96. package/build/components/media-placeholder/index.js.map +1 -1
  97. package/build/components/media-replace-flow/index.js +0 -2
  98. package/build/components/media-replace-flow/index.js.map +1 -1
  99. package/build/components/media-upload/index.native.js +10 -4
  100. package/build/components/media-upload/index.native.js.map +1 -1
  101. package/build/components/navigable-toolbar/index.js +12 -2
  102. package/build/components/navigable-toolbar/index.js.map +1 -1
  103. package/build/components/plain-text/index.native.js +62 -7
  104. package/build/components/plain-text/index.native.js.map +1 -1
  105. package/build/components/publish-date-time-picker/index.js +55 -0
  106. package/build/components/publish-date-time-picker/index.js.map +1 -0
  107. package/build/components/rich-text/format-toolbar-container.js +0 -1
  108. package/build/components/rich-text/format-toolbar-container.js.map +1 -1
  109. package/build/components/rich-text/index.js +2 -2
  110. package/build/components/rich-text/index.js.map +1 -1
  111. package/build/components/rich-text/index.native.js +5 -1
  112. package/build/components/rich-text/index.native.js.map +1 -1
  113. package/build/components/url-input/index.js +11 -4
  114. package/build/components/url-input/index.js.map +1 -1
  115. package/build/components/use-block-drop-zone/index.native.js +167 -0
  116. package/build/components/use-block-drop-zone/index.native.js.map +1 -0
  117. package/build/components/use-on-block-drop/index.native.js +95 -0
  118. package/build/components/use-on-block-drop/index.native.js.map +1 -0
  119. package/build/components/use-setting/index.js +42 -18
  120. package/build/components/use-setting/index.js.map +1 -1
  121. package/build/components/warning/index.js +6 -1
  122. package/build/components/warning/index.js.map +1 -1
  123. package/build/components/writing-flow/use-click-selection.js +1 -3
  124. package/build/components/writing-flow/use-click-selection.js.map +1 -1
  125. package/build/components/writing-flow/use-input.js +15 -0
  126. package/build/components/writing-flow/use-input.js.map +1 -1
  127. package/build/components/writing-flow/use-selection-observer.js +49 -8
  128. package/build/components/writing-flow/use-selection-observer.js.map +1 -1
  129. package/build/elements/index.js +9 -0
  130. package/build/elements/index.js.map +1 -0
  131. package/build/hooks/anchor.js.map +1 -1
  132. package/build/hooks/border.js +2 -7
  133. package/build/hooks/border.js.map +1 -1
  134. package/build/hooks/color-panel.js +14 -7
  135. package/build/hooks/color-panel.js.map +1 -1
  136. package/build/hooks/color.js +8 -88
  137. package/build/hooks/color.js.map +1 -1
  138. package/build/hooks/dimensions.js +16 -6
  139. package/build/hooks/dimensions.js.map +1 -1
  140. package/build/hooks/index.js +2 -0
  141. package/build/hooks/index.js.map +1 -1
  142. package/build/hooks/margin.js +64 -12
  143. package/build/hooks/margin.js.map +1 -1
  144. package/build/hooks/padding.js +60 -12
  145. package/build/hooks/padding.js.map +1 -1
  146. package/build/hooks/settings.js +32 -0
  147. package/build/hooks/settings.js.map +1 -0
  148. package/build/hooks/style.js +14 -13
  149. package/build/hooks/style.js.map +1 -1
  150. package/build/hooks/typography.js +6 -2
  151. package/build/hooks/typography.js.map +1 -1
  152. package/build/index.js +14 -0
  153. package/build/index.js.map +1 -1
  154. package/build/layouts/flex.js +5 -2
  155. package/build/layouts/flex.js.map +1 -1
  156. package/build/store/actions.js +14 -0
  157. package/build/store/actions.js.map +1 -1
  158. package/build/store/defaults.js +0 -1
  159. package/build/store/defaults.js.map +1 -1
  160. package/build/store/reducer.js +17 -2
  161. package/build/store/reducer.js.map +1 -1
  162. package/build/store/selectors.js +43 -13
  163. package/build/store/selectors.js.map +1 -1
  164. package/build-module/components/block-alignment-control/constants.js +36 -0
  165. package/build-module/components/block-alignment-control/constants.js.map +1 -0
  166. package/build-module/components/block-alignment-control/ui.js +4 -35
  167. package/build-module/components/block-alignment-control/ui.js.map +1 -1
  168. package/build-module/components/block-alignment-control/ui.native.js +78 -0
  169. package/build-module/components/block-alignment-control/ui.native.js.map +1 -0
  170. package/build-module/components/block-alignment-matrix-control/index.js +1 -6
  171. package/build-module/components/block-alignment-matrix-control/index.js.map +1 -1
  172. package/build-module/components/block-content-overlay/index.js +3 -78
  173. package/build-module/components/block-content-overlay/index.js.map +1 -1
  174. package/build-module/components/block-draggable/draggable-chip.native.js +51 -0
  175. package/build-module/components/block-draggable/draggable-chip.native.js.map +1 -0
  176. package/build-module/components/block-draggable/dropping-insertion-point.native.js +137 -0
  177. package/build-module/components/block-draggable/dropping-insertion-point.native.js.map +1 -0
  178. package/build-module/components/block-draggable/index.native.js +453 -0
  179. package/build-module/components/block-draggable/index.native.js.map +1 -0
  180. package/build-module/components/block-draggable/use-scroll-when-dragging.native.js +120 -0
  181. package/build-module/components/block-draggable/use-scroll-when-dragging.native.js.map +1 -0
  182. package/build-module/components/block-list/block-list-context.native.js +179 -0
  183. package/build-module/components/block-list/block-list-context.native.js.map +1 -0
  184. package/build-module/components/block-list/block-list-item-cell.native.js +59 -0
  185. package/build-module/components/block-list/block-list-item-cell.native.js.map +1 -0
  186. package/build-module/components/block-list/block-list-item.native.js +12 -9
  187. package/build-module/components/block-list/block-list-item.native.js.map +1 -1
  188. package/build-module/components/block-list/block.native.js +26 -5
  189. package/build-module/components/block-list/block.native.js.map +1 -1
  190. package/build-module/components/block-list/index.js +35 -33
  191. package/build-module/components/block-list/index.js.map +1 -1
  192. package/build-module/components/block-list/index.native.js +72 -23
  193. package/build-module/components/block-list/index.native.js.map +1 -1
  194. package/build-module/components/block-list/use-block-props/index.js +9 -5
  195. package/build-module/components/block-list/use-block-props/index.js.map +1 -1
  196. package/build-module/components/block-list/use-block-props/use-block-class-names.js +1 -7
  197. package/build-module/components/block-list/use-block-props/use-block-class-names.js.map +1 -1
  198. package/build-module/components/block-list/use-in-between-inserter.js +1 -1
  199. package/build-module/components/block-list/use-in-between-inserter.js.map +1 -1
  200. package/build-module/components/block-mobile-toolbar/index.native.js +9 -3
  201. package/build-module/components/block-mobile-toolbar/index.native.js.map +1 -1
  202. package/build-module/components/block-mover/index.native.js +18 -5
  203. package/build-module/components/block-mover/index.native.js.map +1 -1
  204. package/build-module/components/block-navigation/dropdown.js +10 -5
  205. package/build-module/components/block-navigation/dropdown.js.map +1 -1
  206. package/build-module/components/block-popover/inbetween.js +19 -8
  207. package/build-module/components/block-popover/inbetween.js.map +1 -1
  208. package/build-module/components/block-popover/index.js +21 -15
  209. package/build-module/components/block-popover/index.js.map +1 -1
  210. package/build-module/components/block-preview/index.js +1 -1
  211. package/build-module/components/block-preview/index.js.map +1 -1
  212. package/build-module/components/block-tools/block-selection-button.js +1 -0
  213. package/build-module/components/block-tools/block-selection-button.js.map +1 -1
  214. package/build-module/components/block-tools/selected-block-popover.js +2 -29
  215. package/build-module/components/block-tools/selected-block-popover.js.map +1 -1
  216. package/build-module/components/block-variation-transforms/index.js +13 -2
  217. package/build-module/components/block-variation-transforms/index.js.map +1 -1
  218. package/build-module/components/border-radius-control/input-controls.js +11 -4
  219. package/build-module/components/border-radius-control/input-controls.js.map +1 -1
  220. package/build-module/components/color-style-selector/index.js +6 -0
  221. package/build-module/components/color-style-selector/index.js.map +1 -1
  222. package/build-module/components/colors-gradients/dropdown.js +124 -43
  223. package/build-module/components/colors-gradients/dropdown.js.map +1 -1
  224. package/build-module/components/colors-gradients/panel-color-gradient-settings.js +36 -64
  225. package/build-module/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  226. package/build-module/components/convert-to-group-buttons/toolbar.js +23 -6
  227. package/build-module/components/convert-to-group-buttons/toolbar.js.map +1 -1
  228. package/build-module/components/iframe/index.js +52 -51
  229. package/build-module/components/iframe/index.js.map +1 -1
  230. package/build-module/components/image-editor/use-save-image.js +2 -1
  231. package/build-module/components/image-editor/use-save-image.js.map +1 -1
  232. package/build-module/components/index.js +2 -3
  233. package/build-module/components/index.js.map +1 -1
  234. package/build-module/components/inserter/index.js +21 -7
  235. package/build-module/components/inserter/index.js.map +1 -1
  236. package/build-module/components/inserter/index.native.js +2 -2
  237. package/build-module/components/inserter/index.native.js.map +1 -1
  238. package/build-module/components/inserter/quick-inserter.js +4 -5
  239. package/build-module/components/inserter/quick-inserter.js.map +1 -1
  240. package/build-module/components/link-control/constants.js +5 -0
  241. package/build-module/components/link-control/constants.js.map +1 -1
  242. package/build-module/components/link-control/search-results.js +3 -4
  243. package/build-module/components/link-control/search-results.js.map +1 -1
  244. package/build-module/components/link-control/use-search-handler.js +5 -5
  245. package/build-module/components/link-control/use-search-handler.js.map +1 -1
  246. package/build-module/components/list-view/block.js +15 -16
  247. package/build-module/components/list-view/block.js.map +1 -1
  248. package/build-module/components/list-view/branch.js +9 -13
  249. package/build-module/components/list-view/branch.js.map +1 -1
  250. package/build-module/components/list-view/context.js +1 -4
  251. package/build-module/components/list-view/context.js.map +1 -1
  252. package/build-module/components/list-view/drop-indicator.js +0 -1
  253. package/build-module/components/list-view/drop-indicator.js.map +1 -1
  254. package/build-module/components/list-view/index.js +15 -31
  255. package/build-module/components/list-view/index.js.map +1 -1
  256. package/build-module/components/media-placeholder/index.js +0 -2
  257. package/build-module/components/media-placeholder/index.js.map +1 -1
  258. package/build-module/components/media-replace-flow/index.js +0 -2
  259. package/build-module/components/media-replace-flow/index.js.map +1 -1
  260. package/build-module/components/media-upload/index.native.js +8 -3
  261. package/build-module/components/media-upload/index.native.js.map +1 -1
  262. package/build-module/components/navigable-toolbar/index.js +12 -2
  263. package/build-module/components/navigable-toolbar/index.js.map +1 -1
  264. package/build-module/components/plain-text/index.native.js +63 -8
  265. package/build-module/components/plain-text/index.native.js.map +1 -1
  266. package/build-module/components/publish-date-time-picker/index.js +42 -0
  267. package/build-module/components/publish-date-time-picker/index.js.map +1 -0
  268. package/build-module/components/rich-text/format-toolbar-container.js +0 -1
  269. package/build-module/components/rich-text/format-toolbar-container.js.map +1 -1
  270. package/build-module/components/rich-text/index.js +2 -2
  271. package/build-module/components/rich-text/index.js.map +1 -1
  272. package/build-module/components/rich-text/index.native.js +5 -1
  273. package/build-module/components/rich-text/index.native.js.map +1 -1
  274. package/build-module/components/url-input/index.js +11 -4
  275. package/build-module/components/url-input/index.js.map +1 -1
  276. package/build-module/components/use-block-drop-zone/index.native.js +148 -0
  277. package/build-module/components/use-block-drop-zone/index.native.js.map +1 -0
  278. package/build-module/components/use-on-block-drop/index.native.js +83 -0
  279. package/build-module/components/use-on-block-drop/index.native.js.map +1 -0
  280. package/build-module/components/use-setting/index.js +43 -19
  281. package/build-module/components/use-setting/index.js.map +1 -1
  282. package/build-module/components/warning/index.js +6 -1
  283. package/build-module/components/warning/index.js.map +1 -1
  284. package/build-module/components/writing-flow/use-click-selection.js +1 -3
  285. package/build-module/components/writing-flow/use-click-selection.js.map +1 -1
  286. package/build-module/components/writing-flow/use-input.js +15 -0
  287. package/build-module/components/writing-flow/use-input.js.map +1 -1
  288. package/build-module/components/writing-flow/use-selection-observer.js +49 -8
  289. package/build-module/components/writing-flow/use-selection-observer.js.map +1 -1
  290. package/build-module/elements/index.js +2 -0
  291. package/build-module/elements/index.js.map +1 -0
  292. package/build-module/hooks/anchor.js.map +1 -1
  293. package/build-module/hooks/border.js +2 -7
  294. package/build-module/hooks/border.js.map +1 -1
  295. package/build-module/hooks/color-panel.js +11 -6
  296. package/build-module/hooks/color-panel.js.map +1 -1
  297. package/build-module/hooks/color.js +8 -88
  298. package/build-module/hooks/color.js.map +1 -1
  299. package/build-module/hooks/dimensions.js +19 -9
  300. package/build-module/hooks/dimensions.js.map +1 -1
  301. package/build-module/hooks/index.js +1 -0
  302. package/build-module/hooks/index.js.map +1 -1
  303. package/build-module/hooks/margin.js +61 -13
  304. package/build-module/hooks/margin.js.map +1 -1
  305. package/build-module/hooks/padding.js +57 -13
  306. package/build-module/hooks/padding.js.map +1 -1
  307. package/build-module/hooks/settings.js +29 -0
  308. package/build-module/hooks/settings.js.map +1 -0
  309. package/build-module/hooks/style.js +15 -14
  310. package/build-module/hooks/style.js.map +1 -1
  311. package/build-module/hooks/typography.js +6 -2
  312. package/build-module/hooks/typography.js.map +1 -1
  313. package/build-module/index.js +1 -0
  314. package/build-module/index.js.map +1 -1
  315. package/build-module/layouts/flex.js +4 -2
  316. package/build-module/layouts/flex.js.map +1 -1
  317. package/build-module/store/actions.js +12 -0
  318. package/build-module/store/actions.js.map +1 -1
  319. package/build-module/store/defaults.js +0 -1
  320. package/build-module/store/defaults.js.map +1 -1
  321. package/build-module/store/reducer.js +17 -2
  322. package/build-module/store/reducer.js.map +1 -1
  323. package/build-module/store/selectors.js +37 -12
  324. package/build-module/store/selectors.js.map +1 -1
  325. package/build-style/style-rtl.css +100 -225
  326. package/build-style/style.css +100 -225
  327. package/package.json +30 -30
  328. package/src/components/block-alignment-control/constants.js +45 -0
  329. package/src/components/block-alignment-control/ui.js +69 -109
  330. package/src/components/block-alignment-control/ui.native.js +86 -0
  331. package/src/components/block-alignment-matrix-control/index.js +1 -5
  332. package/src/components/block-content-overlay/index.js +8 -95
  333. package/src/components/block-content-overlay/style.scss +2 -12
  334. package/src/components/block-draggable/draggable-chip.native.js +49 -0
  335. package/src/components/block-draggable/dropping-insertion-point.native.js +181 -0
  336. package/src/components/block-draggable/dropping-insertion-point.native.scss +8 -0
  337. package/src/components/block-draggable/index.native.js +462 -0
  338. package/src/components/block-draggable/style.native.scss +19 -0
  339. package/src/components/block-draggable/test/__snapshots__/index.native.js.snap +73 -0
  340. package/src/components/block-draggable/test/helpers.native.js +183 -0
  341. package/src/components/block-draggable/test/index.native.js +496 -0
  342. package/src/components/block-draggable/use-scroll-when-dragging.native.js +135 -0
  343. package/src/components/block-list/block-list-context.native.js +175 -0
  344. package/src/components/block-list/block-list-item-cell.native.js +49 -0
  345. package/src/components/block-list/block-list-item.native.js +7 -11
  346. package/src/components/block-list/block.native.js +37 -8
  347. package/src/components/block-list/index.js +44 -44
  348. package/src/components/block-list/index.native.js +54 -13
  349. package/src/components/block-list/style.scss +7 -18
  350. package/src/components/block-list/test/block-list-context.native.js +253 -0
  351. package/src/components/block-list/test/fixtures/block-list-context.native.js +79 -0
  352. package/src/components/block-list/use-block-props/index.js +10 -5
  353. package/src/components/block-list/use-block-props/use-block-class-names.js +1 -11
  354. package/src/components/block-list/use-in-between-inserter.js +1 -1
  355. package/src/components/block-mobile-toolbar/index.native.js +9 -1
  356. package/src/components/block-mover/index.native.js +22 -6
  357. package/src/components/block-mover/test/__snapshots__/index.native.js.snap +10 -0
  358. package/src/components/block-navigation/dropdown.js +12 -8
  359. package/src/components/block-popover/inbetween.js +21 -8
  360. package/src/components/block-popover/index.js +18 -15
  361. package/src/components/block-popover/style.scss +4 -0
  362. package/src/components/block-preview/index.js +1 -4
  363. package/src/components/block-switcher/style.scss +2 -39
  364. package/src/components/block-tools/block-selection-button.js +1 -0
  365. package/src/components/block-tools/selected-block-popover.js +1 -36
  366. package/src/components/block-tools/style.scss +1 -12
  367. package/src/components/block-variation-transforms/index.js +6 -2
  368. package/src/components/border-radius-control/input-controls.js +16 -8
  369. package/src/components/border-radius-control/style.scss +3 -2
  370. package/src/components/color-palette/test/__snapshots__/control.js.snap +1 -1
  371. package/src/components/color-style-selector/index.js +18 -9
  372. package/src/components/colors-gradients/dropdown.js +130 -62
  373. package/src/components/colors-gradients/panel-color-gradient-settings.js +30 -76
  374. package/src/components/colors-gradients/style.scss +52 -50
  375. package/src/components/convert-to-group-buttons/toolbar.js +30 -13
  376. package/src/components/duotone-control/style.scss +1 -7
  377. package/src/components/iframe/index.js +62 -54
  378. package/src/components/image-editor/use-save-image.js +2 -1
  379. package/src/components/image-size-control/README.md +1 -1
  380. package/src/components/index.js +2 -3
  381. package/src/components/inserter/index.js +20 -0
  382. package/src/components/inserter/index.native.js +2 -2
  383. package/src/components/inserter/quick-inserter.js +3 -11
  384. package/src/components/inserter/style.native.scss +1 -0
  385. package/src/components/inserter/style.scss +2 -1
  386. package/src/components/link-control/constants.js +11 -0
  387. package/src/components/link-control/search-results.js +4 -5
  388. package/src/components/link-control/use-search-handler.js +11 -5
  389. package/src/components/list-view/block.js +24 -34
  390. package/src/components/list-view/branch.js +10 -20
  391. package/src/components/list-view/context.js +1 -4
  392. package/src/components/list-view/drop-indicator.js +0 -1
  393. package/src/components/list-view/index.js +11 -41
  394. package/src/components/list-view/style.scss +2 -1
  395. package/src/components/media-placeholder/index.js +0 -2
  396. package/src/components/media-replace-flow/index.js +0 -2
  397. package/src/components/media-upload/index.native.js +6 -2
  398. package/src/components/media-upload/test/index.native.js +31 -6
  399. package/src/components/navigable-toolbar/index.js +12 -2
  400. package/src/components/plain-text/index.native.js +64 -8
  401. package/src/components/preview-options/style.scss +0 -4
  402. package/src/components/publish-date-time-picker/README.md +52 -0
  403. package/src/components/publish-date-time-picker/index.js +50 -0
  404. package/src/components/publish-date-time-picker/style.scss +20 -0
  405. package/src/components/rich-text/format-toolbar-container.js +0 -1
  406. package/src/components/rich-text/index.js +3 -1
  407. package/src/components/rich-text/index.native.js +4 -0
  408. package/src/components/rich-text/style.scss +2 -8
  409. package/src/components/url-input/index.js +9 -4
  410. package/src/components/use-block-drop-zone/index.native.js +173 -0
  411. package/src/components/use-on-block-drop/index.native.js +119 -0
  412. package/src/components/use-setting/index.js +57 -21
  413. package/src/components/warning/index.js +47 -42
  414. package/src/components/warning/test/__snapshots__/index.js.snap +15 -6
  415. package/src/components/warning/test/index.js +1 -1
  416. package/src/components/writing-flow/use-click-selection.js +1 -4
  417. package/src/components/writing-flow/use-input.js +12 -0
  418. package/src/components/writing-flow/use-selection-observer.js +55 -10
  419. package/src/elements/index.js +1 -0
  420. package/src/hooks/anchor.js +1 -1
  421. package/src/hooks/border.js +2 -11
  422. package/src/hooks/border.scss +0 -48
  423. package/src/hooks/color-panel.js +13 -9
  424. package/src/hooks/color.js +5 -74
  425. package/src/hooks/color.scss +5 -58
  426. package/src/hooks/dimensions.js +55 -41
  427. package/src/hooks/index.js +1 -0
  428. package/src/hooks/margin.js +64 -15
  429. package/src/hooks/padding.js +60 -15
  430. package/src/hooks/padding.scss +12 -0
  431. package/src/hooks/settings.js +32 -0
  432. package/src/hooks/style.js +25 -39
  433. package/src/hooks/test/settings.js +48 -0
  434. package/src/hooks/typography.js +2 -0
  435. package/src/index.js +1 -0
  436. package/src/layouts/flex.js +11 -3
  437. package/src/store/actions.js +12 -0
  438. package/src/store/defaults.js +0 -1
  439. package/src/store/reducer.js +14 -1
  440. package/src/store/selectors.js +42 -12
  441. package/src/store/test/reducer.js +5 -0
  442. package/src/store/test/selectors.js +17 -0
  443. package/src/style.scss +2 -2
  444. package/tsconfig.tsbuildinfo +1 -1
  445. package/build/components/border-style-control/index.js +0 -60
  446. package/build/components/border-style-control/index.js.map +0 -1
  447. package/build/components/colors/color-panel.js +0 -82
  448. package/build/components/colors/color-panel.js.map +0 -1
  449. package/build/components/colors/color-panel.native.js +0 -11
  450. package/build/components/colors/color-panel.native.js.map +0 -1
  451. package/build/components/colors-gradients/tools-panel-color-dropdown.js +0 -89
  452. package/build/components/colors-gradients/tools-panel-color-dropdown.js.map +0 -1
  453. package/build-module/components/border-style-control/index.js +0 -50
  454. package/build-module/components/border-style-control/index.js.map +0 -1
  455. package/build-module/components/colors/color-panel.js +0 -70
  456. package/build-module/components/colors/color-panel.js.map +0 -1
  457. package/build-module/components/colors/color-panel.native.js +0 -4
  458. package/build-module/components/colors/color-panel.native.js.map +0 -1
  459. package/build-module/components/colors-gradients/tools-panel-color-dropdown.js +0 -75
  460. package/build-module/components/colors-gradients/tools-panel-color-dropdown.js.map +0 -1
  461. package/src/components/block-alignment-matrix-control/style.scss +0 -10
  462. package/src/components/border-style-control/index.js +0 -47
  463. package/src/components/border-style-control/style.scss +0 -18
  464. package/src/components/colors/color-panel.js +0 -91
  465. package/src/components/colors/color-panel.native.js +0 -3
  466. package/src/components/colors-gradients/tools-panel-color-dropdown.js +0 -85
@@ -76,36 +76,81 @@ export default function useSelectionObserver() {
76
76
  const { multiSelect, selectBlock, selectionChange } = useDispatch(
77
77
  blockEditorStore
78
78
  );
79
- const { getBlockParents } = useSelect( blockEditorStore );
79
+ const { getBlockParents, getBlockSelectionStart } = useSelect(
80
+ blockEditorStore
81
+ );
80
82
  return useRefEffect(
81
83
  ( node ) => {
82
84
  const { ownerDocument } = node;
83
85
  const { defaultView } = ownerDocument;
84
86
 
85
- function onSelectionChange() {
87
+ function onSelectionChange( event ) {
86
88
  const selection = defaultView.getSelection();
87
-
88
89
  // If no selection is found, end multi selection and disable the
89
90
  // contentEditable wrapper.
90
- if ( ! selection.rangeCount || selection.isCollapsed ) {
91
+ if ( ! selection.rangeCount ) {
92
+ setContentEditableWrapper( node, false );
93
+ return;
94
+ }
95
+ // If selection is collapsed and we haven't used `shift+click`,
96
+ // end multi selection and disable the contentEditable wrapper.
97
+ // We have to check about `shift+click` case because elements
98
+ // that don't support text selection might be involved, and we might
99
+ // update the clientIds to multi-select blocks.
100
+ // For now we check if the event is a `mouse` event.
101
+ const isClickShift = event.shiftKey && event.type === 'mouseup';
102
+ if ( selection.isCollapsed && ! isClickShift ) {
91
103
  setContentEditableWrapper( node, false );
92
104
  return;
93
105
  }
94
106
 
95
- const clientId = getBlockClientId(
107
+ let startClientId = getBlockClientId(
96
108
  extractSelectionStartNode( selection )
97
109
  );
98
- const endClientId = getBlockClientId(
110
+ let endClientId = getBlockClientId(
99
111
  extractSelectionEndNode( selection )
100
112
  );
101
- const isSingularSelection = clientId === endClientId;
113
+ // If the selection has changed and we had pressed `shift+click`,
114
+ // we need to check if in an element that doesn't support
115
+ // text selection has been clicked.
116
+ if ( isClickShift ) {
117
+ const selectedClientId = getBlockSelectionStart();
118
+ const clickedClientId = getBlockClientId( event.target );
119
+ // `endClientId` is not defined if we end the selection by clicking a non-selectable block.
120
+ // We need to check if there was already a selection with a non-selectable focusNode.
121
+ const focusNodeIsNonSelectable =
122
+ clickedClientId !== endClientId;
123
+ if (
124
+ ( startClientId === endClientId &&
125
+ selection.isCollapsed ) ||
126
+ ! endClientId ||
127
+ focusNodeIsNonSelectable
128
+ ) {
129
+ endClientId = clickedClientId;
130
+ }
131
+ // Handle the case when we have a non-selectable block
132
+ // selected and click another one.
133
+ if ( startClientId !== selectedClientId ) {
134
+ startClientId = selectedClientId;
135
+ }
136
+ }
137
+
138
+ // If the selection did not involve a block, return.
139
+ if (
140
+ startClientId === undefined &&
141
+ endClientId === undefined
142
+ ) {
143
+ setContentEditableWrapper( node, false );
144
+ return;
145
+ }
102
146
 
147
+ const isSingularSelection = startClientId === endClientId;
103
148
  if ( isSingularSelection ) {
104
- selectBlock( clientId );
149
+ selectBlock( startClientId );
105
150
  } else {
106
151
  const startPath = [
107
- ...getBlockParents( clientId ),
108
- clientId,
152
+ ...getBlockParents( startClientId ),
153
+ startClientId,
109
154
  ];
110
155
  const endPath = [
111
156
  ...getBlockParents( endClientId ),
@@ -0,0 +1 @@
1
+ export const __experimentalElementButtonClassName = 'wp-element-button';
@@ -117,7 +117,7 @@ export const withInspectorControl = createHigherOrderComponent(
117
117
  * We plan to remove scoping anchors to 'core/heading' to support
118
118
  * anchors for all eligble blocks. Additionally we plan to explore
119
119
  * leveraging InspectorAdvancedControls instead of a custom
120
- * PanelBody title. https://git.io/Jtcov
120
+ * PanelBody title. https://github.com/WordPress/gutenberg/issues/28363
121
121
  */ }
122
122
  { ! isWeb && props.name === 'core/heading' && (
123
123
  <InspectorControls>
@@ -269,17 +269,8 @@ export function BorderPanel( props ) {
269
269
  colors={ colors }
270
270
  enableAlpha={ true }
271
271
  onChange={ onBorderChange }
272
- popoverClassNames={ {
273
- linked: 'block-editor__border-box-control__popover',
274
- top:
275
- 'block-editor__border-box-control__popover-top',
276
- right:
277
- 'block-editor__border-box-control__popover-right',
278
- bottom:
279
- 'block-editor__border-box-control__popover-bottom',
280
- left:
281
- 'block-editor__border-box-control__popover-left',
282
- } }
272
+ popoverPlacement="left-start"
273
+ popoverOffset={ 40 }
283
274
  showStyle={ isStyleSupported }
284
275
  value={ hydratedBorder }
285
276
  __experimentalHasMultipleOrigins={ true }
@@ -3,51 +3,3 @@
3
3
  grid-column: span 1;
4
4
  }
5
5
  }
6
-
7
- .block-editor__border-box-control__popover,
8
- .block-editor__border-box-control__popover-top,
9
- .block-editor__border-box-control__popover-right,
10
- .block-editor__border-box-control__popover-bottom,
11
- .block-editor__border-box-control__popover-left {
12
- .components-popover__content {
13
- width: 282px;
14
- }
15
- }
16
-
17
- $split-border-control-offset: 55px;
18
-
19
- @include break-medium() {
20
- .block-editor__border-box-control__popover,
21
- .block-editor__border-box-control__popover-left {
22
- .components-popover__content {
23
- margin-right: #{ $grid-unit-50 + $grid-unit-15 } !important;
24
- }
25
- }
26
-
27
- .block-editor__border-box-control__popover-top,
28
- .block-editor__border-box-control__popover-bottom {
29
- .components-popover__content {
30
- margin-right: #{ $grid-unit-50 + $grid-unit-15 + $split-border-control-offset } !important;
31
- }
32
- }
33
-
34
- .block-editor__border-box-control__popover-right {
35
- .components-popover__content {
36
- margin-right: #{ $grid-unit-50 + $grid-unit-15 + ( $split-border-control-offset * 2 )} !important;
37
- }
38
- }
39
-
40
- .block-editor__border-box-control__popover,
41
- .block-editor__border-box-control__popover-top,
42
- .block-editor__border-box-control__popover-right,
43
- .block-editor__border-box-control__popover-bottom,
44
- .block-editor__border-box-control__popover-left {
45
- &.is-from-top .components-popover__content {
46
- margin-top: #{ -($grid-unit-50 + $grid-unit-15) } !important;
47
- }
48
-
49
- &.is-from-bottom .components-popover__content {
50
- margin-bottom: #{ -($grid-unit-50 + $grid-unit-15) } !important;
51
- }
52
- }
53
- }
@@ -6,9 +6,10 @@ import { useState, useEffect } from '@wordpress/element';
6
6
  /**
7
7
  * Internal dependencies
8
8
  */
9
+ import ColorGradientSettingsDropdown from '../components/colors-gradients/dropdown';
9
10
  import ContrastChecker from '../components/contrast-checker';
10
- import ToolsPanelColorDropdown from '../components/colors-gradients/tools-panel-color-dropdown';
11
11
  import InspectorControls from '../components/inspector-controls';
12
+ import useMultipleOriginColorsAndGradients from '../components/colors-gradients/use-multiple-origin-colors-and-gradients';
12
13
  import { __unstableUseBlockRef as useBlockRef } from '../components/block-list/use-block-props/use-block-refs';
13
14
 
14
15
  function getComputedStyle( node ) {
@@ -58,16 +59,19 @@ export default function ColorPanel( {
58
59
  setDetectedBackgroundColor( backgroundColor );
59
60
  } );
60
61
 
62
+ const colorGradientSettings = useMultipleOriginColorsAndGradients();
63
+
61
64
  return (
62
65
  <InspectorControls __experimentalGroup="color">
63
- { settings.map( ( setting, index ) => (
64
- <ToolsPanelColorDropdown
65
- key={ index }
66
- settings={ setting }
67
- panelId={ clientId }
68
- enableAlpha={ enableAlpha }
69
- />
70
- ) ) }
66
+ <ColorGradientSettingsDropdown
67
+ enableAlpha={ enableAlpha }
68
+ panelId={ clientId }
69
+ settings={ settings }
70
+ __experimentalIsItemGroup={ false }
71
+ __experimentalHasMultipleOrigins
72
+ __experimentalIsRenderedInSidebar
73
+ { ...colorGradientSettings }
74
+ />
71
75
  { enableContrastChecking && (
72
76
  <ContrastChecker
73
77
  backgroundColor={ detectedBackgroundColor }
@@ -76,34 +76,6 @@ const hasTextColorSupport = ( blockType ) => {
76
76
  return colorSupport && colorSupport.text !== false;
77
77
  };
78
78
 
79
- /**
80
- * Checks whether a color has been set either with a named preset color in
81
- * a top level block attribute or as a custom value within the style attribute
82
- * object.
83
- *
84
- * @param {string} name Name of the color to check.
85
- * @return {boolean} Whether or not a color has a value.
86
- */
87
- const hasColor = ( name ) => ( props ) => {
88
- if ( name === 'background' ) {
89
- return (
90
- !! props.attributes.backgroundColor ||
91
- !! props.attributes.style?.color?.background ||
92
- !! props.attributes.gradient ||
93
- !! props.attributes.style?.color?.gradient
94
- );
95
- }
96
-
97
- if ( name === 'link' ) {
98
- return !! props.attributes.style?.elements?.link?.color?.text;
99
- }
100
-
101
- return (
102
- !! props.attributes[ `${ name }Color` ] ||
103
- !! props.attributes.style?.color?.[ name ]
104
- );
105
- };
106
-
107
79
  /**
108
80
  * Clears a single color property from a style object.
109
81
  *
@@ -114,20 +86,6 @@ const hasColor = ( name ) => ( props ) => {
114
86
  const clearColorFromStyles = ( path, style ) =>
115
87
  cleanEmptyObject( immutableSet( style, path, undefined ) );
116
88
 
117
- /**
118
- * Resets the block attributes for text color.
119
- *
120
- * @param {Object} props Current block props.
121
- * @param {Object} props.attributes Block attributes.
122
- * @param {Function} props.setAttributes Block's setAttributes prop used to apply reset.
123
- */
124
- const resetTextColor = ( { attributes, setAttributes } ) => {
125
- setAttributes( {
126
- textColor: undefined,
127
- style: clearColorFromStyles( [ 'color', 'text' ], attributes.style ),
128
- } );
129
- };
130
-
131
89
  /**
132
90
  * Clears text color related properties from supplied attributes.
133
91
  *
@@ -139,18 +97,6 @@ const resetAllTextFilter = ( attributes ) => ( {
139
97
  style: clearColorFromStyles( [ 'color', 'text' ], attributes.style ),
140
98
  } );
141
99
 
142
- /**
143
- * Resets the block attributes for link color.
144
- *
145
- * @param {Object} props Current block props.
146
- * @param {Object} props.attributes Block attributes.
147
- * @param {Function} props.setAttributes Block's setAttributes prop used to apply reset.
148
- */
149
- const resetLinkColor = ( { attributes, setAttributes } ) => {
150
- const path = [ 'elements', 'link', 'color', 'text' ];
151
- setAttributes( { style: clearColorFromStyles( path, attributes.style ) } );
152
- };
153
-
154
100
  /**
155
101
  * Clears link color related properties from supplied attributes.
156
102
  *
@@ -184,17 +130,6 @@ const clearBackgroundAndGradient = ( attributes ) => ( {
184
130
  },
185
131
  } );
186
132
 
187
- /**
188
- * Resets the block attributes for both background color and gradient.
189
- *
190
- * @param {Object} props Current block props.
191
- * @param {Object} props.attributes Block attributes.
192
- * @param {Function} props.setAttributes Block's setAttributes prop used to apply reset.
193
- */
194
- const resetBackgroundAndGradient = ( { attributes, setAttributes } ) => {
195
- setAttributes( clearBackgroundAndGradient( attributes ) );
196
- };
197
-
198
133
  /**
199
134
  * Filters registered block settings, extending attributes to include
200
135
  * `backgroundColor` and `textColor` attribute.
@@ -496,12 +431,16 @@ export function ColorEdit( props ) {
496
431
 
497
432
  const newStyle = cleanEmptyObject(
498
433
  immutableSet(
499
- style,
434
+ localAttributes.current?.style,
500
435
  [ 'elements', 'link', 'color', 'text' ],
501
436
  newLinkColorValue
502
437
  )
503
438
  );
504
439
  props.setAttributes( { style: newStyle } );
440
+ localAttributes.current = {
441
+ ...localAttributes.current,
442
+ ...{ style: newStyle },
443
+ };
505
444
  };
506
445
 
507
446
  const enableContrastChecking =
@@ -529,8 +468,6 @@ export function ColorEdit( props ) {
529
468
  style?.color?.text
530
469
  ).color,
531
470
  isShownByDefault: defaultColorControls?.text,
532
- hasValue: () => hasColor( 'text' )( props ),
533
- onDeselect: () => resetTextColor( props ),
534
471
  resetAllFilter: resetAllTextFilter,
535
472
  },
536
473
  ]
@@ -553,10 +490,6 @@ export function ColorEdit( props ) {
553
490
  : undefined,
554
491
  isShownByDefault:
555
492
  defaultColorControls?.background,
556
- hasValue: () =>
557
- hasColor( 'background' )( props ),
558
- onDeselect: () =>
559
- resetBackgroundAndGradient( props ),
560
493
  resetAllFilter: clearBackgroundAndGradient,
561
494
  },
562
495
  ]
@@ -573,8 +506,6 @@ export function ColorEdit( props ) {
573
506
  clearable: !! style?.elements?.link?.color
574
507
  ?.text,
575
508
  isShownByDefault: defaultColorControls?.link,
576
- hasValue: () => hasColor( 'link' )( props ),
577
- onDeselect: () => resetLinkColor( props ),
578
509
  resetAllFilter: resetAllLinkFilter,
579
510
  },
580
511
  ]
@@ -22,64 +22,11 @@
22
22
  }
23
23
 
24
24
  /**
25
- * The following styles replicate the separated border of the
26
- * `ItemGroup` component but allows for hidden items. This is because
27
- * to maintain the order of `ToolsPanel` controls, each `ToolsPanelItem`
28
- * must at least render a placeholder which would otherwise interfere
29
- * with the `:last-child` styles.
25
+ * After converting PanelColorGradientSettings to render as a ToolsPanel
26
+ * we need to remove the top margin when wrapping inner content due to
27
+ * rendering via SlotFills.
30
28
  */
31
- .block-editor-tools-panel-color-gradient-settings__item {
32
- padding: 0;
33
-
34
- // Border styles.
35
- border-left: 1px solid rgba(0, 0, 0, 0.1);
36
- border-right: 1px solid rgba(0, 0, 0, 0.1);
37
- border-bottom: 1px solid rgba(0, 0, 0, 0.1);
38
-
39
- &.first {
40
- border-top-left-radius: 2px;
41
- border-top-right-radius: 2px;
42
- border-top: 1px solid rgba(0, 0, 0, 0.1);
43
- }
44
-
45
- &.last {
46
- border-bottom-left-radius: 2px;
47
- border-bottom-right-radius: 2px;
48
- }
49
-
50
- > div,
51
- > div > button {
52
- border-radius: inherit;
53
- }
54
- }
55
-
56
- .block-editor-panel-color-gradient-settings__color-indicator {
57
- // Show a diagonal line (crossed out) for empty swatches.
58
- background: linear-gradient(-45deg, transparent 48%, $gray-300 48%, $gray-300 52%, transparent 52%);
59
- }
60
-
61
- /**
62
- * The following few styles fix the layout and spacing for the due to the
63
- * introduced wrapper element by the `Item` component.
64
- */
65
- .block-editor-tools-panel-color-dropdown {
66
- display: block;
67
- padding: 0;
68
-
69
- > button {
70
- height: 46px;
71
-
72
- &.is-open {
73
- background: $gray-100;
74
- color: var(--wp-admin-theme-color);
75
- }
76
- }
77
- }
78
-
79
- .color-block-support-panel__item-group {
80
- > div {
81
- grid-column: span 2;
82
- border-radius: inherit;
83
- }
29
+ .block-editor-tools-panel-color-gradient-settings__item.first {
30
+ margin-top: 0;
84
31
  }
85
32
  }
@@ -19,6 +19,7 @@ import {
19
19
  } from './gap';
20
20
  import {
21
21
  MarginEdit,
22
+ MarginVisualizer,
22
23
  hasMarginSupport,
23
24
  hasMarginValue,
24
25
  resetMargin,
@@ -26,6 +27,7 @@ import {
26
27
  } from './margin';
27
28
  import {
28
29
  PaddingEdit,
30
+ PaddingVisualizer,
29
31
  hasPaddingSupport,
30
32
  hasPaddingValue,
31
33
  resetPadding,
@@ -71,44 +73,48 @@ export function DimensionsPanel( props ) {
71
73
  } );
72
74
 
73
75
  return (
74
- <InspectorControls __experimentalGroup="dimensions">
75
- { ! isPaddingDisabled && (
76
- <ToolsPanelItem
77
- hasValue={ () => hasPaddingValue( props ) }
78
- label={ __( 'Padding' ) }
79
- onDeselect={ () => resetPadding( props ) }
80
- resetAllFilter={ createResetAllFilter( 'padding' ) }
81
- isShownByDefault={ defaultSpacingControls?.padding }
82
- panelId={ props.clientId }
83
- >
84
- <PaddingEdit { ...props } />
85
- </ToolsPanelItem>
86
- ) }
87
- { ! isMarginDisabled && (
88
- <ToolsPanelItem
89
- hasValue={ () => hasMarginValue( props ) }
90
- label={ __( 'Margin' ) }
91
- onDeselect={ () => resetMargin( props ) }
92
- resetAllFilter={ createResetAllFilter( 'margin' ) }
93
- isShownByDefault={ defaultSpacingControls?.margin }
94
- panelId={ props.clientId }
95
- >
96
- <MarginEdit { ...props } />
97
- </ToolsPanelItem>
98
- ) }
99
- { ! isGapDisabled && (
100
- <ToolsPanelItem
101
- hasValue={ () => hasGapValue( props ) }
102
- label={ __( 'Block spacing' ) }
103
- onDeselect={ () => resetGap( props ) }
104
- resetAllFilter={ createResetAllFilter( 'blockGap' ) }
105
- isShownByDefault={ defaultSpacingControls?.blockGap }
106
- panelId={ props.clientId }
107
- >
108
- <GapEdit { ...props } />
109
- </ToolsPanelItem>
110
- ) }
111
- </InspectorControls>
76
+ <>
77
+ <InspectorControls __experimentalGroup="dimensions">
78
+ { ! isPaddingDisabled && (
79
+ <ToolsPanelItem
80
+ hasValue={ () => hasPaddingValue( props ) }
81
+ label={ __( 'Padding' ) }
82
+ onDeselect={ () => resetPadding( props ) }
83
+ resetAllFilter={ createResetAllFilter( 'padding' ) }
84
+ isShownByDefault={ defaultSpacingControls?.padding }
85
+ panelId={ props.clientId }
86
+ >
87
+ <PaddingEdit { ...props } />
88
+ </ToolsPanelItem>
89
+ ) }
90
+ { ! isMarginDisabled && (
91
+ <ToolsPanelItem
92
+ hasValue={ () => hasMarginValue( props ) }
93
+ label={ __( 'Margin' ) }
94
+ onDeselect={ () => resetMargin( props ) }
95
+ resetAllFilter={ createResetAllFilter( 'margin' ) }
96
+ isShownByDefault={ defaultSpacingControls?.margin }
97
+ panelId={ props.clientId }
98
+ >
99
+ <MarginEdit { ...props } />
100
+ </ToolsPanelItem>
101
+ ) }
102
+ { ! isGapDisabled && (
103
+ <ToolsPanelItem
104
+ hasValue={ () => hasGapValue( props ) }
105
+ label={ __( 'Block spacing' ) }
106
+ onDeselect={ () => resetGap( props ) }
107
+ resetAllFilter={ createResetAllFilter( 'blockGap' ) }
108
+ isShownByDefault={ defaultSpacingControls?.blockGap }
109
+ panelId={ props.clientId }
110
+ >
111
+ <GapEdit { ...props } />
112
+ </ToolsPanelItem>
113
+ ) }
114
+ </InspectorControls>
115
+ { ! isPaddingDisabled && <PaddingVisualizer { ...props } /> }
116
+ { ! isMarginDisabled && <MarginVisualizer { ...props } /> }
117
+ </>
112
118
  );
113
119
  }
114
120
 
@@ -147,7 +153,7 @@ const useIsDimensionsDisabled = ( props = {} ) => {
147
153
  };
148
154
 
149
155
  /**
150
- * Custom hook to retrieve which padding/margin is supported
156
+ * Custom hook to retrieve which padding/margin/blockGap is supported
151
157
  * e.g. top, right, bottom or left.
152
158
  *
153
159
  * Sides are opted into by default. It is only if a specific side is set to
@@ -156,7 +162,7 @@ const useIsDimensionsDisabled = ( props = {} ) => {
156
162
  * @param {string} blockName Block name.
157
163
  * @param {string} feature The feature custom sides relate to e.g. padding or margins.
158
164
  *
159
- * @return {Object} Sides supporting custom margin.
165
+ * @return {?string[]} Strings representing the custom sides available.
160
166
  */
161
167
  export function useCustomSides( blockName, feature ) {
162
168
  const support = getBlockSupport( blockName, SPACING_SUPPORT_KEY );
@@ -166,7 +172,15 @@ export function useCustomSides( blockName, feature ) {
166
172
  return;
167
173
  }
168
174
 
169
- return support[ feature ];
175
+ // Return if the setting is an array of sides (e.g. `[ 'top', 'bottom' ]`).
176
+ if ( Array.isArray( support[ feature ] ) ) {
177
+ return support[ feature ];
178
+ }
179
+
180
+ // Finally, attempt to return `.sides` if the setting is an object.
181
+ if ( support[ feature ]?.sides ) {
182
+ return support[ feature ].sides;
183
+ }
170
184
  }
171
185
 
172
186
  /**
@@ -8,6 +8,7 @@ import './anchor';
8
8
  import './custom-class-name';
9
9
  import './generated-class-name';
10
10
  import './style';
11
+ import './settings';
11
12
  import './color';
12
13
  import './duotone';
13
14
  import './font-size';
@@ -2,12 +2,19 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
- import { Platform } from '@wordpress/element';
5
+ import {
6
+ Platform,
7
+ useMemo,
8
+ useRef,
9
+ useState,
10
+ useEffect,
11
+ } from '@wordpress/element';
6
12
  import { getBlockSupport } from '@wordpress/blocks';
7
13
  import {
8
14
  __experimentalUseCustomUnits as useCustomUnits,
9
15
  __experimentalBoxControl as BoxControl,
10
16
  } from '@wordpress/components';
17
+ import isShallowEqual from '@wordpress/is-shallow-equal';
11
18
 
12
19
  /**
13
20
  * Internal dependencies
@@ -20,6 +27,7 @@ import {
20
27
  useIsDimensionsSupportValid,
21
28
  } from './dimensions';
22
29
  import { cleanEmptyObject } from './utils';
30
+ import BlockPopover from '../components/block-popover';
23
31
 
24
32
  /**
25
33
  * Determines if there is margin support.
@@ -124,26 +132,12 @@ export function MarginEdit( props ) {
124
132
  } );
125
133
  };
126
134
 
127
- const onChangeShowVisualizer = ( next ) => {
128
- const newStyle = {
129
- ...style,
130
- visualizers: {
131
- margin: next,
132
- },
133
- };
134
-
135
- setAttributes( {
136
- style: cleanEmptyObject( newStyle ),
137
- } );
138
- };
139
-
140
135
  return Platform.select( {
141
136
  web: (
142
137
  <>
143
138
  <BoxControl
144
139
  values={ style?.spacing?.margin }
145
140
  onChange={ onChange }
146
- onChangeShowVisualizer={ onChangeShowVisualizer }
147
141
  label={ __( 'Margin' ) }
148
142
  sides={ sides }
149
143
  units={ units }
@@ -155,3 +149,58 @@ export function MarginEdit( props ) {
155
149
  native: null,
156
150
  } );
157
151
  }
152
+
153
+ export function MarginVisualizer( { clientId, attributes } ) {
154
+ const margin = attributes?.style?.spacing?.margin;
155
+ const style = useMemo( () => {
156
+ return {
157
+ borderTopWidth: margin?.top ?? 0,
158
+ borderRightWidth: margin?.right ?? 0,
159
+ borderBottomWidth: margin?.bottom ?? 0,
160
+ borderLeftWidth: margin?.left ?? 0,
161
+ top: margin?.top ? `-${ margin.top }` : 0,
162
+ right: margin?.right ? `-${ margin.right }` : 0,
163
+ bottom: margin?.bottom ? `-${ margin.bottom }` : 0,
164
+ left: margin?.left ? `-${ margin.left }` : 0,
165
+ };
166
+ }, [ margin ] );
167
+
168
+ const [ isActive, setIsActive ] = useState( false );
169
+ const valueRef = useRef( margin );
170
+ const timeoutRef = useRef();
171
+
172
+ const clearTimer = () => {
173
+ if ( timeoutRef.current ) {
174
+ window.clearTimeout( timeoutRef.current );
175
+ }
176
+ };
177
+
178
+ useEffect( () => {
179
+ if ( ! isShallowEqual( margin, valueRef.current ) ) {
180
+ setIsActive( true );
181
+ valueRef.current = margin;
182
+
183
+ clearTimer();
184
+
185
+ timeoutRef.current = setTimeout( () => {
186
+ setIsActive( false );
187
+ }, 400 );
188
+ }
189
+
190
+ return () => clearTimer();
191
+ }, [ margin ] );
192
+
193
+ if ( ! isActive ) {
194
+ return null;
195
+ }
196
+
197
+ return (
198
+ <BlockPopover
199
+ clientId={ clientId }
200
+ __unstableCoverTarget
201
+ __unstableRefreshSize={ margin }
202
+ >
203
+ <div className="block-editor__padding-visualizer" style={ style } />
204
+ </BlockPopover>
205
+ );
206
+ }