@wordpress/block-editor 15.22.1-next.v.202606191442.0 → 15.23.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 (383) hide show
  1. package/CHANGELOG.md +3 -1
  2. package/README.md +2 -2
  3. package/build/components/block-editing-mode/index.cjs +13 -7
  4. package/build/components/block-editing-mode/index.cjs.map +2 -2
  5. package/build/components/block-inspector/index.cjs +50 -51
  6. package/build/components/block-inspector/index.cjs.map +2 -2
  7. package/build/components/block-rename/modal.cjs +0 -1
  8. package/build/components/block-rename/modal.cjs.map +2 -2
  9. package/build/components/block-toolbar/block-toolbar-icon.cjs +14 -6
  10. package/build/components/block-toolbar/block-toolbar-icon.cjs.map +2 -2
  11. package/build/components/colors-gradients/control.cjs +25 -14
  12. package/build/components/colors-gradients/control.cjs.map +2 -2
  13. package/build/components/colors-gradients/dropdown.cjs +4 -1
  14. package/build/components/colors-gradients/dropdown.cjs.map +3 -3
  15. package/build/components/contrast-checker/index.cjs +22 -4
  16. package/build/components/contrast-checker/index.cjs.map +2 -2
  17. package/build/components/date-format-picker/index.cjs +0 -1
  18. package/build/components/date-format-picker/index.cjs.map +2 -2
  19. package/build/components/global-styles/background-panel.cjs +153 -25
  20. package/build/components/global-styles/background-panel.cjs.map +3 -3
  21. package/build/components/global-styles/color-gradient-dropdown-item.cjs +227 -0
  22. package/build/components/global-styles/color-gradient-dropdown-item.cjs.map +7 -0
  23. package/build/components/global-styles/color-panel.cjs +98 -375
  24. package/build/components/global-styles/color-panel.cjs.map +3 -3
  25. package/build/components/global-styles/dimensions-panel.cjs +0 -3
  26. package/build/components/global-styles/dimensions-panel.cjs.map +2 -2
  27. package/build/components/global-styles/hooks.cjs +34 -0
  28. package/build/components/global-styles/hooks.cjs.map +2 -2
  29. package/build/components/global-styles/typography-panel.cjs +82 -10
  30. package/build/components/global-styles/typography-panel.cjs.map +3 -3
  31. package/build/components/inspector-controls/groups.cjs +2 -0
  32. package/build/components/inspector-controls/groups.cjs.map +2 -2
  33. package/build/components/inspector-controls-tabs/styles-tab.cjs +75 -31
  34. package/build/components/inspector-controls-tabs/styles-tab.cjs.map +2 -2
  35. package/build/components/link-control/index.cjs +1 -2
  36. package/build/components/link-control/index.cjs.map +2 -2
  37. package/build/components/list-view/block-select-button.cjs +1 -10
  38. package/build/components/list-view/block-select-button.cjs.map +3 -3
  39. package/build/components/provider/use-block-sync.cjs +3 -1
  40. package/build/components/provider/use-block-sync.cjs.map +2 -2
  41. package/build/components/url-popover/image-url-input-ui.cjs +0 -2
  42. package/build/components/url-popover/image-url-input-ui.cjs.map +2 -2
  43. package/build/components/use-block-display-information/index.cjs +10 -3
  44. package/build/components/use-block-display-information/index.cjs.map +2 -2
  45. package/build/components/use-resize-canvas/index.cjs +16 -53
  46. package/build/components/use-resize-canvas/index.cjs.map +3 -3
  47. package/build/hooks/anchor.cjs +0 -1
  48. package/build/hooks/anchor.cjs.map +2 -2
  49. package/build/hooks/background.cjs +124 -75
  50. package/build/hooks/background.cjs.map +3 -3
  51. package/build/hooks/color.cjs +0 -162
  52. package/build/hooks/color.cjs.map +3 -3
  53. package/build/hooks/contrast-checker.cjs +31 -28
  54. package/build/hooks/contrast-checker.cjs.map +3 -3
  55. package/build/hooks/custom-class-name.cjs +0 -1
  56. package/build/hooks/custom-class-name.cjs.map +2 -2
  57. package/build/hooks/elements.cjs +142 -0
  58. package/build/hooks/elements.cjs.map +7 -0
  59. package/build/hooks/grid-visualizer.cjs +21 -11
  60. package/build/hooks/grid-visualizer.cjs.map +2 -2
  61. package/build/hooks/layout-child.cjs +38 -8
  62. package/build/hooks/layout-child.cjs.map +2 -2
  63. package/build/hooks/layout.cjs +6 -3
  64. package/build/hooks/layout.cjs.map +2 -2
  65. package/build/hooks/states.cjs +15 -23
  66. package/build/hooks/states.cjs.map +2 -2
  67. package/build/hooks/style.cjs +8 -4
  68. package/build/hooks/style.cjs.map +2 -2
  69. package/build/hooks/typography.cjs +62 -10
  70. package/build/hooks/typography.cjs.map +3 -3
  71. package/build/layouts/flex.cjs +99 -6
  72. package/build/layouts/flex.cjs.map +2 -2
  73. package/build/private-apis.cjs +0 -1
  74. package/build/private-apis.cjs.map +2 -2
  75. package/build/store/private-actions.cjs +16 -0
  76. package/build/store/private-actions.cjs.map +2 -2
  77. package/build/store/private-keys.cjs +0 -3
  78. package/build/store/private-keys.cjs.map +2 -2
  79. package/build/store/private-selectors.cjs +24 -6
  80. package/build/store/private-selectors.cjs.map +2 -2
  81. package/build/store/reducer.cjs +19 -3
  82. package/build/store/reducer.cjs.map +2 -2
  83. package/build/utils/block-bindings.cjs +9 -9
  84. package/build/utils/block-bindings.cjs.map +3 -3
  85. package/build/utils/color-values.cjs +10 -1
  86. package/build/utils/color-values.cjs.map +3 -3
  87. package/build/utils/dom.cjs +2 -5
  88. package/build/utils/dom.cjs.map +3 -3
  89. package/build/utils/fit-text-frontend.cjs +6 -2
  90. package/build/utils/fit-text-frontend.cjs.map +3 -3
  91. package/build/utils/fit-text-utils.cjs +1 -1
  92. package/build/utils/fit-text-utils.cjs.map +3 -3
  93. package/build/utils/format-font-style.cjs +1 -1
  94. package/build/utils/format-font-style.cjs.map +3 -3
  95. package/build/utils/format-font-weight.cjs +1 -1
  96. package/build/utils/format-font-weight.cjs.map +3 -3
  97. package/build/utils/get-editor-region.cjs +4 -2
  98. package/build/utils/get-editor-region.cjs.map +3 -3
  99. package/build/utils/get-font-styles-and-weights.cjs +8 -12
  100. package/build/utils/get-font-styles-and-weights.cjs.map +3 -3
  101. package/build/utils/get-px-from-css-unit.cjs +1 -1
  102. package/build/utils/get-px-from-css-unit.cjs.map +1 -1
  103. package/build/utils/index.cjs +1 -1
  104. package/build/utils/index.cjs.map +1 -1
  105. package/build/utils/math.cjs +1 -1
  106. package/build/utils/math.cjs.map +3 -3
  107. package/build/utils/object.cjs +8 -8
  108. package/build/utils/object.cjs.map +3 -3
  109. package/build/utils/order-inserter-block-items.cjs +1 -1
  110. package/build/utils/order-inserter-block-items.cjs.map +3 -3
  111. package/build/utils/pasting.cjs +4 -2
  112. package/build/utils/pasting.cjs.map +3 -3
  113. package/build/utils/selection.cjs +2 -1
  114. package/build/utils/selection.cjs.map +3 -3
  115. package/build/utils/sorting.cjs +9 -3
  116. package/build/utils/sorting.cjs.map +3 -3
  117. package/build/utils/transform-styles/index.cjs +3 -2
  118. package/build/utils/transform-styles/index.cjs.map +3 -3
  119. package/build/utils/transform-styles/postcss-urlrebase.d.cjs +2 -0
  120. package/build/utils/transform-styles/postcss-urlrebase.d.cjs.map +7 -0
  121. package/build/utils/transform-styles/types.cjs +19 -0
  122. package/build/utils/transform-styles/types.cjs.map +7 -0
  123. package/build/utils/types.cjs +19 -0
  124. package/build/utils/types.cjs.map +7 -0
  125. package/build-module/components/block-editing-mode/index.mjs +14 -8
  126. package/build-module/components/block-editing-mode/index.mjs.map +2 -2
  127. package/build-module/components/block-inspector/index.mjs +50 -51
  128. package/build-module/components/block-inspector/index.mjs.map +2 -2
  129. package/build-module/components/block-rename/modal.mjs +0 -1
  130. package/build-module/components/block-rename/modal.mjs.map +2 -2
  131. package/build-module/components/block-toolbar/block-toolbar-icon.mjs +14 -6
  132. package/build-module/components/block-toolbar/block-toolbar-icon.mjs.map +2 -2
  133. package/build-module/components/colors-gradients/control.mjs +27 -15
  134. package/build-module/components/colors-gradients/control.mjs.map +2 -2
  135. package/build-module/components/colors-gradients/dropdown.mjs +4 -1
  136. package/build-module/components/colors-gradients/dropdown.mjs.map +2 -2
  137. package/build-module/components/contrast-checker/index.mjs +18 -4
  138. package/build-module/components/contrast-checker/index.mjs.map +2 -2
  139. package/build-module/components/date-format-picker/index.mjs +0 -1
  140. package/build-module/components/date-format-picker/index.mjs.map +2 -2
  141. package/build-module/components/global-styles/background-panel.mjs +155 -27
  142. package/build-module/components/global-styles/background-panel.mjs.map +2 -2
  143. package/build-module/components/global-styles/color-gradient-dropdown-item.mjs +207 -0
  144. package/build-module/components/global-styles/color-gradient-dropdown-item.mjs.map +7 -0
  145. package/build-module/components/global-styles/color-panel.mjs +106 -387
  146. package/build-module/components/global-styles/color-panel.mjs.map +3 -3
  147. package/build-module/components/global-styles/dimensions-panel.mjs +0 -3
  148. package/build-module/components/global-styles/dimensions-panel.mjs.map +2 -2
  149. package/build-module/components/global-styles/hooks.mjs +33 -0
  150. package/build-module/components/global-styles/hooks.mjs.map +2 -2
  151. package/build-module/components/global-styles/typography-panel.mjs +84 -10
  152. package/build-module/components/global-styles/typography-panel.mjs.map +2 -2
  153. package/build-module/components/inspector-controls/groups.mjs +2 -0
  154. package/build-module/components/inspector-controls/groups.mjs.map +2 -2
  155. package/build-module/components/inspector-controls-tabs/styles-tab.mjs +75 -31
  156. package/build-module/components/inspector-controls-tabs/styles-tab.mjs.map +2 -2
  157. package/build-module/components/link-control/index.mjs +1 -2
  158. package/build-module/components/link-control/index.mjs.map +2 -2
  159. package/build-module/components/list-view/block-select-button.mjs +2 -17
  160. package/build-module/components/list-view/block-select-button.mjs.map +2 -2
  161. package/build-module/components/provider/use-block-sync.mjs +3 -1
  162. package/build-module/components/provider/use-block-sync.mjs.map +2 -2
  163. package/build-module/components/url-popover/image-url-input-ui.mjs +0 -2
  164. package/build-module/components/url-popover/image-url-input-ui.mjs.map +2 -2
  165. package/build-module/components/use-block-display-information/index.mjs +10 -3
  166. package/build-module/components/use-block-display-information/index.mjs.map +2 -2
  167. package/build-module/components/use-resize-canvas/index.mjs +6 -53
  168. package/build-module/components/use-resize-canvas/index.mjs.map +2 -2
  169. package/build-module/hooks/anchor.mjs +0 -1
  170. package/build-module/hooks/anchor.mjs.map +2 -2
  171. package/build-module/hooks/background.mjs +123 -75
  172. package/build-module/hooks/background.mjs.map +2 -2
  173. package/build-module/hooks/color.mjs +2 -175
  174. package/build-module/hooks/color.mjs.map +2 -2
  175. package/build-module/hooks/contrast-checker.mjs +32 -19
  176. package/build-module/hooks/contrast-checker.mjs.map +2 -2
  177. package/build-module/hooks/custom-class-name.mjs +0 -1
  178. package/build-module/hooks/custom-class-name.mjs.map +2 -2
  179. package/build-module/hooks/elements.mjs +115 -0
  180. package/build-module/hooks/elements.mjs.map +7 -0
  181. package/build-module/hooks/grid-visualizer.mjs +21 -11
  182. package/build-module/hooks/grid-visualizer.mjs.map +2 -2
  183. package/build-module/hooks/layout-child.mjs +41 -8
  184. package/build-module/hooks/layout-child.mjs.map +2 -2
  185. package/build-module/hooks/layout.mjs +6 -3
  186. package/build-module/hooks/layout.mjs.map +2 -2
  187. package/build-module/hooks/states.mjs +15 -23
  188. package/build-module/hooks/states.mjs.map +2 -2
  189. package/build-module/hooks/style.mjs +9 -5
  190. package/build-module/hooks/style.mjs.map +2 -2
  191. package/build-module/hooks/typography.mjs +62 -10
  192. package/build-module/hooks/typography.mjs.map +2 -2
  193. package/build-module/layouts/flex.mjs +105 -7
  194. package/build-module/layouts/flex.mjs.map +2 -2
  195. package/build-module/private-apis.mjs +0 -2
  196. package/build-module/private-apis.mjs.map +2 -2
  197. package/build-module/store/private-actions.mjs +14 -0
  198. package/build-module/store/private-actions.mjs.map +2 -2
  199. package/build-module/store/private-keys.mjs +0 -2
  200. package/build-module/store/private-keys.mjs.map +2 -2
  201. package/build-module/store/private-selectors.mjs +22 -6
  202. package/build-module/store/private-selectors.mjs.map +2 -2
  203. package/build-module/store/reducer.mjs +17 -3
  204. package/build-module/store/reducer.mjs.map +2 -2
  205. package/build-module/utils/block-bindings.mjs +9 -9
  206. package/build-module/utils/block-bindings.mjs.map +3 -3
  207. package/build-module/utils/color-values.mjs +9 -1
  208. package/build-module/utils/color-values.mjs.map +3 -3
  209. package/build-module/utils/dom.mjs +2 -5
  210. package/build-module/utils/dom.mjs.map +3 -3
  211. package/build-module/utils/fit-text-frontend.mjs +6 -2
  212. package/build-module/utils/fit-text-frontend.mjs.map +3 -3
  213. package/build-module/utils/fit-text-utils.mjs +1 -1
  214. package/build-module/utils/fit-text-utils.mjs.map +3 -3
  215. package/build-module/utils/format-font-style.mjs +1 -1
  216. package/build-module/utils/format-font-style.mjs.map +3 -3
  217. package/build-module/utils/format-font-weight.mjs +1 -1
  218. package/build-module/utils/format-font-weight.mjs.map +3 -3
  219. package/build-module/utils/get-editor-region.mjs +4 -2
  220. package/build-module/utils/get-editor-region.mjs.map +3 -3
  221. package/build-module/utils/get-font-styles-and-weights.mjs +8 -12
  222. package/build-module/utils/get-font-styles-and-weights.mjs.map +3 -3
  223. package/build-module/utils/get-px-from-css-unit.mjs +1 -1
  224. package/build-module/utils/get-px-from-css-unit.mjs.map +1 -1
  225. package/build-module/utils/index.mjs +1 -1
  226. package/build-module/utils/index.mjs.map +1 -1
  227. package/build-module/utils/math.mjs +1 -1
  228. package/build-module/utils/math.mjs.map +3 -3
  229. package/build-module/utils/object.mjs +8 -8
  230. package/build-module/utils/object.mjs.map +3 -3
  231. package/build-module/utils/order-inserter-block-items.mjs +1 -1
  232. package/build-module/utils/order-inserter-block-items.mjs.map +3 -3
  233. package/build-module/utils/pasting.mjs +4 -2
  234. package/build-module/utils/pasting.mjs.map +3 -3
  235. package/build-module/utils/selection.mjs +2 -1
  236. package/build-module/utils/selection.mjs.map +3 -3
  237. package/build-module/utils/sorting.mjs +9 -3
  238. package/build-module/utils/sorting.mjs.map +3 -3
  239. package/build-module/utils/transform-styles/index.mjs +3 -2
  240. package/build-module/utils/transform-styles/index.mjs.map +3 -3
  241. package/build-module/utils/transform-styles/postcss-urlrebase.d.mjs +1 -0
  242. package/build-module/utils/transform-styles/postcss-urlrebase.d.mjs.map +7 -0
  243. package/build-module/utils/transform-styles/types.mjs +1 -0
  244. package/build-module/utils/transform-styles/types.mjs.map +7 -0
  245. package/build-module/utils/types.mjs +1 -0
  246. package/build-module/utils/types.mjs.map +7 -0
  247. package/build-style/content-rtl.css +2 -0
  248. package/build-style/content.css +2 -0
  249. package/build-style/style-rtl.css +34 -41
  250. package/build-style/style.css +34 -41
  251. package/build-types/utils/block-bindings.d.ts +27 -0
  252. package/build-types/utils/block-bindings.d.ts.map +1 -0
  253. package/build-types/utils/color-values.d.ts +40 -0
  254. package/build-types/utils/color-values.d.ts.map +1 -0
  255. package/build-types/utils/dom.d.ts +19 -19
  256. package/build-types/utils/dom.d.ts.map +1 -1
  257. package/build-types/utils/fit-text-frontend.d.ts +7 -0
  258. package/build-types/utils/fit-text-frontend.d.ts.map +1 -0
  259. package/build-types/utils/fit-text-utils.d.ts +15 -0
  260. package/build-types/utils/fit-text-utils.d.ts.map +1 -0
  261. package/build-types/utils/format-font-style.d.ts +12 -0
  262. package/build-types/utils/format-font-style.d.ts.map +1 -0
  263. package/build-types/utils/format-font-weight.d.ts +12 -0
  264. package/build-types/utils/format-font-weight.d.ts.map +1 -0
  265. package/build-types/utils/get-editor-region.d.ts +9 -0
  266. package/build-types/utils/get-editor-region.d.ts.map +1 -0
  267. package/build-types/utils/get-font-styles-and-weights.d.ts +16 -0
  268. package/build-types/utils/get-font-styles-and-weights.d.ts.map +1 -0
  269. package/build-types/utils/get-px-from-css-unit.d.ts +10 -0
  270. package/build-types/utils/get-px-from-css-unit.d.ts.map +1 -0
  271. package/build-types/utils/index.d.ts +3 -0
  272. package/build-types/utils/index.d.ts.map +1 -0
  273. package/build-types/utils/math.d.ts +61 -0
  274. package/build-types/utils/math.d.ts.map +1 -0
  275. package/build-types/utils/object.d.ts +39 -0
  276. package/build-types/utils/object.d.ts.map +1 -0
  277. package/build-types/utils/order-inserter-block-items.d.ts +13 -0
  278. package/build-types/utils/order-inserter-block-items.d.ts.map +1 -0
  279. package/build-types/utils/pasting.d.ts +28 -0
  280. package/build-types/utils/pasting.d.ts.map +1 -0
  281. package/build-types/utils/selection.d.ts +21 -0
  282. package/build-types/utils/selection.d.ts.map +1 -0
  283. package/build-types/utils/sorting.d.ts +17 -0
  284. package/build-types/utils/sorting.d.ts.map +1 -0
  285. package/build-types/utils/transform-styles/index.d.ts +15 -0
  286. package/build-types/utils/transform-styles/index.d.ts.map +1 -0
  287. package/build-types/utils/transform-styles/types.d.ts +13 -0
  288. package/build-types/utils/transform-styles/types.d.ts.map +1 -0
  289. package/build-types/utils/types.d.ts +28 -0
  290. package/build-types/utils/types.d.ts.map +1 -0
  291. package/package.json +40 -39
  292. package/src/components/alignment-control/test/__snapshots__/index.js.snap +6 -0
  293. package/src/components/block-alignment-control/test/__snapshots__/index.js.snap +5 -0
  294. package/src/components/block-editing-mode/index.js +17 -9
  295. package/src/components/block-icon/test/__snapshots__/index.js.snap +1 -0
  296. package/src/components/block-inspector/index.js +43 -53
  297. package/src/components/block-rename/modal.js +0 -1
  298. package/src/components/block-toolbar/block-toolbar-icon.js +22 -6
  299. package/src/components/block-toolbar/test/block-toolbar-icon.js +99 -0
  300. package/src/components/block-vertical-alignment-control/test/__snapshots__/index.js.snap +4 -0
  301. package/src/components/colors-gradients/control.js +29 -12
  302. package/src/components/colors-gradients/dropdown.js +4 -1
  303. package/src/components/colors-gradients/style.scss +39 -2
  304. package/src/components/contrast-checker/README.md +9 -0
  305. package/src/components/contrast-checker/index.js +42 -3
  306. package/src/components/date-format-picker/index.js +0 -1
  307. package/src/components/default-block-appender/content.scss +3 -0
  308. package/src/components/global-styles/background-panel.js +201 -34
  309. package/src/components/global-styles/color-gradient-dropdown-item.js +258 -0
  310. package/src/components/global-styles/color-panel.js +125 -487
  311. package/src/components/global-styles/dimensions-panel.js +0 -3
  312. package/src/components/global-styles/hooks.js +45 -0
  313. package/src/components/global-styles/test/background-panel.js +56 -0
  314. package/src/components/global-styles/test/color-panel.js +172 -118
  315. package/src/components/global-styles/test/typography-panel.js +167 -0
  316. package/src/components/global-styles/typography-panel.js +100 -11
  317. package/src/components/inspector-controls/README.md +0 -2
  318. package/src/components/inspector-controls/groups.js +2 -0
  319. package/src/components/inspector-controls-tabs/styles-tab.js +74 -28
  320. package/src/components/link-control/index.js +0 -1
  321. package/src/components/link-control/test/index.js +2 -3
  322. package/src/components/list-view/block-select-button.js +2 -17
  323. package/src/components/provider/use-block-sync.js +3 -1
  324. package/src/components/rich-text/content.scss +2 -0
  325. package/src/components/url-popover/image-url-input-ui.js +0 -2
  326. package/src/components/use-block-display-information/index.js +15 -2
  327. package/src/components/use-block-display-information/test/index.js +140 -0
  328. package/src/components/use-resize-canvas/index.js +10 -71
  329. package/src/hooks/anchor.js +0 -1
  330. package/src/hooks/background.js +210 -133
  331. package/src/hooks/background.scss +0 -35
  332. package/src/hooks/color.js +2 -205
  333. package/src/hooks/color.scss +3 -9
  334. package/src/hooks/contrast-checker.js +60 -17
  335. package/src/hooks/custom-class-name.js +0 -1
  336. package/src/hooks/elements.js +140 -0
  337. package/src/hooks/elements.scss +8 -0
  338. package/src/hooks/grid-visualizer.js +59 -45
  339. package/src/hooks/layout-child.js +51 -12
  340. package/src/hooks/layout.js +6 -3
  341. package/src/hooks/states.js +32 -28
  342. package/src/hooks/style.js +11 -7
  343. package/src/hooks/test/background.js +59 -0
  344. package/src/hooks/test/block-style-state.js +14 -14
  345. package/src/hooks/test/layout.js +6 -6
  346. package/src/hooks/test/style.js +8 -8
  347. package/src/hooks/typography.js +70 -6
  348. package/src/layouts/flex.js +118 -15
  349. package/src/private-apis.js +0 -2
  350. package/src/store/private-actions.js +31 -0
  351. package/src/store/private-keys.js +0 -1
  352. package/src/store/private-selectors.js +43 -7
  353. package/src/store/reducer.js +37 -2
  354. package/src/store/test/private-selectors.js +39 -14
  355. package/src/store/test/reducer.js +91 -12
  356. package/src/style.scss +1 -0
  357. package/src/utils/block-bindings.ts +51 -0
  358. package/src/utils/color-values.ts +63 -0
  359. package/src/utils/{dom.js → dom.ts} +27 -27
  360. package/src/utils/{fit-text-frontend.js → fit-text-frontend.ts} +12 -4
  361. package/src/utils/{fit-text-utils.js → fit-text-utils.ts} +15 -7
  362. package/src/utils/{format-font-style.js → format-font-style.ts} +10 -3
  363. package/src/utils/{format-font-weight.js → format-font-weight.ts} +10 -3
  364. package/src/utils/{get-editor-region.js → get-editor-region.ts} +10 -6
  365. package/src/utils/{get-font-styles-and-weights.js → get-font-styles-and-weights.ts} +21 -17
  366. package/src/utils/{math.js → math.ts} +37 -30
  367. package/src/utils/object.ts +89 -0
  368. package/src/utils/{order-inserter-block-items.js → order-inserter-block-items.ts} +8 -5
  369. package/src/utils/{pasting.js → pasting.ts} +18 -11
  370. package/src/utils/{selection.js → selection.ts} +11 -4
  371. package/src/utils/sorting.ts +81 -0
  372. package/src/utils/test/color-values.js +44 -1
  373. package/src/utils/transform-styles/{index.js → index.ts} +25 -25
  374. package/src/utils/transform-styles/postcss-urlrebase.d.ts +15 -0
  375. package/src/utils/transform-styles/types.ts +13 -0
  376. package/src/utils/types.ts +29 -0
  377. package/src/components/use-resize-canvas/README.md +0 -37
  378. package/src/utils/block-bindings.js +0 -46
  379. package/src/utils/color-values.js +0 -28
  380. package/src/utils/object.js +0 -67
  381. package/src/utils/sorting.js +0 -54
  382. /package/src/utils/{get-px-from-css-unit.js → get-px-from-css-unit.ts} +0 -0
  383. /package/src/utils/{index.js → index.ts} +0 -0
@@ -602,7 +602,6 @@ export default function DimensionsPanel( {
602
602
  >
603
603
  { ! showSpacingPresetsControl && (
604
604
  <BoxControl
605
- __next40pxDefaultSize
606
605
  values={ paddingValues }
607
606
  onChange={ setPaddingValues }
608
607
  label={ __( 'Padding' ) }
@@ -645,7 +644,6 @@ export default function DimensionsPanel( {
645
644
  >
646
645
  { ! showSpacingPresetsControl && (
647
646
  <BoxControl
648
- __next40pxDefaultSize
649
647
  values={ marginValues }
650
648
  onChange={ setMarginValues }
651
649
  inputProps={ {
@@ -701,7 +699,6 @@ export default function DimensionsPanel( {
701
699
  { ! showSpacingPresetsControl &&
702
700
  ( isAxialGap ? (
703
701
  <BoxControl
704
- __next40pxDefaultSize
705
702
  label={ __( 'Block spacing' ) }
706
703
  min={ 0 }
707
704
  onChange={ setGapValues }
@@ -5,6 +5,7 @@ import { useMemo } from '@wordpress/element';
5
5
  import { useSelect } from '@wordpress/data';
6
6
  import { store as blocksStore } from '@wordpress/blocks';
7
7
  import { _x } from '@wordpress/i18n';
8
+ import { getValueFromVariable } from '@wordpress/global-styles-engine';
8
9
 
9
10
  /**
10
11
  * Internal dependencies
@@ -306,3 +307,47 @@ export function useGradientsPerOrigin( settings ) {
306
307
  shouldDisplayDefaultGradients,
307
308
  ] );
308
309
  }
310
+
311
+ /**
312
+ * Derives the color/gradient palette data and encode/decode helpers shared by
313
+ * the Color, Background, and Typography style panels, so the common preamble
314
+ * is defined once rather than repeated in each panel.
315
+ *
316
+ * @param {Object} settings Style settings object.
317
+ *
318
+ * @return {Object} Shared color/gradient palette data and helpers.
319
+ */
320
+ export function useColorGradientSettings( settings ) {
321
+ const colors = useColorsPerOrigin( settings );
322
+ const gradients = useGradientsPerOrigin( settings );
323
+ const areCustomSolidsEnabled = settings?.color?.custom;
324
+ const areCustomGradientsEnabled = settings?.color?.customGradient;
325
+ const allColors = useMemo(
326
+ () => colors.flatMap( ( { colors: originColors } ) => originColors ),
327
+ [ colors ]
328
+ );
329
+ const decodeValue = ( rawValue ) =>
330
+ getValueFromVariable( { settings }, '', rawValue );
331
+ const encodeGradientValue = ( gradientValue ) => {
332
+ const allGradients = gradients.flatMap(
333
+ ( { gradients: originGradients } ) => originGradients
334
+ );
335
+ const gradientObject = allGradients.find(
336
+ ( { gradient } ) => gradient === gradientValue
337
+ );
338
+ return gradientObject
339
+ ? 'var:preset|gradient|' + gradientObject.slug
340
+ : gradientValue;
341
+ };
342
+ return {
343
+ colors,
344
+ gradients,
345
+ allColors,
346
+ areCustomSolidsEnabled,
347
+ areCustomGradientsEnabled,
348
+ hasSolidColors: colors.length > 0 || areCustomSolidsEnabled,
349
+ hasGradientColors: gradients.length > 0 || areCustomGradientsEnabled,
350
+ decodeValue,
351
+ encodeGradientValue,
352
+ };
353
+ }
@@ -5,6 +5,8 @@
5
5
  import {
6
6
  hasBackgroundImageValue,
7
7
  hasBackgroundGradientValue,
8
+ hasBackgroundColorValue,
9
+ hasLegacyColorGradientValue,
8
10
  } from '../background-panel';
9
11
 
10
12
  describe( 'hasBackgroundImageValue', () => {
@@ -80,3 +82,57 @@ describe( 'hasBackgroundGradientValue', () => {
80
82
  expect( hasBackgroundGradientValue( undefined ) ).toBe( false );
81
83
  } );
82
84
  } );
85
+
86
+ describe( 'hasBackgroundColorValue', () => {
87
+ it( 'should return `true` when a background color string is set', () => {
88
+ expect(
89
+ hasBackgroundColorValue( { color: { background: '#ff0000' } } )
90
+ ).toBe( true );
91
+ } );
92
+
93
+ it( 'should return `true` for a preset slug reference', () => {
94
+ expect(
95
+ hasBackgroundColorValue( {
96
+ color: { background: 'var:preset|color|vivid-red' },
97
+ } )
98
+ ).toBe( true );
99
+ } );
100
+
101
+ it( 'should return `false` when background color is undefined', () => {
102
+ expect( hasBackgroundColorValue( { color: {} } ) ).toBe( false );
103
+ } );
104
+
105
+ it( 'should return `false` when color is undefined', () => {
106
+ expect( hasBackgroundColorValue( {} ) ).toBe( false );
107
+ } );
108
+
109
+ it( 'should return `false` when style is undefined', () => {
110
+ expect( hasBackgroundColorValue( undefined ) ).toBe( false );
111
+ } );
112
+ } );
113
+
114
+ describe( 'hasLegacyColorGradientValue', () => {
115
+ it( 'should return `true` when a legacy color.gradient string is set', () => {
116
+ expect(
117
+ hasLegacyColorGradientValue( {
118
+ color: { gradient: 'linear-gradient(135deg, red, blue)' },
119
+ } )
120
+ ).toBe( true );
121
+ } );
122
+
123
+ it( 'should return `false` when color.gradient is undefined', () => {
124
+ expect( hasLegacyColorGradientValue( { color: {} } ) ).toBe( false );
125
+ } );
126
+
127
+ it( 'should return `false` when style is undefined', () => {
128
+ expect( hasLegacyColorGradientValue( undefined ) ).toBe( false );
129
+ } );
130
+
131
+ it( 'should not be confused by background.gradient', () => {
132
+ expect(
133
+ hasLegacyColorGradientValue( {
134
+ background: { gradient: 'linear-gradient(red, blue)' },
135
+ } )
136
+ ).toBe( false );
137
+ } );
138
+ } );
@@ -1,135 +1,189 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { screen } from '@testing-library/react';
5
- import { click, render } from '@ariakit/test/react';
4
+ import { renderHook } from '@testing-library/react';
6
5
 
7
6
  /**
8
7
  * Internal dependencies
9
8
  */
10
- import ColorPanel from '../color-panel';
11
-
12
- // ---------------------------------------------------------------------------
13
- // Shared fixtures
14
- // ---------------------------------------------------------------------------
15
-
16
- // Two palette entries that share the same decoded hex value (#000) but carry
17
- // distinct slugs. This mirrors the duplicate-color scenario that motivated
18
- // the slug-based selection work.
19
- const DUPLICATE_PALETTE_SETTINGS = {
9
+ import {
10
+ useHasColorPanel,
11
+ useHasTextPanel,
12
+ useHasBackgroundColorPanel,
13
+ useHasLinkPanel,
14
+ useHasHeadingPanel,
15
+ useHasButtonPanel,
16
+ useHasCaptionPanel,
17
+ } from '../color-panel';
18
+
19
+ const settingsWithColors = ( overrides = {} ) => ( {
20
20
  color: {
21
- text: true,
22
- link: false, // keep the panel simple so button queries are unambiguous
23
- background: false,
24
- custom: false,
25
- customGradient: false,
26
- defaultPalette: false,
27
21
  palette: {
28
- theme: [
29
- {
30
- color: '#000',
31
- name: 'Dark Background',
32
- slug: 'dark-background',
33
- },
34
- { color: '#000', name: 'Dark Text', slug: 'dark-text' },
35
- ],
22
+ theme: [ { slug: 'red', color: '#ff0000', name: 'Red' } ],
36
23
  },
24
+ ...overrides,
37
25
  },
38
- };
39
-
40
- // ---------------------------------------------------------------------------
41
- // ColorPanel setTextColor behaviour (render tests)
42
- // ---------------------------------------------------------------------------
43
-
44
- describe( 'ColorPanel setTextColor', () => {
45
- // Helper: open the Text-color dropdown and return the rendered swatches.
46
- async function openTextDropdown() {
47
- await click(
48
- screen.getByRole( 'button', { name: /Text/, expanded: false } )
49
- );
50
- // `findAllByRole` waits for the Popover/portal content to appear.
51
- return screen.findAllByRole( 'option' );
52
- }
53
-
54
- it( 'encodes a slug-selected color as var:preset|color|<slug> rather than falling back to a hex-value lookup', async () => {
55
- const onChange = jest.fn();
56
-
57
- await render(
58
- <ColorPanel
59
- value={ {} }
60
- inheritedValue={ {} }
61
- settings={ DUPLICATE_PALETTE_SETTINGS }
62
- panelId="test"
63
- onChange={ onChange }
64
- />
65
- );
66
-
67
- const swatches = await openTextDropdown();
68
- // swatch[0] = 'dark-background', swatch[1] = 'dark-text'
69
- await click( swatches[ 1 ] );
70
-
71
- expect( onChange ).toHaveBeenCalledTimes( 1 );
72
- const result = onChange.mock.calls[ 0 ][ 0 ];
73
- // The slug must be encoded directly: not looked up by hex value.
74
- expect( result?.color?.text ).toBe( 'var:preset|color|dark-text' );
75
- } );
76
-
77
- it( 'syncs the link color when text and link share the same raw preset reference', async () => {
78
- const onChange = jest.fn();
79
- const sharedRef = 'var:preset|color|dark-background';
80
-
81
- await render(
82
- <ColorPanel
83
- value={ {} }
84
- inheritedValue={ {
85
- color: { text: sharedRef },
86
- elements: { link: { color: { text: sharedRef } } },
87
- } }
88
- settings={ DUPLICATE_PALETTE_SETTINGS }
89
- panelId="test"
90
- onChange={ onChange }
91
- />
92
- );
93
-
94
- const swatches = await openTextDropdown();
95
- await click( swatches[ 1 ] );
96
-
97
- const result = onChange.mock.calls[ 0 ][ 0 ];
98
- expect( result?.color?.text ).toBe( 'var:preset|color|dark-text' );
99
- // Link must be kept in sync because text and link shared the same ref.
100
- expect( result?.elements?.link?.color?.text ).toBe(
101
- 'var:preset|color|dark-text'
102
- );
103
- } );
104
-
105
- it( 'does NOT sync the link color when text and link have different raw refs, even if their decoded hex values match', async () => {
106
- const onChange = jest.fn();
107
-
108
- await render(
109
- <ColorPanel
110
- value={ {} }
111
- inheritedValue={ {
112
- // Both resolve to #000, but they are different preset references.
113
- color: { text: 'var:preset|color|dark-background' },
114
- elements: {
115
- link: {
116
- color: { text: 'var:preset|color|dark-text' },
117
- },
26
+ } );
27
+
28
+ describe( 'useHasColorPanel', () => {
29
+ // After moving top-level text color to TypographyPanel and top-level
30
+ // background color to BackgroundPanel, the Color panel only aggregates
31
+ // link and element controls (heading, button, caption).
32
+ it( 'should be false when only text color is enabled', () => {
33
+ const { result } = renderHook( () =>
34
+ useHasColorPanel( settingsWithColors( { text: true } ) )
35
+ );
36
+ expect( result.current ).toBeFalsy();
37
+ } );
38
+
39
+ it( 'should be false when only background color is enabled', () => {
40
+ const { result } = renderHook( () =>
41
+ useHasColorPanel( settingsWithColors( { background: true } ) )
42
+ );
43
+ expect( result.current ).toBeFalsy();
44
+ } );
45
+
46
+ it( 'should be false when both text and background are enabled but no element controls are', () => {
47
+ const { result } = renderHook( () =>
48
+ useHasColorPanel(
49
+ settingsWithColors( { text: true, background: true } )
50
+ )
51
+ );
52
+ expect( result.current ).toBeFalsy();
53
+ } );
54
+
55
+ it( 'should be true when link color is enabled', () => {
56
+ const { result } = renderHook( () =>
57
+ useHasColorPanel( settingsWithColors( { link: true } ) )
58
+ );
59
+ expect( result.current ).toBeTruthy();
60
+ } );
61
+
62
+ it( 'should be true when heading element is enabled', () => {
63
+ const { result } = renderHook( () =>
64
+ useHasColorPanel( settingsWithColors( { heading: true } ) )
65
+ );
66
+ expect( result.current ).toBeTruthy();
67
+ } );
68
+
69
+ it( 'should be true when button element is enabled', () => {
70
+ const { result } = renderHook( () =>
71
+ useHasColorPanel( settingsWithColors( { button: true } ) )
72
+ );
73
+ expect( result.current ).toBeTruthy();
74
+ } );
75
+
76
+ it( 'should be true when caption element is enabled', () => {
77
+ const { result } = renderHook( () =>
78
+ useHasColorPanel( settingsWithColors( { caption: true } ) )
79
+ );
80
+ expect( result.current ).toBeTruthy();
81
+ } );
82
+
83
+ it( 'should be false when no color controls are enabled', () => {
84
+ const { result } = renderHook( () => useHasColorPanel( {} ) );
85
+ expect( result.current ).toBeFalsy();
86
+ } );
87
+ } );
88
+
89
+ describe( 'useHasTextPanel', () => {
90
+ // Still exported for TypographyPanel to consume as its text color gate.
91
+ it( 'should be true when text color is enabled and colors exist', () => {
92
+ const { result } = renderHook( () =>
93
+ useHasTextPanel( settingsWithColors( { text: true } ) )
94
+ );
95
+ expect( result.current ).toBeTruthy();
96
+ } );
97
+
98
+ it( 'should be true when text color is enabled with custom colors support', () => {
99
+ const { result } = renderHook( () =>
100
+ useHasTextPanel( { color: { text: true, custom: true } } )
101
+ );
102
+ expect( result.current ).toBeTruthy();
103
+ } );
104
+
105
+ it( 'should be false when text color is disabled', () => {
106
+ const { result } = renderHook( () =>
107
+ useHasTextPanel( settingsWithColors( { text: false } ) )
108
+ );
109
+ expect( result.current ).toBeFalsy();
110
+ } );
111
+
112
+ it( 'should be false when no colors or custom support exist', () => {
113
+ const { result } = renderHook( () =>
114
+ useHasTextPanel( { color: { text: true } } )
115
+ );
116
+ expect( result.current ).toBeFalsy();
117
+ } );
118
+ } );
119
+
120
+ describe( 'useHasBackgroundColorPanel', () => {
121
+ // Still exported for BackgroundPanel to consume as its background color gate.
122
+ it( 'should be true when background is enabled and colors exist', () => {
123
+ const { result } = renderHook( () =>
124
+ useHasBackgroundColorPanel(
125
+ settingsWithColors( { background: true } )
126
+ )
127
+ );
128
+ expect( result.current ).toBeTruthy();
129
+ } );
130
+
131
+ it( 'should be true when only gradients are available', () => {
132
+ const { result } = renderHook( () =>
133
+ useHasBackgroundColorPanel( {
134
+ color: {
135
+ background: true,
136
+ gradients: {
137
+ theme: [
138
+ {
139
+ slug: 'cyan',
140
+ gradient: 'linear-gradient(cyan, blue)',
141
+ name: 'Cyan',
142
+ },
143
+ ],
118
144
  },
119
- } }
120
- settings={ DUPLICATE_PALETTE_SETTINGS }
121
- panelId="test"
122
- onChange={ onChange }
123
- />
145
+ },
146
+ } )
147
+ );
148
+ expect( result.current ).toBeTruthy();
149
+ } );
150
+
151
+ it( 'should be false when background color is disabled', () => {
152
+ const { result } = renderHook( () =>
153
+ useHasBackgroundColorPanel(
154
+ settingsWithColors( { background: false } )
155
+ )
124
156
  );
157
+ expect( result.current ).toBeFalsy();
158
+ } );
159
+ } );
125
160
 
126
- const swatches = await openTextDropdown();
127
- await click( swatches[ 1 ] );
161
+ describe( 'element color hooks', () => {
162
+ it( 'useHasLinkPanel is truthy when link is enabled with colors', () => {
163
+ const { result } = renderHook( () =>
164
+ useHasLinkPanel( settingsWithColors( { link: true } ) )
165
+ );
166
+ expect( result.current ).toBeTruthy();
167
+ } );
128
168
 
129
- const result = onChange.mock.calls[ 0 ][ 0 ];
130
- expect( result?.color?.text ).toBe( 'var:preset|color|dark-text' );
131
- // Link must NOT be updated: raw-ref identity is what matters,
132
- // not decoded-value equality.
133
- expect( result?.elements?.link?.color?.text ).toBeUndefined();
169
+ it( 'useHasHeadingPanel is truthy when heading is enabled with colors', () => {
170
+ const { result } = renderHook( () =>
171
+ useHasHeadingPanel( settingsWithColors( { heading: true } ) )
172
+ );
173
+ expect( result.current ).toBeTruthy();
174
+ } );
175
+
176
+ it( 'useHasButtonPanel is truthy when button is enabled with colors', () => {
177
+ const { result } = renderHook( () =>
178
+ useHasButtonPanel( settingsWithColors( { button: true } ) )
179
+ );
180
+ expect( result.current ).toBeTruthy();
181
+ } );
182
+
183
+ it( 'useHasCaptionPanel is truthy when caption is enabled with colors', () => {
184
+ const { result } = renderHook( () =>
185
+ useHasCaptionPanel( settingsWithColors( { caption: true } ) )
186
+ );
187
+ expect( result.current ).toBeTruthy();
134
188
  } );
135
189
  } );
@@ -0,0 +1,167 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { renderHook, screen } from '@testing-library/react';
5
+ import { click, render } from '@ariakit/test/react';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import TypographyPanel, { useHasTypographyPanel } from '../typography-panel';
11
+
12
+ const settingsWithColors = ( overrides = {} ) => ( {
13
+ color: {
14
+ palette: {
15
+ theme: [ { slug: 'red', color: '#ff0000', name: 'Red' } ],
16
+ },
17
+ ...overrides,
18
+ },
19
+ } );
20
+
21
+ describe( 'useHasTypographyPanel', () => {
22
+ // After moving top-level text color into TypographyPanel, text color
23
+ // alone should be enough to open the panel.
24
+ it( 'should be true when only text color is enabled', () => {
25
+ const { result } = renderHook( () =>
26
+ useHasTypographyPanel( settingsWithColors( { text: true } ) )
27
+ );
28
+ expect( result.current ).toBeTruthy();
29
+ } );
30
+
31
+ it( 'should be true when only font family is enabled', () => {
32
+ const { result } = renderHook( () =>
33
+ useHasTypographyPanel( {
34
+ typography: {
35
+ fontFamilies: {
36
+ theme: [ { slug: 'sans', fontFamily: 'sans-serif' } ],
37
+ },
38
+ },
39
+ } )
40
+ );
41
+ expect( result.current ).toBeTruthy();
42
+ } );
43
+
44
+ it( 'should be true when only line height is enabled', () => {
45
+ const { result } = renderHook( () =>
46
+ useHasTypographyPanel( { typography: { lineHeight: true } } )
47
+ );
48
+ expect( result.current ).toBeTruthy();
49
+ } );
50
+
51
+ it( 'should be false when no typography or text color controls are enabled', () => {
52
+ const { result } = renderHook( () => useHasTypographyPanel( {} ) );
53
+ expect( result.current ).toBeFalsy();
54
+ } );
55
+
56
+ it( 'should be false when text color is enabled but no colors or custom support exist', () => {
57
+ const { result } = renderHook( () =>
58
+ useHasTypographyPanel( { color: { text: true } } )
59
+ );
60
+ expect( result.current ).toBeFalsy();
61
+ } );
62
+
63
+ it( 'should be true when text color is enabled with custom colors support', () => {
64
+ const { result } = renderHook( () =>
65
+ useHasTypographyPanel( { color: { text: true, custom: true } } )
66
+ );
67
+ expect( result.current ).toBeTruthy();
68
+ } );
69
+ } );
70
+
71
+ // ---------------------------------------------------------------------------
72
+ // TypographyPanel — setTextColor link-sync behaviour (render tests)
73
+ // ---------------------------------------------------------------------------
74
+
75
+ // Setting the text color should keep an in-sync link color following it (e.g.
76
+ // a Button's link color tracks its text color). The two palette entries below
77
+ // share the same decoded hex value (#000) but carry distinct slugs, ensuring
78
+ // the sync keys off the raw preset reference rather than the decoded hex.
79
+ const DUPLICATE_PALETTE_SETTINGS = {
80
+ color: {
81
+ text: true,
82
+ custom: false,
83
+ customGradient: false,
84
+ defaultPalette: false,
85
+ palette: {
86
+ theme: [
87
+ {
88
+ color: '#000',
89
+ name: 'Dark Background',
90
+ slug: 'dark-background',
91
+ },
92
+ { color: '#000', name: 'Dark Text', slug: 'dark-text' },
93
+ ],
94
+ },
95
+ },
96
+ };
97
+
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 } )
103
+ );
104
+ // `findAllByRole` waits for the Popover/portal content to appear.
105
+ return screen.findAllByRole( 'option' );
106
+ }
107
+
108
+ it( 'syncs the link color when text and link share the same raw preset reference', async () => {
109
+ const onChange = jest.fn();
110
+ const sharedRef = 'var:preset|color|dark-background';
111
+
112
+ await render(
113
+ <TypographyPanel
114
+ value={ {} }
115
+ inheritedValue={ {
116
+ color: { text: sharedRef },
117
+ elements: { link: { color: { text: sharedRef } } },
118
+ } }
119
+ settings={ DUPLICATE_PALETTE_SETTINGS }
120
+ panelId="test"
121
+ onChange={ onChange }
122
+ />
123
+ );
124
+
125
+ const swatches = await openTextColorDropdown();
126
+ // swatch[0] = 'dark-background', swatch[1] = 'dark-text'
127
+ await click( swatches[ 1 ] );
128
+
129
+ const result = onChange.mock.calls[ 0 ][ 0 ];
130
+ expect( result?.color?.text ).toBe( 'var:preset|color|dark-text' );
131
+ // Link must follow because text and link shared the same ref.
132
+ expect( result?.elements?.link?.color?.text ).toBe(
133
+ 'var:preset|color|dark-text'
134
+ );
135
+ } );
136
+
137
+ it( 'does NOT sync the link color when text and link have different raw refs, even if their decoded hex values match', async () => {
138
+ const onChange = jest.fn();
139
+
140
+ await render(
141
+ <TypographyPanel
142
+ value={ {} }
143
+ inheritedValue={ {
144
+ // Both resolve to #000, but they are different preset references.
145
+ color: { text: 'var:preset|color|dark-background' },
146
+ elements: {
147
+ link: {
148
+ color: { text: 'var:preset|color|dark-text' },
149
+ },
150
+ },
151
+ } }
152
+ settings={ DUPLICATE_PALETTE_SETTINGS }
153
+ panelId="test"
154
+ onChange={ onChange }
155
+ />
156
+ );
157
+
158
+ const swatches = await openTextColorDropdown();
159
+ await click( swatches[ 1 ] );
160
+
161
+ const result = onChange.mock.calls[ 0 ][ 0 ];
162
+ expect( result?.color?.text ).toBe( 'var:preset|color|dark-text' );
163
+ // Link must NOT be updated: raw-ref identity is what matters,
164
+ // not decoded-value equality.
165
+ expect( result?.elements?.link?.color?.text ).toBeUndefined();
166
+ } );
167
+ } );