@wordpress/block-editor 16.2.0 → 17.0.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 +39 -0
- package/build/components/block-inspector/index.cjs +9 -6
- package/build/components/block-inspector/index.cjs.map +2 -2
- package/build/components/block-keyboard-shortcuts/index.cjs +201 -0
- package/build/components/block-keyboard-shortcuts/index.cjs.map +7 -0
- package/build/components/block-list/block.cjs +10 -3
- package/build/components/block-list/block.cjs.map +2 -2
- package/build/components/block-list/index.cjs +6 -1
- package/build/components/block-list/index.cjs.map +2 -2
- package/build/components/block-list/use-block-props/use-focus-first-element.cjs +4 -0
- package/build/components/block-list/use-block-props/use-focus-first-element.cjs.map +2 -2
- package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs +6 -7
- package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs.map +2 -2
- package/build/components/block-parent-selector/index.cjs +98 -29
- package/build/components/block-parent-selector/index.cjs.map +3 -3
- package/build/components/block-popover/inbetween.cjs +2 -2
- package/build/components/block-popover/inbetween.cjs.map +2 -2
- package/build/components/block-preview/index.cjs +0 -4
- package/build/components/block-preview/index.cjs.map +2 -2
- package/build/components/block-styles/index.cjs +77 -33
- package/build/components/block-styles/index.cjs.map +3 -3
- package/build/components/block-visibility/constants.cjs.map +2 -2
- package/build/components/child-layout-control/index.cjs.map +2 -2
- package/build/components/colors/with-colors.cjs +55 -71
- package/build/components/colors/with-colors.cjs.map +2 -2
- package/build/components/dimensions-tool/aspect-ratio-tool.cjs +4 -2
- package/build/components/dimensions-tool/aspect-ratio-tool.cjs.map +2 -2
- package/build/components/dimensions-tool/index.cjs +18 -16
- package/build/components/dimensions-tool/index.cjs.map +2 -2
- package/build/components/dimensions-tool/utils.cjs +61 -0
- package/build/components/dimensions-tool/utils.cjs.map +7 -0
- package/build/components/duotone-control/index.cjs +2 -0
- package/build/components/duotone-control/index.cjs.map +2 -2
- package/build/components/global-styles/advanced-panel.cjs.map +3 -3
- package/build/components/global-styles/border-panel.cjs +2 -5
- package/build/components/global-styles/border-panel.cjs.map +2 -2
- package/build/components/global-styles/color-panel.cjs +14 -2
- package/build/components/global-styles/color-panel.cjs.map +2 -2
- package/build/components/global-styles/dimensions-panel.cjs +9 -5
- package/build/components/global-styles/dimensions-panel.cjs.map +2 -2
- package/build/components/global-styles/filters-panel.cjs +12 -8
- package/build/components/global-styles/filters-panel.cjs.map +2 -2
- package/build/components/global-styles/shadow-panel-components.cjs +16 -11
- package/build/components/global-styles/shadow-panel-components.cjs.map +2 -2
- package/build/components/global-styles/utils.cjs +9 -0
- package/build/components/global-styles/utils.cjs.map +2 -2
- package/build/components/inner-blocks/index.cjs +5 -3
- package/build/components/inner-blocks/index.cjs.map +2 -2
- package/build/components/inserter/block-patterns-explorer/index.cjs +39 -22
- package/build/components/inserter/block-patterns-explorer/index.cjs.map +2 -2
- package/build/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.cjs +21 -55
- package/build/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.cjs.map +2 -2
- package/build/components/inserter/block-patterns-explorer/pattern-list.cjs +19 -44
- package/build/components/inserter/block-patterns-explorer/pattern-list.cjs.map +3 -3
- package/build/components/inserter/hooks/use-insertion-point.cjs +4 -4
- package/build/components/inserter/hooks/use-insertion-point.cjs.map +2 -2
- package/build/components/inserter/menu.cjs +18 -7
- package/build/components/inserter/menu.cjs.map +2 -2
- package/build/components/inserter/quick-inserter.cjs +30 -27
- package/build/components/inserter/quick-inserter.cjs.map +2 -2
- package/build/components/inspector-controls-tabs/styles-tab.cjs +1 -1
- package/build/components/inspector-controls-tabs/styles-tab.cjs.map +2 -2
- package/build/components/list-view/index.cjs +31 -5
- package/build/components/list-view/index.cjs.map +3 -3
- package/build/components/list-view/utils.cjs +13 -1
- package/build/components/list-view/utils.cjs.map +2 -2
- package/build/components/media-placeholder/index.cjs +1 -1
- package/build/components/media-placeholder/index.cjs.map +3 -3
- package/build/components/provider/index.cjs +5 -1
- package/build/components/provider/index.cjs.map +3 -3
- package/build/components/publish-date-time-picker/index.cjs +3 -2
- package/build/components/publish-date-time-picker/index.cjs.map +2 -2
- package/build/components/rich-text/event-listeners/enter.cjs +46 -39
- package/build/components/rich-text/event-listeners/enter.cjs.map +2 -2
- package/build/components/rich-text/index.cjs +7 -5
- package/build/components/rich-text/index.cjs.map +2 -2
- package/build/components/rich-text/multiline.cjs +105 -70
- package/build/components/rich-text/multiline.cjs.map +3 -3
- package/build/components/url-input/index.cjs.map +2 -2
- package/build/components/writing-flow/use-input.cjs +65 -13
- package/build/components/writing-flow/use-input.cjs.map +3 -3
- package/build/hooks/border.cjs +25 -3
- package/build/hooks/border.cjs.map +2 -2
- package/build/hooks/dimensions.cjs +9 -2
- package/build/hooks/dimensions.cjs.map +2 -2
- package/build/hooks/duotone.cjs +4 -3
- package/build/hooks/duotone.cjs.map +2 -2
- package/build/hooks/gap.cjs +8 -2
- package/build/hooks/gap.cjs.map +2 -2
- package/build/hooks/layout-child.cjs +35 -13
- package/build/hooks/layout-child.cjs.map +2 -2
- package/build/hooks/layout.cjs +23 -1
- package/build/hooks/layout.cjs.map +2 -2
- package/build/hooks/states.cjs +7 -4
- package/build/hooks/states.cjs.map +2 -2
- package/build/layouts/constrained.cjs +8 -1
- package/build/layouts/constrained.cjs.map +2 -2
- package/build/layouts/flex.cjs +9 -0
- package/build/layouts/flex.cjs.map +2 -2
- package/build/layouts/flow.cjs +4 -1
- package/build/layouts/flow.cjs.map +2 -2
- package/build/layouts/grid.cjs +5 -1
- package/build/layouts/grid.cjs.map +2 -2
- package/build/private-apis.cjs +3 -1
- package/build/private-apis.cjs.map +2 -2
- package/build/store/actions.cjs +1 -1
- package/build/store/actions.cjs.map +2 -2
- package/build-module/components/block-inspector/index.mjs +9 -6
- package/build-module/components/block-inspector/index.mjs.map +2 -2
- package/build-module/components/block-keyboard-shortcuts/index.mjs +173 -0
- package/build-module/components/block-keyboard-shortcuts/index.mjs.map +7 -0
- package/build-module/components/block-list/block.mjs +10 -3
- package/build-module/components/block-list/block.mjs.map +2 -2
- package/build-module/components/block-list/index.mjs +6 -1
- package/build-module/components/block-list/index.mjs.map +2 -2
- package/build-module/components/block-list/use-block-props/use-focus-first-element.mjs +4 -0
- package/build-module/components/block-list/use-block-props/use-focus-first-element.mjs.map +2 -2
- package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs +6 -7
- package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs.map +2 -2
- package/build-module/components/block-parent-selector/index.mjs +101 -32
- package/build-module/components/block-parent-selector/index.mjs.map +2 -2
- package/build-module/components/block-popover/inbetween.mjs +2 -2
- package/build-module/components/block-popover/inbetween.mjs.map +2 -2
- package/build-module/components/block-preview/index.mjs +0 -4
- package/build-module/components/block-preview/index.mjs.map +2 -2
- package/build-module/components/block-styles/index.mjs +79 -35
- package/build-module/components/block-styles/index.mjs.map +2 -2
- package/build-module/components/block-visibility/constants.mjs.map +2 -2
- package/build-module/components/child-layout-control/index.mjs +5 -5
- package/build-module/components/child-layout-control/index.mjs.map +1 -1
- package/build-module/components/colors/with-colors.mjs +56 -72
- package/build-module/components/colors/with-colors.mjs.map +2 -2
- package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs +4 -2
- package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs.map +2 -2
- package/build-module/components/dimensions-tool/index.mjs +19 -17
- package/build-module/components/dimensions-tool/index.mjs.map +2 -2
- package/build-module/components/dimensions-tool/utils.mjs +35 -0
- package/build-module/components/dimensions-tool/utils.mjs.map +7 -0
- package/build-module/components/duotone-control/index.mjs +2 -0
- package/build-module/components/duotone-control/index.mjs.map +2 -2
- package/build-module/components/global-styles/advanced-panel.mjs +5 -2
- package/build-module/components/global-styles/advanced-panel.mjs.map +2 -2
- package/build-module/components/global-styles/border-panel.mjs +2 -5
- package/build-module/components/global-styles/border-panel.mjs.map +2 -2
- package/build-module/components/global-styles/color-panel.mjs +14 -2
- package/build-module/components/global-styles/color-panel.mjs.map +2 -2
- package/build-module/components/global-styles/dimensions-panel.mjs +9 -5
- package/build-module/components/global-styles/dimensions-panel.mjs.map +2 -2
- package/build-module/components/global-styles/filters-panel.mjs +16 -9
- package/build-module/components/global-styles/filters-panel.mjs.map +2 -2
- package/build-module/components/global-styles/shadow-panel-components.mjs +16 -11
- package/build-module/components/global-styles/shadow-panel-components.mjs.map +2 -2
- package/build-module/components/global-styles/utils.mjs +8 -0
- package/build-module/components/global-styles/utils.mjs.map +2 -2
- package/build-module/components/inner-blocks/index.mjs +5 -3
- package/build-module/components/inner-blocks/index.mjs.map +2 -2
- package/build-module/components/inserter/block-patterns-explorer/index.mjs +39 -22
- package/build-module/components/inserter/block-patterns-explorer/index.mjs.map +2 -2
- package/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.mjs +22 -56
- package/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.mjs.map +2 -2
- package/build-module/components/inserter/block-patterns-explorer/pattern-list.mjs +20 -45
- package/build-module/components/inserter/block-patterns-explorer/pattern-list.mjs.map +2 -2
- package/build-module/components/inserter/hooks/use-insertion-point.mjs +4 -4
- package/build-module/components/inserter/hooks/use-insertion-point.mjs.map +2 -2
- package/build-module/components/inserter/menu.mjs +19 -8
- package/build-module/components/inserter/menu.mjs.map +2 -2
- package/build-module/components/inserter/quick-inserter.mjs +30 -27
- package/build-module/components/inserter/quick-inserter.mjs.map +2 -2
- package/build-module/components/inspector-controls-tabs/styles-tab.mjs +1 -1
- package/build-module/components/inspector-controls-tabs/styles-tab.mjs.map +2 -2
- package/build-module/components/list-view/index.mjs +32 -5
- package/build-module/components/list-view/index.mjs.map +3 -3
- package/build-module/components/list-view/utils.mjs +13 -1
- package/build-module/components/list-view/utils.mjs.map +2 -2
- package/build-module/components/media-placeholder/index.mjs +3 -3
- package/build-module/components/media-placeholder/index.mjs.map +2 -2
- package/build-module/components/provider/index.mjs +6 -2
- package/build-module/components/provider/index.mjs.map +2 -2
- package/build-module/components/publish-date-time-picker/index.mjs +3 -2
- package/build-module/components/publish-date-time-picker/index.mjs.map +2 -2
- package/build-module/components/rich-text/event-listeners/enter.mjs +46 -39
- package/build-module/components/rich-text/event-listeners/enter.mjs.map +2 -2
- package/build-module/components/rich-text/index.mjs +7 -5
- package/build-module/components/rich-text/index.mjs.map +2 -2
- package/build-module/components/rich-text/multiline.mjs +112 -72
- package/build-module/components/rich-text/multiline.mjs.map +2 -2
- package/build-module/components/url-input/index.mjs +2 -2
- package/build-module/components/url-input/index.mjs.map +1 -1
- package/build-module/components/writing-flow/use-input.mjs +66 -14
- package/build-module/components/writing-flow/use-input.mjs.map +3 -3
- package/build-module/hooks/border.mjs +26 -8
- package/build-module/hooks/border.mjs.map +2 -2
- package/build-module/hooks/dimensions.mjs +9 -2
- package/build-module/hooks/dimensions.mjs.map +2 -2
- package/build-module/hooks/duotone.mjs +8 -4
- package/build-module/hooks/duotone.mjs.map +2 -2
- package/build-module/hooks/gap.mjs +6 -1
- package/build-module/hooks/gap.mjs.map +2 -2
- package/build-module/hooks/layout-child.mjs +36 -13
- package/build-module/hooks/layout-child.mjs.map +2 -2
- package/build-module/hooks/layout.mjs +22 -1
- package/build-module/hooks/layout.mjs.map +2 -2
- package/build-module/hooks/states.mjs +8 -5
- package/build-module/hooks/states.mjs.map +2 -2
- package/build-module/layouts/constrained.mjs +8 -1
- package/build-module/layouts/constrained.mjs.map +2 -2
- package/build-module/layouts/flex.mjs +9 -0
- package/build-module/layouts/flex.mjs.map +2 -2
- package/build-module/layouts/flow.mjs +4 -1
- package/build-module/layouts/flow.mjs.map +2 -2
- package/build-module/layouts/grid.mjs +5 -1
- package/build-module/layouts/grid.mjs.map +2 -2
- package/build-module/private-apis.mjs +3 -1
- package/build-module/private-apis.mjs.map +2 -2
- package/build-module/store/actions.mjs +1 -1
- package/build-module/store/actions.mjs.map +2 -2
- package/build-style/style-rtl.css +108 -71
- package/build-style/style.css +108 -71
- package/build-types/components/block-visibility/constants.d.ts +4 -3
- package/build-types/components/block-visibility/constants.d.ts.map +1 -1
- package/package.json +43 -43
- package/src/components/background-image-control/README.md +122 -0
- package/src/components/block-edit-visually-button/README.md +39 -0
- package/src/components/block-editing-mode/README.md +72 -0
- package/src/components/block-inspector/index.js +6 -6
- package/src/components/block-keyboard-shortcuts/index.js +256 -0
- package/src/components/block-list/block.js +7 -0
- package/src/components/block-list/index.js +7 -1
- package/src/components/block-list/use-block-props/use-focus-first-element.js +5 -0
- package/src/components/block-list/use-block-props/use-selected-block-event-handlers.js +6 -8
- package/src/components/block-parent-selector/index.js +111 -30
- package/src/components/block-popover/README.md +10 -3
- package/src/components/block-popover/inbetween.js +8 -2
- package/src/components/block-popover/stories/index.story.jsx +143 -0
- package/src/components/block-preview/index.js +0 -2
- package/src/components/block-styles/index.js +95 -43
- package/src/components/block-styles/style.scss +5 -34
- package/src/components/block-tools/style.scss +94 -0
- package/src/components/block-visibility/constants.ts +4 -3
- package/src/components/child-layout-control/index.js +5 -5
- package/src/components/color-palette/test/__snapshots__/control.js.snap +3 -29
- package/src/components/colors/test/with-colors.js +6 -7
- package/src/components/colors/with-colors.js +79 -105
- package/src/components/dimensions-tool/aspect-ratio-tool.js +16 -4
- package/src/components/dimensions-tool/index.js +34 -22
- package/src/components/dimensions-tool/test/index.js +166 -2
- package/src/components/dimensions-tool/test/utils.js +51 -0
- package/src/components/dimensions-tool/utils.js +67 -0
- package/src/components/duotone-control/index.js +2 -0
- package/src/components/duotone-control/test/index.js +100 -0
- package/src/components/global-styles/advanced-panel.js +5 -2
- package/src/components/global-styles/border-panel.js +11 -9
- package/src/components/global-styles/color-panel.js +13 -1
- package/src/components/global-styles/dimensions-panel.js +17 -5
- package/src/components/global-styles/filters-panel.js +24 -10
- package/src/components/global-styles/shadow-panel-components.js +38 -11
- package/src/components/global-styles/test/border-panel.js +230 -0
- package/src/components/global-styles/test/color-panel.js +24 -0
- package/src/components/global-styles/test/dimensions-panel.js +98 -7
- package/src/components/global-styles/test/filters-panel.js +84 -0
- package/src/components/global-styles/test/utils.js +30 -0
- package/src/components/global-styles/utils.js +23 -0
- package/src/components/inner-blocks/index.js +11 -2
- package/src/components/inner-blocks/stories/index.story.jsx +246 -0
- package/src/components/inserter/block-patterns-explorer/index.js +24 -11
- package/src/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js +18 -56
- package/src/components/inserter/block-patterns-explorer/pattern-list.js +22 -47
- package/src/components/inserter/hooks/use-insertion-point.js +9 -4
- package/src/components/inserter/menu.js +23 -10
- package/src/components/inserter/quick-inserter.js +15 -13
- package/src/components/inserter/style.scss +44 -62
- package/src/components/inspector-controls-tabs/README.md +92 -0
- package/src/components/inspector-controls-tabs/styles-tab.js +1 -1
- package/src/components/link-control/test/index.js +5 -0
- package/src/components/list-view/index.js +50 -7
- package/src/components/list-view/utils.js +16 -1
- package/src/components/media-placeholder/index.js +9 -4
- package/src/components/plain-text/stories/index.story.jsx +3 -0
- package/src/components/provider/index.js +7 -1
- package/src/components/publish-date-time-picker/README.md +10 -0
- package/src/components/publish-date-time-picker/index.js +17 -14
- package/src/components/rich-text/event-listeners/enter.js +58 -45
- package/src/components/rich-text/index.js +9 -4
- package/src/components/rich-text/multiline.js +126 -86
- package/src/components/url-input/index.js +2 -2
- package/src/components/url-input/test/fixtures/validated-input-control-deprecation.js +27 -0
- package/src/components/url-input/test/index.js +5 -0
- package/src/components/url-popover/README.md +7 -0
- package/src/components/url-popover/stories/index.story.jsx +133 -47
- package/src/components/writing-flow/use-input.js +105 -15
- package/src/hooks/border.js +27 -8
- package/src/hooks/dimensions.js +8 -1
- package/src/hooks/duotone.js +23 -7
- package/src/hooks/gap.js +16 -0
- package/src/hooks/layout-child.js +41 -9
- package/src/hooks/layout.js +117 -71
- package/src/hooks/states.js +8 -5
- package/src/hooks/test/gap.js +31 -1
- package/src/hooks/test/layout-child.js +60 -1
- package/src/hooks/test/layout.js +27 -0
- package/src/layouts/constrained.js +9 -1
- package/src/layouts/flex.js +15 -0
- package/src/layouts/flow.js +4 -1
- package/src/layouts/grid.js +9 -1
- package/src/layouts/test/constrained.js +26 -0
- package/src/layouts/test/flow.js +26 -0
- package/src/layouts/test/grid.js +46 -0
- package/src/private-apis.js +2 -0
- package/src/store/actions.js +14 -1
- package/build/components/floating-toolbar/nav-up-icon.cjs +0 -52
- package/build/components/floating-toolbar/nav-up-icon.cjs.map +0 -7
- package/build/components/gradients/with-gradient.cjs +0 -36
- package/build/components/gradients/with-gradient.cjs.map +0 -7
- package/build/components/inserter-button/sparkles.cjs +0 -36
- package/build/components/inserter-button/sparkles.cjs.map +0 -7
- package/build-module/components/floating-toolbar/nav-up-icon.mjs +0 -31
- package/build-module/components/floating-toolbar/nav-up-icon.mjs.map +0 -7
- package/build-module/components/gradients/with-gradient.mjs +0 -11
- package/build-module/components/gradients/with-gradient.mjs.map +0 -7
- package/build-module/components/inserter-button/sparkles.mjs +0 -15
- package/build-module/components/inserter-button/sparkles.mjs.map +0 -7
- package/build-style/default-editor-styles-rtl.css +0 -68
- package/build-style/default-editor-styles.css +0 -68
- package/src/components/floating-toolbar/nav-up-icon.js +0 -22
- package/src/components/gradients/with-gradient.js +0 -9
- package/src/components/inserter-button/README.md +0 -62
- package/src/components/inserter-button/sparkles.js +0 -12
- package/src/default-editor-styles.scss +0 -25
|
@@ -25,13 +25,27 @@ const EMPTY_ARRAY = [];
|
|
|
25
25
|
|
|
26
26
|
export function ShadowPopoverContainer( { shadow, onShadowChange, settings } ) {
|
|
27
27
|
const shadows = useShadowPresets( settings );
|
|
28
|
+
const presets = useMemo( () => {
|
|
29
|
+
if ( ! shadows.length ) {
|
|
30
|
+
return shadows;
|
|
31
|
+
}
|
|
32
|
+
// The entry that clears the shadow is a display-only affordance with no
|
|
33
|
+
// counterpart in `theme.json`. It is added here rather than in
|
|
34
|
+
// `useShadowPresets` so that callers mapping a value back to a preset
|
|
35
|
+
// never mistake it for one and persist a reference to a CSS variable
|
|
36
|
+
// that is never output.
|
|
37
|
+
return [
|
|
38
|
+
{ name: __( 'Unset' ), slug: 'unset', shadow: 'none' },
|
|
39
|
+
...shadows,
|
|
40
|
+
];
|
|
41
|
+
}, [ shadows ] );
|
|
28
42
|
|
|
29
43
|
return (
|
|
30
44
|
<div className="block-editor-global-styles__shadow-popover-container">
|
|
31
45
|
<VStack spacing={ 4 }>
|
|
32
46
|
<Heading level={ 5 }>{ __( 'Drop shadow' ) }</Heading>
|
|
33
47
|
<ShadowPresets
|
|
34
|
-
presets={
|
|
48
|
+
presets={ presets }
|
|
35
49
|
activeShadow={ shadow }
|
|
36
50
|
onSelect={ onShadowChange }
|
|
37
51
|
/>
|
|
@@ -209,6 +223,18 @@ function renderShadowToggle( shadow, onShadowChange, resetConfig ) {
|
|
|
209
223
|
};
|
|
210
224
|
}
|
|
211
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Returns the available shadow presets, from every origin, in the order they
|
|
228
|
+
* are presented to the user.
|
|
229
|
+
*
|
|
230
|
+
* This is the single source of truth for which presets exist: it backs both the
|
|
231
|
+
* popover's preset list and the mapping of a chosen shadow back to the preset
|
|
232
|
+
* it came from, so what is shown and what is stored cannot drift apart.
|
|
233
|
+
*
|
|
234
|
+
* @param {Object} settings Theme.json settings for the current context.
|
|
235
|
+
*
|
|
236
|
+
* @return {Array} The shadow presets.
|
|
237
|
+
*/
|
|
212
238
|
export function useShadowPresets( settings ) {
|
|
213
239
|
return useMemo( () => {
|
|
214
240
|
if ( ! settings?.shadow ) {
|
|
@@ -221,21 +247,22 @@ export function useShadowPresets( settings ) {
|
|
|
221
247
|
theme: themeShadows,
|
|
222
248
|
custom: customShadows,
|
|
223
249
|
} = settings?.shadow?.presets ?? {};
|
|
224
|
-
const unsetShadow = {
|
|
225
|
-
name: __( 'Unset' ),
|
|
226
|
-
slug: 'unset',
|
|
227
|
-
shadow: 'none',
|
|
228
|
-
};
|
|
229
250
|
|
|
230
|
-
const
|
|
251
|
+
const allPresets = [
|
|
231
252
|
...( ( defaultPresetsEnabled && defaultShadows ) || EMPTY_ARRAY ),
|
|
232
253
|
...( themeShadows || EMPTY_ARRAY ),
|
|
233
254
|
...( customShadows || EMPTY_ARRAY ),
|
|
234
255
|
];
|
|
235
|
-
if ( shadowPresets.length ) {
|
|
236
|
-
shadowPresets.unshift( unsetShadow );
|
|
237
|
-
}
|
|
238
256
|
|
|
239
|
-
|
|
257
|
+
// More than one origin can define the same slug, but only the most
|
|
258
|
+
// specific definition is output as a CSS variable. Keeping the ones it
|
|
259
|
+
// overrides would offer swatches that apply a different shadow than
|
|
260
|
+
// the one they show.
|
|
261
|
+
return allPresets.filter(
|
|
262
|
+
( preset, index ) =>
|
|
263
|
+
allPresets.findLastIndex(
|
|
264
|
+
( { slug } ) => slug === preset.slug
|
|
265
|
+
) === index
|
|
266
|
+
);
|
|
240
267
|
}, [ settings ] );
|
|
241
268
|
}
|
|
@@ -432,3 +432,233 @@ describe( 'BorderPanel — inherited Global Styles label treatment', () => {
|
|
|
432
432
|
} );
|
|
433
433
|
} );
|
|
434
434
|
} );
|
|
435
|
+
|
|
436
|
+
describe( 'BorderPanel — shadow preset persistence', () => {
|
|
437
|
+
const selectShadowPreset = async ( user, name ) => {
|
|
438
|
+
await user.click(
|
|
439
|
+
screen.getByRole( 'button', { name: 'Drop shadow' } )
|
|
440
|
+
);
|
|
441
|
+
await user.click( screen.getByRole( 'option', { name } ) );
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
const shadowSettings = ( presets, defaultPresets = true ) => ( {
|
|
445
|
+
shadow: { defaultPresets, presets },
|
|
446
|
+
} );
|
|
447
|
+
|
|
448
|
+
const defaultPreset = {
|
|
449
|
+
name: 'Natural',
|
|
450
|
+
slug: 'natural',
|
|
451
|
+
shadow: '6px 6px 9px rgba(0, 0, 0, 0.2)',
|
|
452
|
+
};
|
|
453
|
+
const themePreset = {
|
|
454
|
+
name: 'Outlined',
|
|
455
|
+
slug: 'outlined',
|
|
456
|
+
shadow: '6px 6px 0px -3px rgba(255, 255, 255, 1), 6px 6px rgba(0, 0, 0, 1)',
|
|
457
|
+
};
|
|
458
|
+
const customPreset = {
|
|
459
|
+
name: 'My shadow',
|
|
460
|
+
slug: 'my-shadow',
|
|
461
|
+
shadow: '0 0 10px rgba(255, 0, 0, 1)',
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
it( 'persists a theme preset as a preset reference when custom presets also exist', async () => {
|
|
465
|
+
const user = userEvent.setup();
|
|
466
|
+
const onChange = jest.fn();
|
|
467
|
+
|
|
468
|
+
render(
|
|
469
|
+
<BorderPanel
|
|
470
|
+
value={ {} }
|
|
471
|
+
settings={ shadowSettings( {
|
|
472
|
+
default: [ defaultPreset ],
|
|
473
|
+
theme: [ themePreset ],
|
|
474
|
+
custom: [ customPreset ],
|
|
475
|
+
} ) }
|
|
476
|
+
onChange={ onChange }
|
|
477
|
+
panelId="test-panel"
|
|
478
|
+
/>
|
|
479
|
+
);
|
|
480
|
+
|
|
481
|
+
await selectShadowPreset( user, 'Outlined' );
|
|
482
|
+
|
|
483
|
+
expect( onChange ).toHaveBeenCalledWith( {
|
|
484
|
+
shadow: 'var:preset|shadow|outlined',
|
|
485
|
+
} );
|
|
486
|
+
} );
|
|
487
|
+
|
|
488
|
+
it( 'persists a default preset as a preset reference when custom presets also exist', async () => {
|
|
489
|
+
const user = userEvent.setup();
|
|
490
|
+
const onChange = jest.fn();
|
|
491
|
+
|
|
492
|
+
render(
|
|
493
|
+
<BorderPanel
|
|
494
|
+
value={ {} }
|
|
495
|
+
settings={ shadowSettings( {
|
|
496
|
+
default: [ defaultPreset ],
|
|
497
|
+
theme: [ themePreset ],
|
|
498
|
+
custom: [ customPreset ],
|
|
499
|
+
} ) }
|
|
500
|
+
onChange={ onChange }
|
|
501
|
+
panelId="test-panel"
|
|
502
|
+
/>
|
|
503
|
+
);
|
|
504
|
+
|
|
505
|
+
await selectShadowPreset( user, 'Natural' );
|
|
506
|
+
|
|
507
|
+
expect( onChange ).toHaveBeenCalledWith( {
|
|
508
|
+
shadow: 'var:preset|shadow|natural',
|
|
509
|
+
} );
|
|
510
|
+
} );
|
|
511
|
+
|
|
512
|
+
it( 'persists a custom preset as a preset reference', async () => {
|
|
513
|
+
const user = userEvent.setup();
|
|
514
|
+
const onChange = jest.fn();
|
|
515
|
+
|
|
516
|
+
render(
|
|
517
|
+
<BorderPanel
|
|
518
|
+
value={ {} }
|
|
519
|
+
settings={ shadowSettings( {
|
|
520
|
+
default: [ defaultPreset ],
|
|
521
|
+
theme: [ themePreset ],
|
|
522
|
+
custom: [ customPreset ],
|
|
523
|
+
} ) }
|
|
524
|
+
onChange={ onChange }
|
|
525
|
+
panelId="test-panel"
|
|
526
|
+
/>
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
await selectShadowPreset( user, 'My shadow' );
|
|
530
|
+
|
|
531
|
+
expect( onChange ).toHaveBeenCalledWith( {
|
|
532
|
+
shadow: 'var:preset|shadow|my-shadow',
|
|
533
|
+
} );
|
|
534
|
+
} );
|
|
535
|
+
|
|
536
|
+
it( 'persists the unset entry as a literal value, not a preset reference', async () => {
|
|
537
|
+
const user = userEvent.setup();
|
|
538
|
+
const onChange = jest.fn();
|
|
539
|
+
|
|
540
|
+
render(
|
|
541
|
+
<BorderPanel
|
|
542
|
+
value={ {} }
|
|
543
|
+
settings={ shadowSettings( {
|
|
544
|
+
theme: [ themePreset ],
|
|
545
|
+
custom: [ customPreset ],
|
|
546
|
+
} ) }
|
|
547
|
+
onChange={ onChange }
|
|
548
|
+
panelId="test-panel"
|
|
549
|
+
/>
|
|
550
|
+
);
|
|
551
|
+
|
|
552
|
+
await selectShadowPreset( user, 'Unset' );
|
|
553
|
+
|
|
554
|
+
expect( onChange ).toHaveBeenCalledWith( { shadow: 'none' } );
|
|
555
|
+
} );
|
|
556
|
+
|
|
557
|
+
it( 'does not reference default presets the theme has opted out of', async () => {
|
|
558
|
+
const user = userEvent.setup();
|
|
559
|
+
const onChange = jest.fn();
|
|
560
|
+
|
|
561
|
+
render(
|
|
562
|
+
<BorderPanel
|
|
563
|
+
value={ {} }
|
|
564
|
+
settings={ shadowSettings(
|
|
565
|
+
{
|
|
566
|
+
// Same shadow value as the theme preset below, so the
|
|
567
|
+
// lookup has to skip it rather than match it first.
|
|
568
|
+
default: [
|
|
569
|
+
{ ...defaultPreset, shadow: themePreset.shadow },
|
|
570
|
+
],
|
|
571
|
+
theme: [ themePreset ],
|
|
572
|
+
},
|
|
573
|
+
false
|
|
574
|
+
) }
|
|
575
|
+
onChange={ onChange }
|
|
576
|
+
panelId="test-panel"
|
|
577
|
+
/>
|
|
578
|
+
);
|
|
579
|
+
|
|
580
|
+
await selectShadowPreset( user, 'Outlined' );
|
|
581
|
+
|
|
582
|
+
// The opted-out preset is not offered, so it is not something the
|
|
583
|
+
// user can have meant.
|
|
584
|
+
expect(
|
|
585
|
+
screen.queryByRole( 'option', { name: 'Natural' } )
|
|
586
|
+
).not.toBeInTheDocument();
|
|
587
|
+
expect( onChange ).toHaveBeenCalledWith( {
|
|
588
|
+
shadow: 'var:preset|shadow|outlined',
|
|
589
|
+
} );
|
|
590
|
+
} );
|
|
591
|
+
|
|
592
|
+
it( 'offers only the most specific preset when a slug is defined twice', async () => {
|
|
593
|
+
const user = userEvent.setup();
|
|
594
|
+
const onChange = jest.fn();
|
|
595
|
+
|
|
596
|
+
// Custom preset slugs are generated as `shadow-<n>` from the custom
|
|
597
|
+
// presets alone, so they can collide with a theme preset's slug.
|
|
598
|
+
const themeShadowOne = {
|
|
599
|
+
name: 'Theme shadow',
|
|
600
|
+
slug: 'shadow-1',
|
|
601
|
+
shadow: '0 0 10px rgba(0, 0, 255, 1)',
|
|
602
|
+
};
|
|
603
|
+
const customShadowOne = {
|
|
604
|
+
name: 'Shadow 1',
|
|
605
|
+
slug: 'shadow-1',
|
|
606
|
+
shadow: '0 0 10px rgba(255, 0, 0, 1)',
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
render(
|
|
610
|
+
<BorderPanel
|
|
611
|
+
value={ {} }
|
|
612
|
+
settings={ shadowSettings( {
|
|
613
|
+
theme: [ themeShadowOne ],
|
|
614
|
+
custom: [ customShadowOne ],
|
|
615
|
+
} ) }
|
|
616
|
+
onChange={ onChange }
|
|
617
|
+
panelId="test-panel"
|
|
618
|
+
/>
|
|
619
|
+
);
|
|
620
|
+
|
|
621
|
+
await user.click(
|
|
622
|
+
screen.getByRole( 'button', { name: 'Drop shadow' } )
|
|
623
|
+
);
|
|
624
|
+
|
|
625
|
+
// `--wp--preset--shadow--shadow-1` holds the custom preset's value, so
|
|
626
|
+
// offering the theme one would show a shadow it cannot apply.
|
|
627
|
+
expect(
|
|
628
|
+
screen.queryByRole( 'option', { name: 'Theme shadow' } )
|
|
629
|
+
).not.toBeInTheDocument();
|
|
630
|
+
|
|
631
|
+
await user.click( screen.getByRole( 'option', { name: 'Shadow 1' } ) );
|
|
632
|
+
|
|
633
|
+
expect( onChange ).toHaveBeenCalledWith( {
|
|
634
|
+
shadow: 'var:preset|shadow|shadow-1',
|
|
635
|
+
} );
|
|
636
|
+
} );
|
|
637
|
+
|
|
638
|
+
it( 'references the most specific origin when two presets share a value', async () => {
|
|
639
|
+
const user = userEvent.setup();
|
|
640
|
+
const onChange = jest.fn();
|
|
641
|
+
|
|
642
|
+
// A custom preset starts out with the same value as the `natural`
|
|
643
|
+
// default one, so this is the state right after adding one.
|
|
644
|
+
render(
|
|
645
|
+
<BorderPanel
|
|
646
|
+
value={ {} }
|
|
647
|
+
settings={ shadowSettings( {
|
|
648
|
+
default: [ defaultPreset ],
|
|
649
|
+
custom: [
|
|
650
|
+
{ ...customPreset, shadow: defaultPreset.shadow },
|
|
651
|
+
],
|
|
652
|
+
} ) }
|
|
653
|
+
onChange={ onChange }
|
|
654
|
+
panelId="test-panel"
|
|
655
|
+
/>
|
|
656
|
+
);
|
|
657
|
+
|
|
658
|
+
await selectShadowPreset( user, 'My shadow' );
|
|
659
|
+
|
|
660
|
+
expect( onChange ).toHaveBeenCalledWith( {
|
|
661
|
+
shadow: 'var:preset|shadow|my-shadow',
|
|
662
|
+
} );
|
|
663
|
+
} );
|
|
664
|
+
} );
|
|
@@ -258,6 +258,30 @@ describe( 'ColorPanel — duplicate-hex preset slug identity', () => {
|
|
|
258
258
|
} );
|
|
259
259
|
} );
|
|
260
260
|
|
|
261
|
+
describe( 'ColorPanel — additional elements', () => {
|
|
262
|
+
it( 'renders additional element color controls', () => {
|
|
263
|
+
render(
|
|
264
|
+
<ColorPanel
|
|
265
|
+
value={ {} }
|
|
266
|
+
settings={ settingsWithColors( {
|
|
267
|
+
text: true,
|
|
268
|
+
background: true,
|
|
269
|
+
} ) }
|
|
270
|
+
onChange={ () => {} }
|
|
271
|
+
panelId="test-panel"
|
|
272
|
+
additionalElements={ [
|
|
273
|
+
{ name: 'textInput', label: 'Inputs' },
|
|
274
|
+
] }
|
|
275
|
+
defaultControls={ { textInput: true } }
|
|
276
|
+
/>
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
expect(
|
|
280
|
+
screen.getByRole( 'button', { name: /^Inputs/ } )
|
|
281
|
+
).toBeVisible();
|
|
282
|
+
} );
|
|
283
|
+
} );
|
|
284
|
+
|
|
261
285
|
describe( 'ColorPanel — inherited Global Styles label treatment', () => {
|
|
262
286
|
describe( 'Link color', () => {
|
|
263
287
|
it( 'exposes an accessible reset when local link.text overrides the inherited value', () => {
|
|
@@ -90,6 +90,14 @@ const baseSettings = {
|
|
|
90
90
|
},
|
|
91
91
|
};
|
|
92
92
|
|
|
93
|
+
const settingsWithAxialGap = {
|
|
94
|
+
...baseSettings,
|
|
95
|
+
spacing: {
|
|
96
|
+
...baseSettings.spacing,
|
|
97
|
+
blockGap: [ 'horizontal', 'vertical' ],
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
93
101
|
const settingsWithDimensions = {
|
|
94
102
|
...baseSettings,
|
|
95
103
|
dimensions: {
|
|
@@ -280,12 +288,7 @@ describe( 'DimensionsPanel — per-control placeholder pattern', () => {
|
|
|
280
288
|
expect( gapInput ).toHaveAttribute( 'placeholder', '1.5rem' );
|
|
281
289
|
} );
|
|
282
290
|
|
|
283
|
-
it( 'renders
|
|
284
|
-
// When blockGap is an object (axial split), the panel still
|
|
285
|
-
// renders the single-input UnitControl path because the
|
|
286
|
-
// settings here do not enable axial gap sides. The placeholder
|
|
287
|
-
// must NOT surface a non-string value into a control that
|
|
288
|
-
// cannot display it.
|
|
291
|
+
it( 'renders the vertical blockGap as a placeholder when the inherited value has an axial shape', () => {
|
|
289
292
|
renderPanel( {
|
|
290
293
|
value: {},
|
|
291
294
|
inheritedValue: {
|
|
@@ -295,7 +298,95 @@ describe( 'DimensionsPanel — per-control placeholder pattern', () => {
|
|
|
295
298
|
} );
|
|
296
299
|
|
|
297
300
|
const gapInput = screen.getByLabelText( /block spacing/i );
|
|
298
|
-
expect( gapInput ).
|
|
301
|
+
expect( gapInput ).toHaveAttribute( 'placeholder', '1rem' );
|
|
302
|
+
} );
|
|
303
|
+
|
|
304
|
+
it( 'renders the vertical blockGap when a local axial value is shown in a single input', () => {
|
|
305
|
+
renderPanel( {
|
|
306
|
+
value: {
|
|
307
|
+
spacing: { blockGap: { top: '1rem', left: '0.5rem' } },
|
|
308
|
+
},
|
|
309
|
+
settings: baseSettings,
|
|
310
|
+
} );
|
|
311
|
+
|
|
312
|
+
const gapInput = screen.getByLabelText( /block spacing/i );
|
|
313
|
+
expect( gapInput ).toHaveValue( 1 );
|
|
314
|
+
} );
|
|
315
|
+
} );
|
|
316
|
+
|
|
317
|
+
describe( 'block spacing (axial gap path)', () => {
|
|
318
|
+
it( 'renders separate horizontal and vertical controls when axial block gap is allowed', async () => {
|
|
319
|
+
const user = userEvent.setup();
|
|
320
|
+
renderPanel( {
|
|
321
|
+
value: {},
|
|
322
|
+
settings: settingsWithAxialGap,
|
|
323
|
+
} );
|
|
324
|
+
|
|
325
|
+
const blockSpacingControl = screen.getByRole( 'group', {
|
|
326
|
+
name: 'Block spacing',
|
|
327
|
+
} );
|
|
328
|
+
await user.click(
|
|
329
|
+
within( blockSpacingControl ).getByRole( 'button', {
|
|
330
|
+
name: 'Unlink sides',
|
|
331
|
+
} )
|
|
332
|
+
);
|
|
333
|
+
|
|
334
|
+
expect(
|
|
335
|
+
within( blockSpacingControl ).getByRole( 'textbox', {
|
|
336
|
+
name: 'Top and bottom sides',
|
|
337
|
+
} )
|
|
338
|
+
).toBeInTheDocument();
|
|
339
|
+
expect(
|
|
340
|
+
within( blockSpacingControl ).getByRole( 'textbox', {
|
|
341
|
+
name: 'Left and right sides',
|
|
342
|
+
} )
|
|
343
|
+
).toBeInTheDocument();
|
|
344
|
+
} );
|
|
345
|
+
|
|
346
|
+
it( 'renders a single control when axial block gap is not allowed', () => {
|
|
347
|
+
renderPanel( {
|
|
348
|
+
value: {},
|
|
349
|
+
settings: settingsWithAxialGap,
|
|
350
|
+
allowAxialBlockGap: false,
|
|
351
|
+
} );
|
|
352
|
+
|
|
353
|
+
expect(
|
|
354
|
+
screen.getByLabelText( /block spacing/i )
|
|
355
|
+
).toBeInTheDocument();
|
|
356
|
+
expect(
|
|
357
|
+
screen.queryByRole( 'group', { name: 'Block spacing' } )
|
|
358
|
+
).not.toBeInTheDocument();
|
|
359
|
+
} );
|
|
360
|
+
|
|
361
|
+
it( 'keeps the block spacing control visible when axial support changes', () => {
|
|
362
|
+
const settings = {
|
|
363
|
+
...settingsWithSpacingPresets,
|
|
364
|
+
spacing: {
|
|
365
|
+
...settingsWithSpacingPresets.spacing,
|
|
366
|
+
blockGap: [ 'horizontal', 'vertical' ],
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
const props = {
|
|
370
|
+
value: {},
|
|
371
|
+
settings,
|
|
372
|
+
onChange: () => {},
|
|
373
|
+
panelId: 'test-panel',
|
|
374
|
+
};
|
|
375
|
+
const { rerender } = render(
|
|
376
|
+
<DimensionsPanel { ...props } allowAxialBlockGap />
|
|
377
|
+
);
|
|
378
|
+
|
|
379
|
+
expect(
|
|
380
|
+
screen.getAllByRole( 'slider', { name: /block spacing/i } )
|
|
381
|
+
).toHaveLength( 2 );
|
|
382
|
+
|
|
383
|
+
rerender(
|
|
384
|
+
<DimensionsPanel { ...props } allowAxialBlockGap={ false } />
|
|
385
|
+
);
|
|
386
|
+
|
|
387
|
+
expect(
|
|
388
|
+
screen.getAllByRole( 'slider', { name: /block spacing/i } )
|
|
389
|
+
).toHaveLength( 1 );
|
|
299
390
|
} );
|
|
300
391
|
} );
|
|
301
392
|
|
|
@@ -185,3 +185,87 @@ describe( 'FiltersPanel — visual treatment and display-without-commit', () =>
|
|
|
185
185
|
expect( onChange ).not.toHaveBeenCalled();
|
|
186
186
|
} );
|
|
187
187
|
} );
|
|
188
|
+
|
|
189
|
+
// Adding two custom duotones in Global Styles seeds both from the palette's
|
|
190
|
+
// darkest and lightest colors, so duplicates are the ordinary case. Only the
|
|
191
|
+
// slug tells them apart.
|
|
192
|
+
const duplicateSettings = {
|
|
193
|
+
color: {
|
|
194
|
+
customDuotone: true,
|
|
195
|
+
defaultDuotone: true,
|
|
196
|
+
duotone: {
|
|
197
|
+
custom: [
|
|
198
|
+
{
|
|
199
|
+
name: 'Duotone 1',
|
|
200
|
+
slug: 'custom-duotone-1',
|
|
201
|
+
colors: [ '#000000', '#ffffff' ],
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: 'Duotone 2',
|
|
205
|
+
slug: 'custom-duotone-2',
|
|
206
|
+
colors: [ '#000000', '#ffffff' ],
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
palette: {
|
|
211
|
+
default: [
|
|
212
|
+
{ name: 'Black', slug: 'black', color: '#000000' },
|
|
213
|
+
{ name: 'White', slug: 'white', color: '#ffffff' },
|
|
214
|
+
],
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
async function openDuotone( user ) {
|
|
220
|
+
await user.click( screen.getByRole( 'button', { name: /duotone/i } ) );
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
describe( 'FiltersPanel — duplicate duotone presets', () => {
|
|
224
|
+
it( 'marks only the stored preset as selected', async () => {
|
|
225
|
+
const user = userEvent.setup();
|
|
226
|
+
|
|
227
|
+
render(
|
|
228
|
+
<FiltersPanel
|
|
229
|
+
value={ {
|
|
230
|
+
filter: { duotone: 'var:preset|duotone|custom-duotone-2' },
|
|
231
|
+
} }
|
|
232
|
+
inheritedValue={ {} }
|
|
233
|
+
settings={ duplicateSettings }
|
|
234
|
+
onChange={ () => {} }
|
|
235
|
+
panelId="test-panel"
|
|
236
|
+
/>
|
|
237
|
+
);
|
|
238
|
+
await openDuotone( user );
|
|
239
|
+
|
|
240
|
+
expect(
|
|
241
|
+
screen.getByRole( 'option', { name: 'Duotone: Duotone 1' } )
|
|
242
|
+
).toHaveAttribute( 'aria-selected', 'false' );
|
|
243
|
+
expect(
|
|
244
|
+
screen.getByRole( 'option', { name: 'Duotone: Duotone 2' } )
|
|
245
|
+
).toHaveAttribute( 'aria-selected', 'true' );
|
|
246
|
+
} );
|
|
247
|
+
|
|
248
|
+
it( 'saves the slug of the preset that was picked', async () => {
|
|
249
|
+
const user = userEvent.setup();
|
|
250
|
+
const onChange = jest.fn();
|
|
251
|
+
|
|
252
|
+
render(
|
|
253
|
+
<FiltersPanel
|
|
254
|
+
value={ {} }
|
|
255
|
+
inheritedValue={ {} }
|
|
256
|
+
settings={ duplicateSettings }
|
|
257
|
+
onChange={ onChange }
|
|
258
|
+
panelId="test-panel"
|
|
259
|
+
/>
|
|
260
|
+
);
|
|
261
|
+
await openDuotone( user );
|
|
262
|
+
|
|
263
|
+
await user.click(
|
|
264
|
+
screen.getByRole( 'option', { name: 'Duotone: Duotone 2' } )
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
expect( onChange ).toHaveBeenCalledWith( {
|
|
268
|
+
filter: { duotone: 'var:preset|duotone|custom-duotone-2' },
|
|
269
|
+
} );
|
|
270
|
+
} );
|
|
271
|
+
} );
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getDuotoneSlugFromPreset } from '../utils';
|
|
2
|
+
|
|
3
|
+
describe( 'global styles utils', () => {
|
|
4
|
+
describe( 'getDuotoneSlugFromPreset', () => {
|
|
5
|
+
it( 'should return the slug of a preset reference', () => {
|
|
6
|
+
expect(
|
|
7
|
+
getDuotoneSlugFromPreset( 'var:preset|duotone|grayscale' )
|
|
8
|
+
).toBe( 'grayscale' );
|
|
9
|
+
} );
|
|
10
|
+
|
|
11
|
+
it( 'should return the slug of a custom preset', () => {
|
|
12
|
+
expect(
|
|
13
|
+
getDuotoneSlugFromPreset(
|
|
14
|
+
'var:preset|duotone|custom-duotone-2'
|
|
15
|
+
)
|
|
16
|
+
).toBe( 'custom-duotone-2' );
|
|
17
|
+
} );
|
|
18
|
+
|
|
19
|
+
it( 'should return undefined for custom colors', () => {
|
|
20
|
+
expect(
|
|
21
|
+
getDuotoneSlugFromPreset( [ '#000000', '#ffffff' ] )
|
|
22
|
+
).toBeUndefined();
|
|
23
|
+
} );
|
|
24
|
+
|
|
25
|
+
it( 'should return undefined for unset and for no value', () => {
|
|
26
|
+
expect( getDuotoneSlugFromPreset( 'unset' ) ).toBeUndefined();
|
|
27
|
+
expect( getDuotoneSlugFromPreset( undefined ) ).toBeUndefined();
|
|
28
|
+
} );
|
|
29
|
+
} );
|
|
30
|
+
} );
|
|
@@ -47,3 +47,26 @@ export function scopeSelector( scope, selector ) {
|
|
|
47
47
|
|
|
48
48
|
return selectorsScoped.join( ', ' );
|
|
49
49
|
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Reads the preset slug out of a duotone style value.
|
|
53
|
+
*
|
|
54
|
+
* Two presets can hold the same pair of colors, so the slug is the only thing
|
|
55
|
+
* that identifies which one is applied. The colors alone do not.
|
|
56
|
+
*
|
|
57
|
+
* Lives here rather than beside its siblings in `hooks/duotone` because that
|
|
58
|
+
* module imports the filters panel, so the panel cannot import back from it.
|
|
59
|
+
*
|
|
60
|
+
* @param {string|string[]|undefined} duotone A duotone style value.
|
|
61
|
+
*
|
|
62
|
+
* @return {string|undefined} The preset slug, if the value references one.
|
|
63
|
+
*/
|
|
64
|
+
export function getDuotoneSlugFromPreset( duotone ) {
|
|
65
|
+
if ( typeof duotone !== 'string' ) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const [ , slug ] = duotone.match( /^var:preset\|duotone\|(.+)$/ ) ?? [];
|
|
70
|
+
|
|
71
|
+
return slug;
|
|
72
|
+
}
|
|
@@ -94,7 +94,11 @@ function UncontrolledInnerBlocks( props ) {
|
|
|
94
94
|
EMPTY_OBJECT;
|
|
95
95
|
|
|
96
96
|
const { allowSizingOnChildren = false } = defaultLayoutBlockSupport;
|
|
97
|
-
|
|
97
|
+
// The support is a config object, e.g. `{ allowSwitching: false, default: { type: 'flex' } }`,
|
|
98
|
+
// so the layout itself lives under `default`. Passing the config through would leave the
|
|
99
|
+
// context without a `type`, and consumers would resolve it to the flow layout.
|
|
100
|
+
const usedLayout =
|
|
101
|
+
layout || defaultLayoutBlockSupport.default || EMPTY_OBJECT;
|
|
98
102
|
|
|
99
103
|
const memoedLayout = useMemo(
|
|
100
104
|
() => ( {
|
|
@@ -174,12 +178,17 @@ export function useInnerBlocksProps( props = {}, options = {} ) {
|
|
|
174
178
|
__unstableDisableLayoutClassNames,
|
|
175
179
|
__unstableDisableDropZone,
|
|
176
180
|
dropZoneElement,
|
|
181
|
+
layout: layoutOverride,
|
|
177
182
|
} = options;
|
|
178
183
|
const {
|
|
179
184
|
clientId,
|
|
180
|
-
layout = null,
|
|
185
|
+
layout: contextLayout = null,
|
|
181
186
|
__unstableLayoutClassNames: layoutClassNames = '',
|
|
182
187
|
} = useBlockEditContext();
|
|
188
|
+
// An options layout takes precedence over the context layout, as it does
|
|
189
|
+
// for the inner blocks settings, so containers whose layout attribute
|
|
190
|
+
// doesn't apply to their inner blocks (e.g. Post Template) can opt out.
|
|
191
|
+
const layout = layoutOverride ?? contextLayout;
|
|
183
192
|
const selected = useSelect(
|
|
184
193
|
( select ) => {
|
|
185
194
|
const {
|