@wordpress/block-editor 12.13.0 → 12.14.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 (344) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-heading-level-dropdown/index.js +1 -1
  3. package/build/components/block-heading-level-dropdown/index.js.map +1 -1
  4. package/build/components/block-list/index.js +2 -9
  5. package/build/components/block-list/index.js.map +1 -1
  6. package/build/components/block-list-appender/index.js +16 -3
  7. package/build/components/block-list-appender/index.js.map +1 -1
  8. package/build/components/block-quick-navigation/index.js +6 -4
  9. package/build/components/block-quick-navigation/index.js.map +1 -1
  10. package/build/components/block-styles/index.js +0 -8
  11. package/build/components/block-styles/index.js.map +1 -1
  12. package/build/components/block-switcher/pattern-transformations-menu.js +18 -14
  13. package/build/components/block-switcher/pattern-transformations-menu.js.map +1 -1
  14. package/build/components/block-tools/back-compat.js +2 -2
  15. package/build/components/block-tools/back-compat.js.map +1 -1
  16. package/build/components/block-tools/block-contextual-toolbar.js +11 -81
  17. package/build/components/block-tools/block-contextual-toolbar.js.map +1 -1
  18. package/build/components/block-tools/empty-block-inserter.js +56 -0
  19. package/build/components/block-tools/empty-block-inserter.js.map +1 -0
  20. package/build/components/block-tools/index.js +48 -9
  21. package/build/components/block-tools/index.js.map +1 -1
  22. package/build/components/block-tools/selected-block-tools.js +113 -0
  23. package/build/components/block-tools/selected-block-tools.js.map +1 -0
  24. package/build/components/block-tools/use-selected-block-tool-props.js +56 -0
  25. package/build/components/block-tools/use-selected-block-tool-props.js.map +1 -0
  26. package/build/components/editable-text/index.js +1 -2
  27. package/build/components/editable-text/index.js.map +1 -1
  28. package/build/components/iframe/index.js +4 -3
  29. package/build/components/iframe/index.js.map +1 -1
  30. package/build/components/inserter/block-patterns-explorer/{explorer.js → index.js} +7 -7
  31. package/build/components/inserter/block-patterns-explorer/index.js.map +1 -0
  32. package/build/components/inserter/block-patterns-explorer/{sidebar.js → pattern-explorer-sidebar.js} +1 -1
  33. package/build/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js.map +1 -0
  34. package/build/components/inserter/block-patterns-explorer/{patterns-list.js → pattern-list.js} +4 -4
  35. package/build/components/inserter/block-patterns-explorer/pattern-list.js.map +1 -0
  36. package/build/components/inserter/block-patterns-tab/index.js +75 -0
  37. package/build/components/inserter/block-patterns-tab/index.js.map +1 -0
  38. package/build/components/inserter/block-patterns-tab/pattern-category-preview-panel.js +48 -0
  39. package/build/components/inserter/block-patterns-tab/pattern-category-preview-panel.js.map +1 -0
  40. package/build/components/inserter/block-patterns-tab/pattern-category-previews.js +108 -0
  41. package/build/components/inserter/block-patterns-tab/pattern-category-previews.js.map +1 -0
  42. package/build/components/inserter/{block-patterns-filter.js → block-patterns-tab/patterns-filter.js} +18 -34
  43. package/build/components/inserter/block-patterns-tab/patterns-filter.js.map +1 -0
  44. package/build/components/inserter/block-patterns-tab/use-pattern-categories.js +55 -0
  45. package/build/components/inserter/block-patterns-tab/use-pattern-categories.js.map +1 -0
  46. package/build/components/inserter/block-patterns-tab/utils.js +70 -0
  47. package/build/components/inserter/block-patterns-tab/utils.js.map +1 -0
  48. package/build/components/inserter/media-tab/media-list.js +9 -5
  49. package/build/components/inserter/media-tab/media-list.js.map +1 -1
  50. package/build/components/inserter/media-tab/media-preview.js +15 -12
  51. package/build/components/inserter/media-tab/media-preview.js.map +1 -1
  52. package/build/components/inserter/menu.js +3 -4
  53. package/build/components/inserter/menu.js.map +1 -1
  54. package/build/components/link-control/index.js +6 -5
  55. package/build/components/link-control/index.js.map +1 -1
  56. package/build/components/list-view/block-select-button.js +39 -0
  57. package/build/components/list-view/block-select-button.js.map +1 -1
  58. package/build/components/list-view/block.js +16 -3
  59. package/build/components/list-view/block.js.map +1 -1
  60. package/build/components/list-view/index.js +3 -2
  61. package/build/components/list-view/index.js.map +1 -1
  62. package/build/components/navigable-toolbar/index.js +69 -18
  63. package/build/components/navigable-toolbar/index.js.map +1 -1
  64. package/build/components/provider/use-block-sync.js +1 -14
  65. package/build/components/provider/use-block-sync.js.map +1 -1
  66. package/build/components/rich-text/index.js +0 -1
  67. package/build/components/rich-text/index.js.map +1 -1
  68. package/build/components/rich-text/index.native.js +3 -1
  69. package/build/components/rich-text/index.native.js.map +1 -1
  70. package/build/components/rich-text/native/format-edit.js +45 -0
  71. package/build/components/rich-text/native/format-edit.js.map +1 -0
  72. package/build/components/rich-text/native/get-format-colors.native.js +41 -0
  73. package/build/components/rich-text/native/get-format-colors.native.js.map +1 -0
  74. package/build/components/rich-text/native/index.js +9 -0
  75. package/build/components/rich-text/native/index.js.map +1 -0
  76. package/build/components/rich-text/native/index.native.js +1158 -0
  77. package/build/components/rich-text/native/index.native.js.map +1 -0
  78. package/build/components/rich-text/native/toolbar-button-with-options.native.js +58 -0
  79. package/build/components/rich-text/native/toolbar-button-with-options.native.js.map +1 -0
  80. package/build/components/rich-text/native/use-format-types.js +111 -0
  81. package/build/components/rich-text/native/use-format-types.js.map +1 -0
  82. package/build/components/rich-text/use-paste-handler.js +2 -5
  83. package/build/components/rich-text/use-paste-handler.js.map +1 -1
  84. package/build/components/url-popover/image-url-input-ui.js +2 -1
  85. package/build/components/url-popover/image-url-input-ui.js.map +1 -1
  86. package/build/components/writing-flow/use-tab-nav.js +7 -3
  87. package/build/components/writing-flow/use-tab-nav.js.map +1 -1
  88. package/build/hooks/align.js +10 -10
  89. package/build/hooks/align.js.map +1 -1
  90. package/build/hooks/align.native.js +2 -2
  91. package/build/hooks/align.native.js.map +1 -1
  92. package/build/hooks/anchor.js +7 -6
  93. package/build/hooks/anchor.js.map +1 -1
  94. package/build/hooks/background.js +16 -4
  95. package/build/hooks/background.js.map +1 -1
  96. package/build/hooks/block-hooks.js +7 -8
  97. package/build/hooks/block-hooks.js.map +1 -1
  98. package/build/hooks/block-rename-ui.js +7 -5
  99. package/build/hooks/block-rename-ui.js.map +1 -1
  100. package/build/hooks/content-lock-ui.js +5 -5
  101. package/build/hooks/content-lock-ui.js.map +1 -1
  102. package/build/hooks/custom-class-name.js +8 -7
  103. package/build/hooks/custom-class-name.js.map +1 -1
  104. package/build/hooks/custom-fields.js +4 -4
  105. package/build/hooks/custom-fields.js.map +1 -1
  106. package/build/hooks/duotone.js +9 -20
  107. package/build/hooks/duotone.js.map +1 -1
  108. package/build/hooks/layout.js +90 -86
  109. package/build/hooks/layout.js.map +1 -1
  110. package/build/hooks/position.js +10 -9
  111. package/build/hooks/position.js.map +1 -1
  112. package/build/hooks/style.js +10 -13
  113. package/build/hooks/style.js.map +1 -1
  114. package/build/hooks/utils.js +30 -0
  115. package/build/hooks/utils.js.map +1 -1
  116. package/build/private-apis.js +3 -0
  117. package/build/private-apis.js.map +1 -1
  118. package/build/store/actions.js +30 -37
  119. package/build/store/actions.js.map +1 -1
  120. package/build/store/reducer.js +18 -0
  121. package/build/store/reducer.js.map +1 -1
  122. package/build/store/selectors.js +16 -13
  123. package/build/store/selectors.js.map +1 -1
  124. package/build-module/components/block-heading-level-dropdown/index.js +1 -1
  125. package/build-module/components/block-heading-level-dropdown/index.js.map +1 -1
  126. package/build-module/components/block-list/index.js +3 -10
  127. package/build-module/components/block-list/index.js.map +1 -1
  128. package/build-module/components/block-list-appender/index.js +16 -3
  129. package/build-module/components/block-list-appender/index.js.map +1 -1
  130. package/build-module/components/block-quick-navigation/index.js +7 -5
  131. package/build-module/components/block-quick-navigation/index.js.map +1 -1
  132. package/build-module/components/block-styles/index.js +0 -8
  133. package/build-module/components/block-styles/index.js.map +1 -1
  134. package/build-module/components/block-switcher/pattern-transformations-menu.js +17 -13
  135. package/build-module/components/block-switcher/pattern-transformations-menu.js.map +1 -1
  136. package/build-module/components/block-tools/back-compat.js +1 -1
  137. package/build-module/components/block-tools/back-compat.js.map +1 -1
  138. package/build-module/components/block-tools/block-contextual-toolbar.js +11 -80
  139. package/build-module/components/block-tools/block-contextual-toolbar.js.map +1 -1
  140. package/build-module/components/block-tools/empty-block-inserter.js +48 -0
  141. package/build-module/components/block-tools/empty-block-inserter.js.map +1 -0
  142. package/build-module/components/block-tools/index.js +48 -9
  143. package/build-module/components/block-tools/index.js.map +1 -1
  144. package/build-module/components/block-tools/selected-block-tools.js +105 -0
  145. package/build-module/components/block-tools/selected-block-tools.js.map +1 -0
  146. package/build-module/components/block-tools/use-selected-block-tool-props.js +50 -0
  147. package/build-module/components/block-tools/use-selected-block-tool-props.js.map +1 -0
  148. package/build-module/components/editable-text/index.js +1 -2
  149. package/build-module/components/editable-text/index.js.map +1 -1
  150. package/build-module/components/iframe/index.js +4 -3
  151. package/build-module/components/iframe/index.js.map +1 -1
  152. package/build-module/components/inserter/block-patterns-explorer/{explorer.js → index.js} +5 -5
  153. package/build-module/components/inserter/block-patterns-explorer/index.js.map +1 -0
  154. package/build-module/components/inserter/block-patterns-explorer/{sidebar.js → pattern-explorer-sidebar.js} +1 -1
  155. package/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js.map +1 -0
  156. package/build-module/components/inserter/block-patterns-explorer/{patterns-list.js → pattern-list.js} +2 -2
  157. package/build-module/components/inserter/block-patterns-explorer/pattern-list.js.map +1 -0
  158. package/build-module/components/inserter/block-patterns-tab/index.js +66 -0
  159. package/build-module/components/inserter/block-patterns-tab/index.js.map +1 -0
  160. package/build-module/components/inserter/block-patterns-tab/pattern-category-preview-panel.js +42 -0
  161. package/build-module/components/inserter/block-patterns-tab/pattern-category-preview-panel.js.map +1 -0
  162. package/build-module/components/inserter/block-patterns-tab/pattern-category-previews.js +100 -0
  163. package/build-module/components/inserter/block-patterns-tab/pattern-category-previews.js.map +1 -0
  164. package/build-module/components/inserter/{block-patterns-filter.js → block-patterns-tab/patterns-filter.js} +7 -20
  165. package/build-module/components/inserter/block-patterns-tab/patterns-filter.js.map +1 -0
  166. package/build-module/components/inserter/block-patterns-tab/use-pattern-categories.js +47 -0
  167. package/build-module/components/inserter/block-patterns-tab/use-pattern-categories.js.map +1 -0
  168. package/build-module/components/inserter/block-patterns-tab/utils.js +58 -0
  169. package/build-module/components/inserter/block-patterns-tab/utils.js.map +1 -0
  170. package/build-module/components/inserter/media-tab/media-list.js +9 -5
  171. package/build-module/components/inserter/media-tab/media-list.js.map +1 -1
  172. package/build-module/components/inserter/media-tab/media-preview.js +15 -12
  173. package/build-module/components/inserter/media-tab/media-preview.js.map +1 -1
  174. package/build-module/components/inserter/menu.js +4 -3
  175. package/build-module/components/inserter/menu.js.map +1 -1
  176. package/build-module/components/link-control/index.js +7 -6
  177. package/build-module/components/link-control/index.js.map +1 -1
  178. package/build-module/components/list-view/block-select-button.js +39 -0
  179. package/build-module/components/list-view/block-select-button.js.map +1 -1
  180. package/build-module/components/list-view/block.js +16 -3
  181. package/build-module/components/list-view/block.js.map +1 -1
  182. package/build-module/components/list-view/index.js +3 -2
  183. package/build-module/components/list-view/index.js.map +1 -1
  184. package/build-module/components/navigable-toolbar/index.js +69 -17
  185. package/build-module/components/navigable-toolbar/index.js.map +1 -1
  186. package/build-module/components/provider/use-block-sync.js +1 -14
  187. package/build-module/components/provider/use-block-sync.js.map +1 -1
  188. package/build-module/components/rich-text/index.js +0 -1
  189. package/build-module/components/rich-text/index.js.map +1 -1
  190. package/build-module/components/rich-text/index.native.js +3 -1
  191. package/build-module/components/rich-text/index.native.js.map +1 -1
  192. package/build-module/components/rich-text/native/format-edit.js +38 -0
  193. package/build-module/components/rich-text/native/format-edit.js.map +1 -0
  194. package/build-module/components/rich-text/native/get-format-colors.native.js +34 -0
  195. package/build-module/components/rich-text/native/get-format-colors.native.js.map +1 -0
  196. package/build-module/components/rich-text/native/index.js +2 -0
  197. package/build-module/components/rich-text/native/index.js.map +1 -0
  198. package/build-module/components/rich-text/native/index.native.js +1148 -0
  199. package/build-module/components/rich-text/native/index.native.js.map +1 -0
  200. package/build-module/components/rich-text/native/toolbar-button-with-options.native.js +51 -0
  201. package/build-module/components/rich-text/native/toolbar-button-with-options.native.js.map +1 -0
  202. package/build-module/components/rich-text/native/use-format-types.js +104 -0
  203. package/build-module/components/rich-text/native/use-format-types.js.map +1 -0
  204. package/build-module/components/rich-text/use-paste-handler.js +2 -5
  205. package/build-module/components/rich-text/use-paste-handler.js.map +1 -1
  206. package/build-module/components/url-popover/image-url-input-ui.js +2 -1
  207. package/build-module/components/url-popover/image-url-input-ui.js.map +1 -1
  208. package/build-module/components/writing-flow/use-tab-nav.js +7 -3
  209. package/build-module/components/writing-flow/use-tab-nav.js.map +1 -1
  210. package/build-module/hooks/align.js +8 -8
  211. package/build-module/hooks/align.js.map +1 -1
  212. package/build-module/hooks/align.native.js +2 -2
  213. package/build-module/hooks/align.native.js.map +1 -1
  214. package/build-module/hooks/anchor.js +5 -4
  215. package/build-module/hooks/anchor.js.map +1 -1
  216. package/build-module/hooks/background.js +17 -5
  217. package/build-module/hooks/background.js.map +1 -1
  218. package/build-module/hooks/block-hooks.js +5 -6
  219. package/build-module/hooks/block-hooks.js.map +1 -1
  220. package/build-module/hooks/block-rename-ui.js +5 -3
  221. package/build-module/hooks/block-rename-ui.js.map +1 -1
  222. package/build-module/hooks/content-lock-ui.js +3 -3
  223. package/build-module/hooks/content-lock-ui.js.map +1 -1
  224. package/build-module/hooks/custom-class-name.js +6 -5
  225. package/build-module/hooks/custom-class-name.js.map +1 -1
  226. package/build-module/hooks/custom-fields.js +4 -4
  227. package/build-module/hooks/custom-fields.js.map +1 -1
  228. package/build-module/hooks/duotone.js +10 -21
  229. package/build-module/hooks/duotone.js.map +1 -1
  230. package/build-module/hooks/layout.js +90 -86
  231. package/build-module/hooks/layout.js.map +1 -1
  232. package/build-module/hooks/position.js +11 -10
  233. package/build-module/hooks/position.js.map +1 -1
  234. package/build-module/hooks/style.js +10 -13
  235. package/build-module/hooks/style.js.map +1 -1
  236. package/build-module/hooks/utils.js +30 -1
  237. package/build-module/hooks/utils.js.map +1 -1
  238. package/build-module/private-apis.js +4 -1
  239. package/build-module/private-apis.js.map +1 -1
  240. package/build-module/store/actions.js +29 -37
  241. package/build-module/store/actions.js.map +1 -1
  242. package/build-module/store/reducer.js +17 -0
  243. package/build-module/store/reducer.js.map +1 -1
  244. package/build-module/store/selectors.js +15 -13
  245. package/build-module/store/selectors.js.map +1 -1
  246. package/build-style/style-rtl.css +16 -15
  247. package/build-style/style.css +16 -15
  248. package/package.json +31 -31
  249. package/src/components/block-heading-level-dropdown/index.js +1 -1
  250. package/src/components/block-list/index.js +4 -18
  251. package/src/components/block-list-appender/index.js +20 -4
  252. package/src/components/block-quick-navigation/index.js +11 -5
  253. package/src/components/block-styles/index.js +0 -10
  254. package/src/components/block-switcher/pattern-transformations-menu.js +20 -14
  255. package/src/components/block-toolbar/style.scss +8 -0
  256. package/src/components/block-tools/back-compat.js +1 -1
  257. package/src/components/block-tools/block-contextual-toolbar.js +11 -134
  258. package/src/components/block-tools/empty-block-inserter.js +56 -0
  259. package/src/components/block-tools/index.js +72 -16
  260. package/src/components/block-tools/selected-block-tools.js +127 -0
  261. package/src/components/block-tools/style.scss +0 -10
  262. package/src/components/block-tools/use-selected-block-tool-props.js +66 -0
  263. package/src/components/editable-text/index.js +1 -8
  264. package/src/components/iframe/index.js +4 -3
  265. package/src/components/inserter/block-patterns-explorer/{explorer.js → index.js} +4 -4
  266. package/src/components/inserter/block-patterns-explorer/{patterns-list.js → pattern-list.js} +4 -1
  267. package/src/components/inserter/block-patterns-tab/index.js +118 -0
  268. package/src/components/inserter/block-patterns-tab/pattern-category-preview-panel.js +48 -0
  269. package/src/components/inserter/block-patterns-tab/pattern-category-previews.js +175 -0
  270. package/src/components/inserter/{block-patterns-filter.js → block-patterns-tab/patterns-filter.js} +15 -21
  271. package/src/components/inserter/block-patterns-tab/use-pattern-categories.js +96 -0
  272. package/src/components/inserter/block-patterns-tab/utils.js +76 -0
  273. package/src/components/inserter/media-tab/media-list.js +7 -7
  274. package/src/components/inserter/media-tab/media-preview.js +27 -22
  275. package/src/components/inserter/menu.js +4 -5
  276. package/src/components/link-control/README.md +2 -2
  277. package/src/components/link-control/index.js +15 -6
  278. package/src/components/link-control/style.scss +8 -5
  279. package/src/components/list-view/block-select-button.js +44 -1
  280. package/src/components/list-view/block.js +11 -11
  281. package/src/components/list-view/index.js +2 -0
  282. package/src/components/media-replace-flow/style.scss +2 -2
  283. package/src/components/navigable-toolbar/index.js +71 -25
  284. package/src/components/plain-text/README.md +3 -3
  285. package/src/components/provider/use-block-sync.js +2 -21
  286. package/src/components/rich-text/README.md +9 -8
  287. package/src/components/rich-text/index.js +0 -1
  288. package/src/components/rich-text/index.native.js +3 -1
  289. package/src/components/rich-text/native/format-edit.js +44 -0
  290. package/src/components/rich-text/native/get-format-colors.native.js +54 -0
  291. package/src/components/rich-text/native/index.js +1 -0
  292. package/src/components/rich-text/native/index.native.js +1363 -0
  293. package/src/components/rich-text/native/style.native.scss +28 -0
  294. package/src/components/rich-text/native/test/__snapshots__/index.native.js.snap +79 -0
  295. package/src/components/rich-text/native/test/index.native.js +278 -0
  296. package/src/components/rich-text/native/test/performance/rich-text.native.js +44 -0
  297. package/src/components/rich-text/native/toolbar-button-with-options.native.js +61 -0
  298. package/src/components/rich-text/native/use-format-types.js +146 -0
  299. package/src/components/rich-text/use-paste-handler.js +1 -6
  300. package/src/components/url-popover/image-url-input-ui.js +1 -0
  301. package/src/components/writing-flow/use-tab-nav.js +8 -3
  302. package/src/hooks/align.js +8 -8
  303. package/src/hooks/align.native.js +2 -2
  304. package/src/hooks/anchor.js +21 -23
  305. package/src/hooks/background.js +28 -6
  306. package/src/hooks/block-hooks.js +20 -16
  307. package/src/hooks/block-rename-ui.js +6 -4
  308. package/src/hooks/content-lock-ui.js +3 -3
  309. package/src/hooks/custom-class-name.js +7 -6
  310. package/src/hooks/custom-fields.js +5 -5
  311. package/src/hooks/duotone.js +23 -33
  312. package/src/hooks/layout.js +114 -105
  313. package/src/hooks/position.js +8 -21
  314. package/src/hooks/style.js +17 -31
  315. package/src/hooks/test/align.js +4 -4
  316. package/src/hooks/utils.js +33 -1
  317. package/src/private-apis.js +4 -1
  318. package/src/store/actions.js +26 -72
  319. package/src/store/reducer.js +19 -0
  320. package/src/store/selectors.js +13 -19
  321. package/build/components/block-tools/selected-block-popover.js +0 -221
  322. package/build/components/block-tools/selected-block-popover.js.map +0 -1
  323. package/build/components/inserter/block-patterns-explorer/explorer.js.map +0 -1
  324. package/build/components/inserter/block-patterns-explorer/patterns-list.js.map +0 -1
  325. package/build/components/inserter/block-patterns-explorer/sidebar.js.map +0 -1
  326. package/build/components/inserter/block-patterns-filter.js.map +0 -1
  327. package/build/components/inserter/block-patterns-tab.js +0 -270
  328. package/build/components/inserter/block-patterns-tab.js.map +0 -1
  329. package/build/store/utils.js +0 -22
  330. package/build/store/utils.js.map +0 -1
  331. package/build-module/components/block-tools/selected-block-popover.js +0 -213
  332. package/build-module/components/block-tools/selected-block-popover.js.map +0 -1
  333. package/build-module/components/inserter/block-patterns-explorer/explorer.js.map +0 -1
  334. package/build-module/components/inserter/block-patterns-explorer/patterns-list.js.map +0 -1
  335. package/build-module/components/inserter/block-patterns-explorer/sidebar.js.map +0 -1
  336. package/build-module/components/inserter/block-patterns-filter.js.map +0 -1
  337. package/build-module/components/inserter/block-patterns-tab.js +0 -254
  338. package/build-module/components/inserter/block-patterns-tab.js.map +0 -1
  339. package/build-module/store/utils.js +0 -16
  340. package/build-module/store/utils.js.map +0 -1
  341. package/src/components/block-tools/selected-block-popover.js +0 -265
  342. package/src/components/inserter/block-patterns-tab.js +0 -448
  343. package/src/store/utils.js +0 -12
  344. /package/src/components/inserter/block-patterns-explorer/{sidebar.js → pattern-explorer-sidebar.js} +0 -0
@@ -0,0 +1,175 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ useMemo,
6
+ useState,
7
+ useCallback,
8
+ useRef,
9
+ useEffect,
10
+ } from '@wordpress/element';
11
+ import { __ } from '@wordpress/i18n';
12
+
13
+ import {
14
+ __experimentalHStack as HStack,
15
+ __experimentalVStack as VStack,
16
+ __experimentalHeading as Heading,
17
+ __experimentalText as Text,
18
+ FlexBlock,
19
+ } from '@wordpress/components';
20
+
21
+ /**
22
+ * Internal dependencies
23
+ */
24
+ import usePatternsState from '../hooks/use-patterns-state';
25
+ import BlockPatternList from '../../block-patterns-list';
26
+ import usePatternsPaging from '../hooks/use-patterns-paging';
27
+ import { PatternsFilter } from './patterns-filter';
28
+ import { usePatternCategories } from './use-pattern-categories';
29
+ import {
30
+ isPatternFiltered,
31
+ allPatternsCategory,
32
+ myPatternsCategory,
33
+ } from './utils';
34
+
35
+ const noop = () => {};
36
+
37
+ export function PatternCategoryPreviews( {
38
+ rootClientId,
39
+ onInsert,
40
+ onHover = noop,
41
+ category,
42
+ showTitlesAsTooltip,
43
+ } ) {
44
+ const [ allPatterns, , onClickPattern ] = usePatternsState(
45
+ onInsert,
46
+ rootClientId
47
+ );
48
+ const [ patternSyncFilter, setPatternSyncFilter ] = useState( 'all' );
49
+ const [ patternSourceFilter, setPatternSourceFilter ] = useState( 'all' );
50
+
51
+ const availableCategories = usePatternCategories(
52
+ rootClientId,
53
+ patternSourceFilter
54
+ );
55
+ const scrollContainerRef = useRef();
56
+ const currentCategoryPatterns = useMemo(
57
+ () =>
58
+ allPatterns.filter( ( pattern ) => {
59
+ if (
60
+ isPatternFiltered(
61
+ pattern,
62
+ patternSourceFilter,
63
+ patternSyncFilter
64
+ )
65
+ ) {
66
+ return false;
67
+ }
68
+
69
+ if ( category.name === allPatternsCategory.name ) {
70
+ return true;
71
+ }
72
+ if ( category.name === myPatternsCategory.name && pattern.id ) {
73
+ return true;
74
+ }
75
+ if ( category.name !== 'uncategorized' ) {
76
+ return pattern.categories?.includes( category.name );
77
+ }
78
+
79
+ // The uncategorized category should show all the patterns without any category
80
+ // or with no available category.
81
+ const availablePatternCategories =
82
+ pattern.categories?.filter( ( cat ) =>
83
+ availableCategories.find(
84
+ ( availableCategory ) =>
85
+ availableCategory.name === cat
86
+ )
87
+ ) ?? [];
88
+
89
+ return availablePatternCategories.length === 0;
90
+ } ),
91
+ [
92
+ allPatterns,
93
+ availableCategories,
94
+ category.name,
95
+ patternSourceFilter,
96
+ patternSyncFilter,
97
+ ]
98
+ );
99
+
100
+ const pagingProps = usePatternsPaging(
101
+ currentCategoryPatterns,
102
+ category,
103
+ scrollContainerRef
104
+ );
105
+ const { changePage } = pagingProps;
106
+
107
+ // Hide block pattern preview on unmount.
108
+ // eslint-disable-next-line react-hooks/exhaustive-deps
109
+ useEffect( () => () => onHover( null ), [] );
110
+
111
+ const onSetPatternSyncFilter = useCallback(
112
+ ( value ) => {
113
+ setPatternSyncFilter( value );
114
+ changePage( 1 );
115
+ },
116
+ [ setPatternSyncFilter, changePage ]
117
+ );
118
+ const onSetPatternSourceFilter = useCallback(
119
+ ( value ) => {
120
+ setPatternSourceFilter( value );
121
+ changePage( 1 );
122
+ },
123
+ [ setPatternSourceFilter, changePage ]
124
+ );
125
+
126
+ return (
127
+ <div className="block-editor-inserter__patterns-category-panel">
128
+ <VStack
129
+ spacing={ 2 }
130
+ className="block-editor-inserter__patterns-category-panel-header"
131
+ >
132
+ <HStack>
133
+ <FlexBlock>
134
+ <Heading level={ 4 } as="div">
135
+ { category.label }
136
+ </Heading>
137
+ </FlexBlock>
138
+ <PatternsFilter
139
+ patternSyncFilter={ patternSyncFilter }
140
+ patternSourceFilter={ patternSourceFilter }
141
+ setPatternSyncFilter={ onSetPatternSyncFilter }
142
+ setPatternSourceFilter={ onSetPatternSourceFilter }
143
+ scrollContainerRef={ scrollContainerRef }
144
+ category={ category }
145
+ />
146
+ </HStack>
147
+ { ! currentCategoryPatterns.length && (
148
+ <Text
149
+ variant="muted"
150
+ className="block-editor-inserter__patterns-category-no-results"
151
+ >
152
+ { __( 'No results found' ) }
153
+ </Text>
154
+ ) }
155
+ </VStack>
156
+
157
+ { currentCategoryPatterns.length > 0 && (
158
+ <BlockPatternList
159
+ ref={ scrollContainerRef }
160
+ shownPatterns={ pagingProps.categoryPatternsAsyncList }
161
+ blockPatterns={ pagingProps.categoryPatterns }
162
+ onClickPattern={ onClickPattern }
163
+ onHover={ onHover }
164
+ label={ category.label }
165
+ orientation="vertical"
166
+ category={ category.name }
167
+ isDraggable
168
+ showTitlesAsTooltip={ showTitlesAsTooltip }
169
+ patternFilter={ patternSourceFilter }
170
+ pagingProps={ pagingProps }
171
+ />
172
+ ) }
173
+ </div>
174
+ );
175
+ }
@@ -9,29 +9,14 @@ import {
9
9
  MenuItemsChoice,
10
10
  ExternalLink,
11
11
  } from '@wordpress/components';
12
- import { __ } from '@wordpress/i18n';
12
+ import { __, _x } from '@wordpress/i18n';
13
13
  import { Icon } from '@wordpress/icons';
14
14
  import { useMemo, createInterpolateElement } from '@wordpress/element';
15
15
 
16
16
  /**
17
17
  * Internal dependencies
18
18
  */
19
- import { myPatternsCategory } from './block-patterns-tab';
20
-
21
- export const PATTERN_TYPES = {
22
- all: 'all',
23
- synced: 'synced',
24
- unsynced: 'unsynced',
25
- user: 'user',
26
- theme: 'theme',
27
- directory: 'directory',
28
- };
29
-
30
- export const SYNC_TYPES = {
31
- all: 'all',
32
- full: 'fully',
33
- unsynced: 'unsynced',
34
- };
19
+ import { myPatternsCategory, SYNC_TYPES, PATTERN_TYPES } from './utils';
35
20
 
36
21
  const getShouldDisableSyncFilter = ( sourceFilter ) =>
37
22
  sourceFilter !== PATTERN_TYPES.all && sourceFilter !== PATTERN_TYPES.user;
@@ -40,7 +25,7 @@ const getShouldDisableNonUserSources = ( category ) => {
40
25
  return category.name === myPatternsCategory.name;
41
26
  };
42
27
 
43
- export function BlockPatternsSyncFilter( {
28
+ export function PatternsFilter( {
44
29
  setPatternSyncFilter,
45
30
  setPatternSourceFilter,
46
31
  patternSyncFilter,
@@ -70,15 +55,24 @@ export function BlockPatternsSyncFilter( {
70
55
 
71
56
  const patternSyncMenuOptions = useMemo(
72
57
  () => [
73
- { value: SYNC_TYPES.all, label: __( 'All' ) },
58
+ {
59
+ value: SYNC_TYPES.all,
60
+ label: _x( 'All', 'Option that shows all patterns' ),
61
+ },
74
62
  {
75
63
  value: SYNC_TYPES.full,
76
- label: __( 'Synced' ),
64
+ label: _x(
65
+ 'Synced',
66
+ 'Option that shows all synchronized patterns'
67
+ ),
77
68
  disabled: shouldDisableSyncFilter,
78
69
  },
79
70
  {
80
71
  value: SYNC_TYPES.unsynced,
81
- label: __( 'Not synced' ),
72
+ label: _x(
73
+ 'Not synced',
74
+ 'Option that shows all patterns that are not synchronized'
75
+ ),
82
76
  disabled: shouldDisableSyncFilter,
83
77
  },
84
78
  ],
@@ -0,0 +1,96 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useMemo, useCallback } from '@wordpress/element';
5
+ import { _x, _n, sprintf } from '@wordpress/i18n';
6
+
7
+ import { speak } from '@wordpress/a11y';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import usePatternsState from '../hooks/use-patterns-state';
13
+ import {
14
+ isPatternFiltered,
15
+ allPatternsCategory,
16
+ myPatternsCategory,
17
+ } from './utils';
18
+
19
+ export function usePatternCategories( rootClientId, sourceFilter = 'all' ) {
20
+ const [ patterns, allCategories ] = usePatternsState(
21
+ undefined,
22
+ rootClientId
23
+ );
24
+
25
+ const filteredPatterns = useMemo(
26
+ () =>
27
+ sourceFilter === 'all'
28
+ ? patterns
29
+ : patterns.filter(
30
+ ( pattern ) =>
31
+ ! isPatternFiltered( pattern, sourceFilter )
32
+ ),
33
+ [ sourceFilter, patterns ]
34
+ );
35
+
36
+ const hasRegisteredCategory = useCallback(
37
+ ( pattern ) => {
38
+ if ( ! pattern.categories || ! pattern.categories.length ) {
39
+ return false;
40
+ }
41
+
42
+ return pattern.categories.some( ( cat ) =>
43
+ allCategories.some( ( category ) => category.name === cat )
44
+ );
45
+ },
46
+ [ allCategories ]
47
+ );
48
+
49
+ // Remove any empty categories.
50
+ const populatedCategories = useMemo( () => {
51
+ const categories = allCategories
52
+ .filter( ( category ) =>
53
+ filteredPatterns.some( ( pattern ) =>
54
+ pattern.categories?.includes( category.name )
55
+ )
56
+ )
57
+ .sort( ( a, b ) => a.label.localeCompare( b.label ) );
58
+
59
+ if (
60
+ filteredPatterns.some(
61
+ ( pattern ) => ! hasRegisteredCategory( pattern )
62
+ ) &&
63
+ ! categories.find(
64
+ ( category ) => category.name === 'uncategorized'
65
+ )
66
+ ) {
67
+ categories.push( {
68
+ name: 'uncategorized',
69
+ label: _x( 'Uncategorized' ),
70
+ } );
71
+ }
72
+ if ( filteredPatterns.some( ( pattern ) => pattern.id ) ) {
73
+ categories.unshift( myPatternsCategory );
74
+ }
75
+ if ( filteredPatterns.length > 0 ) {
76
+ categories.unshift( {
77
+ name: allPatternsCategory.name,
78
+ label: allPatternsCategory.label,
79
+ } );
80
+ }
81
+ speak(
82
+ sprintf(
83
+ /* translators: %d: number of categories . */
84
+ _n(
85
+ '%d category button displayed.',
86
+ '%d category buttons displayed.',
87
+ categories.length
88
+ ),
89
+ categories.length
90
+ )
91
+ );
92
+ return categories;
93
+ }, [ allCategories, filteredPatterns, hasRegisteredCategory ] );
94
+
95
+ return populatedCategories;
96
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+
5
+ import { __ } from '@wordpress/i18n';
6
+
7
+ export const PATTERN_TYPES = {
8
+ all: 'all',
9
+ synced: 'synced',
10
+ unsynced: 'unsynced',
11
+ user: 'user',
12
+ theme: 'theme',
13
+ directory: 'directory',
14
+ };
15
+
16
+ export const SYNC_TYPES = {
17
+ all: 'all',
18
+ full: 'fully',
19
+ unsynced: 'unsynced',
20
+ };
21
+
22
+ export const allPatternsCategory = {
23
+ name: 'allPatterns',
24
+ label: __( 'All patterns' ),
25
+ };
26
+
27
+ export const myPatternsCategory = {
28
+ name: 'myPatterns',
29
+ label: __( 'My patterns' ),
30
+ };
31
+
32
+ export function isPatternFiltered( pattern, sourceFilter, syncFilter ) {
33
+ const isUserPattern = pattern.name.startsWith( 'core/block' );
34
+ const isDirectoryPattern =
35
+ pattern.source === 'core' ||
36
+ pattern.source?.startsWith( 'pattern-directory' );
37
+
38
+ // If theme source selected, filter out user created patterns and those from
39
+ // the core patterns directory.
40
+ if (
41
+ sourceFilter === PATTERN_TYPES.theme &&
42
+ ( isUserPattern || isDirectoryPattern )
43
+ ) {
44
+ return true;
45
+ }
46
+
47
+ // If the directory source is selected, filter out user created patterns
48
+ // and those bundled with the theme.
49
+ if (
50
+ sourceFilter === PATTERN_TYPES.directory &&
51
+ ( isUserPattern || ! isDirectoryPattern )
52
+ ) {
53
+ return true;
54
+ }
55
+
56
+ // If user source selected, filter out theme patterns. Any pattern without
57
+ // an id wasn't created by a user.
58
+ if ( sourceFilter === PATTERN_TYPES.user && ! pattern.id ) {
59
+ return true;
60
+ }
61
+
62
+ // Filter by sync status.
63
+ if ( syncFilter === SYNC_TYPES.full && pattern.syncStatus !== '' ) {
64
+ return true;
65
+ }
66
+
67
+ if (
68
+ syncFilter === SYNC_TYPES.unsynced &&
69
+ pattern.syncStatus !== 'unsynced' &&
70
+ isUserPattern
71
+ ) {
72
+ return true;
73
+ }
74
+
75
+ return false;
76
+ }
@@ -1,16 +1,17 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import {
5
- __unstableComposite as Composite,
6
- __unstableUseCompositeState as useCompositeState,
7
- } from '@wordpress/components';
4
+ import { privateApis as componentsPrivateApis } from '@wordpress/components';
8
5
  import { __ } from '@wordpress/i18n';
9
6
 
10
7
  /**
11
8
  * Internal dependencies
12
9
  */
13
10
  import { MediaPreview } from './media-preview';
11
+ import { unlock } from '../../../lock-unlock';
12
+
13
+ const { CompositeV2: Composite, useCompositeStoreV2: useCompositeStore } =
14
+ unlock( componentsPrivateApis );
14
15
 
15
16
  function MediaList( {
16
17
  mediaList,
@@ -18,10 +19,10 @@ function MediaList( {
18
19
  onClick,
19
20
  label = __( 'Media List' ),
20
21
  } ) {
21
- const composite = useCompositeState();
22
+ const compositeStore = useCompositeStore();
22
23
  return (
23
24
  <Composite
24
- { ...composite }
25
+ store={ compositeStore }
25
26
  role="listbox"
26
27
  className="block-editor-inserter__media-list"
27
28
  aria-label={ label }
@@ -32,7 +33,6 @@ function MediaList( {
32
33
  media={ media }
33
34
  category={ category }
34
35
  onClick={ onClick }
35
- composite={ composite }
36
36
  />
37
37
  ) ) }
38
38
  </Composite>
@@ -7,7 +7,6 @@ import classnames from 'classnames';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import {
10
- __unstableCompositeItem as CompositeItem,
11
10
  Tooltip,
12
11
  DropdownMenu,
13
12
  MenuGroup,
@@ -17,6 +16,7 @@ import {
17
16
  Flex,
18
17
  FlexItem,
19
18
  Button,
19
+ privateApis as componentsPrivateApis,
20
20
  __experimentalVStack as VStack,
21
21
  } from '@wordpress/components';
22
22
  import { __, sprintf } from '@wordpress/i18n';
@@ -33,6 +33,7 @@ import { isBlobURL } from '@wordpress/blob';
33
33
  import InserterDraggableBlocks from '../../inserter-draggable-blocks';
34
34
  import { getBlockAndPreviewFromMedia } from './utils';
35
35
  import { store as blockEditorStore } from '../../../store';
36
+ import { unlock } from '../../../lock-unlock';
36
37
 
37
38
  const ALLOWED_MEDIA_TYPES = [ 'image' ];
38
39
  const MAXIMUM_TITLE_LENGTH = 25;
@@ -42,6 +43,8 @@ const MEDIA_OPTIONS_POPOVER_PROPS = {
42
43
  'block-editor-inserter__media-list__item-preview-options__popover',
43
44
  };
44
45
 
46
+ const { CompositeItemV2: CompositeItem } = unlock( componentsPrivateApis );
47
+
45
48
  function MediaPreviewOptions( { category, media } ) {
46
49
  if ( ! category.getReportUrl ) {
47
50
  return null;
@@ -113,7 +116,7 @@ function InsertExternalImageModal( { onClose, onSubmit } ) {
113
116
  );
114
117
  }
115
118
 
116
- export function MediaPreview( { media, onClick, composite, category } ) {
119
+ export function MediaPreview( { media, onClick, category } ) {
117
120
  const [ showExternalUploadModal, setShowExternalUploadModal ] =
118
121
  useState( false );
119
122
  const [ isHovered, setIsHovered ] = useState( false );
@@ -216,20 +219,22 @@ export function MediaPreview( { media, onClick, composite, category } ) {
216
219
  onDragStart={ onDragStart }
217
220
  onDragEnd={ onDragEnd }
218
221
  >
219
- <Tooltip text={ truncatedTitle || title }>
220
- { /* Adding `is-hovered` class to the wrapper element is needed
221
- because the options Popover is rendered outside of this node. */ }
222
- <div
223
- onMouseEnter={ onMouseEnter }
224
- onMouseLeave={ onMouseLeave }
225
- >
222
+ { /* Adding `is-hovered` class to the wrapper element is needed
223
+ because the options Popover is rendered outside of this node. */ }
224
+ <div
225
+ onMouseEnter={ onMouseEnter }
226
+ onMouseLeave={ onMouseLeave }
227
+ >
228
+ <Tooltip text={ truncatedTitle || title }>
226
229
  <CompositeItem
227
- role="option"
228
- as="div"
229
- { ...composite }
230
- className="block-editor-inserter__media-list__item"
230
+ render={
231
+ <div
232
+ aria-label={ title }
233
+ role="option"
234
+ className="block-editor-inserter__media-list__item"
235
+ />
236
+ }
231
237
  onClick={ () => onMediaInsert( block ) }
232
- aria-label={ title }
233
238
  >
234
239
  <div className="block-editor-inserter__media-list__item-preview">
235
240
  { preview }
@@ -240,14 +245,14 @@ export function MediaPreview( { media, onClick, composite, category } ) {
240
245
  ) }
241
246
  </div>
242
247
  </CompositeItem>
243
- { ! isInserting && (
244
- <MediaPreviewOptions
245
- category={ category }
246
- media={ media }
247
- />
248
- ) }
249
- </div>
250
- </Tooltip>
248
+ </Tooltip>
249
+ { ! isInserting && (
250
+ <MediaPreviewOptions
251
+ category={ category }
252
+ media={ media }
253
+ />
254
+ ) }
255
+ </div>
251
256
  </div>
252
257
  ) }
253
258
  </InserterDraggableBlocks>
@@ -24,9 +24,8 @@ import { useSelect } from '@wordpress/data';
24
24
  import Tips from './tips';
25
25
  import InserterPreviewPanel from './preview-panel';
26
26
  import BlockTypesTab from './block-types-tab';
27
- import BlockPatternsTabs, {
28
- BlockPatternsCategoryDialog,
29
- } from './block-patterns-tab';
27
+ import BlockPatternsTab from './block-patterns-tab';
28
+ import { PatternCategoryPreviewPanel } from './block-patterns-tab/pattern-category-preview-panel';
30
29
  import { MediaTab, MediaCategoryDialog, useMediaCategories } from './media-tab';
31
30
  import InserterSearchResults from './search-results';
32
31
  import useDebouncedInput from './hooks/use-debounced-input';
@@ -160,7 +159,7 @@ function InserterMenu(
160
159
 
161
160
  const patternsTab = useMemo(
162
161
  () => (
163
- <BlockPatternsTabs
162
+ <BlockPatternsTab
164
163
  rootClientId={ destinationRootClientId }
165
164
  onInsert={ onInsertPattern }
166
165
  onSelectCategory={ onClickPatternCategory }
@@ -297,7 +296,7 @@ function InserterMenu(
297
296
  <InserterPreviewPanel item={ hoveredItem } />
298
297
  ) }
299
298
  { showPatternPanel && (
300
- <BlockPatternsCategoryDialog
299
+ <PatternCategoryPreviewPanel
301
300
  rootClientId={ destinationRootClientId }
302
301
  onInsert={ onInsertPattern }
303
302
  onHover={ onHoverPattern }
@@ -275,14 +275,14 @@ If passed, children are rendered after the input.
275
275
 
276
276
  ```jsx
277
277
  <LinkControlSearchInput>
278
- <div className="block-editor-link-control__search-actions">
278
+ <HStack justify="right">
279
279
  <Button
280
280
  type="submit"
281
281
  label={ __( 'Submit' ) }
282
282
  icon={ keyboardReturn }
283
283
  className="block-editor-link-control__search-submit"
284
284
  />
285
- </div>
285
+ </HStack>
286
286
  </LinkControlSearchInput>
287
287
  ```
288
288
 
@@ -6,7 +6,13 @@ import classnames from 'classnames';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
- import { Button, Spinner, Notice, TextControl } from '@wordpress/components';
9
+ import {
10
+ Button,
11
+ Spinner,
12
+ Notice,
13
+ TextControl,
14
+ __experimentalHStack as HStack,
15
+ } from '@wordpress/components';
10
16
  import { __ } from '@wordpress/i18n';
11
17
  import { useRef, useState, useEffect } from '@wordpress/element';
12
18
  import { focus } from '@wordpress/dom';
@@ -467,7 +473,13 @@ function LinkControl( {
467
473
  ) }
468
474
 
469
475
  { showActions && (
470
- <div className="block-editor-link-control__search-actions">
476
+ <HStack
477
+ justify="right"
478
+ className="block-editor-link-control__search-actions"
479
+ >
480
+ <Button variant="tertiary" onClick={ handleCancel }>
481
+ { __( 'Cancel' ) }
482
+ </Button>
471
483
  <Button
472
484
  variant="primary"
473
485
  onClick={ isDisabled ? noop : handleSubmit }
@@ -476,10 +488,7 @@ function LinkControl( {
476
488
  >
477
489
  { __( 'Save' ) }
478
490
  </Button>
479
- <Button variant="tertiary" onClick={ handleCancel }>
480
- { __( 'Cancel' ) }
481
- </Button>
482
- </div>
491
+ </HStack>
483
492
  ) }
484
493
 
485
494
  { renderControlBottom && renderControlBottom() }
@@ -61,6 +61,10 @@ $preview-image-height: 140px;
61
61
  .block-editor-link-control__field {
62
62
  margin: $grid-unit-20; // allow margin collapse for vertical spacing.
63
63
 
64
+ .components-base-control__label {
65
+ color: $gray-900;
66
+ }
67
+
64
68
  input[type="text"],
65
69
  // Specificity overide of URLInput defaults.
66
70
  &.block-editor-url-input input[type="text"].block-editor-url-input__input {
@@ -92,12 +96,7 @@ $preview-image-height: 140px;
92
96
  }
93
97
 
94
98
  .block-editor-link-control__search-actions {
95
- display: flex;
96
- flex-direction: row-reverse; // put "Cancel" on the left but retain DOM order.
97
- justify-content: flex-start;
98
- gap: $grid-unit-10;
99
99
  padding: $grid-unit-10 $grid-unit-20 $grid-unit-20;
100
- order: 20;
101
100
  }
102
101
 
103
102
  .block-editor-link-control__search-results-wrapper {
@@ -419,6 +418,10 @@ $preview-image-height: 140px;
419
418
 
420
419
  .components-base-control__field {
421
420
  display: flex; // don't allow label to wrap under checkbox.
421
+
422
+ .components-checkbox-control__label {
423
+ color: $gray-900;
424
+ }
422
425
  }
423
426
 
424
427
  // Cancel left margin inherited from WP Admin Forms CSS.