@wordpress/block-editor 16.2.0 → 17.0.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 (328) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/build/components/block-inspector/index.cjs +9 -6
  3. package/build/components/block-inspector/index.cjs.map +2 -2
  4. package/build/components/block-keyboard-shortcuts/index.cjs +201 -0
  5. package/build/components/block-keyboard-shortcuts/index.cjs.map +7 -0
  6. package/build/components/block-list/block.cjs +10 -3
  7. package/build/components/block-list/block.cjs.map +2 -2
  8. package/build/components/block-list/index.cjs +6 -1
  9. package/build/components/block-list/index.cjs.map +2 -2
  10. package/build/components/block-list/use-block-props/use-focus-first-element.cjs +4 -0
  11. package/build/components/block-list/use-block-props/use-focus-first-element.cjs.map +2 -2
  12. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs +6 -7
  13. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs.map +2 -2
  14. package/build/components/block-parent-selector/index.cjs +98 -29
  15. package/build/components/block-parent-selector/index.cjs.map +3 -3
  16. package/build/components/block-popover/inbetween.cjs +2 -2
  17. package/build/components/block-popover/inbetween.cjs.map +2 -2
  18. package/build/components/block-preview/index.cjs +0 -4
  19. package/build/components/block-preview/index.cjs.map +2 -2
  20. package/build/components/block-styles/index.cjs +77 -33
  21. package/build/components/block-styles/index.cjs.map +3 -3
  22. package/build/components/block-visibility/constants.cjs.map +2 -2
  23. package/build/components/child-layout-control/index.cjs.map +2 -2
  24. package/build/components/colors/with-colors.cjs +55 -71
  25. package/build/components/colors/with-colors.cjs.map +2 -2
  26. package/build/components/dimensions-tool/aspect-ratio-tool.cjs +4 -2
  27. package/build/components/dimensions-tool/aspect-ratio-tool.cjs.map +2 -2
  28. package/build/components/dimensions-tool/index.cjs +18 -16
  29. package/build/components/dimensions-tool/index.cjs.map +2 -2
  30. package/build/components/dimensions-tool/utils.cjs +61 -0
  31. package/build/components/dimensions-tool/utils.cjs.map +7 -0
  32. package/build/components/duotone-control/index.cjs +2 -0
  33. package/build/components/duotone-control/index.cjs.map +2 -2
  34. package/build/components/global-styles/advanced-panel.cjs.map +3 -3
  35. package/build/components/global-styles/border-panel.cjs +2 -5
  36. package/build/components/global-styles/border-panel.cjs.map +2 -2
  37. package/build/components/global-styles/color-panel.cjs +14 -2
  38. package/build/components/global-styles/color-panel.cjs.map +2 -2
  39. package/build/components/global-styles/dimensions-panel.cjs +9 -5
  40. package/build/components/global-styles/dimensions-panel.cjs.map +2 -2
  41. package/build/components/global-styles/filters-panel.cjs +12 -8
  42. package/build/components/global-styles/filters-panel.cjs.map +2 -2
  43. package/build/components/global-styles/shadow-panel-components.cjs +16 -11
  44. package/build/components/global-styles/shadow-panel-components.cjs.map +2 -2
  45. package/build/components/global-styles/utils.cjs +9 -0
  46. package/build/components/global-styles/utils.cjs.map +2 -2
  47. package/build/components/inner-blocks/index.cjs +5 -3
  48. package/build/components/inner-blocks/index.cjs.map +2 -2
  49. package/build/components/inserter/block-patterns-explorer/index.cjs +39 -22
  50. package/build/components/inserter/block-patterns-explorer/index.cjs.map +2 -2
  51. package/build/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.cjs +21 -55
  52. package/build/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.cjs.map +2 -2
  53. package/build/components/inserter/block-patterns-explorer/pattern-list.cjs +19 -44
  54. package/build/components/inserter/block-patterns-explorer/pattern-list.cjs.map +3 -3
  55. package/build/components/inserter/hooks/use-insertion-point.cjs +4 -4
  56. package/build/components/inserter/hooks/use-insertion-point.cjs.map +2 -2
  57. package/build/components/inserter/menu.cjs +18 -7
  58. package/build/components/inserter/menu.cjs.map +2 -2
  59. package/build/components/inserter/quick-inserter.cjs +30 -27
  60. package/build/components/inserter/quick-inserter.cjs.map +2 -2
  61. package/build/components/inspector-controls-tabs/styles-tab.cjs +1 -1
  62. package/build/components/inspector-controls-tabs/styles-tab.cjs.map +2 -2
  63. package/build/components/list-view/index.cjs +31 -5
  64. package/build/components/list-view/index.cjs.map +3 -3
  65. package/build/components/list-view/utils.cjs +13 -1
  66. package/build/components/list-view/utils.cjs.map +2 -2
  67. package/build/components/media-placeholder/index.cjs +1 -1
  68. package/build/components/media-placeholder/index.cjs.map +3 -3
  69. package/build/components/provider/index.cjs +5 -1
  70. package/build/components/provider/index.cjs.map +3 -3
  71. package/build/components/publish-date-time-picker/index.cjs +3 -2
  72. package/build/components/publish-date-time-picker/index.cjs.map +2 -2
  73. package/build/components/rich-text/event-listeners/enter.cjs +46 -39
  74. package/build/components/rich-text/event-listeners/enter.cjs.map +2 -2
  75. package/build/components/rich-text/index.cjs +7 -5
  76. package/build/components/rich-text/index.cjs.map +2 -2
  77. package/build/components/rich-text/multiline.cjs +105 -70
  78. package/build/components/rich-text/multiline.cjs.map +3 -3
  79. package/build/components/url-input/index.cjs.map +2 -2
  80. package/build/components/writing-flow/use-input.cjs +65 -13
  81. package/build/components/writing-flow/use-input.cjs.map +3 -3
  82. package/build/hooks/border.cjs +25 -3
  83. package/build/hooks/border.cjs.map +2 -2
  84. package/build/hooks/dimensions.cjs +9 -2
  85. package/build/hooks/dimensions.cjs.map +2 -2
  86. package/build/hooks/duotone.cjs +4 -3
  87. package/build/hooks/duotone.cjs.map +2 -2
  88. package/build/hooks/gap.cjs +8 -2
  89. package/build/hooks/gap.cjs.map +2 -2
  90. package/build/hooks/layout-child.cjs +35 -13
  91. package/build/hooks/layout-child.cjs.map +2 -2
  92. package/build/hooks/layout.cjs +23 -1
  93. package/build/hooks/layout.cjs.map +2 -2
  94. package/build/hooks/states.cjs +7 -4
  95. package/build/hooks/states.cjs.map +2 -2
  96. package/build/layouts/constrained.cjs +8 -1
  97. package/build/layouts/constrained.cjs.map +2 -2
  98. package/build/layouts/flex.cjs +9 -0
  99. package/build/layouts/flex.cjs.map +2 -2
  100. package/build/layouts/flow.cjs +4 -1
  101. package/build/layouts/flow.cjs.map +2 -2
  102. package/build/layouts/grid.cjs +5 -1
  103. package/build/layouts/grid.cjs.map +2 -2
  104. package/build/private-apis.cjs +3 -1
  105. package/build/private-apis.cjs.map +2 -2
  106. package/build/store/actions.cjs +1 -1
  107. package/build/store/actions.cjs.map +2 -2
  108. package/build-module/components/block-inspector/index.mjs +9 -6
  109. package/build-module/components/block-inspector/index.mjs.map +2 -2
  110. package/build-module/components/block-keyboard-shortcuts/index.mjs +173 -0
  111. package/build-module/components/block-keyboard-shortcuts/index.mjs.map +7 -0
  112. package/build-module/components/block-list/block.mjs +10 -3
  113. package/build-module/components/block-list/block.mjs.map +2 -2
  114. package/build-module/components/block-list/index.mjs +6 -1
  115. package/build-module/components/block-list/index.mjs.map +2 -2
  116. package/build-module/components/block-list/use-block-props/use-focus-first-element.mjs +4 -0
  117. package/build-module/components/block-list/use-block-props/use-focus-first-element.mjs.map +2 -2
  118. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs +6 -7
  119. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs.map +2 -2
  120. package/build-module/components/block-parent-selector/index.mjs +101 -32
  121. package/build-module/components/block-parent-selector/index.mjs.map +2 -2
  122. package/build-module/components/block-popover/inbetween.mjs +2 -2
  123. package/build-module/components/block-popover/inbetween.mjs.map +2 -2
  124. package/build-module/components/block-preview/index.mjs +0 -4
  125. package/build-module/components/block-preview/index.mjs.map +2 -2
  126. package/build-module/components/block-styles/index.mjs +79 -35
  127. package/build-module/components/block-styles/index.mjs.map +2 -2
  128. package/build-module/components/block-visibility/constants.mjs.map +2 -2
  129. package/build-module/components/child-layout-control/index.mjs +5 -5
  130. package/build-module/components/child-layout-control/index.mjs.map +1 -1
  131. package/build-module/components/colors/with-colors.mjs +56 -72
  132. package/build-module/components/colors/with-colors.mjs.map +2 -2
  133. package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs +4 -2
  134. package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs.map +2 -2
  135. package/build-module/components/dimensions-tool/index.mjs +19 -17
  136. package/build-module/components/dimensions-tool/index.mjs.map +2 -2
  137. package/build-module/components/dimensions-tool/utils.mjs +35 -0
  138. package/build-module/components/dimensions-tool/utils.mjs.map +7 -0
  139. package/build-module/components/duotone-control/index.mjs +2 -0
  140. package/build-module/components/duotone-control/index.mjs.map +2 -2
  141. package/build-module/components/global-styles/advanced-panel.mjs +5 -2
  142. package/build-module/components/global-styles/advanced-panel.mjs.map +2 -2
  143. package/build-module/components/global-styles/border-panel.mjs +2 -5
  144. package/build-module/components/global-styles/border-panel.mjs.map +2 -2
  145. package/build-module/components/global-styles/color-panel.mjs +14 -2
  146. package/build-module/components/global-styles/color-panel.mjs.map +2 -2
  147. package/build-module/components/global-styles/dimensions-panel.mjs +9 -5
  148. package/build-module/components/global-styles/dimensions-panel.mjs.map +2 -2
  149. package/build-module/components/global-styles/filters-panel.mjs +16 -9
  150. package/build-module/components/global-styles/filters-panel.mjs.map +2 -2
  151. package/build-module/components/global-styles/shadow-panel-components.mjs +16 -11
  152. package/build-module/components/global-styles/shadow-panel-components.mjs.map +2 -2
  153. package/build-module/components/global-styles/utils.mjs +8 -0
  154. package/build-module/components/global-styles/utils.mjs.map +2 -2
  155. package/build-module/components/inner-blocks/index.mjs +5 -3
  156. package/build-module/components/inner-blocks/index.mjs.map +2 -2
  157. package/build-module/components/inserter/block-patterns-explorer/index.mjs +39 -22
  158. package/build-module/components/inserter/block-patterns-explorer/index.mjs.map +2 -2
  159. package/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.mjs +22 -56
  160. package/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.mjs.map +2 -2
  161. package/build-module/components/inserter/block-patterns-explorer/pattern-list.mjs +20 -45
  162. package/build-module/components/inserter/block-patterns-explorer/pattern-list.mjs.map +2 -2
  163. package/build-module/components/inserter/hooks/use-insertion-point.mjs +4 -4
  164. package/build-module/components/inserter/hooks/use-insertion-point.mjs.map +2 -2
  165. package/build-module/components/inserter/menu.mjs +19 -8
  166. package/build-module/components/inserter/menu.mjs.map +2 -2
  167. package/build-module/components/inserter/quick-inserter.mjs +30 -27
  168. package/build-module/components/inserter/quick-inserter.mjs.map +2 -2
  169. package/build-module/components/inspector-controls-tabs/styles-tab.mjs +1 -1
  170. package/build-module/components/inspector-controls-tabs/styles-tab.mjs.map +2 -2
  171. package/build-module/components/list-view/index.mjs +32 -5
  172. package/build-module/components/list-view/index.mjs.map +3 -3
  173. package/build-module/components/list-view/utils.mjs +13 -1
  174. package/build-module/components/list-view/utils.mjs.map +2 -2
  175. package/build-module/components/media-placeholder/index.mjs +3 -3
  176. package/build-module/components/media-placeholder/index.mjs.map +2 -2
  177. package/build-module/components/provider/index.mjs +6 -2
  178. package/build-module/components/provider/index.mjs.map +2 -2
  179. package/build-module/components/publish-date-time-picker/index.mjs +3 -2
  180. package/build-module/components/publish-date-time-picker/index.mjs.map +2 -2
  181. package/build-module/components/rich-text/event-listeners/enter.mjs +46 -39
  182. package/build-module/components/rich-text/event-listeners/enter.mjs.map +2 -2
  183. package/build-module/components/rich-text/index.mjs +7 -5
  184. package/build-module/components/rich-text/index.mjs.map +2 -2
  185. package/build-module/components/rich-text/multiline.mjs +112 -72
  186. package/build-module/components/rich-text/multiline.mjs.map +2 -2
  187. package/build-module/components/url-input/index.mjs +2 -2
  188. package/build-module/components/url-input/index.mjs.map +1 -1
  189. package/build-module/components/writing-flow/use-input.mjs +66 -14
  190. package/build-module/components/writing-flow/use-input.mjs.map +3 -3
  191. package/build-module/hooks/border.mjs +26 -8
  192. package/build-module/hooks/border.mjs.map +2 -2
  193. package/build-module/hooks/dimensions.mjs +9 -2
  194. package/build-module/hooks/dimensions.mjs.map +2 -2
  195. package/build-module/hooks/duotone.mjs +8 -4
  196. package/build-module/hooks/duotone.mjs.map +2 -2
  197. package/build-module/hooks/gap.mjs +6 -1
  198. package/build-module/hooks/gap.mjs.map +2 -2
  199. package/build-module/hooks/layout-child.mjs +36 -13
  200. package/build-module/hooks/layout-child.mjs.map +2 -2
  201. package/build-module/hooks/layout.mjs +22 -1
  202. package/build-module/hooks/layout.mjs.map +2 -2
  203. package/build-module/hooks/states.mjs +8 -5
  204. package/build-module/hooks/states.mjs.map +2 -2
  205. package/build-module/layouts/constrained.mjs +8 -1
  206. package/build-module/layouts/constrained.mjs.map +2 -2
  207. package/build-module/layouts/flex.mjs +9 -0
  208. package/build-module/layouts/flex.mjs.map +2 -2
  209. package/build-module/layouts/flow.mjs +4 -1
  210. package/build-module/layouts/flow.mjs.map +2 -2
  211. package/build-module/layouts/grid.mjs +5 -1
  212. package/build-module/layouts/grid.mjs.map +2 -2
  213. package/build-module/private-apis.mjs +3 -1
  214. package/build-module/private-apis.mjs.map +2 -2
  215. package/build-module/store/actions.mjs +1 -1
  216. package/build-module/store/actions.mjs.map +2 -2
  217. package/build-style/style-rtl.css +108 -71
  218. package/build-style/style.css +108 -71
  219. package/build-types/components/block-visibility/constants.d.ts +4 -3
  220. package/build-types/components/block-visibility/constants.d.ts.map +1 -1
  221. package/package.json +43 -43
  222. package/src/components/background-image-control/README.md +122 -0
  223. package/src/components/block-edit-visually-button/README.md +39 -0
  224. package/src/components/block-editing-mode/README.md +72 -0
  225. package/src/components/block-inspector/index.js +6 -6
  226. package/src/components/block-keyboard-shortcuts/index.js +256 -0
  227. package/src/components/block-list/block.js +7 -0
  228. package/src/components/block-list/index.js +7 -1
  229. package/src/components/block-list/use-block-props/use-focus-first-element.js +5 -0
  230. package/src/components/block-list/use-block-props/use-selected-block-event-handlers.js +6 -8
  231. package/src/components/block-parent-selector/index.js +111 -30
  232. package/src/components/block-popover/README.md +10 -3
  233. package/src/components/block-popover/inbetween.js +8 -2
  234. package/src/components/block-popover/stories/index.story.jsx +143 -0
  235. package/src/components/block-preview/index.js +0 -2
  236. package/src/components/block-styles/index.js +95 -43
  237. package/src/components/block-styles/style.scss +5 -34
  238. package/src/components/block-tools/style.scss +94 -0
  239. package/src/components/block-visibility/constants.ts +4 -3
  240. package/src/components/child-layout-control/index.js +5 -5
  241. package/src/components/color-palette/test/__snapshots__/control.js.snap +3 -29
  242. package/src/components/colors/test/with-colors.js +6 -7
  243. package/src/components/colors/with-colors.js +79 -105
  244. package/src/components/dimensions-tool/aspect-ratio-tool.js +16 -4
  245. package/src/components/dimensions-tool/index.js +34 -22
  246. package/src/components/dimensions-tool/test/index.js +166 -2
  247. package/src/components/dimensions-tool/test/utils.js +51 -0
  248. package/src/components/dimensions-tool/utils.js +67 -0
  249. package/src/components/duotone-control/index.js +2 -0
  250. package/src/components/duotone-control/test/index.js +100 -0
  251. package/src/components/global-styles/advanced-panel.js +5 -2
  252. package/src/components/global-styles/border-panel.js +11 -9
  253. package/src/components/global-styles/color-panel.js +13 -1
  254. package/src/components/global-styles/dimensions-panel.js +17 -5
  255. package/src/components/global-styles/filters-panel.js +24 -10
  256. package/src/components/global-styles/shadow-panel-components.js +38 -11
  257. package/src/components/global-styles/test/border-panel.js +230 -0
  258. package/src/components/global-styles/test/color-panel.js +24 -0
  259. package/src/components/global-styles/test/dimensions-panel.js +98 -7
  260. package/src/components/global-styles/test/filters-panel.js +84 -0
  261. package/src/components/global-styles/test/utils.js +30 -0
  262. package/src/components/global-styles/utils.js +23 -0
  263. package/src/components/inner-blocks/index.js +11 -2
  264. package/src/components/inner-blocks/stories/index.story.jsx +246 -0
  265. package/src/components/inserter/block-patterns-explorer/index.js +24 -11
  266. package/src/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js +18 -56
  267. package/src/components/inserter/block-patterns-explorer/pattern-list.js +22 -47
  268. package/src/components/inserter/hooks/use-insertion-point.js +9 -4
  269. package/src/components/inserter/menu.js +23 -10
  270. package/src/components/inserter/quick-inserter.js +15 -13
  271. package/src/components/inserter/style.scss +44 -62
  272. package/src/components/inspector-controls-tabs/README.md +92 -0
  273. package/src/components/inspector-controls-tabs/styles-tab.js +1 -1
  274. package/src/components/link-control/test/index.js +5 -0
  275. package/src/components/list-view/index.js +50 -7
  276. package/src/components/list-view/utils.js +16 -1
  277. package/src/components/media-placeholder/index.js +9 -4
  278. package/src/components/plain-text/stories/index.story.jsx +3 -0
  279. package/src/components/provider/index.js +7 -1
  280. package/src/components/publish-date-time-picker/README.md +10 -0
  281. package/src/components/publish-date-time-picker/index.js +17 -14
  282. package/src/components/rich-text/event-listeners/enter.js +58 -45
  283. package/src/components/rich-text/index.js +9 -4
  284. package/src/components/rich-text/multiline.js +126 -86
  285. package/src/components/url-input/index.js +2 -2
  286. package/src/components/url-input/test/fixtures/validated-input-control-deprecation.js +27 -0
  287. package/src/components/url-input/test/index.js +5 -0
  288. package/src/components/url-popover/README.md +7 -0
  289. package/src/components/url-popover/stories/index.story.jsx +133 -47
  290. package/src/components/writing-flow/use-input.js +105 -15
  291. package/src/hooks/border.js +27 -8
  292. package/src/hooks/dimensions.js +8 -1
  293. package/src/hooks/duotone.js +23 -7
  294. package/src/hooks/gap.js +16 -0
  295. package/src/hooks/layout-child.js +41 -9
  296. package/src/hooks/layout.js +117 -71
  297. package/src/hooks/states.js +8 -5
  298. package/src/hooks/test/gap.js +31 -1
  299. package/src/hooks/test/layout-child.js +60 -1
  300. package/src/hooks/test/layout.js +27 -0
  301. package/src/layouts/constrained.js +9 -1
  302. package/src/layouts/flex.js +15 -0
  303. package/src/layouts/flow.js +4 -1
  304. package/src/layouts/grid.js +9 -1
  305. package/src/layouts/test/constrained.js +26 -0
  306. package/src/layouts/test/flow.js +26 -0
  307. package/src/layouts/test/grid.js +46 -0
  308. package/src/private-apis.js +2 -0
  309. package/src/store/actions.js +14 -1
  310. package/build/components/floating-toolbar/nav-up-icon.cjs +0 -52
  311. package/build/components/floating-toolbar/nav-up-icon.cjs.map +0 -7
  312. package/build/components/gradients/with-gradient.cjs +0 -36
  313. package/build/components/gradients/with-gradient.cjs.map +0 -7
  314. package/build/components/inserter-button/sparkles.cjs +0 -36
  315. package/build/components/inserter-button/sparkles.cjs.map +0 -7
  316. package/build-module/components/floating-toolbar/nav-up-icon.mjs +0 -31
  317. package/build-module/components/floating-toolbar/nav-up-icon.mjs.map +0 -7
  318. package/build-module/components/gradients/with-gradient.mjs +0 -11
  319. package/build-module/components/gradients/with-gradient.mjs.map +0 -7
  320. package/build-module/components/inserter-button/sparkles.mjs +0 -15
  321. package/build-module/components/inserter-button/sparkles.mjs.map +0 -7
  322. package/build-style/default-editor-styles-rtl.css +0 -68
  323. package/build-style/default-editor-styles.css +0 -68
  324. package/src/components/floating-toolbar/nav-up-icon.js +0 -22
  325. package/src/components/gradients/with-gradient.js +0 -9
  326. package/src/components/inserter-button/README.md +0 -62
  327. package/src/components/inserter-button/sparkles.js +0 -12
  328. package/src/default-editor-styles.scss +0 -25
@@ -33,6 +33,7 @@ import { Content, valueToHTMLString } from './content';
33
33
  import { withDeprecations } from './with-deprecations';
34
34
  import BlockContext from '../block-context';
35
35
  import { unlock } from '../../lock-unlock';
36
+ import { PrivateBlockContext } from '../block-list/private-block-context';
36
37
 
37
38
  // `RichTextShortcut` and `RichTextInputEvent` now live in
38
39
  // `@wordpress/rich-text` so they share the shortcut and input-event contexts
@@ -48,7 +49,7 @@ const {
48
49
 
49
50
  const instanceIdKey = Symbol( 'instanceId' );
50
51
 
51
- export function RichTextWrapper(
52
+ function RichTextWrapper(
52
53
  {
53
54
  children,
54
55
  tagName = 'div',
@@ -87,6 +88,7 @@ export function RichTextWrapper(
87
88
  } );
88
89
  }
89
90
 
91
+ const { supportsSplitting } = useContext( PrivateBlockContext );
90
92
  const instanceId = useInstanceId( RichTextWrapper );
91
93
  const anchorRef = useRef();
92
94
  const [ anchorElement, setAnchorElement ] = useState( null );
@@ -511,6 +513,7 @@ export function RichTextWrapper(
511
513
  onSplitAtDoubleLineEnd,
512
514
  keyboardShortcuts,
513
515
  inputEvents,
516
+ supportsSplitting,
514
517
  } ),
515
518
  anchorRef,
516
519
  setAnchorElement,
@@ -529,11 +532,13 @@ export function RichTextWrapper(
529
532
  );
530
533
  }
531
534
 
535
+ const ForwardedRichTextWrapper = forwardRef( RichTextWrapper );
536
+
537
+ export { ForwardedRichTextWrapper as RichTextWrapper };
538
+
532
539
  // This is the private API for the RichText component.
533
540
  // It allows access to all props, not just the public ones.
534
- export const PrivateRichText = withDeprecations(
535
- forwardRef( RichTextWrapper )
536
- );
541
+ export const PrivateRichText = withDeprecations( ForwardedRichTextWrapper );
537
542
 
538
543
  PrivateRichText.Content = Content;
539
544
  PrivateRichText.isEmpty = ( value ) => {
@@ -1,12 +1,130 @@
1
- import { forwardRef } from '@wordpress/element';
1
+ import { forwardRef, useInsertionEffect, useRef } from '@wordpress/element';
2
2
  import deprecated from '@wordpress/deprecated';
3
3
  import { useDispatch, useSelect } from '@wordpress/data';
4
4
  import { ENTER } from '@wordpress/keycodes';
5
- import { create, split, toHTMLString } from '@wordpress/rich-text';
5
+ import {
6
+ create,
7
+ split,
8
+ toHTMLString,
9
+ privateApis as richTextPrivateApis,
10
+ } from '@wordpress/rich-text';
11
+ import { useRefEffect } from '@wordpress/compose';
6
12
  import { RichTextWrapper } from './';
7
13
  import { store as blockEditorStore } from '../../store';
8
14
  import { useBlockEditContext } from '../block-edit';
9
15
  import { getMultilineTag } from './utils';
16
+ import { unlock } from '../../lock-unlock';
17
+
18
+ const { subscribeOwnedListener } = unlock( richTextPrivateApis );
19
+
20
+ function useEnterRef( props ) {
21
+ const { getSelectionStart, getSelectionEnd } =
22
+ useSelect( blockEditorStore );
23
+ const { selectionChange } = useDispatch( blockEditorStore );
24
+ return useRefEffect( ( element ) => {
25
+ function onKeyDown( event ) {
26
+ if ( event.keyCode !== ENTER ) {
27
+ return;
28
+ }
29
+
30
+ event.preventDefault();
31
+
32
+ const { value, values, onChange, index, identifier, clientId } =
33
+ props.current;
34
+ const { offset: start } = getSelectionStart();
35
+ const { offset: end } = getSelectionEnd();
36
+
37
+ // Cannot split if there is no selection.
38
+ if ( typeof start !== 'number' || typeof end !== 'number' ) {
39
+ return;
40
+ }
41
+
42
+ const richTextValue = create( { html: value } );
43
+ richTextValue.start = start;
44
+ richTextValue.end = end;
45
+
46
+ const array = split( richTextValue ).map( ( v ) =>
47
+ toHTMLString( { value: v } )
48
+ );
49
+
50
+ const newValues = values.slice();
51
+ newValues.splice( index, 1, ...array );
52
+ onChange( newValues );
53
+ selectionChange( clientId, `${ identifier }-${ index + 1 }`, 0, 0 );
54
+ }
55
+ // Capture phase so this runs before the generic rich text enter
56
+ // listener, which skips events that already had their default
57
+ // prevented.
58
+ return subscribeOwnedListener( element, 'keydown', onKeyDown, true );
59
+ }, [] );
60
+ }
61
+
62
+ function Line( lineProps ) {
63
+ const {
64
+ value,
65
+ values,
66
+ onChange,
67
+ index,
68
+ identifier,
69
+ multilineTagName,
70
+ ...props
71
+ } = lineProps;
72
+ const { clientId } = useBlockEditContext();
73
+ const { selectionChange } = useDispatch( blockEditorStore );
74
+ const latestRef = useRef();
75
+ useInsertionEffect( () => {
76
+ latestRef.current = { ...lineProps, clientId };
77
+ } );
78
+ const ref = useEnterRef( latestRef );
79
+ return (
80
+ <RichTextWrapper
81
+ key={ index }
82
+ identifier={ `${ identifier }-${ index }` }
83
+ tagName={ multilineTagName }
84
+ value={ value }
85
+ onChange={ ( newValue ) => {
86
+ const newValues = values.slice();
87
+ newValues[ index ] = newValue;
88
+ onChange( newValues );
89
+ } }
90
+ isSelected={ undefined }
91
+ ref={ ref }
92
+ onMerge={ ( forward ) => {
93
+ const newValues = values.slice();
94
+ let offset = 0;
95
+ if ( forward ) {
96
+ if ( ! newValues[ index + 1 ] ) {
97
+ return;
98
+ }
99
+ newValues.splice(
100
+ index,
101
+ 2,
102
+ newValues[ index ] + newValues[ index + 1 ]
103
+ );
104
+ offset = newValues[ index ].length - 1;
105
+ } else {
106
+ if ( ! newValues[ index - 1 ] ) {
107
+ return;
108
+ }
109
+ newValues.splice(
110
+ index - 1,
111
+ 2,
112
+ newValues[ index - 1 ] + newValues[ index ]
113
+ );
114
+ offset = newValues[ index - 1 ].length - 1;
115
+ }
116
+ onChange( newValues );
117
+ selectionChange(
118
+ clientId,
119
+ `${ identifier }-${ index - ( forward ? 0 : 1 ) }`,
120
+ offset,
121
+ offset
122
+ );
123
+ } }
124
+ { ...props }
125
+ />
126
+ );
127
+ }
10
128
 
11
129
  function RichTextMultiline(
12
130
  {
@@ -27,11 +145,6 @@ function RichTextMultiline(
27
145
  link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/nested-blocks-inner-blocks/',
28
146
  } );
29
147
 
30
- const { clientId } = useBlockEditContext();
31
- const { getSelectionStart, getSelectionEnd } =
32
- useSelect( blockEditorStore );
33
- const { selectionChange } = useDispatch( blockEditorStore );
34
-
35
148
  const multilineTagName = getMultilineTag( multiline );
36
149
  value = value || `<${ multilineTagName }></${ multilineTagName }>`;
37
150
  const padded = `</${ multilineTagName }>${ value }<${ multilineTagName }>`;
@@ -54,87 +167,14 @@ function RichTextMultiline(
54
167
  <TagName ref={ forwardedRef }>
55
168
  { values.map( ( _value, index ) => {
56
169
  return (
57
- <RichTextWrapper
170
+ <Line
58
171
  key={ index }
59
- identifier={ `${ identifier }-${ index }` }
60
- tagName={ multilineTagName }
172
+ values={ values }
61
173
  value={ _value }
62
- onChange={ ( newValue ) => {
63
- const newValues = values.slice();
64
- newValues[ index ] = newValue;
65
- _onChange( newValues );
66
- } }
67
- isSelected={ undefined }
68
- onKeyDown={ ( event ) => {
69
- if ( event.keyCode !== ENTER ) {
70
- return;
71
- }
72
-
73
- event.preventDefault();
74
-
75
- const { offset: start } = getSelectionStart();
76
- const { offset: end } = getSelectionEnd();
77
-
78
- // Cannot split if there is no selection.
79
- if (
80
- typeof start !== 'number' ||
81
- typeof end !== 'number'
82
- ) {
83
- return;
84
- }
85
-
86
- const richTextValue = create( { html: _value } );
87
- richTextValue.start = start;
88
- richTextValue.end = end;
89
-
90
- const array = split( richTextValue ).map( ( v ) =>
91
- toHTMLString( { value: v } )
92
- );
93
-
94
- const newValues = values.slice();
95
- newValues.splice( index, 1, ...array );
96
- _onChange( newValues );
97
- selectionChange(
98
- clientId,
99
- `${ identifier }-${ index + 1 }`,
100
- 0,
101
- 0
102
- );
103
- } }
104
- onMerge={ ( forward ) => {
105
- const newValues = values.slice();
106
- let offset = 0;
107
- if ( forward ) {
108
- if ( ! newValues[ index + 1 ] ) {
109
- return;
110
- }
111
- newValues.splice(
112
- index,
113
- 2,
114
- newValues[ index ] + newValues[ index + 1 ]
115
- );
116
- offset = newValues[ index ].length - 1;
117
- } else {
118
- if ( ! newValues[ index - 1 ] ) {
119
- return;
120
- }
121
- newValues.splice(
122
- index - 1,
123
- 2,
124
- newValues[ index - 1 ] + newValues[ index ]
125
- );
126
- offset = newValues[ index - 1 ].length - 1;
127
- }
128
- _onChange( newValues );
129
- selectionChange(
130
- clientId,
131
- `${ identifier }-${
132
- index - ( forward ? 0 : 1 )
133
- }`,
134
- offset,
135
- offset
136
- );
137
- } }
174
+ onChange={ _onChange }
175
+ index={ index }
176
+ identifier={ identifier }
177
+ multilineTagName={ multilineTagName }
138
178
  { ...props }
139
179
  />
140
180
  );
@@ -6,7 +6,7 @@ import { UP, DOWN, ENTER, TAB } from '@wordpress/keycodes';
6
6
  import {
7
7
  BaseControl,
8
8
  Button,
9
- __experimentalInputControl as InputControl,
9
+ __experimentalInputControl as WCInputControl,
10
10
  Spinner,
11
11
  Popover,
12
12
  privateApis as componentsPrivateApis,
@@ -436,7 +436,7 @@ function Control( {
436
436
 
437
437
  const MaybeValidatedInputControl = isValidated
438
438
  ? ValidatedInputControl
439
- : InputControl;
439
+ : WCInputControl;
440
440
 
441
441
  return (
442
442
  <BaseControl { ...controlProps }>
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Temporary test helper while `URLInput` still unlocks the deprecated private
3
+ * `ValidatedInputControl` from `@wordpress/components`.
4
+ *
5
+ * DELETE this file (and remove its imports) once `URLInput` migrates to
6
+ * `@wordpress/ui` `ValidatedInputControl`.
7
+ */
8
+
9
+ export const VALIDATED_INPUT_CONTROL_DEPRECATION =
10
+ 'wp.components.privateApis.ValidatedInputControl is deprecated since version 7.2. Please use ValidatedInputControl from @wordpress/ui instead. Note: This private API will be completely removed within a few Gutenberg plugin releases.';
11
+
12
+ /**
13
+ * Asserts the expected deprecation warning when URL validation rendered the
14
+ * private `ValidatedInputControl`. No-op when validation did not run.
15
+ */
16
+ export function expectValidatedInputControlDeprecationIfCalled() {
17
+ // eslint-disable-next-line no-console -- jest-console mock inspection.
18
+ const deprecationCalls = console.warn.mock.calls.filter(
19
+ ( [ message ] ) => message === VALIDATED_INPUT_CONTROL_DEPRECATION
20
+ );
21
+
22
+ if ( deprecationCalls.length > 0 ) {
23
+ expect( console ).toHaveWarnedWith(
24
+ VALIDATED_INPUT_CONTROL_DEPRECATION
25
+ );
26
+ }
27
+ }
@@ -6,6 +6,7 @@ import { dispatch } from '@wordpress/data';
6
6
  import { UP, DOWN, ENTER, TAB } from '@wordpress/keycodes';
7
7
  import URLInput from '../';
8
8
  import { store as blockEditorStore } from '../../../store';
9
+ import { expectValidatedInputControlDeprecationIfCalled } from './fixtures/validated-input-control-deprecation';
9
10
 
10
11
  jest.mock( '@wordpress/a11y', () => ( { speak: jest.fn() } ) );
11
12
 
@@ -636,6 +637,10 @@ describe( 'URLInput', () => {
636
637
  } );
637
638
 
638
639
  describe( 'validation', () => {
640
+ afterEach( () => {
641
+ expectValidatedInputControlDeprecationIfCalled();
642
+ } );
643
+
639
644
  it( 'should not remount the input when a custom validity is cleared', async () => {
640
645
  const user = userEvent.setup();
641
646
  const props = {
@@ -120,6 +120,13 @@ drawer.
120
120
  - Type: `Function`
121
121
  - Required: No
122
122
 
123
+ ### additionalControls
124
+
125
+ Elements rendered in a row below the URL input. They are hidden while the settings drawer is open.
126
+
127
+ - Type: `Element`
128
+ - Required: No
129
+
123
130
  ## Useful UI pieces
124
131
 
125
132
  The URLPopover exposes two components that may be used as child components to make the UI creation process easier.
@@ -4,56 +4,142 @@ import { __ } from '@wordpress/i18n';
4
4
  import { keyboardReturn } from '@wordpress/icons';
5
5
  import URLPopover from '../';
6
6
 
7
- export default { title: 'BlockEditor/URLPopover' };
7
+ const meta = {
8
+ title: 'BlockEditor/URLPopover',
9
+ component: URLPopover,
10
+ parameters: {
11
+ // FIXME: Story uses a raw unstyled input whose placeholder fails color-contrast.
12
+ // See: https://github.com/WordPress/gutenberg/issues/81596
13
+ a11y: { test: 'todo' },
14
+ docs: {
15
+ canvas: { sourceState: 'shown' },
16
+ description: {
17
+ component:
18
+ 'Popover component used for editing and viewing URLs.',
19
+ },
20
+ },
21
+ },
22
+ argTypes: {
23
+ onClose: {
24
+ action: 'onClose',
25
+ description: 'Callback when the popover is closed.',
26
+ table: {
27
+ type: { summary: 'function' },
28
+ },
29
+ },
30
+ renderSettings: {
31
+ description: 'Callback to render settings inside the popover.',
32
+ table: {
33
+ type: { summary: 'function' },
34
+ },
35
+ control: false,
36
+ },
37
+ additionalControls: {
38
+ description:
39
+ 'Additional controls rendered below the input row. They are hidden while the settings drawer is open.',
40
+ table: {
41
+ type: { summary: 'Element' },
42
+ },
43
+ control: false,
44
+ },
45
+ placement: {
46
+ control: { type: 'select' },
47
+ options: [
48
+ 'top',
49
+ 'top-start',
50
+ 'top-end',
51
+ 'right',
52
+ 'right-start',
53
+ 'right-end',
54
+ 'bottom',
55
+ 'bottom-start',
56
+ 'bottom-end',
57
+ 'left',
58
+ 'left-start',
59
+ 'left-end',
60
+ 'overlay',
61
+ ],
62
+ description: 'Placement of the popover relative to its parent.',
63
+ table: {
64
+ type: { summary: 'string' },
65
+ defaultValue: { summary: "'bottom'" },
66
+ },
67
+ },
68
+ focusOnMount: {
69
+ control: { type: 'select' },
70
+ options: [ 'firstElement', 'firstInputElement', true, false ],
71
+ description:
72
+ 'Controls which element is focused when the popover mounts.',
73
+ table: {
74
+ type: {
75
+ summary: "boolean | 'firstElement' | 'firstInputElement'",
76
+ },
77
+ defaultValue: { summary: "'firstElement'" },
78
+ },
79
+ },
80
+ },
81
+ args: {
82
+ placement: 'bottom',
83
+ focusOnMount: 'firstElement',
84
+ },
85
+ };
8
86
 
9
- const TestURLPopover = () => {
10
- const [ isVisible, setVisiblility ] = useState( false );
11
- const [ url, setUrl ] = useState( '' );
87
+ export default meta;
12
88
 
13
- const close = () => setVisiblility( false );
14
- const setTarget = () => {};
89
+ export const Default = {
90
+ render: function Template( { onClose, ...args } ) {
91
+ const [ isVisible, setIsVisible ] = useState( true );
92
+ const [ url, setUrl ] = useState( '' );
93
+ const [ isOpenInNewTab, setIsOpenInNewTab ] = useState( false );
15
94
 
16
- const handleUrlChange = ( event ) => {
17
- setUrl( event.target.value );
18
- };
95
+ // Close the popover.
96
+ const closePopover = () => setIsVisible( false );
19
97
 
20
- return (
21
- <>
22
- <Button
23
- __next40pxDefaultSize
24
- onClick={ () => setVisiblility( true ) }
25
- >
26
- Edit URL
27
- </Button>
28
- { isVisible && (
29
- <URLPopover
30
- onClose={ close }
31
- renderSettings={ () => (
32
- <ToggleControl
33
- label={ __( 'Open in new tab' ) }
34
- onChange={ setTarget }
35
- />
36
- ) }
98
+ return (
99
+ <>
100
+ <Button
101
+ __next40pxDefaultSize
102
+ onClick={ () => setIsVisible( true ) }
37
103
  >
38
- <form onSubmit={ close }>
39
- <input
40
- type="url"
41
- value={ url }
42
- onChange={ handleUrlChange }
43
- />
44
- <Button
45
- __next40pxDefaultSize
46
- icon={ keyboardReturn }
47
- label={ __( 'Apply' ) }
48
- type="submit"
49
- />
50
- </form>
51
- </URLPopover>
52
- ) }
53
- </>
54
- );
55
- };
56
-
57
- export const _default = () => {
58
- return <TestURLPopover />;
104
+ { __( 'Edit URL' ) }
105
+ </Button>
106
+ { isVisible && (
107
+ <URLPopover
108
+ { ...args }
109
+ onClose={ ( ...closeArgs ) => {
110
+ onClose( ...closeArgs );
111
+ closePopover();
112
+ } }
113
+ renderSettings={ () => (
114
+ <ToggleControl
115
+ label={ __( 'Open in new tab' ) }
116
+ checked={ isOpenInNewTab }
117
+ onChange={ setIsOpenInNewTab }
118
+ />
119
+ ) }
120
+ >
121
+ <form
122
+ onSubmit={ ( e ) => {
123
+ e.preventDefault();
124
+ closePopover();
125
+ } }
126
+ >
127
+ <input
128
+ type="url"
129
+ placeholder={ __( 'Enter URL' ) }
130
+ value={ url }
131
+ onChange={ ( e ) => setUrl( e.target.value ) }
132
+ />
133
+ <Button
134
+ __next40pxDefaultSize
135
+ icon={ keyboardReturn }
136
+ label={ __( 'Apply' ) }
137
+ type="submit"
138
+ />
139
+ </form>
140
+ </URLPopover>
141
+ ) }
142
+ </>
143
+ );
144
+ },
59
145
  };