@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,753 @@
|
|
|
1
|
+
/* eslint jest/expect-expect: ["warn", { "assertFunctionNames": ["expect", "expectLocalOverride", "expectPlaceholderState"] }] */
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { render, screen, within } from '@testing-library/react';
|
|
6
|
+
import userEvent from '@testing-library/user-event';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Internal dependencies
|
|
10
|
+
*/
|
|
11
|
+
import DimensionsPanel from '../dimensions-panel';
|
|
12
|
+
|
|
13
|
+
// The inheritance treatment sits behind the
|
|
14
|
+
// `gutenberg-global-styles-inheritance-ui` experiment. Turn it on so these
|
|
15
|
+
// tests exercise the inheriting path.
|
|
16
|
+
beforeEach( () => {
|
|
17
|
+
window.__experimentalGlobalStylesInheritanceUI = true;
|
|
18
|
+
} );
|
|
19
|
+
|
|
20
|
+
afterEach( () => {
|
|
21
|
+
delete window.__experimentalGlobalStylesInheritanceUI;
|
|
22
|
+
} );
|
|
23
|
+
|
|
24
|
+
// `AspectRatioTool` reads its option list from the block-editor data
|
|
25
|
+
// store via `useSettings`. Mock that hook so the tests can render the
|
|
26
|
+
// full set of inherited and selectable ratios without spinning up a
|
|
27
|
+
// store registry. Per-call resolution lets the same mock answer all
|
|
28
|
+
// of the paths the tool requests on a single render.
|
|
29
|
+
jest.mock( '../../use-settings', () => {
|
|
30
|
+
const actual = jest.requireActual( '../../use-settings' );
|
|
31
|
+
return {
|
|
32
|
+
...actual,
|
|
33
|
+
useSettings: jest.fn( ( ...paths ) =>
|
|
34
|
+
paths.map( ( path ) => {
|
|
35
|
+
switch ( path ) {
|
|
36
|
+
case 'dimensions.aspectRatios.default':
|
|
37
|
+
return [
|
|
38
|
+
{ name: 'Square', slug: 'square', ratio: '1' },
|
|
39
|
+
{
|
|
40
|
+
name: 'Standard',
|
|
41
|
+
slug: 'standard',
|
|
42
|
+
ratio: '4/3',
|
|
43
|
+
},
|
|
44
|
+
{ name: 'Wide', slug: 'wide', ratio: '16/9' },
|
|
45
|
+
];
|
|
46
|
+
case 'dimensions.aspectRatios.theme':
|
|
47
|
+
return [];
|
|
48
|
+
case 'dimensions.defaultAspectRatios':
|
|
49
|
+
return true;
|
|
50
|
+
case 'dimensions.dimensionSizes':
|
|
51
|
+
return undefined;
|
|
52
|
+
case 'spacing.units':
|
|
53
|
+
return [ '%', 'px', 'em', 'rem', 'vh', 'vw' ];
|
|
54
|
+
// `useSpacingSizes` reads these for SpacingSizesControl.
|
|
55
|
+
// The spacing slider tests rely on them being populated;
|
|
56
|
+
// other tests don't render SpacingSizesControl, so the
|
|
57
|
+
// slider hook doesn't reach this path for them.
|
|
58
|
+
case 'spacing.spacingSizes.custom':
|
|
59
|
+
return [];
|
|
60
|
+
case 'spacing.spacingSizes.theme':
|
|
61
|
+
return [];
|
|
62
|
+
case 'spacing.spacingSizes.default':
|
|
63
|
+
return [
|
|
64
|
+
{ name: 'Small', slug: '20', size: '12px' },
|
|
65
|
+
{ name: 'Medium', slug: '40', size: '24px' },
|
|
66
|
+
{ name: 'Large', slug: '60', size: '48px' },
|
|
67
|
+
];
|
|
68
|
+
case 'spacing.defaultSpacingSizes':
|
|
69
|
+
return true;
|
|
70
|
+
default:
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
} )
|
|
74
|
+
),
|
|
75
|
+
};
|
|
76
|
+
} );
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Tests for inherited values in `DimensionsPanel`.
|
|
80
|
+
*
|
|
81
|
+
* The control's `value` prop reads from local `value` only; inherited values
|
|
82
|
+
* are surfaced through placeholders or at-rest selected options when local
|
|
83
|
+
* paths are empty. The wrapping `ToolsPanelItem` carries the inherited or
|
|
84
|
+
* local-override class hooks for label-level treatment.
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
const baseSettings = {
|
|
88
|
+
layout: {
|
|
89
|
+
contentSize: '600px',
|
|
90
|
+
wideSize: '1100px',
|
|
91
|
+
},
|
|
92
|
+
spacing: {
|
|
93
|
+
blockGap: true,
|
|
94
|
+
padding: true,
|
|
95
|
+
margin: true,
|
|
96
|
+
units: [ 'px', 'em', 'rem' ],
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const settingsWithDimensions = {
|
|
101
|
+
...baseSettings,
|
|
102
|
+
dimensions: {
|
|
103
|
+
minHeight: true,
|
|
104
|
+
height: true,
|
|
105
|
+
minWidth: true,
|
|
106
|
+
width: true,
|
|
107
|
+
aspectRatio: true,
|
|
108
|
+
aspectRatios: {
|
|
109
|
+
default: [
|
|
110
|
+
{ name: 'Square', slug: 'square', ratio: '1' },
|
|
111
|
+
{ name: 'Standard', slug: 'standard', ratio: '4/3' },
|
|
112
|
+
{ name: 'Wide', slug: 'wide', ratio: '16/9' },
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
defaultAspectRatios: true,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const settingsWithSpacingPresets = {
|
|
120
|
+
...baseSettings,
|
|
121
|
+
spacing: {
|
|
122
|
+
...baseSettings.spacing,
|
|
123
|
+
spacingSizes: {
|
|
124
|
+
default: [
|
|
125
|
+
{ name: 'Small', slug: '20', size: '12px' },
|
|
126
|
+
{ name: 'Medium', slug: '40', size: '24px' },
|
|
127
|
+
{ name: 'Large', slug: '60', size: '48px' },
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
defaultSpacingSizes: true,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// Render helper that fills in the boilerplate props every test repeats.
|
|
135
|
+
function renderPanel( props ) {
|
|
136
|
+
return render(
|
|
137
|
+
<DimensionsPanel
|
|
138
|
+
onChange={ () => {} }
|
|
139
|
+
panelId="test-panel"
|
|
140
|
+
{ ...props }
|
|
141
|
+
/>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// A local override surfaces the accessible reset-to-inherited affordance, so
|
|
146
|
+
// assert on that rather than the label's CSS class hook.
|
|
147
|
+
function expectLocalOverride() {
|
|
148
|
+
expect(
|
|
149
|
+
screen.getByRole( 'button', {
|
|
150
|
+
name: /reset to inherited value/i,
|
|
151
|
+
} )
|
|
152
|
+
).toBeInTheDocument();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Asserts the placeholder treatment for a control. A control can inherit a
|
|
156
|
+
// value while showing no placeholder when the inherited sides differ
|
|
157
|
+
// (BoxControl cannot render a per-side placeholder). Kept as a helper so the
|
|
158
|
+
// branch isn't a conditional `expect` in the test body (which
|
|
159
|
+
// `jest/no-conditional-expect` disallows).
|
|
160
|
+
function expectPlaceholderState( el, placeholder ) {
|
|
161
|
+
if ( placeholder ) {
|
|
162
|
+
expect( el ).toHaveAttribute( 'placeholder', placeholder );
|
|
163
|
+
} else {
|
|
164
|
+
expect( el ).not.toHaveAttribute( 'placeholder' );
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// `getByLabelText` for the DimensionControl archetype matches both the inner
|
|
169
|
+
// UnitControl input and the sibling RangeControl slider, so filter to the
|
|
170
|
+
// text input element by class.
|
|
171
|
+
const getDimensionInput = ( label ) =>
|
|
172
|
+
screen
|
|
173
|
+
.getAllByLabelText( label )
|
|
174
|
+
.find( ( el ) =>
|
|
175
|
+
el.classList.contains( 'components-input-control__input' )
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
const getPaddingAllSides = () =>
|
|
179
|
+
within( screen.getByRole( 'group', { name: /Padding/ } ) ).getByRole(
|
|
180
|
+
'textbox',
|
|
181
|
+
{ name: 'All sides' }
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
const getPaddingSliders = () =>
|
|
185
|
+
screen
|
|
186
|
+
.getAllByRole( 'slider' )
|
|
187
|
+
.filter( ( s ) =>
|
|
188
|
+
/padding/i.test( s.getAttribute( 'aria-label' ) || '' )
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
describe( 'DimensionsPanel — per-control placeholder pattern', () => {
|
|
192
|
+
describe( 'layout content width', () => {
|
|
193
|
+
it( 'renders an inherited contentSize as the control value when `value` is empty', () => {
|
|
194
|
+
renderPanel( {
|
|
195
|
+
value: {},
|
|
196
|
+
inheritedValue: { layout: { contentSize: '720px' } },
|
|
197
|
+
settings: baseSettings,
|
|
198
|
+
includeLayoutControls: true,
|
|
199
|
+
} );
|
|
200
|
+
|
|
201
|
+
const contentInput = screen.getByLabelText( /content width/i );
|
|
202
|
+
// The inherited value is rendered as the control value (so the
|
|
203
|
+
// unit parses from it) and marked at-rest, with only the numeric
|
|
204
|
+
// portion echoed as the placeholder; the raw unit must not leak in.
|
|
205
|
+
expect( contentInput ).toHaveValue( 720 );
|
|
206
|
+
expect( contentInput ).toHaveAttribute( 'placeholder', '720' );
|
|
207
|
+
expect( contentInput ).not.toHaveAttribute(
|
|
208
|
+
'placeholder',
|
|
209
|
+
'720px'
|
|
210
|
+
);
|
|
211
|
+
} );
|
|
212
|
+
|
|
213
|
+
it( 'renders a locally-set contentSize as the value with no placeholder', () => {
|
|
214
|
+
renderPanel( {
|
|
215
|
+
value: { layout: { contentSize: '900px' } },
|
|
216
|
+
inheritedValue: { layout: { contentSize: '720px' } },
|
|
217
|
+
settings: baseSettings,
|
|
218
|
+
includeLayoutControls: true,
|
|
219
|
+
} );
|
|
220
|
+
|
|
221
|
+
const contentInput = screen.getByLabelText( /content width/i );
|
|
222
|
+
expect( contentInput ).toHaveValue( 900 );
|
|
223
|
+
expect( contentInput ).not.toHaveAttribute( 'placeholder' );
|
|
224
|
+
} );
|
|
225
|
+
|
|
226
|
+
it( 'renders an inherited wideSize as the control value independently of contentSize state', () => {
|
|
227
|
+
renderPanel( {
|
|
228
|
+
value: { layout: { contentSize: '900px' } },
|
|
229
|
+
inheritedValue: {
|
|
230
|
+
layout: { contentSize: '720px', wideSize: '1280px' },
|
|
231
|
+
},
|
|
232
|
+
settings: baseSettings,
|
|
233
|
+
includeLayoutControls: true,
|
|
234
|
+
} );
|
|
235
|
+
|
|
236
|
+
// contentSize: locally-set, no placeholder.
|
|
237
|
+
const contentInput = screen.getByLabelText( /content width/i );
|
|
238
|
+
expect( contentInput ).toHaveValue( 900 );
|
|
239
|
+
|
|
240
|
+
// wideSize: not locally set, rendered as the at-rest control value.
|
|
241
|
+
const wideInput = screen.getByLabelText( /wide width/i );
|
|
242
|
+
expect( wideInput ).toHaveValue( 1280 );
|
|
243
|
+
expect( wideInput ).toHaveAttribute( 'placeholder', '1280' );
|
|
244
|
+
expect( wideInput ).not.toHaveAttribute( 'placeholder', '1280px' );
|
|
245
|
+
} );
|
|
246
|
+
|
|
247
|
+
it( 'commits a local contentSize override on user input without copying any inherited value into other paths (strip-not-copy)', async () => {
|
|
248
|
+
const user = userEvent.setup();
|
|
249
|
+
const onChange = jest.fn();
|
|
250
|
+
|
|
251
|
+
renderPanel( {
|
|
252
|
+
value: {},
|
|
253
|
+
inheritedValue: {
|
|
254
|
+
layout: { contentSize: '720px', wideSize: '1280px' },
|
|
255
|
+
spacing: { blockGap: '1.5rem' },
|
|
256
|
+
},
|
|
257
|
+
settings: baseSettings,
|
|
258
|
+
onChange,
|
|
259
|
+
includeLayoutControls: true,
|
|
260
|
+
} );
|
|
261
|
+
|
|
262
|
+
const contentInput = screen.getByLabelText( /content width/i );
|
|
263
|
+
await user.type( contentInput, '800px' );
|
|
264
|
+
|
|
265
|
+
expect( onChange ).toHaveBeenCalled();
|
|
266
|
+
const lastCall = onChange.mock.calls.at( -1 )[ 0 ];
|
|
267
|
+
|
|
268
|
+
// The committed change is local-only at the touched leaf path;
|
|
269
|
+
// no inherited value (wideSize, blockGap) is copied into the
|
|
270
|
+
// committed `value`.
|
|
271
|
+
expect( lastCall?.layout?.contentSize ).toBeDefined();
|
|
272
|
+
expect( lastCall?.layout?.wideSize ).toBeUndefined();
|
|
273
|
+
expect( lastCall?.spacing?.blockGap ).toBeUndefined();
|
|
274
|
+
} );
|
|
275
|
+
} );
|
|
276
|
+
|
|
277
|
+
describe( 'block spacing (single-input gap path)', () => {
|
|
278
|
+
it( 'renders an inherited blockGap as placeholder when `value` is empty', () => {
|
|
279
|
+
renderPanel( {
|
|
280
|
+
value: {},
|
|
281
|
+
inheritedValue: { spacing: { blockGap: '1.5rem' } },
|
|
282
|
+
settings: baseSettings,
|
|
283
|
+
} );
|
|
284
|
+
|
|
285
|
+
const gapInput = screen.getByLabelText( /block spacing/i );
|
|
286
|
+
expect( gapInput ).toHaveValue( null );
|
|
287
|
+
expect( gapInput ).toHaveAttribute( 'placeholder', '1.5rem' );
|
|
288
|
+
} );
|
|
289
|
+
|
|
290
|
+
it( 'renders no placeholder for blockGap when the inherited value is the compound axial shape (single-input path can only display strings)', () => {
|
|
291
|
+
// When blockGap is an object (axial split), the panel still
|
|
292
|
+
// renders the single-input UnitControl path because the
|
|
293
|
+
// settings here do not enable axial gap sides. The placeholder
|
|
294
|
+
// must NOT surface a non-string value into a control that
|
|
295
|
+
// cannot display it.
|
|
296
|
+
renderPanel( {
|
|
297
|
+
value: {},
|
|
298
|
+
inheritedValue: {
|
|
299
|
+
spacing: { blockGap: { top: '1rem', left: '0.5rem' } },
|
|
300
|
+
},
|
|
301
|
+
settings: baseSettings,
|
|
302
|
+
} );
|
|
303
|
+
|
|
304
|
+
const gapInput = screen.getByLabelText( /block spacing/i );
|
|
305
|
+
expect( gapInput ).not.toHaveAttribute( 'placeholder' );
|
|
306
|
+
} );
|
|
307
|
+
} );
|
|
308
|
+
|
|
309
|
+
describe( 'padding (BoxControl archetype)', () => {
|
|
310
|
+
// In linked mode (the default when there are no local values), the
|
|
311
|
+
// BoxControl renders a single "All sides" input; the placeholder
|
|
312
|
+
// reaches the inner UnitControl via inputProps and the className
|
|
313
|
+
// lands on the inner input wrapper for SCSS targeting.
|
|
314
|
+
it.each( [
|
|
315
|
+
{
|
|
316
|
+
name: 'shorthand string',
|
|
317
|
+
padding: '16px',
|
|
318
|
+
placeholder: '16px',
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: 'object with all sides equal',
|
|
322
|
+
padding: {
|
|
323
|
+
top: '20px',
|
|
324
|
+
right: '20px',
|
|
325
|
+
bottom: '20px',
|
|
326
|
+
left: '20px',
|
|
327
|
+
},
|
|
328
|
+
placeholder: '20px',
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
// Per-side mismatch: the single "All sides" input cannot
|
|
332
|
+
// represent differing sides, so no placeholder is shown.
|
|
333
|
+
name: 'object with sides that differ',
|
|
334
|
+
padding: {
|
|
335
|
+
top: '16px',
|
|
336
|
+
right: '8px',
|
|
337
|
+
bottom: '16px',
|
|
338
|
+
left: '8px',
|
|
339
|
+
},
|
|
340
|
+
placeholder: null,
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
// Only some sides defined (e.g. the top/bottom-only margin a
|
|
344
|
+
// theme may set). No common single-string placeholder.
|
|
345
|
+
name: 'object with only some sides defined',
|
|
346
|
+
padding: {
|
|
347
|
+
top: '16px',
|
|
348
|
+
bottom: '16px',
|
|
349
|
+
},
|
|
350
|
+
placeholder: null,
|
|
351
|
+
},
|
|
352
|
+
] )(
|
|
353
|
+
'renders an inherited padding $name as placeholder $placeholder when `value` is empty',
|
|
354
|
+
( { padding, placeholder } ) => {
|
|
355
|
+
renderPanel( {
|
|
356
|
+
value: {},
|
|
357
|
+
inheritedValue: { spacing: { padding } },
|
|
358
|
+
settings: baseSettings,
|
|
359
|
+
} );
|
|
360
|
+
|
|
361
|
+
const paddingAllSides = getPaddingAllSides();
|
|
362
|
+
expectPlaceholderState( paddingAllSides, placeholder );
|
|
363
|
+
}
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
it( 'renders a locally-set padding shorthand as the value with no placeholder, even when `inheritedValue` also defines it', () => {
|
|
367
|
+
renderPanel( {
|
|
368
|
+
value: { spacing: { padding: '24px' } },
|
|
369
|
+
inheritedValue: { spacing: { padding: '16px' } },
|
|
370
|
+
settings: baseSettings,
|
|
371
|
+
} );
|
|
372
|
+
|
|
373
|
+
const paddingAllSides = getPaddingAllSides();
|
|
374
|
+
expect( paddingAllSides ).toHaveValue( '24' );
|
|
375
|
+
expect( paddingAllSides ).not.toHaveAttribute( 'placeholder' );
|
|
376
|
+
} );
|
|
377
|
+
} );
|
|
378
|
+
|
|
379
|
+
// The min-dimension DimensionControls (minHeight, minWidth) use the
|
|
380
|
+
// local-then-inherited pattern: the inherited value is rendered as the
|
|
381
|
+
// control's value (so the unit parses from it) and marked at-rest, rather
|
|
382
|
+
// than shown as a placeholder. It is only committed to local on user
|
|
383
|
+
// change.
|
|
384
|
+
describe.each( [
|
|
385
|
+
{
|
|
386
|
+
name: 'minHeight',
|
|
387
|
+
leaf: 'minHeight',
|
|
388
|
+
label: /minimum height/i,
|
|
389
|
+
inherited: '320px',
|
|
390
|
+
expected: 320,
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
name: 'minWidth',
|
|
394
|
+
leaf: 'minWidth',
|
|
395
|
+
label: /minimum width/i,
|
|
396
|
+
inherited: '200px',
|
|
397
|
+
expected: 200,
|
|
398
|
+
},
|
|
399
|
+
] )(
|
|
400
|
+
'DimensionControl ($name)',
|
|
401
|
+
( { leaf, label, inherited, expected } ) => {
|
|
402
|
+
it( 'renders an inherited value as the control value when `value` is empty', () => {
|
|
403
|
+
renderPanel( {
|
|
404
|
+
value: {},
|
|
405
|
+
inheritedValue: { dimensions: { [ leaf ]: inherited } },
|
|
406
|
+
settings: settingsWithDimensions,
|
|
407
|
+
} );
|
|
408
|
+
|
|
409
|
+
const input = getDimensionInput( label );
|
|
410
|
+
expect( input ).toBeDefined();
|
|
411
|
+
expect( input ).toHaveValue( expected );
|
|
412
|
+
// The placeholder carries only the numeric portion of the
|
|
413
|
+
// inherited value; the unit selector reflects the inherited
|
|
414
|
+
// unit separately, so the raw unit string must not leak in.
|
|
415
|
+
expect( input ).toHaveAttribute(
|
|
416
|
+
'placeholder',
|
|
417
|
+
`${ expected }`
|
|
418
|
+
);
|
|
419
|
+
expect( input ).not.toHaveAttribute( 'placeholder', inherited );
|
|
420
|
+
} );
|
|
421
|
+
}
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
// The plain `width` DimensionControl still uses the native-placeholder
|
|
425
|
+
// pattern for its inherited value.
|
|
426
|
+
describe( 'DimensionControl (width)', () => {
|
|
427
|
+
it( 'renders an inherited value as placeholder when `value` is empty', () => {
|
|
428
|
+
renderPanel( {
|
|
429
|
+
value: {},
|
|
430
|
+
inheritedValue: { dimensions: { width: '640px' } },
|
|
431
|
+
settings: settingsWithDimensions,
|
|
432
|
+
} );
|
|
433
|
+
|
|
434
|
+
const input = getDimensionInput( /^width$/i );
|
|
435
|
+
expect( input ).toBeDefined();
|
|
436
|
+
expect( input ).toHaveValue( null );
|
|
437
|
+
expect( input ).toHaveAttribute( 'placeholder', '640px' );
|
|
438
|
+
} );
|
|
439
|
+
} );
|
|
440
|
+
|
|
441
|
+
describe( 'minHeight (DimensionControl)', () => {
|
|
442
|
+
it( 'renders a locally-set minHeight as the value with no placeholder, even when `inheritedValue` also defines it', () => {
|
|
443
|
+
renderPanel( {
|
|
444
|
+
value: { dimensions: { minHeight: '480px' } },
|
|
445
|
+
inheritedValue: { dimensions: { minHeight: '320px' } },
|
|
446
|
+
settings: settingsWithDimensions,
|
|
447
|
+
} );
|
|
448
|
+
|
|
449
|
+
const minHeightInput = getDimensionInput( /minimum height/i );
|
|
450
|
+
expect( minHeightInput ).toBeDefined();
|
|
451
|
+
// PresetInputControl parses '480px' into the numeric input
|
|
452
|
+
// + a unit selector; the visible input value is just the
|
|
453
|
+
// numeric portion.
|
|
454
|
+
expect( minHeightInput ).toHaveValue( 480 );
|
|
455
|
+
expect( minHeightInput ).not.toHaveAttribute( 'placeholder' );
|
|
456
|
+
} );
|
|
457
|
+
|
|
458
|
+
it( 'does not call `onChange` on mount of an at-rest minHeight', () => {
|
|
459
|
+
const onChange = jest.fn();
|
|
460
|
+
renderPanel( {
|
|
461
|
+
value: {},
|
|
462
|
+
inheritedValue: { dimensions: { minHeight: '320px' } },
|
|
463
|
+
settings: settingsWithDimensions,
|
|
464
|
+
onChange,
|
|
465
|
+
} );
|
|
466
|
+
|
|
467
|
+
expect( onChange ).not.toHaveBeenCalled();
|
|
468
|
+
} );
|
|
469
|
+
|
|
470
|
+
it( 'commits a local minHeight override on user input without copying any inherited value into other paths', async () => {
|
|
471
|
+
const user = userEvent.setup();
|
|
472
|
+
const onChange = jest.fn();
|
|
473
|
+
|
|
474
|
+
renderPanel( {
|
|
475
|
+
value: {},
|
|
476
|
+
inheritedValue: {
|
|
477
|
+
dimensions: { minHeight: '320px', width: '640px' },
|
|
478
|
+
},
|
|
479
|
+
settings: settingsWithDimensions,
|
|
480
|
+
onChange,
|
|
481
|
+
} );
|
|
482
|
+
|
|
483
|
+
const minHeightInput = getDimensionInput( /minimum height/i );
|
|
484
|
+
expect( minHeightInput ).toBeDefined();
|
|
485
|
+
await user.type( minHeightInput, '500' );
|
|
486
|
+
|
|
487
|
+
expect( onChange ).toHaveBeenCalled();
|
|
488
|
+
const lastCall = onChange.mock.calls.at( -1 )[ 0 ];
|
|
489
|
+
|
|
490
|
+
// The committed change is local-only at the touched leaf path;
|
|
491
|
+
// no other inherited dimension (width) is copied into the
|
|
492
|
+
// committed `value`.
|
|
493
|
+
expect( lastCall?.dimensions?.minHeight ).toBeDefined();
|
|
494
|
+
expect( lastCall?.dimensions?.width ).toBeUndefined();
|
|
495
|
+
} );
|
|
496
|
+
} );
|
|
497
|
+
|
|
498
|
+
describe( 'aspectRatio (native <select> archetype)', () => {
|
|
499
|
+
it( 'preselects the inherited aspectRatio option as at-rest with inherited-value treatment', () => {
|
|
500
|
+
renderPanel( {
|
|
501
|
+
value: {},
|
|
502
|
+
inheritedValue: { dimensions: { aspectRatio: '16/9' } },
|
|
503
|
+
settings: settingsWithDimensions,
|
|
504
|
+
} );
|
|
505
|
+
|
|
506
|
+
const aspectSelect = screen.getByRole( 'combobox', {
|
|
507
|
+
name: /aspect ratio/i,
|
|
508
|
+
} );
|
|
509
|
+
expect( aspectSelect ).toHaveValue( '16/9' );
|
|
510
|
+
} );
|
|
511
|
+
|
|
512
|
+
it( 'renders a locally-set aspectRatio as the selected value with the local-override hook', () => {
|
|
513
|
+
renderPanel( {
|
|
514
|
+
value: { dimensions: { aspectRatio: '1' } },
|
|
515
|
+
inheritedValue: { dimensions: { aspectRatio: '16/9' } },
|
|
516
|
+
settings: settingsWithDimensions,
|
|
517
|
+
} );
|
|
518
|
+
|
|
519
|
+
const aspectSelect = screen.getByRole( 'combobox', {
|
|
520
|
+
name: /aspect ratio/i,
|
|
521
|
+
} );
|
|
522
|
+
expect( aspectSelect ).toHaveValue( '1' );
|
|
523
|
+
// A local override now gets the same local-override flag as
|
|
524
|
+
// every other control, so the inline reset button can attach.
|
|
525
|
+
// The button itself is portaled and covered by the
|
|
526
|
+
// InheritanceResetButton unit tests.
|
|
527
|
+
expectLocalOverride();
|
|
528
|
+
} );
|
|
529
|
+
|
|
530
|
+
it( 'does not call `onChange` on mount of an at-rest aspectRatio', () => {
|
|
531
|
+
const onChange = jest.fn();
|
|
532
|
+
renderPanel( {
|
|
533
|
+
value: {},
|
|
534
|
+
inheritedValue: { dimensions: { aspectRatio: '16/9' } },
|
|
535
|
+
settings: settingsWithDimensions,
|
|
536
|
+
onChange,
|
|
537
|
+
} );
|
|
538
|
+
|
|
539
|
+
expect( onChange ).not.toHaveBeenCalled();
|
|
540
|
+
} );
|
|
541
|
+
|
|
542
|
+
it( 'commits a local aspectRatio override on user selection of a different option without copying any inherited value into other paths', async () => {
|
|
543
|
+
const user = userEvent.setup();
|
|
544
|
+
const onChange = jest.fn();
|
|
545
|
+
|
|
546
|
+
renderPanel( {
|
|
547
|
+
value: {},
|
|
548
|
+
inheritedValue: {
|
|
549
|
+
dimensions: { aspectRatio: '16/9', minHeight: '320px' },
|
|
550
|
+
},
|
|
551
|
+
settings: settingsWithDimensions,
|
|
552
|
+
onChange,
|
|
553
|
+
} );
|
|
554
|
+
|
|
555
|
+
const aspectSelect = screen.getByRole( 'combobox', {
|
|
556
|
+
name: /aspect ratio/i,
|
|
557
|
+
} );
|
|
558
|
+
await user.selectOptions( aspectSelect, '1' );
|
|
559
|
+
|
|
560
|
+
expect( onChange ).toHaveBeenCalled();
|
|
561
|
+
const lastCall = onChange.mock.calls.at( -1 )[ 0 ];
|
|
562
|
+
expect( lastCall?.dimensions?.aspectRatio ).toBe( '1' );
|
|
563
|
+
// minHeight from inheritedValue must not be copied into the
|
|
564
|
+
// committed local value (strip-not-copy).
|
|
565
|
+
expect( lastCall?.dimensions?.minHeight ).toBeUndefined();
|
|
566
|
+
} );
|
|
567
|
+
} );
|
|
568
|
+
|
|
569
|
+
/*
|
|
570
|
+
* Regression: spacing slider stuck on inherited value
|
|
571
|
+
* ----------------------------------------------------
|
|
572
|
+
* `SpacingSizesControl` (the preset chip slider) and the axial-gap
|
|
573
|
+
* `BoxControl` have no native `placeholder` slot — the at-rest cue
|
|
574
|
+
* is the displayed `values` themselves. Previously these reads
|
|
575
|
+
* came from `inheritedValue` only, so when the user dragged the
|
|
576
|
+
* slider, `setPaddingValues` / `setMarginValues` / `setGapValues`
|
|
577
|
+
* wrote to local state but the `values` prop never updated and the
|
|
578
|
+
* slider appeared 'stuck'. The fix merges local-then-inherited
|
|
579
|
+
* before passing to the chip slider / axial BoxControl.
|
|
580
|
+
*/
|
|
581
|
+
describe( 'SpacingSizesControl (preset chip slider)', () => {
|
|
582
|
+
// Each `SpacingSizesControl` slider reports its current preset
|
|
583
|
+
// position via the slider's `value` attribute. The numbering
|
|
584
|
+
// corresponds to the index of the active preset in the merged size
|
|
585
|
+
// list (the slider's `None` zero position precedes the presets).
|
|
586
|
+
it.each( [
|
|
587
|
+
{
|
|
588
|
+
name: 'padding',
|
|
589
|
+
leaf: 'padding',
|
|
590
|
+
match: /padding/i,
|
|
591
|
+
// Local Medium (slug 40) → index 2.
|
|
592
|
+
local: 'var:preset|spacing|40',
|
|
593
|
+
sliderValue: '2',
|
|
594
|
+
valueText: 'Medium',
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
name: 'margin',
|
|
598
|
+
leaf: 'margin',
|
|
599
|
+
match: /margin/i,
|
|
600
|
+
// Local Large (slug 60) → index 3.
|
|
601
|
+
local: 'var:preset|spacing|60',
|
|
602
|
+
sliderValue: '3',
|
|
603
|
+
valueText: 'Large',
|
|
604
|
+
},
|
|
605
|
+
] )(
|
|
606
|
+
'($name) reflects the local value when set, ignoring the inherited fallback',
|
|
607
|
+
( { leaf, match, local, sliderValue, valueText } ) => {
|
|
608
|
+
renderPanel( {
|
|
609
|
+
value: { spacing: { [ leaf ]: local } },
|
|
610
|
+
inheritedValue: {
|
|
611
|
+
spacing: {
|
|
612
|
+
[ leaf ]: leaf === 'padding' ? '10px' : '8px',
|
|
613
|
+
},
|
|
614
|
+
},
|
|
615
|
+
settings: settingsWithSpacingPresets,
|
|
616
|
+
} );
|
|
617
|
+
|
|
618
|
+
const sliders = screen
|
|
619
|
+
.getAllByRole( 'slider' )
|
|
620
|
+
.filter( ( s ) =>
|
|
621
|
+
match.test( s.getAttribute( 'aria-label' ) || '' )
|
|
622
|
+
);
|
|
623
|
+
expect( sliders.length ).toBeGreaterThan( 0 );
|
|
624
|
+
expect(
|
|
625
|
+
sliders.every( ( s ) => s.value === sliderValue )
|
|
626
|
+
).toBe( true );
|
|
627
|
+
expect(
|
|
628
|
+
sliders.every(
|
|
629
|
+
( s ) =>
|
|
630
|
+
s.getAttribute( 'aria-valuetext' ) === valueText
|
|
631
|
+
)
|
|
632
|
+
).toBe( true );
|
|
633
|
+
}
|
|
634
|
+
);
|
|
635
|
+
|
|
636
|
+
it( '(padding) renders the inherited value at-rest when the local path is empty', () => {
|
|
637
|
+
renderPanel( {
|
|
638
|
+
value: {},
|
|
639
|
+
inheritedValue: {
|
|
640
|
+
spacing: { padding: 'var:preset|spacing|20' },
|
|
641
|
+
},
|
|
642
|
+
settings: settingsWithSpacingPresets,
|
|
643
|
+
} );
|
|
644
|
+
|
|
645
|
+
// At-rest, slider tracks inherited 'Small' (slug 20) → index 1.
|
|
646
|
+
const paddingSliders = getPaddingSliders();
|
|
647
|
+
expect( paddingSliders.length ).toBeGreaterThan( 0 );
|
|
648
|
+
expect( paddingSliders.every( ( s ) => s.value === '1' ) ).toBe(
|
|
649
|
+
true
|
|
650
|
+
);
|
|
651
|
+
} );
|
|
652
|
+
|
|
653
|
+
it( '(padding) commits to local on slider activation and the displayed value follows the new local value', () => {
|
|
654
|
+
const { fireEvent } = require( '@testing-library/react' );
|
|
655
|
+
|
|
656
|
+
// Controlled wrapper so we can verify the slider follows local
|
|
657
|
+
// value updates after onChange writes through.
|
|
658
|
+
function Wrapper() {
|
|
659
|
+
const [ value, setValue ] =
|
|
660
|
+
require( '@wordpress/element' ).useState( {} );
|
|
661
|
+
return (
|
|
662
|
+
<DimensionsPanel
|
|
663
|
+
value={ value }
|
|
664
|
+
inheritedValue={ {
|
|
665
|
+
spacing: { padding: 'var:preset|spacing|20' },
|
|
666
|
+
} }
|
|
667
|
+
settings={ settingsWithSpacingPresets }
|
|
668
|
+
onChange={ setValue }
|
|
669
|
+
panelId="test-panel"
|
|
670
|
+
/>
|
|
671
|
+
);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
render( <Wrapper /> );
|
|
675
|
+
|
|
676
|
+
// At-rest the padding slider reads the inherited Small (index 1).
|
|
677
|
+
const slidersBefore = getPaddingSliders();
|
|
678
|
+
expect( slidersBefore[ 0 ].value ).toBe( '1' );
|
|
679
|
+
|
|
680
|
+
// `RangeControl` listens to native `change`/`input` events on
|
|
681
|
+
// its slider; setting the value and firing change is the most
|
|
682
|
+
// reliable way to drive an update through RTL in jsdom.
|
|
683
|
+
fireEvent.change( slidersBefore[ 0 ], { target: { value: '2' } } );
|
|
684
|
+
|
|
685
|
+
const slidersAfter = getPaddingSliders();
|
|
686
|
+
// The activated padding slider advanced from 1 → 2.
|
|
687
|
+
expect( slidersAfter[ 0 ].value ).toBe( '2' );
|
|
688
|
+
expect( slidersAfter[ 0 ] ).toHaveAttribute(
|
|
689
|
+
'aria-valuetext',
|
|
690
|
+
'Medium'
|
|
691
|
+
);
|
|
692
|
+
} );
|
|
693
|
+
|
|
694
|
+
it( 'still surfaces block-sourced inherited padding on a block panel', () => {
|
|
695
|
+
renderPanel( {
|
|
696
|
+
value: {},
|
|
697
|
+
inheritedValue: {
|
|
698
|
+
spacing: {
|
|
699
|
+
padding: {
|
|
700
|
+
top: 'var:preset|spacing|40',
|
|
701
|
+
right: 'var:preset|spacing|40',
|
|
702
|
+
bottom: 'var:preset|spacing|40',
|
|
703
|
+
left: 'var:preset|spacing|40',
|
|
704
|
+
},
|
|
705
|
+
},
|
|
706
|
+
},
|
|
707
|
+
settings: settingsWithSpacingPresets,
|
|
708
|
+
} );
|
|
709
|
+
|
|
710
|
+
const paddingSliders = getPaddingSliders();
|
|
711
|
+
expect( paddingSliders.length ).toBeGreaterThan( 0 );
|
|
712
|
+
// Inherited Medium (slug 40) lands at preset index 2 (None=0,
|
|
713
|
+
// Small=1, Medium=2). All sliders should reflect that.
|
|
714
|
+
expect( paddingSliders.every( ( s ) => s.value === '2' ) ).toBe(
|
|
715
|
+
true
|
|
716
|
+
);
|
|
717
|
+
} );
|
|
718
|
+
} );
|
|
719
|
+
|
|
720
|
+
describe( 'local zero values (override, not inherited placeholder)', () => {
|
|
721
|
+
it( 'treats a local numeric zero minHeight as a local override instead of inherited placeholder', () => {
|
|
722
|
+
renderPanel( {
|
|
723
|
+
value: { dimensions: { minHeight: 0 } },
|
|
724
|
+
inheritedValue: { dimensions: { minHeight: '200px' } },
|
|
725
|
+
settings: settingsWithDimensions,
|
|
726
|
+
} );
|
|
727
|
+
|
|
728
|
+
const minHeightInput = screen
|
|
729
|
+
.getAllByLabelText( /minimum height/i )
|
|
730
|
+
.find(
|
|
731
|
+
( input ) =>
|
|
732
|
+
input.tagName === 'INPUT' && input.value === '0'
|
|
733
|
+
);
|
|
734
|
+
expect( minHeightInput ).toBeDefined();
|
|
735
|
+
expect( minHeightInput ).toHaveValue( 0 );
|
|
736
|
+
expect( minHeightInput ).not.toHaveAttribute( 'placeholder' );
|
|
737
|
+
expectLocalOverride();
|
|
738
|
+
} );
|
|
739
|
+
|
|
740
|
+
it( 'treats a local zero block gap as a local value instead of inherited placeholder', () => {
|
|
741
|
+
renderPanel( {
|
|
742
|
+
value: { spacing: { blockGap: 0 } },
|
|
743
|
+
inheritedValue: { spacing: { blockGap: '2rem' } },
|
|
744
|
+
settings: baseSettings,
|
|
745
|
+
} );
|
|
746
|
+
|
|
747
|
+
const gapInput = screen.getByLabelText( /block spacing/i );
|
|
748
|
+
expect( gapInput ).toHaveValue( 0 );
|
|
749
|
+
expect( gapInput ).not.toHaveAttribute( 'placeholder' );
|
|
750
|
+
expectLocalOverride();
|
|
751
|
+
} );
|
|
752
|
+
} );
|
|
753
|
+
} );
|