@wordpress/block-editor 11.6.0 → 11.8.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 (350) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +46 -55
  3. package/build/components/block-list/block-html.js +1 -3
  4. package/build/components/block-list/block-html.js.map +1 -1
  5. package/build/components/block-list/block.native.js +4 -3
  6. package/build/components/block-list/block.native.js.map +1 -1
  7. package/build/components/block-list/index.native.js +11 -21
  8. package/build/components/block-list/index.native.js.map +1 -1
  9. package/build/components/block-list/use-in-between-inserter.js +3 -1
  10. package/build/components/block-list/use-in-between-inserter.js.map +1 -1
  11. package/build/components/block-popover/inbetween.js +2 -9
  12. package/build/components/block-popover/inbetween.js.map +1 -1
  13. package/build/components/block-preview/auto.js +6 -23
  14. package/build/components/block-preview/auto.js.map +1 -1
  15. package/build/components/block-settings-menu/block-settings-dropdown.js +1 -10
  16. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  17. package/build/components/caption/index.native.js +0 -1
  18. package/build/components/caption/index.native.js.map +1 -1
  19. package/build/components/date-format-picker/index.js +1 -1
  20. package/build/components/date-format-picker/index.js.map +1 -1
  21. package/build/components/editor-styles/index.js +20 -2
  22. package/build/components/editor-styles/index.js.map +1 -1
  23. package/build/components/global-styles/border-panel.js +15 -29
  24. package/build/components/global-styles/border-panel.js.map +1 -1
  25. package/build/components/global-styles/color-panel.js +583 -0
  26. package/build/components/global-styles/color-panel.js.map +1 -0
  27. package/build/components/global-styles/dimensions-panel.js +23 -44
  28. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  29. package/build/components/global-styles/effects-panel.js +244 -0
  30. package/build/components/global-styles/effects-panel.js.map +1 -0
  31. package/build/components/global-styles/filters-panel.js +151 -0
  32. package/build/components/global-styles/filters-panel.js.map +1 -0
  33. package/build/components/global-styles/get-block-css-selector.js +118 -0
  34. package/build/components/global-styles/get-block-css-selector.js.map +1 -0
  35. package/build/components/global-styles/hooks.js +60 -1
  36. package/build/components/global-styles/hooks.js.map +1 -1
  37. package/build/components/global-styles/index.js +46 -2
  38. package/build/components/global-styles/index.js.map +1 -1
  39. package/build/components/global-styles/typography-panel.js +9 -35
  40. package/build/components/global-styles/typography-panel.js.map +1 -1
  41. package/build/components/global-styles/use-global-styles-output.js +173 -91
  42. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  43. package/build/components/global-styles/utils.js +2 -1
  44. package/build/components/global-styles/utils.js.map +1 -1
  45. package/build/components/iframe/index.js +1 -1
  46. package/build/components/iframe/index.js.map +1 -1
  47. package/build/components/image-size-control/index.js +8 -5
  48. package/build/components/image-size-control/index.js.map +1 -1
  49. package/build/components/image-size-control/use-dimension-handler.js +5 -3
  50. package/build/components/image-size-control/use-dimension-handler.js.map +1 -1
  51. package/build/components/index.js +16 -0
  52. package/build/components/index.js.map +1 -1
  53. package/build/components/inserter/block-patterns-tab.js +4 -2
  54. package/build/components/inserter/block-patterns-tab.js.map +1 -1
  55. package/build/components/inspector-controls-tabs/position-controls-panel.js +43 -7
  56. package/build/components/inspector-controls-tabs/position-controls-panel.js.map +1 -1
  57. package/build/components/inspector-controls-tabs/utils.js +5 -3
  58. package/build/components/inspector-controls-tabs/utils.js.map +1 -1
  59. package/build/components/line-height-control/index.js +15 -1
  60. package/build/components/line-height-control/index.js.map +1 -1
  61. package/build/components/list-view/appender.js +105 -0
  62. package/build/components/list-view/appender.js.map +1 -0
  63. package/build/components/list-view/block.js +6 -5
  64. package/build/components/list-view/block.js.map +1 -1
  65. package/build/components/list-view/branch.js +25 -5
  66. package/build/components/list-view/branch.js.map +1 -1
  67. package/build/components/list-view/index.js +56 -14
  68. package/build/components/list-view/index.js.map +1 -1
  69. package/build/components/list-view/use-list-view-client-ids.js +7 -3
  70. package/build/components/list-view/use-list-view-client-ids.js.map +1 -1
  71. package/build/components/list-view/use-list-view-drop-zone.js +8 -2
  72. package/build/components/list-view/use-list-view-drop-zone.js.map +1 -1
  73. package/build/components/media-replace-flow/index.js +13 -4
  74. package/build/components/media-replace-flow/index.js.map +1 -1
  75. package/build/components/off-canvas-editor/block-contents.js +6 -1
  76. package/build/components/off-canvas-editor/block-contents.js.map +1 -1
  77. package/build/components/off-canvas-editor/index.js +17 -14
  78. package/build/components/off-canvas-editor/index.js.map +1 -1
  79. package/build/components/resizable-box-popover/index.js +38 -0
  80. package/build/components/resizable-box-popover/index.js.map +1 -0
  81. package/build/components/rich-text/format-edit.js +2 -30
  82. package/build/components/rich-text/format-edit.js.map +1 -1
  83. package/build/components/rich-text/index.js +0 -1
  84. package/build/components/rich-text/index.js.map +1 -1
  85. package/build/components/rich-text/index.native.js +7 -11
  86. package/build/components/rich-text/index.native.js.map +1 -1
  87. package/build/components/spacing-sizes-control/spacing-input-control.js +8 -0
  88. package/build/components/spacing-sizes-control/spacing-input-control.js.map +1 -1
  89. package/build/components/writing-flow/use-input.js +4 -8
  90. package/build/components/writing-flow/use-input.js.map +1 -1
  91. package/build/hooks/anchor.js +1 -1
  92. package/build/hooks/anchor.js.map +1 -1
  93. package/build/hooks/border.js +1 -2
  94. package/build/hooks/border.js.map +1 -1
  95. package/build/hooks/color.js +92 -229
  96. package/build/hooks/color.js.map +1 -1
  97. package/build/hooks/content-lock-ui.js +4 -2
  98. package/build/hooks/content-lock-ui.js.map +1 -1
  99. package/build/hooks/{color-panel.js → contrast-checker.js} +11 -49
  100. package/build/hooks/contrast-checker.js.map +1 -0
  101. package/build/hooks/dimensions.js +0 -1
  102. package/build/hooks/dimensions.js.map +1 -1
  103. package/build/hooks/duotone.js +92 -64
  104. package/build/hooks/duotone.js.map +1 -1
  105. package/build/hooks/margin.js +27 -17
  106. package/build/hooks/margin.js.map +1 -1
  107. package/build/hooks/padding.js +19 -9
  108. package/build/hooks/padding.js.map +1 -1
  109. package/build/hooks/position.js +2 -2
  110. package/build/hooks/position.js.map +1 -1
  111. package/build/hooks/style.js +23 -26
  112. package/build/hooks/style.js.map +1 -1
  113. package/build/hooks/typography.js +0 -1
  114. package/build/hooks/typography.js.map +1 -1
  115. package/build/hooks/utils.js +28 -76
  116. package/build/hooks/utils.js.map +1 -1
  117. package/build/layouts/grid.js +165 -0
  118. package/build/layouts/grid.js.map +1 -0
  119. package/build/layouts/index.js +3 -1
  120. package/build/layouts/index.js.map +1 -1
  121. package/build/layouts/utils.js +3 -2
  122. package/build/layouts/utils.js.map +1 -1
  123. package/build/private-apis.js +7 -1
  124. package/build/private-apis.js.map +1 -1
  125. package/build/store/actions.js +1 -1
  126. package/build/store/actions.js.map +1 -1
  127. package/build/utils/object.js +76 -0
  128. package/build/utils/object.js.map +1 -0
  129. package/build-module/components/block-list/block-html.js +1 -3
  130. package/build-module/components/block-list/block-html.js.map +1 -1
  131. package/build-module/components/block-list/block.native.js +4 -3
  132. package/build-module/components/block-list/block.native.js.map +1 -1
  133. package/build-module/components/block-list/index.native.js +11 -19
  134. package/build-module/components/block-list/index.native.js.map +1 -1
  135. package/build-module/components/block-list/use-in-between-inserter.js +2 -1
  136. package/build-module/components/block-list/use-in-between-inserter.js.map +1 -1
  137. package/build-module/components/block-popover/inbetween.js +2 -9
  138. package/build-module/components/block-popover/inbetween.js.map +1 -1
  139. package/build-module/components/block-preview/auto.js +6 -22
  140. package/build-module/components/block-preview/auto.js.map +1 -1
  141. package/build-module/components/block-settings-menu/block-settings-dropdown.js +1 -9
  142. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  143. package/build-module/components/caption/index.native.js +0 -1
  144. package/build-module/components/caption/index.native.js.map +1 -1
  145. package/build-module/components/date-format-picker/index.js +1 -1
  146. package/build-module/components/date-format-picker/index.js.map +1 -1
  147. package/build-module/components/editor-styles/index.js +19 -2
  148. package/build-module/components/editor-styles/index.js.map +1 -1
  149. package/build-module/components/global-styles/border-panel.js +15 -29
  150. package/build-module/components/global-styles/border-panel.js.map +1 -1
  151. package/build-module/components/global-styles/color-panel.js +554 -0
  152. package/build-module/components/global-styles/color-panel.js.map +1 -0
  153. package/build-module/components/global-styles/dimensions-panel.js +22 -44
  154. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  155. package/build-module/components/global-styles/effects-panel.js +228 -0
  156. package/build-module/components/global-styles/effects-panel.js.map +1 -0
  157. package/build-module/components/global-styles/filters-panel.js +139 -0
  158. package/build-module/components/global-styles/filters-panel.js.map +1 -0
  159. package/build-module/components/global-styles/get-block-css-selector.js +109 -0
  160. package/build-module/components/global-styles/get-block-css-selector.js.map +1 -0
  161. package/build-module/components/global-styles/hooks.js +58 -1
  162. package/build-module/components/global-styles/hooks.js.map +1 -1
  163. package/build-module/components/global-styles/index.js +5 -1
  164. package/build-module/components/global-styles/index.js.map +1 -1
  165. package/build-module/components/global-styles/typography-panel.js +8 -35
  166. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  167. package/build-module/components/global-styles/use-global-styles-output.js +175 -93
  168. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  169. package/build-module/components/global-styles/utils.js +2 -1
  170. package/build-module/components/global-styles/utils.js.map +1 -1
  171. package/build-module/components/iframe/index.js +1 -1
  172. package/build-module/components/iframe/index.js.map +1 -1
  173. package/build-module/components/image-size-control/index.js +8 -5
  174. package/build-module/components/image-size-control/index.js.map +1 -1
  175. package/build-module/components/image-size-control/use-dimension-handler.js +5 -3
  176. package/build-module/components/image-size-control/use-dimension-handler.js.map +1 -1
  177. package/build-module/components/index.js +1 -0
  178. package/build-module/components/index.js.map +1 -1
  179. package/build-module/components/inserter/block-patterns-tab.js +5 -2
  180. package/build-module/components/inserter/block-patterns-tab.js.map +1 -1
  181. package/build-module/components/inspector-controls-tabs/position-controls-panel.js +42 -7
  182. package/build-module/components/inspector-controls-tabs/position-controls-panel.js.map +1 -1
  183. package/build-module/components/inspector-controls-tabs/utils.js +4 -3
  184. package/build-module/components/inspector-controls-tabs/utils.js.map +1 -1
  185. package/build-module/components/line-height-control/index.js +15 -1
  186. package/build-module/components/line-height-control/index.js.map +1 -1
  187. package/build-module/components/list-view/appender.js +88 -0
  188. package/build-module/components/list-view/appender.js.map +1 -0
  189. package/build-module/components/list-view/block.js +6 -4
  190. package/build-module/components/list-view/block.js.map +1 -1
  191. package/build-module/components/list-view/branch.js +22 -5
  192. package/build-module/components/list-view/branch.js.map +1 -1
  193. package/build-module/components/list-view/index.js +50 -13
  194. package/build-module/components/list-view/index.js.map +1 -1
  195. package/build-module/components/list-view/use-list-view-client-ids.js +7 -3
  196. package/build-module/components/list-view/use-list-view-client-ids.js.map +1 -1
  197. package/build-module/components/list-view/use-list-view-drop-zone.js +8 -4
  198. package/build-module/components/list-view/use-list-view-drop-zone.js.map +1 -1
  199. package/build-module/components/media-replace-flow/index.js +12 -4
  200. package/build-module/components/media-replace-flow/index.js.map +1 -1
  201. package/build-module/components/off-canvas-editor/block-contents.js +5 -1
  202. package/build-module/components/off-canvas-editor/block-contents.js.map +1 -1
  203. package/build-module/components/off-canvas-editor/index.js +17 -14
  204. package/build-module/components/off-canvas-editor/index.js.map +1 -1
  205. package/build-module/components/resizable-box-popover/index.js +26 -0
  206. package/build-module/components/resizable-box-popover/index.js.map +1 -0
  207. package/build-module/components/rich-text/format-edit.js +3 -31
  208. package/build-module/components/rich-text/format-edit.js.map +1 -1
  209. package/build-module/components/rich-text/index.js +0 -1
  210. package/build-module/components/rich-text/index.js.map +1 -1
  211. package/build-module/components/rich-text/index.native.js +7 -10
  212. package/build-module/components/rich-text/index.native.js.map +1 -1
  213. package/build-module/components/spacing-sizes-control/spacing-input-control.js +7 -0
  214. package/build-module/components/spacing-sizes-control/spacing-input-control.js.map +1 -1
  215. package/build-module/components/writing-flow/use-input.js +4 -8
  216. package/build-module/components/writing-flow/use-input.js.map +1 -1
  217. package/build-module/hooks/anchor.js +1 -1
  218. package/build-module/hooks/anchor.js.map +1 -1
  219. package/build-module/hooks/border.js +1 -2
  220. package/build-module/hooks/border.js.map +1 -1
  221. package/build-module/hooks/color.js +90 -232
  222. package/build-module/hooks/color.js.map +1 -1
  223. package/build-module/hooks/content-lock-ui.js +4 -2
  224. package/build-module/hooks/content-lock-ui.js.map +1 -1
  225. package/build-module/hooks/{color-panel.js → contrast-checker.js} +10 -44
  226. package/build-module/hooks/contrast-checker.js.map +1 -0
  227. package/build-module/hooks/dimensions.js +0 -1
  228. package/build-module/hooks/dimensions.js.map +1 -1
  229. package/build-module/hooks/duotone.js +91 -65
  230. package/build-module/hooks/duotone.js.map +1 -1
  231. package/build-module/hooks/margin.js +29 -18
  232. package/build-module/hooks/margin.js.map +1 -1
  233. package/build-module/hooks/padding.js +21 -10
  234. package/build-module/hooks/padding.js.map +1 -1
  235. package/build-module/hooks/position.js +3 -3
  236. package/build-module/hooks/position.js.map +1 -1
  237. package/build-module/hooks/style.js +23 -26
  238. package/build-module/hooks/style.js.map +1 -1
  239. package/build-module/hooks/typography.js +0 -1
  240. package/build-module/hooks/typography.js.map +1 -1
  241. package/build-module/hooks/utils.js +27 -74
  242. package/build-module/hooks/utils.js.map +1 -1
  243. package/build-module/layouts/grid.js +151 -0
  244. package/build-module/layouts/grid.js.map +1 -0
  245. package/build-module/layouts/index.js +2 -1
  246. package/build-module/layouts/index.js.map +1 -1
  247. package/build-module/layouts/utils.js +3 -2
  248. package/build-module/layouts/utils.js.map +1 -1
  249. package/build-module/private-apis.js +5 -1
  250. package/build-module/private-apis.js.map +1 -1
  251. package/build-module/store/actions.js +1 -1
  252. package/build-module/store/actions.js.map +1 -1
  253. package/build-module/utils/object.js +69 -0
  254. package/build-module/utils/object.js.map +1 -0
  255. package/build-style/style-rtl.css +77 -16
  256. package/build-style/style.css +77 -16
  257. package/package.json +31 -31
  258. package/src/components/block-draggable/content.scss +1 -1
  259. package/src/components/block-inspector/style.scss +6 -4
  260. package/src/components/block-list/block-html.js +1 -1
  261. package/src/components/block-list/block.native.js +3 -2
  262. package/src/components/block-list/index.native.js +19 -38
  263. package/src/components/block-list/use-in-between-inserter.js +4 -1
  264. package/src/components/block-popover/inbetween.js +2 -13
  265. package/src/components/block-preview/auto.js +2 -17
  266. package/src/components/block-settings-menu/block-settings-dropdown.js +2 -12
  267. package/src/components/caption/index.native.js +0 -1
  268. package/src/components/colors-gradients/style.scss +8 -8
  269. package/src/components/date-format-picker/index.js +1 -1
  270. package/src/components/editor-styles/index.js +29 -1
  271. package/src/components/global-styles/README.md +129 -16
  272. package/src/components/global-styles/border-panel.js +13 -32
  273. package/src/components/global-styles/color-panel.js +706 -0
  274. package/src/components/global-styles/dimensions-panel.js +43 -55
  275. package/src/components/global-styles/effects-panel.js +228 -0
  276. package/src/components/global-styles/filters-panel.js +157 -0
  277. package/src/components/global-styles/get-block-css-selector.js +118 -0
  278. package/src/components/global-styles/hooks.js +90 -0
  279. package/src/components/global-styles/index.js +4 -1
  280. package/src/components/global-styles/style.scss +42 -0
  281. package/src/components/global-styles/test/use-global-styles-output.js +34 -5
  282. package/src/components/global-styles/typography-panel.js +26 -51
  283. package/src/components/global-styles/use-global-styles-output.js +188 -89
  284. package/src/components/global-styles/utils.js +3 -0
  285. package/src/components/iframe/index.js +1 -1
  286. package/src/components/image-size-control/index.js +4 -3
  287. package/src/components/image-size-control/test/index.js +2 -2
  288. package/src/components/image-size-control/use-dimension-handler.js +4 -3
  289. package/src/components/index.js +4 -1
  290. package/src/components/inner-blocks/README.md +1 -1
  291. package/src/components/inserter/block-patterns-tab.js +3 -1
  292. package/src/components/inspector-controls-tabs/position-controls-panel.js +40 -9
  293. package/src/components/inspector-controls-tabs/utils.js +4 -3
  294. package/src/components/line-height-control/index.js +10 -1
  295. package/src/components/list-view/README.md +2 -0
  296. package/src/components/list-view/appender.js +101 -0
  297. package/src/components/list-view/block.js +6 -4
  298. package/src/components/list-view/branch.js +30 -1
  299. package/src/components/list-view/index.js +60 -11
  300. package/src/components/list-view/style.scss +22 -1
  301. package/src/components/list-view/test/use-list-view-drop-zone.js +188 -0
  302. package/src/components/list-view/use-list-view-client-ids.js +5 -3
  303. package/src/components/list-view/use-list-view-drop-zone.js +9 -3
  304. package/src/components/media-replace-flow/index.js +36 -24
  305. package/src/components/media-replace-flow/style.scss +5 -2
  306. package/src/components/off-canvas-editor/block-contents.js +4 -0
  307. package/src/components/off-canvas-editor/index.js +15 -11
  308. package/src/components/resizable-box-popover/index.js +27 -0
  309. package/src/components/rich-text/format-edit.js +2 -32
  310. package/src/components/rich-text/index.js +0 -1
  311. package/src/components/rich-text/index.native.js +2 -5
  312. package/src/components/spacing-sizes-control/spacing-input-control.js +10 -0
  313. package/src/components/spacing-sizes-control/style.scss +7 -7
  314. package/src/components/writing-flow/use-input.js +4 -5
  315. package/src/hooks/anchor.js +1 -1
  316. package/src/hooks/border.js +1 -2
  317. package/src/hooks/color.js +120 -296
  318. package/src/hooks/content-lock-ui.js +6 -2
  319. package/src/hooks/{color-panel.js → contrast-checker.js} +10 -46
  320. package/src/hooks/dimensions.js +0 -1
  321. package/src/hooks/duotone.js +121 -76
  322. package/src/hooks/margin.js +31 -26
  323. package/src/hooks/padding.js +24 -18
  324. package/src/hooks/position.js +3 -3
  325. package/src/hooks/style.js +29 -28
  326. package/src/hooks/test/utils.js +0 -104
  327. package/src/hooks/typography.js +0 -1
  328. package/src/hooks/utils.js +31 -74
  329. package/src/layouts/grid.js +172 -0
  330. package/src/layouts/index.js +2 -1
  331. package/src/layouts/test/grid.js +21 -0
  332. package/src/layouts/utils.js +2 -2
  333. package/src/private-apis.js +4 -0
  334. package/src/store/actions.js +1 -1
  335. package/src/style.scss +1 -0
  336. package/src/utils/object.js +69 -0
  337. package/src/utils/test/object.js +145 -0
  338. package/tsconfig.tsbuildinfo +1 -1
  339. package/build/components/rich-text/use-native-props.js +0 -11
  340. package/build/components/rich-text/use-native-props.js.map +0 -1
  341. package/build/components/rich-text/use-native-props.native.js +0 -24
  342. package/build/components/rich-text/use-native-props.native.js.map +0 -1
  343. package/build/hooks/color-panel.js.map +0 -1
  344. package/build-module/components/rich-text/use-native-props.js +0 -4
  345. package/build-module/components/rich-text/use-native-props.js.map +0 -1
  346. package/build-module/components/rich-text/use-native-props.native.js +0 -15
  347. package/build-module/components/rich-text/use-native-props.native.js.map +0 -1
  348. package/build-module/hooks/color-panel.js.map +0 -1
  349. package/src/components/rich-text/use-native-props.js +0 -3
  350. package/src/components/rich-text/use-native-props.native.js +0 -17
@@ -8,7 +8,11 @@ import namesPlugin from 'colord/plugins/names';
8
8
  /**
9
9
  * WordPress dependencies
10
10
  */
11
- import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks';
11
+ import {
12
+ getBlockSupport,
13
+ getBlockType,
14
+ hasBlockSupport,
15
+ } from '@wordpress/blocks';
12
16
  import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose';
13
17
  import { addFilter } from '@wordpress/hooks';
14
18
  import { useMemo, useContext, createPortal } from '@wordpress/element';
@@ -28,6 +32,8 @@ import {
28
32
  __unstableDuotoneStylesheet as DuotoneStylesheet,
29
33
  __unstableDuotoneUnsetStylesheet as DuotoneUnsetStylesheet,
30
34
  } from '../components/duotone';
35
+ import { getBlockCSSSelector } from '../components/global-styles/get-block-css-selector';
36
+ import { scopeSelector } from '../components/global-styles/utils';
31
37
  import { store as blockEditorStore } from '../store';
32
38
 
33
39
  const EMPTY_ARRAY = [];
@@ -162,7 +168,9 @@ function DuotonePanel( { attributes, setAttributes } ) {
162
168
  * @return {Object} Filtered block settings.
163
169
  */
164
170
  function addDuotoneAttributes( settings ) {
165
- if ( ! hasBlockSupport( settings, 'color.__experimentalDuotone' ) ) {
171
+ // Previous `color.__experimentalDuotone` support flag is migrated via
172
+ // block_type_metadata_settings filter in `lib/block-supports/duotone.php`.
173
+ if ( ! hasBlockSupport( settings, 'filter.duotone' ) ) {
166
174
  return settings;
167
175
  }
168
176
 
@@ -189,10 +197,13 @@ function addDuotoneAttributes( settings ) {
189
197
  */
190
198
  const withDuotoneControls = createHigherOrderComponent(
191
199
  ( BlockEdit ) => ( props ) => {
200
+ // Previous `color.__experimentalDuotone` support flag is migrated via
201
+ // block_type_metadata_settings filter in `lib/block-supports/duotone.php`.
192
202
  const hasDuotoneSupport = hasBlockSupport(
193
203
  props.name,
194
- 'color.__experimentalDuotone'
204
+ 'filter.duotone'
195
205
  );
206
+
196
207
  const isContentLocked = useSelect(
197
208
  ( select ) => {
198
209
  return select(
@@ -218,77 +229,71 @@ const withDuotoneControls = createHigherOrderComponent(
218
229
  'withDuotoneControls'
219
230
  );
220
231
 
221
- /**
222
- * Function that scopes a selector with another one. This works a bit like
223
- * SCSS nesting except the `&` operator isn't supported.
224
- *
225
- * @example
226
- * ```js
227
- * const scope = '.a, .b .c';
228
- * const selector = '> .x, .y';
229
- * const merged = scopeSelector( scope, selector );
230
- * // merged is '.a > .x, .a .y, .b .c > .x, .b .c .y'
231
- * ```
232
- *
233
- * @param {string} scope Selector to scope to.
234
- * @param {string} selector Original selector.
235
- *
236
- * @return {string} Scoped selector.
237
- */
238
- function scopeSelector( scope, selector ) {
239
- const scopes = scope.split( ',' );
240
- const selectors = selector.split( ',' );
241
-
242
- const selectorsScoped = [];
243
- scopes.forEach( ( outer ) => {
244
- selectors.forEach( ( inner ) => {
245
- selectorsScoped.push( `${ outer.trim() } ${ inner.trim() }` );
246
- } );
247
- } );
248
-
249
- return selectorsScoped.join( ', ' );
250
- }
232
+ function DuotoneStyles( {
233
+ id: filterId,
234
+ selector: duotoneSelector,
235
+ attribute: duotoneAttr,
236
+ } ) {
237
+ const element = useContext( BlockList.__unstableElementContext );
251
238
 
252
- function BlockDuotoneStyles( { name, duotoneStyle, id } ) {
253
239
  const duotonePalette = useMultiOriginPresets( {
254
240
  presetSetting: 'color.duotone',
255
241
  defaultSetting: 'color.defaultDuotone',
256
242
  } );
257
243
 
258
- const element = useContext( BlockList.__unstableElementContext );
259
-
260
- // Portals cannot exist without a container.
261
- // Guard against empty Duotone styles.
262
- if ( ! element || ! duotoneStyle ) {
263
- return null;
244
+ // Possible values for duotone attribute:
245
+ // 1. Array of colors - e.g. ['#000000', '#ffffff'].
246
+ // 2. Variable for an existing Duotone preset - e.g. 'var:preset|duotone|green-blue' or 'var(--wp--preset--duotone--green-blue)''
247
+ // 3. A CSS string - e.g. 'unset' to remove globally applied duotone.
248
+ const isCustom = Array.isArray( duotoneAttr );
249
+ const duotonePreset = isCustom
250
+ ? undefined
251
+ : getColorsFromDuotonePreset( duotoneAttr, duotonePalette );
252
+ const isPreset = typeof duotoneAttr === 'string' && duotonePreset;
253
+ const isCSS = typeof duotoneAttr === 'string' && ! isPreset;
254
+
255
+ // Match the structure of WP_Duotone_Gutenberg::render_duotone_support() in PHP.
256
+ let colors = null;
257
+ if ( isPreset ) {
258
+ // Array of colors.
259
+ colors = duotonePreset;
260
+ } else if ( isCSS ) {
261
+ // CSS filter property string (e.g. 'unset').
262
+ colors = duotoneAttr;
263
+ } else if ( isCustom ) {
264
+ // Array of colors.
265
+ colors = duotoneAttr;
264
266
  }
265
267
 
266
- let colors = duotoneStyle;
268
+ // Build the CSS selectors to which the filter will be applied.
269
+ const selectors = duotoneSelector.split( ',' );
267
270
 
268
- if ( ! Array.isArray( colors ) && colors !== 'unset' ) {
269
- colors = getColorsFromDuotonePreset( colors, duotonePalette );
270
- }
271
+ const selectorsScoped = selectors.map( ( selectorPart ) => {
272
+ // Extra .editor-styles-wrapper specificity is needed in the editor
273
+ // since we're not using inline styles to apply the filter. We need to
274
+ // override duotone applied by global styles and theme.json.
271
275
 
272
- const duotoneSupportSelectors = getBlockSupport(
273
- name,
274
- 'color.__experimentalDuotone'
275
- );
276
+ // Assuming the selector part is a subclass selector (not a tag name)
277
+ // so we can prepend the filter id class. If we want to support elements
278
+ // such as `img` or namespaces, we'll need to add a case for that here.
279
+ return `.editor-styles-wrapper .${ filterId }${ selectorPart.trim() }`;
280
+ } );
276
281
 
277
- // Extra .editor-styles-wrapper specificity is needed in the editor
278
- // since we're not using inline styles to apply the filter. We need to
279
- // override duotone applied by global styles and theme.json.
280
- const selectorsGroup = scopeSelector(
281
- `.editor-styles-wrapper .${ id }`,
282
- duotoneSupportSelectors
283
- );
282
+ const selector = selectorsScoped.join( ', ' );
283
+
284
+ const isValidFilter = Array.isArray( colors ) || colors === 'unset';
284
285
 
285
- return createPortal(
286
- <InlineDuotone
287
- selector={ selectorsGroup }
288
- id={ id }
289
- colors={ colors }
290
- />,
291
- element
286
+ return (
287
+ element &&
288
+ isValidFilter &&
289
+ createPortal(
290
+ <InlineDuotone
291
+ selector={ selector }
292
+ id={ filterId }
293
+ colors={ colors }
294
+ />,
295
+ element
296
+ )
292
297
  );
293
298
  }
294
299
 
@@ -301,16 +306,56 @@ function BlockDuotoneStyles( { name, duotoneStyle, id } ) {
301
306
  */
302
307
  const withDuotoneStyles = createHigherOrderComponent(
303
308
  ( BlockListBlock ) => ( props ) => {
304
- const duotoneSupport = getBlockSupport(
305
- props.name,
306
- 'color.__experimentalDuotone'
307
- );
308
-
309
- const id = `wp-duotone-${ useInstanceId( BlockListBlock ) }`;
310
- const className = duotoneSupport
311
- ? classnames( props?.className, id )
309
+ const id = useInstanceId( BlockListBlock );
310
+
311
+ const selector = useMemo( () => {
312
+ const blockType = getBlockType( props.name );
313
+
314
+ if ( blockType ) {
315
+ // Backwards compatibility for `supports.color.__experimentalDuotone`
316
+ // is provided via the `block_type_metadata_settings` filter. If
317
+ // `supports.filter.duotone` has not been set and the
318
+ // experimental property has been, the experimental property
319
+ // value is copied into `supports.filter.duotone`.
320
+ const duotoneSupport = getBlockSupport(
321
+ blockType,
322
+ 'filter.duotone',
323
+ false
324
+ );
325
+ if ( ! duotoneSupport ) {
326
+ return null;
327
+ }
328
+
329
+ // If the experimental duotone support was set, that value is
330
+ // to be treated as a selector and requires scoping.
331
+ const experimentalDuotone = getBlockSupport(
332
+ blockType,
333
+ 'color.__experimentalDuotone',
334
+ false
335
+ );
336
+ if ( experimentalDuotone ) {
337
+ const rootSelector = getBlockCSSSelector( blockType );
338
+ return typeof experimentalDuotone === 'string'
339
+ ? scopeSelector( rootSelector, experimentalDuotone )
340
+ : rootSelector;
341
+ }
342
+
343
+ // Regular filter.duotone support uses filter.duotone selectors with fallbacks.
344
+ return getBlockCSSSelector( blockType, 'filter.duotone', {
345
+ fallback: true,
346
+ } );
347
+ }
348
+ }, [ props.name ] );
349
+
350
+ const attribute = props?.attributes?.style?.color?.duotone;
351
+
352
+ const filterClass = `wp-duotone-${ id }`;
353
+
354
+ const shouldRender = selector && attribute;
355
+
356
+ const className = shouldRender
357
+ ? classnames( props?.className, filterClass )
312
358
  : props?.className;
313
- const duotoneStyle = props?.attributes?.style?.color?.duotone;
314
359
 
315
360
  // CAUTION: code added before this line will be executed
316
361
  // for all blocks, not just those that support duotone. Code added
@@ -318,11 +363,11 @@ const withDuotoneStyles = createHigherOrderComponent(
318
363
  // performance.
319
364
  return (
320
365
  <>
321
- { duotoneSupport && duotoneStyle && (
322
- <BlockDuotoneStyles
323
- name={ props?.name }
324
- duotoneStyle={ duotoneStyle }
325
- id={ id }
366
+ { shouldRender && (
367
+ <DuotoneStyles
368
+ id={ filterClass }
369
+ selector={ selector }
370
+ attribute={ attribute }
326
371
  />
327
372
  ) }
328
373
  <BlockListBlock { ...props } className={ className } />
@@ -1,43 +1,48 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { useMemo, useRef, useState, useEffect } from '@wordpress/element';
4
+ import { useState, useRef, useEffect } from '@wordpress/element';
5
5
  import isShallowEqual from '@wordpress/is-shallow-equal';
6
6
 
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
10
  import BlockPopover from '../components/block-popover';
11
- import { getSpacingPresetCssVar } from '../components/spacing-sizes-control/utils';
11
+ import { __unstableUseBlockElement as useBlockElement } from '../components/block-list/use-block-props/use-block-refs';
12
+
13
+ function getComputedCSS( element, property ) {
14
+ return element.ownerDocument.defaultView
15
+ .getComputedStyle( element )
16
+ .getPropertyValue( property );
17
+ }
12
18
 
13
19
  export function MarginVisualizer( { clientId, attributes, forceShow } ) {
20
+ const blockElement = useBlockElement( clientId );
21
+ const [ style, setStyle ] = useState();
22
+
14
23
  const margin = attributes?.style?.spacing?.margin;
15
24
 
16
- const style = useMemo( () => {
17
- const marginTop = margin?.top
18
- ? getSpacingPresetCssVar( margin?.top )
19
- : 0;
20
- const marginRight = margin?.right
21
- ? getSpacingPresetCssVar( margin?.right )
22
- : 0;
23
- const marginBottom = margin?.bottom
24
- ? getSpacingPresetCssVar( margin?.bottom )
25
- : 0;
26
- const marginLeft = margin?.left
27
- ? getSpacingPresetCssVar( margin?.left )
28
- : 0;
25
+ useEffect( () => {
26
+ if ( ! blockElement ) {
27
+ return;
28
+ }
29
29
 
30
- return {
31
- borderTopWidth: marginTop,
32
- borderRightWidth: marginRight,
33
- borderBottomWidth: marginBottom,
34
- borderLeftWidth: marginLeft,
35
- top: marginTop ? `calc(${ marginTop } * -1)` : 0,
36
- right: marginRight ? `calc(${ marginRight } * -1)` : 0,
37
- bottom: marginBottom ? `calc(${ marginBottom } * -1)` : 0,
38
- left: marginLeft ? `calc(${ marginLeft } * -1)` : 0,
39
- };
40
- }, [ margin ] );
30
+ const top = getComputedCSS( blockElement, 'margin-top' );
31
+ const right = getComputedCSS( blockElement, 'margin-right' );
32
+ const bottom = getComputedCSS( blockElement, 'margin-bottom' );
33
+ const left = getComputedCSS( blockElement, 'margin-left' );
34
+
35
+ setStyle( {
36
+ borderTopWidth: top,
37
+ borderRightWidth: right,
38
+ borderBottomWidth: bottom,
39
+ borderLeftWidth: left,
40
+ top: top ? `-${ top }` : 0,
41
+ right: right ? `-${ right }` : 0,
42
+ bottom: bottom ? `-${ bottom }` : 0,
43
+ left: left ? `-${ left }` : 0,
44
+ } );
45
+ }, [ blockElement, margin ] );
41
46
 
42
47
  const [ isActive, setIsActive ] = useState( false );
43
48
  const valueRef = useRef( margin );
@@ -1,33 +1,39 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { useState, useRef, useEffect, useMemo } from '@wordpress/element';
4
+ import { useState, useRef, useEffect } from '@wordpress/element';
5
5
  import isShallowEqual from '@wordpress/is-shallow-equal';
6
6
 
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
10
  import BlockPopover from '../components/block-popover';
11
- import { getSpacingPresetCssVar } from '../components/spacing-sizes-control/utils';
11
+ import { __unstableUseBlockElement as useBlockElement } from '../components/block-list/use-block-props/use-block-refs';
12
+
13
+ function getComputedCSS( element, property ) {
14
+ return element.ownerDocument.defaultView
15
+ .getComputedStyle( element )
16
+ .getPropertyValue( property );
17
+ }
12
18
 
13
19
  export function PaddingVisualizer( { clientId, attributes, forceShow } ) {
20
+ const blockElement = useBlockElement( clientId );
21
+ const [ style, setStyle ] = useState();
22
+
14
23
  const padding = attributes?.style?.spacing?.padding;
15
- const style = useMemo( () => {
16
- return {
17
- borderTopWidth: padding?.top
18
- ? getSpacingPresetCssVar( padding?.top )
19
- : 0,
20
- borderRightWidth: padding?.right
21
- ? getSpacingPresetCssVar( padding?.right )
22
- : 0,
23
- borderBottomWidth: padding?.bottom
24
- ? getSpacingPresetCssVar( padding?.bottom )
25
- : 0,
26
- borderLeftWidth: padding?.left
27
- ? getSpacingPresetCssVar( padding?.left )
28
- : 0,
29
- };
30
- }, [ padding ] );
24
+
25
+ useEffect( () => {
26
+ if ( ! blockElement ) {
27
+ return;
28
+ }
29
+
30
+ setStyle( {
31
+ borderTopWidth: getComputedCSS( blockElement, 'padding-top' ),
32
+ borderRightWidth: getComputedCSS( blockElement, 'padding-right' ),
33
+ borderBottomWidth: getComputedCSS( blockElement, 'padding-bottom' ),
34
+ borderLeftWidth: getComputedCSS( blockElement, 'padding-left' ),
35
+ } );
36
+ }, [ blockElement, padding ] );
31
37
 
32
38
  const [ isActive, setIsActive ] = useState( false );
33
39
  const valueRef = useRef( padding );
@@ -6,7 +6,7 @@ import classnames from 'classnames';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
- import { __, sprintf } from '@wordpress/i18n';
9
+ import { __, _x, sprintf } from '@wordpress/i18n';
10
10
  import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks';
11
11
  import {
12
12
  BaseControl,
@@ -49,7 +49,7 @@ const DEFAULT_OPTION = {
49
49
  const STICKY_OPTION = {
50
50
  key: 'sticky',
51
51
  value: 'sticky',
52
- name: __( 'Sticky' ),
52
+ name: _x( 'Sticky', 'Name for the value of the CSS position property' ),
53
53
  className: OPTION_CLASSNAME,
54
54
  __experimentalHint: __(
55
55
  'The block will stick to the top of the window instead of scrolling.'
@@ -59,7 +59,7 @@ const STICKY_OPTION = {
59
59
  const FIXED_OPTION = {
60
60
  key: 'fixed',
61
61
  value: 'fixed',
62
- name: __( 'Fixed' ),
62
+ name: _x( 'Fixed', 'Name for the value of the CSS position property' ),
63
63
  className: OPTION_CLASSNAME,
64
64
  __experimentalHint: __(
65
65
  'The block will not move when the page is scrolled.'
@@ -384,39 +384,40 @@ const withElementsStyles = createHigherOrderComponent(
384
384
  );
385
385
 
386
386
  const styles = useMemo( () => {
387
- const rawElementsStyles = props.attributes.style?.elements;
387
+ // The .editor-styles-wrapper selector is required on elements styles. As it is
388
+ // added to all other editor styles, not providing it causes reset and global
389
+ // styles to override element styles because of higher specificity.
390
+ const elements = [
391
+ {
392
+ styles: ! skipLinkColorSerialization
393
+ ? props.attributes.style?.elements?.link
394
+ : undefined,
395
+ selector: `.editor-styles-wrapper .${ blockElementsContainerIdentifier } ${ ELEMENTS.link }`,
396
+ },
397
+ {
398
+ styles: ! skipLinkColorSerialization
399
+ ? props.attributes.style?.elements?.link?.[ ':hover' ]
400
+ : undefined,
401
+ selector: `.editor-styles-wrapper .${ blockElementsContainerIdentifier } ${ ELEMENTS.link }:hover`,
402
+ },
403
+ ];
388
404
  const elementCssRules = [];
389
- if (
390
- rawElementsStyles &&
391
- Object.keys( rawElementsStyles ).length > 0
392
- ) {
393
- // Remove values based on whether serialization has been skipped for a specific style.
394
- const filteredElementsStyles = {
395
- ...rawElementsStyles,
396
- link: {
397
- ...rawElementsStyles.link,
398
- color: ! skipLinkColorSerialization
399
- ? rawElementsStyles.link?.color
400
- : undefined,
401
- },
402
- };
403
-
404
- for ( const [ elementName, elementStyles ] of Object.entries(
405
- filteredElementsStyles
406
- ) ) {
405
+ for ( const { styles: elementStyles, selector } of elements ) {
406
+ if ( elementStyles ) {
407
407
  const cssRule = compileCSS( elementStyles, {
408
- // The .editor-styles-wrapper selector is required on elements styles. As it is
409
- // added to all other editor styles, not providing it causes reset and global
410
- // styles to override element styles because of higher specificity.
411
- selector: `.editor-styles-wrapper .${ blockElementsContainerIdentifier } ${ ELEMENTS[ elementName ] }`,
408
+ selector,
412
409
  } );
413
- if ( !! cssRule ) {
414
- elementCssRules.push( cssRule );
415
- }
410
+ elementCssRules.push( cssRule );
416
411
  }
417
412
  }
418
- return elementCssRules.length > 0 ? elementCssRules : undefined;
419
- }, [ props.attributes.style?.elements ] );
413
+ return elementCssRules.length > 0
414
+ ? elementCssRules.join( '' )
415
+ : undefined;
416
+ }, [
417
+ props.attributes.style?.elements,
418
+ blockElementsContainerIdentifier,
419
+ skipLinkColorSerialization,
420
+ ] );
420
421
 
421
422
  const element = useContext( BlockList.__unstableElementContext );
422
423
 
@@ -7,113 +7,9 @@ import { applyFilters } from '@wordpress/hooks';
7
7
  * Internal dependencies
8
8
  */
9
9
  import '../anchor';
10
- import { immutableSet } from '../utils';
11
10
 
12
11
  const noop = () => {};
13
12
 
14
- describe( 'immutableSet', () => {
15
- describe( 'handling falsy values properly', () => {
16
- it( 'should create a new object if `undefined` is passed', () => {
17
- const result = immutableSet( undefined, 'test', 1 );
18
-
19
- expect( result ).toEqual( { test: 1 } );
20
- } );
21
-
22
- it( 'should create a new object if `null` is passed', () => {
23
- const result = immutableSet( null, 'test', 1 );
24
-
25
- expect( result ).toEqual( { test: 1 } );
26
- } );
27
-
28
- it( 'should create a new object if `false` is passed', () => {
29
- const result = immutableSet( false, 'test', 1 );
30
-
31
- expect( result ).toEqual( { test: 1 } );
32
- } );
33
-
34
- it( 'should create a new object if `0` is passed', () => {
35
- const result = immutableSet( 0, 'test', 1 );
36
-
37
- expect( result ).toEqual( { test: 1 } );
38
- } );
39
-
40
- it( 'should create a new object if an empty string is passed', () => {
41
- const result = immutableSet( '', 'test', 1 );
42
-
43
- expect( result ).toEqual( { test: 1 } );
44
- } );
45
-
46
- it( 'should create a new object if a NaN is passed', () => {
47
- const result = immutableSet( NaN, 'test', 1 );
48
-
49
- expect( result ).toEqual( { test: 1 } );
50
- } );
51
- } );
52
-
53
- describe( 'manages data assignment properly', () => {
54
- it( 'assigns value properly when it does not exist', () => {
55
- const result = immutableSet( {}, 'test', 1 );
56
-
57
- expect( result ).toEqual( { test: 1 } );
58
- } );
59
-
60
- it( 'overrides existing values', () => {
61
- const result = immutableSet( { test: 1 }, 'test', 2 );
62
-
63
- expect( result ).toEqual( { test: 2 } );
64
- } );
65
-
66
- describe( 'with array notation access', () => {
67
- it( 'assigns values at deeper levels', () => {
68
- const result = immutableSet( {}, [ 'foo', 'bar', 'baz' ], 5 );
69
-
70
- expect( result ).toEqual( { foo: { bar: { baz: 5 } } } );
71
- } );
72
-
73
- it( 'overrides existing values at deeper levels', () => {
74
- const result = immutableSet(
75
- { foo: { bar: { baz: 1 } } },
76
- [ 'foo', 'bar', 'baz' ],
77
- 5
78
- );
79
-
80
- expect( result ).toEqual( { foo: { bar: { baz: 5 } } } );
81
- } );
82
-
83
- it( 'keeps other properties intact', () => {
84
- const result = immutableSet(
85
- { foo: { bar: { baz: 1 } } },
86
- [ 'foo', 'bar', 'test' ],
87
- 5
88
- );
89
-
90
- expect( result ).toEqual( {
91
- foo: { bar: { baz: 1, test: 5 } },
92
- } );
93
- } );
94
- } );
95
- } );
96
-
97
- describe( 'does not mutate the original object', () => {
98
- it( 'clones the object at the first level', () => {
99
- const input = {};
100
- const result = immutableSet( input, 'test', 1 );
101
-
102
- expect( result ).not.toBe( input );
103
- } );
104
-
105
- it( 'clones the object at deeper levels', () => {
106
- const input = { foo: { bar: { baz: 1 } } };
107
- const result = immutableSet( input, [ 'foo', 'bar', 'baz' ], 2 );
108
-
109
- expect( result ).not.toBe( input );
110
- expect( result.foo ).not.toBe( input.foo );
111
- expect( result.foo.bar ).not.toBe( input.foo.bar );
112
- expect( result.foo.bar.baz ).not.toBe( input.foo.bar.baz );
113
- } );
114
- } );
115
- } );
116
-
117
13
  describe( 'anchor', () => {
118
14
  const blockSettings = {
119
15
  save: noop,
@@ -138,7 +138,6 @@ export function TypographyPanel( {
138
138
  <StylesTypographyPanel
139
139
  as={ TypographyInspectorControl }
140
140
  panelId={ clientId }
141
- name={ name }
142
141
  settings={ settings }
143
142
  value={ value }
144
143
  onChange={ onChange }