@wordpress/block-editor 16.0.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.
- package/CHANGELOG.md +18 -0
- package/README.md +8 -0
- package/build/components/alignment-control/ui.cjs +2 -4
- package/build/components/alignment-control/ui.cjs.map +2 -2
- package/build/components/background-image-control/index.cjs +40 -10
- package/build/components/background-image-control/index.cjs.map +2 -2
- package/build/components/block-alignment-control/ui.cjs +5 -3
- package/build/components/block-alignment-control/ui.cjs.map +2 -2
- package/build/components/block-inspector/index.cjs +73 -46
- package/build/components/block-inspector/index.cjs.map +2 -2
- package/build/components/block-list/block-html.cjs +4 -1
- package/build/components/block-list/block-html.cjs.map +2 -2
- package/build/components/block-list/use-block-props/index.cjs +5 -2
- package/build/components/block-list/use-block-props/index.cjs.map +2 -2
- package/build/components/block-list/use-block-props/use-focus-handler.cjs +2 -3
- package/build/components/block-list/use-block-props/use-focus-handler.cjs.map +2 -2
- package/build/components/block-list/use-block-props/use-register-block-event-handlers.cjs +48 -0
- package/build/components/block-list/use-block-props/use-register-block-event-handlers.cjs.map +7 -0
- package/build/components/block-parent-selector/index.cjs +2 -2
- package/build/components/block-parent-selector/index.cjs.map +2 -2
- package/build/components/block-toolbar/switch-section-style.cjs +4 -2
- package/build/components/block-toolbar/switch-section-style.cjs.map +3 -3
- package/build/components/block-tools/empty-block-inserter.cjs +2 -7
- package/build/components/block-tools/empty-block-inserter.cjs.map +2 -2
- package/build/components/block-vertical-alignment-control/ui.cjs +3 -5
- package/build/components/block-vertical-alignment-control/ui.cjs.map +2 -2
- package/build/components/border-radius-control/utils.cjs +8 -58
- package/build/components/border-radius-control/utils.cjs.map +2 -2
- package/build/components/colors-gradients/control.cjs +5 -3
- package/build/components/colors-gradients/control.cjs.map +2 -2
- package/build/components/dimension-control/index.cjs +30 -20
- package/build/components/dimension-control/index.cjs.map +3 -3
- package/build/components/dimensions-tool/aspect-ratio-tool.cjs +9 -2
- package/build/components/dimensions-tool/aspect-ratio-tool.cjs.map +3 -3
- package/build/components/editor-styles/index.cjs +9 -1
- package/build/components/editor-styles/index.cjs.map +2 -2
- package/build/components/global-styles/background-panel.cjs +66 -25
- package/build/components/global-styles/background-panel.cjs.map +3 -3
- package/build/components/global-styles/border-panel.cjs +153 -55
- package/build/components/global-styles/border-panel.cjs.map +3 -3
- package/build/components/global-styles/color-gradient-dropdown-item.cjs +46 -14
- package/build/components/global-styles/color-gradient-dropdown-item.cjs.map +3 -3
- package/build/components/global-styles/color-panel.cjs +63 -17
- package/build/components/global-styles/color-panel.cjs.map +2 -2
- package/build/components/global-styles/dimensions-panel.cjs +242 -64
- package/build/components/global-styles/dimensions-panel.cjs.map +3 -3
- package/build/components/global-styles/filters-panel.cjs +59 -20
- package/build/components/global-styles/filters-panel.cjs.map +3 -3
- package/build/components/global-styles/hooks.cjs +4 -1
- package/build/components/global-styles/hooks.cjs.map +2 -2
- package/build/components/global-styles/inheritance/index.cjs +142 -0
- package/build/components/global-styles/inheritance/index.cjs.map +7 -0
- package/build/components/global-styles/inherited-value-context.cjs +173 -0
- package/build/components/global-styles/inherited-value-context.cjs.map +7 -0
- package/build/components/global-styles/shadow-panel-components.cjs +38 -20
- package/build/components/global-styles/shadow-panel-components.cjs.map +2 -2
- package/build/components/global-styles/state-control.cjs +1 -1
- package/build/components/global-styles/state-control.cjs.map +2 -2
- package/build/components/global-styles/typography-panel.cjs +271 -78
- package/build/components/global-styles/typography-panel.cjs.map +3 -3
- package/build/components/inspector-controls-tabs/styles-tab.cjs +10 -1
- package/build/components/inspector-controls-tabs/styles-tab.cjs.map +2 -2
- package/build/components/line-height-control/index.cjs +1 -1
- package/build/components/line-height-control/index.cjs.map +2 -2
- package/build/components/link-control/index.cjs +3 -1
- package/build/components/link-control/index.cjs.map +2 -2
- package/build/components/preset-input-control/index.cjs +2 -1
- package/build/components/preset-input-control/index.cjs.map +2 -2
- package/build/components/provider/block-refs-provider.cjs +8 -2
- package/build/components/provider/block-refs-provider.cjs.map +2 -2
- package/build/components/provider/index.cjs +1 -1
- package/build/components/provider/index.cjs.map +2 -2
- package/build/components/provider/use-block-sync.cjs +18 -6
- package/build/components/provider/use-block-sync.cjs.map +2 -2
- package/build/components/provider/use-media-upload-settings.cjs +3 -1
- package/build/components/provider/use-media-upload-settings.cjs.map +2 -2
- package/build/components/rich-text/index.cjs +23 -13
- package/build/components/rich-text/index.cjs.map +2 -2
- package/build/components/spacing-sizes-control/utils.cjs +6 -19
- package/build/components/spacing-sizes-control/utils.cjs.map +2 -2
- package/build/components/text-indent-control/index.cjs +8 -2
- package/build/components/text-indent-control/index.cjs.map +2 -2
- package/build/components/url-input/index.cjs +303 -344
- package/build/components/url-input/index.cjs.map +3 -3
- package/build/components/writing-flow/index.cjs +2 -0
- package/build/components/writing-flow/index.cjs.map +3 -3
- package/build/components/writing-flow/use-arrow-nav.cjs +24 -1
- package/build/components/writing-flow/use-arrow-nav.cjs.map +2 -2
- package/build/components/writing-flow/use-click-selection.cjs +28 -2
- package/build/components/writing-flow/use-click-selection.cjs.map +2 -2
- package/build/components/writing-flow/use-editable-root-event-handlers.cjs +179 -0
- package/build/components/writing-flow/use-editable-root-event-handlers.cjs.map +7 -0
- package/build/components/writing-flow/use-editable-root.cjs +5 -42
- package/build/components/writing-flow/use-editable-root.cjs.map +2 -2
- package/build/components/writing-flow/use-home-end.cjs +1 -1
- package/build/components/writing-flow/use-home-end.cjs.map +2 -2
- package/build/components/writing-flow/use-selection-observer.cjs +17 -13
- package/build/components/writing-flow/use-selection-observer.cjs.map +2 -2
- package/build/components/writing-flow/utils.cjs +3 -14
- package/build/components/writing-flow/utils.cjs.map +2 -2
- package/build/hooks/background.cjs +13 -10
- package/build/hooks/background.cjs.map +2 -2
- package/build/hooks/block-style-variation.cjs +4 -45
- package/build/hooks/block-style-variation.cjs.map +3 -3
- package/build/hooks/border.cjs +19 -4
- package/build/hooks/border.cjs.map +2 -2
- package/build/hooks/custom-css.cjs +6 -2
- package/build/hooks/custom-css.cjs.map +2 -2
- package/build/hooks/dimensions.cjs +15 -4
- package/build/hooks/dimensions.cjs.map +2 -2
- package/build/hooks/duotone.cjs +26 -14
- package/build/hooks/duotone.cjs.map +3 -3
- package/build/hooks/elements.cjs +14 -4
- package/build/hooks/elements.cjs.map +2 -2
- package/build/hooks/line-height.cjs +1 -2
- package/build/hooks/line-height.cjs.map +2 -2
- package/build/hooks/typography.cjs +13 -4
- package/build/hooks/typography.cjs.map +2 -2
- package/build/private-apis.cjs +9 -5
- package/build/private-apis.cjs.map +3 -3
- package/build/store/actions.cjs +9 -4
- package/build/store/actions.cjs.map +2 -2
- package/build/store/private-selectors.cjs +28 -1
- package/build/store/private-selectors.cjs.map +2 -2
- package/build/store/reducer.cjs +6 -6
- package/build/store/reducer.cjs.map +2 -2
- package/build/store/selectors.cjs +23 -0
- package/build/store/selectors.cjs.map +2 -2
- package/build/utils/native-undo.cjs +55 -0
- package/build/utils/native-undo.cjs.map +7 -0
- package/build-module/components/alignment-control/ui.mjs +2 -4
- package/build-module/components/alignment-control/ui.mjs.map +2 -2
- package/build-module/components/background-image-control/index.mjs +43 -10
- package/build-module/components/background-image-control/index.mjs.map +2 -2
- package/build-module/components/block-alignment-control/ui.mjs +5 -3
- package/build-module/components/block-alignment-control/ui.mjs.map +2 -2
- package/build-module/components/block-inspector/index.mjs +74 -46
- package/build-module/components/block-inspector/index.mjs.map +2 -2
- package/build-module/components/block-list/block-html.mjs +4 -1
- package/build-module/components/block-list/block-html.mjs.map +2 -2
- package/build-module/components/block-list/use-block-props/index.mjs +5 -2
- package/build-module/components/block-list/use-block-props/index.mjs.map +2 -2
- package/build-module/components/block-list/use-block-props/use-focus-handler.mjs +2 -3
- package/build-module/components/block-list/use-block-props/use-focus-handler.mjs.map +2 -2
- package/build-module/components/block-list/use-block-props/use-register-block-event-handlers.mjs +28 -0
- package/build-module/components/block-list/use-block-props/use-register-block-event-handlers.mjs.map +7 -0
- package/build-module/components/block-parent-selector/index.mjs +2 -2
- package/build-module/components/block-parent-selector/index.mjs.map +2 -2
- package/build-module/components/block-toolbar/switch-section-style.mjs +4 -2
- package/build-module/components/block-toolbar/switch-section-style.mjs.map +2 -2
- package/build-module/components/block-tools/empty-block-inserter.mjs +2 -7
- package/build-module/components/block-tools/empty-block-inserter.mjs.map +2 -2
- package/build-module/components/block-vertical-alignment-control/ui.mjs +4 -6
- package/build-module/components/block-vertical-alignment-control/ui.mjs.map +2 -2
- package/build-module/components/border-radius-control/utils.mjs +11 -53
- package/build-module/components/border-radius-control/utils.mjs.map +2 -2
- package/build-module/components/colors-gradients/control.mjs +5 -3
- package/build-module/components/colors-gradients/control.mjs.map +2 -2
- package/build-module/components/dimension-control/index.mjs +30 -20
- package/build-module/components/dimension-control/index.mjs.map +2 -2
- package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs +10 -6
- package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs.map +2 -2
- package/build-module/components/editor-styles/index.mjs +9 -1
- package/build-module/components/editor-styles/index.mjs.map +2 -2
- package/build-module/components/global-styles/background-panel.mjs +71 -29
- package/build-module/components/global-styles/background-panel.mjs.map +2 -2
- package/build-module/components/global-styles/border-panel.mjs +157 -56
- package/build-module/components/global-styles/border-panel.mjs.map +2 -2
- package/build-module/components/global-styles/color-gradient-dropdown-item.mjs +51 -15
- package/build-module/components/global-styles/color-gradient-dropdown-item.mjs.map +2 -2
- package/build-module/components/global-styles/color-panel.mjs +63 -17
- package/build-module/components/global-styles/color-panel.mjs.map +2 -2
- package/build-module/components/global-styles/dimensions-panel.mjs +248 -66
- package/build-module/components/global-styles/dimensions-panel.mjs.map +2 -2
- package/build-module/components/global-styles/filters-panel.mjs +64 -21
- package/build-module/components/global-styles/filters-panel.mjs.map +2 -2
- package/build-module/components/global-styles/hooks.mjs +4 -1
- package/build-module/components/global-styles/hooks.mjs.map +2 -2
- package/build-module/components/global-styles/inheritance/index.mjs +108 -0
- package/build-module/components/global-styles/inheritance/index.mjs.map +7 -0
- package/build-module/components/global-styles/inherited-value-context.mjs +141 -0
- package/build-module/components/global-styles/inherited-value-context.mjs.map +7 -0
- package/build-module/components/global-styles/shadow-panel-components.mjs +38 -20
- package/build-module/components/global-styles/shadow-panel-components.mjs.map +2 -2
- package/build-module/components/global-styles/state-control.mjs +1 -1
- package/build-module/components/global-styles/state-control.mjs.map +2 -2
- package/build-module/components/global-styles/typography-panel.mjs +276 -79
- package/build-module/components/global-styles/typography-panel.mjs.map +2 -2
- package/build-module/components/inspector-controls-tabs/styles-tab.mjs +6 -1
- package/build-module/components/inspector-controls-tabs/styles-tab.mjs.map +2 -2
- package/build-module/components/line-height-control/index.mjs +1 -1
- package/build-module/components/line-height-control/index.mjs.map +2 -2
- package/build-module/components/link-control/index.mjs +4 -2
- package/build-module/components/link-control/index.mjs.map +2 -2
- package/build-module/components/preset-input-control/index.mjs +2 -1
- package/build-module/components/preset-input-control/index.mjs.map +2 -2
- package/build-module/components/provider/block-refs-provider.mjs +8 -2
- package/build-module/components/provider/block-refs-provider.mjs.map +2 -2
- package/build-module/components/provider/index.mjs +1 -1
- package/build-module/components/provider/index.mjs.map +2 -2
- package/build-module/components/provider/use-block-sync.mjs +18 -6
- package/build-module/components/provider/use-block-sync.mjs.map +2 -2
- package/build-module/components/provider/use-media-upload-settings.mjs +3 -1
- package/build-module/components/provider/use-media-upload-settings.mjs.map +2 -2
- package/build-module/components/rich-text/index.mjs +28 -14
- package/build-module/components/rich-text/index.mjs.map +2 -2
- package/build-module/components/spacing-sizes-control/utils.mjs +6 -18
- package/build-module/components/spacing-sizes-control/utils.mjs.map +2 -2
- package/build-module/components/text-indent-control/index.mjs +8 -2
- package/build-module/components/text-indent-control/index.mjs.map +2 -2
- package/build-module/components/url-input/index.mjs +306 -353
- package/build-module/components/url-input/index.mjs.map +2 -2
- package/build-module/components/writing-flow/index.mjs +2 -0
- package/build-module/components/writing-flow/index.mjs.map +2 -2
- package/build-module/components/writing-flow/use-arrow-nav.mjs +24 -1
- package/build-module/components/writing-flow/use-arrow-nav.mjs.map +2 -2
- package/build-module/components/writing-flow/use-click-selection.mjs +28 -2
- package/build-module/components/writing-flow/use-click-selection.mjs.map +2 -2
- package/build-module/components/writing-flow/use-editable-root-event-handlers.mjs +154 -0
- package/build-module/components/writing-flow/use-editable-root-event-handlers.mjs.map +7 -0
- package/build-module/components/writing-flow/use-editable-root.mjs +5 -37
- package/build-module/components/writing-flow/use-editable-root.mjs.map +2 -2
- package/build-module/components/writing-flow/use-home-end.mjs +1 -1
- package/build-module/components/writing-flow/use-home-end.mjs.map +2 -2
- package/build-module/components/writing-flow/use-selection-observer.mjs +18 -14
- package/build-module/components/writing-flow/use-selection-observer.mjs.map +2 -2
- package/build-module/components/writing-flow/utils.mjs +2 -11
- package/build-module/components/writing-flow/utils.mjs.map +2 -2
- package/build-module/hooks/background.mjs +13 -10
- package/build-module/hooks/background.mjs.map +2 -2
- package/build-module/hooks/block-style-variation.mjs +8 -44
- package/build-module/hooks/block-style-variation.mjs.map +2 -2
- package/build-module/hooks/border.mjs +19 -4
- package/build-module/hooks/border.mjs.map +2 -2
- package/build-module/hooks/custom-css.mjs +7 -3
- package/build-module/hooks/custom-css.mjs.map +2 -2
- package/build-module/hooks/dimensions.mjs +15 -4
- package/build-module/hooks/dimensions.mjs.map +2 -2
- package/build-module/hooks/duotone.mjs +20 -9
- package/build-module/hooks/duotone.mjs.map +2 -2
- package/build-module/hooks/elements.mjs +14 -4
- package/build-module/hooks/elements.mjs.map +2 -2
- package/build-module/hooks/line-height.mjs +1 -2
- package/build-module/hooks/line-height.mjs.map +2 -2
- package/build-module/hooks/typography.mjs +13 -4
- package/build-module/hooks/typography.mjs.map +2 -2
- package/build-module/private-apis.mjs +7 -3
- package/build-module/private-apis.mjs.map +2 -2
- package/build-module/store/actions.mjs +9 -4
- package/build-module/store/actions.mjs.map +2 -2
- package/build-module/store/private-selectors.mjs +29 -1
- package/build-module/store/private-selectors.mjs.map +2 -2
- package/build-module/store/reducer.mjs +6 -6
- package/build-module/store/reducer.mjs.map +2 -2
- package/build-module/store/selectors.mjs +23 -0
- package/build-module/store/selectors.mjs.map +2 -2
- package/build-module/utils/native-undo.mjs +29 -0
- package/build-module/utils/native-undo.mjs.map +7 -0
- package/build-style/content-rtl.css +10 -18
- package/build-style/content.css +10 -18
- package/build-style/style-rtl.css +150 -7
- package/build-style/style.css +150 -7
- package/package.json +40 -41
- package/src/components/alignment-control/test/__snapshots__/index.js.snap +1 -1
- package/src/components/alignment-control/ui.js +2 -4
- package/src/components/background-image-control/index.js +74 -37
- package/src/components/background-image-control/style.scss +13 -4
- package/src/components/block-alignment-control/test/__snapshots__/index.js.snap +3 -3
- package/src/components/block-alignment-control/test/index.js +1 -1
- package/src/components/block-alignment-control/ui.js +4 -2
- package/src/components/block-breadcrumb/test/__snapshots__/index.js.snap +1 -1
- package/src/components/block-compare/test/__snapshots__/block-view.js.snap +1 -1
- package/src/components/block-icon/test/__snapshots__/index.js.snap +1 -1
- package/src/components/block-inspector/index.js +60 -31
- package/src/components/block-list/block-html.js +5 -0
- package/src/components/block-list/content.scss +1 -11
- package/src/components/block-list/use-block-props/index.js +5 -1
- package/src/components/block-list/use-block-props/use-focus-handler.js +9 -8
- package/src/components/block-list/use-block-props/use-register-block-event-handlers.js +45 -0
- package/src/components/block-parent-selector/index.js +5 -2
- package/src/components/block-toolbar/switch-section-style.js +5 -2
- package/src/components/block-tools/empty-block-inserter.js +3 -7
- package/src/components/block-vertical-alignment-control/test/__snapshots__/index.js.snap +3 -3
- package/src/components/block-vertical-alignment-control/test/index.js +18 -2
- package/src/components/block-vertical-alignment-control/ui.js +3 -5
- package/src/components/border-radius-control/test/utils.js +0 -41
- package/src/components/border-radius-control/utils.js +16 -107
- package/src/components/button-block-appender/content.scss +6 -2
- package/src/components/color-palette/test/__snapshots__/control.js.snap +1 -1
- package/src/components/colors-gradients/control.js +6 -3
- package/src/components/default-block-appender/test/__snapshots__/index.js.snap +1 -1
- package/src/components/dimension-control/index.js +13 -1
- package/src/components/dimensions-tool/aspect-ratio-tool.js +13 -6
- package/src/components/editor-styles/index.js +16 -1
- package/src/components/global-styles/background-panel.js +107 -34
- package/src/components/global-styles/border-panel.js +219 -48
- package/src/components/global-styles/color-gradient-dropdown-item.js +93 -28
- package/src/components/global-styles/color-panel.js +92 -11
- package/src/components/global-styles/dimensions-panel.js +422 -71
- package/src/components/global-styles/filters-panel.js +88 -28
- package/src/components/global-styles/hooks.js +8 -1
- package/src/components/global-styles/inheritance/index.js +204 -0
- package/src/components/global-styles/inheritance/style.scss +184 -0
- package/src/components/global-styles/inheritance/test/index.js +281 -0
- package/src/components/global-styles/inherited-value-context.js +271 -0
- package/src/components/global-styles/shadow-panel-components.js +48 -26
- package/src/components/global-styles/state-control.js +2 -2
- package/src/components/global-styles/test/background-panel.js +338 -1
- package/src/components/global-styles/test/border-panel.js +441 -0
- package/src/components/global-styles/test/color-panel.js +182 -2
- package/src/components/global-styles/test/dimensions-panel.js +753 -0
- package/src/components/global-styles/test/filters-panel.js +194 -0
- package/src/components/global-styles/test/inherited-value-context-core.js +98 -0
- package/src/components/global-styles/test/inherited-value-context.js +454 -0
- package/src/components/global-styles/test/typography-panel-core.js +185 -0
- package/src/components/global-styles/test/typography-panel.js +849 -12
- package/src/components/global-styles/typography-panel.js +449 -100
- package/src/components/image-editor/style.scss +33 -0
- package/src/components/inner-blocks/test/__snapshots__/index.js.snap +1 -1
- package/src/components/inspector-controls-tabs/styles-tab.js +5 -1
- package/src/components/line-height-control/index.js +1 -1
- package/src/components/link-control/index.js +7 -2
- package/src/components/preset-input-control/index.js +4 -1
- package/src/components/provider/block-refs-provider.js +12 -2
- package/src/components/provider/index.js +2 -2
- package/src/components/provider/use-block-sync.js +18 -6
- package/src/components/provider/use-media-upload-settings.js +2 -0
- package/src/components/rich-text/index.js +37 -16
- package/src/components/spacing-sizes-control/test/utils.js +16 -5
- package/src/components/spacing-sizes-control/utils.js +11 -28
- package/src/components/text-indent-control/index.js +8 -0
- package/src/components/url-input/index.js +363 -431
- package/src/components/url-input/test/index.js +592 -0
- package/src/components/warning/test/__snapshots__/index.js.snap +1 -1
- package/src/components/writing-flow/index.js +2 -0
- package/src/components/writing-flow/use-arrow-nav.js +51 -1
- package/src/components/writing-flow/use-click-selection.js +54 -3
- package/src/components/writing-flow/use-editable-root-event-handlers.js +266 -0
- package/src/components/writing-flow/use-editable-root.js +7 -77
- package/src/components/writing-flow/use-home-end.js +17 -9
- package/src/components/writing-flow/use-selection-observer.js +32 -15
- package/src/components/writing-flow/utils.js +3 -24
- package/src/hooks/background.js +26 -21
- package/src/hooks/block-fields/rich-text/styles.scss +1 -1
- package/src/hooks/block-style-variation.js +8 -74
- package/src/hooks/border.js +19 -4
- package/src/hooks/custom-css.js +15 -6
- package/src/hooks/dimensions.js +17 -4
- package/src/hooks/duotone.js +26 -8
- package/src/hooks/elements.js +14 -3
- package/src/hooks/line-height.js +0 -1
- package/src/hooks/test/inherited-value-wiring.js +411 -0
- package/src/hooks/test/preset-round-trip.js +456 -0
- package/src/hooks/typography.js +35 -23
- package/src/private-apis.js +11 -2
- package/src/store/actions.js +10 -4
- package/src/store/private-selectors.js +57 -1
- package/src/store/reducer.js +9 -9
- package/src/store/selectors.js +56 -8
- package/src/store/test/private-selectors.js +160 -1
- package/src/style.scss +2 -0
- package/src/utils/native-undo.js +56 -0
- package/build/components/duotone/utils.cjs +0 -87
- package/build/components/duotone/utils.cjs.map +0 -7
- package/build-module/components/duotone/utils.mjs +0 -59
- package/build-module/components/duotone/utils.mjs.map +0 -7
- package/src/components/duotone/utils.js +0 -90
- package/src/hooks/test/get-variation-styles-with-ref-values.js +0 -91
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { useSelect } from '@wordpress/data';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
import { useResolvedStyle } from '../inherited-value-context';
|
|
15
|
+
import { BlockContextProvider } from '../../block-context';
|
|
16
|
+
|
|
17
|
+
import { globalStylesDataKey } from '../../../store/private-keys';
|
|
18
|
+
|
|
19
|
+
// The inheritance treatment sits behind the
|
|
20
|
+
// `gutenberg-global-styles-inheritance-ui` experiment. Turn it on so these
|
|
21
|
+
// tests exercise the resolving path. The off path lives in
|
|
22
|
+
// `inherited-value-context-core.js`.
|
|
23
|
+
beforeEach( () => {
|
|
24
|
+
window.__experimentalGlobalStylesInheritanceUI = true;
|
|
25
|
+
} );
|
|
26
|
+
|
|
27
|
+
afterEach( () => {
|
|
28
|
+
delete window.__experimentalGlobalStylesInheritanceUI;
|
|
29
|
+
} );
|
|
30
|
+
|
|
31
|
+
jest.mock( '@wordpress/data', () => ( {
|
|
32
|
+
useSelect: jest.fn(),
|
|
33
|
+
useDispatch: jest.fn( () => ( {} ) ),
|
|
34
|
+
useRegistry: jest.fn( () => ( {} ) ),
|
|
35
|
+
createSelector: jest.fn( ( callback ) => callback ),
|
|
36
|
+
createReduxStore: jest.fn(),
|
|
37
|
+
createRegistry: jest.fn(),
|
|
38
|
+
register: jest.fn(),
|
|
39
|
+
select: jest.fn(),
|
|
40
|
+
dispatch: jest.fn(),
|
|
41
|
+
combineReducers: jest.fn( ( reducers ) => reducers ),
|
|
42
|
+
subscribe: jest.fn(),
|
|
43
|
+
RegistryProvider: ( { children } ) => children,
|
|
44
|
+
RegistryConsumer: ( { children } ) => children( {} ),
|
|
45
|
+
AsyncModeProvider: ( { children } ) => children,
|
|
46
|
+
useRegistrySelect: jest.fn(),
|
|
47
|
+
useRegistryDispatch: jest.fn( () => ( {} ) ),
|
|
48
|
+
withSelect: ( mapStateToProps ) => ( Component ) => ( props ) =>
|
|
49
|
+
Component( {
|
|
50
|
+
...props,
|
|
51
|
+
...( mapStateToProps?.( () => ( {} ) ) || {} ),
|
|
52
|
+
} ),
|
|
53
|
+
withDispatch: () => ( Component ) => ( props ) => Component( props ),
|
|
54
|
+
withRegistry: ( Component ) => Component,
|
|
55
|
+
} ) );
|
|
56
|
+
|
|
57
|
+
jest.mock( '../../../store', () => ( {
|
|
58
|
+
store: { name: 'core/block-editor' },
|
|
59
|
+
} ) );
|
|
60
|
+
|
|
61
|
+
// `inherited-value-context.js` imports `store as blocksStore` from
|
|
62
|
+
// `@wordpress/blocks` for `useVariationAndElements`. The blocks store's
|
|
63
|
+
// transitive import chain fails under this file's `@wordpress/data` mock
|
|
64
|
+
// (missing `createSelector`), so stub the blocks module with just the shape
|
|
65
|
+
// needed.
|
|
66
|
+
jest.mock( '@wordpress/blocks', () => ( {
|
|
67
|
+
store: { name: 'core/blocks' },
|
|
68
|
+
getBlockType: ( blockName ) =>
|
|
69
|
+
( {
|
|
70
|
+
'core/group': { title: 'Group' },
|
|
71
|
+
'core/heading': { title: 'Heading' },
|
|
72
|
+
'core/paragraph': { title: 'Paragraph' },
|
|
73
|
+
} )[ blockName ],
|
|
74
|
+
} ) );
|
|
75
|
+
|
|
76
|
+
// `useResolvedStyle` derives the applied variation from the block's
|
|
77
|
+
// `className`; map `is-style-<slug>` to `<slug>` for these tests. The
|
|
78
|
+
// variation-ref resolution itself now lives in `resolveStyle`
|
|
79
|
+
// (`@wordpress/global-styles-engine`) and is covered by its own tests.
|
|
80
|
+
jest.mock( '../../../hooks/block-style-variation', () => ( {
|
|
81
|
+
getVariationNameFromClass: ( className ) => {
|
|
82
|
+
const match = /is-style-([\w-]+)/.exec( className || '' );
|
|
83
|
+
return match ? match[ 1 ] : null;
|
|
84
|
+
},
|
|
85
|
+
} ) );
|
|
86
|
+
|
|
87
|
+
describe( 'useResolvedStyle hook', () => {
|
|
88
|
+
beforeEach( () => {
|
|
89
|
+
useSelect.mockReset();
|
|
90
|
+
} );
|
|
91
|
+
|
|
92
|
+
function Probe( { blockName, className, selectedState } ) {
|
|
93
|
+
const v = useResolvedStyle( blockName, className, selectedState );
|
|
94
|
+
return <div data-testid="probe">{ JSON.stringify( v ) }</div>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// The hook issues two `useSelect` reads: the merged Global Styles
|
|
98
|
+
// payload (block-editor store) and the block's registered styles
|
|
99
|
+
// (blocks store). Feed both from one stub.
|
|
100
|
+
function mockStores(
|
|
101
|
+
rawGlobalStyles,
|
|
102
|
+
{ blockStyles = [], attributes = {} } = {}
|
|
103
|
+
) {
|
|
104
|
+
useSelect.mockImplementation( ( mapSelect ) =>
|
|
105
|
+
mapSelect( () => ( {
|
|
106
|
+
// `globalStylesDataKey` holds the BARE merged styles tree
|
|
107
|
+
// in production (see `editor/src/components/provider/
|
|
108
|
+
// use-block-editor-settings.js:237`,
|
|
109
|
+
// `mergedGlobalStyles.styles`), not the wrapped
|
|
110
|
+
// `{ settings, styles }` envelope. The hook wraps the bare
|
|
111
|
+
// tree before passing to the builder.
|
|
112
|
+
getSettings: () => ( {
|
|
113
|
+
[ globalStylesDataKey ]: rawGlobalStyles,
|
|
114
|
+
} ),
|
|
115
|
+
getBlockStyles: () => blockStyles,
|
|
116
|
+
// The hook reads the block's `level` attribute to pick the
|
|
117
|
+
// heading element layers. No block edit context is provided
|
|
118
|
+
// here, so `clientId` is undefined; the stub returns whatever
|
|
119
|
+
// attributes the test supplies regardless.
|
|
120
|
+
getBlockAttributes: () => attributes,
|
|
121
|
+
} ) )
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Resolves a block's styles as rendered inside an Accordion, which supplies
|
|
126
|
+
// the heading level to every descendant through block context.
|
|
127
|
+
function resolveInAccordion( blockName, level = 3 ) {
|
|
128
|
+
render(
|
|
129
|
+
<BlockContextProvider
|
|
130
|
+
value={ { 'core/accordion-heading-level': level } }
|
|
131
|
+
>
|
|
132
|
+
<Probe blockName={ blockName } />
|
|
133
|
+
</BlockContextProvider>
|
|
134
|
+
);
|
|
135
|
+
return JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Accordion Heading resolves its level from the parent Accordion's block
|
|
139
|
+
// context, not from its own `level` attribute, and has no level-0 state.
|
|
140
|
+
test( 'accordion-heading takes its level from block context', () => {
|
|
141
|
+
mockStores( {
|
|
142
|
+
elements: {
|
|
143
|
+
heading: { color: { text: '#111111' } },
|
|
144
|
+
h3: { typography: { fontSize: '19px' } },
|
|
145
|
+
},
|
|
146
|
+
} );
|
|
147
|
+
const parsed = resolveInAccordion( 'core/accordion-heading' );
|
|
148
|
+
expect( parsed.value.typography.fontSize ).toBe( '19px' );
|
|
149
|
+
expect( parsed.value.color.text ).toBe( '#111111' );
|
|
150
|
+
} );
|
|
151
|
+
|
|
152
|
+
test( 'accordion-heading with no context still resolves to h3', () => {
|
|
153
|
+
mockStores( {
|
|
154
|
+
elements: { h3: { typography: { fontSize: '19px' } } },
|
|
155
|
+
} );
|
|
156
|
+
render( <Probe blockName="core/accordion-heading" /> );
|
|
157
|
+
const parsed = JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
158
|
+
expect( parsed.value.typography.fontSize ).toBe( '19px' );
|
|
159
|
+
} );
|
|
160
|
+
|
|
161
|
+
test( "accordion-heading's own level attribute wins over block context", () => {
|
|
162
|
+
mockStores(
|
|
163
|
+
{
|
|
164
|
+
elements: {
|
|
165
|
+
h3: { typography: { fontSize: '19px' } },
|
|
166
|
+
h5: { typography: { fontSize: '13px' } },
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
{ attributes: { level: 5 } }
|
|
170
|
+
);
|
|
171
|
+
const parsed = resolveInAccordion( 'core/accordion-heading' );
|
|
172
|
+
// The attribute is what the front end serializes (`save.js` renders
|
|
173
|
+
// `h${ level || 3 }`), so it takes precedence when the two disagree.
|
|
174
|
+
expect( parsed.value.typography.fontSize ).toBe( '13px' );
|
|
175
|
+
} );
|
|
176
|
+
|
|
177
|
+
// An ordinary Heading can be placed inside an Accordion Panel, which puts
|
|
178
|
+
// `core/accordion-heading-level` in its block context. Only the blocks that
|
|
179
|
+
// opt in may read that key.
|
|
180
|
+
test( 'a plain heading ignores an accordion level in block context', () => {
|
|
181
|
+
mockStores(
|
|
182
|
+
{
|
|
183
|
+
elements: {
|
|
184
|
+
h2: { typography: { fontSize: '24px' } },
|
|
185
|
+
h3: { typography: { fontSize: '19px' } },
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
{ attributes: { level: 2 } }
|
|
189
|
+
);
|
|
190
|
+
const parsed = resolveInAccordion( 'core/heading' );
|
|
191
|
+
expect( parsed.value.typography.fontSize ).toBe( '24px' );
|
|
192
|
+
} );
|
|
193
|
+
|
|
194
|
+
// A title block at level 0 renders a paragraph, so no heading element styles
|
|
195
|
+
// reach it. `0` is the one falsy level, and an `||` anywhere on the path
|
|
196
|
+
// from the `level` attribute to `getElementLayers` would silently turn it
|
|
197
|
+
// into "no level given" and wrongly fold the generic `heading` layer.
|
|
198
|
+
test( 'a title block at level 0 folds no heading element styles', () => {
|
|
199
|
+
mockStores(
|
|
200
|
+
{
|
|
201
|
+
typography: { lineHeight: '1.6' },
|
|
202
|
+
elements: {
|
|
203
|
+
heading: { typography: { fontSize: '30px' } },
|
|
204
|
+
h2: { typography: { fontSize: '24px' } },
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
{ attributes: { level: 0 } }
|
|
208
|
+
);
|
|
209
|
+
render( <Probe blockName="core/site-title" /> );
|
|
210
|
+
const parsed = JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
211
|
+
expect( parsed.value.typography.fontSize ).toBeUndefined();
|
|
212
|
+
// Root styles still resolve, so the assertion above means "no heading
|
|
213
|
+
// layer", not "nothing resolved at all".
|
|
214
|
+
expect( parsed.value.typography.lineHeight ).toBe( '1.6' );
|
|
215
|
+
} );
|
|
216
|
+
|
|
217
|
+
// A whole-block link block (e.g. Read More) renders as an `<a>`, so the root
|
|
218
|
+
// `styles.elements.link` layer paints it and folds into its top-level
|
|
219
|
+
// controls, just as `button` does for core/button.
|
|
220
|
+
test( 'a whole-block link folds the link element into top-level controls', () => {
|
|
221
|
+
mockStores( {
|
|
222
|
+
typography: { lineHeight: '1.6' },
|
|
223
|
+
elements: {
|
|
224
|
+
link: {
|
|
225
|
+
color: { text: '#0073aa' },
|
|
226
|
+
typography: { fontSize: '14px' },
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
} );
|
|
230
|
+
render( <Probe blockName="core/read-more" /> );
|
|
231
|
+
const parsed = JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
232
|
+
expect( parsed.value.color.text ).toBe( '#0073aa' );
|
|
233
|
+
expect( parsed.value.typography.fontSize ).toBe( '14px' );
|
|
234
|
+
// The link element source is recorded as the element layer.
|
|
235
|
+
expect( parsed.sources[ 'color.text' ].layer ).toBe( 'element' );
|
|
236
|
+
} );
|
|
237
|
+
|
|
238
|
+
// A block that only *contains* links (Paragraph) must not fold `link` into
|
|
239
|
+
// its own text controls; the link styles stay under the `elements.link`
|
|
240
|
+
// passthrough for the Link colour control to read.
|
|
241
|
+
test( 'a container block does not fold the link element into its text controls', () => {
|
|
242
|
+
mockStores( {
|
|
243
|
+
typography: { lineHeight: '1.6' },
|
|
244
|
+
elements: { link: { color: { text: '#0073aa' } } },
|
|
245
|
+
} );
|
|
246
|
+
render( <Probe blockName="core/paragraph" /> );
|
|
247
|
+
const parsed = JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
248
|
+
expect( parsed.value.color?.text ).toBeUndefined();
|
|
249
|
+
// It remains available via the passthrough for the Link colour control.
|
|
250
|
+
expect( parsed.value.elements.link.color.text ).toBe( '#0073aa' );
|
|
251
|
+
} );
|
|
252
|
+
|
|
253
|
+
test( 'returns empty value and sources when no block name is given', () => {
|
|
254
|
+
mockStores( { typography: { fontSize: '16px' } } );
|
|
255
|
+
render( <Probe /> );
|
|
256
|
+
expect( screen.getByTestId( 'probe' ) ).toHaveTextContent(
|
|
257
|
+
'{"value":{},"sources":{}}'
|
|
258
|
+
);
|
|
259
|
+
} );
|
|
260
|
+
|
|
261
|
+
test( 'returns empty value and sources during hydration', () => {
|
|
262
|
+
mockStores( null );
|
|
263
|
+
render( <Probe blockName="core/heading" /> );
|
|
264
|
+
expect( screen.getByTestId( 'probe' ) ).toHaveTextContent(
|
|
265
|
+
'{"value":{},"sources":{}}'
|
|
266
|
+
);
|
|
267
|
+
} );
|
|
268
|
+
|
|
269
|
+
test( 'reads the block element passthrough from the merged payload', () => {
|
|
270
|
+
mockStores( {
|
|
271
|
+
typography: { fontSize: '16px' },
|
|
272
|
+
elements: { h2: { typography: { fontSize: '24px' } } },
|
|
273
|
+
} );
|
|
274
|
+
render( <Probe blockName="core/heading" /> );
|
|
275
|
+
const parsed = JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
276
|
+
// The h2 element styles are preserved under the nested
|
|
277
|
+
// `elements` passthrough, not folded up to the top level.
|
|
278
|
+
expect( parsed.value.elements.h2.typography.fontSize ).toBe( '24px' );
|
|
279
|
+
expect(
|
|
280
|
+
parsed.sources[ 'elements.h2.typography.fontSize' ].layer
|
|
281
|
+
).toBe( 'root' );
|
|
282
|
+
} );
|
|
283
|
+
} );
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Regression suite for the production data-shape contract.
|
|
287
|
+
*
|
|
288
|
+
* `settings[ globalStylesDataKey ]` carries the BARE merged Global
|
|
289
|
+
* Styles tree — `{ typography: {...}, color: {...}, blocks: {...},
|
|
290
|
+
* elements: {...}, ... }` — produced by
|
|
291
|
+
* `editor/src/components/provider/use-block-editor-settings.js:237`
|
|
292
|
+
* (`mergedGlobalStyles.styles`). It is NOT the wrapped
|
|
293
|
+
* `{ settings, styles }` envelope.
|
|
294
|
+
*
|
|
295
|
+
* Pre-hot-fix, the hook passed the bare tree directly to
|
|
296
|
+
* `resolveStyle`, which destructures `const { styles } =
|
|
297
|
+
* globalStyles` and so saw `undefined` and early-returned `{}`. Every
|
|
298
|
+
* panel got an empty `inheritedValue`; nothing surfaced in the
|
|
299
|
+
* inspector. None of the original suites caught it because their
|
|
300
|
+
* fixtures all set `[ globalStylesDataKey ]: { styles: { ... } }` —
|
|
301
|
+
* encoding the wrong shape assumption.
|
|
302
|
+
*
|
|
303
|
+
* This suite uses fixtures that mirror the production producer's
|
|
304
|
+
* output and asserts the hook → resolver pipeline yields a
|
|
305
|
+
* non-empty `inheritedValue` end-to-end. A future regression on the
|
|
306
|
+
* data-shape contract — at the producer, the wrapping step inside the
|
|
307
|
+
* hook, or the resolver's destructure — surfaces here in CI.
|
|
308
|
+
*/
|
|
309
|
+
describe( 'useResolvedStyle – production bare-tree shape', () => {
|
|
310
|
+
beforeEach( () => {
|
|
311
|
+
useSelect.mockReset();
|
|
312
|
+
} );
|
|
313
|
+
|
|
314
|
+
function Probe( { blockName, className } ) {
|
|
315
|
+
const { value } = useResolvedStyle( blockName, className );
|
|
316
|
+
return <div data-testid="probe">{ JSON.stringify( value ) }</div>;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Representative bare-tree fixture shaped like a real
|
|
321
|
+
* `mergedGlobalStyles.styles` payload from a child theme that:
|
|
322
|
+
*
|
|
323
|
+
* - Sets a root text color, body background, and root line height.
|
|
324
|
+
* - Overrides `core/heading` with a font-family + weight.
|
|
325
|
+
* - Overrides the `h2` element specifically with a smaller
|
|
326
|
+
* font size and a different color.
|
|
327
|
+
* - Registers a `plain` variation under `core/quote` that
|
|
328
|
+
* drops the border and recolors the text.
|
|
329
|
+
* - Includes a `{ ref: 'styles.color.background' }` envelope on
|
|
330
|
+
* the `core/group` background to verify ref resolution still
|
|
331
|
+
* works end-to-end (ref envelopes resolve against the wrapped
|
|
332
|
+
* `{ styles }` tree). This is block-sourced, so it survives the
|
|
333
|
+
* non-cascading root drop.
|
|
334
|
+
*/
|
|
335
|
+
const productionShapeFixture = {
|
|
336
|
+
typography: { lineHeight: '1.6' },
|
|
337
|
+
color: {
|
|
338
|
+
text: '#1a1a1a',
|
|
339
|
+
background: '#ffffff',
|
|
340
|
+
},
|
|
341
|
+
elements: {
|
|
342
|
+
link: { color: { text: '#0073aa' } },
|
|
343
|
+
},
|
|
344
|
+
blocks: {
|
|
345
|
+
'core/heading': {
|
|
346
|
+
typography: {
|
|
347
|
+
fontFamily: 'serif',
|
|
348
|
+
fontWeight: '600',
|
|
349
|
+
},
|
|
350
|
+
elements: {
|
|
351
|
+
h2: {
|
|
352
|
+
typography: { fontSize: '28px' },
|
|
353
|
+
color: { text: '#444444' },
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
'core/quote': {
|
|
358
|
+
border: { width: '4px', color: '#cccccc' },
|
|
359
|
+
variations: {
|
|
360
|
+
plain: {
|
|
361
|
+
border: { width: '0px' },
|
|
362
|
+
color: { text: '#666666' },
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
'core/group': {
|
|
367
|
+
color: { background: { ref: 'styles.color.background' } },
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
function mountWithFixture( ui, rawGlobalStyles = productionShapeFixture ) {
|
|
373
|
+
useSelect.mockImplementation( ( mapSelect ) =>
|
|
374
|
+
mapSelect( () => ( {
|
|
375
|
+
getSettings: () => ( {
|
|
376
|
+
[ globalStylesDataKey ]: rawGlobalStyles,
|
|
377
|
+
} ),
|
|
378
|
+
getBlockStyles: () => [],
|
|
379
|
+
getBlockAttributes: () => ( {} ),
|
|
380
|
+
} ) )
|
|
381
|
+
);
|
|
382
|
+
return render( ui );
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
test( 'root + block override merge yields non-empty payload at the panel boundary', () => {
|
|
386
|
+
mountWithFixture( <Probe blockName="core/heading" /> );
|
|
387
|
+
const parsed = JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
388
|
+
expect( parsed ).toMatchObject( {
|
|
389
|
+
typography: {
|
|
390
|
+
lineHeight: '1.6', // from root layer
|
|
391
|
+
fontFamily: 'serif', // from block override
|
|
392
|
+
fontWeight: '600', // from block override
|
|
393
|
+
},
|
|
394
|
+
color: { text: '#1a1a1a' }, // from root layer
|
|
395
|
+
} );
|
|
396
|
+
} );
|
|
397
|
+
|
|
398
|
+
test( 'block element override is preserved under the elements passthrough', () => {
|
|
399
|
+
mountWithFixture( <Probe blockName="core/heading" /> );
|
|
400
|
+
const parsed = JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
401
|
+
// Block-level h2 override stays nested under `elements.h2`.
|
|
402
|
+
expect( parsed.elements.h2.typography.fontSize ).toBe( '28px' );
|
|
403
|
+
expect( parsed.elements.h2.color.text ).toBe( '#444444' );
|
|
404
|
+
// Root + block overrides still merge at the top level.
|
|
405
|
+
expect( parsed.typography.lineHeight ).toBe( '1.6' );
|
|
406
|
+
} );
|
|
407
|
+
|
|
408
|
+
test( 'variation override layers on top of block override', () => {
|
|
409
|
+
mountWithFixture(
|
|
410
|
+
<Probe blockName="core/quote" className="is-style-plain" />
|
|
411
|
+
);
|
|
412
|
+
const parsed = JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
413
|
+
expect( parsed.border.width ).toBe( '0px' ); // variation wins
|
|
414
|
+
expect( parsed.border.color ).toBe( '#cccccc' ); // block passthrough
|
|
415
|
+
expect( parsed.color.text ).toBe( '#666666' ); // variation wins
|
|
416
|
+
} );
|
|
417
|
+
|
|
418
|
+
test( '{ ref } envelope resolves against the bare tree at the leaf', () => {
|
|
419
|
+
mountWithFixture( <Probe blockName="core/group" /> );
|
|
420
|
+
const parsed = JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
421
|
+
expect( parsed.color.background ).toBe( '#ffffff' );
|
|
422
|
+
} );
|
|
423
|
+
|
|
424
|
+
test( 'block with no overrides still inherits root + element layers', () => {
|
|
425
|
+
mountWithFixture( <Probe blockName="core/paragraph" /> );
|
|
426
|
+
const parsed = JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
427
|
+
expect( parsed.typography.lineHeight ).toBe( '1.6' );
|
|
428
|
+
// The root link element styles stay nested under `elements.link`.
|
|
429
|
+
expect( parsed.elements.link.color.text ).toBe( '#0073aa' );
|
|
430
|
+
} );
|
|
431
|
+
|
|
432
|
+
test( 'panel-readable keys are absent when the producer accidentally double-wraps the data', () => {
|
|
433
|
+
// Regression guard against re-introducing the original bug. If
|
|
434
|
+
// a future refactor accidentally double-wraps the data —
|
|
435
|
+
// i.e. stores `{ styles: { typography: ... } }` at the dataKey
|
|
436
|
+
// instead of the bare tree — the Provider's wrapper produces
|
|
437
|
+
// `{ styles: { styles: { typography: ... } } }`, the resolver
|
|
438
|
+
// destructures `styles = { styles: { typography: ... } }`, and
|
|
439
|
+
// `pickLayerRootContribution` treats `styles` as a leaf-bearing
|
|
440
|
+
// key so the merged payload is `{ styles: { typography: ... } }`
|
|
441
|
+
// — non-empty in object terms, but the panel-readable keys
|
|
442
|
+
// (`typography`, `color`, ...) are absent at the top level. The
|
|
443
|
+
// user observes the same thing they did before the hot fix: no
|
|
444
|
+
// inherited values surface in the inspector. This case asserts
|
|
445
|
+
// the panel-readable keys are missing, which is what the panels
|
|
446
|
+
// actually consume.
|
|
447
|
+
mountWithFixture( <Probe blockName="core/heading" />, {
|
|
448
|
+
styles: productionShapeFixture,
|
|
449
|
+
} );
|
|
450
|
+
const parsed = JSON.parse( screen.getByTestId( 'probe' ).textContent );
|
|
451
|
+
expect( parsed.typography ).toBeUndefined();
|
|
452
|
+
expect( parsed.color ).toBeUndefined();
|
|
453
|
+
} );
|
|
454
|
+
} );
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
import { click, render as renderAriakit } from '@ariakit/test/react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import TypographyPanel from '../typography-panel';
|
|
11
|
+
|
|
12
|
+
// Coverage for `TypographyPanel` with the `gutenberg-global-styles-inheritance-ui`
|
|
13
|
+
// experiment off, which is what WordPress Core gets. Deleted rather than set to
|
|
14
|
+
// `false`, because an experiment that was never turned on leaves the global
|
|
15
|
+
// unset, and `undefined` is the value that fires a receiving component's own
|
|
16
|
+
// default parameter. Setting `false` here would test a state that does not
|
|
17
|
+
// occur.
|
|
18
|
+
beforeEach( () => {
|
|
19
|
+
delete window.__experimentalGlobalStylesInheritanceUI;
|
|
20
|
+
} );
|
|
21
|
+
|
|
22
|
+
afterEach( () => {
|
|
23
|
+
delete window.__experimentalGlobalStylesInheritanceUI;
|
|
24
|
+
} );
|
|
25
|
+
|
|
26
|
+
const baseSettings = {
|
|
27
|
+
typography: {
|
|
28
|
+
lineHeight: true,
|
|
29
|
+
letterSpacing: true,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Two presets with distinct slugs and distinct hex values, enough to drive the
|
|
34
|
+
// text color dropdown.
|
|
35
|
+
const PALETTE_SETTINGS = {
|
|
36
|
+
color: {
|
|
37
|
+
text: true,
|
|
38
|
+
custom: false,
|
|
39
|
+
customGradient: false,
|
|
40
|
+
defaultPalette: false,
|
|
41
|
+
palette: {
|
|
42
|
+
theme: [
|
|
43
|
+
{ color: '#0000ff', name: 'Blue', slug: 'blue' },
|
|
44
|
+
{ color: '#ff0000', name: 'Red', slug: 'red' },
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
function renderPanel( props ) {
|
|
51
|
+
return render(
|
|
52
|
+
<TypographyPanel
|
|
53
|
+
value={ {} }
|
|
54
|
+
settings={ baseSettings }
|
|
55
|
+
onChange={ () => {} }
|
|
56
|
+
panelId="test-panel"
|
|
57
|
+
{ ...props }
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const getItem = ( name ) => {
|
|
63
|
+
const control = screen.getByRole( 'spinbutton', { name } );
|
|
64
|
+
// The class hooks sit on the wrapping ToolsPanelItem, which has no role.
|
|
65
|
+
// eslint-disable-next-line testing-library/no-node-access
|
|
66
|
+
return control.closest( '.components-tools-panel-item' );
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
describe( 'TypographyPanel — experiment off', () => {
|
|
70
|
+
// `showInheritanceLabelIndicators` defaults to the experiment flag, so a
|
|
71
|
+
// caller that passes no prop gets no inheritance treatment. The layout
|
|
72
|
+
// className must still come through.
|
|
73
|
+
it( 'applies no inherited treatment by default, even when an inherited value is present', () => {
|
|
74
|
+
renderPanel( {
|
|
75
|
+
value: {},
|
|
76
|
+
inheritedValue: { typography: { lineHeight: '1.5' } },
|
|
77
|
+
} );
|
|
78
|
+
|
|
79
|
+
const lineHeightItem = getItem( /line height/i );
|
|
80
|
+
expect( lineHeightItem ).toHaveClass( 'single-column' );
|
|
81
|
+
expect( lineHeightItem ).not.toHaveClass(
|
|
82
|
+
'is-inherited-from-global-styles'
|
|
83
|
+
);
|
|
84
|
+
} );
|
|
85
|
+
|
|
86
|
+
it( 'renders no reset dot by default when a local value shadows an inherited one', () => {
|
|
87
|
+
renderPanel( {
|
|
88
|
+
value: { typography: { lineHeight: '2' } },
|
|
89
|
+
inheritedValue: { typography: { lineHeight: '1.5' } },
|
|
90
|
+
} );
|
|
91
|
+
|
|
92
|
+
expect( getItem( /line height/i ) ).not.toHaveClass(
|
|
93
|
+
'has-local-override-from-global-styles'
|
|
94
|
+
);
|
|
95
|
+
expect(
|
|
96
|
+
screen.queryByRole( 'button', {
|
|
97
|
+
name: 'Reset to inherited value',
|
|
98
|
+
} )
|
|
99
|
+
).not.toBeInTheDocument();
|
|
100
|
+
} );
|
|
101
|
+
|
|
102
|
+
it( 'renders the default color reset button by default when a local color shadows an inherited one', async () => {
|
|
103
|
+
await renderAriakit(
|
|
104
|
+
<TypographyPanel
|
|
105
|
+
value={ { color: { text: 'var:preset|color|blue' } } }
|
|
106
|
+
inheritedValue={ { color: { text: 'var:preset|color|red' } } }
|
|
107
|
+
settings={ PALETTE_SETTINGS }
|
|
108
|
+
panelId="test"
|
|
109
|
+
onChange={ jest.fn() }
|
|
110
|
+
/>
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
expect(
|
|
114
|
+
screen.queryByRole( 'button', {
|
|
115
|
+
name: /reset to inherited value/i,
|
|
116
|
+
} )
|
|
117
|
+
).not.toBeInTheDocument();
|
|
118
|
+
expect(
|
|
119
|
+
screen.getByRole( 'button', { name: /^reset$/i } )
|
|
120
|
+
).toBeInTheDocument();
|
|
121
|
+
} );
|
|
122
|
+
} );
|
|
123
|
+
|
|
124
|
+
describe( 'TypographyPanel — experiment off, setTextColor link sync', () => {
|
|
125
|
+
async function pickRed( value, inheritedValue ) {
|
|
126
|
+
const onChange = jest.fn();
|
|
127
|
+
await renderAriakit(
|
|
128
|
+
<TypographyPanel
|
|
129
|
+
value={ value }
|
|
130
|
+
inheritedValue={ inheritedValue }
|
|
131
|
+
settings={ PALETTE_SETTINGS }
|
|
132
|
+
panelId="test"
|
|
133
|
+
onChange={ onChange }
|
|
134
|
+
/>
|
|
135
|
+
);
|
|
136
|
+
await click(
|
|
137
|
+
screen.getByRole( 'button', { name: /Color/, expanded: false } )
|
|
138
|
+
);
|
|
139
|
+
// `findAllByRole` waits for the Popover/portal content to appear.
|
|
140
|
+
const swatches = await screen.findAllByRole( 'option' );
|
|
141
|
+
// swatch[0] = 'Blue', swatch[1] = 'Red'
|
|
142
|
+
await click( swatches[ 1 ] );
|
|
143
|
+
return onChange.mock.calls[ 0 ][ 0 ];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
it( 'leaves an unset link color alone when a text color is already set', async () => {
|
|
147
|
+
// With the experiment on this falls back to the inherited link color
|
|
148
|
+
// and syncs. Off, it compares the inherited text and link colors
|
|
149
|
+
// directly, which on this path is the block's own pair, so a link
|
|
150
|
+
// color that was never set does not start tracking.
|
|
151
|
+
const result = await pickRed( {
|
|
152
|
+
color: { text: 'var:preset|color|blue' },
|
|
153
|
+
} );
|
|
154
|
+
|
|
155
|
+
expect( result?.color?.text ).toBe( 'var:preset|color|red' );
|
|
156
|
+
expect( result?.elements?.link?.color?.text ).toBeUndefined();
|
|
157
|
+
} );
|
|
158
|
+
|
|
159
|
+
it( 'starts a link color tracking when neither is set', async () => {
|
|
160
|
+
// Both sides are undefined, so they compare as matching and the link
|
|
161
|
+
// color starts following the text color.
|
|
162
|
+
const result = await pickRed( {} );
|
|
163
|
+
|
|
164
|
+
expect( result?.color?.text ).toBe( 'var:preset|color|red' );
|
|
165
|
+
expect( result?.elements?.link?.color?.text ).toBe(
|
|
166
|
+
'var:preset|color|red'
|
|
167
|
+
);
|
|
168
|
+
} );
|
|
169
|
+
|
|
170
|
+
// In Global Styles `value` is the user config and `inheritedValue` the
|
|
171
|
+
// merged one. Comparing `value` would find undefined on both sides.
|
|
172
|
+
it( 'reads the merged config, not the user config, in Global Styles', async () => {
|
|
173
|
+
const result = await pickRed(
|
|
174
|
+
{},
|
|
175
|
+
{
|
|
176
|
+
color: { text: 'var:preset|color|blue' },
|
|
177
|
+
elements: { link: { color: { text: 'var:preset|color|red' } } },
|
|
178
|
+
}
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
expect( result?.color?.text ).toBe( 'var:preset|color|red' );
|
|
182
|
+
// The theme's text and link colors differ, so the link does not track.
|
|
183
|
+
expect( result?.elements?.link?.color?.text ).toBeUndefined();
|
|
184
|
+
} );
|
|
185
|
+
} );
|