@wordpress/block-editor 15.21.1 → 15.22.1-next.v.202606191442.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 +6 -0
- package/build/components/block-card/index.cjs +4 -5
- package/build/components/block-card/index.cjs.map +2 -2
- package/build/components/block-inspector/index.cjs +3 -4
- package/build/components/block-inspector/index.cjs.map +2 -2
- package/build/components/block-mover/mover-description.cjs +6 -6
- package/build/components/block-mover/mover-description.cjs.map +1 -1
- package/build/components/block-patterns-list/index.cjs.map +2 -2
- package/build/components/block-patterns-paging/index.cjs +4 -4
- package/build/components/block-patterns-paging/index.cjs.map +2 -2
- package/build/components/block-popover/use-popover-scroll.cjs.map +1 -1
- package/build/components/block-quick-navigation/index.cjs +7 -5
- package/build/components/block-quick-navigation/index.cjs.map +2 -2
- package/build/components/block-toolbar/edit-section-button.cjs.map +1 -1
- package/build/components/block-tools/use-block-toolbar-popover-props.cjs +10 -4
- package/build/components/block-tools/use-block-toolbar-popover-props.cjs.map +2 -2
- package/build/components/child-layout-control/index.cjs +51 -19
- package/build/components/child-layout-control/index.cjs.map +2 -2
- package/build/components/dimensions-tool/index.cjs +4 -5
- package/build/components/dimensions-tool/index.cjs.map +2 -2
- package/build/components/dimensions-tool/scale-tool.cjs +1 -1
- package/build/components/dimensions-tool/scale-tool.cjs.map +2 -2
- package/build/components/global-styles/dimensions-panel.cjs +1 -1
- package/build/components/global-styles/dimensions-panel.cjs.map +2 -2
- package/build/components/global-styles/shadow-panel-components.cjs.map +2 -2
- package/build/components/grid/grid-item-resizer.cjs.map +1 -1
- package/build/components/grid/grid-visualizer.cjs.map +1 -1
- package/build/components/iframe/index.cjs +6 -3
- package/build/components/iframe/index.cjs.map +3 -3
- package/build/components/image-editor/use-transform-image.cjs.map +1 -1
- package/build/components/inserter/get-appender-label.cjs.map +1 -1
- package/build/components/inserter/media-tab/media-preview.cjs.map +2 -2
- package/build/components/inserter/search-items.cjs.map +1 -1
- package/build/components/inspector-controls/fill.cjs +1 -3
- package/build/components/inspector-controls/fill.cjs.map +2 -2
- package/build/components/inspector-controls-tabs/index.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/keyboard-shortcuts/index.cjs.map +1 -1
- package/build/components/line-height-control/index.cjs.map +1 -1
- package/build/components/link-control/index.cjs +1 -1
- package/build/components/link-control/index.cjs.map +1 -1
- package/build/components/link-control/normalize-url.cjs.map +1 -1
- package/build/components/list-view/block-select-button.cjs.map +2 -2
- package/build/components/list-view/utils.cjs.map +1 -1
- package/build/components/preset-input-control/custom-value-controls.cjs.map +2 -2
- package/build/components/provider/index.cjs.map +1 -1
- package/build/components/provider/use-block-sync.cjs.map +1 -1
- package/build/components/rich-text/event-listeners/before-input-rules.cjs +1 -1
- package/build/components/rich-text/event-listeners/before-input-rules.cjs.map +2 -2
- package/build/components/rich-text/event-listeners/paste-handler.cjs.map +1 -1
- package/build/components/rich-text/prevent-event-discovery.cjs +1 -1
- package/build/components/rich-text/prevent-event-discovery.cjs.map +1 -1
- package/build/components/writing-flow/use-tab-nav.cjs.map +1 -1
- package/build/hooks/anchor.cjs +1 -1
- package/build/hooks/anchor.cjs.map +1 -1
- package/build/hooks/background.cjs.map +1 -1
- package/build/hooks/block-fields/index.cjs +13 -2
- package/build/hooks/block-fields/index.cjs.map +2 -2
- package/build/hooks/dimensions.cjs +13 -2
- package/build/hooks/dimensions.cjs.map +2 -2
- package/build/hooks/layout-child.cjs +27 -2
- package/build/hooks/layout-child.cjs.map +2 -2
- package/build/hooks/list-view.cjs +10 -7
- package/build/hooks/list-view.cjs.map +2 -2
- package/build/hooks/spacing-visualizer.cjs.map +1 -1
- package/build/hooks/state-utils.cjs.map +1 -1
- package/build/hooks/style.cjs +42 -2
- package/build/hooks/style.cjs.map +2 -2
- package/build/private-apis.cjs +4 -0
- package/build/private-apis.cjs.map +2 -2
- package/build/store/actions.cjs.map +1 -1
- package/build/store/private-selectors.cjs +19 -2
- package/build/store/private-selectors.cjs.map +2 -2
- package/build/store/reducer.cjs.map +1 -1
- package/build/store/selectors.cjs.map +1 -1
- package/build/utils/dom.cjs.map +1 -1
- package/build/utils/selection.cjs +1 -1
- package/build-module/components/block-card/index.mjs +5 -6
- package/build-module/components/block-card/index.mjs.map +2 -2
- package/build-module/components/block-inspector/index.mjs +3 -5
- package/build-module/components/block-inspector/index.mjs.map +2 -2
- package/build-module/components/block-mover/mover-description.mjs +6 -6
- package/build-module/components/block-mover/mover-description.mjs.map +1 -1
- package/build-module/components/block-patterns-list/index.mjs.map +2 -2
- package/build-module/components/block-patterns-paging/index.mjs +4 -4
- package/build-module/components/block-patterns-paging/index.mjs.map +2 -2
- package/build-module/components/block-popover/use-popover-scroll.mjs.map +1 -1
- package/build-module/components/block-quick-navigation/index.mjs +8 -6
- package/build-module/components/block-quick-navigation/index.mjs.map +2 -2
- package/build-module/components/block-toolbar/edit-section-button.mjs.map +1 -1
- package/build-module/components/block-tools/use-block-toolbar-popover-props.mjs +10 -4
- package/build-module/components/block-tools/use-block-toolbar-popover-props.mjs.map +2 -2
- package/build-module/components/child-layout-control/index.mjs +51 -19
- package/build-module/components/child-layout-control/index.mjs.map +2 -2
- package/build-module/components/dimensions-tool/index.mjs +4 -5
- package/build-module/components/dimensions-tool/index.mjs.map +2 -2
- package/build-module/components/dimensions-tool/scale-tool.mjs +1 -1
- package/build-module/components/dimensions-tool/scale-tool.mjs.map +2 -2
- package/build-module/components/global-styles/dimensions-panel.mjs +1 -2
- package/build-module/components/global-styles/dimensions-panel.mjs.map +2 -2
- package/build-module/components/global-styles/shadow-panel-components.mjs.map +2 -2
- package/build-module/components/grid/grid-item-resizer.mjs.map +1 -1
- package/build-module/components/grid/grid-visualizer.mjs.map +1 -1
- package/build-module/components/iframe/index.mjs +6 -3
- package/build-module/components/iframe/index.mjs.map +2 -2
- package/build-module/components/image-editor/use-transform-image.mjs.map +1 -1
- package/build-module/components/inserter/get-appender-label.mjs.map +1 -1
- package/build-module/components/inserter/media-tab/media-preview.mjs.map +2 -2
- package/build-module/components/inserter/search-items.mjs.map +1 -1
- package/build-module/components/inspector-controls/fill.mjs +1 -3
- package/build-module/components/inspector-controls/fill.mjs.map +2 -2
- package/build-module/components/inspector-controls-tabs/index.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/keyboard-shortcuts/index.mjs.map +1 -1
- package/build-module/components/line-height-control/index.mjs.map +1 -1
- package/build-module/components/link-control/index.mjs +1 -1
- package/build-module/components/link-control/index.mjs.map +1 -1
- package/build-module/components/link-control/normalize-url.mjs.map +1 -1
- package/build-module/components/list-view/block-select-button.mjs.map +2 -2
- package/build-module/components/list-view/utils.mjs.map +1 -1
- package/build-module/components/preset-input-control/custom-value-controls.mjs.map +2 -2
- package/build-module/components/provider/index.mjs.map +1 -1
- package/build-module/components/provider/use-block-sync.mjs.map +1 -1
- package/build-module/components/rich-text/event-listeners/before-input-rules.mjs +1 -1
- package/build-module/components/rich-text/event-listeners/before-input-rules.mjs.map +2 -2
- package/build-module/components/rich-text/event-listeners/paste-handler.mjs.map +1 -1
- package/build-module/components/rich-text/prevent-event-discovery.mjs +1 -1
- package/build-module/components/rich-text/prevent-event-discovery.mjs.map +1 -1
- package/build-module/components/writing-flow/use-tab-nav.mjs.map +1 -1
- package/build-module/hooks/anchor.mjs +1 -1
- package/build-module/hooks/anchor.mjs.map +1 -1
- package/build-module/hooks/background.mjs.map +1 -1
- package/build-module/hooks/block-fields/index.mjs +13 -2
- package/build-module/hooks/block-fields/index.mjs.map +2 -2
- package/build-module/hooks/dimensions.mjs +12 -2
- package/build-module/hooks/dimensions.mjs.map +2 -2
- package/build-module/hooks/layout-child.mjs +27 -2
- package/build-module/hooks/layout-child.mjs.map +2 -2
- package/build-module/hooks/list-view.mjs +10 -7
- package/build-module/hooks/list-view.mjs.map +2 -2
- package/build-module/hooks/spacing-visualizer.mjs.map +1 -1
- package/build-module/hooks/state-utils.mjs.map +1 -1
- package/build-module/hooks/style.mjs +44 -3
- package/build-module/hooks/style.mjs.map +2 -2
- package/build-module/private-apis.mjs +8 -0
- package/build-module/private-apis.mjs.map +2 -2
- package/build-module/store/actions.mjs.map +1 -1
- package/build-module/store/private-selectors.mjs +18 -1
- package/build-module/store/private-selectors.mjs.map +2 -2
- package/build-module/store/reducer.mjs.map +1 -1
- package/build-module/store/selectors.mjs.map +1 -1
- package/build-module/utils/dom.mjs.map +1 -1
- package/build-module/utils/selection.mjs +1 -1
- package/package.json +45 -40
- package/src/components/block-card/index.js +7 -13
- package/src/components/block-inspector/index.js +2 -10
- package/src/components/block-patterns-list/index.js +0 -1
- package/src/components/block-quick-navigation/index.js +7 -7
- package/src/components/block-tools/use-block-toolbar-popover-props.js +10 -4
- package/src/components/child-layout-control/index.js +65 -20
- package/src/components/child-layout-control/test/index.js +64 -0
- package/src/components/dimensions-tool/index.js +4 -9
- package/src/components/dimensions-tool/scale-tool.js +1 -2
- package/src/components/dimensions-tool/test/index.js +89 -11
- package/src/components/global-styles/dimensions-panel.js +1 -2
- package/src/components/global-styles/shadow-panel-components.js +0 -1
- package/src/components/iframe/index.js +8 -3
- package/src/components/inserter/media-tab/media-preview.js +0 -1
- package/src/components/inspector-controls/fill.js +6 -8
- package/src/components/inspector-controls-tabs/index.js +0 -1
- package/src/components/inspector-controls-tabs/styles-tab.js +5 -1
- package/src/components/list-view/block-select-button.js +0 -1
- package/src/components/preset-input-control/custom-value-controls.js +0 -1
- package/src/hooks/block-fields/index.js +27 -2
- package/src/hooks/dimensions.js +14 -3
- package/src/hooks/layout-child.js +41 -2
- package/src/hooks/list-view.js +10 -11
- package/src/hooks/style.js +80 -2
- package/src/hooks/test/dimensions.js +71 -0
- package/src/hooks/test/layout-child.js +165 -0
- package/src/hooks/test/style.js +126 -4
- package/src/private-apis.js +8 -0
- package/src/store/private-selectors.js +47 -0
- package/src/store/test/private-selectors.js +138 -0
|
@@ -16,6 +16,17 @@ import { useState } from '@wordpress/element';
|
|
|
16
16
|
import DimensionsTool from '../';
|
|
17
17
|
|
|
18
18
|
const EMPTY_OBJECT = {};
|
|
19
|
+
const ASPECT_RATIO_OPTIONS = [
|
|
20
|
+
{ label: 'Original', value: 'auto' },
|
|
21
|
+
{ label: '16/9', value: '16/9' },
|
|
22
|
+
{ label: '4/3', value: '4/3' },
|
|
23
|
+
{
|
|
24
|
+
label: 'Custom',
|
|
25
|
+
value: 'custom',
|
|
26
|
+
disabled: true,
|
|
27
|
+
hidden: true,
|
|
28
|
+
},
|
|
29
|
+
];
|
|
19
30
|
|
|
20
31
|
function Example( { initialValue, onChange, ...props } ) {
|
|
21
32
|
const [ value, setValue ] = useState( initialValue );
|
|
@@ -33,16 +44,27 @@ function Example( { initialValue, onChange, ...props } ) {
|
|
|
33
44
|
} }
|
|
34
45
|
defaultScale="cover"
|
|
35
46
|
defaultAspectRatio="auto"
|
|
36
|
-
aspectRatioOptions={
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
aspectRatioOptions={ ASPECT_RATIO_OPTIONS }
|
|
48
|
+
value={ value }
|
|
49
|
+
{ ...props }
|
|
50
|
+
/>
|
|
51
|
+
</ToolsPanel>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function ControlledExample( { value, onChange, ...props } ) {
|
|
56
|
+
return (
|
|
57
|
+
<ToolsPanel
|
|
58
|
+
label="Dimensions"
|
|
59
|
+
panelId="panel-id"
|
|
60
|
+
resetAll={ () => onChange( EMPTY_OBJECT ) }
|
|
61
|
+
>
|
|
62
|
+
<DimensionsTool
|
|
63
|
+
panelId="panel-id"
|
|
64
|
+
onChange={ onChange }
|
|
65
|
+
defaultScale="cover"
|
|
66
|
+
defaultAspectRatio="auto"
|
|
67
|
+
aspectRatioOptions={ ASPECT_RATIO_OPTIONS }
|
|
46
68
|
value={ value }
|
|
47
69
|
{ ...props }
|
|
48
70
|
/>
|
|
@@ -60,6 +82,39 @@ function Example( { initialValue, onChange, ...props } ) {
|
|
|
60
82
|
// properties are treated differently from missing properties.
|
|
61
83
|
|
|
62
84
|
describe( 'DimensionsTool', () => {
|
|
85
|
+
describe( 'controlled values', () => {
|
|
86
|
+
it( 'updates the aspect ratio control when the value prop changes', () => {
|
|
87
|
+
const onChange = jest.fn();
|
|
88
|
+
const { rerender } = render(
|
|
89
|
+
<ControlledExample
|
|
90
|
+
value={ { aspectRatio: '16/9' } }
|
|
91
|
+
onChange={ onChange }
|
|
92
|
+
/>
|
|
93
|
+
);
|
|
94
|
+
const aspectRatioSelect = screen.getByRole( 'combobox', {
|
|
95
|
+
name: 'Aspect ratio',
|
|
96
|
+
} );
|
|
97
|
+
|
|
98
|
+
expect( aspectRatioSelect ).toHaveValue( '16/9' );
|
|
99
|
+
|
|
100
|
+
rerender(
|
|
101
|
+
<ControlledExample
|
|
102
|
+
value={ { aspectRatio: '4/3' } }
|
|
103
|
+
onChange={ onChange }
|
|
104
|
+
/>
|
|
105
|
+
);
|
|
106
|
+
expect( aspectRatioSelect ).toHaveValue( '4/3' );
|
|
107
|
+
|
|
108
|
+
rerender(
|
|
109
|
+
<ControlledExample
|
|
110
|
+
value={ EMPTY_OBJECT }
|
|
111
|
+
onChange={ onChange }
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
expect( aspectRatioSelect ).toHaveValue( 'auto' );
|
|
115
|
+
} );
|
|
116
|
+
} );
|
|
117
|
+
|
|
63
118
|
describe( 'updating aspectRatio', () => {
|
|
64
119
|
it( 'when starting with empty initial state, setting aspectRatio also sets scale (0000) -> (1100)', async () => {
|
|
65
120
|
const user = userEvent.setup();
|
|
@@ -323,7 +378,30 @@ describe( 'DimensionsTool', () => {
|
|
|
323
378
|
} );
|
|
324
379
|
|
|
325
380
|
describe( 'updating scale', () => {
|
|
326
|
-
|
|
381
|
+
it( 'when default scale is cover, setting scale to fill preserves the fill value', async () => {
|
|
382
|
+
const user = userEvent.setup();
|
|
383
|
+
const onChange = jest.fn();
|
|
384
|
+
|
|
385
|
+
const initialValue = {
|
|
386
|
+
aspectRatio: '16/9',
|
|
387
|
+
scale: 'cover',
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
render(
|
|
391
|
+
<Example initialValue={ initialValue } onChange={ onChange } />
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
const scaleFillRadio = screen.getByRole( 'radio', {
|
|
395
|
+
name: 'Fill',
|
|
396
|
+
} );
|
|
397
|
+
|
|
398
|
+
await user.click( scaleFillRadio );
|
|
399
|
+
expect( scaleFillRadio ).toBeChecked();
|
|
400
|
+
|
|
401
|
+
expect( onChange.mock.calls ).toStrictEqual( [
|
|
402
|
+
[ { aspectRatio: '16/9', scale: 'fill' } ],
|
|
403
|
+
] );
|
|
404
|
+
} );
|
|
327
405
|
} );
|
|
328
406
|
|
|
329
407
|
describe( 'updating dimensions', () => {
|
|
@@ -32,7 +32,6 @@ import { setImmutably } from '../../utils/object';
|
|
|
32
32
|
import {
|
|
33
33
|
DEFAULT_BLOCK_STYLE_STATE,
|
|
34
34
|
hasPseudoBlockStyleState,
|
|
35
|
-
isDefaultBlockStyleState,
|
|
36
35
|
hasViewportBlockStyleState,
|
|
37
36
|
} from '../../hooks/block-style-state';
|
|
38
37
|
|
|
@@ -95,7 +94,7 @@ function hasWidth( settings ) {
|
|
|
95
94
|
|
|
96
95
|
function hasAspectRatio( settings, styleState = DEFAULT_BLOCK_STYLE_STATE ) {
|
|
97
96
|
return (
|
|
98
|
-
|
|
97
|
+
! hasPseudoBlockStyleState( styleState ) &&
|
|
99
98
|
settings?.dimensions?.aspectRatio
|
|
100
99
|
);
|
|
101
100
|
}
|
|
@@ -20,7 +20,6 @@ import { shadow as shadowIcon, Icon, check, reset } from '@wordpress/icons';
|
|
|
20
20
|
*/
|
|
21
21
|
import clsx from 'clsx';
|
|
22
22
|
|
|
23
|
-
// eslint-disable-next-line @wordpress/use-recommended-components -- `Tooltip` is not yet on the recommended `@wordpress/ui` allow-list; landing as a migration step ahead of the wider rollout.
|
|
24
23
|
import { Tooltip } from '@wordpress/ui';
|
|
25
24
|
|
|
26
25
|
/**
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import clsx from 'clsx';
|
|
5
|
+
import { version as reactVersion } from 'react';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* WordPress dependencies
|
|
@@ -102,6 +103,12 @@ function getIframeSrc( resolvedAssets ) {
|
|
|
102
103
|
return src;
|
|
103
104
|
}
|
|
104
105
|
|
|
106
|
+
let body = '';
|
|
107
|
+
if ( reactVersion.split( '.' )[ 0 ] === '18' ) {
|
|
108
|
+
body =
|
|
109
|
+
'<body><script>document.currentScript.parentElement.remove()</script></body>';
|
|
110
|
+
}
|
|
111
|
+
|
|
105
112
|
// Correct doctype is required to enable rendering in standards mode.
|
|
106
113
|
// Also preload the styles to avoid a flash of unstyled content.
|
|
107
114
|
const html = `<!doctype html>
|
|
@@ -125,9 +132,7 @@ function getIframeSrc( resolvedAssets ) {
|
|
|
125
132
|
${ resolvedAssets.styles ?? '' }
|
|
126
133
|
${ resolvedAssets.scripts ?? '' }
|
|
127
134
|
</head>
|
|
128
|
-
|
|
129
|
-
<script>document.currentScript.parentElement.remove()</script>
|
|
130
|
-
</body>
|
|
135
|
+
${ body }
|
|
131
136
|
</html>`;
|
|
132
137
|
|
|
133
138
|
src = URL.createObjectURL( new Blob( [ html ], { type: 'text/html' } ) );
|
|
@@ -27,7 +27,6 @@ import { store as noticesStore } from '@wordpress/notices';
|
|
|
27
27
|
import { isBlobURL } from '@wordpress/blob';
|
|
28
28
|
import { getFilename } from '@wordpress/url';
|
|
29
29
|
|
|
30
|
-
// eslint-disable-next-line @wordpress/use-recommended-components -- `Tooltip` is not yet on the recommended `@wordpress/ui` allow-list; landing as a migration step ahead of the wider rollout.
|
|
31
30
|
import { Tooltip } from '@wordpress/ui';
|
|
32
31
|
|
|
33
32
|
/**
|
|
@@ -26,7 +26,6 @@ import {
|
|
|
26
26
|
import { ListViewContentFill } from './list-view-content-popover';
|
|
27
27
|
|
|
28
28
|
const PATTERN_EDITING_GROUPS = [ 'content', 'list' ];
|
|
29
|
-
const TEMPLATE_PART_GROUPS = [ 'default', 'settings', 'advanced' ];
|
|
30
29
|
|
|
31
30
|
export default function InspectorControlsFill( {
|
|
32
31
|
children,
|
|
@@ -56,17 +55,16 @@ export default function InspectorControlsFill( {
|
|
|
56
55
|
|
|
57
56
|
// During pattern editing:
|
|
58
57
|
// - All blocks can show pattern editing groups (content, list).
|
|
59
|
-
// - Template parts can show
|
|
58
|
+
// - Template parts can show any inspector group.
|
|
60
59
|
// - Other blocks cannot show a settings tab.
|
|
61
60
|
if ( context[ mayDisplayPatternEditingControlsKey ] ) {
|
|
62
|
-
// Template parts
|
|
63
|
-
//
|
|
61
|
+
// Template parts have also historically supported
|
|
62
|
+
// any block inspector groups for extenders. The settings
|
|
63
|
+
// tab is also used by core for the 'Design' panel. Specifically
|
|
64
|
+
// for that block the restrictions on allowed groups are lessened.
|
|
64
65
|
const isTemplatePart = context.name === 'core/template-part';
|
|
65
|
-
const isTemplatePartGroup = TEMPLATE_PART_GROUPS.includes( group );
|
|
66
66
|
const isPatternEditingGroup = PATTERN_EDITING_GROUPS.includes( group );
|
|
67
|
-
|
|
68
|
-
const canShowGroup =
|
|
69
|
-
( isTemplatePart && isTemplatePartGroup ) || isPatternEditingGroup;
|
|
67
|
+
const canShowGroup = isTemplatePart || isPatternEditingGroup;
|
|
70
68
|
|
|
71
69
|
if ( ! canShowGroup ) {
|
|
72
70
|
return null;
|
|
@@ -9,7 +9,6 @@ import { useEffect, useState, useRef } from '@wordpress/element';
|
|
|
9
9
|
import { store as preferencesStore } from '@wordpress/preferences';
|
|
10
10
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
11
11
|
|
|
12
|
-
// eslint-disable-next-line @wordpress/use-recommended-components -- `Tooltip` is not yet on the recommended `@wordpress/ui` allow-list; landing as a migration step ahead of the wider rollout.
|
|
13
12
|
import { Tooltip } from '@wordpress/ui';
|
|
14
13
|
|
|
15
14
|
/**
|
|
@@ -79,7 +79,11 @@ const StylesTab = ( {
|
|
|
79
79
|
contentClientIds={ contentClientIds }
|
|
80
80
|
/>
|
|
81
81
|
) }
|
|
82
|
-
{
|
|
82
|
+
{
|
|
83
|
+
// Extenders have in the past always been allowed to add controls to group
|
|
84
|
+
// the restrictions are lessened for that block.
|
|
85
|
+
}
|
|
86
|
+
{ ( ! isSectionBlock || blockName === 'core/template-part' ) && (
|
|
83
87
|
<>
|
|
84
88
|
<InspectorControls.Slot
|
|
85
89
|
group="color"
|
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
import { SPACE, ENTER } from '@wordpress/keycodes';
|
|
23
23
|
import { useSelect } from '@wordpress/data';
|
|
24
24
|
|
|
25
|
-
// eslint-disable-next-line @wordpress/use-recommended-components -- `Tooltip` is not yet on the recommended `@wordpress/ui` allow-list; landing as a migration step ahead of the wider rollout.
|
|
26
25
|
import { Tooltip } from '@wordpress/ui';
|
|
27
26
|
|
|
28
27
|
/**
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
__experimentalUnitControl as UnitControl,
|
|
7
7
|
} from '@wordpress/components';
|
|
8
8
|
|
|
9
|
-
// eslint-disable-next-line @wordpress/use-recommended-components -- `Tooltip` is not yet on the recommended `@wordpress/ui` allow-list; landing as a migration step ahead of the wider rollout.
|
|
10
9
|
import { Tooltip } from '@wordpress/ui';
|
|
11
10
|
|
|
12
11
|
/**
|
|
@@ -14,6 +14,7 @@ import { useContext, useState, useMemo } from '@wordpress/element';
|
|
|
14
14
|
import { __ } from '@wordpress/i18n';
|
|
15
15
|
import { store as blockEditorStore } from '../../store';
|
|
16
16
|
import { unlock } from '../../lock-unlock';
|
|
17
|
+
import { replacePatternOverridesDefaultBinding } from '../../utils/block-bindings';
|
|
17
18
|
import BlockContext from '../../components/block-context';
|
|
18
19
|
import BlockIcon from '../../components/block-icon';
|
|
19
20
|
import useBlockDisplayTitle from '../../components/block-title/use-block-display-title';
|
|
@@ -80,15 +81,39 @@ function BlockFields( {
|
|
|
80
81
|
return _attributes;
|
|
81
82
|
}
|
|
82
83
|
|
|
84
|
+
/*
|
|
85
|
+
* The pattern overrides `__default` binding is a placeholder, not
|
|
86
|
+
* a real attribute: expand it to the block's bindable attributes
|
|
87
|
+
* before resolving values, as other bindings consumers do.
|
|
88
|
+
*/
|
|
89
|
+
const { __experimentalBlockBindingsSupportedAttributes } =
|
|
90
|
+
select( blockEditorStore ).getSettings();
|
|
91
|
+
const bindableAttributes =
|
|
92
|
+
__experimentalBlockBindingsSupportedAttributes?.[
|
|
93
|
+
blockType?.name
|
|
94
|
+
];
|
|
95
|
+
const bindings = bindableAttributes
|
|
96
|
+
? replacePatternOverridesDefaultBinding(
|
|
97
|
+
_attributes.metadata.bindings,
|
|
98
|
+
bindableAttributes
|
|
99
|
+
)
|
|
100
|
+
: _attributes.metadata.bindings;
|
|
101
|
+
|
|
83
102
|
const { getBlockBindingsSource } = unlock( select( blocksStore ) );
|
|
84
|
-
return Object.entries(
|
|
103
|
+
return Object.entries( bindings ).reduce(
|
|
85
104
|
( acc, [ attribute, binding ] ) => {
|
|
105
|
+
// Skip a `__default` binding that could not be expanded:
|
|
106
|
+
// it is not a real block attribute.
|
|
107
|
+
if ( attribute === '__default' ) {
|
|
108
|
+
return acc;
|
|
109
|
+
}
|
|
86
110
|
const source = getBlockBindingsSource( binding.source );
|
|
87
111
|
if ( ! source ) {
|
|
88
112
|
return acc;
|
|
89
113
|
}
|
|
90
114
|
const values = source.getValues( {
|
|
91
115
|
select,
|
|
116
|
+
clientId,
|
|
92
117
|
context: blockContext,
|
|
93
118
|
bindings: { [ attribute ]: binding },
|
|
94
119
|
} );
|
|
@@ -97,7 +122,7 @@ function BlockFields( {
|
|
|
97
122
|
_attributes
|
|
98
123
|
);
|
|
99
124
|
},
|
|
100
|
-
[ blockContext, clientId ]
|
|
125
|
+
[ blockContext, clientId, blockType?.name ]
|
|
101
126
|
);
|
|
102
127
|
const { selectBlock, toggleBlockHighlight } =
|
|
103
128
|
useDispatch( blockEditorStore );
|
package/src/hooks/dimensions.js
CHANGED
|
@@ -190,6 +190,14 @@ export function hasDimensionsSupport( blockName, feature = 'any' ) {
|
|
|
190
190
|
return !! support?.[ feature ];
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
+
export function isExplicitAspectRatio( aspectRatio ) {
|
|
194
|
+
if ( ! aspectRatio ) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return `${ aspectRatio }`.trim().toLowerCase() !== 'auto';
|
|
199
|
+
}
|
|
200
|
+
|
|
193
201
|
export default {
|
|
194
202
|
useBlockProps,
|
|
195
203
|
attributeKeys: [ 'height', 'minHeight', 'width', 'style' ],
|
|
@@ -206,8 +214,11 @@ function useBlockProps( { name, height, minHeight, style } ) {
|
|
|
206
214
|
return {};
|
|
207
215
|
}
|
|
208
216
|
|
|
217
|
+
const hasExplicitAspectRatio = isExplicitAspectRatio(
|
|
218
|
+
style?.dimensions?.aspectRatio
|
|
219
|
+
);
|
|
209
220
|
const className = clsx( {
|
|
210
|
-
'has-aspect-ratio':
|
|
221
|
+
'has-aspect-ratio': hasExplicitAspectRatio,
|
|
211
222
|
} );
|
|
212
223
|
|
|
213
224
|
// Allow dimensions-based inline style overrides to override any global styles rules that
|
|
@@ -215,12 +226,12 @@ function useBlockProps( { name, height, minHeight, style } ) {
|
|
|
215
226
|
const inlineStyleOverrides = {};
|
|
216
227
|
|
|
217
228
|
// Apply rules to unset incompatible styles.
|
|
218
|
-
// Note that
|
|
229
|
+
// Note that an explicit `aspectRatio` will win out if both an aspect ratio and height-related properties are set.
|
|
219
230
|
// This is because the aspect ratio is a newer block support, so (in theory) any aspect ratio
|
|
220
231
|
// that is set should be intentional and should override any existing height properties. The Cover block
|
|
221
232
|
// and dimensions controls have logic that will manually clear the aspect ratio if height properties
|
|
222
233
|
// are set.
|
|
223
|
-
if (
|
|
234
|
+
if ( hasExplicitAspectRatio ) {
|
|
224
235
|
// To ensure the aspect ratio does not get overridden by `minHeight` or `height` unset any existing rule.
|
|
225
236
|
inlineStyleOverrides.minHeight = 'unset';
|
|
226
237
|
inlineStyleOverrides.height = 'unset';
|
|
@@ -28,6 +28,24 @@ const RESPONSIVE_BREAKPOINTS = {
|
|
|
28
28
|
tablet: '@media (480px < width <= 782px)',
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
+
// These are the serialized `selfStretch` values. `max` used to be called
|
|
32
|
+
// "Fixed" in the UI, but was renamed and replaced by `fixedNoShrink`.
|
|
33
|
+
const FLEX_CHILD_LAYOUT_VALUES = {
|
|
34
|
+
fit: 'fit',
|
|
35
|
+
grow: 'fill',
|
|
36
|
+
max: 'fixed',
|
|
37
|
+
fixed: 'fixedNoShrink',
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const FLEX_SIZE_VALUES = [
|
|
41
|
+
FLEX_CHILD_LAYOUT_VALUES.max,
|
|
42
|
+
FLEX_CHILD_LAYOUT_VALUES.fixed,
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
function isFlexSizeValue( value ) {
|
|
46
|
+
return FLEX_SIZE_VALUES.includes( value );
|
|
47
|
+
}
|
|
48
|
+
|
|
31
49
|
function serializeRule( { selector, declarations } ) {
|
|
32
50
|
return `${ selector } {
|
|
33
51
|
${ Object.entries( declarations )
|
|
@@ -60,6 +78,7 @@ export function getChildLayoutStyleRules( {
|
|
|
60
78
|
columnSpan,
|
|
61
79
|
rowSpan,
|
|
62
80
|
} = effectiveLayout;
|
|
81
|
+
const baseSelfStretch = layout.selfStretch;
|
|
63
82
|
const { columnCount, minimumColumnWidth } = parentLayout;
|
|
64
83
|
const rules = [];
|
|
65
84
|
|
|
@@ -69,10 +88,30 @@ export function getChildLayoutStyleRules( {
|
|
|
69
88
|
hasViewportOverride( 'selfStretch' ) ||
|
|
70
89
|
hasViewportOverride( 'flexSize' )
|
|
71
90
|
) {
|
|
72
|
-
if (
|
|
91
|
+
if (
|
|
92
|
+
hasViewportOverrides &&
|
|
93
|
+
( selfStretch === FLEX_CHILD_LAYOUT_VALUES.fit ||
|
|
94
|
+
selfStretch === FLEX_CHILD_LAYOUT_VALUES.grow ) &&
|
|
95
|
+
isFlexSizeValue( baseSelfStretch ) &&
|
|
96
|
+
layout.flexSize
|
|
97
|
+
) {
|
|
98
|
+
declarations[ 'flex-basis' ] = 'unset';
|
|
99
|
+
if ( baseSelfStretch === FLEX_CHILD_LAYOUT_VALUES.fixed ) {
|
|
100
|
+
declarations[ 'flex-shrink' ] = 'unset';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if ( isFlexSizeValue( selfStretch ) && flexSize ) {
|
|
73
104
|
declarations[ 'flex-basis' ] = flexSize;
|
|
105
|
+
if ( selfStretch === FLEX_CHILD_LAYOUT_VALUES.fixed ) {
|
|
106
|
+
declarations[ 'flex-shrink' ] = '0';
|
|
107
|
+
} else if (
|
|
108
|
+
hasViewportOverrides &&
|
|
109
|
+
baseSelfStretch === FLEX_CHILD_LAYOUT_VALUES.fixed
|
|
110
|
+
) {
|
|
111
|
+
declarations[ 'flex-shrink' ] = 'unset';
|
|
112
|
+
}
|
|
74
113
|
declarations[ 'box-sizing' ] = 'border-box';
|
|
75
|
-
} else if ( selfStretch ===
|
|
114
|
+
} else if ( selfStretch === FLEX_CHILD_LAYOUT_VALUES.grow ) {
|
|
76
115
|
declarations[ 'flex-grow' ] = '1';
|
|
77
116
|
}
|
|
78
117
|
}
|
package/src/hooks/list-view.js
CHANGED
|
@@ -50,26 +50,25 @@ export function ListViewPanel( { clientId, name } ) {
|
|
|
50
50
|
useDispatch( blockEditorStore )
|
|
51
51
|
);
|
|
52
52
|
|
|
53
|
-
const isEnabled =
|
|
54
|
-
const { hasChildren, isNestedListView } = useSelect(
|
|
53
|
+
const { isEnabled, hasChildren, isNestedListView } = useSelect(
|
|
55
54
|
( select ) => {
|
|
56
|
-
const {
|
|
57
|
-
|
|
55
|
+
const {
|
|
56
|
+
getBlockCount,
|
|
57
|
+
getBlockParents,
|
|
58
|
+
shouldRenderBlockListView,
|
|
59
|
+
} = unlock( select( blockEditorStore ) );
|
|
58
60
|
|
|
59
61
|
// Avoid showing List Views for both parent and child blocks that have support.
|
|
60
62
|
// In this situation the parent will show the child in its list already.
|
|
61
63
|
// Search parents to see if there's one that also has support, and if so skip rendering.
|
|
62
64
|
// This matches closely the logic in the `BlockCard` component.
|
|
63
65
|
const parents = getBlockParents( clientId, false );
|
|
64
|
-
const _isNestedListView = parents.find( ( parentId ) =>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
parentName === 'core/navigation' ||
|
|
68
|
-
hasBlockSupport( parentName, 'listView' )
|
|
69
|
-
);
|
|
70
|
-
} );
|
|
66
|
+
const _isNestedListView = parents.find( ( parentId ) =>
|
|
67
|
+
shouldRenderBlockListView( parentId )
|
|
68
|
+
);
|
|
71
69
|
|
|
72
70
|
return {
|
|
71
|
+
isEnabled: shouldRenderBlockListView( clientId ),
|
|
73
72
|
hasChildren: !! getBlockCount( clientId ),
|
|
74
73
|
isNestedListView: _isNestedListView,
|
|
75
74
|
};
|
package/src/hooks/style.js
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
DIMENSIONS_SUPPORT_KEY,
|
|
30
30
|
SPACING_SUPPORT_KEY,
|
|
31
31
|
DimensionsPanel,
|
|
32
|
+
isExplicitAspectRatio,
|
|
32
33
|
} from './dimensions';
|
|
33
34
|
import {
|
|
34
35
|
cleanEmptyObject,
|
|
@@ -134,6 +135,72 @@ function getStateFallbackBorderStyles( stateStyles ) {
|
|
|
134
135
|
return cleanEmptyObject( { border: cleanEmptyObject( fallbackBorder ) } );
|
|
135
136
|
}
|
|
136
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Returns background reset CSS for a state that sets a solid background color.
|
|
140
|
+
*
|
|
141
|
+
* When a state sets `color.background` (a solid color) without also setting a
|
|
142
|
+
* gradient (`color.gradient` or `background.gradient`), any gradient applied to
|
|
143
|
+
* the default state via an inline `background` shorthand or `background-image`
|
|
144
|
+
* declaration must be explicitly cleared. Without this, the gradient image layer
|
|
145
|
+
* remains visible even though the solid hover color wins `background-color`.
|
|
146
|
+
*
|
|
147
|
+
* @param {Object} stateStyles State style object.
|
|
148
|
+
* @param {string} selector CSS selector for the generated style.
|
|
149
|
+
* @return {string|undefined} CSS string with background-image reset, or undefined.
|
|
150
|
+
*/
|
|
151
|
+
function getStateBackgroundResetCSS( stateStyles, selector ) {
|
|
152
|
+
const hasSolidBackground = !! stateStyles?.color?.background;
|
|
153
|
+
|
|
154
|
+
if ( ! hasSolidBackground ) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const hasColorGradient = !! stateStyles?.color?.gradient;
|
|
159
|
+
const hasBackgroundGradient =
|
|
160
|
+
!! stateStyles?.background?.gradient ||
|
|
161
|
+
!! stateStyles?.background?.backgroundImage;
|
|
162
|
+
|
|
163
|
+
if ( hasColorGradient || hasBackgroundGradient ) {
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const declaration = 'background-image: unset !important';
|
|
168
|
+
return selector
|
|
169
|
+
? `${ selector } { ${ declaration }; }`
|
|
170
|
+
: `${ declaration };`;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Returns fallback dimension styles that keep state styles aligned with the
|
|
175
|
+
* default dimensions block-support output.
|
|
176
|
+
*
|
|
177
|
+
* @param {Object} stateStyles State style object.
|
|
178
|
+
* @return {Object|undefined} Style object containing fallback dimension styles.
|
|
179
|
+
*/
|
|
180
|
+
function getStateFallbackDimensionStyles( stateStyles ) {
|
|
181
|
+
const dimensions = stateStyles?.dimensions;
|
|
182
|
+
if ( ! dimensions ) {
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if ( isExplicitAspectRatio( dimensions.aspectRatio ) ) {
|
|
187
|
+
return {
|
|
188
|
+
dimensions: {
|
|
189
|
+
minHeight: 'unset',
|
|
190
|
+
height: 'unset',
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if ( dimensions.minHeight || dimensions.height ) {
|
|
196
|
+
return {
|
|
197
|
+
dimensions: {
|
|
198
|
+
aspectRatio: 'unset',
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
137
204
|
/**
|
|
138
205
|
* Generates CSS for a block instance state style object.
|
|
139
206
|
*
|
|
@@ -146,14 +213,25 @@ function getStateFallbackBorderStyles( stateStyles ) {
|
|
|
146
213
|
* @return {string} Generated stylesheet.
|
|
147
214
|
*/
|
|
148
215
|
export function getStateStylesCSS( stateStyles, selector ) {
|
|
149
|
-
const
|
|
216
|
+
const fallbackDimensionStyles =
|
|
217
|
+
getStateFallbackDimensionStyles( stateStyles );
|
|
218
|
+
const stylesWithDimensionFallbacks = fallbackDimensionStyles
|
|
219
|
+
? mergeStyleObjects( stateStyles, fallbackDimensionStyles )
|
|
220
|
+
: stateStyles;
|
|
221
|
+
const css = compileCSS( stylesWithDimensionFallbacks, { selector } );
|
|
150
222
|
const importantCSS = css ? css.replace( /;/g, ' !important;' ) : undefined;
|
|
151
223
|
const fallbackBorderStyles = getStateFallbackBorderStyles( stateStyles );
|
|
152
224
|
const fallbackCSS = fallbackBorderStyles
|
|
153
225
|
? compileCSS( fallbackBorderStyles, { selector } )
|
|
154
226
|
: undefined;
|
|
227
|
+
const backgroundResetCSS = getStateBackgroundResetCSS(
|
|
228
|
+
stateStyles,
|
|
229
|
+
selector
|
|
230
|
+
);
|
|
155
231
|
|
|
156
|
-
return [ importantCSS, fallbackCSS ]
|
|
232
|
+
return [ importantCSS, fallbackCSS, backgroundResetCSS ]
|
|
233
|
+
.filter( Boolean )
|
|
234
|
+
.join( '\n' );
|
|
157
235
|
}
|
|
158
236
|
|
|
159
237
|
function isPlainObject( value ) {
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
getBlockType,
|
|
6
|
+
registerBlockType,
|
|
7
|
+
unregisterBlockType,
|
|
8
|
+
} from '@wordpress/blocks';
|
|
9
|
+
|
|
1
10
|
/**
|
|
2
11
|
* Internal dependencies
|
|
3
12
|
*/
|
|
13
|
+
import dimensions from '../dimensions';
|
|
4
14
|
import { getDimensionsClassesAndStyles } from '../use-dimensions-props';
|
|
5
15
|
|
|
6
16
|
describe( 'getDimensionsClassesAndStyles', () => {
|
|
@@ -126,3 +136,64 @@ describe( 'getDimensionsClassesAndStyles', () => {
|
|
|
126
136
|
} );
|
|
127
137
|
} );
|
|
128
138
|
} );
|
|
139
|
+
|
|
140
|
+
describe( 'useBlockProps', () => {
|
|
141
|
+
const blockName = 'test/dimensions-with-aspect-ratio';
|
|
142
|
+
|
|
143
|
+
afterEach( () => {
|
|
144
|
+
if ( getBlockType( blockName ) ) {
|
|
145
|
+
unregisterBlockType( blockName );
|
|
146
|
+
}
|
|
147
|
+
} );
|
|
148
|
+
|
|
149
|
+
const registerDimensionsBlock = () =>
|
|
150
|
+
registerBlockType( blockName, {
|
|
151
|
+
apiVersion: 3,
|
|
152
|
+
title: 'Dimensions with aspect ratio',
|
|
153
|
+
category: 'text',
|
|
154
|
+
supports: {
|
|
155
|
+
dimensions: {
|
|
156
|
+
aspectRatio: true,
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
} );
|
|
160
|
+
|
|
161
|
+
it( 'unsets height styles when aspect ratio is explicit', () => {
|
|
162
|
+
registerDimensionsBlock();
|
|
163
|
+
|
|
164
|
+
expect(
|
|
165
|
+
dimensions.useBlockProps( {
|
|
166
|
+
name: blockName,
|
|
167
|
+
style: {
|
|
168
|
+
dimensions: {
|
|
169
|
+
aspectRatio: '16/9',
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
} )
|
|
173
|
+
).toEqual( {
|
|
174
|
+
className: 'has-aspect-ratio',
|
|
175
|
+
style: {
|
|
176
|
+
minHeight: 'unset',
|
|
177
|
+
height: 'unset',
|
|
178
|
+
},
|
|
179
|
+
} );
|
|
180
|
+
} );
|
|
181
|
+
|
|
182
|
+
it( 'does not unset height styles when aspect ratio is the default', () => {
|
|
183
|
+
registerDimensionsBlock();
|
|
184
|
+
|
|
185
|
+
expect(
|
|
186
|
+
dimensions.useBlockProps( {
|
|
187
|
+
name: blockName,
|
|
188
|
+
style: {
|
|
189
|
+
dimensions: {
|
|
190
|
+
aspectRatio: 'auto',
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
} )
|
|
194
|
+
).toEqual( {
|
|
195
|
+
className: '',
|
|
196
|
+
style: {},
|
|
197
|
+
} );
|
|
198
|
+
} );
|
|
199
|
+
} );
|