@wordpress/block-editor 15.9.1-next.8b30e05b0.0 → 15.10.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/README.md +8 -0
- package/build/components/block-alignment-matrix-control/index.js +1 -8
- package/build/components/block-alignment-matrix-control/index.js.map +2 -2
- package/build/components/block-bindings/attribute-control.js +172 -0
- package/build/components/block-bindings/attribute-control.js.map +7 -0
- package/build/components/block-bindings/index.js +47 -0
- package/build/components/block-bindings/index.js.map +7 -0
- package/build/components/block-bindings/source-fields-list.js +135 -0
- package/build/components/block-bindings/source-fields-list.js.map +7 -0
- package/build/components/block-bindings/use-block-bindings-utils.js +66 -0
- package/build/components/block-bindings/use-block-bindings-utils.js.map +7 -0
- package/build/components/block-edit/edit.js +1 -3
- package/build/components/block-edit/edit.js.map +2 -2
- package/build/components/block-inspector/edit-contents.js +93 -14
- package/build/components/block-inspector/edit-contents.js.map +3 -3
- package/build/components/block-inspector/index.js +44 -28
- package/build/components/block-inspector/index.js.map +2 -2
- package/build/components/block-settings-menu-controls/edit-section-menu-item.js +39 -9
- package/build/components/block-settings-menu-controls/edit-section-menu-item.js.map +3 -3
- package/build/components/block-styles/preview-panel.js +3 -5
- package/build/components/block-styles/preview-panel.js.map +2 -2
- package/build/components/block-styles/use-styles-for-block.js +2 -2
- package/build/components/block-styles/use-styles-for-block.js.map +2 -2
- package/build/components/block-toolbar/index.js +1 -8
- package/build/components/block-toolbar/index.js.map +3 -3
- package/build/components/content-only-controls/index.js +2 -25
- package/build/components/content-only-controls/index.js.map +2 -2
- package/build/components/content-only-controls/link/index.js +3 -3
- package/build/components/content-only-controls/link/index.js.map +2 -2
- package/build/components/content-only-controls/media/index.js +3 -3
- package/build/components/content-only-controls/media/index.js.map +2 -2
- package/build/components/content-only-controls/rich-text/index.js +3 -2
- package/build/components/content-only-controls/rich-text/index.js.map +2 -2
- package/build/components/dimensions-tool/width-height-tool.js +4 -16
- package/build/components/dimensions-tool/width-height-tool.js.map +3 -3
- package/build/components/grid/grid-item-resizer.js +9 -5
- package/build/components/grid/grid-item-resizer.js.map +2 -2
- package/build/components/image-editor/cropper.js +3 -34
- package/build/components/image-editor/cropper.js.map +3 -3
- package/build/components/image-editor/index.js +9 -3
- package/build/components/image-editor/index.js.map +2 -2
- package/build/components/image-editor/use-transform-image.js +62 -32
- package/build/components/image-editor/use-transform-image.js.map +2 -2
- package/build/components/image-editor/zoom-dropdown.js +2 -2
- package/build/components/image-editor/zoom-dropdown.js.map +2 -2
- package/build/components/index.js +7 -3
- package/build/components/index.js.map +2 -2
- package/build/components/inserter/hooks/use-insertion-point.js +5 -2
- package/build/components/inserter/hooks/use-insertion-point.js.map +2 -2
- package/build/components/inserter-draggable-blocks/index.js +8 -4
- package/build/components/inserter-draggable-blocks/index.js.map +2 -2
- package/build/components/inspector-controls-tabs/content-tab.js +3 -2
- package/build/components/inspector-controls-tabs/content-tab.js.map +2 -2
- package/build/components/link-control/index.js +1 -1
- package/build/components/link-control/index.js.map +2 -2
- package/build/components/link-control/search-input.js +2 -2
- package/build/components/link-control/search-input.js.map +2 -2
- package/build/hooks/block-bindings.js +22 -260
- package/build/hooks/block-bindings.js.map +3 -3
- package/build/layouts/grid.js +23 -28
- package/build/layouts/grid.js.map +2 -2
- package/build/private-apis.js +1 -0
- package/build/private-apis.js.map +2 -2
- package/build/store/private-keys.js +3 -0
- package/build/store/private-keys.js.map +2 -2
- package/build/store/private-selectors.js +2 -1
- package/build/store/private-selectors.js.map +2 -2
- package/build/store/reducer.js +3 -2
- package/build/store/reducer.js.map +2 -2
- package/build/utils/block-bindings.js +2 -44
- package/build/utils/block-bindings.js.map +3 -3
- package/build/utils/index.js +2 -5
- package/build/utils/index.js.map +2 -2
- package/build-module/components/block-alignment-matrix-control/index.js +1 -8
- package/build-module/components/block-alignment-matrix-control/index.js.map +2 -2
- package/build-module/components/block-bindings/attribute-control.js +150 -0
- package/build-module/components/block-bindings/attribute-control.js.map +7 -0
- package/build-module/components/block-bindings/index.js +10 -0
- package/build-module/components/block-bindings/index.js.map +7 -0
- package/build-module/components/block-bindings/source-fields-list.js +104 -0
- package/build-module/components/block-bindings/source-fields-list.js.map +7 -0
- package/build-module/components/block-bindings/use-block-bindings-utils.js +45 -0
- package/build-module/components/block-bindings/use-block-bindings-utils.js.map +7 -0
- package/build-module/components/block-edit/edit.js +1 -3
- package/build-module/components/block-edit/edit.js.map +2 -2
- package/build-module/components/block-inspector/edit-contents.js +93 -14
- package/build-module/components/block-inspector/edit-contents.js.map +2 -2
- package/build-module/components/block-inspector/index.js +44 -28
- package/build-module/components/block-inspector/index.js.map +2 -2
- package/build-module/components/block-settings-menu-controls/edit-section-menu-item.js +39 -9
- package/build-module/components/block-settings-menu-controls/edit-section-menu-item.js.map +2 -2
- package/build-module/components/block-styles/preview-panel.js +3 -5
- package/build-module/components/block-styles/preview-panel.js.map +2 -2
- package/build-module/components/block-styles/use-styles-for-block.js +2 -2
- package/build-module/components/block-styles/use-styles-for-block.js.map +2 -2
- package/build-module/components/block-toolbar/index.js +1 -8
- package/build-module/components/block-toolbar/index.js.map +2 -2
- package/build-module/components/content-only-controls/index.js +2 -25
- package/build-module/components/content-only-controls/index.js.map +2 -2
- package/build-module/components/content-only-controls/link/index.js +3 -3
- package/build-module/components/content-only-controls/link/index.js.map +2 -2
- package/build-module/components/content-only-controls/media/index.js +3 -3
- package/build-module/components/content-only-controls/media/index.js.map +2 -2
- package/build-module/components/content-only-controls/rich-text/index.js +3 -2
- package/build-module/components/content-only-controls/rich-text/index.js.map +2 -2
- package/build-module/components/dimensions-tool/width-height-tool.js +4 -6
- package/build-module/components/dimensions-tool/width-height-tool.js.map +2 -2
- package/build-module/components/grid/grid-item-resizer.js +9 -5
- package/build-module/components/grid/grid-item-resizer.js.map +2 -2
- package/build-module/components/image-editor/cropper.js +3 -34
- package/build-module/components/image-editor/cropper.js.map +2 -2
- package/build-module/components/image-editor/index.js +9 -3
- package/build-module/components/image-editor/index.js.map +2 -2
- package/build-module/components/image-editor/use-transform-image.js +63 -33
- package/build-module/components/image-editor/use-transform-image.js.map +2 -2
- package/build-module/components/image-editor/zoom-dropdown.js +2 -2
- package/build-module/components/image-editor/zoom-dropdown.js.map +2 -2
- package/build-module/components/index.js +74 -68
- package/build-module/components/index.js.map +2 -2
- package/build-module/components/inserter/hooks/use-insertion-point.js +5 -2
- package/build-module/components/inserter/hooks/use-insertion-point.js.map +2 -2
- package/build-module/components/inserter-draggable-blocks/index.js +8 -4
- package/build-module/components/inserter-draggable-blocks/index.js.map +2 -2
- package/build-module/components/inspector-controls-tabs/content-tab.js +3 -2
- package/build-module/components/inspector-controls-tabs/content-tab.js.map +2 -2
- package/build-module/components/link-control/index.js +1 -1
- package/build-module/components/link-control/index.js.map +2 -2
- package/build-module/components/link-control/search-input.js +2 -2
- package/build-module/components/link-control/search-input.js.map +2 -2
- package/build-module/hooks/block-bindings.js +27 -270
- package/build-module/hooks/block-bindings.js.map +2 -2
- package/build-module/layouts/grid.js +23 -28
- package/build-module/layouts/grid.js.map +2 -2
- package/build-module/private-apis.js +3 -1
- package/build-module/private-apis.js.map +2 -2
- package/build-module/store/private-keys.js +2 -0
- package/build-module/store/private-keys.js.map +2 -2
- package/build-module/store/private-selectors.js +4 -2
- package/build-module/store/private-selectors.js.map +2 -2
- package/build-module/store/reducer.js +4 -3
- package/build-module/store/reducer.js.map +2 -2
- package/build-module/utils/block-bindings.js +1 -42
- package/build-module/utils/block-bindings.js.map +2 -2
- package/build-module/utils/index.js +1 -3
- package/build-module/utils/index.js.map +2 -2
- package/build-style/style-rtl.css +6 -6
- package/build-style/style.css +6 -6
- package/package.json +39 -40
- package/src/components/block-alignment-matrix-control/index.js +1 -5
- package/src/components/block-bindings/attribute-control.js +174 -0
- package/src/components/block-bindings/index.js +6 -0
- package/src/components/block-bindings/source-fields-list.js +130 -0
- package/src/components/block-bindings/use-block-bindings-utils.js +156 -0
- package/src/components/block-edit/edit.js +1 -3
- package/src/components/block-inspector/edit-contents.js +108 -18
- package/src/components/block-inspector/index.js +53 -30
- package/src/components/block-settings-menu-controls/edit-section-menu-item.js +50 -6
- package/src/components/block-styles/preview-panel.js +3 -5
- package/src/components/block-styles/use-styles-for-block.js +2 -2
- package/src/components/block-toolbar/index.js +1 -6
- package/src/components/block-toolbar/style.scss +6 -6
- package/src/components/content-only-controls/index.js +2 -27
- package/src/components/content-only-controls/link/index.js +3 -3
- package/src/components/content-only-controls/media/index.js +3 -3
- package/src/components/content-only-controls/rich-text/index.js +3 -2
- package/src/components/dimensions-tool/width-height-tool.js +6 -13
- package/src/components/grid/grid-item-resizer.js +18 -5
- package/src/components/image-editor/cropper.js +3 -32
- package/src/components/image-editor/index.js +34 -29
- package/src/components/image-editor/use-transform-image.js +80 -34
- package/src/components/image-editor/zoom-dropdown.js +2 -2
- package/src/components/index.js +5 -1
- package/src/components/inserter/hooks/use-insertion-point.js +3 -0
- package/src/components/inserter/style.scss +1 -1
- package/src/components/inserter-draggable-blocks/index.js +19 -8
- package/src/components/inspector-controls-tabs/content-tab.js +6 -2
- package/src/components/link-control/index.js +1 -1
- package/src/components/link-control/search-input.js +8 -2
- package/src/components/link-control/test/index.js +146 -7
- package/src/hooks/block-bindings.js +27 -347
- package/src/layouts/grid.js +40 -72
- package/src/layouts/test/grid.js +14 -0
- package/src/private-apis.js +2 -0
- package/src/store/private-keys.js +1 -0
- package/src/store/private-selectors.js +8 -1
- package/src/store/reducer.js +10 -3
- package/src/utils/block-bindings.js +0 -157
- package/src/utils/index.js +0 -1
- package/tsconfig.json +1 -0
- package/build/components/block-toolbar/block-name-context.js +0 -30
- package/build/components/block-toolbar/block-name-context.js.map +0 -7
- package/build-module/components/block-toolbar/block-name-context.js +0 -9
- package/build-module/components/block-toolbar/block-name-context.js.map +0 -7
- package/src/components/block-toolbar/block-name-context.js +0 -9
- /package/src/{utils → components/block-bindings}/test/use-block-bindings-utils.js +0 -0
|
@@ -32,7 +32,6 @@ import { BlockGroupToolbar } from '../convert-to-group-buttons';
|
|
|
32
32
|
import BlockEditVisuallyButton from '../block-edit-visually-button';
|
|
33
33
|
import { useShowHoveredOrFocusedGestures } from './utils';
|
|
34
34
|
import { store as blockEditorStore } from '../../store';
|
|
35
|
-
import __unstableBlockNameContext from './block-name-context';
|
|
36
35
|
import NavigableToolbar from '../navigable-toolbar';
|
|
37
36
|
import { useHasBlockToolbar } from './use-has-block-toolbar';
|
|
38
37
|
import ChangeDesign from './change-design';
|
|
@@ -265,11 +264,7 @@ export function PrivateBlockToolbar( {
|
|
|
265
264
|
group="other"
|
|
266
265
|
className="block-editor-block-toolbar__slot"
|
|
267
266
|
/>
|
|
268
|
-
<
|
|
269
|
-
value={ blockType?.name }
|
|
270
|
-
>
|
|
271
|
-
<__unstableBlockToolbarLastItem.Slot />
|
|
272
|
-
</__unstableBlockNameContext.Provider>
|
|
267
|
+
<__unstableBlockToolbarLastItem.Slot />
|
|
273
268
|
</>
|
|
274
269
|
) }
|
|
275
270
|
<BlockEditVisuallyButton clientIds={ blockClientIds } />
|
|
@@ -193,6 +193,12 @@
|
|
|
193
193
|
font-size: $helptext-font-size;
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
+
|
|
197
|
+
.block-editor-block-icon {
|
|
198
|
+
width: 0 !important;
|
|
199
|
+
height: 0 !important;
|
|
200
|
+
min-width: 0 !important;
|
|
201
|
+
}
|
|
196
202
|
}
|
|
197
203
|
|
|
198
204
|
// Padding overrides.
|
|
@@ -201,12 +207,6 @@
|
|
|
201
207
|
padding-right: 6px;
|
|
202
208
|
}
|
|
203
209
|
|
|
204
|
-
.block-editor-block-icon {
|
|
205
|
-
width: 0 !important;
|
|
206
|
-
height: 0 !important;
|
|
207
|
-
min-width: 0 !important;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
210
|
// Parent selector overrides
|
|
211
211
|
.block-editor-block-parent-selector .block-editor-block-parent-selector__button {
|
|
212
212
|
border-top-right-radius: 0;
|
|
@@ -295,19 +295,13 @@ function BlockFields( { clientId } ) {
|
|
|
295
295
|
field.Edit = createConfiguredControl( {
|
|
296
296
|
control: fieldDef.type,
|
|
297
297
|
clientId,
|
|
298
|
-
updateBlockAttributes,
|
|
299
298
|
fieldDef,
|
|
300
299
|
} );
|
|
301
300
|
}
|
|
302
301
|
|
|
303
302
|
return field;
|
|
304
303
|
} );
|
|
305
|
-
}, [
|
|
306
|
-
blockTypeFields,
|
|
307
|
-
blockType?.attributes,
|
|
308
|
-
clientId,
|
|
309
|
-
updateBlockAttributes,
|
|
310
|
-
] );
|
|
304
|
+
}, [ blockTypeFields, blockType?.attributes, clientId ] );
|
|
311
305
|
|
|
312
306
|
const handleToggleField = ( fieldId ) => {
|
|
313
307
|
setForm( ( prev ) => {
|
|
@@ -351,26 +345,7 @@ function BlockFields( { clientId } ) {
|
|
|
351
345
|
fields={ dataFormFields }
|
|
352
346
|
form={ form }
|
|
353
347
|
onChange={ ( changes ) => {
|
|
354
|
-
|
|
355
|
-
const mappedChanges = {};
|
|
356
|
-
Object.entries( changes ).forEach(
|
|
357
|
-
( [ fieldId, fieldValue ] ) => {
|
|
358
|
-
const field = dataFormFields.find(
|
|
359
|
-
( f ) => f.id === fieldId
|
|
360
|
-
);
|
|
361
|
-
if ( field && field.setValue ) {
|
|
362
|
-
const updates = field.setValue( {
|
|
363
|
-
item: attributes,
|
|
364
|
-
value: fieldValue,
|
|
365
|
-
} );
|
|
366
|
-
Object.assign( mappedChanges, updates );
|
|
367
|
-
} else {
|
|
368
|
-
// For fields without setValue, use the value directly
|
|
369
|
-
mappedChanges[ fieldId ] = fieldValue;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
);
|
|
373
|
-
updateBlockAttributes( clientId, mappedChanges );
|
|
348
|
+
updateBlockAttributes( clientId, changes );
|
|
374
349
|
} }
|
|
375
350
|
/>
|
|
376
351
|
</div>
|
|
@@ -67,15 +67,15 @@ export function getUpdatedLinkAttributes( {
|
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
export default function Link( { data, field, config = {} } ) {
|
|
70
|
+
export default function Link( { data, field, onChange, config = {} } ) {
|
|
71
71
|
const [ isLinkControlOpen, setIsLinkControlOpen ] = useState( false );
|
|
72
72
|
const { popoverProps } = useInspectorPopoverPlacement( {
|
|
73
73
|
isControl: true,
|
|
74
74
|
} );
|
|
75
|
-
const {
|
|
75
|
+
const { fieldDef } = config;
|
|
76
76
|
const updateAttributes = ( newValue ) => {
|
|
77
77
|
const mappedChanges = field.setValue( { item: data, value: newValue } );
|
|
78
|
-
|
|
78
|
+
onChange( mappedChanges );
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
const value = field.getValue( { item: data } );
|
|
@@ -83,19 +83,19 @@ function MediaThumbnail( { data, field, attachment } ) {
|
|
|
83
83
|
return <Icon icon={ mediaIcon } size={ 24 } />;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
export default function Media( { data, field, config = {} } ) {
|
|
86
|
+
export default function Media( { data, field, onChange, config = {} } ) {
|
|
87
87
|
const { popoverProps } = useInspectorPopoverPlacement( {
|
|
88
88
|
isControl: true,
|
|
89
89
|
} );
|
|
90
90
|
const value = field.getValue( { item: data } );
|
|
91
91
|
const { allowedTypes = [], multiple = false } = field.config || {};
|
|
92
|
-
const {
|
|
92
|
+
const { fieldDef } = config;
|
|
93
93
|
const updateAttributes = ( newFieldValue ) => {
|
|
94
94
|
const mappedChanges = field.setValue( {
|
|
95
95
|
item: data,
|
|
96
96
|
value: newFieldValue,
|
|
97
97
|
} );
|
|
98
|
-
|
|
98
|
+
onChange( mappedChanges );
|
|
99
99
|
};
|
|
100
100
|
|
|
101
101
|
// Check if featured image is supported by checking if it's in the mapping
|
|
@@ -23,15 +23,16 @@ export default function RichTextControl( {
|
|
|
23
23
|
data,
|
|
24
24
|
field,
|
|
25
25
|
hideLabelFromVision,
|
|
26
|
+
onChange,
|
|
26
27
|
config = {},
|
|
27
28
|
} ) {
|
|
28
29
|
const registry = useRegistry();
|
|
29
30
|
const attrValue = field.getValue( { item: data } );
|
|
30
31
|
const fieldConfig = field.config || {};
|
|
31
|
-
const { clientId
|
|
32
|
+
const { clientId } = config;
|
|
32
33
|
const updateAttributes = ( html ) => {
|
|
33
34
|
const mappedChanges = field.setValue( { item: data, value: html } );
|
|
34
|
-
|
|
35
|
+
onChange( mappedChanges );
|
|
35
36
|
};
|
|
36
37
|
const [ selection, setSelection ] = useState( {
|
|
37
38
|
start: undefined,
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import styled from '@emotion/styled';
|
|
5
|
-
|
|
6
1
|
/**
|
|
7
2
|
* WordPress dependencies
|
|
8
3
|
*/
|
|
@@ -12,10 +7,6 @@ import {
|
|
|
12
7
|
} from '@wordpress/components';
|
|
13
8
|
import { __ } from '@wordpress/i18n';
|
|
14
9
|
|
|
15
|
-
const SingleColumnToolsPanelItem = styled( ToolsPanelItem )`
|
|
16
|
-
grid-column: span 1;
|
|
17
|
-
`;
|
|
18
|
-
|
|
19
10
|
/**
|
|
20
11
|
* @typedef {import('@wordpress/components/build-types/unit-control/types').WPUnitControlUnit} WPUnitControlUnit
|
|
21
12
|
*/
|
|
@@ -72,7 +63,8 @@ export default function WidthHeightTool( {
|
|
|
72
63
|
|
|
73
64
|
return (
|
|
74
65
|
<>
|
|
75
|
-
<
|
|
66
|
+
<ToolsPanelItem
|
|
67
|
+
style={ { gridColumn: 'span 1' } }
|
|
76
68
|
label={ __( 'Width' ) }
|
|
77
69
|
isShownByDefault={ isShownByDefault }
|
|
78
70
|
hasValue={ () => width !== '' }
|
|
@@ -89,8 +81,9 @@ export default function WidthHeightTool( {
|
|
|
89
81
|
onChange={ onDimensionChange( 'width' ) }
|
|
90
82
|
size="__unstable-large"
|
|
91
83
|
/>
|
|
92
|
-
</
|
|
93
|
-
<
|
|
84
|
+
</ToolsPanelItem>
|
|
85
|
+
<ToolsPanelItem
|
|
86
|
+
style={ { gridColumn: 'span 1' } }
|
|
94
87
|
label={ __( 'Height' ) }
|
|
95
88
|
isShownByDefault={ isShownByDefault }
|
|
96
89
|
hasValue={ () => height !== '' }
|
|
@@ -107,7 +100,7 @@ export default function WidthHeightTool( {
|
|
|
107
100
|
onChange={ onDimensionChange( 'height' ) }
|
|
108
101
|
size="__unstable-large"
|
|
109
102
|
/>
|
|
110
|
-
</
|
|
103
|
+
</ToolsPanelItem>
|
|
111
104
|
</>
|
|
112
105
|
);
|
|
113
106
|
}
|
|
@@ -61,16 +61,29 @@ function GridItemResizerInner( {
|
|
|
61
61
|
const blockClientRect = blockElement.getBoundingClientRect();
|
|
62
62
|
const rootBlockClientRect =
|
|
63
63
|
rootBlockElement.getBoundingClientRect();
|
|
64
|
+
|
|
65
|
+
const topAvailable = blockClientRect.top > rootBlockClientRect.top;
|
|
66
|
+
const bottomAvailable =
|
|
67
|
+
blockClientRect.bottom < rootBlockClientRect.bottom;
|
|
68
|
+
const leftAvailable =
|
|
69
|
+
blockClientRect.left > rootBlockClientRect.left;
|
|
70
|
+
const rightAvailable =
|
|
71
|
+
blockClientRect.right < rootBlockClientRect.right;
|
|
72
|
+
|
|
64
73
|
setEnableSide( {
|
|
65
|
-
top:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
top: !! isManualGrid
|
|
75
|
+
? topAvailable
|
|
76
|
+
: ! bottomAvailable && topAvailable,
|
|
77
|
+
bottom: bottomAvailable,
|
|
78
|
+
left: !! isManualGrid
|
|
79
|
+
? leftAvailable
|
|
80
|
+
: ! rightAvailable && leftAvailable,
|
|
81
|
+
right: rightAvailable,
|
|
69
82
|
} );
|
|
70
83
|
} );
|
|
71
84
|
observer.observe( blockElement );
|
|
72
85
|
return () => observer.disconnect();
|
|
73
|
-
}, [ blockElement, rootBlockElement ] );
|
|
86
|
+
}, [ blockElement, rootBlockElement, isManualGrid ] );
|
|
74
87
|
|
|
75
88
|
const justification = {
|
|
76
89
|
right: 'left',
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import Cropper from 'react-easy-crop';
|
|
5
4
|
import clsx from 'clsx';
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -9,12 +8,11 @@ import clsx from 'clsx';
|
|
|
9
8
|
*/
|
|
10
9
|
import { Spinner } from '@wordpress/components';
|
|
11
10
|
import { useResizeObserver } from '@wordpress/compose';
|
|
11
|
+
import { ImageCropper as ImageCropperComponent } from '@wordpress/image-cropper';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Internal dependencies
|
|
15
15
|
*/
|
|
16
|
-
import { MIN_ZOOM, MAX_ZOOM } from './constants';
|
|
17
|
-
|
|
18
16
|
import { useImageEditingContext } from './context';
|
|
19
17
|
|
|
20
18
|
export default function ImageCropper( {
|
|
@@ -25,17 +23,7 @@ export default function ImageCropper( {
|
|
|
25
23
|
naturalWidth,
|
|
26
24
|
borderProps,
|
|
27
25
|
} ) {
|
|
28
|
-
const {
|
|
29
|
-
isInProgress,
|
|
30
|
-
editedUrl,
|
|
31
|
-
position,
|
|
32
|
-
zoom,
|
|
33
|
-
aspect,
|
|
34
|
-
setPosition,
|
|
35
|
-
setCrop,
|
|
36
|
-
setZoom,
|
|
37
|
-
rotation,
|
|
38
|
-
} = useImageEditingContext();
|
|
26
|
+
const { isInProgress, editedUrl, rotation } = useImageEditingContext();
|
|
39
27
|
const [ contentResizeListener, { width: clientWidth } ] =
|
|
40
28
|
useResizeObserver();
|
|
41
29
|
|
|
@@ -60,24 +48,7 @@ export default function ImageCropper( {
|
|
|
60
48
|
height: editedHeight,
|
|
61
49
|
} }
|
|
62
50
|
>
|
|
63
|
-
<
|
|
64
|
-
image={ editedUrl || url }
|
|
65
|
-
disabled={ isInProgress }
|
|
66
|
-
minZoom={ MIN_ZOOM / 100 }
|
|
67
|
-
maxZoom={ MAX_ZOOM / 100 }
|
|
68
|
-
crop={ position }
|
|
69
|
-
zoom={ zoom / 100 }
|
|
70
|
-
aspect={ aspect }
|
|
71
|
-
onCropChange={ ( pos ) => {
|
|
72
|
-
setPosition( pos );
|
|
73
|
-
} }
|
|
74
|
-
onCropComplete={ ( newCropPercent ) => {
|
|
75
|
-
setCrop( newCropPercent );
|
|
76
|
-
} }
|
|
77
|
-
onZoomChange={ ( newZoom ) => {
|
|
78
|
-
setZoom( newZoom * 100 );
|
|
79
|
-
} }
|
|
80
|
-
/>
|
|
51
|
+
<ImageCropperComponent src={ editedUrl || url } />
|
|
81
52
|
{ isInProgress && <Spinner /> }
|
|
82
53
|
</div>
|
|
83
54
|
);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { ToolbarGroup, ToolbarItem } from '@wordpress/components';
|
|
5
|
+
import { ImageCropperProvider } from '@wordpress/image-cropper';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Internal dependencies
|
|
@@ -26,36 +27,40 @@ export default function ImageEditor( {
|
|
|
26
27
|
borderProps,
|
|
27
28
|
} ) {
|
|
28
29
|
return (
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
naturalWidth={ naturalWidth }
|
|
33
|
-
naturalHeight={ naturalHeight }
|
|
34
|
-
onSaveImage={ onSaveImage }
|
|
35
|
-
onFinishEditing={ onFinishEditing }
|
|
36
|
-
>
|
|
37
|
-
<Cropper
|
|
38
|
-
borderProps={ borderProps }
|
|
30
|
+
<ImageCropperProvider>
|
|
31
|
+
<ImageEditingProvider
|
|
32
|
+
id={ id }
|
|
39
33
|
url={ url }
|
|
40
|
-
width={ width }
|
|
41
|
-
height={ height }
|
|
42
|
-
naturalHeight={ naturalHeight }
|
|
43
34
|
naturalWidth={ naturalWidth }
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
35
|
+
naturalHeight={ naturalHeight }
|
|
36
|
+
onSaveImage={ onSaveImage }
|
|
37
|
+
onFinishEditing={ onFinishEditing }
|
|
38
|
+
>
|
|
39
|
+
<Cropper
|
|
40
|
+
borderProps={ borderProps }
|
|
41
|
+
url={ url }
|
|
42
|
+
width={ width }
|
|
43
|
+
height={ height }
|
|
44
|
+
naturalHeight={ naturalHeight }
|
|
45
|
+
naturalWidth={ naturalWidth }
|
|
46
|
+
/>
|
|
47
|
+
<BlockControls>
|
|
48
|
+
<ToolbarGroup>
|
|
49
|
+
<ZoomDropdown />
|
|
50
|
+
<ToolbarItem>
|
|
51
|
+
{ ( toggleProps ) => (
|
|
52
|
+
<AspectRatioDropdown
|
|
53
|
+
toggleProps={ toggleProps }
|
|
54
|
+
/>
|
|
55
|
+
) }
|
|
56
|
+
</ToolbarItem>
|
|
57
|
+
<RotationButton />
|
|
58
|
+
</ToolbarGroup>
|
|
59
|
+
<ToolbarGroup>
|
|
60
|
+
<FormControls />
|
|
61
|
+
</ToolbarGroup>
|
|
62
|
+
</BlockControls>
|
|
63
|
+
</ImageEditingProvider>
|
|
64
|
+
</ImageCropperProvider>
|
|
60
65
|
);
|
|
61
66
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { useCallback, useMemo, useState } from '@wordpress/element';
|
|
4
|
+
import { useCallback, useEffect, useMemo, useState } from '@wordpress/element';
|
|
5
5
|
import { applyFilters } from '@wordpress/hooks';
|
|
6
|
+
import { useImageCropper } from '@wordpress/image-cropper';
|
|
6
7
|
|
|
7
8
|
export default function useTransformImage( {
|
|
8
9
|
url,
|
|
@@ -10,30 +11,63 @@ export default function useTransformImage( {
|
|
|
10
11
|
naturalHeight,
|
|
11
12
|
} ) {
|
|
12
13
|
const [ editedUrl, setEditedUrl ] = useState();
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
const { cropperState, setCropperState } = useImageCropper();
|
|
15
|
+
const { zoom, aspectRatio, crop, croppedArea } = cropperState;
|
|
16
|
+
|
|
17
|
+
const setZoom = useCallback(
|
|
18
|
+
( newZoom ) => {
|
|
19
|
+
setCropperState( { zoom: newZoom } );
|
|
20
|
+
},
|
|
21
|
+
[ setCropperState ]
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const setAspectRatio = useCallback(
|
|
25
|
+
( newAspect ) => {
|
|
26
|
+
setCropperState( { aspectRatio: newAspect } );
|
|
27
|
+
},
|
|
28
|
+
[ setCropperState ]
|
|
29
|
+
);
|
|
19
30
|
|
|
31
|
+
const defaultAspect = naturalWidth / naturalHeight;
|
|
32
|
+
const rotatedAspect = naturalHeight / naturalWidth;
|
|
33
|
+
|
|
34
|
+
// Initialize aspect ratio on mount or when defaultAspect changes
|
|
35
|
+
useEffect( () => {
|
|
36
|
+
setAspectRatio( defaultAspect );
|
|
37
|
+
}, [] ); // eslint-disable-line react-hooks/exhaustive-deps
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* rotateClockwise rotates the image by 90° clockwise by drawing the original image onto a canvas with rotation applied,
|
|
41
|
+
* then saves it as a new blob URL (editedUrl).
|
|
42
|
+
* This creates a new rotated image file, bypassing the image-cropper’s CSS transform rotation.
|
|
43
|
+
* It's a bespoke solution to ensure that the rotated image fills the content width.
|
|
44
|
+
*/
|
|
45
|
+
const [ internalRotation, setInternalRotation ] = useState( 0 );
|
|
20
46
|
const rotateClockwise = useCallback( () => {
|
|
21
|
-
const angle = (
|
|
47
|
+
const angle = ( internalRotation + 90 ) % 360;
|
|
22
48
|
|
|
23
49
|
let naturalAspectRatio = defaultAspect;
|
|
50
|
+
const isDefaultAspect =
|
|
51
|
+
defaultAspect === aspectRatio || rotatedAspect === aspectRatio;
|
|
52
|
+
const shouldResetAspect = zoom !== 1 || ! isDefaultAspect;
|
|
24
53
|
|
|
25
|
-
if (
|
|
54
|
+
if ( internalRotation % 180 === 90 ) {
|
|
26
55
|
naturalAspectRatio = 1 / defaultAspect;
|
|
27
56
|
}
|
|
28
57
|
|
|
29
58
|
if ( angle === 0 ) {
|
|
30
59
|
setEditedUrl();
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
60
|
+
setInternalRotation( angle );
|
|
61
|
+
const newAspectRatio = shouldResetAspect
|
|
62
|
+
? aspectRatio
|
|
63
|
+
: defaultAspect;
|
|
64
|
+
setCropperState( {
|
|
65
|
+
aspectRatio: newAspectRatio,
|
|
66
|
+
crop: {
|
|
67
|
+
x: -( crop.y * naturalAspectRatio ),
|
|
68
|
+
y: crop.x * naturalAspectRatio,
|
|
69
|
+
},
|
|
70
|
+
} );
|
|
37
71
|
return;
|
|
38
72
|
}
|
|
39
73
|
|
|
@@ -67,12 +101,17 @@ export default function useTransformImage( {
|
|
|
67
101
|
|
|
68
102
|
canvas.toBlob( ( blob ) => {
|
|
69
103
|
setEditedUrl( URL.createObjectURL( blob ) );
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
104
|
+
setInternalRotation( angle );
|
|
105
|
+
const newAspectRatio = shouldResetAspect
|
|
106
|
+
? aspectRatio
|
|
107
|
+
: canvas.width / canvas.height;
|
|
108
|
+
setCropperState( {
|
|
109
|
+
aspectRatio: newAspectRatio,
|
|
110
|
+
crop: {
|
|
111
|
+
x: -( crop.y * naturalAspectRatio ),
|
|
112
|
+
y: crop.x * naturalAspectRatio,
|
|
113
|
+
},
|
|
114
|
+
} );
|
|
76
115
|
} );
|
|
77
116
|
}
|
|
78
117
|
|
|
@@ -88,33 +127,40 @@ export default function useTransformImage( {
|
|
|
88
127
|
if ( typeof imgCrossOrigin === 'string' ) {
|
|
89
128
|
el.crossOrigin = imgCrossOrigin;
|
|
90
129
|
}
|
|
91
|
-
}, [
|
|
130
|
+
}, [
|
|
131
|
+
internalRotation,
|
|
132
|
+
defaultAspect,
|
|
133
|
+
url,
|
|
134
|
+
setCropperState,
|
|
135
|
+
crop,
|
|
136
|
+
zoom,
|
|
137
|
+
aspectRatio,
|
|
138
|
+
rotatedAspect,
|
|
139
|
+
setInternalRotation,
|
|
140
|
+
] );
|
|
92
141
|
|
|
93
142
|
return useMemo(
|
|
94
143
|
() => ( {
|
|
95
144
|
editedUrl,
|
|
96
145
|
setEditedUrl,
|
|
97
|
-
crop,
|
|
98
|
-
setCrop,
|
|
99
|
-
position,
|
|
100
|
-
setPosition,
|
|
146
|
+
crop: croppedArea,
|
|
101
147
|
zoom,
|
|
102
148
|
setZoom,
|
|
103
|
-
rotation,
|
|
104
|
-
setRotation,
|
|
149
|
+
rotation: internalRotation,
|
|
105
150
|
rotateClockwise,
|
|
106
|
-
aspect,
|
|
107
|
-
setAspect,
|
|
151
|
+
aspect: aspectRatio,
|
|
152
|
+
setAspect: setAspectRatio,
|
|
108
153
|
defaultAspect,
|
|
109
154
|
} ),
|
|
110
155
|
[
|
|
111
156
|
editedUrl,
|
|
112
|
-
|
|
113
|
-
position,
|
|
157
|
+
croppedArea,
|
|
114
158
|
zoom,
|
|
115
|
-
|
|
159
|
+
setZoom,
|
|
160
|
+
internalRotation,
|
|
116
161
|
rotateClockwise,
|
|
117
|
-
|
|
162
|
+
aspectRatio,
|
|
163
|
+
setAspectRatio,
|
|
118
164
|
defaultAspect,
|
|
119
165
|
]
|
|
120
166
|
);
|
|
@@ -39,8 +39,8 @@ export default function ZoomDropdown() {
|
|
|
39
39
|
label={ __( 'Zoom' ) }
|
|
40
40
|
min={ MIN_ZOOM }
|
|
41
41
|
max={ MAX_ZOOM }
|
|
42
|
-
value={ Math.round( zoom ) }
|
|
43
|
-
onChange={ setZoom }
|
|
42
|
+
value={ Math.round( zoom * 100 ) }
|
|
43
|
+
onChange={ ( newZoom ) => setZoom( newZoom / 100 ) }
|
|
44
44
|
/>
|
|
45
45
|
</DropdownContentWrapper>
|
|
46
46
|
) }
|
package/src/components/index.js
CHANGED
|
@@ -11,6 +11,11 @@ export {
|
|
|
11
11
|
BlockAlignmentControl,
|
|
12
12
|
BlockAlignmentToolbar,
|
|
13
13
|
} from './block-alignment-control';
|
|
14
|
+
export {
|
|
15
|
+
BlockBindingsAttributeControl,
|
|
16
|
+
BlockBindingsSourceFieldsList,
|
|
17
|
+
useBlockBindingsUtils,
|
|
18
|
+
} from './block-bindings';
|
|
14
19
|
export { default as __experimentalBlockFullHeightAligmentControl } from './block-full-height-alignment-control';
|
|
15
20
|
export { default as __experimentalBlockAlignmentMatrixControl } from './block-alignment-matrix-control';
|
|
16
21
|
export { default as BlockBreadcrumb } from './block-breadcrumb';
|
|
@@ -107,7 +112,6 @@ export {
|
|
|
107
112
|
|
|
108
113
|
export { default as __unstableBlockSettingsMenuFirstItem } from './block-settings-menu/block-settings-menu-first-item';
|
|
109
114
|
export { default as __unstableBlockToolbarLastItem } from './block-toolbar/block-toolbar-last-item';
|
|
110
|
-
export { default as __unstableBlockNameContext } from './block-toolbar/block-name-context';
|
|
111
115
|
export { default as __unstableInserterMenuExtension } from './inserter-menu-extension';
|
|
112
116
|
export { default as __experimentalPreviewOptions } from './preview-options';
|
|
113
117
|
export { default as __experimentalUseResizeCanvas } from './use-resize-canvas';
|
|
@@ -201,6 +201,8 @@ function useInsertionPoint( {
|
|
|
201
201
|
onSelect,
|
|
202
202
|
shouldFocusBlock,
|
|
203
203
|
selectBlockOnInsert,
|
|
204
|
+
setLastFocus,
|
|
205
|
+
registry,
|
|
204
206
|
]
|
|
205
207
|
);
|
|
206
208
|
|
|
@@ -234,6 +236,7 @@ function useInsertionPoint( {
|
|
|
234
236
|
hideInsertionPoint,
|
|
235
237
|
destinationRootClientId,
|
|
236
238
|
destinationIndex,
|
|
239
|
+
registry,
|
|
237
240
|
]
|
|
238
241
|
);
|
|
239
242
|
|
|
@@ -383,7 +383,7 @@ $block-inserter-tabs-height: 44px;
|
|
|
383
383
|
left: 0;
|
|
384
384
|
bottom: 0;
|
|
385
385
|
width: $sidebar-width;
|
|
386
|
-
padding: $grid-unit-30 $grid-unit-
|
|
386
|
+
padding: $grid-unit-30 $grid-unit-30 $grid-unit-30;
|
|
387
387
|
overflow-x: visible;
|
|
388
388
|
overflow-y: auto;
|
|
389
389
|
|
|
@@ -21,14 +21,15 @@ const InserterDraggableBlocks = ( {
|
|
|
21
21
|
children,
|
|
22
22
|
pattern,
|
|
23
23
|
} ) => {
|
|
24
|
+
const blockName = blocks.length === 1 ? blocks[ 0 ].name : undefined;
|
|
24
25
|
const blockTypeIcon = useSelect(
|
|
25
26
|
( select ) => {
|
|
26
|
-
const { getBlockType } = select( blocksStore );
|
|
27
27
|
return (
|
|
28
|
-
|
|
28
|
+
blockName &&
|
|
29
|
+
select( blocksStore ).getBlockType( blockName )?.icon
|
|
29
30
|
);
|
|
30
31
|
},
|
|
31
|
-
[
|
|
32
|
+
[ blockName ]
|
|
32
33
|
);
|
|
33
34
|
|
|
34
35
|
const { startDragging, stopDragging } = unlock(
|
|
@@ -57,13 +58,23 @@ const InserterDraggableBlocks = ( {
|
|
|
57
58
|
transferData={ { type: 'inserter', blocks: draggableBlocks } }
|
|
58
59
|
onDragStart={ ( event ) => {
|
|
59
60
|
startDragging();
|
|
61
|
+
const addedTypes = new Set();
|
|
60
62
|
for ( const block of draggableBlocks ) {
|
|
61
63
|
const type = `wp-block:${ block.name }`;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
/*
|
|
65
|
+
* Only add each block type once to avoid DataTransferItemList::add `NotSupportedError`
|
|
66
|
+
* when patterns contain multiple blocks of the same type.
|
|
67
|
+
*/
|
|
68
|
+
if ( ! addedTypes.has( type ) ) {
|
|
69
|
+
/*
|
|
70
|
+
* This will fill in the dataTransfer.types array so that
|
|
71
|
+
* the drop zone can check if the draggable is eligible.
|
|
72
|
+
* Unfortuantely, on drag start, we don't have access to the
|
|
73
|
+
* actual data, only the data keys/types.
|
|
74
|
+
*/
|
|
75
|
+
event.dataTransfer.items.add( '', type );
|
|
76
|
+
addedTypes.add( type );
|
|
77
|
+
}
|
|
67
78
|
}
|
|
68
79
|
} }
|
|
69
80
|
onDragEnd={ () => {
|