@wordpress/block-editor 15.19.1-next.v.202605131032.0 → 15.21.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 (342) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/build/components/block-card/index.cjs +51 -41
  3. package/build/components/block-card/index.cjs.map +3 -3
  4. package/build/components/block-heading-level-dropdown/heading-level-icon.cjs.map +3 -3
  5. package/build/components/block-icon/index.cjs +7 -1
  6. package/build/components/block-icon/index.cjs.map +3 -3
  7. package/build/components/block-inspector/index.cjs +156 -11
  8. package/build/components/block-inspector/index.cjs.map +3 -3
  9. package/build/components/block-inspector/inspector-pre-tabs-slot-fill.cjs +38 -0
  10. package/build/components/block-inspector/inspector-pre-tabs-slot-fill.cjs.map +7 -0
  11. package/build/components/block-list/use-block-props/use-focus-handler.cjs +3 -4
  12. package/build/components/block-list/use-block-props/use-focus-handler.cjs.map +3 -3
  13. package/build/components/block-list/use-block-props/use-is-hovered.cjs +24 -14
  14. package/build/components/block-list/use-block-props/use-is-hovered.cjs.map +3 -3
  15. package/build/components/block-lock/modal.cjs.map +3 -3
  16. package/build/components/block-patterns-list/index.cjs +13 -2
  17. package/build/components/block-patterns-list/index.cjs.map +2 -2
  18. package/build/components/block-popover/index.cjs +13 -3
  19. package/build/components/block-popover/index.cjs.map +2 -2
  20. package/build/components/block-toolbar/switch-section-style.cjs.map +3 -3
  21. package/build/components/block-visibility/modal.cjs.map +3 -3
  22. package/build/components/block-visibility/viewport-visibility-info.cjs.map +3 -3
  23. package/build/components/child-layout-control/index.cjs +10 -5
  24. package/build/components/child-layout-control/index.cjs.map +2 -2
  25. package/build/components/colors-gradients/control.cjs +7 -4
  26. package/build/components/colors-gradients/control.cjs.map +2 -2
  27. package/build/components/global-styles/advanced-panel.cjs +24 -22
  28. package/build/components/global-styles/advanced-panel.cjs.map +3 -3
  29. package/build/components/global-styles/color-panel.cjs +95 -58
  30. package/build/components/global-styles/color-panel.cjs.map +2 -2
  31. package/build/components/global-styles/dimensions-panel.cjs +15 -8
  32. package/build/components/global-styles/dimensions-panel.cjs.map +2 -2
  33. package/build/components/global-styles/index.cjs +3 -0
  34. package/build/components/global-styles/index.cjs.map +2 -2
  35. package/build/components/global-styles/shadow-panel-components.cjs +38 -26
  36. package/build/components/global-styles/shadow-panel-components.cjs.map +2 -2
  37. package/build/components/global-styles/state-control-badges.cjs +69 -0
  38. package/build/components/global-styles/state-control-badges.cjs.map +7 -0
  39. package/build/components/global-styles/state-control.cjs +54 -63
  40. package/build/components/global-styles/state-control.cjs.map +3 -3
  41. package/build/components/iframe/use-scale-canvas.cjs +4 -1
  42. package/build/components/iframe/use-scale-canvas.cjs.map +2 -2
  43. package/build/components/inserter/hooks/use-patterns-state.cjs +4 -6
  44. package/build/components/inserter/hooks/use-patterns-state.cjs.map +2 -2
  45. package/build/components/inserter/index.cjs +1 -0
  46. package/build/components/inserter/index.cjs.map +2 -2
  47. package/build/components/inserter/media-tab/media-preview.cjs +27 -18
  48. package/build/components/inserter/media-tab/media-preview.cjs.map +2 -2
  49. package/build/components/inserter/panel.cjs.map +3 -3
  50. package/build/components/inspector-controls/block-support-tools-panel.cjs +10 -2
  51. package/build/components/inspector-controls/block-support-tools-panel.cjs.map +2 -2
  52. package/build/components/inspector-controls/fill.cjs +14 -4
  53. package/build/components/inspector-controls/fill.cjs.map +2 -2
  54. package/build/components/inspector-controls/groups.cjs +2 -0
  55. package/build/components/inspector-controls/groups.cjs.map +2 -2
  56. package/build/components/inspector-controls-tabs/index.cjs +13 -8
  57. package/build/components/inspector-controls-tabs/index.cjs.map +3 -3
  58. package/build/components/inspector-controls-tabs/settings-tab.cjs +1 -4
  59. package/build/components/inspector-controls-tabs/settings-tab.cjs.map +3 -3
  60. package/build/components/inspector-controls-tabs/styles-tab.cjs +9 -0
  61. package/build/components/inspector-controls-tabs/styles-tab.cjs.map +3 -3
  62. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs +11 -5
  63. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs.map +2 -2
  64. package/build/components/list-view/block-select-button.cjs +20 -8
  65. package/build/components/list-view/block-select-button.cjs.map +2 -2
  66. package/build/components/list-view/block.cjs +2 -1
  67. package/build/components/list-view/block.cjs.map +2 -2
  68. package/build/components/preset-input-control/custom-value-controls.cjs +10 -1
  69. package/build/components/preset-input-control/custom-value-controls.cjs.map +2 -2
  70. package/build/components/preset-input-control/index.cjs.map +3 -3
  71. package/build/components/provider/use-media-upload-settings.cjs +1 -0
  72. package/build/components/provider/use-media-upload-settings.cjs.map +2 -2
  73. package/build/components/rich-text/event-listeners/enter.cjs +9 -2
  74. package/build/components/rich-text/event-listeners/enter.cjs.map +3 -3
  75. package/build/components/rich-text/event-listeners/paste-handler.cjs +4 -4
  76. package/build/components/rich-text/event-listeners/paste-handler.cjs.map +3 -3
  77. package/build/hooks/background.cjs +13 -3
  78. package/build/hooks/background.cjs.map +2 -2
  79. package/build/hooks/block-fields/link/index.cjs.map +3 -3
  80. package/build/hooks/block-fields/media/index.cjs.map +3 -3
  81. package/build/hooks/block-style-state.cjs +112 -0
  82. package/build/hooks/block-style-state.cjs.map +7 -0
  83. package/build/hooks/border.cjs +13 -3
  84. package/build/hooks/border.cjs.map +2 -2
  85. package/build/hooks/color.cjs +28 -9
  86. package/build/hooks/color.cjs.map +2 -2
  87. package/build/hooks/dimensions.cjs +15 -6
  88. package/build/hooks/dimensions.cjs.map +2 -2
  89. package/build/hooks/layout-child.cjs +147 -61
  90. package/build/hooks/layout-child.cjs.map +2 -2
  91. package/build/hooks/layout.cjs +263 -56
  92. package/build/hooks/layout.cjs.map +3 -3
  93. package/build/hooks/state-utils.cjs +94 -0
  94. package/build/hooks/state-utils.cjs.map +7 -0
  95. package/build/hooks/states.cjs +124 -0
  96. package/build/hooks/states.cjs.map +7 -0
  97. package/build/hooks/style.cjs +304 -17
  98. package/build/hooks/style.cjs.map +3 -3
  99. package/build/hooks/typography.cjs +14 -5
  100. package/build/hooks/typography.cjs.map +2 -2
  101. package/build/layouts/constrained.cjs +128 -55
  102. package/build/layouts/constrained.cjs.map +3 -3
  103. package/build/layouts/flex.cjs +119 -31
  104. package/build/layouts/flex.cjs.map +3 -3
  105. package/build/layouts/grid.cjs +103 -40
  106. package/build/layouts/grid.cjs.map +3 -3
  107. package/build/private-apis.cjs +2 -0
  108. package/build/private-apis.cjs.map +2 -2
  109. package/build/store/private-actions.cjs +18 -0
  110. package/build/store/private-actions.cjs.map +2 -2
  111. package/build/store/private-keys.cjs +10 -2
  112. package/build/store/private-keys.cjs.map +2 -2
  113. package/build/store/private-selectors.cjs +32 -2
  114. package/build/store/private-selectors.cjs.map +2 -2
  115. package/build/store/reducer.cjs +70 -1
  116. package/build/store/reducer.cjs.map +2 -2
  117. package/build/store/utils.cjs +1 -1
  118. package/build/store/utils.cjs.map +2 -2
  119. package/build/utils/color-values.cjs +44 -0
  120. package/build/utils/color-values.cjs.map +7 -0
  121. package/build-module/components/block-card/index.mjs +52 -45
  122. package/build-module/components/block-card/index.mjs.map +2 -2
  123. package/build-module/components/block-heading-level-dropdown/heading-level-icon.mjs +2 -2
  124. package/build-module/components/block-heading-level-dropdown/heading-level-icon.mjs.map +2 -2
  125. package/build-module/components/block-icon/index.mjs +8 -2
  126. package/build-module/components/block-icon/index.mjs.map +2 -2
  127. package/build-module/components/block-inspector/index.mjs +166 -13
  128. package/build-module/components/block-inspector/index.mjs.map +2 -2
  129. package/build-module/components/block-inspector/inspector-pre-tabs-slot-fill.mjs +12 -0
  130. package/build-module/components/block-inspector/inspector-pre-tabs-slot-fill.mjs.map +7 -0
  131. package/build-module/components/block-list/use-block-props/use-focus-handler.mjs +7 -5
  132. package/build-module/components/block-list/use-block-props/use-focus-handler.mjs.map +2 -2
  133. package/build-module/components/block-list/use-block-props/use-is-hovered.mjs +28 -15
  134. package/build-module/components/block-list/use-block-props/use-is-hovered.mjs.map +2 -2
  135. package/build-module/components/block-lock/modal.mjs +4 -4
  136. package/build-module/components/block-lock/modal.mjs.map +2 -2
  137. package/build-module/components/block-patterns-list/index.mjs +14 -4
  138. package/build-module/components/block-patterns-list/index.mjs.map +2 -2
  139. package/build-module/components/block-popover/index.mjs +13 -3
  140. package/build-module/components/block-popover/index.mjs.map +2 -2
  141. package/build-module/components/block-toolbar/switch-section-style.mjs +2 -2
  142. package/build-module/components/block-toolbar/switch-section-style.mjs.map +2 -2
  143. package/build-module/components/block-visibility/modal.mjs +2 -2
  144. package/build-module/components/block-visibility/modal.mjs.map +2 -2
  145. package/build-module/components/block-visibility/viewport-visibility-info.mjs +2 -2
  146. package/build-module/components/block-visibility/viewport-visibility-info.mjs.map +2 -2
  147. package/build-module/components/child-layout-control/index.mjs +10 -5
  148. package/build-module/components/child-layout-control/index.mjs.map +2 -2
  149. package/build-module/components/colors-gradients/control.mjs +7 -4
  150. package/build-module/components/colors-gradients/control.mjs.map +2 -2
  151. package/build-module/components/global-styles/advanced-panel.mjs +25 -27
  152. package/build-module/components/global-styles/advanced-panel.mjs.map +2 -2
  153. package/build-module/components/global-styles/color-panel.mjs +96 -59
  154. package/build-module/components/global-styles/color-panel.mjs.map +2 -2
  155. package/build-module/components/global-styles/dimensions-panel.mjs +20 -8
  156. package/build-module/components/global-styles/dimensions-panel.mjs.map +2 -2
  157. package/build-module/components/global-styles/index.mjs +2 -0
  158. package/build-module/components/global-styles/index.mjs.map +2 -2
  159. package/build-module/components/global-styles/shadow-panel-components.mjs +39 -28
  160. package/build-module/components/global-styles/shadow-panel-components.mjs.map +2 -2
  161. package/build-module/components/global-styles/state-control-badges.mjs +48 -0
  162. package/build-module/components/global-styles/state-control-badges.mjs.map +7 -0
  163. package/build-module/components/global-styles/state-control.mjs +57 -71
  164. package/build-module/components/global-styles/state-control.mjs.map +2 -2
  165. package/build-module/components/iframe/use-scale-canvas.mjs +4 -1
  166. package/build-module/components/iframe/use-scale-canvas.mjs.map +2 -2
  167. package/build-module/components/inserter/hooks/use-patterns-state.mjs +8 -7
  168. package/build-module/components/inserter/hooks/use-patterns-state.mjs.map +2 -2
  169. package/build-module/components/inserter/index.mjs +1 -0
  170. package/build-module/components/inserter/index.mjs.map +2 -2
  171. package/build-module/components/inserter/media-tab/media-preview.mjs +27 -19
  172. package/build-module/components/inserter/media-tab/media-preview.mjs.map +2 -2
  173. package/build-module/components/inserter/panel.mjs +2 -2
  174. package/build-module/components/inserter/panel.mjs.map +2 -2
  175. package/build-module/components/inspector-controls/block-support-tools-panel.mjs +10 -2
  176. package/build-module/components/inspector-controls/block-support-tools-panel.mjs.map +2 -2
  177. package/build-module/components/inspector-controls/fill.mjs +18 -5
  178. package/build-module/components/inspector-controls/fill.mjs.map +2 -2
  179. package/build-module/components/inspector-controls/groups.mjs +2 -0
  180. package/build-module/components/inspector-controls/groups.mjs.map +2 -2
  181. package/build-module/components/inspector-controls-tabs/index.mjs +14 -10
  182. package/build-module/components/inspector-controls-tabs/index.mjs.map +2 -2
  183. package/build-module/components/inspector-controls-tabs/settings-tab.mjs +1 -4
  184. package/build-module/components/inspector-controls-tabs/settings-tab.mjs.map +2 -2
  185. package/build-module/components/inspector-controls-tabs/styles-tab.mjs +9 -0
  186. package/build-module/components/inspector-controls-tabs/styles-tab.mjs.map +2 -2
  187. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs +11 -5
  188. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs.map +2 -2
  189. package/build-module/components/list-view/block-select-button.mjs +20 -9
  190. package/build-module/components/list-view/block-select-button.mjs.map +2 -2
  191. package/build-module/components/list-view/block.mjs +2 -1
  192. package/build-module/components/list-view/block.mjs.map +2 -2
  193. package/build-module/components/preset-input-control/custom-value-controls.mjs +10 -2
  194. package/build-module/components/preset-input-control/custom-value-controls.mjs.map +2 -2
  195. package/build-module/components/preset-input-control/index.mjs +2 -2
  196. package/build-module/components/preset-input-control/index.mjs.map +2 -2
  197. package/build-module/components/provider/use-media-upload-settings.mjs +1 -0
  198. package/build-module/components/provider/use-media-upload-settings.mjs.map +2 -2
  199. package/build-module/components/rich-text/event-listeners/enter.mjs +9 -2
  200. package/build-module/components/rich-text/event-listeners/enter.mjs.map +2 -2
  201. package/build-module/components/rich-text/event-listeners/paste-handler.mjs +4 -4
  202. package/build-module/components/rich-text/event-listeners/paste-handler.mjs.map +2 -2
  203. package/build-module/hooks/background.mjs +18 -3
  204. package/build-module/hooks/background.mjs.map +2 -2
  205. package/build-module/hooks/block-fields/link/index.mjs +3 -3
  206. package/build-module/hooks/block-fields/link/index.mjs.map +2 -2
  207. package/build-module/hooks/block-fields/media/index.mjs +3 -3
  208. package/build-module/hooks/block-fields/media/index.mjs.map +2 -2
  209. package/build-module/hooks/block-style-state.mjs +79 -0
  210. package/build-module/hooks/block-style-state.mjs.map +7 -0
  211. package/build-module/hooks/border.mjs +18 -3
  212. package/build-module/hooks/border.mjs.map +2 -2
  213. package/build-module/hooks/color.mjs +33 -9
  214. package/build-module/hooks/color.mjs.map +2 -2
  215. package/build-module/hooks/dimensions.mjs +20 -6
  216. package/build-module/hooks/dimensions.mjs.map +2 -2
  217. package/build-module/hooks/layout-child.mjs +141 -61
  218. package/build-module/hooks/layout-child.mjs.map +2 -2
  219. package/build-module/hooks/layout.mjs +270 -58
  220. package/build-module/hooks/layout.mjs.map +2 -2
  221. package/build-module/hooks/state-utils.mjs +64 -0
  222. package/build-module/hooks/state-utils.mjs.map +7 -0
  223. package/build-module/hooks/states.mjs +85 -0
  224. package/build-module/hooks/states.mjs.map +7 -0
  225. package/build-module/hooks/style.mjs +309 -18
  226. package/build-module/hooks/style.mjs.map +2 -2
  227. package/build-module/hooks/typography.mjs +19 -5
  228. package/build-module/hooks/typography.mjs.map +2 -2
  229. package/build-module/layouts/constrained.mjs +130 -57
  230. package/build-module/layouts/constrained.mjs.map +2 -2
  231. package/build-module/layouts/flex.mjs +123 -35
  232. package/build-module/layouts/flex.mjs.map +2 -2
  233. package/build-module/layouts/grid.mjs +105 -42
  234. package/build-module/layouts/grid.mjs.map +2 -2
  235. package/build-module/private-apis.mjs +4 -0
  236. package/build-module/private-apis.mjs.map +2 -2
  237. package/build-module/store/private-actions.mjs +16 -0
  238. package/build-module/store/private-actions.mjs.map +2 -2
  239. package/build-module/store/private-keys.mjs +7 -1
  240. package/build-module/store/private-keys.mjs.map +2 -2
  241. package/build-module/store/private-selectors.mjs +30 -2
  242. package/build-module/store/private-selectors.mjs.map +2 -2
  243. package/build-module/store/reducer.mjs +69 -1
  244. package/build-module/store/reducer.mjs.map +2 -2
  245. package/build-module/store/utils.mjs +5 -2
  246. package/build-module/store/utils.mjs.map +2 -2
  247. package/build-module/utils/color-values.mjs +19 -0
  248. package/build-module/utils/color-values.mjs.map +7 -0
  249. package/build-style/content-rtl.css +18 -3
  250. package/build-style/content.css +18 -3
  251. package/build-style/style-rtl.css +14 -17
  252. package/build-style/style.css +14 -17
  253. package/package.json +39 -39
  254. package/src/components/audio-player/index.native.js +7 -3
  255. package/src/components/block-card/index.js +67 -60
  256. package/src/components/block-heading-level-dropdown/heading-level-icon.js +2 -2
  257. package/src/components/block-icon/index.js +5 -2
  258. package/src/components/block-icon/index.native.js +2 -2
  259. package/src/components/block-inspector/index.js +153 -7
  260. package/src/components/block-inspector/inspector-pre-tabs-slot-fill.js +11 -0
  261. package/src/components/block-list/block-selection-button.native.js +3 -3
  262. package/src/components/block-list/content.scss +0 -6
  263. package/src/components/block-list/use-block-props/use-focus-handler.js +8 -6
  264. package/src/components/block-list/use-block-props/use-is-hovered.js +32 -15
  265. package/src/components/block-lock/modal.js +4 -4
  266. package/src/components/block-patterns-list/index.js +14 -5
  267. package/src/components/block-patterns-list/stories/index.story.jsx +2 -0
  268. package/src/components/block-patterns-list/style.scss +0 -1
  269. package/src/components/block-popover/index.js +20 -10
  270. package/src/components/block-toolbar/switch-section-style.js +2 -2
  271. package/src/components/block-visibility/modal.js +2 -2
  272. package/src/components/block-visibility/viewport-visibility-info.js +2 -2
  273. package/src/components/child-layout-control/index.js +15 -8
  274. package/src/components/child-layout-control/test/index.js +126 -0
  275. package/src/components/colors-gradients/control.js +10 -8
  276. package/src/components/colors-gradients/test/control.js +98 -1
  277. package/src/components/global-styles/advanced-panel.js +44 -39
  278. package/src/components/global-styles/color-panel.js +133 -60
  279. package/src/components/global-styles/dimensions-panel.js +29 -8
  280. package/src/components/global-styles/index.js +1 -0
  281. package/src/components/global-styles/shadow-panel-components.js +29 -19
  282. package/src/components/global-styles/state-control-badges.js +58 -0
  283. package/src/components/global-styles/state-control.js +28 -36
  284. package/src/components/global-styles/test/color-panel.js +135 -0
  285. package/src/components/iframe/use-scale-canvas.js +8 -2
  286. package/src/components/inserter/hooks/use-patterns-state.js +12 -7
  287. package/src/components/inserter/index.js +1 -0
  288. package/src/components/inserter/media-tab/media-preview.js +29 -20
  289. package/src/components/inserter/panel.js +2 -2
  290. package/src/components/inserter/style.scss +1 -0
  291. package/src/components/inserter-button/index.native.js +5 -2
  292. package/src/components/inspector-controls/block-support-tools-panel.js +10 -2
  293. package/src/components/inspector-controls/fill.js +18 -5
  294. package/src/components/inspector-controls/groups.js +2 -0
  295. package/src/components/inspector-controls-tabs/index.js +9 -5
  296. package/src/components/inspector-controls-tabs/settings-tab.js +1 -7
  297. package/src/components/inspector-controls-tabs/styles-tab.js +6 -0
  298. package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +13 -7
  299. package/src/components/list-view/block-select-button.js +19 -9
  300. package/src/components/list-view/block.js +6 -1
  301. package/src/components/media-replace-flow/style.scss +0 -18
  302. package/src/components/preset-input-control/custom-value-controls.js +13 -6
  303. package/src/components/preset-input-control/index.js +2 -2
  304. package/src/components/provider/use-media-upload-settings.js +1 -0
  305. package/src/components/rich-text/event-listeners/enter.js +14 -2
  306. package/src/components/rich-text/event-listeners/paste-handler.js +5 -4
  307. package/src/components/unsupported-block-details/index.native.js +6 -2
  308. package/src/components/video-player/index.native.js +2 -2
  309. package/src/components/warning/index.native.js +2 -2
  310. package/src/hooks/background.js +59 -37
  311. package/src/hooks/block-fields/link/index.js +3 -3
  312. package/src/hooks/block-fields/media/index.js +3 -3
  313. package/src/hooks/block-style-state.js +127 -0
  314. package/src/hooks/border.js +25 -6
  315. package/src/hooks/color.js +40 -18
  316. package/src/hooks/dimensions.js +32 -11
  317. package/src/hooks/layout-child.js +179 -62
  318. package/src/hooks/layout.js +349 -75
  319. package/src/hooks/layout.scss +6 -0
  320. package/src/hooks/state-utils.js +158 -0
  321. package/src/hooks/states.js +109 -0
  322. package/src/hooks/style.js +456 -19
  323. package/src/hooks/test/block-style-state.js +270 -0
  324. package/src/hooks/test/layout.js +185 -0
  325. package/src/hooks/test/state-utils.js +193 -0
  326. package/src/hooks/test/style.js +301 -1
  327. package/src/hooks/typography.js +33 -14
  328. package/src/layouts/constrained.js +182 -95
  329. package/src/layouts/flex.js +141 -36
  330. package/src/layouts/grid.js +122 -32
  331. package/src/layouts/test/flex.js +57 -20
  332. package/src/private-apis.js +4 -0
  333. package/src/store/private-actions.js +32 -0
  334. package/src/store/private-keys.js +4 -0
  335. package/src/store/private-selectors.js +61 -2
  336. package/src/store/reducer.js +105 -1
  337. package/src/store/test/private-actions.js +26 -0
  338. package/src/store/test/private-selectors.js +143 -0
  339. package/src/store/test/reducer.js +363 -0
  340. package/src/store/utils.js +6 -2
  341. package/src/utils/color-values.js +28 -0
  342. package/src/utils/test/color-values.js +78 -0
@@ -40,13 +40,14 @@ function helpText( selfStretch, parentLayout ) {
40
40
  /**
41
41
  * Form to edit the child layout value.
42
42
  *
43
- * @param {Object} props Props.
44
- * @param {Object} props.value The child layout value.
45
- * @param {Function} props.onChange Function to update the child layout value.
46
- * @param {Object} props.parentLayout The parent layout value.
43
+ * @param {Object} props Props.
44
+ * @param {Object} props.value The child layout value.
45
+ * @param {Function} props.onChange Function to update the child layout value.
46
+ * @param {Object} props.parentLayout The parent layout value.
47
47
  *
48
- * @param {boolean} props.isShownByDefault
49
- * @param {string} props.panelId
48
+ * @param {boolean} props.isShownByDefault Whether the control is shown by default.
49
+ * @param {string} props.panelId The panel ID.
50
+ * @param {boolean} props.showGridSpanDefaults Whether unset grid span controls should show default values.
50
51
  * @return {Element} child layout edit element.
51
52
  */
52
53
  export default function ChildLayoutControl( {
@@ -55,6 +56,7 @@ export default function ChildLayoutControl( {
55
56
  parentLayout,
56
57
  isShownByDefault,
57
58
  panelId,
59
+ showGridSpanDefaults = true,
58
60
  } ) {
59
61
  const {
60
62
  type: parentType,
@@ -80,6 +82,7 @@ export default function ChildLayoutControl( {
80
82
  parentLayout={ parentLayout }
81
83
  isShownByDefault={ isShownByDefault }
82
84
  panelId={ panelId }
85
+ showGridSpanDefaults={ showGridSpanDefaults }
83
86
  />
84
87
  );
85
88
  }
@@ -206,6 +209,7 @@ function GridControls( {
206
209
  parentLayout,
207
210
  isShownByDefault,
208
211
  panelId,
212
+ showGridSpanDefaults,
209
213
  } ) {
210
214
  const { columnStart, rowStart, columnSpan, rowSpan } = childLayout;
211
215
  const { columnCount, rowCount } = parentLayout ?? {};
@@ -243,6 +247,9 @@ function GridControls( {
243
247
  window.__experimentalEnableGridInteractivity && rowCount
244
248
  ? rowCount - ( rowStart ?? 1 ) + 1
245
249
  : undefined;
250
+ const columnSpanValue =
251
+ columnSpan ?? ( showGridSpanDefaults ? 1 : undefined );
252
+ const rowSpanValue = rowSpan ?? ( showGridSpanDefaults ? 1 : undefined );
246
253
 
247
254
  return (
248
255
  <>
@@ -274,7 +281,7 @@ function GridControls( {
274
281
  columnSpan: constrainedValue,
275
282
  } );
276
283
  } }
277
- value={ columnSpan ?? 1 }
284
+ value={ columnSpanValue }
278
285
  min={ 1 }
279
286
  max={ maxColumnSpan }
280
287
  />
@@ -298,7 +305,7 @@ function GridControls( {
298
305
  rowSpan: constrainedValue,
299
306
  } );
300
307
  } }
301
- value={ rowSpan ?? 1 }
308
+ value={ rowSpanValue }
302
309
  min={ 1 }
303
310
  max={ maxRowSpan }
304
311
  />
@@ -0,0 +1,126 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { render, screen } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
6
+
7
+ /**
8
+ * WordPress dependencies
9
+ */
10
+ import { __experimentalToolsPanel as ToolsPanel } from '@wordpress/components';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import ChildLayoutControl from '../';
16
+
17
+ jest.mock( '@wordpress/data/src/components/use-select', () =>
18
+ jest.fn( ( mapSelect ) => {
19
+ if ( typeof mapSelect === 'function' ) {
20
+ return mapSelect( () => ( {
21
+ getBlockRootClientId: () => 'root-client-id',
22
+ } ) );
23
+ }
24
+
25
+ return {
26
+ getBlockAttributes: () => ( {} ),
27
+ getBlockOrder: () => [],
28
+ };
29
+ } )
30
+ );
31
+
32
+ jest.mock( '@wordpress/data/src/components/use-dispatch', () => ( {
33
+ useDispatch: () => ( {
34
+ __unstableMarkNextChangeAsNotPersistent: jest.fn(),
35
+ moveBlocksToPosition: jest.fn(),
36
+ } ),
37
+ } ) );
38
+
39
+ describe( 'ChildLayoutControl', () => {
40
+ const baseProps = {
41
+ onChange: jest.fn(),
42
+ parentLayout: {
43
+ type: 'grid',
44
+ },
45
+ isShownByDefault: true,
46
+ panelId: 'client-id',
47
+ };
48
+
49
+ afterEach( () => {
50
+ jest.clearAllMocks();
51
+ } );
52
+
53
+ function renderControl( props ) {
54
+ return render(
55
+ <ToolsPanel
56
+ label="Dimensions"
57
+ resetAll={ jest.fn() }
58
+ panelId="client-id"
59
+ >
60
+ <ChildLayoutControl { ...baseProps } { ...props } />
61
+ </ToolsPanel>
62
+ );
63
+ }
64
+
65
+ it( 'shows default grid span values for unset span controls by default', () => {
66
+ renderControl( { value: {} } );
67
+
68
+ expect(
69
+ screen.getByRole( 'spinbutton', { name: 'Column span' } )
70
+ ).toHaveValue( 1 );
71
+ expect(
72
+ screen.getByRole( 'spinbutton', { name: 'Row span' } )
73
+ ).toHaveValue( 1 );
74
+ } );
75
+
76
+ it( 'shows empty grid span values when defaults are hidden', () => {
77
+ renderControl( { value: {}, showGridSpanDefaults: false } );
78
+
79
+ expect(
80
+ screen.getByRole( 'spinbutton', { name: 'Column span' } )
81
+ ).toHaveValue( null );
82
+ expect(
83
+ screen.getByRole( 'spinbutton', { name: 'Row span' } )
84
+ ).toHaveValue( null );
85
+ } );
86
+
87
+ it( 'shows explicitly set grid span values when defaults are hidden', () => {
88
+ renderControl( {
89
+ value: {
90
+ columnSpan: 1,
91
+ rowSpan: 2,
92
+ },
93
+ showGridSpanDefaults: false,
94
+ } );
95
+
96
+ expect(
97
+ screen.getByRole( 'spinbutton', { name: 'Column span' } )
98
+ ).toHaveValue( 1 );
99
+ expect(
100
+ screen.getByRole( 'spinbutton', { name: 'Row span' } )
101
+ ).toHaveValue( 2 );
102
+ } );
103
+
104
+ it( 'sets a numeric span when entering 1 into an empty span control', async () => {
105
+ const user = userEvent.setup();
106
+ const onChange = jest.fn();
107
+
108
+ renderControl( {
109
+ value: {},
110
+ onChange,
111
+ showGridSpanDefaults: false,
112
+ } );
113
+
114
+ await user.type(
115
+ screen.getByRole( 'spinbutton', { name: 'Column span' } ),
116
+ '1'
117
+ );
118
+
119
+ expect( onChange ).toHaveBeenCalledWith( {
120
+ columnStart: undefined,
121
+ rowStart: undefined,
122
+ rowSpan: undefined,
123
+ columnSpan: 1,
124
+ } );
125
+ } );
126
+ } );
@@ -42,6 +42,7 @@ function ColorGradientControlInner( {
42
42
  onColorChange,
43
43
  onGradientChange,
44
44
  colorValue,
45
+ colorSlug,
45
46
  gradientValue,
46
47
  clearable,
47
48
  showTitle = true,
@@ -59,18 +60,19 @@ function ColorGradientControlInner( {
59
60
  return null;
60
61
  }
61
62
 
63
+ const colorPaletteOnChange = canChooseAGradient
64
+ ? ( newColor, _index, newSlug ) => {
65
+ onColorChange( newColor, newSlug );
66
+ onGradientChange();
67
+ }
68
+ : ( newColor, _index, newSlug ) => onColorChange( newColor, newSlug );
69
+
62
70
  const tabPanels = {
63
71
  [ TAB_IDS.color ]: (
64
72
  <ColorPalette
65
73
  value={ colorValue }
66
- onChange={
67
- canChooseAGradient
68
- ? ( newColor ) => {
69
- onColorChange( newColor );
70
- onGradientChange();
71
- }
72
- : onColorChange
73
- }
74
+ selectedSlug={ colorSlug }
75
+ onChange={ colorPaletteOnChange }
74
76
  { ...{ colors, disableCustomColors } }
75
77
  __experimentalIsRenderedInSidebar={
76
78
  __experimentalIsRenderedInSidebar
@@ -2,7 +2,7 @@
2
2
  * External dependencies
3
3
  */
4
4
  import { screen } from '@testing-library/react';
5
- import { render } from '@ariakit/test/react';
5
+ import { click, render } from '@ariakit/test/react';
6
6
 
7
7
  /**
8
8
  * Internal dependencies
@@ -131,4 +131,101 @@ describe( 'ColorPaletteControl', () => {
131
131
  'components-custom-gradient-picker__control-point-button'
132
132
  );
133
133
  } );
134
+
135
+ describe( 'slug-based color selection', () => {
136
+ // Two entries that share the same hex value — used to verify that slug
137
+ // disambiguation works correctly.
138
+ const DUPLICATE_COLOR_PALETTE = [
139
+ {
140
+ color: '#000',
141
+ name: 'Dark Background',
142
+ slug: 'dark-background',
143
+ },
144
+ { color: '#000', name: 'Dark Text', slug: 'dark-text' },
145
+ ];
146
+
147
+ it( 'forwards colorSlug as selectedSlug to ColorPalette, marking only the slug-matched swatch as selected', async () => {
148
+ await render(
149
+ <ColorGradientControl
150
+ label="Test Color Gradient"
151
+ colorValue="#000"
152
+ colorSlug="dark-text"
153
+ colors={ DUPLICATE_COLOR_PALETTE }
154
+ gradients={ [] }
155
+ disableCustomColors={ false }
156
+ disableCustomGradients
157
+ onColorChange={ noop }
158
+ onGradientChange={ noop }
159
+ />
160
+ );
161
+
162
+ const options = screen.getAllByRole( 'option' );
163
+ // 'dark-background' is index 0, 'dark-text' is index 1.
164
+ // With colorSlug="dark-text", only the second swatch should be selected.
165
+ expect( options[ 0 ] ).toHaveAttribute( 'aria-selected', 'false' );
166
+ expect( options[ 1 ] ).toHaveAttribute( 'aria-selected', 'true' );
167
+ } );
168
+
169
+ it( 'calls onColorChange with (color, slug) when a swatch is clicked (color-only palette)', async () => {
170
+ const onColorChange = jest.fn();
171
+
172
+ await render(
173
+ <ColorGradientControl
174
+ label="Test Color Gradient"
175
+ colorValue={ undefined }
176
+ colors={ DUPLICATE_COLOR_PALETTE }
177
+ gradients={ [] }
178
+ disableCustomColors={ false }
179
+ disableCustomGradients
180
+ onColorChange={ onColorChange }
181
+ onGradientChange={ noop }
182
+ />
183
+ );
184
+
185
+ const options = screen.getAllByRole( 'option' );
186
+ // Click the second swatch: color='#000', slug='dark-text'.
187
+ await click( options[ 1 ] );
188
+
189
+ expect( onColorChange ).toHaveBeenCalledWith( '#000', 'dark-text' );
190
+ } );
191
+
192
+ it( 'calls onColorChange with (color, slug) and calls onGradientChange() when both colors and gradients are available', async () => {
193
+ const onColorChange = jest.fn();
194
+ const onGradientChange = jest.fn();
195
+
196
+ await render(
197
+ <ColorGradientControl
198
+ label="Test Color Gradient"
199
+ colorValue={ undefined }
200
+ colors={ DUPLICATE_COLOR_PALETTE }
201
+ gradients={ [
202
+ {
203
+ gradient:
204
+ 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)',
205
+ name: 'Vivid cyan blue to vivid purple',
206
+ slug: 'vivid-cyan-blue-to-vivid-purple',
207
+ },
208
+ ] }
209
+ disableCustomColors={ false }
210
+ disableCustomGradients={ false }
211
+ onColorChange={ onColorChange }
212
+ onGradientChange={ onGradientChange }
213
+ />
214
+ );
215
+
216
+ // When both colors and gradients are available the color tab is shown
217
+ // by default (no gradientValue). Click the first color swatch.
218
+ const options = screen.getAllByRole( 'option' );
219
+ await click( options[ 0 ] );
220
+
221
+ // First entry: color='#000', slug='dark-background'.
222
+ expect( onColorChange ).toHaveBeenCalledWith(
223
+ '#000',
224
+ 'dark-background'
225
+ );
226
+ // Selecting a color must also clear the active gradient.
227
+ expect( onGradientChange ).toHaveBeenCalledTimes( 1 );
228
+ expect( onGradientChange ).toHaveBeenCalledWith();
229
+ } );
230
+ } );
134
231
  } );
@@ -1,11 +1,8 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import {
5
- TextareaControl,
6
- Notice,
7
- __experimentalVStack as VStack,
8
- } from '@wordpress/components';
4
+ import { TextareaControl, Notice } from '@wordpress/components';
5
+ import { Stack } from '@wordpress/ui';
9
6
  import { useState } from '@wordpress/element';
10
7
  import { __ } from '@wordpress/i18n';
11
8
 
@@ -29,6 +26,41 @@ export function validateCSS( css ) {
29
26
  return true;
30
27
  }
31
28
 
29
+ /**
30
+ * Returns the error message string if the CSS contains HTML markup, or null if it is clean.
31
+ *
32
+ * @param {string} css The CSS string to check.
33
+ * @return {string|null} An error message, or null if the CSS is valid.
34
+ */
35
+ function getMarkupValidationError( css ) {
36
+ return validateCSS( css )
37
+ ? null
38
+ : __( 'The custom CSS is invalid. Do not use <> markup.' );
39
+ }
40
+
41
+ /**
42
+ * Full CSS validation: markup check first (fast), then a CSS parser (slower).
43
+ *
44
+ * @param {string} css The CSS string to validate.
45
+ * @return {string|null} An error message, or null if the CSS is valid.
46
+ */
47
+ function getCSSValidationError( css ) {
48
+ if ( ! css ) {
49
+ return null;
50
+ }
51
+ const markupError = getMarkupValidationError( css );
52
+ if ( markupError ) {
53
+ return markupError;
54
+ }
55
+ const [ transformed ] = transformStyles(
56
+ [ { css } ],
57
+ '.for-validation-only'
58
+ );
59
+ return transformed === null
60
+ ? __( 'There is an error with your CSS structure.' )
61
+ : null;
62
+ }
63
+
32
64
  export default function AdvancedPanel( {
33
65
  value,
34
66
  onChange,
@@ -36,51 +68,24 @@ export default function AdvancedPanel( {
36
68
  help,
37
69
  } ) {
38
70
  // Custom CSS
39
- const [ cssError, setCSSError ] = useState( null );
40
71
  const customCSS = inheritedValue?.css;
72
+ const [ cssError, setCSSError ] = useState( () =>
73
+ getCSSValidationError( customCSS )
74
+ );
41
75
  function handleOnChange( newValue ) {
42
76
  onChange( {
43
77
  ...value,
44
78
  css: newValue,
45
79
  } );
46
80
 
47
- // Validate immediately on change for quick feedback.
48
- if ( ! validateCSS( newValue ) ) {
49
- setCSSError(
50
- __( 'The custom CSS is invalid. Do not use <> markup.' )
51
- );
52
- return;
53
- }
54
-
55
- // Clear HTML markup error if CSS is now valid.
56
- if ( cssError ) {
57
- setCSSError( null );
58
- }
81
+ setCSSError( getMarkupValidationError( newValue ) );
59
82
  }
60
83
  function handleOnBlur( event ) {
61
- const cssValue = event?.target?.value;
62
-
63
- if ( ! cssValue || ! validateCSS( cssValue ) ) {
64
- return;
65
- }
66
-
67
- // Check if the value is valid CSS structure on blur (more expensive check).
68
- // Pass a wrapping selector to ensure that `transformStyles` validates the CSS.
69
- // Note that the wrapping selector here is not used in the actual output of any styles.
70
- const [ transformed ] = transformStyles(
71
- [ { css: cssValue } ],
72
- '.for-validation-only'
73
- );
74
-
75
- setCSSError(
76
- transformed === null
77
- ? __( 'There is an error with your CSS structure.' )
78
- : null
79
- );
84
+ setCSSError( getCSSValidationError( event?.target?.value ) );
80
85
  }
81
86
 
82
87
  return (
83
- <VStack spacing={ 3 }>
88
+ <Stack direction="column" gap="md">
84
89
  { cssError && (
85
90
  <Notice status="error" onRemove={ () => setCSSError( null ) }>
86
91
  { cssError }
@@ -95,6 +100,6 @@ export default function AdvancedPanel( {
95
100
  spellCheck={ false }
96
101
  help={ help }
97
102
  />
98
- </VStack>
103
+ </Stack>
99
104
  );
100
105
  }