@wordpress/block-library 10.1.1-next.v.202607070741.0 → 10.3.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 (580) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/build/accordion/block.json +1 -0
  3. package/build/accordion-panel/block.json +1 -0
  4. package/build/button/edit.cjs +18 -8
  5. package/build/button/edit.cjs.map +2 -2
  6. package/build/code/edit.cjs +3 -1
  7. package/build/code/edit.cjs.map +2 -2
  8. package/build/cover/block.json +12 -0
  9. package/build/cover/edit/block-controls.cjs +14 -5
  10. package/build/cover/edit/block-controls.cjs.map +2 -2
  11. package/build/cover/edit/embed-video-url-input.cjs +5 -3
  12. package/build/cover/edit/embed-video-url-input.cjs.map +3 -3
  13. package/build/cover/edit/index.cjs +76 -32
  14. package/build/cover/edit/index.cjs.map +2 -2
  15. package/build/cover/embed-video-utils.cjs +17 -7
  16. package/build/cover/embed-video-utils.cjs.map +2 -2
  17. package/build/details/transforms.cjs +1 -3
  18. package/build/details/transforms.cjs.map +2 -2
  19. package/build/embed/edit.cjs +1 -1
  20. package/build/embed/edit.cjs.map +2 -2
  21. package/build/embed/embed-placeholder.cjs +1 -2
  22. package/build/embed/embed-placeholder.cjs.map +2 -2
  23. package/build/file/edit.cjs +4 -3
  24. package/build/file/edit.cjs.map +2 -2
  25. package/build/file/transforms.cjs +25 -60
  26. package/build/file/transforms.cjs.map +2 -2
  27. package/build/gallery/block.json +4 -2
  28. package/build/gallery/dynamic-gallery.cjs +104 -61
  29. package/build/gallery/dynamic-gallery.cjs.map +3 -3
  30. package/build/gallery/edit.cjs +1 -1
  31. package/build/gallery/edit.cjs.map +3 -3
  32. package/build/gallery/gap-styles.cjs +49 -13
  33. package/build/gallery/gap-styles.cjs.map +3 -3
  34. package/build/gallery/use-dynamic-gallery.cjs +15 -8
  35. package/build/gallery/use-dynamic-gallery.cjs.map +2 -2
  36. package/build/group/transforms.cjs +1 -1
  37. package/build/group/transforms.cjs.map +2 -2
  38. package/build/heading/edit.cjs +1 -1
  39. package/build/heading/edit.cjs.map +2 -2
  40. package/build/html/modal.cjs +63 -54
  41. package/build/html/modal.cjs.map +3 -3
  42. package/build/icon/block.json +5 -3
  43. package/build/icon/components/custom-inserter/icon-grid.cjs +25 -12
  44. package/build/icon/components/custom-inserter/icon-grid.cjs.map +2 -2
  45. package/build/icon/components/custom-inserter/index.cjs +100 -31
  46. package/build/icon/components/custom-inserter/index.cjs.map +3 -3
  47. package/build/icon/edit.cjs +11 -12
  48. package/build/icon/edit.cjs.map +2 -2
  49. package/build/image/block.json +1 -1
  50. package/build/image/edit.cjs +1 -35
  51. package/build/image/edit.cjs.map +2 -2
  52. package/build/image/image.cjs +23 -18
  53. package/build/image/image.cjs.map +3 -3
  54. package/build/image/transforms.cjs +78 -0
  55. package/build/image/transforms.cjs.map +3 -3
  56. package/build/image/use-open-image-media-editor-modal.cjs +6 -2
  57. package/build/image/use-open-image-media-editor-modal.cjs.map +2 -2
  58. package/build/index.cjs +18 -8
  59. package/build/index.cjs.map +2 -2
  60. package/build/latest-posts/edit.cjs +5 -8
  61. package/build/latest-posts/edit.cjs.map +2 -2
  62. package/build/list-item/edit.cjs +1 -1
  63. package/build/list-item/edit.cjs.map +2 -2
  64. package/build/list-item/hooks/use-enter.cjs +14 -17
  65. package/build/list-item/hooks/use-enter.cjs.map +3 -3
  66. package/build/list-item/hooks/use-indent-list-item.cjs +10 -2
  67. package/build/list-item/hooks/use-indent-list-item.cjs.map +2 -2
  68. package/build/list-item/hooks/use-space.cjs +3 -2
  69. package/build/list-item/hooks/use-space.cjs.map +3 -3
  70. package/build/math/edit.cjs +39 -56
  71. package/build/math/edit.cjs.map +3 -3
  72. package/build/media-text/edit.cjs +2 -1
  73. package/build/media-text/edit.cjs.map +2 -2
  74. package/build/more/edit.cjs +2 -2
  75. package/build/more/edit.cjs.map +2 -2
  76. package/build/navigation/edit/index.cjs +30 -16
  77. package/build/navigation/edit/index.cjs.map +3 -3
  78. package/build/navigation/edit/use-layout-custom-properties.cjs +72 -0
  79. package/build/navigation/edit/use-layout-custom-properties.cjs.map +7 -0
  80. package/build/navigation/view.cjs +9 -6
  81. package/build/navigation/view.cjs.map +2 -2
  82. package/build/navigation-link/edit.cjs +3 -3
  83. package/build/navigation-link/edit.cjs.map +2 -2
  84. package/build/navigation-link/link-ui/index.cjs +2 -2
  85. package/build/navigation-link/link-ui/index.cjs.map +2 -2
  86. package/build/paragraph/edit.cjs +5 -2
  87. package/build/paragraph/edit.cjs.map +3 -3
  88. package/build/paragraph/index.cjs +4 -1
  89. package/build/paragraph/index.cjs.map +2 -2
  90. package/build/paragraph/use-enter.cjs +3 -7
  91. package/build/paragraph/use-enter.cjs.map +3 -3
  92. package/build/playlist/block.json +29 -10
  93. package/build/playlist/context.cjs +2 -1
  94. package/build/playlist/context.cjs.map +2 -2
  95. package/build/playlist/edit.cjs +328 -39
  96. package/build/playlist/edit.cjs.map +3 -3
  97. package/build/playlist/index.cjs +1 -1
  98. package/build/playlist/index.cjs.map +2 -2
  99. package/build/playlist/utils.cjs +37 -8
  100. package/build/playlist/utils.cjs.map +2 -2
  101. package/build/playlist/view.cjs +83 -13
  102. package/build/playlist/view.cjs.map +2 -2
  103. package/build/playlist-track/block.json +4 -2
  104. package/build/playlist-track/edit.cjs +115 -70
  105. package/build/playlist-track/edit.cjs.map +2 -2
  106. package/build/post-content/block.json +1 -0
  107. package/build/post-content/edit.cjs +36 -15
  108. package/build/post-content/edit.cjs.map +2 -2
  109. package/build/post-featured-image/edit.cjs +3 -2
  110. package/build/post-featured-image/edit.cjs.map +2 -2
  111. package/build/post-template/block.json +2 -1
  112. package/build/post-template/edit.cjs +10 -1
  113. package/build/post-template/edit.cjs.map +2 -2
  114. package/build/post-terms/edit.cjs +2 -2
  115. package/build/post-terms/edit.cjs.map +2 -2
  116. package/build/post-title/edit.cjs +2 -2
  117. package/build/post-title/edit.cjs.map +2 -2
  118. package/build/preformatted/edit.cjs +3 -1
  119. package/build/preformatted/edit.cjs.map +2 -2
  120. package/build/pullquote/block.json +3 -1
  121. package/build/pullquote/edit.cjs +5 -3
  122. package/build/pullquote/edit.cjs.map +2 -2
  123. package/build/query/block.json +3 -2
  124. package/build/query/edit/inspector-controls/index.cjs +42 -5
  125. package/build/query/edit/inspector-controls/index.cjs.map +2 -2
  126. package/build/query/edit/inspector-controls/offset-controls.cjs +1 -2
  127. package/build/query/edit/inspector-controls/offset-controls.cjs.map +2 -2
  128. package/build/query/edit/inspector-controls/pages-control.cjs +0 -1
  129. package/build/query/edit/inspector-controls/pages-control.cjs.map +2 -2
  130. package/build/query/edit/query-content.cjs +10 -3
  131. package/build/query/edit/query-content.cjs.map +2 -2
  132. package/build/query/index.cjs +2 -1
  133. package/build/query/index.cjs.map +2 -2
  134. package/build/quote/block.json +3 -1
  135. package/build/quote/transforms.cjs +1 -3
  136. package/build/quote/transforms.cjs.map +2 -2
  137. package/build/read-more/edit.cjs +3 -1
  138. package/build/read-more/edit.cjs.map +2 -2
  139. package/build/rss/edit.cjs +0 -1
  140. package/build/rss/edit.cjs.map +2 -2
  141. package/build/site-tagline/edit.cjs +3 -1
  142. package/build/site-tagline/edit.cjs.map +2 -2
  143. package/build/site-title/edit.cjs +3 -1
  144. package/build/site-title/edit.cjs.map +2 -2
  145. package/build/social-links/edit.cjs +11 -4
  146. package/build/social-links/edit.cjs.map +2 -2
  147. package/build/tab-list/block.json +4 -3
  148. package/build/tab-list/edit.cjs +67 -11
  149. package/build/tab-list/edit.cjs.map +3 -3
  150. package/build/tab-list/tab-movers.cjs +87 -0
  151. package/build/tab-list/tab-movers.cjs.map +7 -0
  152. package/build/tab-panel/block.json +1 -6
  153. package/build/tab-panel/edit.cjs +16 -24
  154. package/build/tab-panel/edit.cjs.map +2 -2
  155. package/build/tab-panels/block.json +0 -1
  156. package/build/table/edit.cjs +1 -1
  157. package/build/table/edit.cjs.map +2 -2
  158. package/build/tabs/block.json +0 -5
  159. package/build/tabs/edit.cjs +4 -39
  160. package/build/tabs/edit.cjs.map +3 -3
  161. package/build/tabs/use-tab-actions.cjs +23 -1
  162. package/build/tabs/use-tab-actions.cjs.map +2 -2
  163. package/build/tabs/use-tab-list-items-sync.cjs +19 -1
  164. package/build/tabs/use-tab-list-items-sync.cjs.map +2 -2
  165. package/build/term-name/block.json +1 -3
  166. package/build/term-name/deprecated.cjs +105 -0
  167. package/build/term-name/deprecated.cjs.map +7 -0
  168. package/build/term-name/edit.cjs +11 -37
  169. package/build/term-name/edit.cjs.map +3 -3
  170. package/build/term-name/index.cjs +3 -1
  171. package/build/term-name/index.cjs.map +3 -3
  172. package/build/utils/caption.cjs +2 -2
  173. package/build/utils/caption.cjs.map +2 -2
  174. package/build/utils/waveform-player.cjs +138 -22
  175. package/build/utils/waveform-player.cjs.map +2 -2
  176. package/build/utils/waveform-utils.cjs +315 -17
  177. package/build/utils/waveform-utils.cjs.map +2 -2
  178. package/build/verse/edit.cjs +3 -1
  179. package/build/verse/edit.cjs.map +2 -2
  180. package/build/video/edit.cjs +2 -11
  181. package/build/video/edit.cjs.map +3 -3
  182. package/build/video/tracks-editor.cjs +0 -1
  183. package/build/video/tracks-editor.cjs.map +2 -2
  184. package/build-module/accordion/block.json +1 -0
  185. package/build-module/accordion-panel/block.json +1 -0
  186. package/build-module/button/edit.mjs +19 -14
  187. package/build-module/button/edit.mjs.map +2 -2
  188. package/build-module/code/edit.mjs +3 -1
  189. package/build-module/code/edit.mjs.map +2 -2
  190. package/build-module/cover/block.json +12 -0
  191. package/build-module/cover/edit/block-controls.mjs +14 -5
  192. package/build-module/cover/edit/block-controls.mjs.map +2 -2
  193. package/build-module/cover/edit/embed-video-url-input.mjs +5 -4
  194. package/build-module/cover/edit/embed-video-url-input.mjs.map +2 -2
  195. package/build-module/cover/edit/index.mjs +79 -35
  196. package/build-module/cover/edit/index.mjs.map +2 -2
  197. package/build-module/cover/embed-video-utils.mjs +16 -7
  198. package/build-module/cover/embed-video-utils.mjs.map +2 -2
  199. package/build-module/details/transforms.mjs +2 -7
  200. package/build-module/details/transforms.mjs.map +2 -2
  201. package/build-module/embed/edit.mjs +1 -1
  202. package/build-module/embed/edit.mjs.map +2 -2
  203. package/build-module/embed/embed-placeholder.mjs +1 -2
  204. package/build-module/embed/embed-placeholder.mjs.map +2 -2
  205. package/build-module/file/edit.mjs +4 -3
  206. package/build-module/file/edit.mjs.map +2 -2
  207. package/build-module/file/transforms.mjs +25 -60
  208. package/build-module/file/transforms.mjs.map +2 -2
  209. package/build-module/gallery/block.json +4 -2
  210. package/build-module/gallery/dynamic-gallery.mjs +104 -61
  211. package/build-module/gallery/dynamic-gallery.mjs.map +2 -2
  212. package/build-module/gallery/edit.mjs +3 -3
  213. package/build-module/gallery/edit.mjs.map +2 -2
  214. package/build-module/gallery/gap-styles.mjs +53 -14
  215. package/build-module/gallery/gap-styles.mjs.map +2 -2
  216. package/build-module/gallery/use-dynamic-gallery.mjs +16 -9
  217. package/build-module/gallery/use-dynamic-gallery.mjs.map +2 -2
  218. package/build-module/group/transforms.mjs +2 -5
  219. package/build-module/group/transforms.mjs.map +2 -2
  220. package/build-module/heading/edit.mjs +1 -1
  221. package/build-module/heading/edit.mjs.map +2 -2
  222. package/build-module/html/modal.mjs +68 -55
  223. package/build-module/html/modal.mjs.map +2 -2
  224. package/build-module/icon/block.json +5 -3
  225. package/build-module/icon/components/custom-inserter/icon-grid.mjs +25 -12
  226. package/build-module/icon/components/custom-inserter/icon-grid.mjs.map +2 -2
  227. package/build-module/icon/components/custom-inserter/index.mjs +102 -33
  228. package/build-module/icon/components/custom-inserter/index.mjs.map +2 -2
  229. package/build-module/icon/edit.mjs +11 -12
  230. package/build-module/icon/edit.mjs.map +2 -2
  231. package/build-module/image/block.json +1 -1
  232. package/build-module/image/edit.mjs +1 -35
  233. package/build-module/image/edit.mjs.map +2 -2
  234. package/build-module/image/image.mjs +23 -18
  235. package/build-module/image/image.mjs.map +2 -2
  236. package/build-module/image/transforms.mjs +78 -0
  237. package/build-module/image/transforms.mjs.map +2 -2
  238. package/build-module/image/use-open-image-media-editor-modal.mjs +6 -2
  239. package/build-module/image/use-open-image-media-editor-modal.mjs.map +2 -2
  240. package/build-module/index.mjs +18 -8
  241. package/build-module/index.mjs.map +2 -2
  242. package/build-module/latest-posts/edit.mjs +5 -8
  243. package/build-module/latest-posts/edit.mjs.map +2 -2
  244. package/build-module/list-item/edit.mjs +1 -1
  245. package/build-module/list-item/edit.mjs.map +2 -2
  246. package/build-module/list-item/hooks/use-enter.mjs +15 -21
  247. package/build-module/list-item/hooks/use-enter.mjs.map +2 -2
  248. package/build-module/list-item/hooks/use-indent-list-item.mjs +10 -2
  249. package/build-module/list-item/hooks/use-indent-list-item.mjs.map +2 -2
  250. package/build-module/list-item/hooks/use-space.mjs +4 -6
  251. package/build-module/list-item/hooks/use-space.mjs.map +2 -2
  252. package/build-module/math/edit.mjs +41 -60
  253. package/build-module/math/edit.mjs.map +2 -2
  254. package/build-module/media-text/edit.mjs +2 -1
  255. package/build-module/media-text/edit.mjs.map +2 -2
  256. package/build-module/more/edit.mjs +2 -2
  257. package/build-module/more/edit.mjs.map +2 -2
  258. package/build-module/navigation/edit/index.mjs +30 -16
  259. package/build-module/navigation/edit/index.mjs.map +2 -2
  260. package/build-module/navigation/edit/use-layout-custom-properties.mjs +51 -0
  261. package/build-module/navigation/edit/use-layout-custom-properties.mjs.map +7 -0
  262. package/build-module/navigation/view.mjs +9 -6
  263. package/build-module/navigation/view.mjs.map +2 -2
  264. package/build-module/navigation-link/edit.mjs +3 -3
  265. package/build-module/navigation-link/edit.mjs.map +2 -2
  266. package/build-module/navigation-link/link-ui/index.mjs +2 -2
  267. package/build-module/navigation-link/link-ui/index.mjs.map +2 -2
  268. package/build-module/paragraph/edit.mjs +6 -2
  269. package/build-module/paragraph/edit.mjs.map +2 -2
  270. package/build-module/paragraph/index.mjs +4 -1
  271. package/build-module/paragraph/index.mjs.map +2 -2
  272. package/build-module/paragraph/use-enter.mjs +4 -11
  273. package/build-module/paragraph/use-enter.mjs.map +2 -2
  274. package/build-module/playlist/block.json +29 -10
  275. package/build-module/playlist/context.mjs +2 -1
  276. package/build-module/playlist/context.mjs.map +2 -2
  277. package/build-module/playlist/edit.mjs +331 -41
  278. package/build-module/playlist/edit.mjs.map +2 -2
  279. package/build-module/playlist/index.mjs +1 -1
  280. package/build-module/playlist/index.mjs.map +2 -2
  281. package/build-module/playlist/utils.mjs +35 -7
  282. package/build-module/playlist/utils.mjs.map +2 -2
  283. package/build-module/playlist/view.mjs +89 -14
  284. package/build-module/playlist/view.mjs.map +2 -2
  285. package/build-module/playlist-track/block.json +4 -2
  286. package/build-module/playlist-track/edit.mjs +117 -71
  287. package/build-module/playlist-track/edit.mjs.map +2 -2
  288. package/build-module/post-content/block.json +1 -0
  289. package/build-module/post-content/edit.mjs +37 -15
  290. package/build-module/post-content/edit.mjs.map +2 -2
  291. package/build-module/post-featured-image/edit.mjs +3 -2
  292. package/build-module/post-featured-image/edit.mjs.map +2 -2
  293. package/build-module/post-template/block.json +2 -1
  294. package/build-module/post-template/edit.mjs +10 -1
  295. package/build-module/post-template/edit.mjs.map +2 -2
  296. package/build-module/post-terms/edit.mjs +2 -2
  297. package/build-module/post-terms/edit.mjs.map +2 -2
  298. package/build-module/post-title/edit.mjs +2 -2
  299. package/build-module/post-title/edit.mjs.map +2 -2
  300. package/build-module/preformatted/edit.mjs +3 -1
  301. package/build-module/preformatted/edit.mjs.map +2 -2
  302. package/build-module/pullquote/block.json +3 -1
  303. package/build-module/pullquote/edit.mjs +5 -3
  304. package/build-module/pullquote/edit.mjs.map +2 -2
  305. package/build-module/query/block.json +3 -2
  306. package/build-module/query/edit/inspector-controls/index.mjs +44 -6
  307. package/build-module/query/edit/inspector-controls/index.mjs.map +2 -2
  308. package/build-module/query/edit/inspector-controls/offset-controls.mjs +2 -3
  309. package/build-module/query/edit/inspector-controls/offset-controls.mjs.map +2 -2
  310. package/build-module/query/edit/inspector-controls/pages-control.mjs +0 -1
  311. package/build-module/query/edit/inspector-controls/pages-control.mjs.map +2 -2
  312. package/build-module/query/edit/query-content.mjs +10 -3
  313. package/build-module/query/edit/query-content.mjs.map +2 -2
  314. package/build-module/query/index.mjs +2 -1
  315. package/build-module/query/index.mjs.map +2 -2
  316. package/build-module/quote/block.json +3 -1
  317. package/build-module/quote/transforms.mjs +2 -4
  318. package/build-module/quote/transforms.mjs.map +2 -2
  319. package/build-module/read-more/edit.mjs +3 -1
  320. package/build-module/read-more/edit.mjs.map +2 -2
  321. package/build-module/rss/edit.mjs +0 -1
  322. package/build-module/rss/edit.mjs.map +2 -2
  323. package/build-module/site-tagline/edit.mjs +3 -1
  324. package/build-module/site-tagline/edit.mjs.map +2 -2
  325. package/build-module/site-title/edit.mjs +3 -1
  326. package/build-module/site-title/edit.mjs.map +2 -2
  327. package/build-module/social-links/edit.mjs +11 -4
  328. package/build-module/social-links/edit.mjs.map +2 -2
  329. package/build-module/tab-list/block.json +4 -3
  330. package/build-module/tab-list/edit.mjs +74 -13
  331. package/build-module/tab-list/edit.mjs.map +2 -2
  332. package/build-module/tab-list/tab-movers.mjs +59 -0
  333. package/build-module/tab-list/tab-movers.mjs.map +7 -0
  334. package/build-module/tab-panel/block.json +1 -6
  335. package/build-module/tab-panel/edit.mjs +17 -25
  336. package/build-module/tab-panel/edit.mjs.map +2 -2
  337. package/build-module/tab-panels/block.json +0 -1
  338. package/build-module/table/edit.mjs +1 -1
  339. package/build-module/table/edit.mjs.map +2 -2
  340. package/build-module/tabs/block.json +0 -5
  341. package/build-module/tabs/edit.mjs +5 -45
  342. package/build-module/tabs/edit.mjs.map +2 -2
  343. package/build-module/tabs/use-tab-actions.mjs +23 -1
  344. package/build-module/tabs/use-tab-actions.mjs.map +2 -2
  345. package/build-module/tabs/use-tab-list-items-sync.mjs +19 -1
  346. package/build-module/tabs/use-tab-list-items-sync.mjs.map +2 -2
  347. package/build-module/term-name/block.json +1 -3
  348. package/build-module/term-name/deprecated.mjs +74 -0
  349. package/build-module/term-name/deprecated.mjs.map +7 -0
  350. package/build-module/term-name/edit.mjs +11 -28
  351. package/build-module/term-name/edit.mjs.map +2 -2
  352. package/build-module/term-name/index.mjs +3 -1
  353. package/build-module/term-name/index.mjs.map +2 -2
  354. package/build-module/utils/caption.mjs +2 -2
  355. package/build-module/utils/caption.mjs.map +2 -2
  356. package/build-module/utils/waveform-player.mjs +144 -23
  357. package/build-module/utils/waveform-player.mjs.map +2 -2
  358. package/build-module/utils/waveform-utils.mjs +310 -16
  359. package/build-module/utils/waveform-utils.mjs.map +2 -2
  360. package/build-module/verse/edit.mjs +3 -1
  361. package/build-module/verse/edit.mjs.map +2 -2
  362. package/build-module/video/edit.mjs +2 -11
  363. package/build-module/video/edit.mjs.map +2 -2
  364. package/build-module/video/tracks-editor.mjs +0 -1
  365. package/build-module/video/tracks-editor.mjs.map +2 -2
  366. package/build-style/cover/editor-rtl.css +3 -0
  367. package/build-style/cover/editor.css +3 -0
  368. package/build-style/editor-rtl.css +61 -59
  369. package/build-style/editor.css +61 -59
  370. package/build-style/icon/editor-rtl.css +80 -10
  371. package/build-style/icon/editor.css +80 -10
  372. package/build-style/image/editor-rtl.css +3 -32
  373. package/build-style/image/editor.css +3 -32
  374. package/build-style/more/editor-rtl.css +2 -2
  375. package/build-style/more/editor.css +2 -2
  376. package/build-style/navigation/editor-rtl.css +3 -4
  377. package/build-style/navigation/editor.css +3 -4
  378. package/build-style/navigation-link/editor-rtl.css +1 -1
  379. package/build-style/navigation-link/editor.css +1 -1
  380. package/build-style/nextpage/editor-rtl.css +2 -2
  381. package/build-style/nextpage/editor.css +2 -2
  382. package/build-style/playlist/editor-rtl.css +4 -3
  383. package/build-style/playlist/editor.css +4 -3
  384. package/build-style/playlist/style-rtl.css +81 -5
  385. package/build-style/playlist/style.css +81 -5
  386. package/build-style/playlist-track/style-rtl.css +10 -0
  387. package/build-style/playlist-track/style.css +10 -0
  388. package/build-style/pullquote/editor-rtl.css +4 -0
  389. package/build-style/pullquote/editor.css +4 -0
  390. package/build-style/style-rtl.css +91 -5
  391. package/build-style/style.css +91 -5
  392. package/build-style/tab-list/editor-rtl.css +101 -0
  393. package/build-style/tab-list/editor.css +101 -0
  394. package/build-style/video/editor-rtl.css +1 -1
  395. package/build-style/video/editor.css +1 -1
  396. package/build-types/table-of-contents/list.d.ts +1 -1
  397. package/build-types/table-of-contents/list.d.ts.map +1 -1
  398. package/package.json +47 -45
  399. package/src/accordion/README.md +1 -0
  400. package/src/accordion/block.json +1 -0
  401. package/src/accordion-panel/block.json +1 -0
  402. package/src/breadcrumbs/index.php +3 -1
  403. package/src/button/edit.js +21 -15
  404. package/src/button/index.php +1 -1
  405. package/src/code/edit.js +7 -2
  406. package/src/cover/README.md +60 -0
  407. package/src/cover/block.json +12 -0
  408. package/src/cover/edit/block-controls.js +26 -11
  409. package/src/cover/edit/embed-video-url-input.js +5 -4
  410. package/src/cover/edit/index.js +109 -46
  411. package/src/cover/editor.scss +6 -0
  412. package/src/cover/embed-video-utils.js +38 -13
  413. package/src/cover/index.php +9 -2
  414. package/src/details/transforms.js +2 -7
  415. package/src/editor.scss +1 -0
  416. package/src/embed/edit.js +3 -1
  417. package/src/embed/embed-placeholder.js +9 -8
  418. package/src/file/edit.js +8 -8
  419. package/src/file/transforms.js +28 -60
  420. package/src/form/index.php +6 -4
  421. package/src/gallery/README.md +1 -1
  422. package/src/gallery/block.json +4 -2
  423. package/src/gallery/dynamic-gallery.js +133 -74
  424. package/src/gallery/edit.js +3 -3
  425. package/src/gallery/gap-styles.js +79 -20
  426. package/src/gallery/index.php +103 -43
  427. package/src/gallery/use-dynamic-gallery.js +27 -12
  428. package/src/group/transforms.js +2 -5
  429. package/src/heading/edit.js +1 -1
  430. package/src/html/modal.js +13 -2
  431. package/src/icon/README.md +1 -3
  432. package/src/icon/block.json +5 -3
  433. package/src/icon/components/custom-inserter/icon-grid.js +40 -11
  434. package/src/icon/components/custom-inserter/index.js +98 -25
  435. package/src/icon/edit.js +11 -17
  436. package/src/icon/editor.scss +33 -11
  437. package/src/image/README.md +1 -1
  438. package/src/image/block.json +1 -1
  439. package/src/image/edit.js +1 -57
  440. package/src/image/editor.scss +6 -44
  441. package/src/image/image.js +56 -27
  442. package/src/image/test/use-open-image-media-editor-modal.js +37 -1
  443. package/src/image/transforms.js +128 -0
  444. package/src/image/use-open-image-media-editor-modal.js +8 -1
  445. package/src/index.js +19 -7
  446. package/src/latest-posts/edit.js +5 -8
  447. package/src/latest-posts/index.php +49 -18
  448. package/src/list-item/edit.js +1 -1
  449. package/src/list-item/hooks/use-enter.js +15 -22
  450. package/src/list-item/hooks/use-indent-list-item.js +10 -1
  451. package/src/list-item/hooks/use-space.js +4 -6
  452. package/src/math/edit.js +42 -59
  453. package/src/media-text/edit.js +1 -0
  454. package/src/media-text/editor.scss +1 -0
  455. package/src/media-text/index.php +11 -2
  456. package/src/more/edit.js +7 -4
  457. package/src/more/editor.scss +1 -1
  458. package/src/navigation/edit/index.js +52 -36
  459. package/src/navigation/edit/test/layout-custom-properties.js +138 -0
  460. package/src/navigation/edit/use-layout-custom-properties.js +84 -0
  461. package/src/navigation/editor.scss +1 -2
  462. package/src/navigation/index.php +123 -12
  463. package/src/navigation/test/view.js +51 -0
  464. package/src/navigation/view.js +15 -14
  465. package/src/navigation-link/edit.js +11 -7
  466. package/src/navigation-link/editor.scss +1 -1
  467. package/src/navigation-link/index.php +70 -3
  468. package/src/navigation-link/link-ui/index.js +2 -1
  469. package/src/navigation-link/test/__snapshots__/hooks.js.snap +1 -1
  470. package/src/navigation-submenu/index.php +6 -3
  471. package/src/nextpage/editor.scss +1 -1
  472. package/src/page-list/index.php +4 -3
  473. package/src/paragraph/edit.js +9 -2
  474. package/src/paragraph/index.js +4 -1
  475. package/src/paragraph/use-enter.js +4 -11
  476. package/src/pattern/index.php +5 -5
  477. package/src/playlist/README.md +17 -18
  478. package/src/playlist/block.json +29 -10
  479. package/src/playlist/context.js +1 -0
  480. package/src/playlist/edit.js +395 -59
  481. package/src/playlist/editor.scss +4 -5
  482. package/src/playlist/index.js +1 -1
  483. package/src/playlist/index.php +71 -22
  484. package/src/playlist/style.scss +54 -1
  485. package/src/playlist/test/edit-component.js +139 -0
  486. package/src/playlist/test/edit.js +43 -2
  487. package/src/playlist/utils.js +49 -10
  488. package/src/playlist/view.js +97 -16
  489. package/src/playlist-track/README.md +3 -3
  490. package/src/playlist-track/block.json +4 -2
  491. package/src/playlist-track/edit.js +116 -75
  492. package/src/playlist-track/index.php +26 -11
  493. package/src/playlist-track/style.scss +10 -0
  494. package/src/playlist-track/test/edit.js +253 -0
  495. package/src/post-content/README.md +1 -0
  496. package/src/post-content/block.json +1 -0
  497. package/src/post-content/edit.js +45 -16
  498. package/src/post-excerpt/index.php +4 -1
  499. package/src/post-featured-image/edit.js +3 -2
  500. package/src/post-featured-image/index.php +4 -1
  501. package/src/post-template/README.md +1 -0
  502. package/src/post-template/block.json +2 -1
  503. package/src/post-template/edit.js +9 -0
  504. package/src/post-terms/edit.js +7 -4
  505. package/src/post-title/edit.js +5 -3
  506. package/src/preformatted/edit.js +7 -2
  507. package/src/pullquote/README.md +1 -0
  508. package/src/pullquote/block.json +3 -1
  509. package/src/pullquote/edit.js +9 -4
  510. package/src/pullquote/editor.scss +6 -0
  511. package/src/query/README.md +2 -1
  512. package/src/query/block.json +3 -2
  513. package/src/query/edit/inspector-controls/index.js +47 -4
  514. package/src/query/edit/inspector-controls/offset-controls.js +2 -3
  515. package/src/query/edit/inspector-controls/pages-control.js +0 -1
  516. package/src/query/edit/query-content.js +19 -3
  517. package/src/query/index.js +1 -0
  518. package/src/quote/README.md +1 -0
  519. package/src/quote/block.json +3 -1
  520. package/src/quote/transforms.js +2 -4
  521. package/src/read-more/edit.js +7 -2
  522. package/src/rss/edit.js +0 -1
  523. package/src/rss/index.php +10 -4
  524. package/src/site-tagline/edit.js +7 -2
  525. package/src/site-title/edit.js +7 -2
  526. package/src/social-link/index.php +19 -9
  527. package/src/social-links/edit.js +21 -12
  528. package/src/tab-list/README.md +4 -5
  529. package/src/tab-list/block.json +4 -3
  530. package/src/tab-list/edit.js +92 -28
  531. package/src/tab-list/editor.scss +9 -0
  532. package/src/tab-list/index.php +9 -4
  533. package/src/tab-list/tab-movers.js +72 -0
  534. package/src/tab-panel/README.md +4 -6
  535. package/src/tab-panel/block.json +1 -6
  536. package/src/tab-panel/edit.js +20 -33
  537. package/src/tab-panels/README.md +5 -3
  538. package/src/tab-panels/block.json +0 -1
  539. package/src/table/edit.js +1 -1
  540. package/src/table-of-contents/index.php +386 -1
  541. package/src/tabs/README.md +18 -9
  542. package/src/tabs/block.json +0 -5
  543. package/src/tabs/edit.js +7 -64
  544. package/src/tabs/use-tab-actions.js +32 -3
  545. package/src/tabs/use-tab-list-items-sync.js +24 -4
  546. package/src/tag-cloud/index.php +3 -2
  547. package/src/template-part/index.php +3 -17
  548. package/src/term-name/README.md +1 -1
  549. package/src/term-name/block.json +1 -3
  550. package/src/term-name/deprecated.js +74 -0
  551. package/src/term-name/edit.js +2 -18
  552. package/src/term-name/index.js +2 -0
  553. package/src/utils/caption.js +7 -4
  554. package/src/utils/media-control.scss +1 -5
  555. package/src/utils/test/waveform-player.js +297 -34
  556. package/src/utils/test/waveform-utils.js +473 -5
  557. package/src/utils/waveform-player.js +189 -59
  558. package/src/utils/waveform-utils.js +443 -40
  559. package/src/verse/edit.js +7 -2
  560. package/src/video/edit.js +0 -8
  561. package/src/video/editor.scss +1 -1
  562. package/src/video/index.php +2 -2
  563. package/src/video/tracks-editor.js +0 -1
  564. package/build/image/animated-gif-convert-control.cjs +0 -105
  565. package/build/image/animated-gif-convert-control.cjs.map +0 -7
  566. package/build/utils/gif-conversion-attributes.cjs +0 -40
  567. package/build/utils/gif-conversion-attributes.cjs.map +0 -7
  568. package/build/video/gif-restore-control.cjs +0 -73
  569. package/build/video/gif-restore-control.cjs.map +0 -7
  570. package/build-module/image/animated-gif-convert-control.mjs +0 -87
  571. package/build-module/image/animated-gif-convert-control.mjs.map +0 -7
  572. package/build-module/utils/gif-conversion-attributes.mjs +0 -15
  573. package/build-module/utils/gif-conversion-attributes.mjs.map +0 -7
  574. package/build-module/video/gif-restore-control.mjs +0 -55
  575. package/build-module/video/gif-restore-control.mjs.map +0 -7
  576. package/src/image/animated-gif-convert-control.js +0 -135
  577. package/src/image/test/animated-gif-convert-control.js +0 -276
  578. package/src/utils/gif-conversion-attributes.js +0 -30
  579. package/src/utils/test/gif-conversion-attributes.js +0 -60
  580. package/src/video/gif-restore-control.js +0 -92
@@ -74,14 +74,44 @@ function OrderControl( { orderby, order, onChange } ) {
74
74
  );
75
75
  }
76
76
 
77
+ /**
78
+ * Confirmation for leaving dynamic mode, shown from both the block toolbar and
79
+ * the Source panel so the two entry points explain the change identically.
80
+ *
81
+ * Detaching keeps the images the gallery currently shows but breaks the link to
82
+ * its source, so it's worth confirming — mirroring the dialog `GallerySourcePanel`
83
+ * shows for the opposite direction.
84
+ *
85
+ * @param {Object} props
86
+ * @param {Function} props.onConfirm Called when the user confirms detaching.
87
+ * @param {Function} props.onCancel Called when the user dismisses the dialog.
88
+ */
89
+ function DetachGalleryDialog( { onConfirm, onCancel } ) {
90
+ return (
91
+ <ConfirmDialog
92
+ isOpen
93
+ title={ __( 'Detach Gallery' ) }
94
+ __experimentalHideHeader={ false }
95
+ confirmButtonText={ __( 'Detach' ) }
96
+ onConfirm={ onConfirm }
97
+ onCancel={ onCancel }
98
+ size="medium"
99
+ >
100
+ { __(
101
+ 'The gallery displays the images attached to the post. Detaching will enable you to add, delete, or reorder images. However, new attachments will no longer be added automatically.'
102
+ ) }
103
+ </ConfirmDialog>
104
+ );
105
+ }
106
+
77
107
  /**
78
108
  * The Gallery block's "Source" inspector panel.
79
109
  *
80
- * In dynamic mode it shows the resolved source, a control to convert back to
81
- * individual images, and the source ordering. In static mode it offers the
82
- * entry point into dynamic mode and, since switching discards any hand-added
83
- * images, owns the confirmation dialog for that one-way change. Rendered inside
84
- * the block's `InspectorControls`, alongside the Settings panel.
110
+ * In dynamic mode it shows the resolved source, a control to detach the gallery
111
+ * from it, and the source ordering. In static mode it offers the entry point
112
+ * into dynamic mode. Either direction is a one-way change, so both are behind a
113
+ * confirmation dialog this panel owns. Rendered inside the block's
114
+ * `InspectorControls`, alongside the Settings panel.
85
115
  *
86
116
  * @param {Object} props
87
117
  * @param {Object} props.dynamic The `useDynamicGallery` result.
@@ -110,6 +140,7 @@ export function GallerySourcePanel( {
110
140
  const isDynamic = !! dynamicContent;
111
141
 
112
142
  const [ isConfirming, setIsConfirming ] = useState( false );
143
+ const [ isConfirmingDetach, setIsConfirmingDetach ] = useState( false );
113
144
 
114
145
  // Entering dynamic mode discards any hand-added images, so confirm first
115
146
  // when there are images to lose; otherwise switch straight away.
@@ -123,63 +154,76 @@ export function GallerySourcePanel( {
123
154
 
124
155
  if ( isDynamic ) {
125
156
  return (
126
- <ToolsPanel
127
- label={ __( 'Source' ) }
128
- resetAll={ resetSource }
129
- dropdownMenuProps={ dropdownMenuProps }
130
- >
131
- <div className="wp-block-gallery__source-settings">
132
- <p className="wp-block-gallery__source-description">
133
- { sourceDescriptor?.description ??
134
- __( 'Dynamic images.' ) }
135
- </p>
136
- <Button
137
- __next40pxDefaultSize
138
- variant="secondary"
139
- onClick={ convertToStatic }
140
- // Guard the race where the media is still resolving:
141
- // converting now would map over an incomplete (or empty)
142
- // list and produce a gallery missing images.
143
- disabled={ isResolvingDynamic }
144
- accessibleWhenDisabled
145
- >
146
- { __( 'Convert to individual images' ) }
147
- </Button>
148
- </div>
149
- { hasMoreImagesThanCap && (
150
- <Notice
151
- className="wp-block-gallery__source-notice"
152
- status="warning"
153
- isDismissible={ false }
154
- >
155
- { sprintf(
156
- /* translators: 1: number of images shown. 2: total number of matching images. */
157
- __(
158
- 'Only the first %1$d of %2$d images will be displayed.'
159
- ),
160
- MAX_IMAGES,
161
- dynamicMediaTotal
162
- ) }
163
- </Notice>
164
- ) }
165
- <ToolsPanelItem
166
- isShownByDefault
167
- label={ __( 'Order by' ) }
168
- hasValue={ () =>
169
- sourceOrderby !== DEFAULT_ORDERBY ||
170
- sourceOrder !== DEFAULT_ORDER
171
- }
172
- onDeselect={ () => setSourceOrder( undefined, undefined ) }
157
+ <>
158
+ <ToolsPanel
159
+ label={ __( 'Source' ) }
160
+ resetAll={ resetSource }
161
+ dropdownMenuProps={ dropdownMenuProps }
173
162
  >
174
- <OrderControl
175
- orderby={ sourceOrderby }
176
- order={ sourceOrder }
177
- onChange={ ( { orderby, order } ) =>
178
- setSourceOrder( orderby, order )
163
+ <div className="wp-block-gallery__source-settings">
164
+ <p className="wp-block-gallery__source-description">
165
+ { sourceDescriptor?.description ??
166
+ __( 'Dynamic images.' ) }
167
+ </p>
168
+ <Button
169
+ __next40pxDefaultSize
170
+ variant="secondary"
171
+ onClick={ () => setIsConfirmingDetach( true ) }
172
+ // Guard the race where the media is still resolving:
173
+ // detaching now would map over an incomplete (or
174
+ // empty) list and produce a gallery missing images.
175
+ disabled={ isResolvingDynamic }
176
+ accessibleWhenDisabled
177
+ >
178
+ { __( 'Detach Gallery' ) }
179
+ </Button>
180
+ </div>
181
+ { hasMoreImagesThanCap && (
182
+ <Notice
183
+ className="wp-block-gallery__source-notice"
184
+ status="warning"
185
+ isDismissible={ false }
186
+ >
187
+ { sprintf(
188
+ /* translators: 1: number of images shown. 2: total number of matching images. */
189
+ __(
190
+ 'Only the first %1$d of %2$d images will be displayed.'
191
+ ),
192
+ MAX_IMAGES,
193
+ dynamicMediaTotal
194
+ ) }
195
+ </Notice>
196
+ ) }
197
+ <ToolsPanelItem
198
+ isShownByDefault
199
+ label={ __( 'Order by' ) }
200
+ hasValue={ () =>
201
+ sourceOrderby !== DEFAULT_ORDERBY ||
202
+ sourceOrder !== DEFAULT_ORDER
203
+ }
204
+ onDeselect={ () =>
205
+ setSourceOrder( undefined, undefined )
179
206
  }
207
+ >
208
+ <OrderControl
209
+ orderby={ sourceOrderby }
210
+ order={ sourceOrder }
211
+ onChange={ ( { orderby, order } ) =>
212
+ setSourceOrder( orderby, order )
213
+ }
214
+ />
215
+ </ToolsPanelItem>
216
+ </ToolsPanel>
217
+ { isConfirmingDetach && (
218
+ <DetachGalleryDialog
219
+ onConfirm={ () => {
220
+ convertToStatic();
221
+ setIsConfirmingDetach( false );
222
+ } }
223
+ onCancel={ () => setIsConfirmingDetach( false ) }
180
224
  />
181
- </ToolsPanelItem>
182
- </ToolsPanel>
225
+ ) }
226
+ </>
183
227
  );
184
228
  }
185
229
 
@@ -266,7 +310,8 @@ function GalleryImagesPreview( { imageBlocks } ) {
266
310
  /**
267
311
  * Renders a dynamic-mode gallery on the canvas:
268
312
  *
269
- * - a block-toolbar control to convert back to individual images;
313
+ * - a block-toolbar control to detach the gallery from its source, confirmed in
314
+ * a dialog;
270
315
  * - the gallery `<figure>` wrapper holding a non-editable preview of the
271
316
  * resolved media (or a placeholder while resolving / when nothing is found),
272
317
  * with the gallery's provided context so the previewed images inherit
@@ -306,13 +351,15 @@ export function GalleryDynamicView( {
306
351
  convertToStatic,
307
352
  } = dynamic;
308
353
 
309
- // Converting to a static gallery materializes editable inner blocks, which
310
- // is a structural change. Only offer it when the block is fully editable:
354
+ // Detaching the gallery materializes editable inner blocks, which is a
355
+ // structural change. Only offer it when the block is fully editable:
311
356
  // under a content lock (e.g. inside a `contentOnly` group) the editing mode
312
357
  // is `'contentOnly'`/`'disabled'`, where structural toolbar controls are
313
358
  // hidden and the conversion shouldn't be possible.
314
359
  const blockEditingMode = useBlockEditingMode();
315
360
 
361
+ const [ isConfirmingDetach, setIsConfirmingDetach ] = useState( false );
362
+
316
363
  // Empty-state copy for the preview. Framed as forward-looking ("… will appear
317
364
  // here") rather than as an error, since the same empty result covers both a
318
365
  // post with no matching images and a template with no post in context yet —
@@ -326,18 +373,30 @@ export function GalleryDynamicView( {
326
373
  return (
327
374
  <>
328
375
  { blockEditingMode === 'default' && (
329
- <BlockControls group="other">
330
- <ToolbarButton
331
- onClick={ convertToStatic }
332
- // Same guard as the inspector's "Convert to individual
333
- // images": both call `convertToStatic`, which would map over
334
- // a still-resolving (or empty) media list. (`ToolbarButton`
335
- // stays focusable when disabled by default.)
336
- disabled={ isResolvingDynamic }
337
- >
338
- { __( 'Convert to images' ) }
339
- </ToolbarButton>
340
- </BlockControls>
376
+ <>
377
+ <BlockControls group="other">
378
+ <ToolbarButton
379
+ onClick={ () => setIsConfirmingDetach( true ) }
380
+ // Same guard as the inspector's "Detach Gallery": both end in
381
+ // `convertToStatic`, which would map over a
382
+ // still-resolving (or empty) media list.
383
+ // (`ToolbarButton` stays focusable when disabled by
384
+ // default.)
385
+ disabled={ isResolvingDynamic }
386
+ >
387
+ { __( 'Detach' ) }
388
+ </ToolbarButton>
389
+ </BlockControls>
390
+ { isConfirmingDetach && (
391
+ <DetachGalleryDialog
392
+ onConfirm={ () => {
393
+ convertToStatic();
394
+ setIsConfirmingDetach( false );
395
+ } }
396
+ onCancel={ () => setIsConfirmingDetach( false ) }
397
+ />
398
+ ) }
399
+ </>
341
400
  ) }
342
401
  <figure { ...blockProps }>
343
402
  { dynamicImageBlocks.length ? (
@@ -66,7 +66,7 @@ import {
66
66
  import useImageSizes from './use-image-sizes';
67
67
  import useGetNewImages from './use-get-new-images';
68
68
  import useGetMedia from './use-get-media';
69
- import GapStyles from './gap-styles';
69
+ import GalleryGapCustomProperties from './gap-styles';
70
70
  import useDynamicGallery from './use-dynamic-gallery';
71
71
  import { GallerySourcePanel, GalleryDynamicView } from './dynamic-gallery';
72
72
  import { getDynamicSource, ATTACHED_MEDIA } from './dynamic-source';
@@ -941,8 +941,8 @@ export default function GalleryEdit( props ) {
941
941
  />
942
942
  </BlockControls>
943
943
  ) }
944
- <GapStyles
945
- blockGap={ attributes.style?.spacing?.blockGap }
944
+ <GalleryGapCustomProperties
945
+ style={ attributes.style }
946
946
  clientId={ clientId }
947
947
  />
948
948
  </>
@@ -3,35 +3,94 @@
3
3
  */
4
4
  import {
5
5
  __experimentalGetGapCSSValue as getGapCSSValue,
6
+ privateApis as blockEditorPrivateApis,
7
+ store as blockEditorStore,
6
8
  useStyleOverride,
9
+ useSettings,
7
10
  } from '@wordpress/block-editor';
11
+ import { useSelect } from '@wordpress/data';
12
+ import { privateApis as globalStylesEnginePrivateApis } from '@wordpress/global-styles-engine';
8
13
 
9
- export default function GapStyles( { blockGap, clientId } ) {
10
- // --gallery-block--gutter-size is deprecated. --wp--style--gallery-gap-default should be used by themes that want to set a default
11
- // gap on the gallery.
12
- const fallbackValue = `var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )`;
13
- let gapValue = fallbackValue;
14
- let column = fallbackValue;
15
- let row;
16
-
17
- // Check for the possibility of split block gap values. See: https://github.com/WordPress/gutenberg/pull/37736
18
- if ( !! blockGap ) {
19
- row =
20
- typeof blockGap === 'string'
21
- ? getGapCSSValue( blockGap )
22
- : getGapCSSValue( blockGap?.top ) || fallbackValue;
14
+ /**
15
+ * Internal dependencies
16
+ */
17
+ import { unlock } from '../lock-unlock';
18
+
19
+ const { getResponsiveMediaQueries } = unlock( globalStylesEnginePrivateApis );
20
+ const { globalStylesDataKey } = unlock( blockEditorPrivateApis );
21
+ const GALLERY_BLOCK_NAME = 'core/gallery';
22
+
23
+ // --gallery-block--gutter-size is deprecated. --wp--style--gallery-gap-default should be used by themes that want to set a default
24
+ // gap on the gallery.
25
+ const FALLBACK_VALUE = `var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )`;
26
+
27
+ function getGalleryGapCustomPropertyStyle( selector, blockGap ) {
28
+ let column = FALLBACK_VALUE;
29
+ if ( blockGap ) {
23
30
  column =
24
31
  typeof blockGap === 'string'
25
- ? getGapCSSValue( blockGap )
26
- : getGapCSSValue( blockGap?.left ) || fallbackValue;
27
- gapValue = row === column ? row : `${ row } ${ column }`;
32
+ ? getGapCSSValue( blockGap ) || FALLBACK_VALUE
33
+ : getGapCSSValue( blockGap?.left ) || FALLBACK_VALUE;
28
34
  }
29
35
 
30
36
  // The unstable gallery gap calculation requires a real value (such as `0px`) and not `0`.
31
- const gap = `#block-${ clientId } {
32
- --wp--style--unstable-gallery-gap: ${ column === '0' ? '0px' : column };
33
- gap: ${ gapValue }
37
+ return `${ selector } {
38
+ --wp--style--unstable-gallery-gap: ${ column === '0' ? '0px' : column }
34
39
  }`;
40
+ }
41
+
42
+ function getBlockGapValue( style ) {
43
+ if ( ! Object.hasOwn( style?.spacing || {}, 'blockGap' ) ) {
44
+ return undefined;
45
+ }
46
+
47
+ return style.spacing.blockGap;
48
+ }
49
+
50
+ export default function GalleryGapCustomProperties( { style, clientId } ) {
51
+ const selector = `#block-${ clientId }`;
52
+ const [ viewportSettings ] = useSettings( 'viewport' );
53
+ const globalStyles = useSelect(
54
+ ( select ) =>
55
+ select( blockEditorStore ).getSettings()?.[ globalStylesDataKey ],
56
+ []
57
+ );
58
+ const globalGalleryStyles =
59
+ globalStyles?.blocks?.[ GALLERY_BLOCK_NAME ] || {};
60
+ const styleBlockGap = getBlockGapValue( style );
61
+ const globalGalleryBlockGap =
62
+ globalGalleryStyles?.spacing?.blockGap ?? FALLBACK_VALUE;
63
+ // Prefer the block's own gap value, then Gallery global styles. Missing
64
+ // values fall back to the Gallery blockGap default.
65
+ const blockGap =
66
+ styleBlockGap === undefined ? globalGalleryBlockGap : styleBlockGap;
67
+ let gap = getGalleryGapCustomPropertyStyle( selector, blockGap );
68
+
69
+ Object.entries( getResponsiveMediaQueries( viewportSettings ) ).forEach(
70
+ ( [ viewport, mediaQuery ] ) => {
71
+ const styleViewportBlockGap = getBlockGapValue(
72
+ style?.[ viewport ]
73
+ );
74
+ // Viewport-specific block values win. Gallery global viewport values
75
+ // only apply when the block has no base gap, so they do not override an instance value.
76
+ const globalViewportBlockGap =
77
+ styleBlockGap === undefined
78
+ ? globalGalleryStyles?.[ viewport ]?.spacing?.blockGap
79
+ : undefined;
80
+ const viewportBlockGap =
81
+ styleViewportBlockGap === undefined
82
+ ? globalViewportBlockGap
83
+ : styleViewportBlockGap;
84
+ if ( viewportBlockGap === undefined || viewportBlockGap === null ) {
85
+ return;
86
+ }
87
+
88
+ gap += `${ mediaQuery }{${ getGalleryGapCustomPropertyStyle(
89
+ selector,
90
+ viewportBlockGap
91
+ ) }}`;
92
+ }
93
+ );
35
94
 
36
95
  useStyleOverride( { css: gap } );
37
96
 
@@ -52,6 +52,41 @@ function block_core_gallery_render_context( $context, $parsed_block ) {
52
52
 
53
53
  add_filter( 'render_block_context', 'block_core_gallery_render_context', 10, 2 );
54
54
 
55
+ /**
56
+ * Returns the column gap value used for Gallery image width calculations.
57
+ *
58
+ * @since 7.1.0
59
+ *
60
+ * @param string|array|null $gap Gallery block gap value.
61
+ * @param string $fallback_gap Fallback gap value.
62
+ * @return string Gallery column gap value.
63
+ */
64
+ function block_core_gallery_get_column_gap_value( $gap, $fallback_gap ) {
65
+ if ( is_array( $gap ) ) {
66
+ $gap = $gap['left'] ?? $fallback_gap;
67
+ }
68
+
69
+ // Make sure $gap is a string to avoid PHP 8.1 deprecation error in preg_match() when the value is null.
70
+ $gap = is_string( $gap ) ? $gap : '';
71
+
72
+ // Skip if gap value contains unsupported characters.
73
+ // Regex for CSS value borrowed from `safecss_filter_attr`, and used here
74
+ // because we only want to match against the value, not the CSS attribute.
75
+ $gap = $gap && preg_match( '%[\\\(&=}]|/\*%', $gap ) ? null : $gap;
76
+
77
+ // Get spacing CSS variable from preset value if provided.
78
+ if ( is_string( $gap ) && str_contains( $gap, 'var:preset|spacing|' ) ) {
79
+ $index_to_splice = strrpos( $gap, '|' ) + 1;
80
+ $slug = _wp_to_kebab_case( substr( $gap, $index_to_splice ) );
81
+ $gap = "var(--wp--preset--spacing--$slug)";
82
+ }
83
+
84
+ $gap_column = ( null !== $gap && '' !== $gap ) ? $gap : $fallback_gap;
85
+
86
+ // The unstable gallery gap calculation requires a real value (such as `0px`) and not `0`.
87
+ return '0' === $gap_column ? '0px' : $gap_column;
88
+ }
89
+
55
90
  /**
56
91
  * Resolves a Gallery block's `dynamicContent` to an ordered list of image
57
92
  * attachment IDs.
@@ -272,6 +307,8 @@ function block_core_gallery_render_dynamic_image( $attachment_id, $attributes, $
272
307
  * @return string The content of the block being rendered.
273
308
  */
274
309
  function block_core_gallery_render( $attributes, $content, $block ) {
310
+ static $global_styles = null;
311
+
275
312
  // In dynamic mode the gallery's images are resolved at render time instead of
276
313
  // being authored as inner blocks, so `save.js` persists at most the
277
314
  // gallery-level caption — a bare `<figcaption>`, or nothing when there is no
@@ -345,36 +382,15 @@ function block_core_gallery_render( $attributes, $content, $block ) {
345
382
  // the current gap setting in order to maintain the number of flex columns
346
383
  // so a css var is added to allow this.
347
384
 
348
- $gap = $attributes['style']['spacing']['blockGap'] ?? null;
349
- // Skip if gap value contains unsupported characters.
350
- // Regex for CSS value borrowed from `safecss_filter_attr`, and used here
351
- // because we only want to match against the value, not the CSS attribute.
352
- if ( is_array( $gap ) ) {
353
- foreach ( $gap as $key => $value ) {
354
- // Make sure $value is a string to avoid PHP 8.1 deprecation error in preg_match() when the value is null.
355
- $value = is_string( $value ) ? $value : '';
356
- $value = $value && preg_match( '%[\\\(&=}]|/\*%', $value ) ? null : $value;
357
-
358
- // Get spacing CSS variable from preset value if provided.
359
- if ( is_string( $value ) && str_contains( $value, 'var:preset|spacing|' ) ) {
360
- $index_to_splice = strrpos( $value, '|' ) + 1;
361
- $slug = _wp_to_kebab_case( substr( $value, $index_to_splice ) );
362
- $value = "var(--wp--preset--spacing--$slug)";
363
- }
364
-
365
- $gap[ $key ] = $value;
366
- }
367
- } else {
368
- // Make sure $gap is a string to avoid PHP 8.1 deprecation error in preg_match() when the value is null.
369
- $gap = is_string( $gap ) ? $gap : '';
370
- $gap = $gap && preg_match( '%[\\\(&=}]|/\*%', $gap ) ? null : $gap;
371
-
372
- // Get spacing CSS variable from preset value if provided.
373
- if ( is_string( $gap ) && str_contains( $gap, 'var:preset|spacing|' ) ) {
374
- $index_to_splice = strrpos( $gap, '|' ) + 1;
375
- $slug = _wp_to_kebab_case( substr( $gap, $index_to_splice ) );
376
- $gap = "var(--wp--preset--spacing--$slug)";
377
- }
385
+ $style_attr = is_array( $attributes['style'] ?? null )
386
+ ? $attributes['style']
387
+ : array();
388
+ if (
389
+ defined( 'IS_GUTENBERG_PLUGIN' ) &&
390
+ IS_GUTENBERG_PLUGIN &&
391
+ function_exists( 'gutenberg_resolve_style_state_aliases' )
392
+ ) {
393
+ $style_attr = gutenberg_resolve_style_state_aliases( $style_attr, 'core/gallery' );
378
394
  }
379
395
 
380
396
  $unique_gallery_classname = wp_unique_id( 'wp-block-gallery-' );
@@ -385,31 +401,75 @@ function block_core_gallery_render( $attributes, $content, $block ) {
385
401
  // --gallery-block--gutter-size is deprecated. --wp--style--gallery-gap-default should be used by themes that want to set a default
386
402
  // gap on the gallery.
387
403
  $fallback_gap = 'var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )';
388
- $gap_value = $gap ? $gap : $fallback_gap;
389
- $gap_column = $gap_value;
390
404
 
391
- if ( is_array( $gap_value ) ) {
392
- $gap_row = $gap_value['top'] ?? $fallback_gap;
393
- $gap_column = $gap_value['left'] ?? $fallback_gap;
394
- $gap_value = $gap_row === $gap_column ? $gap_row : $gap_row . ' ' . $gap_column;
405
+ if ( null === $global_styles ) {
406
+ $global_styles = function_exists( 'wp_get_global_styles' ) ? wp_get_global_styles() : array();
395
407
  }
396
408
 
397
- // The unstable gallery gap calculation requires a real value (such as `0px`) and not `0`.
398
- if ( '0' === $gap_column ) {
399
- $gap_column = '0px';
400
- }
401
-
402
- // Set the CSS variable to the column value, and the `gap` property to the combined gap value.
409
+ $global_gallery_styles = $global_styles['blocks']['core/gallery'] ?? array();
410
+ $global_gallery_gap = $global_gallery_styles['spacing']['blockGap'] ?? $fallback_gap;
411
+ $has_block_gap = is_array( $style_attr['spacing'] ?? null ) && array_key_exists( 'blockGap', $style_attr['spacing'] );
412
+ // Prefer the block's own gap value, then Gallery global styles. Missing
413
+ // values fall back to the Gallery blockGap default.
414
+ $block_gap = $has_block_gap
415
+ ? $style_attr['spacing']['blockGap']
416
+ : $global_gallery_gap;
417
+ $gap_column = block_core_gallery_get_column_gap_value( $block_gap, $fallback_gap );
418
+
419
+ // Set the CSS variable to the column value for Gallery's flex width calculations.
403
420
  $gallery_styles = array(
404
421
  array(
405
422
  'selector' => ".wp-block-gallery.{$unique_gallery_classname}",
406
423
  'declarations' => array(
407
424
  '--wp--style--unstable-gallery-gap' => $gap_column,
408
- 'gap' => $gap_value,
409
425
  ),
410
426
  ),
411
427
  );
412
428
 
429
+ $global_settings = wp_get_global_settings();
430
+ $viewport_settings = $global_settings['viewport'] ?? null;
431
+ $responsive_media_queries = array();
432
+ foreach ( array( 'WP_Theme_JSON_Gutenberg', 'WP_Theme_JSON' ) as $theme_json_class_name ) {
433
+ if ( method_exists( $theme_json_class_name, 'get_viewport_media_queries' ) ) {
434
+ $responsive_media_queries = $theme_json_class_name::get_viewport_media_queries( $viewport_settings );
435
+ break;
436
+ }
437
+ }
438
+
439
+ foreach ( $responsive_media_queries as $breakpoint => $media_query ) {
440
+ $viewport_style = $style_attr[ $breakpoint ] ?? null;
441
+ $has_viewport_block_gap = is_array( $viewport_style ) &&
442
+ is_array( $viewport_style['spacing'] ?? null ) &&
443
+ array_key_exists( 'blockGap', $viewport_style['spacing'] );
444
+ $has_global_viewport_block_gap = is_array( $global_gallery_styles[ $breakpoint ]['spacing'] ?? null ) &&
445
+ array_key_exists( 'blockGap', $global_gallery_styles[ $breakpoint ]['spacing'] );
446
+
447
+ // Viewport-specific block values win. Gallery global viewport values
448
+ // only apply when the block has no base gap, so they do not override an instance value.
449
+ if ( $has_viewport_block_gap ) {
450
+ $viewport_gap = $viewport_style['spacing']['blockGap'];
451
+ } elseif ( ! $has_block_gap && $has_global_viewport_block_gap ) {
452
+ $viewport_gap = $global_gallery_styles[ $breakpoint ]['spacing']['blockGap'];
453
+ } else {
454
+ continue;
455
+ }
456
+
457
+ if ( null === $viewport_gap ) {
458
+ continue;
459
+ }
460
+
461
+ $gallery_styles[] = array(
462
+ 'selector' => ".wp-block-gallery.{$unique_gallery_classname}",
463
+ 'declarations' => array(
464
+ '--wp--style--unstable-gallery-gap' => block_core_gallery_get_column_gap_value(
465
+ $viewport_gap,
466
+ $fallback_gap
467
+ ),
468
+ ),
469
+ 'rules_group' => $media_query,
470
+ );
471
+ }
472
+
413
473
  wp_style_engine_get_stylesheet_from_css_rules(
414
474
  $gallery_styles,
415
475
  array( 'context' => 'block-supports' )
@@ -2,7 +2,7 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { useMemo } from '@wordpress/element';
5
- import { useDispatch, useSelect } from '@wordpress/data';
5
+ import { useDispatch, useSelect, useRegistry } from '@wordpress/data';
6
6
  import { store as blockEditorStore } from '@wordpress/block-editor';
7
7
  import { store as coreStore } from '@wordpress/core-data';
8
8
  import { createBlock } from '@wordpress/blocks';
@@ -122,7 +122,9 @@ export default function useDynamicGallery( {
122
122
  const sourceOrderby = dynamicContent?.args?.orderBy ?? DEFAULT_ORDERBY;
123
123
  const sourceOrder = dynamicContent?.args?.order ?? DEFAULT_ORDER;
124
124
 
125
- const { replaceInnerBlocks } = useDispatch( blockEditorStore );
125
+ const registry = useRegistry();
126
+ const { replaceInnerBlocks, __unstableMarkNextChangeAsNotPersistent } =
127
+ useDispatch( blockEditorStore );
126
128
 
127
129
  // Resolve the configured source to a media query. `null` (static mode, or an
128
130
  // unresolvable source) short-circuits the select below so no request fires.
@@ -208,21 +210,34 @@ export default function useDynamicGallery( {
208
210
  // for the pre-innerBlocks format (see `deprecated.js`/`transforms.js`), empty
209
211
  // on any gallery reachable here.
210
212
  function enableDynamicMode() {
211
- setAttributes( { dynamicContent: { source: ATTACHED_MEDIA } } );
212
- replaceInnerBlocks( clientId, [] );
213
+ // Batch the attribute change and the inner-block reset into a single
214
+ // undo level: they're two halves of one mode switch, so one undo should
215
+ // revert both. Marking the second dispatch non-persistent stops it from
216
+ // opening a second undo level, which would otherwise leave the gallery
217
+ // in a half-switched state (dynamic source set, images still present).
218
+ registry.batch( () => {
219
+ setAttributes( { dynamicContent: { source: ATTACHED_MEDIA } } );
220
+ __unstableMarkNextChangeAsNotPersistent();
221
+ replaceInnerBlocks( clientId, [] );
222
+ } );
213
223
  }
214
224
 
215
225
  // "Pins" a dynamic gallery: materializes the currently-resolved media as
216
226
  // real, editable image blocks and leaves dynamic mode.
217
227
  function convertToStatic() {
218
- // Build fresh blocks rather than reusing the preview's `dynamicImageBlocks`
219
- // so the materialized inner blocks get their own client IDs, distinct from
220
- // the (disabled) preview instances.
221
- replaceInnerBlocks(
222
- clientId,
223
- buildImageBlocks( dynamicMedia, imageAttributes )
224
- );
225
- setAttributes( { dynamicContent: undefined } );
228
+ // Batch the inner-block materialization and the attribute change into a
229
+ // single undo level so one undo reverts the whole conversion (see
230
+ // `enableDynamicMode`). Build fresh blocks rather than reusing the
231
+ // preview's `dynamicImageBlocks` so the materialized inner blocks get
232
+ // their own client IDs, distinct from the (disabled) preview instances.
233
+ registry.batch( () => {
234
+ replaceInnerBlocks(
235
+ clientId,
236
+ buildImageBlocks( dynamicMedia, imageAttributes )
237
+ );
238
+ __unstableMarkNextChangeAsNotPersistent();
239
+ setAttributes( { dynamicContent: undefined } );
240
+ } );
226
241
  }
227
242
 
228
243
  // Updates the source ordering within `dynamicContent.args`. Passing
@@ -1,10 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import {
5
- createBlock,
6
- __experimentalCloneSanitizedBlock,
7
- } from '@wordpress/blocks';
4
+ import { createBlock, cloneSanitizedBlock } from '@wordpress/blocks';
8
5
 
9
6
  const transforms = {
10
7
  from: [
@@ -33,7 +30,7 @@ const transforms = {
33
30
  // are removed both from their original location and within the
34
31
  // new group block.
35
32
  const groupInnerBlocks = blocks.map( ( block ) =>
36
- __experimentalCloneSanitizedBlock( block )
33
+ cloneSanitizedBlock( block )
37
34
  );
38
35
 
39
36
  return createBlock(