@wordpress/block-editor 16.0.1-next.v.202607070741.0 → 16.1.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 (679) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/README.md +8 -0
  3. package/build/components/alignment-control/ui.cjs +2 -4
  4. package/build/components/alignment-control/ui.cjs.map +2 -2
  5. package/build/components/background-image-control/index.cjs +40 -10
  6. package/build/components/background-image-control/index.cjs.map +2 -2
  7. package/build/components/block-alignment-control/ui.cjs +5 -3
  8. package/build/components/block-alignment-control/ui.cjs.map +2 -2
  9. package/build/components/block-canvas/index.cjs +6 -1
  10. package/build/components/block-canvas/index.cjs.map +2 -2
  11. package/build/components/block-controls/groups.cjs +3 -1
  12. package/build/components/block-controls/groups.cjs.map +2 -2
  13. package/build/components/block-edit/edit.cjs +10 -18
  14. package/build/components/block-edit/edit.cjs.map +2 -2
  15. package/build/components/block-inspector/index.cjs +73 -46
  16. package/build/components/block-inspector/index.cjs.map +2 -2
  17. package/build/components/block-list/block-html.cjs +4 -1
  18. package/build/components/block-list/block-html.cjs.map +2 -2
  19. package/build/components/block-list/block.cjs +9 -3
  20. package/build/components/block-list/block.cjs.map +3 -3
  21. package/build/components/block-list/index.cjs +1 -3
  22. package/build/components/block-list/index.cjs.map +2 -2
  23. package/build/components/block-list/use-block-props/index.cjs +7 -2
  24. package/build/components/block-list/use-block-props/index.cjs.map +2 -2
  25. package/build/components/block-list/use-block-props/use-focus-first-element.cjs +9 -4
  26. package/build/components/block-list/use-block-props/use-focus-first-element.cjs.map +2 -2
  27. package/build/components/block-list/use-block-props/use-focus-handler.cjs +11 -4
  28. package/build/components/block-list/use-block-props/use-focus-handler.cjs.map +2 -2
  29. package/build/components/block-list/use-block-props/use-register-block-event-handlers.cjs +48 -0
  30. package/build/components/block-list/use-block-props/use-register-block-event-handlers.cjs.map +7 -0
  31. package/build/components/block-parent-selector/index.cjs +2 -2
  32. package/build/components/block-parent-selector/index.cjs.map +2 -2
  33. package/build/components/block-toolbar/index.cjs +43 -24
  34. package/build/components/block-toolbar/index.cjs.map +2 -2
  35. package/build/components/block-toolbar/switch-section-style.cjs +4 -2
  36. package/build/components/block-toolbar/switch-section-style.cjs.map +3 -3
  37. package/build/components/block-tools/empty-block-inserter.cjs +2 -7
  38. package/build/components/block-tools/empty-block-inserter.cjs.map +2 -2
  39. package/build/components/block-tools/index.cjs +7 -2
  40. package/build/components/block-tools/index.cjs.map +2 -2
  41. package/build/components/block-vertical-alignment-control/ui.cjs +3 -5
  42. package/build/components/block-vertical-alignment-control/ui.cjs.map +2 -2
  43. package/build/components/block-visibility/modal.cjs +20 -6
  44. package/build/components/block-visibility/modal.cjs.map +2 -2
  45. package/build/components/block-visibility/use-block-visibility.cjs +16 -6
  46. package/build/components/block-visibility/use-block-visibility.cjs.map +3 -3
  47. package/build/components/block-visibility/utils.cjs +15 -2
  48. package/build/components/block-visibility/utils.cjs.map +3 -3
  49. package/build/components/block-visibility/viewport-menu-item.cjs +7 -1
  50. package/build/components/block-visibility/viewport-menu-item.cjs.map +2 -2
  51. package/build/components/block-visibility/viewport-toolbar.cjs +5 -0
  52. package/build/components/block-visibility/viewport-toolbar.cjs.map +2 -2
  53. package/build/components/block-visibility/viewport-visibility-info.cjs +5 -1
  54. package/build/components/block-visibility/viewport-visibility-info.cjs.map +2 -2
  55. package/build/components/border-radius-control/utils.cjs +8 -58
  56. package/build/components/border-radius-control/utils.cjs.map +2 -2
  57. package/build/components/child-layout-control/index.cjs +0 -4
  58. package/build/components/child-layout-control/index.cjs.map +2 -2
  59. package/build/components/colors-gradients/control.cjs +5 -3
  60. package/build/components/colors-gradients/control.cjs.map +2 -2
  61. package/build/components/dimension-control/index.cjs +30 -20
  62. package/build/components/dimension-control/index.cjs.map +3 -3
  63. package/build/components/dimensions-tool/aspect-ratio-tool.cjs +9 -2
  64. package/build/components/dimensions-tool/aspect-ratio-tool.cjs.map +3 -3
  65. package/build/components/editor-styles/index.cjs +9 -1
  66. package/build/components/editor-styles/index.cjs.map +2 -2
  67. package/build/components/global-styles/background-panel.cjs +66 -25
  68. package/build/components/global-styles/background-panel.cjs.map +3 -3
  69. package/build/components/global-styles/border-panel.cjs +153 -55
  70. package/build/components/global-styles/border-panel.cjs.map +3 -3
  71. package/build/components/global-styles/color-gradient-dropdown-item.cjs +46 -14
  72. package/build/components/global-styles/color-gradient-dropdown-item.cjs.map +3 -3
  73. package/build/components/global-styles/color-panel.cjs +63 -17
  74. package/build/components/global-styles/color-panel.cjs.map +2 -2
  75. package/build/components/global-styles/dimensions-panel.cjs +242 -64
  76. package/build/components/global-styles/dimensions-panel.cjs.map +3 -3
  77. package/build/components/global-styles/filters-panel.cjs +59 -20
  78. package/build/components/global-styles/filters-panel.cjs.map +3 -3
  79. package/build/components/global-styles/hooks.cjs +4 -1
  80. package/build/components/global-styles/hooks.cjs.map +2 -2
  81. package/build/components/global-styles/inheritance/index.cjs +142 -0
  82. package/build/components/global-styles/inheritance/index.cjs.map +7 -0
  83. package/build/components/global-styles/inherited-value-context.cjs +173 -0
  84. package/build/components/global-styles/inherited-value-context.cjs.map +7 -0
  85. package/build/components/global-styles/shadow-panel-components.cjs +38 -20
  86. package/build/components/global-styles/shadow-panel-components.cjs.map +2 -2
  87. package/build/components/global-styles/state-control-badges.cjs +39 -3
  88. package/build/components/global-styles/state-control-badges.cjs.map +2 -2
  89. package/build/components/global-styles/state-control.cjs +1 -1
  90. package/build/components/global-styles/state-control.cjs.map +2 -2
  91. package/build/components/global-styles/typography-panel.cjs +271 -79
  92. package/build/components/global-styles/typography-panel.cjs.map +3 -3
  93. package/build/components/image-size-control/index.cjs +2 -4
  94. package/build/components/image-size-control/index.cjs.map +2 -2
  95. package/build/components/inserter/media-tab/hooks.cjs +33 -6
  96. package/build/components/inserter/media-tab/hooks.cjs.map +2 -2
  97. package/build/components/inserter/media-tab/media-panel.cjs +78 -16
  98. package/build/components/inserter/media-tab/media-panel.cjs.map +3 -3
  99. package/build/components/inspector-controls-tabs/styles-tab.cjs +10 -1
  100. package/build/components/inspector-controls-tabs/styles-tab.cjs.map +2 -2
  101. package/build/components/keyboard-shortcuts/index.cjs +19 -11
  102. package/build/components/keyboard-shortcuts/index.cjs.map +2 -2
  103. package/build/components/line-height-control/index.cjs +1 -2
  104. package/build/components/line-height-control/index.cjs.map +2 -2
  105. package/build/components/link-control/index.cjs +3 -1
  106. package/build/components/link-control/index.cjs.map +2 -2
  107. package/build/components/list-view/block.cjs +13 -4
  108. package/build/components/list-view/block.cjs.map +2 -2
  109. package/build/components/media-placeholder/index.cjs +0 -1
  110. package/build/components/media-placeholder/index.cjs.map +2 -2
  111. package/build/components/preset-input-control/index.cjs +2 -1
  112. package/build/components/preset-input-control/index.cjs.map +2 -2
  113. package/build/components/provider/block-refs-provider.cjs +8 -2
  114. package/build/components/provider/block-refs-provider.cjs.map +2 -2
  115. package/build/components/provider/index.cjs +1 -1
  116. package/build/components/provider/index.cjs.map +2 -2
  117. package/build/components/provider/use-block-sync.cjs +18 -6
  118. package/build/components/provider/use-block-sync.cjs.map +2 -2
  119. package/build/components/provider/use-media-upload-settings.cjs +3 -1
  120. package/build/components/provider/use-media-upload-settings.cjs.map +2 -2
  121. package/build/components/rich-text/event-listeners/before-input-rules.cjs +3 -4
  122. package/build/components/rich-text/event-listeners/before-input-rules.cjs.map +3 -3
  123. package/build/components/rich-text/event-listeners/delete.cjs +2 -3
  124. package/build/components/rich-text/event-listeners/delete.cjs.map +3 -3
  125. package/build/components/rich-text/event-listeners/enter.cjs +3 -2
  126. package/build/components/rich-text/event-listeners/enter.cjs.map +3 -3
  127. package/build/components/rich-text/event-listeners/input-events.cjs +3 -3
  128. package/build/components/rich-text/event-listeners/input-events.cjs.map +3 -3
  129. package/build/components/rich-text/event-listeners/input-rules.cjs +3 -4
  130. package/build/components/rich-text/event-listeners/input-rules.cjs.map +3 -3
  131. package/build/components/rich-text/event-listeners/insert-replacement-text.cjs +3 -3
  132. package/build/components/rich-text/event-listeners/insert-replacement-text.cjs.map +3 -3
  133. package/build/components/rich-text/event-listeners/paste-handler.cjs +2 -1
  134. package/build/components/rich-text/event-listeners/paste-handler.cjs.map +3 -3
  135. package/build/components/rich-text/event-listeners/remove-browser-shortcuts.cjs +3 -3
  136. package/build/components/rich-text/event-listeners/remove-browser-shortcuts.cjs.map +3 -3
  137. package/build/components/rich-text/event-listeners/shortcuts.cjs +3 -3
  138. package/build/components/rich-text/event-listeners/shortcuts.cjs.map +3 -3
  139. package/build/components/rich-text/event-listeners/undo-automatic-change.cjs +3 -3
  140. package/build/components/rich-text/event-listeners/undo-automatic-change.cjs.map +3 -3
  141. package/build/components/rich-text/index.cjs +76 -17
  142. package/build/components/rich-text/index.cjs.map +2 -2
  143. package/build/components/spacing-sizes-control/utils.cjs +6 -19
  144. package/build/components/spacing-sizes-control/utils.cjs.map +2 -2
  145. package/build/components/text-indent-control/index.cjs +8 -2
  146. package/build/components/text-indent-control/index.cjs.map +2 -2
  147. package/build/components/typewriter/index.cjs +129 -136
  148. package/build/components/typewriter/index.cjs.map +3 -3
  149. package/build/components/url-input/index.cjs +303 -344
  150. package/build/components/url-input/index.cjs.map +3 -3
  151. package/build/components/use-block-commands/index.cjs +21 -17
  152. package/build/components/use-block-commands/index.cjs.map +2 -2
  153. package/build/components/use-on-block-drop/index.cjs +1 -1
  154. package/build/components/use-on-block-drop/index.cjs.map +2 -2
  155. package/build/components/writing-flow/index.cjs +14 -1
  156. package/build/components/writing-flow/index.cjs.map +3 -3
  157. package/build/components/writing-flow/use-arrow-nav.cjs +42 -6
  158. package/build/components/writing-flow/use-arrow-nav.cjs.map +2 -2
  159. package/build/components/writing-flow/use-click-selection.cjs +29 -3
  160. package/build/components/writing-flow/use-click-selection.cjs.map +2 -2
  161. package/build/components/writing-flow/use-clipboard-handler.cjs +4 -1
  162. package/build/components/writing-flow/use-clipboard-handler.cjs.map +2 -2
  163. package/build/components/writing-flow/use-drag-selection.cjs +3 -8
  164. package/build/components/writing-flow/use-drag-selection.cjs.map +2 -2
  165. package/build/components/writing-flow/use-editable-root-event-handlers.cjs +179 -0
  166. package/build/components/writing-flow/use-editable-root-event-handlers.cjs.map +7 -0
  167. package/build/components/writing-flow/use-editable-root.cjs +75 -0
  168. package/build/components/writing-flow/use-editable-root.cjs.map +7 -0
  169. package/build/components/writing-flow/use-home-end.cjs +64 -0
  170. package/build/components/writing-flow/use-home-end.cjs.map +7 -0
  171. package/build/components/writing-flow/use-input.cjs +15 -5
  172. package/build/components/writing-flow/use-input.cjs.map +2 -2
  173. package/build/components/writing-flow/use-multi-selection.cjs +2 -2
  174. package/build/components/writing-flow/use-multi-selection.cjs.map +2 -2
  175. package/build/components/writing-flow/use-select-all.cjs +14 -2
  176. package/build/components/writing-flow/use-select-all.cjs.map +2 -2
  177. package/build/components/writing-flow/use-selection-observer.cjs +132 -22
  178. package/build/components/writing-flow/use-selection-observer.cjs.map +3 -3
  179. package/build/components/writing-flow/utils.cjs +28 -2
  180. package/build/components/writing-flow/utils.cjs.map +2 -2
  181. package/build/hooks/background.cjs +14 -10
  182. package/build/hooks/background.cjs.map +2 -2
  183. package/build/hooks/block-fields/rich-text/index.cjs +2 -3
  184. package/build/hooks/block-fields/rich-text/index.cjs.map +3 -3
  185. package/build/hooks/block-style-variation.cjs +4 -45
  186. package/build/hooks/block-style-variation.cjs.map +3 -3
  187. package/build/hooks/border.cjs +19 -4
  188. package/build/hooks/border.cjs.map +2 -2
  189. package/build/hooks/custom-css.cjs +6 -2
  190. package/build/hooks/custom-css.cjs.map +2 -2
  191. package/build/hooks/dimensions.cjs +15 -4
  192. package/build/hooks/dimensions.cjs.map +2 -2
  193. package/build/hooks/duotone.cjs +26 -14
  194. package/build/hooks/duotone.cjs.map +3 -3
  195. package/build/hooks/elements.cjs +15 -5
  196. package/build/hooks/elements.cjs.map +2 -2
  197. package/build/hooks/grid-visualizer.cjs +5 -3
  198. package/build/hooks/grid-visualizer.cjs.map +2 -2
  199. package/build/hooks/layout-child.cjs +22 -12
  200. package/build/hooks/layout-child.cjs.map +3 -3
  201. package/build/hooks/layout.cjs +28 -13
  202. package/build/hooks/layout.cjs.map +3 -3
  203. package/build/hooks/line-height.cjs +1 -2
  204. package/build/hooks/line-height.cjs.map +2 -2
  205. package/build/hooks/states.cjs +27 -7
  206. package/build/hooks/states.cjs.map +3 -3
  207. package/build/hooks/style.cjs +31 -9
  208. package/build/hooks/style.cjs.map +3 -3
  209. package/build/hooks/text-align.cjs +36 -6
  210. package/build/hooks/text-align.cjs.map +3 -3
  211. package/build/hooks/typography.cjs +14 -5
  212. package/build/hooks/typography.cjs.map +2 -2
  213. package/build/layouts/constrained.cjs +14 -6
  214. package/build/layouts/constrained.cjs.map +2 -2
  215. package/build/layouts/flex.cjs +27 -19
  216. package/build/layouts/flex.cjs.map +2 -2
  217. package/build/layouts/grid.cjs +0 -2
  218. package/build/layouts/grid.cjs.map +2 -2
  219. package/build/private-apis.cjs +9 -5
  220. package/build/private-apis.cjs.map +3 -3
  221. package/build/store/actions.cjs +11 -6
  222. package/build/store/actions.cjs.map +2 -2
  223. package/build/store/private-selectors.cjs +41 -3
  224. package/build/store/private-selectors.cjs.map +3 -3
  225. package/build/store/reducer.cjs +6 -6
  226. package/build/store/reducer.cjs.map +2 -2
  227. package/build/store/selectors.cjs +23 -0
  228. package/build/store/selectors.cjs.map +2 -2
  229. package/build/utils/block-bindings.cjs +29 -0
  230. package/build/utils/block-bindings.cjs.map +2 -2
  231. package/build/utils/dom.cjs +14 -0
  232. package/build/utils/dom.cjs.map +2 -2
  233. package/build/{components/rich-text/input-event.cjs → utils/native-undo.cjs} +29 -24
  234. package/build/utils/native-undo.cjs.map +7 -0
  235. package/build-module/components/alignment-control/ui.mjs +2 -4
  236. package/build-module/components/alignment-control/ui.mjs.map +2 -2
  237. package/build-module/components/background-image-control/index.mjs +43 -10
  238. package/build-module/components/background-image-control/index.mjs.map +2 -2
  239. package/build-module/components/block-alignment-control/ui.mjs +5 -3
  240. package/build-module/components/block-alignment-control/ui.mjs.map +2 -2
  241. package/build-module/components/block-canvas/index.mjs +7 -2
  242. package/build-module/components/block-canvas/index.mjs.map +2 -2
  243. package/build-module/components/block-controls/groups.mjs +3 -1
  244. package/build-module/components/block-controls/groups.mjs.map +2 -2
  245. package/build-module/components/block-edit/edit.mjs +11 -18
  246. package/build-module/components/block-edit/edit.mjs.map +2 -2
  247. package/build-module/components/block-inspector/index.mjs +74 -46
  248. package/build-module/components/block-inspector/index.mjs.map +2 -2
  249. package/build-module/components/block-list/block-html.mjs +4 -1
  250. package/build-module/components/block-list/block-html.mjs.map +2 -2
  251. package/build-module/components/block-list/block.mjs +9 -3
  252. package/build-module/components/block-list/block.mjs.map +3 -3
  253. package/build-module/components/block-list/index.mjs +1 -3
  254. package/build-module/components/block-list/index.mjs.map +2 -2
  255. package/build-module/components/block-list/use-block-props/index.mjs +7 -2
  256. package/build-module/components/block-list/use-block-props/index.mjs.map +2 -2
  257. package/build-module/components/block-list/use-block-props/use-focus-first-element.mjs +9 -4
  258. package/build-module/components/block-list/use-block-props/use-focus-first-element.mjs.map +2 -2
  259. package/build-module/components/block-list/use-block-props/use-focus-handler.mjs +11 -4
  260. package/build-module/components/block-list/use-block-props/use-focus-handler.mjs.map +2 -2
  261. package/build-module/components/block-list/use-block-props/use-register-block-event-handlers.mjs +28 -0
  262. package/build-module/components/block-list/use-block-props/use-register-block-event-handlers.mjs.map +7 -0
  263. package/build-module/components/block-parent-selector/index.mjs +2 -2
  264. package/build-module/components/block-parent-selector/index.mjs.map +2 -2
  265. package/build-module/components/block-toolbar/index.mjs +43 -24
  266. package/build-module/components/block-toolbar/index.mjs.map +2 -2
  267. package/build-module/components/block-toolbar/switch-section-style.mjs +4 -2
  268. package/build-module/components/block-toolbar/switch-section-style.mjs.map +2 -2
  269. package/build-module/components/block-tools/empty-block-inserter.mjs +2 -7
  270. package/build-module/components/block-tools/empty-block-inserter.mjs.map +2 -2
  271. package/build-module/components/block-tools/index.mjs +7 -2
  272. package/build-module/components/block-tools/index.mjs.map +2 -2
  273. package/build-module/components/block-vertical-alignment-control/ui.mjs +4 -6
  274. package/build-module/components/block-vertical-alignment-control/ui.mjs.map +2 -2
  275. package/build-module/components/block-visibility/modal.mjs +22 -10
  276. package/build-module/components/block-visibility/modal.mjs.map +2 -2
  277. package/build-module/components/block-visibility/use-block-visibility.mjs +17 -7
  278. package/build-module/components/block-visibility/use-block-visibility.mjs.map +2 -2
  279. package/build-module/components/block-visibility/utils.mjs +18 -3
  280. package/build-module/components/block-visibility/utils.mjs.map +2 -2
  281. package/build-module/components/block-visibility/viewport-menu-item.mjs +7 -1
  282. package/build-module/components/block-visibility/viewport-menu-item.mjs.map +2 -2
  283. package/build-module/components/block-visibility/viewport-toolbar.mjs +5 -0
  284. package/build-module/components/block-visibility/viewport-toolbar.mjs.map +2 -2
  285. package/build-module/components/block-visibility/viewport-visibility-info.mjs +5 -1
  286. package/build-module/components/block-visibility/viewport-visibility-info.mjs.map +2 -2
  287. package/build-module/components/border-radius-control/utils.mjs +11 -53
  288. package/build-module/components/border-radius-control/utils.mjs.map +2 -2
  289. package/build-module/components/child-layout-control/index.mjs +0 -4
  290. package/build-module/components/child-layout-control/index.mjs.map +2 -2
  291. package/build-module/components/colors-gradients/control.mjs +5 -3
  292. package/build-module/components/colors-gradients/control.mjs.map +2 -2
  293. package/build-module/components/dimension-control/index.mjs +30 -20
  294. package/build-module/components/dimension-control/index.mjs.map +2 -2
  295. package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs +10 -6
  296. package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs.map +2 -2
  297. package/build-module/components/editor-styles/index.mjs +9 -1
  298. package/build-module/components/editor-styles/index.mjs.map +2 -2
  299. package/build-module/components/global-styles/background-panel.mjs +71 -29
  300. package/build-module/components/global-styles/background-panel.mjs.map +2 -2
  301. package/build-module/components/global-styles/border-panel.mjs +157 -56
  302. package/build-module/components/global-styles/border-panel.mjs.map +2 -2
  303. package/build-module/components/global-styles/color-gradient-dropdown-item.mjs +51 -15
  304. package/build-module/components/global-styles/color-gradient-dropdown-item.mjs.map +2 -2
  305. package/build-module/components/global-styles/color-panel.mjs +63 -17
  306. package/build-module/components/global-styles/color-panel.mjs.map +2 -2
  307. package/build-module/components/global-styles/dimensions-panel.mjs +248 -66
  308. package/build-module/components/global-styles/dimensions-panel.mjs.map +2 -2
  309. package/build-module/components/global-styles/filters-panel.mjs +64 -21
  310. package/build-module/components/global-styles/filters-panel.mjs.map +2 -2
  311. package/build-module/components/global-styles/hooks.mjs +4 -1
  312. package/build-module/components/global-styles/hooks.mjs.map +2 -2
  313. package/build-module/components/global-styles/inheritance/index.mjs +108 -0
  314. package/build-module/components/global-styles/inheritance/index.mjs.map +7 -0
  315. package/build-module/components/global-styles/inherited-value-context.mjs +141 -0
  316. package/build-module/components/global-styles/inherited-value-context.mjs.map +7 -0
  317. package/build-module/components/global-styles/shadow-panel-components.mjs +38 -20
  318. package/build-module/components/global-styles/shadow-panel-components.mjs.map +2 -2
  319. package/build-module/components/global-styles/state-control-badges.mjs +41 -5
  320. package/build-module/components/global-styles/state-control-badges.mjs.map +2 -2
  321. package/build-module/components/global-styles/state-control.mjs +1 -1
  322. package/build-module/components/global-styles/state-control.mjs.map +2 -2
  323. package/build-module/components/global-styles/typography-panel.mjs +276 -80
  324. package/build-module/components/global-styles/typography-panel.mjs.map +2 -2
  325. package/build-module/components/image-size-control/index.mjs +2 -4
  326. package/build-module/components/image-size-control/index.mjs.map +2 -2
  327. package/build-module/components/inserter/media-tab/hooks.mjs +33 -6
  328. package/build-module/components/inserter/media-tab/hooks.mjs.map +2 -2
  329. package/build-module/components/inserter/media-tab/media-panel.mjs +86 -18
  330. package/build-module/components/inserter/media-tab/media-panel.mjs.map +2 -2
  331. package/build-module/components/inspector-controls-tabs/styles-tab.mjs +6 -1
  332. package/build-module/components/inspector-controls-tabs/styles-tab.mjs.map +2 -2
  333. package/build-module/components/keyboard-shortcuts/index.mjs +19 -11
  334. package/build-module/components/keyboard-shortcuts/index.mjs.map +2 -2
  335. package/build-module/components/line-height-control/index.mjs +1 -2
  336. package/build-module/components/line-height-control/index.mjs.map +2 -2
  337. package/build-module/components/link-control/index.mjs +4 -2
  338. package/build-module/components/link-control/index.mjs.map +2 -2
  339. package/build-module/components/list-view/block.mjs +13 -4
  340. package/build-module/components/list-view/block.mjs.map +2 -2
  341. package/build-module/components/media-placeholder/index.mjs +0 -1
  342. package/build-module/components/media-placeholder/index.mjs.map +2 -2
  343. package/build-module/components/preset-input-control/index.mjs +2 -1
  344. package/build-module/components/preset-input-control/index.mjs.map +2 -2
  345. package/build-module/components/provider/block-refs-provider.mjs +8 -2
  346. package/build-module/components/provider/block-refs-provider.mjs.map +2 -2
  347. package/build-module/components/provider/index.mjs +1 -1
  348. package/build-module/components/provider/index.mjs.map +2 -2
  349. package/build-module/components/provider/use-block-sync.mjs +18 -6
  350. package/build-module/components/provider/use-block-sync.mjs.map +2 -2
  351. package/build-module/components/provider/use-media-upload-settings.mjs +3 -1
  352. package/build-module/components/provider/use-media-upload-settings.mjs.map +2 -2
  353. package/build-module/components/rich-text/event-listeners/before-input-rules.mjs +8 -5
  354. package/build-module/components/rich-text/event-listeners/before-input-rules.mjs.map +2 -2
  355. package/build-module/components/rich-text/event-listeners/delete.mjs +7 -4
  356. package/build-module/components/rich-text/event-listeners/delete.mjs.map +2 -2
  357. package/build-module/components/rich-text/event-listeners/enter.mjs +8 -3
  358. package/build-module/components/rich-text/event-listeners/enter.mjs.map +2 -2
  359. package/build-module/components/rich-text/event-listeners/input-events.mjs +3 -3
  360. package/build-module/components/rich-text/event-listeners/input-events.mjs.map +2 -2
  361. package/build-module/components/rich-text/event-listeners/input-rules.mjs +8 -5
  362. package/build-module/components/rich-text/event-listeners/input-rules.mjs.map +2 -2
  363. package/build-module/components/rich-text/event-listeners/insert-replacement-text.mjs +3 -3
  364. package/build-module/components/rich-text/event-listeners/insert-replacement-text.mjs.map +2 -2
  365. package/build-module/components/rich-text/event-listeners/paste-handler.mjs +8 -2
  366. package/build-module/components/rich-text/event-listeners/paste-handler.mjs.map +2 -2
  367. package/build-module/components/rich-text/event-listeners/remove-browser-shortcuts.mjs +3 -3
  368. package/build-module/components/rich-text/event-listeners/remove-browser-shortcuts.mjs.map +2 -2
  369. package/build-module/components/rich-text/event-listeners/shortcuts.mjs +3 -3
  370. package/build-module/components/rich-text/event-listeners/shortcuts.mjs.map +2 -2
  371. package/build-module/components/rich-text/event-listeners/undo-automatic-change.mjs +3 -3
  372. package/build-module/components/rich-text/event-listeners/undo-automatic-change.mjs.map +2 -2
  373. package/build-module/components/rich-text/index.mjs +79 -14
  374. package/build-module/components/rich-text/index.mjs.map +2 -2
  375. package/build-module/components/spacing-sizes-control/utils.mjs +6 -18
  376. package/build-module/components/spacing-sizes-control/utils.mjs.map +2 -2
  377. package/build-module/components/text-indent-control/index.mjs +8 -2
  378. package/build-module/components/text-indent-control/index.mjs.map +2 -2
  379. package/build-module/components/typewriter/index.mjs +129 -136
  380. package/build-module/components/typewriter/index.mjs.map +2 -2
  381. package/build-module/components/url-input/index.mjs +306 -353
  382. package/build-module/components/url-input/index.mjs.map +2 -2
  383. package/build-module/components/use-block-commands/index.mjs +21 -17
  384. package/build-module/components/use-block-commands/index.mjs.map +2 -2
  385. package/build-module/components/use-on-block-drop/index.mjs +2 -2
  386. package/build-module/components/use-on-block-drop/index.mjs.map +2 -2
  387. package/build-module/components/writing-flow/index.mjs +14 -1
  388. package/build-module/components/writing-flow/index.mjs.map +2 -2
  389. package/build-module/components/writing-flow/use-arrow-nav.mjs +43 -7
  390. package/build-module/components/writing-flow/use-arrow-nav.mjs.map +2 -2
  391. package/build-module/components/writing-flow/use-click-selection.mjs +29 -3
  392. package/build-module/components/writing-flow/use-click-selection.mjs.map +2 -2
  393. package/build-module/components/writing-flow/use-clipboard-handler.mjs +5 -2
  394. package/build-module/components/writing-flow/use-clipboard-handler.mjs.map +2 -2
  395. package/build-module/components/writing-flow/use-drag-selection.mjs +1 -6
  396. package/build-module/components/writing-flow/use-drag-selection.mjs.map +2 -2
  397. package/build-module/components/writing-flow/use-editable-root-event-handlers.mjs +154 -0
  398. package/build-module/components/writing-flow/use-editable-root-event-handlers.mjs.map +7 -0
  399. package/build-module/components/writing-flow/use-editable-root.mjs +54 -0
  400. package/build-module/components/writing-flow/use-editable-root.mjs.map +7 -0
  401. package/build-module/components/writing-flow/use-home-end.mjs +43 -0
  402. package/build-module/components/writing-flow/use-home-end.mjs.map +7 -0
  403. package/build-module/components/writing-flow/use-input.mjs +15 -5
  404. package/build-module/components/writing-flow/use-input.mjs.map +2 -2
  405. package/build-module/components/writing-flow/use-multi-selection.mjs +2 -2
  406. package/build-module/components/writing-flow/use-multi-selection.mjs.map +2 -2
  407. package/build-module/components/writing-flow/use-select-all.mjs +19 -3
  408. package/build-module/components/writing-flow/use-select-all.mjs.map +2 -2
  409. package/build-module/components/writing-flow/use-selection-observer.mjs +134 -21
  410. package/build-module/components/writing-flow/use-selection-observer.mjs.map +2 -2
  411. package/build-module/components/writing-flow/utils.mjs +26 -1
  412. package/build-module/components/writing-flow/utils.mjs.map +2 -2
  413. package/build-module/hooks/background.mjs +14 -10
  414. package/build-module/hooks/background.mjs.map +2 -2
  415. package/build-module/hooks/block-fields/rich-text/index.mjs +2 -6
  416. package/build-module/hooks/block-fields/rich-text/index.mjs.map +2 -2
  417. package/build-module/hooks/block-style-variation.mjs +8 -44
  418. package/build-module/hooks/block-style-variation.mjs.map +2 -2
  419. package/build-module/hooks/border.mjs +19 -4
  420. package/build-module/hooks/border.mjs.map +2 -2
  421. package/build-module/hooks/custom-css.mjs +7 -3
  422. package/build-module/hooks/custom-css.mjs.map +2 -2
  423. package/build-module/hooks/dimensions.mjs +15 -4
  424. package/build-module/hooks/dimensions.mjs.map +2 -2
  425. package/build-module/hooks/duotone.mjs +20 -9
  426. package/build-module/hooks/duotone.mjs.map +2 -2
  427. package/build-module/hooks/elements.mjs +15 -5
  428. package/build-module/hooks/elements.mjs.map +2 -2
  429. package/build-module/hooks/grid-visualizer.mjs +5 -3
  430. package/build-module/hooks/grid-visualizer.mjs.map +2 -2
  431. package/build-module/hooks/layout-child.mjs +22 -12
  432. package/build-module/hooks/layout-child.mjs.map +2 -2
  433. package/build-module/hooks/layout.mjs +28 -13
  434. package/build-module/hooks/layout.mjs.map +2 -2
  435. package/build-module/hooks/line-height.mjs +1 -2
  436. package/build-module/hooks/line-height.mjs.map +2 -2
  437. package/build-module/hooks/states.mjs +27 -7
  438. package/build-module/hooks/states.mjs.map +2 -2
  439. package/build-module/hooks/style.mjs +40 -11
  440. package/build-module/hooks/style.mjs.map +2 -2
  441. package/build-module/hooks/text-align.mjs +39 -10
  442. package/build-module/hooks/text-align.mjs.map +2 -2
  443. package/build-module/hooks/typography.mjs +14 -5
  444. package/build-module/hooks/typography.mjs.map +2 -2
  445. package/build-module/layouts/constrained.mjs +14 -6
  446. package/build-module/layouts/constrained.mjs.map +2 -2
  447. package/build-module/layouts/flex.mjs +27 -19
  448. package/build-module/layouts/flex.mjs.map +2 -2
  449. package/build-module/layouts/grid.mjs +0 -2
  450. package/build-module/layouts/grid.mjs.map +2 -2
  451. package/build-module/private-apis.mjs +7 -3
  452. package/build-module/private-apis.mjs.map +2 -2
  453. package/build-module/store/actions.mjs +12 -7
  454. package/build-module/store/actions.mjs.map +2 -2
  455. package/build-module/store/private-selectors.mjs +42 -3
  456. package/build-module/store/private-selectors.mjs.map +2 -2
  457. package/build-module/store/reducer.mjs +6 -6
  458. package/build-module/store/reducer.mjs.map +2 -2
  459. package/build-module/store/selectors.mjs +23 -0
  460. package/build-module/store/selectors.mjs.map +2 -2
  461. package/build-module/utils/block-bindings.mjs +28 -0
  462. package/build-module/utils/block-bindings.mjs.map +2 -2
  463. package/build-module/utils/dom.mjs +13 -0
  464. package/build-module/utils/dom.mjs.map +2 -2
  465. package/build-module/utils/native-undo.mjs +29 -0
  466. package/build-module/utils/native-undo.mjs.map +7 -0
  467. package/build-style/content-rtl.css +14 -27
  468. package/build-style/content.css +14 -27
  469. package/build-style/default-editor-styles-rtl.css +1 -1
  470. package/build-style/default-editor-styles.css +1 -1
  471. package/build-style/style-rtl.css +191 -61
  472. package/build-style/style.css +191 -61
  473. package/build-types/components/block-context/index.d.ts +7 -0
  474. package/build-types/components/block-context/index.d.ts.map +1 -1
  475. package/build-types/utils/block-bindings.d.ts +19 -0
  476. package/build-types/utils/block-bindings.d.ts.map +1 -1
  477. package/build-types/utils/dom.d.ts +11 -0
  478. package/build-types/utils/dom.d.ts.map +1 -1
  479. package/build-types/utils/get-px-from-css-unit.d.ts +2 -2
  480. package/build-types/utils/get-px-from-css-unit.d.ts.map +1 -1
  481. package/build-types/utils/pasting.d.ts +1 -1
  482. package/build-types/utils/pasting.d.ts.map +1 -1
  483. package/package.json +43 -44
  484. package/src/components/alignment-control/test/__snapshots__/index.js.snap +1 -1
  485. package/src/components/alignment-control/ui.js +2 -4
  486. package/src/components/background-image-control/index.js +74 -37
  487. package/src/components/background-image-control/style.scss +13 -4
  488. package/src/components/block-alignment-control/test/__snapshots__/index.js.snap +3 -3
  489. package/src/components/block-alignment-control/test/index.js +1 -1
  490. package/src/components/block-alignment-control/ui.js +4 -2
  491. package/src/components/block-breadcrumb/test/__snapshots__/index.js.snap +1 -1
  492. package/src/components/block-canvas/index.js +9 -2
  493. package/src/components/block-card/style.scss +1 -1
  494. package/src/components/block-compare/test/__snapshots__/block-view.js.snap +1 -1
  495. package/src/components/block-controls/groups.js +2 -0
  496. package/src/components/block-edit/edit.js +13 -31
  497. package/src/components/block-icon/test/__snapshots__/index.js.snap +1 -1
  498. package/src/components/block-inspector/index.js +60 -31
  499. package/src/components/block-list/block-html.js +5 -0
  500. package/src/components/block-list/block.js +6 -0
  501. package/src/components/block-list/content.scss +1 -11
  502. package/src/components/block-list/index.js +0 -2
  503. package/src/components/block-list/use-block-props/index.js +7 -1
  504. package/src/components/block-list/use-block-props/use-focus-first-element.js +23 -4
  505. package/src/components/block-list/use-block-props/use-focus-handler.js +35 -9
  506. package/src/components/block-list/use-block-props/use-register-block-event-handlers.js +45 -0
  507. package/src/components/block-lock/style.scss +1 -1
  508. package/src/components/block-manager/style.scss +1 -1
  509. package/src/components/block-navigation/style.scss +1 -1
  510. package/src/components/block-parent-selector/index.js +5 -2
  511. package/src/components/block-quick-navigation/style.scss +1 -3
  512. package/src/components/block-styles/style.scss +2 -2
  513. package/src/components/block-toolbar/index.js +41 -18
  514. package/src/components/block-toolbar/switch-section-style.js +5 -2
  515. package/src/components/block-tools/empty-block-inserter.js +3 -7
  516. package/src/components/block-tools/index.js +7 -0
  517. package/src/components/block-types-list/style.scss +0 -1
  518. package/src/components/block-vertical-alignment-control/test/__snapshots__/index.js.snap +3 -3
  519. package/src/components/block-vertical-alignment-control/test/index.js +18 -2
  520. package/src/components/block-vertical-alignment-control/ui.js +3 -5
  521. package/src/components/block-visibility/modal.js +24 -10
  522. package/src/components/block-visibility/style.scss +1 -1
  523. package/src/components/block-visibility/test/use-block-visibility.js +128 -35
  524. package/src/components/block-visibility/test/utils.js +11 -0
  525. package/src/components/block-visibility/use-block-visibility.js +33 -11
  526. package/src/components/block-visibility/utils.js +31 -6
  527. package/src/components/block-visibility/viewport-menu-item.js +10 -1
  528. package/src/components/block-visibility/viewport-toolbar.js +6 -0
  529. package/src/components/block-visibility/viewport-visibility-info.js +5 -1
  530. package/src/components/border-radius-control/test/utils.js +0 -41
  531. package/src/components/border-radius-control/utils.js +16 -107
  532. package/src/components/button-block-appender/content.scss +7 -9
  533. package/src/components/child-layout-control/index.js +0 -4
  534. package/src/components/color-palette/test/__snapshots__/control.js.snap +3 -3
  535. package/src/components/colors-gradients/control.js +6 -3
  536. package/src/components/default-block-appender/test/__snapshots__/index.js.snap +1 -1
  537. package/src/components/dimension-control/index.js +13 -1
  538. package/src/components/dimensions-tool/aspect-ratio-tool.js +13 -6
  539. package/src/components/editor-styles/index.js +16 -1
  540. package/src/components/font-family/stories/index.story.jsx +1 -1
  541. package/src/components/global-styles/background-panel.js +107 -34
  542. package/src/components/global-styles/border-panel.js +219 -48
  543. package/src/components/global-styles/color-gradient-dropdown-item.js +93 -28
  544. package/src/components/global-styles/color-panel.js +92 -11
  545. package/src/components/global-styles/dimensions-panel.js +422 -71
  546. package/src/components/global-styles/filters-panel.js +88 -28
  547. package/src/components/global-styles/hooks.js +8 -1
  548. package/src/components/global-styles/inheritance/index.js +204 -0
  549. package/src/components/global-styles/inheritance/style.scss +184 -0
  550. package/src/components/global-styles/inheritance/test/index.js +281 -0
  551. package/src/components/global-styles/inherited-value-context.js +271 -0
  552. package/src/components/global-styles/shadow-panel-components.js +48 -26
  553. package/src/components/global-styles/state-control-badges.js +45 -6
  554. package/src/components/global-styles/state-control.js +2 -2
  555. package/src/components/global-styles/style.scss +5 -0
  556. package/src/components/global-styles/test/background-panel.js +338 -1
  557. package/src/components/global-styles/test/border-panel.js +441 -0
  558. package/src/components/global-styles/test/color-panel.js +182 -2
  559. package/src/components/global-styles/test/dimensions-panel.js +753 -0
  560. package/src/components/global-styles/test/filters-panel.js +194 -0
  561. package/src/components/global-styles/test/inherited-value-context-core.js +98 -0
  562. package/src/components/global-styles/test/inherited-value-context.js +454 -0
  563. package/src/components/global-styles/test/state-control-badges.js +65 -0
  564. package/src/components/global-styles/test/typography-panel-core.js +185 -0
  565. package/src/components/global-styles/test/typography-panel.js +849 -12
  566. package/src/components/global-styles/typography-panel.js +449 -101
  567. package/src/components/image-editor/style.scss +33 -0
  568. package/src/components/image-size-control/index.js +0 -2
  569. package/src/components/inner-blocks/test/__snapshots__/index.js.snap +1 -1
  570. package/src/components/inserter/media-tab/hooks.js +55 -7
  571. package/src/components/inserter/media-tab/media-panel.js +117 -21
  572. package/src/components/inserter/media-tab/test/hooks.js +63 -0
  573. package/src/components/inserter/media-tab/test/media-panel.js +127 -0
  574. package/src/components/inserter/style.scss +19 -16
  575. package/src/components/inserter-list-item/style.scss +0 -15
  576. package/src/components/inspector-controls-tabs/styles-tab.js +5 -1
  577. package/src/components/keyboard-shortcuts/index.js +28 -11
  578. package/src/components/line-height-control/index.js +1 -2
  579. package/src/components/link-control/index.js +7 -2
  580. package/src/components/link-control/style.scss +2 -2
  581. package/src/components/link-control/test/index.js +6 -6
  582. package/src/components/link-picker/style.scss +1 -2
  583. package/src/components/list-view/block.js +13 -4
  584. package/src/components/list-view/style.scss +4 -5
  585. package/src/components/media-placeholder/index.js +0 -1
  586. package/src/components/multi-selection-inspector/style.scss +1 -1
  587. package/src/components/preset-input-control/index.js +4 -1
  588. package/src/components/provider/block-refs-provider.js +12 -2
  589. package/src/components/provider/index.js +2 -2
  590. package/src/components/provider/use-block-sync.js +18 -6
  591. package/src/components/provider/use-media-upload-settings.js +2 -0
  592. package/src/components/responsive-block-control/style.scss +1 -1
  593. package/src/components/rich-text/event-listeners/before-input-rules.js +8 -5
  594. package/src/components/rich-text/event-listeners/delete.js +7 -4
  595. package/src/components/rich-text/event-listeners/enter.js +10 -4
  596. package/src/components/rich-text/event-listeners/input-events.js +4 -3
  597. package/src/components/rich-text/event-listeners/input-rules.js +8 -5
  598. package/src/components/rich-text/event-listeners/insert-replacement-text.js +4 -3
  599. package/src/components/rich-text/event-listeners/paste-handler.js +15 -3
  600. package/src/components/rich-text/event-listeners/remove-browser-shortcuts.js +4 -3
  601. package/src/components/rich-text/event-listeners/shortcuts.js +4 -3
  602. package/src/components/rich-text/event-listeners/undo-automatic-change.js +4 -3
  603. package/src/components/rich-text/index.js +116 -26
  604. package/src/components/skip-to-selected-block/style.scss +1 -1
  605. package/src/components/spacing-sizes-control/test/utils.js +16 -5
  606. package/src/components/spacing-sizes-control/utils.js +11 -28
  607. package/src/components/text-indent-control/index.js +8 -0
  608. package/src/components/typewriter/index.js +228 -224
  609. package/src/components/url-input/index.js +363 -431
  610. package/src/components/url-input/test/index.js +592 -0
  611. package/src/components/use-block-commands/index.js +27 -17
  612. package/src/components/use-on-block-drop/index.js +2 -2
  613. package/src/components/warning/test/__snapshots__/index.js.snap +1 -1
  614. package/src/components/writing-flow/index.js +17 -1
  615. package/src/components/writing-flow/use-arrow-nav.js +90 -13
  616. package/src/components/writing-flow/use-click-selection.js +55 -5
  617. package/src/components/writing-flow/use-clipboard-handler.js +5 -2
  618. package/src/components/writing-flow/use-drag-selection.js +1 -14
  619. package/src/components/writing-flow/use-editable-root-event-handlers.js +266 -0
  620. package/src/components/writing-flow/use-editable-root.js +112 -0
  621. package/src/components/writing-flow/use-home-end.js +71 -0
  622. package/src/components/writing-flow/use-input.js +25 -8
  623. package/src/components/writing-flow/use-multi-selection.js +2 -3
  624. package/src/components/writing-flow/use-select-all.js +33 -3
  625. package/src/components/writing-flow/use-selection-observer.js +218 -42
  626. package/src/components/writing-flow/utils.js +62 -0
  627. package/src/hooks/background.js +27 -24
  628. package/src/hooks/block-fields/link/styles.scss +1 -6
  629. package/src/hooks/block-fields/media/styles.scss +1 -6
  630. package/src/hooks/block-fields/rich-text/index.js +6 -9
  631. package/src/hooks/block-fields/rich-text/styles.scss +1 -1
  632. package/src/hooks/block-style-variation.js +8 -74
  633. package/src/hooks/border.js +19 -4
  634. package/src/hooks/custom-css.js +15 -6
  635. package/src/hooks/dimensions.js +17 -4
  636. package/src/hooks/duotone.js +26 -8
  637. package/src/hooks/elements.js +14 -4
  638. package/src/hooks/grid-visualizer.js +40 -36
  639. package/src/hooks/layout-child.js +19 -9
  640. package/src/hooks/layout.js +48 -31
  641. package/src/hooks/line-height.js +0 -1
  642. package/src/hooks/states.js +38 -9
  643. package/src/hooks/style.js +67 -17
  644. package/src/hooks/test/inherited-value-wiring.js +411 -0
  645. package/src/hooks/test/preset-round-trip.js +456 -0
  646. package/src/hooks/test/style.js +29 -0
  647. package/src/hooks/test/text-align.js +34 -1
  648. package/src/hooks/text-align.js +41 -10
  649. package/src/hooks/typography.js +35 -24
  650. package/src/layouts/constrained.js +5 -1
  651. package/src/layouts/flex.js +5 -1
  652. package/src/layouts/grid.js +0 -2
  653. package/src/private-apis.js +11 -2
  654. package/src/store/actions.js +53 -19
  655. package/src/store/private-selectors.js +82 -6
  656. package/src/store/reducer.js +9 -9
  657. package/src/store/selectors.js +56 -8
  658. package/src/store/test/actions.js +1 -1
  659. package/src/store/test/private-selectors.js +271 -1
  660. package/src/style.scss +2 -0
  661. package/src/utils/block-bindings.ts +50 -0
  662. package/src/utils/dom.ts +33 -0
  663. package/src/utils/native-undo.js +56 -0
  664. package/src/utils/test/block-bindings.js +181 -0
  665. package/build/components/duotone/utils.cjs +0 -87
  666. package/build/components/duotone/utils.cjs.map +0 -7
  667. package/build/components/rich-text/input-event.cjs.map +0 -7
  668. package/build/components/rich-text/shortcut.cjs +0 -51
  669. package/build/components/rich-text/shortcut.cjs.map +0 -7
  670. package/build-module/components/duotone/utils.mjs +0 -59
  671. package/build-module/components/duotone/utils.mjs.map +0 -7
  672. package/build-module/components/rich-text/input-event.mjs +0 -25
  673. package/build-module/components/rich-text/input-event.mjs.map +0 -7
  674. package/build-module/components/rich-text/shortcut.mjs +0 -26
  675. package/build-module/components/rich-text/shortcut.mjs.map +0 -7
  676. package/src/components/duotone/utils.js +0 -90
  677. package/src/components/rich-text/input-event.js +0 -31
  678. package/src/components/rich-text/shortcut.js +0 -32
  679. package/src/hooks/test/get-variation-styles-with-ref-values.js +0 -91
@@ -1,14 +1,670 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { renderHook, screen } from '@testing-library/react';
5
- import { click, render } from '@ariakit/test/react';
4
+ import { act, render, renderHook, screen } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
6
+ import { click, render as renderAriakit } from '@ariakit/test/react';
6
7
 
7
8
  /**
8
9
  * Internal dependencies
9
10
  */
10
11
  import TypographyPanel, { useHasTypographyPanel } from '../typography-panel';
11
12
 
13
+ // The inheritance treatment sits behind the
14
+ // `gutenberg-global-styles-inheritance-ui` experiment. Turn it on so these
15
+ // tests exercise the inheriting path. The off path lives in
16
+ // `typography-panel-core.js`.
17
+ beforeEach( () => {
18
+ window.__experimentalGlobalStylesInheritanceUI = true;
19
+ } );
20
+
21
+ afterEach( () => {
22
+ delete window.__experimentalGlobalStylesInheritanceUI;
23
+ } );
24
+
25
+ /**
26
+ * Render helper that flushes async state effects from Ariakit-based
27
+ * controls (CustomSelectControl, FontAppearanceControl, FontFamily) so
28
+ * tests don't trip the strict `console.error` rule on
29
+ * "An update to %s inside a test was not wrapped in act(...)".
30
+ *
31
+ * The first microtask flush handles Ariakit's `useLayoutEffect`-driven
32
+ * state updates that cannot be wrapped by `render()`'s implicit act.
33
+ *
34
+ * @param {React.ReactElement} ui React element to render.
35
+ * @return {ReturnType<typeof render>} The settled `render()` result, including `container`, `rerender`, etc.
36
+ */
37
+ async function renderAndSettle( ui ) {
38
+ let result;
39
+ // eslint-disable-next-line testing-library/no-unnecessary-act -- Ariakit `useLayoutEffect` chains in CustomSelect / FontAppearance / FontFamily emit state updates outside RTL's implicit act, so we must wrap render explicitly.
40
+ await act( async () => {
41
+ result = render( ui );
42
+ } );
43
+ return result;
44
+ }
45
+
46
+ /**
47
+ * Renders `TypographyPanel` with sensible defaults so tests only pass the
48
+ * props they actually care about (usually `value` and `inheritedValue`).
49
+ *
50
+ * @param {Object} props Props to override the defaults.
51
+ * @return {ReturnType<typeof render>} The `render()` result.
52
+ */
53
+ function renderPanel( props ) {
54
+ return render(
55
+ <TypographyPanel
56
+ value={ {} }
57
+ settings={ baseSettings }
58
+ onChange={ () => {} }
59
+ panelId="test-panel"
60
+ { ...props }
61
+ />
62
+ );
63
+ }
64
+
65
+ /**
66
+ * Async variant of `renderPanel` for controls (Ariakit-based) that need
67
+ * their effects flushed. See `renderAndSettle`.
68
+ *
69
+ * @param {Object} props Props to override the defaults.
70
+ * @return {Promise<ReturnType<typeof render>>} The settled `render()` result.
71
+ */
72
+ function renderPanelAndSettle( props ) {
73
+ return renderAndSettle(
74
+ <TypographyPanel
75
+ value={ {} }
76
+ settings={ baseSettings }
77
+ onChange={ () => {} }
78
+ panelId="test-panel"
79
+ { ...props }
80
+ />
81
+ );
82
+ }
83
+
84
+ /**
85
+ * Tests for inherited values in `TypographyPanel`.
86
+ *
87
+ * The tests intentionally target representative control paths rather than full
88
+ * panel coverage. They verify that inherited values are displayed without
89
+ * being committed, and that local overrides remain the source of truth.
90
+ */
91
+
92
+ const baseSettings = {
93
+ typography: {
94
+ lineHeight: true,
95
+ letterSpacing: true,
96
+ textColumns: true,
97
+ textIndent: 'subsequent',
98
+ textDecoration: true,
99
+ writingMode: true,
100
+ textTransform: true,
101
+ textAlign: true,
102
+ fontSize: true,
103
+ customFontSize: true,
104
+ fontSizes: {
105
+ theme: [
106
+ { slug: 'large', size: '24px', name: 'Large' },
107
+ { slug: 'huge', size: '42px', name: 'Huge' },
108
+ ],
109
+ },
110
+ },
111
+ };
112
+
113
+ // Settings variant that also enables the FontFamily and FontAppearance
114
+ // controls. Kept separate from `baseSettings` because mounting these
115
+ // controls registers extra ToolsPanelItem callbacks that surface React
116
+ // 18 `act(...)` warnings under jsdom; the warnings are spurious for
117
+ // tests that don't exercise font appearance / family. New per-archetype
118
+ // tests that DO assert font appearance / family behaviour opt into
119
+ // this richer settings object.
120
+ const settingsWithFonts = {
121
+ typography: {
122
+ ...baseSettings.typography,
123
+ fontFamily: true,
124
+ fontStyle: true,
125
+ fontWeight: true,
126
+ fontFamilies: {
127
+ theme: [
128
+ { slug: 'serif', name: 'Serif', fontFamily: 'Georgia, serif' },
129
+ {
130
+ slug: 'sans',
131
+ name: 'Sans',
132
+ fontFamily: 'system-ui, sans-serif',
133
+ },
134
+ ],
135
+ },
136
+ },
137
+ };
138
+
139
+ describe( 'TypographyPanel — inheritedValue round-trip', () => {
140
+ it( 'renders a numeric leaf from `inheritedValue` as the control value when `value` is empty', () => {
141
+ // LineHeightControl uses the local-then-inherited pattern: the
142
+ // inherited value is rendered as the control's value (so the
143
+ // numeric stepper increments from the inherited base) and an
144
+ // inherited-value class hook marks it as at-rest. It is only
145
+ // committed to local on user change.
146
+ const inheritedValue = {
147
+ typography: { lineHeight: '1.7' },
148
+ };
149
+
150
+ renderPanel( { inheritedValue } );
151
+
152
+ const lineHeightInput = screen.getByLabelText( /line height/i );
153
+ expect( lineHeightInput ).toHaveValue( 1.7 );
154
+ } );
155
+
156
+ it( 'renders an integer leaf from `inheritedValue` as placeholder when `value` is empty', () => {
157
+ // Placeholder-capable controls communicate the inherited value
158
+ // via the native `placeholder` attribute rather than as the
159
+ // rendered `value`, so users can distinguish local values from
160
+ // inherited values.
161
+ const inheritedValue = {
162
+ typography: { textColumns: 3 },
163
+ };
164
+
165
+ renderPanel( { inheritedValue } );
166
+
167
+ const columnsInput = screen.getByLabelText( /columns/i );
168
+ // No locally-set value; the rendered value is empty.
169
+ expect( columnsInput ).toHaveValue( null );
170
+ // The inherited value reaches the user via the native
171
+ // `placeholder` attribute.
172
+ expect( columnsInput ).toHaveAttribute( 'placeholder', '3' );
173
+ } );
174
+
175
+ it( 'renders a locally-set integer leaf as the value, with no placeholder, even when `inheritedValue` also defines it', () => {
176
+ // Local override wins over the inherited value, and there is
177
+ // no placeholder treatment because the user has committed a
178
+ // value of their own.
179
+ const inheritedValue = {
180
+ typography: { textColumns: 3 },
181
+ };
182
+ const value = {
183
+ typography: { textColumns: 5 },
184
+ };
185
+
186
+ renderPanel( { value, inheritedValue } );
187
+
188
+ const columnsInput = screen.getByLabelText( /columns/i );
189
+ expect( columnsInput ).toHaveValue( 5 );
190
+ expect( columnsInput ).not.toHaveAttribute( 'placeholder' );
191
+ } );
192
+
193
+ it( 'shows no placeholder for an integer leaf when `inheritedValue` also omits it', () => {
194
+ // Without an inherited value, there is nothing to communicate
195
+ // as a placeholder; the input renders as an ordinary empty
196
+ // NumberControl.
197
+ renderPanel( { inheritedValue: {} } );
198
+
199
+ const columnsInput = screen.getByLabelText( /columns/i );
200
+ expect( columnsInput ).toHaveValue( null );
201
+ expect( columnsInput ).not.toHaveAttribute( 'placeholder' );
202
+ } );
203
+
204
+ it( 'commits a local override on user input without copying the inherited value into other paths', async () => {
205
+ // A local commit writes only the path the user touched. The
206
+ // inherited value is never copied into local attributes by typing.
207
+ const user = userEvent.setup();
208
+ const onChange = jest.fn();
209
+ const inheritedValue = {
210
+ typography: { textColumns: 3, lineHeight: '1.7' },
211
+ };
212
+
213
+ renderPanel( { inheritedValue, onChange } );
214
+
215
+ const columnsInput = screen.getByLabelText( /columns/i );
216
+ await user.type( columnsInput, '2' );
217
+
218
+ // onChange must be called with the typed value at exactly the
219
+ // touched path; no other path is mutated, and no inherited
220
+ // value is copied into the local payload.
221
+ expect( onChange ).toHaveBeenCalled();
222
+ const lastCall = onChange.mock.calls.at( -1 )[ 0 ];
223
+ // NumberControl emits the value as a string; the existing
224
+ // setTextColumns setter passes it through without coercion.
225
+ // What matters here is that *only* the touched leaf is
226
+ // written, not the type of the value.
227
+ expect( lastCall ).toEqual( {
228
+ typography: { textColumns: '2' },
229
+ } );
230
+ // Critically: lineHeight (which only exists in inheritedValue)
231
+ // must NOT appear in the local payload.
232
+ expect( lastCall.typography ).not.toHaveProperty( 'lineHeight' );
233
+ } );
234
+
235
+ it( 'returns to placeholder rendering after a local override is reset', () => {
236
+ // Reset clears the local attribute so the inherited value
237
+ // re-surfaces via placeholder. We simulate the reset by
238
+ // re-rendering with `value` cleared (the same effect
239
+ // `resetTextColumns` produces by setting the leaf to
240
+ // `undefined`).
241
+ const inheritedValue = {
242
+ typography: { textColumns: 3 },
243
+ };
244
+
245
+ const { rerender } = renderPanel( {
246
+ value: { typography: { textColumns: 5 } },
247
+ inheritedValue,
248
+ } );
249
+
250
+ // See locally-set value first.
251
+ expect( screen.getByLabelText( /columns/i ) ).toHaveValue( 5 );
252
+ expect( screen.getByLabelText( /columns/i ) ).not.toHaveAttribute(
253
+ 'placeholder'
254
+ );
255
+
256
+ // Reset: local value cleared.
257
+ rerender(
258
+ <TypographyPanel
259
+ value={ {} }
260
+ inheritedValue={ inheritedValue }
261
+ settings={ baseSettings }
262
+ onChange={ () => {} }
263
+ panelId="test-panel"
264
+ />
265
+ );
266
+
267
+ // Placeholder is back; local value is gone.
268
+ const columnsInput = screen.getByLabelText( /columns/i );
269
+ expect( columnsInput ).toHaveValue( null );
270
+ expect( columnsInput ).toHaveAttribute( 'placeholder', '3' );
271
+ } );
272
+
273
+ it( 'renders a locally-set numeric leaf as the value, with no placeholder, even when `inheritedValue` also defines it', () => {
274
+ // Local values remain the source of truth when both local and
275
+ // inherited values are present.
276
+ const inheritedValue = {
277
+ typography: { lineHeight: '2.2' },
278
+ };
279
+ const value = {
280
+ typography: { lineHeight: '1.4' },
281
+ };
282
+
283
+ renderPanel( { value, inheritedValue } );
284
+
285
+ const lineHeightInput = screen.getByLabelText( /line height/i );
286
+ expect( lineHeightInput ).toHaveValue( 1.4 );
287
+ } );
288
+
289
+ it( 'renders a unit-string leaf from `inheritedValue` as the control value when `value` is empty', () => {
290
+ // LetterSpacingControl uses the local-then-inherited pattern: the
291
+ // inherited value is rendered as the control's value (so the unit
292
+ // parses from it rather than sitting behind a default px unit) and an
293
+ // inherited-value class hook marks it at-rest. It is only committed to
294
+ // local on user change.
295
+ const inheritedValue = {
296
+ typography: { letterSpacing: '0.5px' },
297
+ };
298
+
299
+ renderPanel( { inheritedValue } );
300
+
301
+ const letterSpacingInput = screen.getByLabelText( /letter spacing/i );
302
+ expect( letterSpacingInput ).toHaveValue( 0.5 );
303
+ // The placeholder carries only the numeric portion of the inherited
304
+ // value; the unit selector reflects the inherited unit separately, so
305
+ // the raw unit string ("0.5px") must never leak into the placeholder.
306
+ expect( letterSpacingInput ).toHaveAttribute( 'placeholder', '0.5' );
307
+ expect( letterSpacingInput ).not.toHaveAttribute(
308
+ 'placeholder',
309
+ '0.5px'
310
+ );
311
+ } );
312
+
313
+ it( 'renders a locally-set unit-string leaf as the value, with no placeholder, even when `inheritedValue` also defines it', () => {
314
+ const inheritedValue = {
315
+ typography: { letterSpacing: '0.5px' },
316
+ };
317
+ const value = {
318
+ typography: { letterSpacing: '2px' },
319
+ };
320
+
321
+ renderPanel( { value, inheritedValue } );
322
+
323
+ const letterSpacingInput = screen.getByLabelText( /letter spacing/i );
324
+ expect( letterSpacingInput ).toHaveValue( 2 );
325
+ expect( letterSpacingInput ).not.toHaveAttribute( 'placeholder' );
326
+ } );
327
+
328
+ it( 'value for one input does not leak when other inputs are committed', () => {
329
+ // A locally-set lineHeight should not affect the inherited value
330
+ // rendering for letterSpacing, and vice versa. Each control's
331
+ // local/inherited resolution is computed independently from its own
332
+ // leaf path.
333
+ const inheritedValue = {
334
+ typography: { lineHeight: '1.7', letterSpacing: '0.5px' },
335
+ };
336
+ const value = {
337
+ typography: { lineHeight: '1.4' },
338
+ };
339
+
340
+ renderPanel( { value, inheritedValue } );
341
+
342
+ // lineHeight: locally-set, not at-rest.
343
+ const lineHeightInput = screen.getByLabelText( /line height/i );
344
+ expect( lineHeightInput ).toHaveValue( 1.4 );
345
+
346
+ // letterSpacing: not locally set, shows the inherited value at rest.
347
+ const letterSpacingInput = screen.getByLabelText( /letter spacing/i );
348
+ expect( letterSpacingInput ).toHaveValue( 0.5 );
349
+ } );
350
+
351
+ it( 'falls back to `value` when `inheritedValue` is omitted (pre-feature behaviour is preserved)', () => {
352
+ // The `inheritedValue = value` default keeps call sites that
353
+ // have not yet opted into separate inherited data on the existing
354
+ // code path: no placeholder, no local-value regression.
355
+ renderPanel( { value: { typography: { lineHeight: '1.9' } } } );
356
+
357
+ expect( screen.getByLabelText( /line height/i ) ).toHaveValue( 1.9 );
358
+ } );
359
+
360
+ it( 'renders nothing for a leaf when both `value` and `inheritedValue` omit it', () => {
361
+ renderPanel( { inheritedValue: {} } );
362
+
363
+ // An empty NumberControl input has no `value` attribute applied;
364
+ // RTL returns `null` (not `0`, not the empty string) for that case.
365
+ expect( screen.getByLabelText( /line height/i ) ).toHaveValue( null );
366
+ } );
367
+
368
+ it( 'accepts a `var:preset|font-size|…` leaf in `inheritedValue` without throwing', () => {
369
+ // This verifies the panel accepts preset-shaped inherited values
370
+ // at its prop boundary and renders the Font size control. The
371
+ // decoded value flows through the panel's internal `decodeValue`
372
+ // pipe into `FontSizePicker`; the visible representation of a
373
+ // selected preset is owned by that component and is not part of
374
+ // the `inheritedValue` contract.
375
+ const inheritedValue = {
376
+ typography: { fontSize: 'var:preset|font-size|large' },
377
+ };
378
+
379
+ expect( () => {
380
+ renderPanel( { inheritedValue } );
381
+ } ).not.toThrow();
382
+
383
+ // The Font size ToolsPanelItem label is rendered in the DOM.
384
+ expect( screen.getAllByText( /font size/i ).length ).toBeGreaterThan(
385
+ 0
386
+ );
387
+ } );
388
+
389
+ describe( 'ToggleGroup-style controls (textDecoration, writingMode, textTransform, textAlign)', () => {
390
+ it( 'preselects the inherited textDecoration option', async () => {
391
+ const inheritedValue = {
392
+ typography: { textDecoration: 'underline' },
393
+ };
394
+
395
+ await renderPanelAndSettle( { inheritedValue } );
396
+
397
+ // The inherited option is rendered as the pressed one.
398
+ // `TextDecorationControl` uses `isDeselectable=true` so the
399
+ // option element is a `<button aria-pressed="true">` rather
400
+ // than an Ariakit Radio with `aria-checked`.
401
+ expect(
402
+ screen.getByRole( 'button', {
403
+ name: /underline/i,
404
+ pressed: true,
405
+ } )
406
+ ).toBeInTheDocument();
407
+ } );
408
+
409
+ it( 'mounting an at-rest ToggleGroup does not call onChange (display-without-commit)', async () => {
410
+ // The display-without-commit invariant: rendering an
411
+ // at-rest control with an inherited preselection must
412
+ // never invoke the parent `onChange`. Otherwise the act
413
+ // of opening the inspector would silently commit every
414
+ // inherited value into the local block attributes.
415
+ const onChange = jest.fn();
416
+ const inheritedValue = {
417
+ typography: {
418
+ textDecoration: 'underline',
419
+ writingMode: 'horizontal-tb',
420
+ textTransform: 'uppercase',
421
+ textAlign: 'center',
422
+ fontStyle: 'italic',
423
+ fontWeight: '700',
424
+ fontFamily: 'Georgia, serif',
425
+ },
426
+ };
427
+
428
+ await renderPanelAndSettle( {
429
+ inheritedValue,
430
+ settings: settingsWithFonts,
431
+ onChange,
432
+ } );
433
+
434
+ expect( onChange ).not.toHaveBeenCalled();
435
+ } );
436
+
437
+ it( 'activating the at-rest preselected option commits the inherited value to local', async () => {
438
+ // When the user explicitly activates the already-preselected
439
+ // at-rest option (Space/Enter/click), we treat that as the
440
+ // "accept this inherited value" affordance and commit the
441
+ // inherited value to the local payload. The interceptor
442
+ // bypasses the inner ToggleGroupControl's equality
443
+ // short-circuit which would otherwise emit `undefined`.
444
+ const user = userEvent.setup();
445
+ const onChange = jest.fn();
446
+ const inheritedValue = {
447
+ typography: { textDecoration: 'underline' },
448
+ };
449
+
450
+ await renderPanelAndSettle( { inheritedValue, onChange } );
451
+
452
+ // Click the already-preselected "Underline" option (a
453
+ // button under `isDeselectable` ToggleGroupControl).
454
+ const underline = screen.getByRole( 'button', {
455
+ name: /underline/i,
456
+ pressed: true,
457
+ } );
458
+ await user.click( underline );
459
+
460
+ expect( onChange ).toHaveBeenCalled();
461
+ const lastCall = onChange.mock.calls.at( -1 )[ 0 ];
462
+ expect( lastCall ).toEqual( {
463
+ typography: { textDecoration: 'underline' },
464
+ } );
465
+ } );
466
+
467
+ it( 'renders a locally-set ToggleGroup value, not the inherited one', async () => {
468
+ // Regression guard: when the user has committed a local
469
+ // value, the panel must render that local value, not the
470
+ // inherited value. This guards against losing local writes when
471
+ // rendering with inherited data.
472
+ const inheritedValue = {
473
+ typography: { textDecoration: 'underline' },
474
+ };
475
+ const value = {
476
+ typography: { textDecoration: 'line-through' },
477
+ };
478
+
479
+ await renderPanelAndSettle( {
480
+ value,
481
+ inheritedValue,
482
+ } );
483
+
484
+ // The locally-set option is the one currently pressed.
485
+ const pressed = screen.getByRole( 'button', {
486
+ pressed: true,
487
+ name: /strikethrough/i,
488
+ } );
489
+ expect( pressed ).toBeInTheDocument();
490
+ } );
491
+ } );
492
+
493
+ describe( 'TextIndent (input archetype)', () => {
494
+ it( 'renders an inherited textIndent as the control value when local is unset', async () => {
495
+ const inheritedValue = {
496
+ typography: { textIndent: '2rem' },
497
+ };
498
+
499
+ await renderPanelAndSettle( { inheritedValue } );
500
+
501
+ // `TextIndentControl` in `withSlider` mode renders both a
502
+ // UnitControl number input AND a RangeControl slider with
503
+ // the same label, so we target the spinbutton role to
504
+ // pick the UnitControl input specifically. The inherited
505
+ // value is rendered as the control's value (parsed quantity),
506
+ // so the unit selector reflects the inherited unit and the
507
+ // stepper starts from it; it is committed to local only on
508
+ // user change.
509
+ const indentInput = screen.getByRole( 'spinbutton', {
510
+ name: /line indent/i,
511
+ } );
512
+ expect( indentInput ).toHaveValue( 2 );
513
+ } );
514
+
515
+ it( 'renders a locally-set textIndent as the value, with no placeholder', async () => {
516
+ const inheritedValue = {
517
+ typography: { textIndent: '2rem' },
518
+ };
519
+ const value = {
520
+ typography: { textIndent: '4rem' },
521
+ };
522
+
523
+ await renderPanelAndSettle( { value, inheritedValue } );
524
+
525
+ const indentInput = screen.getByRole( 'spinbutton', {
526
+ name: /line indent/i,
527
+ } );
528
+ expect( indentInput ).toHaveValue( 4 );
529
+ expect( indentInput ).not.toHaveAttribute( 'placeholder' );
530
+ } );
531
+ } );
532
+
533
+ describe( 'Font appearance (composite ToggleGroup-like select)', () => {
534
+ it( 'mounting an at-rest font appearance does not call onChange (display-without-commit)', async () => {
535
+ const onChange = jest.fn();
536
+ const inheritedValue = {
537
+ typography: { fontStyle: 'italic', fontWeight: '700' },
538
+ };
539
+
540
+ await renderPanelAndSettle( {
541
+ inheritedValue,
542
+ settings: settingsWithFonts,
543
+ onChange,
544
+ } );
545
+
546
+ expect( onChange ).not.toHaveBeenCalled();
547
+ } );
548
+ } );
549
+
550
+ describe( 'FontFamily (CustomSelect archetype)', () => {
551
+ it( 'mounting an at-rest font family does not call onChange (display-without-commit)', async () => {
552
+ const onChange = jest.fn();
553
+ const inheritedValue = {
554
+ typography: { fontFamily: 'Georgia, serif' },
555
+ };
556
+
557
+ await renderPanelAndSettle( {
558
+ inheritedValue,
559
+ settings: settingsWithFonts,
560
+ onChange,
561
+ } );
562
+
563
+ expect( onChange ).not.toHaveBeenCalled();
564
+ } );
565
+ } );
566
+
567
+ describe( 'preset decode + explicit-empty in panel', () => {
568
+ // These tests cover preset decoding and explicit-empty values at
569
+ // the panel render boundary.
570
+
571
+ it( 'decodes a preset fontSize for placeholder display, never leaking the raw preset string', () => {
572
+ const inheritedValue = {
573
+ typography: { fontSize: 'var:preset|font-size|large' },
574
+ };
575
+
576
+ const { container } = renderPanel( { inheritedValue } );
577
+
578
+ // The decoded human-readable value (`24px`, from the
579
+ // `large` preset in `baseSettings`) is what reaches the
580
+ // rendered DOM; the raw `var:preset|...` form must not
581
+ // appear in any text, value, or placeholder.
582
+ expect( container.innerHTML ).not.toContain(
583
+ 'var:preset|font-size|large'
584
+ );
585
+ expect( container.innerHTML ).not.toContain(
586
+ 'var(--wp--preset--font-size--large)'
587
+ );
588
+ } );
589
+
590
+ it.each( [ '', null ] )(
591
+ 'does not render the at-rest placeholder cue when inheritedValue.typography.lineHeight is explicit-empty (%p)',
592
+ ( emptyValue ) => {
593
+ // Note on `{}` empty-object: the resolver
594
+ // (`resolveStyle` →
595
+ // `pickLayerRootContribution`) drops `{}` at the
596
+ // layer-merge stage, so the panel never receives a
597
+ // `{}` leaf in production (asserted at the helper
598
+ // level by `preset-round-trip.js` and at the resolver
599
+ // level by `resolve-style.ts`'s
600
+ // `explicit-empty normalization` describe). The
601
+ // panel-level guard only needs to defend against
602
+ // `''` and `null` leaves, which can flow through
603
+ // when the GS payload itself contains them at any
604
+ // layer.
605
+ const inheritedValue = {
606
+ typography: { lineHeight: emptyValue },
607
+ };
608
+
609
+ renderPanel( { inheritedValue } );
610
+
611
+ const lineHeightInput = screen.getByLabelText( /line height/i );
612
+ expect( lineHeightInput ).toHaveValue( null );
613
+ // The explicit-empty inherited leaf is not surfaced as an
614
+ // inherited placeholder; `LineHeightControl` falls back to its
615
+ // own `BASE_DEFAULT_VALUE` (1.5) default placeholder instead.
616
+ expect( lineHeightInput ).toHaveAttribute(
617
+ 'placeholder',
618
+ '1.5'
619
+ );
620
+ }
621
+ );
622
+ } );
623
+
624
+ describe( 'FontSize (preset picker + custom-size input)', () => {
625
+ it( 'mounting an at-rest font size does not call onChange (display-without-commit)', async () => {
626
+ const onChange = jest.fn();
627
+ const inheritedValue = {
628
+ typography: { fontSize: 'var:preset|font-size|large' },
629
+ };
630
+
631
+ await renderPanelAndSettle( { inheritedValue, onChange } );
632
+
633
+ expect( onChange ).not.toHaveBeenCalled();
634
+ } );
635
+ } );
636
+
637
+ it( 'treats local zero values as local overrides instead of inherited placeholders', () => {
638
+ const inheritedValue = {
639
+ typography: { lineHeight: '2', textColumns: 3 },
640
+ };
641
+ const value = {
642
+ typography: { lineHeight: 0, textColumns: 0 },
643
+ };
644
+
645
+ renderPanel( { value, inheritedValue } );
646
+
647
+ const lineHeightInput = screen.getByLabelText( /line height/i );
648
+ expect( lineHeightInput ).toHaveValue( 0 );
649
+ // The inherited line height ('2') must not leak in as a placeholder;
650
+ // `LineHeightControl`'s own default (1.5) may remain, but the value is
651
+ // the local zero override.
652
+ expect( lineHeightInput ).not.toHaveAttribute( 'placeholder', '2' );
653
+
654
+ const columnsInput = screen.getByLabelText( /columns/i );
655
+ expect( columnsInput ).toHaveValue( 0 );
656
+ expect( columnsInput ).not.toHaveAttribute( 'placeholder' );
657
+
658
+ // Both zero values are local overrides, so each control surfaces the
659
+ // accessible reset-to-inherited affordance.
660
+ expect(
661
+ screen.getAllByRole( 'button', {
662
+ name: /reset to inherited value/i,
663
+ } )
664
+ ).toHaveLength( 2 );
665
+ } );
666
+ } );
667
+
12
668
  const settingsWithColors = ( overrides = {} ) => ( {
13
669
  color: {
14
670
  palette: {
@@ -95,21 +751,66 @@ const DUPLICATE_PALETTE_SETTINGS = {
95
751
  },
96
752
  };
97
753
 
98
- describe( 'TypographyPanel setTextColor link sync', () => {
99
- // Helper: open the text Color dropdown and return the rendered swatches.
100
- async function openTextColorDropdown() {
101
- await click(
102
- screen.getByRole( 'button', { name: /Color/, expanded: false } )
754
+ // Helper: open the text Color dropdown and return the rendered swatches.
755
+ async function openTextColorDropdown() {
756
+ await click(
757
+ screen.getByRole( 'button', { name: /Color/, expanded: false } )
758
+ );
759
+ // `findAllByRole` waits for the Popover/portal content to appear.
760
+ return screen.findAllByRole( 'option' );
761
+ }
762
+
763
+ describe( 'TypographyPanel — duplicate-hex preset slug identity', () => {
764
+ it( 'commits the inherited preset slug when accepting the preselected inherited color', async () => {
765
+ const onChange = jest.fn();
766
+
767
+ await renderAriakit(
768
+ <TypographyPanel
769
+ value={ {} }
770
+ inheritedValue={ {
771
+ color: { text: 'var:preset|color|dark-text' },
772
+ } }
773
+ settings={ DUPLICATE_PALETTE_SETTINGS }
774
+ panelId="test"
775
+ onChange={ onChange }
776
+ />
103
777
  );
104
- // `findAllByRole` waits for the Popover/portal content to appear.
105
- return screen.findAllByRole( 'option' );
106
- }
107
778
 
779
+ const swatches = await openTextColorDropdown();
780
+ // swatch[1] ('Dark Text') is the preselected inherited option;
781
+ // activating it is the "accept inherited value" gesture. The commit
782
+ // must carry the inherited slug, not re-encode the shared #000 hex
783
+ // to whichever duplicate appears first in the palette.
784
+ await click( swatches[ 1 ] );
785
+
786
+ const result = onChange.mock.calls[ 0 ][ 0 ];
787
+ expect( result?.color?.text ).toBe( 'var:preset|color|dark-text' );
788
+ } );
789
+
790
+ it( 'marks only the local preset as selected when another preset shares its hex', async () => {
791
+ await renderAriakit(
792
+ <TypographyPanel
793
+ value={ { color: { text: 'var:preset|color|dark-text' } } }
794
+ settings={ DUPLICATE_PALETTE_SETTINGS }
795
+ panelId="test"
796
+ onChange={ jest.fn() }
797
+ />
798
+ );
799
+
800
+ // swatch[0] = 'Dark Background', swatch[1] = 'Dark Text'. Selection
801
+ // must follow the stored slug; matching by hex would mark both.
802
+ const swatches = await openTextColorDropdown();
803
+ expect( swatches[ 1 ] ).toHaveAttribute( 'aria-selected', 'true' );
804
+ expect( swatches[ 0 ] ).toHaveAttribute( 'aria-selected', 'false' );
805
+ } );
806
+ } );
807
+
808
+ describe( 'TypographyPanel — setTextColor link sync', () => {
108
809
  it( 'syncs the link color when text and link share the same raw preset reference', async () => {
109
810
  const onChange = jest.fn();
110
811
  const sharedRef = 'var:preset|color|dark-background';
111
812
 
112
- await render(
813
+ await renderAriakit(
113
814
  <TypographyPanel
114
815
  value={ {} }
115
816
  inheritedValue={ {
@@ -137,7 +838,7 @@ describe( 'TypographyPanel — setTextColor link sync', () => {
137
838
  it( 'does NOT sync the link color when text and link have different raw refs, even if their decoded hex values match', async () => {
138
839
  const onChange = jest.fn();
139
840
 
140
- await render(
841
+ await renderAriakit(
141
842
  <TypographyPanel
142
843
  value={ {} }
143
844
  inheritedValue={ {
@@ -164,4 +865,140 @@ describe( 'TypographyPanel — setTextColor link sync', () => {
164
865
  // not decoded-value equality.
165
866
  expect( result?.elements?.link?.color?.text ).toBeUndefined();
166
867
  } );
868
+
869
+ it( 'preserves a deliberately-set local link color when the text color changes and nothing is inherited', async () => {
870
+ // Regression: with a theme that inherits no link color, a link
871
+ // color the user set on the block instance must survive a
872
+ // subsequent text color change instead of being overwritten to
873
+ // track the text color.
874
+ const onChange = jest.fn();
875
+
876
+ await renderAriakit(
877
+ <TypographyPanel
878
+ value={ {
879
+ elements: {
880
+ link: {
881
+ color: { text: 'var:preset|color|dark-text' },
882
+ },
883
+ },
884
+ } }
885
+ inheritedValue={ {} }
886
+ settings={ DUPLICATE_PALETTE_SETTINGS }
887
+ panelId="test"
888
+ onChange={ onChange }
889
+ />
890
+ );
891
+
892
+ const swatches = await openTextColorDropdown();
893
+ // swatch[0] = 'dark-background'
894
+ await click( swatches[ 0 ] );
895
+
896
+ const result = onChange.mock.calls[ 0 ][ 0 ];
897
+ expect( result?.color?.text ).toBe(
898
+ 'var:preset|color|dark-background'
899
+ );
900
+ // The deliberately-set local link color is untouched.
901
+ expect( result?.elements?.link?.color?.text ).toBe(
902
+ 'var:preset|color|dark-text'
903
+ );
904
+ } );
905
+
906
+ it( 'keeps a local link color tracking when it currently matches the local text color', async () => {
907
+ // When the local link color equals the local text color it is
908
+ // still tracking, so a text color change carries the link along.
909
+ const onChange = jest.fn();
910
+ const sharedRef = 'var:preset|color|blue';
911
+ const distinctPaletteSettings = {
912
+ color: {
913
+ text: true,
914
+ custom: false,
915
+ customGradient: false,
916
+ defaultPalette: false,
917
+ palette: {
918
+ theme: [
919
+ { color: '#0000ff', name: 'Blue', slug: 'blue' },
920
+ { color: '#ff0000', name: 'Red', slug: 'red' },
921
+ ],
922
+ },
923
+ },
924
+ };
925
+
926
+ await renderAriakit(
927
+ <TypographyPanel
928
+ value={ {
929
+ color: { text: sharedRef },
930
+ elements: { link: { color: { text: sharedRef } } },
931
+ } }
932
+ inheritedValue={ {} }
933
+ settings={ distinctPaletteSettings }
934
+ panelId="test"
935
+ onChange={ onChange }
936
+ />
937
+ );
938
+
939
+ const swatches = await openTextColorDropdown();
940
+ // swatch[1] = 'red'
941
+ await click( swatches[ 1 ] );
942
+
943
+ const result = onChange.mock.calls[ 0 ][ 0 ];
944
+ expect( result?.color?.text ).toBe( 'var:preset|color|red' );
945
+ // Link follows because it was still tracking the text color.
946
+ expect( result?.elements?.link?.color?.text ).toBe(
947
+ 'var:preset|color|red'
948
+ );
949
+ } );
950
+ } );
951
+
952
+ describe( 'TypographyPanel layout className preserved regardless of inheritance indicators', () => {
953
+ const inheritedValue = {
954
+ typography: { lineHeight: '1.5', letterSpacing: '1px' },
955
+ };
956
+
957
+ const getItem = ( name ) => {
958
+ const control = screen.getByRole( 'spinbutton', { name } );
959
+ // The layout class sits on the wrapping ToolsPanelItem, which has no role.
960
+ // eslint-disable-next-line testing-library/no-node-access
961
+ return control.closest( '.components-tools-panel-item' );
962
+ };
963
+
964
+ it( 'keeps the single-column layout class when showInheritanceLabelIndicators is false (regression)', () => {
965
+ renderPanel( {
966
+ showInheritanceLabelIndicators: false,
967
+ value: {},
968
+ inheritedValue,
969
+ } );
970
+
971
+ const lineHeightItem = getItem( /line height/i );
972
+ const letterSpacingItem = getItem( /letter spacing/i );
973
+
974
+ expect( lineHeightItem ).toHaveClass( 'single-column' );
975
+ expect( letterSpacingItem ).toHaveClass( 'single-column' );
976
+
977
+ expect( lineHeightItem ).not.toHaveClass(
978
+ 'is-inherited-from-global-styles'
979
+ );
980
+ expect( letterSpacingItem ).not.toHaveClass(
981
+ 'is-inherited-from-global-styles'
982
+ );
983
+ } );
984
+
985
+ it( 'folds the single-column layout class together with the inherited treatment when indicators are on', () => {
986
+ renderPanel( {
987
+ showInheritanceLabelIndicators: true,
988
+ value: {},
989
+ inheritedValue,
990
+ } );
991
+
992
+ const lineHeightItem = getItem( /line height/i );
993
+ const letterSpacingItem = getItem( /letter spacing/i );
994
+
995
+ expect( lineHeightItem ).toHaveClass( 'single-column' );
996
+ expect( lineHeightItem ).toHaveClass(
997
+ 'is-inherited-from-global-styles'
998
+ );
999
+ expect( letterSpacingItem ).toHaveClass( 'single-column' );
1000
+ expect( letterSpacingItem ).toHaveClass(
1001
+ 'is-inherited-from-global-styles'
1002
+ );
1003
+ } );
167
1004
  } );