@wordpress/block-editor 8.3.0 → 8.5.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 (443) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +56 -18
  3. package/build/components/alignment-control/index.js +13 -6
  4. package/build/components/alignment-control/index.js.map +1 -1
  5. package/build/components/block-alignment-control/index.js +13 -6
  6. package/build/components/block-alignment-control/index.js.map +1 -1
  7. package/build/components/block-draggable/index.js +2 -3
  8. package/build/components/block-draggable/index.js.map +1 -1
  9. package/build/components/block-icon/index.js +4 -0
  10. package/build/components/block-icon/index.js.map +1 -1
  11. package/build/components/block-inspector/index.js +6 -1
  12. package/build/components/block-inspector/index.js.map +1 -1
  13. package/build/components/block-list/block-html.js +4 -1
  14. package/build/components/block-list/block-html.js.map +1 -1
  15. package/build/components/block-list/block.js +4 -1
  16. package/build/components/block-list/block.js.map +1 -1
  17. package/build/components/block-list/use-block-props/index.js +1 -6
  18. package/build/components/block-list/use-block-props/index.js.map +1 -1
  19. package/build/components/block-list/use-block-props/use-focus-first-element.js +22 -6
  20. package/build/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
  21. package/build/components/block-list/use-block-props/use-focus-handler.js +7 -1
  22. package/build/components/block-list/use-block-props/use-focus-handler.js.map +1 -1
  23. package/build/components/block-list-appender/index.js +6 -1
  24. package/build/components/block-list-appender/index.js.map +1 -1
  25. package/build/components/block-lock/index.js +32 -0
  26. package/build/components/block-lock/index.js.map +1 -0
  27. package/build/components/block-lock/menu-item.js +67 -0
  28. package/build/components/block-lock/menu-item.js.map +1 -0
  29. package/build/components/block-lock/modal.js +134 -0
  30. package/build/components/block-lock/modal.js.map +1 -0
  31. package/build/components/block-lock/toolbar.js +78 -0
  32. package/build/components/block-lock/toolbar.js.map +1 -0
  33. package/build/components/block-mover/index.js +4 -0
  34. package/build/components/block-mover/index.js.map +1 -1
  35. package/build/components/block-settings-menu/block-settings-dropdown.js +75 -10
  36. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  37. package/build/components/block-settings-menu-controls/index.js +19 -9
  38. package/build/components/block-settings-menu-controls/index.js.map +1 -1
  39. package/build/components/block-switcher/index.js +1 -1
  40. package/build/components/block-switcher/index.js.map +1 -1
  41. package/build/components/block-title/index.js +2 -2
  42. package/build/components/block-title/index.js.map +1 -1
  43. package/build/components/block-title/use-block-display-title.js +8 -6
  44. package/build/components/block-title/use-block-display-title.js.map +1 -1
  45. package/build/components/block-toolbar/block-name-context.js +17 -0
  46. package/build/components/block-toolbar/block-name-context.js.map +1 -0
  47. package/build/components/block-toolbar/block-toolbar-last-item.js +20 -0
  48. package/build/components/block-toolbar/block-toolbar-last-item.js.map +1 -0
  49. package/build/components/block-toolbar/index.js +24 -5
  50. package/build/components/block-toolbar/index.js.map +1 -1
  51. package/build/components/block-tools/index.js +0 -16
  52. package/build/components/block-tools/index.js.map +1 -1
  53. package/build/components/block-variation-transforms/index.js +92 -47
  54. package/build/components/block-variation-transforms/index.js.map +1 -1
  55. package/build/components/block-vertical-alignment-control/index.js +13 -6
  56. package/build/components/block-vertical-alignment-control/index.js.map +1 -1
  57. package/build/components/border-radius-control/index.js +0 -1
  58. package/build/components/border-radius-control/index.js.map +1 -1
  59. package/build/components/border-radius-control/utils.js +1 -1
  60. package/build/components/border-radius-control/utils.js.map +1 -1
  61. package/build/components/colors-gradients/control.js +3 -1
  62. package/build/components/colors-gradients/control.js.map +1 -1
  63. package/build/components/contrast-checker/index.js +4 -0
  64. package/build/components/contrast-checker/index.js.map +1 -1
  65. package/build/components/convert-to-group-buttons/index.js +8 -0
  66. package/build/components/convert-to-group-buttons/index.js.map +1 -1
  67. package/build/components/convert-to-group-buttons/toolbar.js +105 -0
  68. package/build/components/convert-to-group-buttons/toolbar.js.map +1 -0
  69. package/build/components/copy-handler/index.js +4 -0
  70. package/build/components/copy-handler/index.js.map +1 -1
  71. package/build/components/date-format-picker/index.js +132 -0
  72. package/build/components/date-format-picker/index.js.map +1 -0
  73. package/build/components/font-sizes/font-size-picker.js +4 -0
  74. package/build/components/font-sizes/font-size-picker.js.map +1 -1
  75. package/build/components/iframe/index.js +6 -9
  76. package/build/components/iframe/index.js.map +1 -1
  77. package/build/components/index.js +27 -0
  78. package/build/components/index.js.map +1 -1
  79. package/build/components/justify-content-control/index.js +13 -6
  80. package/build/components/justify-content-control/index.js.map +1 -1
  81. package/build/components/keyboard-shortcuts/index.js +1 -1
  82. package/build/components/keyboard-shortcuts/index.js.map +1 -1
  83. package/build/components/line-height-control/index.js +15 -6
  84. package/build/components/line-height-control/index.js.map +1 -1
  85. package/build/components/list-view/block-select-button.js +24 -23
  86. package/build/components/list-view/block-select-button.js.map +1 -1
  87. package/build/components/list-view/block.js +38 -13
  88. package/build/components/list-view/block.js.map +1 -1
  89. package/build/components/list-view/branch.js +16 -13
  90. package/build/components/list-view/branch.js.map +1 -1
  91. package/build/components/list-view/index.js +7 -1
  92. package/build/components/list-view/index.js.map +1 -1
  93. package/build/components/list-view/use-block-selection.js +9 -2
  94. package/build/components/list-view/use-block-selection.js.map +1 -1
  95. package/build/components/media-replace-flow/index.js +4 -0
  96. package/build/components/media-replace-flow/index.js.map +1 -1
  97. package/build/components/multi-selection-inspector/index.js +1 -1
  98. package/build/components/multi-selection-inspector/index.js.map +1 -1
  99. package/build/components/rich-text/index.js +27 -5
  100. package/build/components/rich-text/index.js.map +1 -1
  101. package/build/components/rich-text/index.native.js +13 -9
  102. package/build/components/rich-text/index.native.js.map +1 -1
  103. package/build/components/rich-text/split-value.js +12 -2
  104. package/build/components/rich-text/split-value.js.map +1 -1
  105. package/build/components/rich-text/use-firefox-compat.js +49 -0
  106. package/build/components/rich-text/use-firefox-compat.js.map +1 -0
  107. package/build/components/rich-text/use-input-rules.js +34 -2
  108. package/build/components/rich-text/use-input-rules.js.map +1 -1
  109. package/build/components/skip-to-selected-block/index.js +4 -0
  110. package/build/components/skip-to-selected-block/index.js.map +1 -1
  111. package/build/components/url-popover/image-url-input-ui.js +11 -27
  112. package/build/components/url-popover/image-url-input-ui.js.map +1 -1
  113. package/build/components/writing-flow/index.js +9 -1
  114. package/build/components/writing-flow/index.js.map +1 -1
  115. package/build/components/writing-flow/use-arrow-nav.js +3 -44
  116. package/build/components/writing-flow/use-arrow-nav.js.map +1 -1
  117. package/build/components/writing-flow/use-click-selection.js +68 -0
  118. package/build/components/writing-flow/use-click-selection.js.map +1 -0
  119. package/build/components/writing-flow/use-drag-selection.js +134 -0
  120. package/build/components/writing-flow/use-drag-selection.js.map +1 -0
  121. package/build/components/writing-flow/use-input.js +116 -0
  122. package/build/components/writing-flow/use-input.js.map +1 -0
  123. package/build/components/writing-flow/use-multi-selection.js +18 -38
  124. package/build/components/writing-flow/use-multi-selection.js.map +1 -1
  125. package/build/components/writing-flow/use-selection-observer.js +161 -0
  126. package/build/components/writing-flow/use-selection-observer.js.map +1 -0
  127. package/build/components/writing-flow/use-tab-nav.js +1 -8
  128. package/build/components/writing-flow/use-tab-nav.js.map +1 -1
  129. package/build/hooks/anchor.js +7 -6
  130. package/build/hooks/anchor.js.map +1 -1
  131. package/build/hooks/border-color.js +3 -3
  132. package/build/hooks/border-color.js.map +1 -1
  133. package/build/hooks/border.js +0 -14
  134. package/build/hooks/border.js.map +1 -1
  135. package/build/hooks/color.js +20 -17
  136. package/build/hooks/color.js.map +1 -1
  137. package/build/hooks/font-family.js +5 -1
  138. package/build/hooks/font-family.js.map +1 -1
  139. package/build/hooks/font-size.js +4 -2
  140. package/build/hooks/font-size.js.map +1 -1
  141. package/build/hooks/gap.js +77 -5
  142. package/build/hooks/gap.js.map +1 -1
  143. package/build/hooks/layout.js +7 -2
  144. package/build/hooks/layout.js.map +1 -1
  145. package/build/hooks/style.js +34 -3
  146. package/build/hooks/style.js.map +1 -1
  147. package/build/hooks/utils.js +29 -0
  148. package/build/hooks/utils.js.map +1 -1
  149. package/build/layouts/flex.js +82 -15
  150. package/build/layouts/flex.js.map +1 -1
  151. package/build/layouts/flow.js +22 -13
  152. package/build/layouts/flow.js.map +1 -1
  153. package/build/store/actions.js +297 -51
  154. package/build/store/actions.js.map +1 -1
  155. package/build/store/defaults.js +5 -1
  156. package/build/store/defaults.js.map +1 -1
  157. package/build/store/reducer.js +25 -13
  158. package/build/store/reducer.js.map +1 -1
  159. package/build/store/selectors.js +171 -21
  160. package/build/store/selectors.js.map +1 -1
  161. package/build/utils/dom.js +2 -1
  162. package/build/utils/dom.js.map +1 -1
  163. package/build-module/components/alignment-control/index.js +12 -4
  164. package/build-module/components/alignment-control/index.js.map +1 -1
  165. package/build-module/components/block-alignment-control/index.js +12 -4
  166. package/build-module/components/block-alignment-control/index.js.map +1 -1
  167. package/build-module/components/block-draggable/index.js +2 -3
  168. package/build-module/components/block-draggable/index.js.map +1 -1
  169. package/build-module/components/block-icon/index.js +4 -0
  170. package/build-module/components/block-icon/index.js.map +1 -1
  171. package/build-module/components/block-inspector/index.js +6 -1
  172. package/build-module/components/block-inspector/index.js.map +1 -1
  173. package/build-module/components/block-list/block-html.js +5 -2
  174. package/build-module/components/block-list/block-html.js.map +1 -1
  175. package/build-module/components/block-list/block.js +5 -2
  176. package/build-module/components/block-list/block.js.map +1 -1
  177. package/build-module/components/block-list/use-block-props/index.js +1 -4
  178. package/build-module/components/block-list/use-block-props/index.js.map +1 -1
  179. package/build-module/components/block-list/use-block-props/use-focus-first-element.js +22 -6
  180. package/build-module/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
  181. package/build-module/components/block-list/use-block-props/use-focus-handler.js +7 -1
  182. package/build-module/components/block-list/use-block-props/use-focus-handler.js.map +1 -1
  183. package/build-module/components/block-list-appender/index.js +6 -1
  184. package/build-module/components/block-list-appender/index.js.map +1 -1
  185. package/build-module/components/block-lock/index.js +4 -0
  186. package/build-module/components/block-lock/index.js.map +1 -0
  187. package/build-module/components/block-lock/menu-item.js +53 -0
  188. package/build-module/components/block-lock/menu-item.js.map +1 -0
  189. package/build-module/components/block-lock/modal.js +119 -0
  190. package/build-module/components/block-lock/modal.js.map +1 -0
  191. package/build-module/components/block-lock/toolbar.js +63 -0
  192. package/build-module/components/block-lock/toolbar.js.map +1 -0
  193. package/build-module/components/block-mover/index.js +4 -0
  194. package/build-module/components/block-mover/index.js.map +1 -1
  195. package/build-module/components/block-settings-menu/block-settings-dropdown.js +75 -12
  196. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  197. package/build-module/components/block-settings-menu-controls/index.js +18 -9
  198. package/build-module/components/block-settings-menu-controls/index.js.map +1 -1
  199. package/build-module/components/block-switcher/index.js +2 -2
  200. package/build-module/components/block-switcher/index.js.map +1 -1
  201. package/build-module/components/block-title/index.js +2 -2
  202. package/build-module/components/block-title/index.js.map +1 -1
  203. package/build-module/components/block-title/use-block-display-title.js +8 -6
  204. package/build-module/components/block-title/use-block-display-title.js.map +1 -1
  205. package/build-module/components/block-toolbar/block-name-context.js +9 -0
  206. package/build-module/components/block-toolbar/block-name-context.js.map +1 -0
  207. package/build-module/components/block-toolbar/block-toolbar-last-item.js +11 -0
  208. package/build-module/components/block-toolbar/block-toolbar-last-item.js.map +1 -0
  209. package/build-module/components/block-toolbar/index.js +19 -4
  210. package/build-module/components/block-toolbar/index.js.map +1 -1
  211. package/build-module/components/block-tools/index.js +0 -16
  212. package/build-module/components/block-tools/index.js.map +1 -1
  213. package/build-module/components/block-variation-transforms/index.js +95 -49
  214. package/build-module/components/block-variation-transforms/index.js.map +1 -1
  215. package/build-module/components/block-vertical-alignment-control/index.js +12 -4
  216. package/build-module/components/block-vertical-alignment-control/index.js.map +1 -1
  217. package/build-module/components/border-radius-control/index.js +0 -1
  218. package/build-module/components/border-radius-control/index.js.map +1 -1
  219. package/build-module/components/border-radius-control/utils.js +1 -1
  220. package/build-module/components/border-radius-control/utils.js.map +1 -1
  221. package/build-module/components/colors-gradients/control.js +3 -1
  222. package/build-module/components/colors-gradients/control.js.map +1 -1
  223. package/build-module/components/contrast-checker/index.js +4 -0
  224. package/build-module/components/contrast-checker/index.js.map +1 -1
  225. package/build-module/components/convert-to-group-buttons/index.js +2 -1
  226. package/build-module/components/convert-to-group-buttons/index.js.map +1 -1
  227. package/build-module/components/convert-to-group-buttons/toolbar.js +90 -0
  228. package/build-module/components/convert-to-group-buttons/toolbar.js.map +1 -0
  229. package/build-module/components/copy-handler/index.js +4 -0
  230. package/build-module/components/copy-handler/index.js.map +1 -1
  231. package/build-module/components/date-format-picker/index.js +122 -0
  232. package/build-module/components/date-format-picker/index.js.map +1 -0
  233. package/build-module/components/font-sizes/font-size-picker.js +4 -0
  234. package/build-module/components/font-sizes/font-size-picker.js.map +1 -1
  235. package/build-module/components/iframe/index.js +6 -9
  236. package/build-module/components/iframe/index.js.map +1 -1
  237. package/build-module/components/index.js +3 -0
  238. package/build-module/components/index.js.map +1 -1
  239. package/build-module/components/justify-content-control/index.js +12 -4
  240. package/build-module/components/justify-content-control/index.js.map +1 -1
  241. package/build-module/components/keyboard-shortcuts/index.js +1 -1
  242. package/build-module/components/keyboard-shortcuts/index.js.map +1 -1
  243. package/build-module/components/line-height-control/index.js +14 -5
  244. package/build-module/components/line-height-control/index.js.map +1 -1
  245. package/build-module/components/list-view/block-select-button.js +24 -23
  246. package/build-module/components/list-view/block-select-button.js.map +1 -1
  247. package/build-module/components/list-view/block.js +36 -13
  248. package/build-module/components/list-view/block.js.map +1 -1
  249. package/build-module/components/list-view/branch.js +16 -13
  250. package/build-module/components/list-view/branch.js.map +1 -1
  251. package/build-module/components/list-view/index.js +7 -1
  252. package/build-module/components/list-view/index.js.map +1 -1
  253. package/build-module/components/list-view/use-block-selection.js +10 -3
  254. package/build-module/components/list-view/use-block-selection.js.map +1 -1
  255. package/build-module/components/media-replace-flow/index.js +4 -0
  256. package/build-module/components/media-replace-flow/index.js.map +1 -1
  257. package/build-module/components/multi-selection-inspector/index.js +2 -2
  258. package/build-module/components/multi-selection-inspector/index.js.map +1 -1
  259. package/build-module/components/rich-text/index.js +26 -5
  260. package/build-module/components/rich-text/index.js.map +1 -1
  261. package/build-module/components/rich-text/index.native.js +13 -9
  262. package/build-module/components/rich-text/index.native.js.map +1 -1
  263. package/build-module/components/rich-text/split-value.js +12 -2
  264. package/build-module/components/rich-text/split-value.js.map +1 -1
  265. package/build-module/components/rich-text/use-firefox-compat.js +39 -0
  266. package/build-module/components/rich-text/use-firefox-compat.js.map +1 -0
  267. package/build-module/components/rich-text/use-input-rules.js +35 -4
  268. package/build-module/components/rich-text/use-input-rules.js.map +1 -1
  269. package/build-module/components/skip-to-selected-block/index.js +4 -0
  270. package/build-module/components/skip-to-selected-block/index.js.map +1 -1
  271. package/build-module/components/url-popover/image-url-input-ui.js +12 -28
  272. package/build-module/components/url-popover/image-url-input-ui.js.map +1 -1
  273. package/build-module/components/writing-flow/index.js +5 -1
  274. package/build-module/components/writing-flow/index.js.map +1 -1
  275. package/build-module/components/writing-flow/use-arrow-nav.js +4 -45
  276. package/build-module/components/writing-flow/use-arrow-nav.js.map +1 -1
  277. package/build-module/components/writing-flow/use-click-selection.js +57 -0
  278. package/build-module/components/writing-flow/use-click-selection.js.map +1 -0
  279. package/build-module/components/writing-flow/use-drag-selection.js +124 -0
  280. package/build-module/components/writing-flow/use-drag-selection.js.map +1 -0
  281. package/build-module/components/writing-flow/use-input.js +104 -0
  282. package/build-module/components/writing-flow/use-input.js.map +1 -0
  283. package/build-module/components/writing-flow/use-multi-selection.js +18 -37
  284. package/build-module/components/writing-flow/use-multi-selection.js.map +1 -1
  285. package/build-module/components/writing-flow/use-selection-observer.js +150 -0
  286. package/build-module/components/writing-flow/use-selection-observer.js.map +1 -0
  287. package/build-module/components/writing-flow/use-tab-nav.js +1 -9
  288. package/build-module/components/writing-flow/use-tab-nav.js.map +1 -1
  289. package/build-module/hooks/anchor.js +7 -6
  290. package/build-module/hooks/anchor.js.map +1 -1
  291. package/build-module/hooks/border-color.js +5 -5
  292. package/build-module/hooks/border-color.js.map +1 -1
  293. package/build-module/hooks/border.js +0 -12
  294. package/build-module/hooks/border.js.map +1 -1
  295. package/build-module/hooks/color.js +19 -18
  296. package/build-module/hooks/color.js.map +1 -1
  297. package/build-module/hooks/font-family.js +3 -1
  298. package/build-module/hooks/font-family.js.map +1 -1
  299. package/build-module/hooks/font-size.js +4 -3
  300. package/build-module/hooks/font-size.js.map +1 -1
  301. package/build-module/hooks/gap.js +75 -7
  302. package/build-module/hooks/gap.js.map +1 -1
  303. package/build-module/hooks/layout.js +7 -2
  304. package/build-module/hooks/layout.js.map +1 -1
  305. package/build-module/hooks/style.js +33 -3
  306. package/build-module/hooks/style.js.map +1 -1
  307. package/build-module/hooks/utils.js +26 -0
  308. package/build-module/hooks/utils.js.map +1 -1
  309. package/build-module/layouts/flex.js +81 -16
  310. package/build-module/layouts/flex.js.map +1 -1
  311. package/build-module/layouts/flow.js +20 -13
  312. package/build-module/layouts/flow.js.map +1 -1
  313. package/build-module/store/actions.js +286 -49
  314. package/build-module/store/actions.js.map +1 -1
  315. package/build-module/store/defaults.js +5 -1
  316. package/build-module/store/defaults.js.map +1 -1
  317. package/build-module/store/reducer.js +25 -13
  318. package/build-module/store/reducer.js.map +1 -1
  319. package/build-module/store/selectors.js +162 -20
  320. package/build-module/store/selectors.js.map +1 -1
  321. package/build-module/utils/dom.js +2 -1
  322. package/build-module/utils/dom.js.map +1 -1
  323. package/build-style/style-rtl.css +214 -24
  324. package/build-style/style.css +214 -24
  325. package/build-types/utils/dom.d.ts.map +1 -1
  326. package/package.json +28 -27
  327. package/src/components/alignment-control/index.js +9 -4
  328. package/src/components/block-alignment-control/index.js +9 -4
  329. package/src/components/block-draggable/index.js +2 -5
  330. package/src/components/block-icon/index.js +3 -0
  331. package/src/components/block-inspector/index.js +4 -0
  332. package/src/components/block-list/block-html.js +8 -4
  333. package/src/components/block-list/block.js +5 -1
  334. package/src/components/block-list/style.scss +4 -5
  335. package/src/components/block-list/use-block-props/index.js +0 -5
  336. package/src/components/block-list/use-block-props/use-focus-first-element.js +27 -6
  337. package/src/components/block-list/use-block-props/use-focus-handler.js +8 -0
  338. package/src/components/block-list-appender/index.js +5 -0
  339. package/src/components/block-lock/index.js +3 -0
  340. package/src/components/block-lock/menu-item.js +59 -0
  341. package/src/components/block-lock/modal.js +170 -0
  342. package/src/components/block-lock/style.scss +70 -0
  343. package/src/components/block-lock/toolbar.js +68 -0
  344. package/src/components/block-mover/index.js +3 -0
  345. package/src/components/block-mover/style.scss +4 -0
  346. package/src/components/block-settings-menu/block-settings-dropdown.js +109 -9
  347. package/src/components/block-settings-menu-controls/index.js +33 -12
  348. package/src/components/block-switcher/index.js +2 -2
  349. package/src/components/block-switcher/style.scss +8 -1
  350. package/src/components/block-switcher/test/index.js +2 -2
  351. package/src/components/block-title/README.md +6 -1
  352. package/src/components/block-title/index.js +2 -2
  353. package/src/components/block-title/test/index.js +43 -1
  354. package/src/components/block-title/use-block-display-title.js +10 -7
  355. package/src/components/block-toolbar/block-name-context.js +8 -0
  356. package/src/components/block-toolbar/block-toolbar-last-item.js +12 -0
  357. package/src/components/block-toolbar/index.js +24 -2
  358. package/src/components/block-toolbar/style.scss +10 -0
  359. package/src/components/block-tools/index.js +0 -19
  360. package/src/components/block-tools/style.scss +27 -0
  361. package/src/components/block-variation-transforms/index.js +105 -36
  362. package/src/components/block-variation-transforms/style.scss +1 -1
  363. package/src/components/block-vertical-alignment-control/index.js +9 -4
  364. package/src/components/border-radius-control/index.js +0 -1
  365. package/src/components/border-radius-control/test/utils.js +4 -0
  366. package/src/components/border-radius-control/utils.js +2 -1
  367. package/src/components/button-block-appender/style.scss +5 -1
  368. package/src/components/color-palette/test/__snapshots__/control.js.snap +70 -4
  369. package/src/components/colors-gradients/control.js +1 -1
  370. package/src/components/colors-gradients/style.scss +6 -0
  371. package/src/components/contrast-checker/index.js +3 -0
  372. package/src/components/convert-to-group-buttons/index.js +6 -1
  373. package/src/components/convert-to-group-buttons/toolbar.js +87 -0
  374. package/src/components/copy-handler/index.js +3 -0
  375. package/src/components/date-format-picker/README.md +58 -0
  376. package/src/components/date-format-picker/index.js +161 -0
  377. package/src/components/date-format-picker/style.scss +31 -0
  378. package/src/components/font-sizes/font-size-picker.js +3 -0
  379. package/src/components/iframe/index.js +5 -7
  380. package/src/components/index.js +3 -0
  381. package/src/components/justify-content-control/index.js +9 -4
  382. package/src/components/keyboard-shortcuts/index.js +1 -1
  383. package/src/components/line-height-control/index.js +11 -6
  384. package/src/components/link-control/README.md +1 -1
  385. package/src/components/list-view/block-select-button.js +21 -30
  386. package/src/components/list-view/block.js +55 -13
  387. package/src/components/list-view/branch.js +37 -15
  388. package/src/components/list-view/index.js +6 -0
  389. package/src/components/list-view/style.scss +56 -14
  390. package/src/components/list-view/use-block-selection.js +15 -2
  391. package/src/components/media-placeholder/README.md +8 -0
  392. package/src/components/media-replace-flow/index.js +3 -0
  393. package/src/components/multi-selection-inspector/index.js +2 -2
  394. package/src/components/rich-text/index.js +25 -2
  395. package/src/components/rich-text/index.native.js +24 -8
  396. package/src/components/rich-text/split-value.js +5 -1
  397. package/src/components/rich-text/use-firefox-compat.js +39 -0
  398. package/src/components/rich-text/use-input-rules.js +40 -3
  399. package/src/components/skip-to-selected-block/index.js +3 -0
  400. package/src/components/url-input/style.scss +3 -2
  401. package/src/components/url-popover/image-url-input-ui.js +16 -29
  402. package/src/components/writing-flow/index.js +8 -0
  403. package/src/components/writing-flow/readme.md +28 -0
  404. package/src/components/writing-flow/use-arrow-nav.js +4 -53
  405. package/src/components/writing-flow/use-click-selection.js +65 -0
  406. package/src/components/writing-flow/use-drag-selection.js +126 -0
  407. package/src/components/writing-flow/use-input.js +112 -0
  408. package/src/components/writing-flow/use-multi-selection.js +13 -36
  409. package/src/components/writing-flow/use-selection-observer.js +153 -0
  410. package/src/components/writing-flow/use-tab-nav.js +1 -11
  411. package/src/hooks/anchor.js +8 -6
  412. package/src/hooks/border-color.js +5 -5
  413. package/src/hooks/border.js +0 -13
  414. package/src/hooks/color.js +51 -24
  415. package/src/hooks/font-family.js +5 -2
  416. package/src/hooks/font-size.js +10 -7
  417. package/src/hooks/gap.js +91 -12
  418. package/src/hooks/layout.js +11 -1
  419. package/src/hooks/style.js +40 -4
  420. package/src/hooks/test/gap.js +66 -0
  421. package/src/hooks/test/style.js +94 -0
  422. package/src/hooks/test/utils.js +1 -1
  423. package/src/hooks/utils.js +26 -0
  424. package/src/layouts/flex.js +93 -6
  425. package/src/layouts/flow.js +28 -12
  426. package/src/store/actions.js +349 -32
  427. package/src/store/defaults.js +7 -1
  428. package/src/store/reducer.js +25 -10
  429. package/src/store/selectors.js +207 -25
  430. package/src/store/test/selectors.js +305 -5
  431. package/src/style.scss +2 -0
  432. package/src/utils/dom.js +2 -1
  433. package/tsconfig.tsbuildinfo +1 -1
  434. package/build/components/block-list/use-block-props/use-multi-selection.js +0 -205
  435. package/build/components/block-list/use-block-props/use-multi-selection.js.map +0 -1
  436. package/build/components/block-list/use-block-props/use-scroll-into-view.js +0 -77
  437. package/build/components/block-list/use-block-props/use-scroll-into-view.js.map +0 -1
  438. package/build-module/components/block-list/use-block-props/use-multi-selection.js +0 -192
  439. package/build-module/components/block-list/use-block-props/use-multi-selection.js.map +0 -1
  440. package/build-module/components/block-list/use-block-props/use-scroll-into-view.js +0 -63
  441. package/build-module/components/block-list/use-block-props/use-scroll-into-view.js.map +0 -1
  442. package/src/components/block-list/use-block-props/use-multi-selection.js +0 -227
  443. package/src/components/block-list/use-block-props/use-scroll-into-view.js +0 -73
@@ -23,39 +23,59 @@ import { isClientIdSelected } from './utils';
23
23
  * When a block is collapsed, we do not count their children as part of that total. In the current drag
24
24
  * implementation dragged blocks and their children are not counted.
25
25
  *
26
- * @param {Object} block block tree
27
- * @param {Object} expandedState state that notes which branches are collapsed
28
- * @param {Array} draggedClientIds a list of dragged client ids
26
+ * @param {Object} block block tree
27
+ * @param {Object} expandedState state that notes which branches are collapsed
28
+ * @param {Array} draggedClientIds a list of dragged client ids
29
+ * @param {boolean} isExpandedByDefault flag to determine the default fallback expanded state.
29
30
  * @return {number} block count
30
31
  */
31
- function countBlocks( block, expandedState, draggedClientIds ) {
32
+ function countBlocks(
33
+ block,
34
+ expandedState,
35
+ draggedClientIds,
36
+ isExpandedByDefault
37
+ ) {
32
38
  const isDragged = draggedClientIds?.includes( block.clientId );
33
39
  if ( isDragged ) {
34
40
  return 0;
35
41
  }
36
- const isExpanded = expandedState[ block.clientId ] ?? true;
42
+ const isExpanded = expandedState[ block.clientId ] ?? isExpandedByDefault;
43
+
37
44
  if ( isExpanded ) {
38
45
  return (
39
46
  1 +
40
47
  block.innerBlocks.reduce(
41
- countReducer( expandedState, draggedClientIds ),
48
+ countReducer(
49
+ expandedState,
50
+ draggedClientIds,
51
+ isExpandedByDefault
52
+ ),
42
53
  0
43
54
  )
44
55
  );
45
56
  }
46
57
  return 1;
47
58
  }
48
- const countReducer = ( expandedState, draggedClientIds ) => (
49
- count,
50
- block
51
- ) => {
59
+ const countReducer = (
60
+ expandedState,
61
+ draggedClientIds,
62
+ isExpandedByDefault
63
+ ) => ( count, block ) => {
52
64
  const isDragged = draggedClientIds?.includes( block.clientId );
53
65
  if ( isDragged ) {
54
66
  return count;
55
67
  }
56
- const isExpanded = expandedState[ block.clientId ] ?? true;
68
+ const isExpanded = expandedState[ block.clientId ] ?? isExpandedByDefault;
57
69
  if ( isExpanded && block.innerBlocks.length > 0 ) {
58
- return count + countBlocks( block, expandedState, draggedClientIds );
70
+ return (
71
+ count +
72
+ countBlocks(
73
+ block,
74
+ expandedState,
75
+ draggedClientIds,
76
+ isExpandedByDefault
77
+ )
78
+ );
59
79
  }
60
80
  return count + 1;
61
81
  };
@@ -72,6 +92,7 @@ function ListViewBranch( props ) {
72
92
  isBranchSelected = false,
73
93
  listPosition = 0,
74
94
  fixedListWindow,
95
+ expandNested,
75
96
  } = props;
76
97
 
77
98
  const {
@@ -93,14 +114,14 @@ function ListViewBranch( props ) {
93
114
  nextPosition += countBlocks(
94
115
  filteredBlocks[ index - 1 ],
95
116
  expandedState,
96
- draggedClientIds
117
+ draggedClientIds,
118
+ expandNested
97
119
  );
98
120
  }
99
121
 
100
122
  const usesWindowing = __experimentalPersistentListViewFeatures;
101
123
 
102
124
  const { itemInView } = fixedListWindow;
103
-
104
125
  const blockInView =
105
126
  ! usesWindowing || itemInView( nextPosition );
106
127
 
@@ -113,7 +134,7 @@ function ListViewBranch( props ) {
113
134
  showNestedBlocks && !! innerBlocks && !! innerBlocks.length;
114
135
 
115
136
  const isExpanded = hasNestedBlocks
116
- ? expandedState[ clientId ] ?? true
137
+ ? expandedState[ clientId ] ?? expandNested
117
138
  : undefined;
118
139
 
119
140
  const isDragged = !! draggedClientIds?.includes( clientId );
@@ -165,6 +186,7 @@ function ListViewBranch( props ) {
165
186
  fixedListWindow={ fixedListWindow }
166
187
  isBranchSelected={ isSelectedBranch }
167
188
  selectedClientIds={ selectedClientIds }
189
+ expandNested={ expandNested }
168
190
  />
169
191
  ) }
170
192
  </AsyncModeProvider>
@@ -59,6 +59,8 @@ export const BLOCK_LIST_ITEM_HEIGHT = 36;
59
59
  * @param {boolean} props.__experimentalFeatures Flag to enable experimental features.
60
60
  * @param {boolean} props.__experimentalPersistentListViewFeatures Flag to enable features for the Persistent List View experiment.
61
61
  * @param {boolean} props.__experimentalHideContainerBlockActions Flag to hide actions of top level blocks (like core/widget-area)
62
+ * @param {string} props.id Unique identifier for the root list element (primarily for a11y purposes).
63
+ * @param {boolean} props.expandNested Flag to determine whether nested levels are expanded by default.
62
64
  * @param {Object} ref Forwarded ref
63
65
  */
64
66
  function ListView(
@@ -69,6 +71,8 @@ function ListView(
69
71
  __experimentalHideContainerBlockActions,
70
72
  showNestedBlocks,
71
73
  showBlockMovers,
74
+ id,
75
+ expandNested = false,
72
76
  ...props
73
77
  },
74
78
  ref
@@ -205,6 +209,7 @@ function ListView(
205
209
  blockDropTarget={ blockDropTarget }
206
210
  />
207
211
  <TreeGrid
212
+ id={ id }
208
213
  className="block-editor-list-view-tree"
209
214
  aria-label={ __( 'Block navigation structure' ) }
210
215
  ref={ treeGridRef }
@@ -220,6 +225,7 @@ function ListView(
220
225
  showBlockMovers={ showBlockMovers }
221
226
  fixedListWindow={ fixedListWindow }
222
227
  selectedClientIds={ selectedClientIds }
228
+ expandNested={ expandNested }
223
229
  { ...props }
224
230
  />
225
231
  </ListViewContext.Provider>
@@ -15,7 +15,8 @@
15
15
  // Use position relative for row animation.
16
16
  position: relative;
17
17
 
18
- &.is-selected {
18
+ // The background has to be applied to the td, not tr, or border-radius won't work.
19
+ &.is-selected td {
19
20
  background: var(--wp-admin-theme-color);
20
21
  }
21
22
  &.is-selected .block-editor-list-view-block-contents,
@@ -40,27 +41,53 @@
40
41
  box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) $white;
41
42
  }
42
43
 
44
+ &.is-dragging {
45
+ display: none;
46
+ }
47
+
48
+ // Border radius for corners of the selected item.
49
+ &.is-first-selected td:first-child {
50
+ border-top-left-radius: $radius-block-ui;
51
+ }
52
+ &.is-first-selected td:last-child {
53
+ border-top-right-radius: $radius-block-ui;
54
+ }
55
+ &.is-last-selected td:first-child {
56
+ border-bottom-left-radius: $radius-block-ui;
57
+ }
58
+ &.is-last-selected td:last-child {
59
+ border-bottom-right-radius: $radius-block-ui;
60
+ }
43
61
  &.is-branch-selected:not(.is-selected) {
44
62
  // Lighten a CSS variable without introducing a new SASS variable
45
63
  background:
46
64
  linear-gradient(transparentize($white, 0.1), transparentize($white, 0.1)),
47
65
  linear-gradient(var(--wp-admin-theme-color), var(--wp-admin-theme-color));
48
66
  }
49
- &.is-branch-selected.is-selected .block-editor-list-view-block-contents {
50
- border-radius: 2px 2px 0 0;
67
+ &.is-branch-selected.is-first-selected td:first-child {
68
+ border-top-left-radius: $radius-block-ui;
69
+ }
70
+ &.is-branch-selected.is-first-selected td:last-child {
71
+ border-top-right-radius: $radius-block-ui;
51
72
  }
52
73
  &[aria-expanded="false"] {
53
- &.is-branch-selected.is-selected .block-editor-list-view-block-contents {
54
- border-radius: 2px;
74
+ &.is-branch-selected.is-first-selected td:first-child {
75
+ border-top-left-radius: $radius-block-ui;
76
+ }
77
+ &.is-branch-selected.is-first-selected td:last-child {
78
+ border-top-right-radius: $radius-block-ui;
79
+ }
80
+ &.is-branch-selected.is-last-selected td:first-child {
81
+ border-bottom-left-radius: $radius-block-ui;
82
+ }
83
+ &.is-branch-selected.is-last-selected td:last-child {
84
+ border-bottom-right-radius: $radius-block-ui;
55
85
  }
56
86
  }
57
- &.is-branch-selected:not(.is-selected) .block-editor-list-view-block-contents {
87
+ &.is-branch-selected:not(.is-selected) td {
58
88
  border-radius: 0;
59
89
  }
60
90
 
61
- &.is-dragging {
62
- display: none;
63
- }
64
91
 
65
92
  // List View renders a fixed number of items and relies on each item having a fixed height of 36px.
66
93
  // If this value changes, we should also change the itemHeight value set in useFixedWindowList.
@@ -73,7 +100,7 @@
73
100
  padding: ($grid-unit-15 * 0.5) $grid-unit-15 ($grid-unit-15 * 0.5) 0;
74
101
  text-align: left;
75
102
  color: $gray-900;
76
- border-radius: 2px;
103
+ border-radius: $radius-block-ui;
77
104
  position: relative;
78
105
  white-space: nowrap;
79
106
 
@@ -106,7 +133,7 @@
106
133
  left: 0;
107
134
  border-radius: inherit;
108
135
  box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
109
- z-index: 1;
136
+ z-index: 2;
110
137
  pointer-events: none;
111
138
 
112
139
  // Hide focus styles while a user is dragging blocks/files etc.
@@ -152,17 +179,23 @@
152
179
  .block-editor-list-view-block__mover-cell {
153
180
  line-height: 0;
154
181
  width: $button-size;
155
- opacity: 0;
156
182
  vertical-align: middle;
157
183
  @include reduce-motion("transition");
158
184
 
185
+ > * {
186
+ opacity: 0;
187
+ }
188
+
159
189
  // Show on hover, visible, and show above to keep the hit area size.
160
190
  &:hover,
161
191
  &.is-visible {
162
192
  position: relative;
163
193
  z-index: 1;
164
- opacity: 1;
165
- @include edit-post__fade-in-animation;
194
+
195
+ > * {
196
+ opacity: 1;
197
+ @include edit-post__fade-in-animation;
198
+ }
166
199
  }
167
200
 
168
201
  &,
@@ -278,6 +311,15 @@
278
311
  &.is-selected .block-editor-list-view-block-select-button__anchor {
279
312
  background: rgba($black, 0.3);
280
313
  }
314
+
315
+ .block-editor-list-view-block-select-button__lock {
316
+ line-height: 0;
317
+ width: 24px;
318
+ min-width: 24px;
319
+ margin-left: auto;
320
+ padding: 0;
321
+ vertical-align: middle;
322
+ }
281
323
  }
282
324
 
283
325
  .block-editor-list-view-block-select-button__description,
@@ -10,7 +10,7 @@ import { speak } from '@wordpress/a11y';
10
10
  import { __, sprintf } from '@wordpress/i18n';
11
11
  import { useDispatch, useSelect } from '@wordpress/data';
12
12
  import { useCallback } from '@wordpress/element';
13
- import { UP, DOWN } from '@wordpress/keycodes';
13
+ import { UP, DOWN, HOME, END } from '@wordpress/keycodes';
14
14
  import { store as blocksStore } from '@wordpress/blocks';
15
15
 
16
16
  /**
@@ -49,7 +49,10 @@ export default function useBlockSelection() {
49
49
 
50
50
  const isKeyPress =
51
51
  event.type === 'keydown' &&
52
- ( event.keyCode === UP || event.keyCode === DOWN );
52
+ ( event.keyCode === UP ||
53
+ event.keyCode === DOWN ||
54
+ event.keyCode === HOME ||
55
+ event.keyCode === END );
53
56
 
54
57
  // Handle clicking on a block when no blocks are selected, and return early.
55
58
  if (
@@ -114,6 +117,16 @@ export default function useBlockSelection() {
114
117
  // the total number of blocks deselected is greater than one.
115
118
  const updatedSelectedBlocks = getSelectedBlockClientIds();
116
119
 
120
+ // If the selection is greater than 1 and the Home or End keys
121
+ // were used to generate the selection, then skip announcing the
122
+ // deselected blocks.
123
+ if (
124
+ ( event.keyCode === HOME || event.keyCode === END ) &&
125
+ updatedSelectedBlocks.length > 1
126
+ ) {
127
+ return;
128
+ }
129
+
117
130
  const selectionDiff = difference(
118
131
  selectedBlocks,
119
132
  updatedSelectedBlocks
@@ -140,6 +140,14 @@ Whether to allow multiple selection of files or not.
140
140
  - Default: `false`
141
141
  - Platform: Web
142
142
 
143
+ ### mediaPreview
144
+
145
+ The component is rendered as a preview in the placeholder.
146
+
147
+ - Type: `Component`
148
+ - Required: No
149
+ - Platform: Web
150
+
143
151
  ### onError
144
152
 
145
153
  Callback called when an upload error happens.
@@ -212,6 +212,9 @@ const MediaReplaceFlow = ( {
212
212
  );
213
213
  };
214
214
 
215
+ /**
216
+ * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-replace-flow/README.md
217
+ */
215
218
  export default compose( [
216
219
  withDispatch( ( dispatch ) => {
217
220
  const { createNotice, removeNotice } = dispatch( noticesStore );
@@ -5,7 +5,7 @@ import { sprintf, _n } from '@wordpress/i18n';
5
5
  import { withSelect } from '@wordpress/data';
6
6
  import { serialize } from '@wordpress/blocks';
7
7
  import { count as wordCount } from '@wordpress/wordcount';
8
- import { stack } from '@wordpress/icons';
8
+ import { copy } from '@wordpress/icons';
9
9
 
10
10
  /**
11
11
  * Internal dependencies
@@ -18,7 +18,7 @@ function MultiSelectionInspector( { blocks } ) {
18
18
 
19
19
  return (
20
20
  <div className="block-editor-multi-selection-inspector__card">
21
- <BlockIcon icon={ stack } showColors />
21
+ <BlockIcon icon={ copy } showColors />
22
22
  <div className="block-editor-multi-selection-inspector__card-content">
23
23
  <div className="block-editor-multi-selection-inspector__card-title">
24
24
  { sprintf(
@@ -45,6 +45,7 @@ import { useFormatTypes } from './use-format-types';
45
45
  import { useRemoveBrowserShortcuts } from './use-remove-browser-shortcuts';
46
46
  import { useShortcuts } from './use-shortcuts';
47
47
  import { useInputEvents } from './use-input-events';
48
+ import { useFirefoxCompat } from './use-firefox-compat';
48
49
  import FormatEdit from './format-edit';
49
50
  import { getMultilineTag, getAllowedFormats } from './utils';
50
51
 
@@ -131,6 +132,7 @@ function RichTextWrapper(
131
132
  if ( originalIsSelected === undefined ) {
132
133
  isSelected =
133
134
  selectionStart.clientId === clientId &&
135
+ selectionEnd.clientId === clientId &&
134
136
  selectionStart.attributeKey === identifier;
135
137
  } else if ( originalIsSelected ) {
136
138
  isSelected = selectionStart.clientId === clientId;
@@ -171,7 +173,26 @@ function RichTextWrapper(
171
173
 
172
174
  const onSelectionChange = useCallback(
173
175
  ( start, end ) => {
174
- selectionChange( clientId, identifier, start, end );
176
+ const selection = {};
177
+ const unset = start === undefined && end === undefined;
178
+
179
+ if ( typeof start === 'number' || unset ) {
180
+ selection.start = {
181
+ clientId,
182
+ attributeKey: identifier,
183
+ offset: start,
184
+ };
185
+ }
186
+
187
+ if ( typeof end === 'number' || unset ) {
188
+ selection.end = {
189
+ clientId,
190
+ attributeKey: identifier,
191
+ offset: end,
192
+ };
193
+ }
194
+
195
+ selectionChange( selection );
175
196
  },
176
197
  [ clientId, identifier ]
177
198
  );
@@ -330,6 +351,7 @@ function RichTextWrapper(
330
351
  { ...props }
331
352
  { ...autocompleteProps }
332
353
  ref={ useMergeRefs( [
354
+ forwardedRef,
333
355
  autocompleteProps.ref,
334
356
  props.ref,
335
357
  richTextRef,
@@ -339,6 +361,7 @@ function RichTextWrapper(
339
361
  __unstableAllowPrefixTransformations,
340
362
  formatTypes,
341
363
  onReplace,
364
+ selectionChange,
342
365
  } ),
343
366
  useRemoveBrowserShortcuts(),
344
367
  useShortcuts( keyboardShortcuts ),
@@ -370,8 +393,8 @@ function RichTextWrapper(
370
393
  disableLineBreaks,
371
394
  onSplitAtEnd,
372
395
  } ),
396
+ useFirefoxCompat(),
373
397
  anchorRef,
374
- forwardedRef,
375
398
  ] ) }
376
399
  contentEditable={ true }
377
400
  suppressContentEditableWarning={ true }
@@ -66,6 +66,8 @@ function RichTextWrapper(
66
66
  {
67
67
  children,
68
68
  tagName,
69
+ start,
70
+ reversed,
69
71
  value: originalValue,
70
72
  onChange: originalOnChange,
71
73
  isSelected: originalIsSelected,
@@ -214,8 +216,13 @@ function RichTextWrapper(
214
216
  }
215
217
 
216
218
  const onSelectionChange = useCallback(
217
- ( start, end ) => {
218
- selectionChange( clientId, identifier, start, end );
219
+ ( selectionChangeStart, selectionChangeEnd ) => {
220
+ selectionChange(
221
+ clientId,
222
+ identifier,
223
+ selectionChangeStart,
224
+ selectionChangeEnd
225
+ );
219
226
  },
220
227
  [ clientId, identifier ]
221
228
  );
@@ -349,9 +356,11 @@ function RichTextWrapper(
349
356
  onChange( insertLineSeparator( value ) );
350
357
  }
351
358
  } else {
352
- const { text, start, end } = value;
359
+ const { text, start: splitStart, end: splitEnd } = value;
353
360
  const canSplitAtEnd =
354
- onSplitAtEnd && start === end && end === text.length;
361
+ onSplitAtEnd &&
362
+ splitStart === splitEnd &&
363
+ splitEnd === text.length;
355
364
 
356
365
  if ( shiftKey || ( ! canSplit && ! canSplitAtEnd ) ) {
357
366
  if ( ! disableLineBreaks ) {
@@ -530,15 +539,18 @@ function RichTextWrapper(
530
539
  return;
531
540
  }
532
541
 
533
- const { start, text } = value;
534
- const characterBefore = text.slice( start - 1, start );
542
+ const { start: startPosition, text } = value;
543
+ const characterBefore = text.slice(
544
+ startPosition - 1,
545
+ startPosition
546
+ );
535
547
 
536
548
  // The character right before the caret must be a plain space.
537
549
  if ( characterBefore !== ' ' ) {
538
550
  return;
539
551
  }
540
552
 
541
- const trimmedTextBefore = text.slice( 0, start ).trim();
553
+ const trimmedTextBefore = text.slice( 0, startPosition ).trim();
542
554
  const prefixTransforms = getBlockTransforms( 'from' ).filter(
543
555
  ( { type } ) => type === 'prefix'
544
556
  );
@@ -553,7 +565,9 @@ function RichTextWrapper(
553
565
  return;
554
566
  }
555
567
 
556
- const content = valueToFormat( slice( value, start, text.length ) );
568
+ const content = valueToFormat(
569
+ slice( value, startPosition, text.length )
570
+ );
557
571
  const block = transformation.transform( content );
558
572
 
559
573
  onReplace( [ block ] );
@@ -575,6 +589,8 @@ function RichTextWrapper(
575
589
  selectionEnd={ selectionEnd }
576
590
  onSelectionChange={ onSelectionChange }
577
591
  tagName={ tagName }
592
+ start={ start }
593
+ reversed={ reversed }
578
594
  placeholder={ placeholder }
579
595
  allowedFormats={ adjustedAllowedFormats }
580
596
  withoutInteractiveFormatting={ withoutInteractiveFormatting }
@@ -20,8 +20,12 @@ export function splitValue( {
20
20
  return;
21
21
  }
22
22
 
23
+ // Ensure the value has a selection. This might happen when trying to split
24
+ // an empty value before there was a `selectionchange` event.
25
+ const { start = 0, end = 0 } = value;
26
+ const valueWithEnsuredSelection = { ...value, start, end };
23
27
  const blocks = [];
24
- const [ before, after ] = split( value );
28
+ const [ before, after ] = split( valueWithEnsuredSelection );
25
29
  const hasPastedBlocks = pastedBlocks.length > 0;
26
30
  let lastPastedBlockIndex = -1;
27
31
 
@@ -0,0 +1,39 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useRefEffect } from '@wordpress/compose';
5
+ import { useSelect } from '@wordpress/data';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { store as blockEditorStore } from '../../store';
11
+
12
+ export function useFirefoxCompat() {
13
+ const { isMultiSelecting } = useSelect( blockEditorStore );
14
+ return useRefEffect( ( element ) => {
15
+ function onFocus() {
16
+ if ( ! isMultiSelecting() ) {
17
+ return;
18
+ }
19
+
20
+ // This is a little hack to work around focus issues with nested
21
+ // editable elements in Firefox. For some reason the editable child
22
+ // element sometimes regains focus, while it should not be focusable
23
+ // and focus should remain on the editable parent element.
24
+ // To do: try to find the cause of the shifting focus.
25
+ const parentEditable = element.parentElement.closest(
26
+ '[contenteditable="true"]'
27
+ );
28
+
29
+ if ( parentEditable ) {
30
+ parentEditable.focus();
31
+ }
32
+ }
33
+
34
+ element.addEventListener( 'focus', onFocus );
35
+ return () => {
36
+ element.removeEventListener( 'focus', onFocus );
37
+ };
38
+ }, [] );
39
+ }
@@ -1,9 +1,14 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { findKey } from 'lodash';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
4
9
  import { useRef } from '@wordpress/element';
5
10
  import { useRefEffect } from '@wordpress/compose';
6
- import { slice, toHTMLString } from '@wordpress/rich-text';
11
+ import { insert, toHTMLString } from '@wordpress/rich-text';
7
12
  import { getBlockTransforms, findTransform } from '@wordpress/blocks';
8
13
  import { useDispatch } from '@wordpress/data';
9
14
 
@@ -13,6 +18,37 @@ import { useDispatch } from '@wordpress/data';
13
18
  import { store as blockEditorStore } from '../../store';
14
19
  import { preventEventDiscovery } from './prevent-event-discovery';
15
20
 
21
+ // A robust way to retain selection position through various
22
+ // transforms is to insert a special character at the position and
23
+ // then recover it.
24
+ const START_OF_SELECTED_AREA = '\u0086';
25
+
26
+ function findSelection( blocks ) {
27
+ let i = blocks.length;
28
+
29
+ while ( i-- ) {
30
+ const attributeKey = findKey(
31
+ blocks[ i ].attributes,
32
+ ( v ) =>
33
+ typeof v === 'string' &&
34
+ v.indexOf( START_OF_SELECTED_AREA ) !== -1
35
+ );
36
+
37
+ if ( attributeKey ) {
38
+ blocks[ i ].attributes[ attributeKey ] = blocks[ i ].attributes[
39
+ attributeKey
40
+ ].replace( START_OF_SELECTED_AREA, '' );
41
+ return blocks[ i ].clientId;
42
+ }
43
+
44
+ const nestedSelection = findSelection( blocks[ i ].innerBlocks );
45
+
46
+ if ( nestedSelection ) {
47
+ return nestedSelection;
48
+ }
49
+ }
50
+ }
51
+
16
52
  export function useInputRules( props ) {
17
53
  const {
18
54
  __unstableMarkLastChangeAsPersistent,
@@ -22,7 +58,7 @@ export function useInputRules( props ) {
22
58
  propsRef.current = props;
23
59
  return useRefEffect( ( element ) => {
24
60
  function inputRule() {
25
- const { value, onReplace } = propsRef.current;
61
+ const { value, onReplace, selectionChange } = propsRef.current;
26
62
 
27
63
  if ( ! onReplace ) {
28
64
  return;
@@ -52,10 +88,11 @@ export function useInputRules( props ) {
52
88
  }
53
89
 
54
90
  const content = toHTMLString( {
55
- value: slice( value, start, text.length ),
91
+ value: insert( value, START_OF_SELECTED_AREA, 0, start ),
56
92
  } );
57
93
  const block = transformation.transform( content );
58
94
 
95
+ selectionChange( findSelection( [ block ] ) );
59
96
  onReplace( [ block ] );
60
97
  __unstableMarkAutomaticChange();
61
98
  }
@@ -28,6 +28,9 @@ const SkipToSelectedBlock = ( { selectedBlockClientId } ) => {
28
28
  ) : null;
29
29
  };
30
30
 
31
+ /**
32
+ * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/skip-to-selected-block/README.md
33
+ */
31
34
  export default withSelect( ( select ) => {
32
35
  return {
33
36
  selectedBlockClientId: select(
@@ -71,12 +71,13 @@ $input-size: 300px;
71
71
  .block-editor-url-input .components-spinner {
72
72
  display: none;
73
73
  @include break-small() {
74
- display: inherit;
74
+ display: grid;
75
75
  }
76
76
  }
77
77
 
78
78
  .block-editor-url-input__suggestion {
79
- padding: 4px $input-padding;
79
+ min-height: $button-size;
80
+ height: auto;
80
81
  color: $gray-700;
81
82
  display: block;
82
83
  font-size: $default-font-size;