@wordpress/block-editor 14.11.0 → 14.12.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 +2 -0
- package/build/components/grid/grid-visualizer.js +11 -19
- package/build/components/grid/grid-visualizer.js.map +1 -1
- package/build/components/grid/utils.js +6 -4
- package/build/components/grid/utils.js.map +1 -1
- package/build/components/inserter/menu.js +13 -2
- package/build/components/inserter/menu.js.map +1 -1
- package/build/components/inspector-controls-tabs/position-controls-panel.js +49 -21
- package/build/components/inspector-controls-tabs/position-controls-panel.js.map +1 -1
- package/build/components/spacing-sizes-control/index.js +44 -2
- package/build/components/spacing-sizes-control/index.js.map +1 -1
- package/build/components/spacing-sizes-control/linked-button.js +6 -9
- package/build/components/spacing-sizes-control/linked-button.js.map +1 -1
- package/build/components/spacing-sizes-control/utils.js +0 -108
- package/build/components/spacing-sizes-control/utils.js.map +1 -1
- package/build/hooks/contrast-checker.js +41 -22
- package/build/hooks/contrast-checker.js.map +1 -1
- package/build/hooks/custom-class-name.js +2 -1
- package/build/hooks/custom-class-name.js.map +1 -1
- package/build/store/selectors.js +13 -2
- package/build/store/selectors.js.map +1 -1
- package/build-module/components/grid/grid-visualizer.js +11 -19
- package/build-module/components/grid/grid-visualizer.js.map +1 -1
- package/build-module/components/grid/utils.js +6 -4
- package/build-module/components/grid/utils.js.map +1 -1
- package/build-module/components/inserter/menu.js +13 -2
- package/build-module/components/inserter/menu.js.map +1 -1
- package/build-module/components/inspector-controls-tabs/position-controls-panel.js +51 -23
- package/build-module/components/inspector-controls-tabs/position-controls-panel.js.map +1 -1
- package/build-module/components/spacing-sizes-control/index.js +45 -1
- package/build-module/components/spacing-sizes-control/index.js.map +1 -1
- package/build-module/components/spacing-sizes-control/linked-button.js +7 -10
- package/build-module/components/spacing-sizes-control/linked-button.js.map +1 -1
- package/build-module/components/spacing-sizes-control/utils.js +0 -104
- package/build-module/components/spacing-sizes-control/utils.js.map +1 -1
- package/build-module/hooks/contrast-checker.js +42 -23
- package/build-module/hooks/contrast-checker.js.map +1 -1
- package/build-module/hooks/custom-class-name.js +2 -1
- package/build-module/hooks/custom-class-name.js.map +1 -1
- package/build-module/store/selectors.js +13 -2
- package/build-module/store/selectors.js.map +1 -1
- package/build-style/style-rtl.css +1 -0
- package/build-style/style.css +1 -0
- package/package.json +34 -34
- package/src/components/grid/grid-visualizer.js +10 -21
- package/src/components/grid/style.scss +1 -0
- package/src/components/grid/utils.js +6 -4
- package/src/components/inserter/menu.js +11 -9
- package/src/components/inspector-controls-tabs/position-controls-panel.js +62 -27
- package/src/components/spacing-sizes-control/README.md +93 -0
- package/src/components/spacing-sizes-control/index.js +44 -1
- package/src/components/spacing-sizes-control/linked-button.js +8 -10
- package/src/components/spacing-sizes-control/test/utils.js +0 -151
- package/src/components/spacing-sizes-control/utils.js +0 -106
- package/src/hooks/contrast-checker.js +64 -30
- package/src/hooks/custom-class-name.js +2 -1
- package/src/store/selectors.js +15 -7
package/build-style/style.css
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/block-editor",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.12.0",
|
|
4
4
|
"description": "Generic block editor.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -37,38 +37,38 @@
|
|
|
37
37
|
"@emotion/react": "^11.7.1",
|
|
38
38
|
"@emotion/styled": "^11.6.0",
|
|
39
39
|
"@react-spring/web": "^9.4.5",
|
|
40
|
-
"@wordpress/a11y": "^4.
|
|
41
|
-
"@wordpress/api-fetch": "^7.
|
|
42
|
-
"@wordpress/blob": "^4.
|
|
43
|
-
"@wordpress/block-serialization-default-parser": "^5.
|
|
44
|
-
"@wordpress/blocks": "^14.
|
|
45
|
-
"@wordpress/commands": "^1.
|
|
46
|
-
"@wordpress/components": "^29.
|
|
47
|
-
"@wordpress/compose": "^7.
|
|
48
|
-
"@wordpress/data": "^10.
|
|
49
|
-
"@wordpress/date": "^5.
|
|
50
|
-
"@wordpress/deprecated": "^4.
|
|
51
|
-
"@wordpress/dom": "^4.
|
|
52
|
-
"@wordpress/element": "^6.
|
|
53
|
-
"@wordpress/escape-html": "^3.
|
|
54
|
-
"@wordpress/hooks": "^4.
|
|
55
|
-
"@wordpress/html-entities": "^4.
|
|
56
|
-
"@wordpress/i18n": "^5.
|
|
57
|
-
"@wordpress/icons": "^10.
|
|
58
|
-
"@wordpress/is-shallow-equal": "^5.
|
|
59
|
-
"@wordpress/keyboard-shortcuts": "^5.
|
|
60
|
-
"@wordpress/keycodes": "^4.
|
|
61
|
-
"@wordpress/notices": "^5.
|
|
62
|
-
"@wordpress/preferences": "^4.
|
|
63
|
-
"@wordpress/priority-queue": "^3.
|
|
64
|
-
"@wordpress/private-apis": "^1.
|
|
65
|
-
"@wordpress/rich-text": "^7.
|
|
66
|
-
"@wordpress/style-engine": "^2.
|
|
67
|
-
"@wordpress/token-list": "^3.
|
|
68
|
-
"@wordpress/upload-media": "^0.
|
|
69
|
-
"@wordpress/url": "^4.
|
|
70
|
-
"@wordpress/warning": "^3.
|
|
71
|
-
"@wordpress/wordcount": "^4.
|
|
40
|
+
"@wordpress/a11y": "^4.17.0",
|
|
41
|
+
"@wordpress/api-fetch": "^7.17.0",
|
|
42
|
+
"@wordpress/blob": "^4.17.0",
|
|
43
|
+
"@wordpress/block-serialization-default-parser": "^5.17.0",
|
|
44
|
+
"@wordpress/blocks": "^14.6.0",
|
|
45
|
+
"@wordpress/commands": "^1.17.0",
|
|
46
|
+
"@wordpress/components": "^29.3.0",
|
|
47
|
+
"@wordpress/compose": "^7.17.0",
|
|
48
|
+
"@wordpress/data": "^10.17.0",
|
|
49
|
+
"@wordpress/date": "^5.17.0",
|
|
50
|
+
"@wordpress/deprecated": "^4.17.0",
|
|
51
|
+
"@wordpress/dom": "^4.17.0",
|
|
52
|
+
"@wordpress/element": "^6.17.0",
|
|
53
|
+
"@wordpress/escape-html": "^3.17.0",
|
|
54
|
+
"@wordpress/hooks": "^4.17.0",
|
|
55
|
+
"@wordpress/html-entities": "^4.17.0",
|
|
56
|
+
"@wordpress/i18n": "^5.17.0",
|
|
57
|
+
"@wordpress/icons": "^10.17.0",
|
|
58
|
+
"@wordpress/is-shallow-equal": "^5.17.0",
|
|
59
|
+
"@wordpress/keyboard-shortcuts": "^5.17.0",
|
|
60
|
+
"@wordpress/keycodes": "^4.17.0",
|
|
61
|
+
"@wordpress/notices": "^5.17.0",
|
|
62
|
+
"@wordpress/preferences": "^4.17.0",
|
|
63
|
+
"@wordpress/priority-queue": "^3.17.0",
|
|
64
|
+
"@wordpress/private-apis": "^1.17.0",
|
|
65
|
+
"@wordpress/rich-text": "^7.17.0",
|
|
66
|
+
"@wordpress/style-engine": "^2.17.0",
|
|
67
|
+
"@wordpress/token-list": "^3.17.0",
|
|
68
|
+
"@wordpress/upload-media": "^0.2.0",
|
|
69
|
+
"@wordpress/url": "^4.17.0",
|
|
70
|
+
"@wordpress/warning": "^3.17.0",
|
|
71
|
+
"@wordpress/wordcount": "^4.17.0",
|
|
72
72
|
"change-case": "^4.1.2",
|
|
73
73
|
"clsx": "^2.1.1",
|
|
74
74
|
"colord": "^2.7.0",
|
|
@@ -91,5 +91,5 @@
|
|
|
91
91
|
"publishConfig": {
|
|
92
92
|
"access": "public"
|
|
93
93
|
},
|
|
94
|
-
"gitHead": "
|
|
94
|
+
"gitHead": "68a831c3178197fe87db284d4b94e5743bfb6b6c"
|
|
95
95
|
}
|
|
@@ -54,29 +54,18 @@ const GridVisualizerGrid = forwardRef(
|
|
|
54
54
|
const [ isDroppingAllowed, setIsDroppingAllowed ] = useState( false );
|
|
55
55
|
|
|
56
56
|
useEffect( () => {
|
|
57
|
-
const
|
|
58
|
-
for ( const element of [ gridElement, ...gridElement.children ] ) {
|
|
59
|
-
const observer = new window.ResizeObserver( () => {
|
|
60
|
-
setGridInfo( getGridInfo( gridElement ) );
|
|
61
|
-
} );
|
|
62
|
-
observer.observe( element );
|
|
63
|
-
observers.push( observer );
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const mutationObserver = new window.MutationObserver( () => {
|
|
57
|
+
const resizeCallback = () =>
|
|
67
58
|
setGridInfo( getGridInfo( gridElement ) );
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
59
|
+
// Both border-box and content-box are observed as they may change
|
|
60
|
+
// independently. This requires two observers because a single one
|
|
61
|
+
// can’t be made to monitor both on the same element.
|
|
62
|
+
const borderBoxSpy = new window.ResizeObserver( resizeCallback );
|
|
63
|
+
borderBoxSpy.observe( gridElement, { box: 'border-box' } );
|
|
64
|
+
const contentBoxSpy = new window.ResizeObserver( resizeCallback );
|
|
65
|
+
contentBoxSpy.observe( gridElement );
|
|
76
66
|
return () => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
67
|
+
borderBoxSpy.disconnect();
|
|
68
|
+
contentBoxSpy.disconnect();
|
|
80
69
|
};
|
|
81
70
|
}, [ gridElement ] );
|
|
82
71
|
|
|
@@ -187,10 +187,12 @@ export function getGridInfo( gridElement ) {
|
|
|
187
187
|
gridTemplateColumns,
|
|
188
188
|
gridTemplateRows,
|
|
189
189
|
gap: getComputedCSS( gridElement, 'gap' ),
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
190
|
+
inset: `
|
|
191
|
+
calc(${ paddingTop } + ${ borderTopWidth })
|
|
192
|
+
calc(${ paddingRight } + ${ borderRightWidth })
|
|
193
|
+
calc(${ paddingBottom } + ${ borderBottomWidth })
|
|
194
|
+
calc(${ paddingLeft } + ${ borderLeftWidth })
|
|
195
|
+
`,
|
|
194
196
|
},
|
|
195
197
|
};
|
|
196
198
|
}
|
|
@@ -54,15 +54,17 @@ function InserterMenu(
|
|
|
54
54
|
},
|
|
55
55
|
ref
|
|
56
56
|
) {
|
|
57
|
-
const isZoomOutMode = useSelect(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
57
|
+
const { isZoomOutMode, hasSectionRootClientId } = useSelect( ( select ) => {
|
|
58
|
+
const { isZoomOut, getSectionRootClientId } = unlock(
|
|
59
|
+
select( blockEditorStore )
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
isZoomOutMode: isZoomOut(),
|
|
64
|
+
hasSectionRootClientId: !! getSectionRootClientId(),
|
|
65
|
+
};
|
|
66
|
+
}, [] );
|
|
67
|
+
|
|
66
68
|
const [ filterValue, setFilterValue, delayedFilterValue ] =
|
|
67
69
|
useDebouncedInput( __experimentalFilterValue );
|
|
68
70
|
const [ hoveredItem, setHoveredItem ] = useState( null );
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import {
|
|
5
|
-
PanelBody,
|
|
6
5
|
__experimentalUseSlotFills as useSlotFills,
|
|
6
|
+
__experimentalToolsPanel as ToolsPanel,
|
|
7
|
+
__experimentalToolsPanelItem as ToolsPanelItem,
|
|
7
8
|
} from '@wordpress/components';
|
|
8
|
-
import { useSelect } from '@wordpress/data';
|
|
9
|
-
import { useLayoutEffect, useState } from '@wordpress/element';
|
|
9
|
+
import { useDispatch, useSelect } from '@wordpress/data';
|
|
10
10
|
import { __ } from '@wordpress/i18n';
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -15,40 +15,75 @@ import { __ } from '@wordpress/i18n';
|
|
|
15
15
|
import InspectorControlsGroups from '../inspector-controls/groups';
|
|
16
16
|
import { default as InspectorControls } from '../inspector-controls';
|
|
17
17
|
import { store as blockEditorStore } from '../../store';
|
|
18
|
+
import { useToolsPanelDropdownMenuProps } from '../global-styles/utils';
|
|
19
|
+
import { cleanEmptyObject } from '../../hooks/utils';
|
|
18
20
|
|
|
19
21
|
const PositionControlsPanel = () => {
|
|
20
|
-
const
|
|
22
|
+
const { selectedClientIds, selectedBlocks, hasPositionAttribute } =
|
|
23
|
+
useSelect( ( select ) => {
|
|
24
|
+
const { getBlocksByClientId, getSelectedBlockClientIds } =
|
|
25
|
+
select( blockEditorStore );
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const clientIds = getSelectedBlockClientIds();
|
|
27
|
-
return {
|
|
28
|
-
multiSelectedBlocks: getBlocksByClientId( clientIds ),
|
|
29
|
-
};
|
|
30
|
-
}, [] );
|
|
27
|
+
const selectedBlockClientIds = getSelectedBlockClientIds();
|
|
28
|
+
const _selectedBlocks = getBlocksByClientId(
|
|
29
|
+
selectedBlockClientIds
|
|
30
|
+
);
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
setInitialOpen(
|
|
37
|
-
multiSelectedBlocks.some(
|
|
32
|
+
return {
|
|
33
|
+
selectedClientIds: selectedBlockClientIds,
|
|
34
|
+
selectedBlocks: _selectedBlocks,
|
|
35
|
+
hasPositionAttribute: _selectedBlocks?.some(
|
|
38
36
|
( { attributes } ) => !! attributes?.style?.position?.type
|
|
39
|
-
)
|
|
40
|
-
|
|
37
|
+
),
|
|
38
|
+
};
|
|
39
|
+
}, [] );
|
|
40
|
+
|
|
41
|
+
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
42
|
+
const dropdownMenuProps = useToolsPanelDropdownMenuProps();
|
|
43
|
+
|
|
44
|
+
function resetPosition() {
|
|
45
|
+
if ( ! selectedClientIds?.length || ! selectedBlocks?.length ) {
|
|
46
|
+
return;
|
|
41
47
|
}
|
|
42
|
-
|
|
48
|
+
|
|
49
|
+
const attributesByClientId = Object.fromEntries(
|
|
50
|
+
selectedBlocks?.map( ( { clientId, attributes } ) => [
|
|
51
|
+
clientId,
|
|
52
|
+
{
|
|
53
|
+
style: cleanEmptyObject( {
|
|
54
|
+
...attributes?.style,
|
|
55
|
+
position: {
|
|
56
|
+
...attributes?.style?.position,
|
|
57
|
+
type: undefined,
|
|
58
|
+
top: undefined,
|
|
59
|
+
right: undefined,
|
|
60
|
+
bottom: undefined,
|
|
61
|
+
left: undefined,
|
|
62
|
+
},
|
|
63
|
+
} ),
|
|
64
|
+
},
|
|
65
|
+
] )
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
updateBlockAttributes( selectedClientIds, attributesByClientId, true );
|
|
69
|
+
}
|
|
43
70
|
|
|
44
71
|
return (
|
|
45
|
-
<
|
|
72
|
+
<ToolsPanel
|
|
46
73
|
className="block-editor-block-inspector__position"
|
|
47
|
-
|
|
48
|
-
|
|
74
|
+
label={ __( 'Position' ) }
|
|
75
|
+
resetAll={ resetPosition }
|
|
76
|
+
dropdownMenuProps={ dropdownMenuProps }
|
|
49
77
|
>
|
|
50
|
-
<
|
|
51
|
-
|
|
78
|
+
<ToolsPanelItem
|
|
79
|
+
isShownByDefault={ hasPositionAttribute }
|
|
80
|
+
label={ __( 'Position' ) }
|
|
81
|
+
hasValue={ () => hasPositionAttribute }
|
|
82
|
+
onDeselect={ resetPosition }
|
|
83
|
+
>
|
|
84
|
+
<InspectorControls.Slot group="position" />
|
|
85
|
+
</ToolsPanelItem>
|
|
86
|
+
</ToolsPanel>
|
|
52
87
|
);
|
|
53
88
|
};
|
|
54
89
|
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Spacing Sizes Control
|
|
2
|
+
|
|
3
|
+
The SpacingSizesControl component provides a flexible user interface for controlling spacing values in blocks, allowing users to modify values for different sides. It supports three viewing modes:
|
|
4
|
+
|
|
5
|
+
1. Single: Control one side at a time.
|
|
6
|
+
2. Axial: Control horizontal and vertical sides together.
|
|
7
|
+
3. Custom: Control each side separately.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```jsx
|
|
12
|
+
import { __experimentalSpacingSizesControl as SpacingSizesControl } from '@wordpress/block-editor';
|
|
13
|
+
import { useState } from '@wordpress/element';
|
|
14
|
+
|
|
15
|
+
function Example() {
|
|
16
|
+
const [ sides, setSides ] = useState( {
|
|
17
|
+
top: '0px',
|
|
18
|
+
right: '0px',
|
|
19
|
+
bottom: '0px',
|
|
20
|
+
left: '0px',
|
|
21
|
+
} );
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<SpacingSizesControl
|
|
25
|
+
values={ sides }
|
|
26
|
+
onChange={ setSides }
|
|
27
|
+
label="Sides"
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Props
|
|
34
|
+
|
|
35
|
+
### `inputProps`
|
|
36
|
+
|
|
37
|
+
- Type: `Object`
|
|
38
|
+
- Required: No
|
|
39
|
+
- Description: Additional props to pass to the input controls.
|
|
40
|
+
|
|
41
|
+
### `label`
|
|
42
|
+
|
|
43
|
+
- Type: `String`
|
|
44
|
+
- Required: Yes
|
|
45
|
+
- Description: Label for the control.
|
|
46
|
+
|
|
47
|
+
### `minimumCustomValue`
|
|
48
|
+
|
|
49
|
+
- Type: `Number`
|
|
50
|
+
- Default: 0
|
|
51
|
+
- Description: Minimum value allowed for custom input.
|
|
52
|
+
|
|
53
|
+
### `onChange`
|
|
54
|
+
|
|
55
|
+
- Type: `Function`
|
|
56
|
+
- Required: Yes
|
|
57
|
+
- Description: Callback function called when spacing values change. Receives an object containing the updated values.
|
|
58
|
+
|
|
59
|
+
### `onMouseOut`
|
|
60
|
+
|
|
61
|
+
- Type: `Function`
|
|
62
|
+
- Required: No
|
|
63
|
+
- Description: Callback function called when mouse leaves the control.
|
|
64
|
+
|
|
65
|
+
### `onMouseOver`
|
|
66
|
+
|
|
67
|
+
- Type: `Function`
|
|
68
|
+
- Required: No
|
|
69
|
+
- Description: Callback function called when mouse enters the control.
|
|
70
|
+
|
|
71
|
+
### `showSideInLabel`
|
|
72
|
+
|
|
73
|
+
- Type: `Boolean`
|
|
74
|
+
- Default: true
|
|
75
|
+
- Description: Whether to show the side (top, right, etc.) in the control label.
|
|
76
|
+
|
|
77
|
+
### `sides`
|
|
78
|
+
|
|
79
|
+
- Type: `Array`
|
|
80
|
+
- Default: ALL_SIDES (top, right, bottom, left)
|
|
81
|
+
- Description: Array of sides that can be controlled.
|
|
82
|
+
|
|
83
|
+
### `useSelect`
|
|
84
|
+
|
|
85
|
+
- Type: `Boolean`
|
|
86
|
+
- Required: No
|
|
87
|
+
- Description: Whether to use a select control for predefined values.
|
|
88
|
+
|
|
89
|
+
### `values`
|
|
90
|
+
|
|
91
|
+
- Type: `Object`
|
|
92
|
+
- Required: No
|
|
93
|
+
- Description: Object containing the current spacing values for each side.
|
|
@@ -12,11 +12,11 @@ import { _x, sprintf } from '@wordpress/i18n';
|
|
|
12
12
|
/**
|
|
13
13
|
* Internal dependencies
|
|
14
14
|
*/
|
|
15
|
+
import useSpacingSizes from './hooks/use-spacing-sizes';
|
|
15
16
|
import AxialInputControls from './input-controls/axial';
|
|
16
17
|
import SeparatedInputControls from './input-controls/separated';
|
|
17
18
|
import SingleInputControl from './input-controls/single';
|
|
18
19
|
import LinkedButton from './linked-button';
|
|
19
|
-
import useSpacingSizes from './hooks/use-spacing-sizes';
|
|
20
20
|
import {
|
|
21
21
|
ALL_SIDES,
|
|
22
22
|
DEFAULT_VALUES,
|
|
@@ -25,6 +25,49 @@ import {
|
|
|
25
25
|
getInitialView,
|
|
26
26
|
} from './utils';
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* A flexible control for managing spacing values in the block editor. Supports single, axial,
|
|
30
|
+
* and separated input controls for different spacing configurations with automatic view selection
|
|
31
|
+
* based on current values and available sides.
|
|
32
|
+
*
|
|
33
|
+
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/spacing-sizes-control/README.md
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```jsx
|
|
37
|
+
* import { __experimentalSpacingSizesControl as SpacingSizesControl } from '@wordpress/block-editor';
|
|
38
|
+
* import { useState } from '@wordpress/element';
|
|
39
|
+
*
|
|
40
|
+
* function Example() {
|
|
41
|
+
* const [ sides, setSides ] = useState( {
|
|
42
|
+
* top: '0px',
|
|
43
|
+
* right: '0px',
|
|
44
|
+
* bottom: '0px',
|
|
45
|
+
* left: '0px',
|
|
46
|
+
* } );
|
|
47
|
+
*
|
|
48
|
+
* return (
|
|
49
|
+
* <SpacingSizesControl
|
|
50
|
+
* values={ sides }
|
|
51
|
+
* onChange={ setSides }
|
|
52
|
+
* label="Sides"
|
|
53
|
+
* />
|
|
54
|
+
* );
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @param {Object} props Component props.
|
|
59
|
+
* @param {Object} props.inputProps Additional props for input controls.
|
|
60
|
+
* @param {string} props.label Label for the control.
|
|
61
|
+
* @param {number} props.minimumCustomValue Minimum value for custom input.
|
|
62
|
+
* @param {Function} props.onChange Called when spacing values change.
|
|
63
|
+
* @param {Function} props.onMouseOut Called when mouse leaves the control.
|
|
64
|
+
* @param {Function} props.onMouseOver Called when mouse enters the control.
|
|
65
|
+
* @param {boolean} props.showSideInLabel Show side in control label.
|
|
66
|
+
* @param {Array} props.sides Available sides for control.
|
|
67
|
+
* @param {boolean} props.useSelect Use select control for predefined values.
|
|
68
|
+
* @param {Object} props.values Current spacing values.
|
|
69
|
+
* @return {Element} Spacing sizes control component.
|
|
70
|
+
*/
|
|
28
71
|
export default function SpacingSizesControl( {
|
|
29
72
|
inputProps,
|
|
30
73
|
label: labelProp,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { Button
|
|
4
|
+
import { Button } from '@wordpress/components';
|
|
5
5
|
import { link, linkOff } from '@wordpress/icons';
|
|
6
6
|
import { __ } from '@wordpress/i18n';
|
|
7
7
|
|
|
@@ -9,14 +9,12 @@ export default function LinkedButton( { isLinked, ...props } ) {
|
|
|
9
9
|
const label = isLinked ? __( 'Unlink sides' ) : __( 'Link sides' );
|
|
10
10
|
|
|
11
11
|
return (
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/>
|
|
20
|
-
</Tooltip>
|
|
12
|
+
<Button
|
|
13
|
+
{ ...props }
|
|
14
|
+
size="small"
|
|
15
|
+
icon={ isLinked ? link : linkOff }
|
|
16
|
+
iconSize={ 24 }
|
|
17
|
+
label={ label }
|
|
18
|
+
/>
|
|
21
19
|
);
|
|
22
20
|
}
|
|
@@ -3,20 +3,15 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import {
|
|
5
5
|
ALL_SIDES,
|
|
6
|
-
getAllRawValue,
|
|
7
6
|
getCustomValueFromPreset,
|
|
8
7
|
getInitialView,
|
|
9
8
|
getPresetValueFromCustomValue,
|
|
10
9
|
getSliderValueFromPreset,
|
|
11
10
|
getSpacingPresetCssVar,
|
|
12
11
|
getSpacingPresetSlug,
|
|
13
|
-
getSupportedMenuItems,
|
|
14
12
|
hasAxisSupport,
|
|
15
13
|
hasBalancedSidesSupport,
|
|
16
|
-
isValuesDefined,
|
|
17
|
-
isValuesMixed,
|
|
18
14
|
isValueSpacingPreset,
|
|
19
|
-
LABELS,
|
|
20
15
|
VIEWS,
|
|
21
16
|
} from '../utils';
|
|
22
17
|
|
|
@@ -114,88 +109,6 @@ describe( 'getSliderValueFromPreset', () => {
|
|
|
114
109
|
} );
|
|
115
110
|
} );
|
|
116
111
|
|
|
117
|
-
describe( 'getAllRawValue', () => {
|
|
118
|
-
const customValues = {
|
|
119
|
-
top: '5px',
|
|
120
|
-
bottom: '5px',
|
|
121
|
-
left: '6px',
|
|
122
|
-
right: '2px',
|
|
123
|
-
};
|
|
124
|
-
it( 'should return the most common custom value from the values object', () => {
|
|
125
|
-
expect( getAllRawValue( customValues ) ).toBe( '5px' );
|
|
126
|
-
} );
|
|
127
|
-
const presetValues = {
|
|
128
|
-
top: 'var:preset|spacing|30',
|
|
129
|
-
bottom: 'var:preset|spacing|20',
|
|
130
|
-
left: 'var:preset|spacing|10',
|
|
131
|
-
right: 'var:preset|spacing|30',
|
|
132
|
-
};
|
|
133
|
-
it( 'should return the most common preset value from the values object', () => {
|
|
134
|
-
expect( getAllRawValue( presetValues ) ).toBe(
|
|
135
|
-
'var:preset|spacing|30'
|
|
136
|
-
);
|
|
137
|
-
} );
|
|
138
|
-
} );
|
|
139
|
-
|
|
140
|
-
describe( 'isValuesMixed', () => {
|
|
141
|
-
const unmixedValues = {
|
|
142
|
-
top: '5px',
|
|
143
|
-
bottom: '5px',
|
|
144
|
-
left: '5px',
|
|
145
|
-
right: '5px',
|
|
146
|
-
};
|
|
147
|
-
it( 'should return false if all values are the same', () => {
|
|
148
|
-
expect( isValuesMixed( unmixedValues ) ).toBe( false );
|
|
149
|
-
} );
|
|
150
|
-
const mixedValues = {
|
|
151
|
-
top: 'var:preset|spacing|30',
|
|
152
|
-
bottom: 'var:preset|spacing|20',
|
|
153
|
-
left: 'var:preset|spacing|10',
|
|
154
|
-
right: 'var:preset|spacing|30',
|
|
155
|
-
};
|
|
156
|
-
it( 'should return true if all the values are not the same', () => {
|
|
157
|
-
expect( isValuesMixed( mixedValues ) ).toBe( true );
|
|
158
|
-
} );
|
|
159
|
-
const singleValue = {
|
|
160
|
-
top: 'var:preset|spacing|30',
|
|
161
|
-
};
|
|
162
|
-
it( 'should return true if only one side set', () => {
|
|
163
|
-
expect( isValuesMixed( singleValue ) ).toBe( true );
|
|
164
|
-
} );
|
|
165
|
-
const incompleteValues = {
|
|
166
|
-
top: 'var:preset|spacing|30',
|
|
167
|
-
bottom: 'var:preset|spacing|30',
|
|
168
|
-
left: 'var:preset|spacing|30',
|
|
169
|
-
};
|
|
170
|
-
it( 'should return true if all sides not set', () => {
|
|
171
|
-
expect( isValuesMixed( incompleteValues ) ).toBe( true );
|
|
172
|
-
} );
|
|
173
|
-
} );
|
|
174
|
-
|
|
175
|
-
describe( 'isValuesDefined', () => {
|
|
176
|
-
const undefinedValues = {
|
|
177
|
-
top: undefined,
|
|
178
|
-
bottom: undefined,
|
|
179
|
-
left: undefined,
|
|
180
|
-
right: undefined,
|
|
181
|
-
};
|
|
182
|
-
it( 'should return false if values are not defined', () => {
|
|
183
|
-
expect( isValuesDefined( undefinedValues ) ).toBe( false );
|
|
184
|
-
} );
|
|
185
|
-
it( 'should return false if values is passed in as null', () => {
|
|
186
|
-
expect( isValuesDefined( null ) ).toBe( false );
|
|
187
|
-
} );
|
|
188
|
-
const definedValues = {
|
|
189
|
-
top: 'var:preset|spacing|30',
|
|
190
|
-
bottom: 'var:preset|spacing|20',
|
|
191
|
-
left: 'var:preset|spacing|10',
|
|
192
|
-
right: 'var:preset|spacing|30',
|
|
193
|
-
};
|
|
194
|
-
it( 'should return true if all the values are not the same', () => {
|
|
195
|
-
expect( isValuesDefined( definedValues ) ).toBe( true );
|
|
196
|
-
} );
|
|
197
|
-
} );
|
|
198
|
-
|
|
199
112
|
describe( 'hasAxisSupport', () => {
|
|
200
113
|
it( 'should return true for horizontal support if it is in sides', () => {
|
|
201
114
|
expect( hasAxisSupport( [ 'horizontal' ], 'horizontal' ) ).toBe( true );
|
|
@@ -228,70 +141,6 @@ describe( 'hasAxisSupport', () => {
|
|
|
228
141
|
} );
|
|
229
142
|
} );
|
|
230
143
|
|
|
231
|
-
describe( 'getSupportedMenuItems', () => {
|
|
232
|
-
it( 'returns no items when sides are not configured', () => {
|
|
233
|
-
expect( getSupportedMenuItems( [] ) ).toEqual( {} );
|
|
234
|
-
expect( getSupportedMenuItems() ).toEqual( {} );
|
|
235
|
-
} );
|
|
236
|
-
|
|
237
|
-
const sideConfigs = [
|
|
238
|
-
[ LABELS.axial, [ 'horizontal', 'vertical' ] ],
|
|
239
|
-
[ LABELS.axial, [ 'top', 'right', 'bottom', 'left' ] ],
|
|
240
|
-
[ LABELS.horizontal, [ 'horizontal' ] ],
|
|
241
|
-
[ LABELS.horizontal, [ 'left', 'right' ] ],
|
|
242
|
-
[ LABELS.vertical, [ 'vertical' ] ],
|
|
243
|
-
[ LABELS.vertical, [ 'top', 'bottom' ] ],
|
|
244
|
-
[ LABELS.horizontal, [ 'horizontal' ] ],
|
|
245
|
-
];
|
|
246
|
-
|
|
247
|
-
test.each( sideConfigs )(
|
|
248
|
-
'should include %s axial menu with %s sides',
|
|
249
|
-
( label, sides ) => {
|
|
250
|
-
expect( getSupportedMenuItems( sides ) ).toHaveProperty(
|
|
251
|
-
'axial.label',
|
|
252
|
-
label
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
);
|
|
256
|
-
|
|
257
|
-
it( 'returns no axial item when not not supported', () => {
|
|
258
|
-
expect( getSupportedMenuItems( [ 'left', 'top' ] ) ).not.toHaveProperty(
|
|
259
|
-
'axial'
|
|
260
|
-
);
|
|
261
|
-
} );
|
|
262
|
-
|
|
263
|
-
it( 'should include the correct individual side options', () => {
|
|
264
|
-
expect( getSupportedMenuItems( [ 'top' ] ) ).toHaveProperty(
|
|
265
|
-
'top.label',
|
|
266
|
-
LABELS.top
|
|
267
|
-
);
|
|
268
|
-
expect( getSupportedMenuItems( [ 'right' ] ) ).toHaveProperty(
|
|
269
|
-
'right.label',
|
|
270
|
-
LABELS.right
|
|
271
|
-
);
|
|
272
|
-
expect( getSupportedMenuItems( [ 'bottom' ] ) ).toHaveProperty(
|
|
273
|
-
'bottom.label',
|
|
274
|
-
LABELS.bottom
|
|
275
|
-
);
|
|
276
|
-
expect( getSupportedMenuItems( [ 'left' ] ) ).toHaveProperty(
|
|
277
|
-
'left.label',
|
|
278
|
-
LABELS.left
|
|
279
|
-
);
|
|
280
|
-
} );
|
|
281
|
-
it( 'should include the custom option only when applicable', () => {
|
|
282
|
-
expect( getSupportedMenuItems( [ 'top', 'left' ] ) ).toHaveProperty(
|
|
283
|
-
'custom.label',
|
|
284
|
-
LABELS.custom
|
|
285
|
-
);
|
|
286
|
-
expect( getSupportedMenuItems( [ 'top' ] ) ).not.toHaveProperty(
|
|
287
|
-
'custom'
|
|
288
|
-
);
|
|
289
|
-
expect(
|
|
290
|
-
getSupportedMenuItems( [ 'horizontal', 'vertical' ] )
|
|
291
|
-
).not.toHaveProperty( 'custom.label' );
|
|
292
|
-
} );
|
|
293
|
-
} );
|
|
294
|
-
|
|
295
144
|
describe( 'hasBalancedSidesSupport', () => {
|
|
296
145
|
it( 'should determine balanced sides', () => {
|
|
297
146
|
expect( hasBalancedSidesSupport( ALL_SIDES ) ).toBe( true );
|