@wordpress/block-editor 9.7.0 → 9.8.1-next.957ca95e4c.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 (396) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-alignment-control/use-available-alignments.js +1 -1
  3. package/build/components/block-alignment-control/use-available-alignments.js.map +1 -1
  4. package/build/components/block-edit-visually-button/index.js +46 -0
  5. package/build/components/block-edit-visually-button/index.js.map +1 -0
  6. package/build/components/block-list/block-list-compact.native.js +73 -0
  7. package/build/components/block-list/block-list-compact.native.js.map +1 -0
  8. package/build/components/block-list/use-block-props/use-focus-first-element.js +1 -1
  9. package/build/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
  10. package/build/components/block-popover/inbetween.js +4 -2
  11. package/build/components/block-popover/inbetween.js.map +1 -1
  12. package/build/components/block-popover/index.js +11 -7
  13. package/build/components/block-popover/index.js.map +1 -1
  14. package/build/components/block-settings-menu/index.js +2 -6
  15. package/build/components/block-settings-menu/index.js.map +1 -1
  16. package/build/components/block-switcher/index.js +10 -16
  17. package/build/components/block-switcher/index.js.map +1 -1
  18. package/build/components/block-toolbar/index.js +5 -1
  19. package/build/components/block-toolbar/index.js.map +1 -1
  20. package/build/components/block-tools/selected-block-popover.js +10 -2
  21. package/build/components/block-tools/selected-block-popover.js.map +1 -1
  22. package/build/components/block-tools/use-block-toolbar-popover-props.js +126 -0
  23. package/build/components/block-tools/use-block-toolbar-popover-props.js.map +1 -0
  24. package/build/components/border-radius-control/all-input-control.js +31 -3
  25. package/build/components/border-radius-control/all-input-control.js.map +1 -1
  26. package/build/components/border-radius-control/index.js +20 -6
  27. package/build/components/border-radius-control/index.js.map +1 -1
  28. package/build/components/border-radius-control/input-controls.js +21 -6
  29. package/build/components/border-radius-control/input-controls.js.map +1 -1
  30. package/build/components/border-radius-control/utils.js +13 -16
  31. package/build/components/border-radius-control/utils.js.map +1 -1
  32. package/build/components/colors/with-colors.js +17 -4
  33. package/build/components/colors/with-colors.js.map +1 -1
  34. package/build/components/colors-gradients/control.js +1 -0
  35. package/build/components/colors-gradients/control.js.map +1 -1
  36. package/build/components/copy-handler/index.js +6 -0
  37. package/build/components/copy-handler/index.js.map +1 -1
  38. package/build/components/date-format-picker/index.js +2 -7
  39. package/build/components/date-format-picker/index.js.map +1 -1
  40. package/build/components/duotone/components.js +5 -5
  41. package/build/components/duotone/components.js.map +1 -1
  42. package/build/components/font-family/index.js +1 -1
  43. package/build/components/font-family/index.js.map +1 -1
  44. package/build/components/font-sizes/with-font-sizes.js +17 -4
  45. package/build/components/font-sizes/with-font-sizes.js.map +1 -1
  46. package/build/components/index.js +9 -0
  47. package/build/components/index.js.map +1 -1
  48. package/build/components/inner-blocks/index.native.js +6 -2
  49. package/build/components/inner-blocks/index.native.js.map +1 -1
  50. package/build/components/inserter/search-items.js +22 -4
  51. package/build/components/inserter/search-items.js.map +1 -1
  52. package/build/components/link-control/link-preview.js +0 -1
  53. package/build/components/link-control/link-preview.js.map +1 -1
  54. package/build/components/list-view/block-select-button.js +5 -2
  55. package/build/components/list-view/block-select-button.js.map +1 -1
  56. package/build/components/list-view/use-block-selection.js +1 -7
  57. package/build/components/list-view/use-block-selection.js.map +1 -1
  58. package/build/components/rich-text/index.js +10 -0
  59. package/build/components/rich-text/index.js.map +1 -1
  60. package/build/components/rich-text/use-enter.js +0 -4
  61. package/build/components/rich-text/use-enter.js.map +1 -1
  62. package/build/components/rich-text/use-format-types.js +8 -11
  63. package/build/components/rich-text/use-format-types.js.map +1 -1
  64. package/build/components/spacing-sizes-control/all-input-control.js +53 -0
  65. package/build/components/spacing-sizes-control/all-input-control.js.map +1 -0
  66. package/build/components/spacing-sizes-control/axial-input-controls.js +69 -0
  67. package/build/components/spacing-sizes-control/axial-input-controls.js.map +1 -0
  68. package/build/components/spacing-sizes-control/index.js +100 -0
  69. package/build/components/spacing-sizes-control/index.js.map +1 -0
  70. package/build/components/spacing-sizes-control/input-controls.js +52 -0
  71. package/build/components/spacing-sizes-control/input-controls.js.map +1 -0
  72. package/build/components/spacing-sizes-control/linked-button.js +38 -0
  73. package/build/components/spacing-sizes-control/linked-button.js.map +1 -0
  74. package/build/components/spacing-sizes-control/spacing-input-control.js +213 -0
  75. package/build/components/spacing-sizes-control/spacing-input-control.js.map +1 -0
  76. package/build/components/spacing-sizes-control/utils.js +233 -0
  77. package/build/components/spacing-sizes-control/utils.js.map +1 -0
  78. package/build/components/text-decoration-control/index.js +28 -17
  79. package/build/components/text-decoration-control/index.js.map +1 -1
  80. package/build/components/text-transform-control/index.js +21 -14
  81. package/build/components/text-transform-control/index.js.map +1 -1
  82. package/build/components/url-input/index.js +1 -1
  83. package/build/components/url-input/index.js.map +1 -1
  84. package/build/components/writing-flow/index.js +2 -0
  85. package/build/components/writing-flow/index.js.map +1 -1
  86. package/build/components/writing-flow/use-multi-selection.js +4 -2
  87. package/build/components/writing-flow/use-multi-selection.js.map +1 -1
  88. package/build/components/writing-flow/use-select-all.js +7 -10
  89. package/build/components/writing-flow/use-select-all.js.map +1 -1
  90. package/build/components/writing-flow/use-selection-observer.js +10 -2
  91. package/build/components/writing-flow/use-selection-observer.js.map +1 -1
  92. package/build/hooks/align.js +3 -1
  93. package/build/hooks/align.js.map +1 -1
  94. package/build/hooks/anchor.js +3 -7
  95. package/build/hooks/anchor.js.map +1 -1
  96. package/build/hooks/border-radius.js +2 -7
  97. package/build/hooks/border-radius.js.map +1 -1
  98. package/build/hooks/border.js +2 -2
  99. package/build/hooks/border.js.map +1 -1
  100. package/build/hooks/color.js +4 -1
  101. package/build/hooks/color.js.map +1 -1
  102. package/build/hooks/dimensions.js +15 -0
  103. package/build/hooks/dimensions.js.map +1 -1
  104. package/build/hooks/duotone.js +4 -4
  105. package/build/hooks/duotone.js.map +1 -1
  106. package/build/hooks/font-appearance.js +2 -1
  107. package/build/hooks/font-appearance.js.map +1 -1
  108. package/build/hooks/font-family.js +3 -1
  109. package/build/hooks/font-family.js.map +1 -1
  110. package/build/hooks/font-size.js +3 -1
  111. package/build/hooks/font-size.js.map +1 -1
  112. package/build/hooks/gap.js +25 -6
  113. package/build/hooks/gap.js.map +1 -1
  114. package/build/hooks/generated-class-name.js +1 -7
  115. package/build/hooks/generated-class-name.js.map +1 -1
  116. package/build/hooks/layout.js +23 -13
  117. package/build/hooks/layout.js.map +1 -1
  118. package/build/hooks/letter-spacing.js +2 -1
  119. package/build/hooks/letter-spacing.js.map +1 -1
  120. package/build/hooks/line-height.js +2 -1
  121. package/build/hooks/line-height.js.map +1 -1
  122. package/build/hooks/lock.js +3 -7
  123. package/build/hooks/lock.js.map +1 -1
  124. package/build/hooks/margin.js +28 -12
  125. package/build/hooks/margin.js.map +1 -1
  126. package/build/hooks/padding.js +19 -8
  127. package/build/hooks/padding.js.map +1 -1
  128. package/build/hooks/style.js +4 -50
  129. package/build/hooks/style.js.map +1 -1
  130. package/build/hooks/text-decoration.js +2 -1
  131. package/build/hooks/text-decoration.js.map +1 -1
  132. package/build/hooks/text-transform.js +2 -1
  133. package/build/hooks/text-transform.js.map +1 -1
  134. package/build/layouts/constrained.js +225 -0
  135. package/build/layouts/constrained.js.map +1 -0
  136. package/build/layouts/flex.js +1 -1
  137. package/build/layouts/flex.js.map +1 -1
  138. package/build/layouts/flow.js +18 -152
  139. package/build/layouts/flow.js.map +1 -1
  140. package/build/layouts/index.js +3 -1
  141. package/build/layouts/index.js.map +1 -1
  142. package/build/layouts/utils.js +43 -0
  143. package/build/layouts/utils.js.map +1 -1
  144. package/build/store/actions.js +25 -3
  145. package/build/store/actions.js.map +1 -1
  146. package/build/store/selectors.js +4 -6
  147. package/build/store/selectors.js.map +1 -1
  148. package/build-module/components/block-alignment-control/use-available-alignments.js +1 -1
  149. package/build-module/components/block-alignment-control/use-available-alignments.js.map +1 -1
  150. package/build-module/components/block-edit-visually-button/index.js +35 -0
  151. package/build-module/components/block-edit-visually-button/index.js.map +1 -0
  152. package/build-module/components/block-list/block-list-compact.native.js +58 -0
  153. package/build-module/components/block-list/block-list-compact.native.js.map +1 -0
  154. package/build-module/components/block-list/use-block-props/use-focus-first-element.js +1 -1
  155. package/build-module/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
  156. package/build-module/components/block-popover/inbetween.js +4 -2
  157. package/build-module/components/block-popover/inbetween.js.map +1 -1
  158. package/build-module/components/block-popover/index.js +9 -7
  159. package/build-module/components/block-popover/index.js.map +1 -1
  160. package/build-module/components/block-settings-menu/index.js +3 -6
  161. package/build-module/components/block-settings-menu/index.js.map +1 -1
  162. package/build-module/components/block-switcher/index.js +10 -16
  163. package/build-module/components/block-switcher/index.js.map +1 -1
  164. package/build-module/components/block-toolbar/index.js +4 -1
  165. package/build-module/components/block-toolbar/index.js.map +1 -1
  166. package/build-module/components/block-tools/selected-block-popover.js +8 -2
  167. package/build-module/components/block-tools/selected-block-popover.js.map +1 -1
  168. package/build-module/components/block-tools/use-block-toolbar-popover-props.js +114 -0
  169. package/build-module/components/block-tools/use-block-toolbar-popover-props.js.map +1 -0
  170. package/build-module/components/border-radius-control/all-input-control.js +32 -4
  171. package/build-module/components/border-radius-control/all-input-control.js.map +1 -1
  172. package/build-module/components/border-radius-control/index.js +20 -6
  173. package/build-module/components/border-radius-control/index.js.map +1 -1
  174. package/build-module/components/border-radius-control/input-controls.js +22 -7
  175. package/build-module/components/border-radius-control/input-controls.js.map +1 -1
  176. package/build-module/components/border-radius-control/utils.js +13 -16
  177. package/build-module/components/border-radius-control/utils.js.map +1 -1
  178. package/build-module/components/colors/with-colors.js +16 -3
  179. package/build-module/components/colors/with-colors.js.map +1 -1
  180. package/build-module/components/colors-gradients/control.js +1 -0
  181. package/build-module/components/colors-gradients/control.js.map +1 -1
  182. package/build-module/components/copy-handler/index.js +7 -1
  183. package/build-module/components/copy-handler/index.js.map +1 -1
  184. package/build-module/components/date-format-picker/index.js +2 -6
  185. package/build-module/components/date-format-picker/index.js.map +1 -1
  186. package/build-module/components/duotone/components.js +5 -5
  187. package/build-module/components/duotone/components.js.map +1 -1
  188. package/build-module/components/font-family/index.js +1 -1
  189. package/build-module/components/font-family/index.js.map +1 -1
  190. package/build-module/components/font-sizes/with-font-sizes.js +16 -3
  191. package/build-module/components/font-sizes/with-font-sizes.js.map +1 -1
  192. package/build-module/components/index.js +1 -0
  193. package/build-module/components/index.js.map +1 -1
  194. package/build-module/components/inner-blocks/index.native.js +5 -2
  195. package/build-module/components/inner-blocks/index.native.js.map +1 -1
  196. package/build-module/components/inserter/search-items.js +19 -5
  197. package/build-module/components/inserter/search-items.js.map +1 -1
  198. package/build-module/components/link-control/link-preview.js +0 -1
  199. package/build-module/components/link-control/link-preview.js.map +1 -1
  200. package/build-module/components/list-view/block-select-button.js +5 -2
  201. package/build-module/components/list-view/block-select-button.js.map +1 -1
  202. package/build-module/components/list-view/use-block-selection.js +1 -6
  203. package/build-module/components/list-view/use-block-selection.js.map +1 -1
  204. package/build-module/components/rich-text/index.js +10 -0
  205. package/build-module/components/rich-text/index.js.map +1 -1
  206. package/build-module/components/rich-text/use-enter.js +0 -4
  207. package/build-module/components/rich-text/use-enter.js.map +1 -1
  208. package/build-module/components/rich-text/use-format-types.js +8 -10
  209. package/build-module/components/rich-text/use-format-types.js.map +1 -1
  210. package/build-module/components/spacing-sizes-control/all-input-control.js +41 -0
  211. package/build-module/components/spacing-sizes-control/all-input-control.js.map +1 -0
  212. package/build-module/components/spacing-sizes-control/axial-input-controls.js +57 -0
  213. package/build-module/components/spacing-sizes-control/axial-input-controls.js.map +1 -0
  214. package/build-module/components/spacing-sizes-control/index.js +83 -0
  215. package/build-module/components/spacing-sizes-control/index.js.map +1 -0
  216. package/build-module/components/spacing-sizes-control/input-controls.js +41 -0
  217. package/build-module/components/spacing-sizes-control/input-controls.js.map +1 -0
  218. package/build-module/components/spacing-sizes-control/linked-button.js +28 -0
  219. package/build-module/components/spacing-sizes-control/linked-button.js.map +1 -0
  220. package/build-module/components/spacing-sizes-control/spacing-input-control.js +197 -0
  221. package/build-module/components/spacing-sizes-control/spacing-input-control.js.map +1 -0
  222. package/build-module/components/spacing-sizes-control/utils.js +203 -0
  223. package/build-module/components/spacing-sizes-control/utils.js.map +1 -0
  224. package/build-module/components/text-decoration-control/index.js +25 -18
  225. package/build-module/components/text-decoration-control/index.js.map +1 -1
  226. package/build-module/components/text-transform-control/index.js +19 -15
  227. package/build-module/components/text-transform-control/index.js.map +1 -1
  228. package/build-module/components/url-input/index.js +1 -1
  229. package/build-module/components/url-input/index.js.map +1 -1
  230. package/build-module/components/writing-flow/index.js +2 -0
  231. package/build-module/components/writing-flow/index.js.map +1 -1
  232. package/build-module/components/writing-flow/use-multi-selection.js +4 -2
  233. package/build-module/components/writing-flow/use-multi-selection.js.map +1 -1
  234. package/build-module/components/writing-flow/use-select-all.js +7 -10
  235. package/build-module/components/writing-flow/use-select-all.js.map +1 -1
  236. package/build-module/components/writing-flow/use-selection-observer.js +10 -2
  237. package/build-module/components/writing-flow/use-selection-observer.js.map +1 -1
  238. package/build-module/hooks/align.js +4 -2
  239. package/build-module/hooks/align.js.map +1 -1
  240. package/build-module/hooks/anchor.js +3 -6
  241. package/build-module/hooks/anchor.js.map +1 -1
  242. package/build-module/hooks/border-radius.js +2 -7
  243. package/build-module/hooks/border-radius.js.map +1 -1
  244. package/build-module/hooks/border.js +2 -2
  245. package/build-module/hooks/border.js.map +1 -1
  246. package/build-module/hooks/color.js +4 -1
  247. package/build-module/hooks/color.js.map +1 -1
  248. package/build-module/hooks/dimensions.js +13 -0
  249. package/build-module/hooks/dimensions.js.map +1 -1
  250. package/build-module/hooks/duotone.js +4 -4
  251. package/build-module/hooks/duotone.js.map +1 -1
  252. package/build-module/hooks/font-appearance.js +2 -1
  253. package/build-module/hooks/font-appearance.js.map +1 -1
  254. package/build-module/hooks/font-family.js +3 -1
  255. package/build-module/hooks/font-family.js.map +1 -1
  256. package/build-module/hooks/font-size.js +3 -1
  257. package/build-module/hooks/font-size.js.map +1 -1
  258. package/build-module/hooks/gap.js +21 -4
  259. package/build-module/hooks/gap.js.map +1 -1
  260. package/build-module/hooks/generated-class-name.js +1 -6
  261. package/build-module/hooks/generated-class-name.js.map +1 -1
  262. package/build-module/hooks/layout.js +24 -14
  263. package/build-module/hooks/layout.js.map +1 -1
  264. package/build-module/hooks/letter-spacing.js +2 -1
  265. package/build-module/hooks/letter-spacing.js.map +1 -1
  266. package/build-module/hooks/line-height.js +2 -1
  267. package/build-module/hooks/line-height.js.map +1 -1
  268. package/build-module/hooks/lock.js +3 -6
  269. package/build-module/hooks/lock.js.map +1 -1
  270. package/build-module/hooks/margin.js +26 -12
  271. package/build-module/hooks/margin.js.map +1 -1
  272. package/build-module/hooks/padding.js +17 -8
  273. package/build-module/hooks/padding.js.map +1 -1
  274. package/build-module/hooks/style.js +7 -53
  275. package/build-module/hooks/style.js.map +1 -1
  276. package/build-module/hooks/text-decoration.js +2 -1
  277. package/build-module/hooks/text-decoration.js.map +1 -1
  278. package/build-module/hooks/text-transform.js +2 -1
  279. package/build-module/hooks/text-transform.js.map +1 -1
  280. package/build-module/layouts/constrained.js +207 -0
  281. package/build-module/layouts/constrained.js.map +1 -0
  282. package/build-module/layouts/flex.js +1 -1
  283. package/build-module/layouts/flex.js.map +1 -1
  284. package/build-module/layouts/flow.js +20 -147
  285. package/build-module/layouts/flow.js.map +1 -1
  286. package/build-module/layouts/index.js +2 -1
  287. package/build-module/layouts/index.js.map +1 -1
  288. package/build-module/layouts/utils.js +40 -0
  289. package/build-module/layouts/utils.js.map +1 -1
  290. package/build-module/store/actions.js +25 -3
  291. package/build-module/store/actions.js.map +1 -1
  292. package/build-module/store/selectors.js +5 -7
  293. package/build-module/store/selectors.js.map +1 -1
  294. package/build-style/style-rtl.css +157 -61
  295. package/build-style/style.css +157 -61
  296. package/package.json +30 -28
  297. package/src/components/block-alignment-control/use-available-alignments.js +1 -1
  298. package/src/components/block-edit-visually-button/index.js +39 -0
  299. package/src/components/block-list/block-list-compact.native.js +62 -0
  300. package/src/components/block-list/style.scss +29 -6
  301. package/src/components/block-list/use-block-props/use-focus-first-element.js +1 -1
  302. package/src/components/block-popover/inbetween.js +4 -1
  303. package/src/components/block-popover/index.js +22 -15
  304. package/src/components/block-settings-menu/index.js +11 -15
  305. package/src/components/block-switcher/index.js +9 -13
  306. package/src/components/block-switcher/test/index.js +2 -2
  307. package/src/components/block-toolbar/index.js +2 -0
  308. package/src/components/block-tools/selected-block-popover.js +7 -0
  309. package/src/components/block-tools/use-block-toolbar-popover-props.js +123 -0
  310. package/src/components/border-radius-control/all-input-control.js +41 -4
  311. package/src/components/border-radius-control/index.js +25 -5
  312. package/src/components/border-radius-control/input-controls.js +40 -13
  313. package/src/components/border-radius-control/test/utils.js +22 -60
  314. package/src/components/border-radius-control/utils.js +12 -16
  315. package/src/components/button-block-appender/style.scss +23 -0
  316. package/src/components/colors/with-colors.js +11 -1
  317. package/src/components/colors-gradients/control.js +1 -0
  318. package/src/components/copy-handler/index.js +18 -0
  319. package/src/components/date-format-picker/index.js +12 -14
  320. package/src/components/date-format-picker/style.scss +0 -4
  321. package/src/components/duotone/components.js +5 -5
  322. package/src/components/duotone-control/style.scss +0 -4
  323. package/src/components/font-appearance-control/style.scss +0 -2
  324. package/src/components/font-family/index.js +1 -1
  325. package/src/components/font-sizes/with-font-sizes.js +11 -1
  326. package/src/components/index.js +1 -0
  327. package/src/components/inner-blocks/index.native.js +5 -1
  328. package/src/components/inserter/search-items.js +17 -5
  329. package/src/components/link-control/link-preview.js +0 -1
  330. package/src/components/link-control/test/index.js +540 -893
  331. package/src/components/list-view/block-select-button.js +7 -2
  332. package/src/components/list-view/style.scss +11 -4
  333. package/src/components/list-view/use-block-selection.js +2 -8
  334. package/src/components/media-replace-flow/style.scss +1 -0
  335. package/src/components/rich-text/index.js +9 -0
  336. package/src/components/rich-text/use-enter.js +0 -3
  337. package/src/components/rich-text/use-format-types.js +6 -6
  338. package/src/components/spacing-sizes-control/all-input-control.js +40 -0
  339. package/src/components/spacing-sizes-control/axial-input-controls.js +62 -0
  340. package/src/components/spacing-sizes-control/index.js +91 -0
  341. package/src/components/spacing-sizes-control/input-controls.js +46 -0
  342. package/src/components/spacing-sizes-control/linked-button.js +25 -0
  343. package/src/components/spacing-sizes-control/spacing-input-control.js +285 -0
  344. package/src/components/spacing-sizes-control/style.scss +122 -0
  345. package/src/components/spacing-sizes-control/test/utils.js +182 -0
  346. package/src/components/spacing-sizes-control/utils.js +222 -0
  347. package/src/components/text-decoration-control/index.js +41 -30
  348. package/src/components/text-decoration-control/stories/index.js +37 -0
  349. package/src/components/text-transform-control/index.js +27 -27
  350. package/src/components/text-transform-control/stories/index.js +37 -0
  351. package/src/components/url-input/index.js +1 -1
  352. package/src/components/url-input/style.scss +2 -2
  353. package/src/components/url-popover/style.scss +0 -3
  354. package/src/components/writing-flow/index.js +2 -0
  355. package/src/components/writing-flow/use-multi-selection.js +4 -1
  356. package/src/components/writing-flow/use-select-all.js +10 -13
  357. package/src/components/writing-flow/use-selection-observer.js +10 -2
  358. package/src/hooks/align.js +2 -2
  359. package/src/hooks/anchor.js +1 -6
  360. package/src/hooks/border-radius.js +2 -6
  361. package/src/hooks/border.js +2 -2
  362. package/src/hooks/color.js +13 -3
  363. package/src/hooks/dimensions.js +14 -0
  364. package/src/hooks/duotone.js +4 -4
  365. package/src/hooks/font-appearance.js +1 -0
  366. package/src/hooks/font-family.js +2 -0
  367. package/src/hooks/font-size.js +2 -0
  368. package/src/hooks/gap.js +42 -19
  369. package/src/hooks/generated-class-name.js +6 -9
  370. package/src/hooks/layout.js +47 -16
  371. package/src/hooks/letter-spacing.js +1 -0
  372. package/src/hooks/line-height.js +1 -0
  373. package/src/hooks/lock.js +1 -6
  374. package/src/hooks/margin.js +49 -17
  375. package/src/hooks/padding.js +41 -14
  376. package/src/hooks/style.js +5 -56
  377. package/src/hooks/test/gap.js +16 -0
  378. package/src/hooks/text-decoration.js +1 -0
  379. package/src/hooks/text-transform.js +1 -0
  380. package/src/hooks/typography.scss +0 -7
  381. package/src/layouts/constrained.js +220 -0
  382. package/src/layouts/flex.js +1 -1
  383. package/src/layouts/flow.js +17 -173
  384. package/src/layouts/index.js +2 -1
  385. package/src/layouts/test/constrained.js +21 -0
  386. package/src/layouts/utils.js +34 -0
  387. package/src/store/actions.js +32 -4
  388. package/src/store/selectors.js +5 -4
  389. package/src/style.scss +1 -2
  390. package/build/components/block-settings-menu/block-edit-visually-button.js +0 -70
  391. package/build/components/block-settings-menu/block-edit-visually-button.js.map +0 -1
  392. package/build-module/components/block-settings-menu/block-edit-visually-button.js +0 -56
  393. package/build-module/components/block-settings-menu/block-edit-visually-button.js.map +0 -1
  394. package/src/components/block-settings-menu/block-edit-visually-button.js +0 -52
  395. package/src/components/text-decoration-control/style.scss +0 -18
  396. package/src/components/text-transform-control/style.scss +0 -18
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-editor",
3
- "version": "9.7.0",
3
+ "version": "9.8.1-next.957ca95e4c.0",
4
4
  "description": "Generic block editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -33,32 +33,33 @@
33
33
  "dependencies": {
34
34
  "@babel/runtime": "^7.16.0",
35
35
  "@react-spring/web": "^9.4.5",
36
- "@wordpress/a11y": "^3.15.0",
37
- "@wordpress/api-fetch": "^6.12.0",
38
- "@wordpress/blob": "^3.15.0",
39
- "@wordpress/blocks": "^11.14.0",
40
- "@wordpress/components": "^19.17.0",
41
- "@wordpress/compose": "^5.13.0",
42
- "@wordpress/data": "^6.15.0",
43
- "@wordpress/date": "^4.15.0",
44
- "@wordpress/deprecated": "^3.15.0",
45
- "@wordpress/dom": "^3.15.0",
46
- "@wordpress/element": "^4.13.0",
47
- "@wordpress/hooks": "^3.15.0",
48
- "@wordpress/html-entities": "^3.15.0",
49
- "@wordpress/i18n": "^4.15.0",
50
- "@wordpress/icons": "^9.6.0",
51
- "@wordpress/is-shallow-equal": "^4.15.0",
52
- "@wordpress/keyboard-shortcuts": "^3.13.0",
53
- "@wordpress/keycodes": "^3.15.0",
54
- "@wordpress/notices": "^3.15.0",
55
- "@wordpress/rich-text": "^5.13.0",
56
- "@wordpress/shortcode": "^3.15.0",
57
- "@wordpress/style-engine": "^0.14.0",
58
- "@wordpress/token-list": "^2.15.0",
59
- "@wordpress/url": "^3.16.0",
60
- "@wordpress/warning": "^2.15.0",
61
- "@wordpress/wordcount": "^3.15.0",
36
+ "@wordpress/a11y": "^3.16.1-next.957ca95e4c.0",
37
+ "@wordpress/api-fetch": "^6.13.1-next.957ca95e4c.0",
38
+ "@wordpress/blob": "^3.16.1-next.957ca95e4c.0",
39
+ "@wordpress/blocks": "^11.15.1-next.957ca95e4c.0",
40
+ "@wordpress/components": "^20.0.2-next.957ca95e4c.0",
41
+ "@wordpress/compose": "^5.14.1-next.957ca95e4c.0",
42
+ "@wordpress/data": "^7.0.1-next.957ca95e4c.0",
43
+ "@wordpress/date": "^4.16.1-next.957ca95e4c.0",
44
+ "@wordpress/deprecated": "^3.16.1-next.957ca95e4c.0",
45
+ "@wordpress/dom": "^3.16.1-next.957ca95e4c.0",
46
+ "@wordpress/element": "^4.14.1-next.957ca95e4c.0",
47
+ "@wordpress/hooks": "^3.16.1-next.957ca95e4c.0",
48
+ "@wordpress/html-entities": "^3.16.1-next.957ca95e4c.0",
49
+ "@wordpress/i18n": "^4.16.1-next.957ca95e4c.0",
50
+ "@wordpress/icons": "^9.7.1-next.957ca95e4c.0",
51
+ "@wordpress/is-shallow-equal": "^4.16.1-next.957ca95e4c.0",
52
+ "@wordpress/keyboard-shortcuts": "^3.14.1-next.957ca95e4c.0",
53
+ "@wordpress/keycodes": "^3.16.1-next.957ca95e4c.0",
54
+ "@wordpress/notices": "^3.16.1-next.957ca95e4c.0",
55
+ "@wordpress/rich-text": "^5.14.1-next.957ca95e4c.0",
56
+ "@wordpress/shortcode": "^3.16.1-next.957ca95e4c.0",
57
+ "@wordpress/style-engine": "^0.15.1-next.957ca95e4c.0",
58
+ "@wordpress/token-list": "^2.16.1-next.957ca95e4c.0",
59
+ "@wordpress/url": "^3.17.1-next.957ca95e4c.0",
60
+ "@wordpress/warning": "^2.16.1-next.957ca95e4c.0",
61
+ "@wordpress/wordcount": "^3.16.1-next.957ca95e4c.0",
62
+ "change-case": "^4.1.2",
62
63
  "classnames": "^2.3.1",
63
64
  "colord": "^2.7.0",
64
65
  "diff": "^4.0.2",
@@ -68,6 +69,7 @@
68
69
  "react-autosize-textarea": "^7.1.0",
69
70
  "react-easy-crop": "^3.0.0",
70
71
  "rememo": "^4.0.0",
72
+ "remove-accents": "^0.4.2",
71
73
  "traverse": "^0.6.6"
72
74
  },
73
75
  "peerDependencies": {
@@ -77,5 +79,5 @@
77
79
  "publishConfig": {
78
80
  "access": "public"
79
81
  },
80
- "gitHead": "08358f53b627a15148c3a3e433cdf58cf8714aa4"
82
+ "gitHead": "272a74bbbaab10ee24424eafe9578e705fbfbbb4"
81
83
  }
@@ -46,7 +46,7 @@ export default function useAvailableAlignments( controls = DEFAULT_CONTROLS ) {
46
46
  }
47
47
 
48
48
  // Starting here, it's the fallback for themes not supporting the layout config.
49
- if ( layoutType.name !== 'default' ) {
49
+ if ( layoutType.name !== 'default' && layoutType.name !== 'constrained' ) {
50
50
  return [];
51
51
  }
52
52
  const { alignments: availableAlignments = DEFAULT_CONTROLS } = layout;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { ToolbarButton, ToolbarGroup } from '@wordpress/components';
5
+ import { __ } from '@wordpress/i18n';
6
+ import { useSelect, useDispatch } from '@wordpress/data';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { store as blockEditorStore } from '../../store';
12
+
13
+ export default function BlockEditVisuallyButton( { clientIds } ) {
14
+ // Edit visually only works for single block selection.
15
+ const clientId = clientIds.length === 1 ? clientIds[ 0 ] : undefined;
16
+ const canEditVisually = useSelect(
17
+ ( select ) =>
18
+ !! clientId &&
19
+ select( blockEditorStore ).getBlockMode( clientId ) === 'html',
20
+ [ clientId ]
21
+ );
22
+ const { toggleBlockMode } = useDispatch( blockEditorStore );
23
+
24
+ if ( ! canEditVisually ) {
25
+ return null;
26
+ }
27
+
28
+ return (
29
+ <ToolbarGroup>
30
+ <ToolbarButton
31
+ onClick={ () => {
32
+ toggleBlockMode( clientId );
33
+ } }
34
+ >
35
+ { __( 'Edit visually' ) }
36
+ </ToolbarButton>
37
+ </ToolbarGroup>
38
+ );
39
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { View } from 'react-native';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { store as blockEditorStore } from '@wordpress/block-editor';
10
+ import { useSelect } from '@wordpress/data';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import styles from './style.scss';
16
+ import BlockListBlock from './block';
17
+
18
+ /**
19
+ * NOTE: This is a component currently used by the List block (V2)
20
+ * It only passes the needed props for this block, if other blocks will use it
21
+ * make sure you pass other props that might be required coming from:
22
+ * components/inner-blocks/index.native.js
23
+ */
24
+
25
+ function BlockListCompact( props ) {
26
+ const {
27
+ marginHorizontal = styles.defaultBlock.marginLeft,
28
+ marginVertical = styles.defaultBlock.marginTop,
29
+ rootClientId,
30
+ } = props;
31
+ const { blockClientIds } = useSelect(
32
+ ( select ) => {
33
+ const { getBlockOrder } = select( blockEditorStore );
34
+ const blockOrder = getBlockOrder( rootClientId );
35
+
36
+ return {
37
+ blockClientIds: blockOrder,
38
+ };
39
+ },
40
+ [ rootClientId ]
41
+ );
42
+
43
+ const containerStyle = {
44
+ marginVertical: -marginVertical,
45
+ marginHorizontal: -marginHorizontal,
46
+ };
47
+
48
+ return (
49
+ <View style={ containerStyle }>
50
+ { blockClientIds.map( ( currentClientId ) => (
51
+ <BlockListBlock
52
+ clientId={ currentClientId }
53
+ key={ currentClientId }
54
+ marginHorizontal={ marginHorizontal }
55
+ marginVertical={ marginVertical }
56
+ />
57
+ ) ) }
58
+ </View>
59
+ );
60
+ }
61
+
62
+ export default BlockListCompact;
@@ -4,10 +4,6 @@
4
4
  margin: 0;
5
5
  }
6
6
 
7
- /**
8
- * Notices & Block Selected/Hover Styles.
9
- */
10
-
11
7
  /**
12
8
  * Cross-Block Selection
13
9
  */
@@ -104,8 +100,20 @@
104
100
  border-color: var(--wp-admin-theme-color);
105
101
  }
106
102
  }
107
- }
108
103
 
104
+ // Ensure an accurate partial text selection.
105
+ // To do this, we disable text selection on the main container, then re-enable it only on the
106
+ // elements that actually get selected.
107
+ // To keep in mind: user-select is currently inherited to all nodes inside.
108
+ .has-multi-selection & {
109
+ user-select: none;
110
+ }
111
+
112
+ // Re-enable it on components inside.
113
+ [class^="components-"] {
114
+ user-select: text;
115
+ }
116
+ }
109
117
 
110
118
  .is-block-moving-mode.block-editor-block-list__block-selection-button {
111
119
  // Should be invisible but not unfocusable.
@@ -118,6 +126,19 @@
118
126
  .block-editor-block-list__layout .block-editor-block-list__block {
119
127
  position: relative;
120
128
 
129
+ // Re-enable text-selection on editable blocks.
130
+ user-select: text;
131
+
132
+ // Hide the select style pseudo element as it interferes with the style.
133
+ &.is-partially-selected::after {
134
+ height: 0;
135
+ }
136
+
137
+ &.is-highlighted::after,
138
+ &.is-highlighted ~ .is-multi-selected::after {
139
+ height: auto;
140
+ }
141
+
121
142
  // Break long strings of text without spaces so they don't overflow the block.
122
143
  overflow-wrap: break-word;
123
144
 
@@ -192,7 +213,9 @@
192
213
  bottom: 0;
193
214
  left: 0;
194
215
  border-radius: $radius-block-ui;
195
- box-shadow: 0 0 0 var(--wp-admin-border-width-focus) transparent;
216
+ box-shadow: 0 0 0 0 transparent;
217
+ transition: box-shadow 0.1s linear;
218
+ @include reduce-motion("transition");
196
219
  }
197
220
 
198
221
  // Warnings
@@ -85,7 +85,7 @@ export function useFocusFirstElement( clientId ) {
85
85
  const { ownerDocument } = ref.current;
86
86
 
87
87
  // Do not focus the block if it already contains the active element.
88
- if ( ref.current.contains( ownerDocument.activeElement ) ) {
88
+ if ( isInsideRootBlock( ref.current, ownerDocument.activeElement ) ) {
89
89
  return;
90
90
  }
91
91
 
@@ -154,7 +154,10 @@ function BlockPopoverInbetween( {
154
154
 
155
155
  const popoverScrollRef = usePopoverScroll( __unstableContentRef );
156
156
 
157
- if ( ! previousElement || ! nextElement || ! isVisible ) {
157
+ // If there's either a previous or a next element, show the inbetween popover.
158
+ // Note that drag and drop uses the inbetween popover to show the drop indicator
159
+ // before the first block and after the last block.
160
+ if ( ( ! previousElement && ! nextElement ) || ! isVisible ) {
158
161
  return null;
159
162
  }
160
163
 
@@ -6,8 +6,9 @@ import classnames from 'classnames';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
+ import { useMergeRefs } from '@wordpress/compose';
9
10
  import { Popover } from '@wordpress/components';
10
- import { useMemo } from '@wordpress/element';
11
+ import { forwardRef, useMemo } from '@wordpress/element';
11
12
 
12
13
  /**
13
14
  * Internal dependencies
@@ -15,19 +16,25 @@ import { useMemo } from '@wordpress/element';
15
16
  import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs';
16
17
  import usePopoverScroll from './use-popover-scroll';
17
18
 
18
- export default function BlockPopover( {
19
- clientId,
20
- bottomClientId,
21
- children,
22
- __unstableRefreshSize,
23
- __unstableCoverTarget = false,
24
- __unstablePopoverSlot,
25
- __unstableContentRef,
26
- ...props
27
- } ) {
19
+ function BlockPopover(
20
+ {
21
+ clientId,
22
+ bottomClientId,
23
+ children,
24
+ __unstableRefreshSize,
25
+ __unstableCoverTarget = false,
26
+ __unstablePopoverSlot,
27
+ __unstableContentRef,
28
+ ...props
29
+ },
30
+ ref
31
+ ) {
28
32
  const selectedElement = useBlockElement( clientId );
29
33
  const lastSelectedElement = useBlockElement( bottomClientId ?? clientId );
30
- const popoverScrollRef = usePopoverScroll( __unstableContentRef );
34
+ const mergedRefs = useMergeRefs( [
35
+ ref,
36
+ usePopoverScroll( __unstableContentRef ),
37
+ ] );
31
38
  const style = useMemo( () => {
32
39
  if ( ! selectedElement || lastSelectedElement !== selectedElement ) {
33
40
  return {};
@@ -51,7 +58,7 @@ export default function BlockPopover( {
51
58
 
52
59
  return (
53
60
  <Popover
54
- ref={ popoverScrollRef }
61
+ ref={ mergedRefs }
55
62
  animate={ false }
56
63
  position="top right left"
57
64
  focusOnMount={ false }
@@ -59,8 +66,6 @@ export default function BlockPopover( {
59
66
  // Render in the old slot if needed for backward compatibility,
60
67
  // otherwise render in place (not in the default popover slot).
61
68
  __unstableSlotName={ __unstablePopoverSlot || null }
62
- // Observe movement for block animations (especially horizontal).
63
- __unstableObserveElement={ selectedElement }
64
69
  __unstableForcePosition
65
70
  __unstableShift
66
71
  { ...props }
@@ -74,3 +79,5 @@ export default function BlockPopover( {
74
79
  </Popover>
75
80
  );
76
81
  }
82
+
83
+ export default forwardRef( BlockPopover );
@@ -7,24 +7,20 @@ import { ToolbarGroup, ToolbarItem } from '@wordpress/components';
7
7
  * Internal dependencies
8
8
  */
9
9
  import BlockSettingsDropdown from './block-settings-dropdown';
10
- import BlockEditVisuallyButton from './block-edit-visually-button';
11
10
 
12
11
  export function BlockSettingsMenu( { clientIds, ...props } ) {
13
12
  return (
14
- <>
15
- <BlockEditVisuallyButton clientIds={ clientIds } { ...props } />
16
- <ToolbarGroup>
17
- <ToolbarItem>
18
- { ( toggleProps ) => (
19
- <BlockSettingsDropdown
20
- clientIds={ clientIds }
21
- toggleProps={ toggleProps }
22
- { ...props }
23
- />
24
- ) }
25
- </ToolbarItem>
26
- </ToolbarGroup>
27
- </>
13
+ <ToolbarGroup>
14
+ <ToolbarItem>
15
+ { ( toggleProps ) => (
16
+ <BlockSettingsDropdown
17
+ clientIds={ clientIds }
18
+ toggleProps={ toggleProps }
19
+ { ...props }
20
+ />
21
+ ) }
22
+ </ToolbarItem>
23
+ </ToolbarGroup>
28
24
  );
29
25
  }
30
26
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { castArray, uniq } from 'lodash';
4
+ import { castArray } from 'lodash';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -28,10 +28,10 @@ import { copy } from '@wordpress/icons';
28
28
  import { store as blockEditorStore } from '../../store';
29
29
  import useBlockDisplayInformation from '../use-block-display-information';
30
30
  import BlockIcon from '../block-icon';
31
- import BlockTitle from '../block-title';
32
31
  import BlockTransformationsMenu from './block-transformations-menu';
33
32
  import BlockStylesMenu from './block-styles-menu';
34
33
  import PatternTransformationsMenu from './pattern-transformations-menu';
34
+ import useBlockDisplayTitle from '../block-title/use-block-display-title';
35
35
 
36
36
  export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
37
37
  const { replaceBlocks } = useDispatch( blockEditorStore );
@@ -41,7 +41,6 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
41
41
  canRemove,
42
42
  hasBlockStyles,
43
43
  icon,
44
- blockTitle,
45
44
  patterns,
46
45
  } = useSelect(
47
46
  ( select ) => {
@@ -64,7 +63,7 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
64
63
  _icon = blockInformation?.icon; // Take into account active block variations.
65
64
  } else {
66
65
  const isSelectionOfSameType =
67
- uniq( blocks.map( ( { name } ) => name ) ).length === 1;
66
+ new Set( blocks.map( ( { name } ) => name ) ).size === 1;
68
67
  // When selection consists of blocks of multiple types, display an
69
68
  // appropriate icon to communicate the non-uniformity.
70
69
  _icon = isSelectionOfSameType
@@ -79,7 +78,6 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
79
78
  canRemove: canRemoveBlocks( clientIds, rootClientId ),
80
79
  hasBlockStyles: !! styles?.length,
81
80
  icon: _icon,
82
- blockTitle: getBlockType( firstBlockName )?.title,
83
81
  patterns: __experimentalGetPatternTransformItems(
84
82
  blocks,
85
83
  rootClientId
@@ -89,6 +87,10 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
89
87
  [ clientIds, blocks, blockInformation?.icon ]
90
88
  );
91
89
 
90
+ const blockTitle = useBlockDisplayTitle( {
91
+ clientId: Array.isArray( clientIds ) ? clientIds[ 0 ] : clientIds,
92
+ maximumLength: 35,
93
+ } );
92
94
  const isReusable = blocks.length === 1 && isReusableBlock( blocks[ 0 ] );
93
95
  const isTemplate = blocks.length === 1 && isTemplatePart( blocks[ 0 ] );
94
96
 
@@ -119,10 +121,7 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
119
121
  <BlockIcon icon={ icon } showColors />
120
122
  { ( isReusable || isTemplate ) && (
121
123
  <span className="block-editor-block-switcher__toggle-text">
122
- <BlockTitle
123
- clientId={ clientIds }
124
- maximumLength={ 35 }
125
- />
124
+ { blockTitle }
126
125
  </span>
127
126
  ) }
128
127
  </>
@@ -176,10 +175,7 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
176
175
  />
177
176
  { ( isReusable || isTemplate ) && (
178
177
  <span className="block-editor-block-switcher__toggle-text">
179
- <BlockTitle
180
- clientId={ clientIds }
181
- maximumLength={ 35 }
182
- />
178
+ { blockTitle }
183
179
  </span>
184
180
  ) }
185
181
  </>
@@ -8,7 +8,6 @@ import { shallow, mount } from 'enzyme';
8
8
  */
9
9
  import { useSelect } from '@wordpress/data';
10
10
  import { registerBlockType, unregisterBlockType } from '@wordpress/blocks';
11
- import { DOWN } from '@wordpress/keycodes';
12
11
  import { Button } from '@wordpress/components';
13
12
  import { copy } from '@wordpress/icons';
14
13
 
@@ -18,6 +17,7 @@ import { copy } from '@wordpress/icons';
18
17
  import { BlockSwitcher, BlockSwitcherDropdownMenu } from '../';
19
18
 
20
19
  jest.mock( '@wordpress/data/src/components/use-select', () => jest.fn() );
20
+ jest.mock( '../../block-title/use-block-display-title', () => jest.fn() );
21
21
 
22
22
  describe( 'BlockSwitcher', () => {
23
23
  test( 'should not render block switcher without blocks', () => {
@@ -179,7 +179,7 @@ describe( 'BlockSwitcherDropdownMenu', () => {
179
179
  const onToggleStub = jest.fn();
180
180
  const mockKeyDown = {
181
181
  preventDefault: () => {},
182
- keyCode: DOWN,
182
+ code: 'ArrowDown',
183
183
  };
184
184
 
185
185
  afterEach( () => {
@@ -23,6 +23,7 @@ import __unstableBlockToolbarLastItem from './block-toolbar-last-item';
23
23
  import BlockSettingsMenu from '../block-settings-menu';
24
24
  import { BlockLockToolbar } from '../block-lock';
25
25
  import { BlockGroupToolbar } from '../convert-to-group-buttons';
26
+ import BlockEditVisuallyButton from '../block-edit-visually-button';
26
27
  import { useShowMoversGestures } from './utils';
27
28
  import { store as blockEditorStore } from '../../store';
28
29
  import __unstableBlockNameContext from './block-name-context';
@@ -159,6 +160,7 @@ const BlockToolbar = ( { hideDragHandle } ) => {
159
160
  </__unstableBlockNameContext.Provider>
160
161
  </>
161
162
  ) }
163
+ <BlockEditVisuallyButton clientIds={ blockClientIds } />
162
164
  <BlockSettingsMenu clientIds={ blockClientIds } />
163
165
  </div>
164
166
  );
@@ -20,6 +20,7 @@ import BlockSelectionButton from './block-selection-button';
20
20
  import BlockContextualToolbar from './block-contextual-toolbar';
21
21
  import { store as blockEditorStore } from '../../store';
22
22
  import BlockPopover from '../block-popover';
23
+ import useBlockToolbarPopoverProps from './use-block-toolbar-popover-props';
23
24
 
24
25
  function selector( select ) {
25
26
  const {
@@ -113,6 +114,11 @@ function SelectedBlockPopover( {
113
114
  // to it when re-mounting.
114
115
  const initialToolbarItemIndexRef = useRef();
115
116
 
117
+ const popoverProps = useBlockToolbarPopoverProps( {
118
+ contentElement: __unstableContentRef?.current,
119
+ clientId,
120
+ } );
121
+
116
122
  if ( ! shouldShowBreadcrumb && ! shouldShowContextualToolbar ) {
117
123
  return null;
118
124
  }
@@ -126,6 +132,7 @@ function SelectedBlockPopover( {
126
132
  } ) }
127
133
  __unstablePopoverSlot={ __unstablePopoverSlot }
128
134
  __unstableContentRef={ __unstableContentRef }
135
+ { ...popoverProps }
129
136
  >
130
137
  { shouldShowContextualToolbar && (
131
138
  <BlockContextualToolbar
@@ -0,0 +1,123 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useRefEffect } from '@wordpress/compose';
5
+ import { useSelect } from '@wordpress/data';
6
+ import { useCallback, useLayoutEffect, useState } from '@wordpress/element';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { store as blockEditorStore } from '../../store';
12
+ import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs';
13
+
14
+ // By default the toolbar sets the `shift` prop. If the user scrolls the page
15
+ // down the toolbar will stay on screen by adopting a sticky position at the
16
+ // top of the viewport.
17
+ const DEFAULT_PROPS = { __unstableForcePosition: true, __unstableShift: true };
18
+
19
+ // When there isn't enough height between the top of the block and the editor
20
+ // canvas, the `shift` prop is set to `false`, as it will cause the block to be
21
+ // obscured. The `flip` behavior is enabled (by setting `forcePosition` to
22
+ // `false`), which positions the toolbar below the block.
23
+ const RESTRICTED_HEIGHT_PROPS = {
24
+ __unstableForcePosition: false,
25
+ __unstableShift: false,
26
+ };
27
+
28
+ /**
29
+ * Get the popover props for the block toolbar, determined by the space at the top of the canvas and the toolbar height.
30
+ *
31
+ * @param {Element} contentElement The DOM element that represents the editor content or canvas.
32
+ * @param {Element} selectedBlockElement The outer DOM element of the first selected block.
33
+ * @param {number} toolbarHeight The height of the toolbar in pixels.
34
+ *
35
+ * @return {Object} The popover props used to determine the position of the toolbar.
36
+ */
37
+ function getProps( contentElement, selectedBlockElement, toolbarHeight ) {
38
+ if ( ! contentElement || ! selectedBlockElement ) {
39
+ return DEFAULT_PROPS;
40
+ }
41
+
42
+ const blockRect = selectedBlockElement.getBoundingClientRect();
43
+ const contentRect = contentElement.getBoundingClientRect();
44
+
45
+ if ( blockRect.top - contentRect.top > toolbarHeight ) {
46
+ return DEFAULT_PROPS;
47
+ }
48
+
49
+ return RESTRICTED_HEIGHT_PROPS;
50
+ }
51
+
52
+ /**
53
+ * Determines the desired popover positioning behavior, returning a set of appropriate props.
54
+ *
55
+ * @param {Object} elements
56
+ * @param {Element} elements.contentElement The DOM element that represents the editor content or canvas.
57
+ * @param {string} elements.clientId The clientId of the first selected block.
58
+ *
59
+ * @return {Object} The popover props used to determine the position of the toolbar.
60
+ */
61
+ export default function useBlockToolbarPopoverProps( {
62
+ contentElement,
63
+ clientId,
64
+ } ) {
65
+ const selectedBlockElement = useBlockElement( clientId );
66
+ const [ toolbarHeight, setToolbarHeight ] = useState( 0 );
67
+ const [ props, setProps ] = useState( () =>
68
+ getProps( contentElement, selectedBlockElement, toolbarHeight )
69
+ );
70
+ const blockIndex = useSelect(
71
+ ( select ) => select( blockEditorStore ).getBlockIndex( clientId ),
72
+ [ clientId ]
73
+ );
74
+
75
+ const popoverRef = useRefEffect( ( popoverNode ) => {
76
+ setToolbarHeight( popoverNode.offsetHeight );
77
+ }, [] );
78
+
79
+ const updateProps = useCallback(
80
+ () =>
81
+ setProps(
82
+ getProps( contentElement, selectedBlockElement, toolbarHeight )
83
+ ),
84
+ [ contentElement, selectedBlockElement, toolbarHeight ]
85
+ );
86
+
87
+ // Update props when the block is moved. This also ensures the props are
88
+ // correct on initial mount, and when the selected block or content element
89
+ // changes (since the callback ref will update).
90
+ useLayoutEffect( updateProps, [ blockIndex, updateProps ] );
91
+
92
+ // Update props when the viewport is resized or the block is resized.
93
+ useLayoutEffect( () => {
94
+ if ( ! contentElement || ! selectedBlockElement ) {
95
+ return;
96
+ }
97
+
98
+ // Update the toolbar props on viewport resize.
99
+ const contentView = contentElement?.ownerDocument?.defaultView;
100
+ contentView?.addEventHandler?.( 'resize', updateProps );
101
+
102
+ // Update the toolbar props on block resize.
103
+ let resizeObserver;
104
+ const blockView = selectedBlockElement?.ownerDocument?.defaultView;
105
+ if ( blockView.ResizeObserver ) {
106
+ resizeObserver = new blockView.ResizeObserver( updateProps );
107
+ resizeObserver.observe( selectedBlockElement );
108
+ }
109
+
110
+ return () => {
111
+ contentView?.removeEventHandler?.( 'resize', updateProps );
112
+
113
+ if ( resizeObserver ) {
114
+ resizeObserver.disconnect();
115
+ }
116
+ };
117
+ }, [ updateProps, contentElement, selectedBlockElement ] );
118
+
119
+ return {
120
+ ...props,
121
+ ref: popoverRef,
122
+ };
123
+ }