@wordpress/block-editor 11.3.5 → 11.3.7
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 +11 -1
- package/build/components/block-inspector/index.js +11 -10
- package/build/components/block-inspector/index.js.map +1 -1
- package/build/components/block-inspector/useBlockInspectorAnimationSettings.js +46 -0
- package/build/components/block-inspector/useBlockInspectorAnimationSettings.js.map +1 -0
- package/build/components/block-settings-menu/block-settings-dropdown.js +2 -2
- package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
- package/build/components/inserter/index.js +29 -17
- package/build/components/inserter/index.js.map +1 -1
- package/build/components/inserter/media-tab/hooks.js +10 -11
- package/build/components/inserter/media-tab/hooks.js.map +1 -1
- package/build/components/inserter/media-tab/media-list.js +5 -108
- package/build/components/inserter/media-tab/media-list.js.map +1 -1
- package/build/components/inserter/media-tab/media-preview.js +242 -0
- package/build/components/inserter/media-tab/media-preview.js.map +1 -0
- package/build/components/inserter/menu.js +4 -7
- package/build/components/inserter/menu.js.map +1 -1
- package/build/components/inserter/quick-inserter.js +4 -2
- package/build/components/inserter/quick-inserter.js.map +1 -1
- package/build/components/inserter/search-results.js +10 -3
- package/build/components/inserter/search-results.js.map +1 -1
- package/build/components/link-control/index.js +17 -44
- package/build/components/link-control/index.js.map +1 -1
- package/build/components/off-canvas-editor/appender.js +28 -3
- package/build/components/off-canvas-editor/appender.js.map +1 -1
- package/build/components/off-canvas-editor/block-contents.js +1 -1
- package/build/components/off-canvas-editor/block-contents.js.map +1 -1
- package/build/components/off-canvas-editor/branch.js +5 -3
- package/build/components/off-canvas-editor/branch.js.map +1 -1
- package/build/components/off-canvas-editor/index.js +4 -1
- package/build/components/off-canvas-editor/index.js.map +1 -1
- package/build/private-apis.js +4 -1
- package/build/private-apis.js.map +1 -1
- package/build/store/actions.js +28 -14
- package/build/store/actions.js.map +1 -1
- package/build/store/defaults.js +28 -1
- package/build/store/defaults.js.map +1 -1
- package/build/store/selectors.js +1 -1
- package/build/store/selectors.js.map +1 -1
- package/build-module/components/block-inspector/index.js +9 -9
- package/build-module/components/block-inspector/index.js.map +1 -1
- package/build-module/components/block-inspector/useBlockInspectorAnimationSettings.js +37 -0
- package/build-module/components/block-inspector/useBlockInspectorAnimationSettings.js.map +1 -0
- package/build-module/components/block-settings-menu/block-settings-dropdown.js +2 -2
- package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
- package/build-module/components/inserter/index.js +28 -16
- package/build-module/components/inserter/index.js.map +1 -1
- package/build-module/components/inserter/media-tab/hooks.js +10 -11
- package/build-module/components/inserter/media-tab/hooks.js.map +1 -1
- package/build-module/components/inserter/media-tab/media-list.js +6 -105
- package/build-module/components/inserter/media-tab/media-list.js.map +1 -1
- package/build-module/components/inserter/media-tab/media-preview.js +222 -0
- package/build-module/components/inserter/media-tab/media-preview.js.map +1 -0
- package/build-module/components/inserter/menu.js +4 -7
- package/build-module/components/inserter/menu.js.map +1 -1
- package/build-module/components/inserter/quick-inserter.js +4 -2
- package/build-module/components/inserter/quick-inserter.js.map +1 -1
- package/build-module/components/inserter/search-results.js +10 -3
- package/build-module/components/inserter/search-results.js.map +1 -1
- package/build-module/components/link-control/index.js +16 -44
- package/build-module/components/link-control/index.js.map +1 -1
- package/build-module/components/off-canvas-editor/appender.js +28 -4
- package/build-module/components/off-canvas-editor/appender.js.map +1 -1
- package/build-module/components/off-canvas-editor/block-contents.js +1 -1
- package/build-module/components/off-canvas-editor/block-contents.js.map +1 -1
- package/build-module/components/off-canvas-editor/branch.js +5 -3
- package/build-module/components/off-canvas-editor/branch.js.map +1 -1
- package/build-module/components/off-canvas-editor/index.js +4 -1
- package/build-module/components/off-canvas-editor/index.js.map +1 -1
- package/build-module/private-apis.js +3 -1
- package/build-module/private-apis.js.map +1 -1
- package/build-module/store/actions.js +28 -14
- package/build-module/store/actions.js.map +1 -1
- package/build-module/store/defaults.js +28 -1
- package/build-module/store/defaults.js.map +1 -1
- package/build-module/store/selectors.js +1 -1
- package/build-module/store/selectors.js.map +1 -1
- package/build-style/style-rtl.css +46 -8
- package/build-style/style.css +46 -8
- package/package.json +4 -4
- package/src/components/block-inspector/index.js +11 -14
- package/src/components/block-inspector/useBlockInspectorAnimationSettings.js +53 -0
- package/src/components/block-settings-menu/block-settings-dropdown.js +4 -1
- package/src/components/inserter/index.js +30 -11
- package/src/components/inserter/media-tab/hooks.js +9 -8
- package/src/components/inserter/media-tab/media-list.js +3 -122
- package/src/components/inserter/media-tab/media-preview.js +268 -0
- package/src/components/inserter/menu.js +14 -20
- package/src/components/inserter/quick-inserter.js +2 -0
- package/src/components/inserter/search-results.js +7 -1
- package/src/components/inserter/style.scss +25 -0
- package/src/components/link-control/index.js +23 -58
- package/src/components/link-control/style.scss +23 -7
- package/src/components/link-control/test/index.js +5 -134
- package/src/components/media-replace-flow/test/index.js +1 -1
- package/src/components/off-canvas-editor/appender.js +30 -4
- package/src/components/off-canvas-editor/block-contents.js +1 -1
- package/src/components/off-canvas-editor/branch.js +3 -1
- package/src/components/off-canvas-editor/index.js +3 -0
- package/src/components/spacing-sizes-control/style.scss +1 -1
- package/src/private-apis.js +2 -0
- package/src/store/actions.js +16 -6
- package/src/store/defaults.js +14 -1
- package/src/store/selectors.js +4 -1
- package/src/store/test/actions.js +4 -2
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import classnames from 'classnames';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import {
|
|
10
|
+
__unstableCompositeItem as CompositeItem,
|
|
11
|
+
Tooltip,
|
|
12
|
+
DropdownMenu,
|
|
13
|
+
MenuGroup,
|
|
14
|
+
MenuItem,
|
|
15
|
+
Spinner,
|
|
16
|
+
Modal,
|
|
17
|
+
Flex,
|
|
18
|
+
FlexItem,
|
|
19
|
+
Button,
|
|
20
|
+
__experimentalVStack as VStack,
|
|
21
|
+
} from '@wordpress/components';
|
|
22
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
23
|
+
import { useMemo, useCallback, useState } from '@wordpress/element';
|
|
24
|
+
import { cloneBlock } from '@wordpress/blocks';
|
|
25
|
+
import { moreVertical, external } from '@wordpress/icons';
|
|
26
|
+
import { useSelect, useDispatch } from '@wordpress/data';
|
|
27
|
+
import { store as noticesStore } from '@wordpress/notices';
|
|
28
|
+
import { isBlobURL } from '@wordpress/blob';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Internal dependencies
|
|
32
|
+
*/
|
|
33
|
+
import InserterDraggableBlocks from '../../inserter-draggable-blocks';
|
|
34
|
+
import { getBlockAndPreviewFromMedia } from './utils';
|
|
35
|
+
import { store as blockEditorStore } from '../../../store';
|
|
36
|
+
|
|
37
|
+
const ALLOWED_MEDIA_TYPES = [ 'image' ];
|
|
38
|
+
const MAXIMUM_TITLE_LENGTH = 25;
|
|
39
|
+
const MEDIA_OPTIONS_POPOVER_PROPS = {
|
|
40
|
+
position: 'bottom left',
|
|
41
|
+
className:
|
|
42
|
+
'block-editor-inserter__media-list__item-preview-options__popover',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
function MediaPreviewOptions( { category, media } ) {
|
|
46
|
+
if ( ! category.getReportUrl ) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const reportUrl = category.getReportUrl( media );
|
|
50
|
+
return (
|
|
51
|
+
<DropdownMenu
|
|
52
|
+
className="block-editor-inserter__media-list__item-preview-options"
|
|
53
|
+
label={ __( 'Options' ) }
|
|
54
|
+
popoverProps={ MEDIA_OPTIONS_POPOVER_PROPS }
|
|
55
|
+
icon={ moreVertical }
|
|
56
|
+
>
|
|
57
|
+
{ () => (
|
|
58
|
+
<MenuGroup>
|
|
59
|
+
<MenuItem
|
|
60
|
+
onClick={ () =>
|
|
61
|
+
window.open( reportUrl, '_blank' ).focus()
|
|
62
|
+
}
|
|
63
|
+
icon={ external }
|
|
64
|
+
>
|
|
65
|
+
{ sprintf(
|
|
66
|
+
/* translators: %s: The media type to report e.g: "image", "video", "audio" */
|
|
67
|
+
__( 'Report %s' ),
|
|
68
|
+
category.mediaType
|
|
69
|
+
) }
|
|
70
|
+
</MenuItem>
|
|
71
|
+
</MenuGroup>
|
|
72
|
+
) }
|
|
73
|
+
</DropdownMenu>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function InsertExternalImageModal( { onClose, onSubmit } ) {
|
|
78
|
+
return (
|
|
79
|
+
<Modal
|
|
80
|
+
title={ __( 'Insert external image' ) }
|
|
81
|
+
onRequestClose={ onClose }
|
|
82
|
+
className="block-editor-inserter-media-tab-media-preview-inserter-external-image-modal"
|
|
83
|
+
>
|
|
84
|
+
<VStack spacing={ 3 }>
|
|
85
|
+
<p>
|
|
86
|
+
{ __(
|
|
87
|
+
'This image cannot be uploaded to your Media Library, but it can still be inserted as an external image.'
|
|
88
|
+
) }
|
|
89
|
+
</p>
|
|
90
|
+
<p>
|
|
91
|
+
{ __(
|
|
92
|
+
'External images can be removed by the external provider without warning and could even have legal compliance issues related to privacy legislation.'
|
|
93
|
+
) }
|
|
94
|
+
</p>
|
|
95
|
+
</VStack>
|
|
96
|
+
<Flex
|
|
97
|
+
className="block-editor-block-lock-modal__actions"
|
|
98
|
+
justify="flex-end"
|
|
99
|
+
expanded={ false }
|
|
100
|
+
>
|
|
101
|
+
<FlexItem>
|
|
102
|
+
<Button variant="tertiary" onClick={ onClose }>
|
|
103
|
+
{ __( 'Cancel' ) }
|
|
104
|
+
</Button>
|
|
105
|
+
</FlexItem>
|
|
106
|
+
<FlexItem>
|
|
107
|
+
<Button variant="primary" onClick={ onSubmit }>
|
|
108
|
+
{ __( 'Insert' ) }
|
|
109
|
+
</Button>
|
|
110
|
+
</FlexItem>
|
|
111
|
+
</Flex>
|
|
112
|
+
</Modal>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function MediaPreview( { media, onClick, composite, category } ) {
|
|
117
|
+
const [ showExternalUploadModal, setShowExternalUploadModal ] =
|
|
118
|
+
useState( false );
|
|
119
|
+
const [ isHovered, setIsHovered ] = useState( false );
|
|
120
|
+
const [ isInserting, setIsInserting ] = useState( false );
|
|
121
|
+
const [ block, preview ] = useMemo(
|
|
122
|
+
() => getBlockAndPreviewFromMedia( media, category.mediaType ),
|
|
123
|
+
[ media, category.mediaType ]
|
|
124
|
+
);
|
|
125
|
+
const { createErrorNotice, createSuccessNotice } =
|
|
126
|
+
useDispatch( noticesStore );
|
|
127
|
+
const mediaUpload = useSelect(
|
|
128
|
+
( select ) => select( blockEditorStore ).getSettings().mediaUpload,
|
|
129
|
+
[]
|
|
130
|
+
);
|
|
131
|
+
const onMediaInsert = useCallback(
|
|
132
|
+
( previewBlock ) => {
|
|
133
|
+
// Prevent multiple uploads when we're in the process of inserting.
|
|
134
|
+
if ( isInserting ) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const clonedBlock = cloneBlock( previewBlock );
|
|
138
|
+
const { id, url, caption } = clonedBlock.attributes;
|
|
139
|
+
// Media item already exists in library, so just insert it.
|
|
140
|
+
if ( !! id ) {
|
|
141
|
+
onClick( clonedBlock );
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
setIsInserting( true );
|
|
145
|
+
// Media item does not exist in library, so try to upload it.
|
|
146
|
+
// Fist fetch the image data. This may fail if the image host
|
|
147
|
+
// doesn't allow CORS with the domain.
|
|
148
|
+
// If this happens, we insert the image block using the external
|
|
149
|
+
// URL and let the user know about the possible implications.
|
|
150
|
+
window
|
|
151
|
+
.fetch( url )
|
|
152
|
+
.then( ( response ) => response.blob() )
|
|
153
|
+
.then( ( blob ) => {
|
|
154
|
+
mediaUpload( {
|
|
155
|
+
filesList: [ blob ],
|
|
156
|
+
additionalData: { caption },
|
|
157
|
+
onFileChange( [ img ] ) {
|
|
158
|
+
if ( isBlobURL( img.url ) ) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
onClick( {
|
|
162
|
+
...clonedBlock,
|
|
163
|
+
attributes: {
|
|
164
|
+
...clonedBlock.attributes,
|
|
165
|
+
id: img.id,
|
|
166
|
+
url: img.url,
|
|
167
|
+
},
|
|
168
|
+
} );
|
|
169
|
+
createSuccessNotice(
|
|
170
|
+
__( 'Image uploaded and inserted.' ),
|
|
171
|
+
{ type: 'snackbar' }
|
|
172
|
+
);
|
|
173
|
+
setIsInserting( false );
|
|
174
|
+
},
|
|
175
|
+
allowedTypes: ALLOWED_MEDIA_TYPES,
|
|
176
|
+
onError( message ) {
|
|
177
|
+
createErrorNotice( message, { type: 'snackbar' } );
|
|
178
|
+
setIsInserting( false );
|
|
179
|
+
},
|
|
180
|
+
} );
|
|
181
|
+
} )
|
|
182
|
+
.catch( () => {
|
|
183
|
+
setShowExternalUploadModal( true );
|
|
184
|
+
setIsInserting( false );
|
|
185
|
+
} );
|
|
186
|
+
},
|
|
187
|
+
[
|
|
188
|
+
isInserting,
|
|
189
|
+
onClick,
|
|
190
|
+
mediaUpload,
|
|
191
|
+
createErrorNotice,
|
|
192
|
+
createSuccessNotice,
|
|
193
|
+
]
|
|
194
|
+
);
|
|
195
|
+
const title = media.title?.rendered || media.title;
|
|
196
|
+
let truncatedTitle;
|
|
197
|
+
if ( title.length > MAXIMUM_TITLE_LENGTH ) {
|
|
198
|
+
const omission = '...';
|
|
199
|
+
truncatedTitle =
|
|
200
|
+
title.slice( 0, MAXIMUM_TITLE_LENGTH - omission.length ) + omission;
|
|
201
|
+
}
|
|
202
|
+
const onMouseEnter = useCallback( () => setIsHovered( true ), [] );
|
|
203
|
+
const onMouseLeave = useCallback( () => setIsHovered( false ), [] );
|
|
204
|
+
return (
|
|
205
|
+
<>
|
|
206
|
+
<InserterDraggableBlocks isEnabled={ true } blocks={ [ block ] }>
|
|
207
|
+
{ ( { draggable, onDragStart, onDragEnd } ) => (
|
|
208
|
+
<div
|
|
209
|
+
className={ classnames(
|
|
210
|
+
'block-editor-inserter__media-list__list-item',
|
|
211
|
+
{
|
|
212
|
+
'is-hovered': isHovered,
|
|
213
|
+
}
|
|
214
|
+
) }
|
|
215
|
+
draggable={ draggable }
|
|
216
|
+
onDragStart={ onDragStart }
|
|
217
|
+
onDragEnd={ onDragEnd }
|
|
218
|
+
>
|
|
219
|
+
<Tooltip text={ truncatedTitle || title }>
|
|
220
|
+
{ /* Adding `is-hovered` class to the wrapper element is needed
|
|
221
|
+
because the options Popover is rendered outside of this node. */ }
|
|
222
|
+
<div
|
|
223
|
+
onMouseEnter={ onMouseEnter }
|
|
224
|
+
onMouseLeave={ onMouseLeave }
|
|
225
|
+
>
|
|
226
|
+
<CompositeItem
|
|
227
|
+
role="option"
|
|
228
|
+
as="div"
|
|
229
|
+
{ ...composite }
|
|
230
|
+
className="block-editor-inserter__media-list__item"
|
|
231
|
+
onClick={ () => onMediaInsert( block ) }
|
|
232
|
+
aria-label={ title }
|
|
233
|
+
>
|
|
234
|
+
<div className="block-editor-inserter__media-list__item-preview">
|
|
235
|
+
{ preview }
|
|
236
|
+
{ isInserting && (
|
|
237
|
+
<div className="block-editor-inserter__media-list__item-preview-spinner">
|
|
238
|
+
<Spinner />
|
|
239
|
+
</div>
|
|
240
|
+
) }
|
|
241
|
+
</div>
|
|
242
|
+
</CompositeItem>
|
|
243
|
+
{ ! isInserting && (
|
|
244
|
+
<MediaPreviewOptions
|
|
245
|
+
category={ category }
|
|
246
|
+
media={ media }
|
|
247
|
+
/>
|
|
248
|
+
) }
|
|
249
|
+
</div>
|
|
250
|
+
</Tooltip>
|
|
251
|
+
</div>
|
|
252
|
+
) }
|
|
253
|
+
</InserterDraggableBlocks>
|
|
254
|
+
{ showExternalUploadModal && (
|
|
255
|
+
<InsertExternalImageModal
|
|
256
|
+
onClose={ () => setShowExternalUploadModal( false ) }
|
|
257
|
+
onSubmit={ () => {
|
|
258
|
+
onClick( cloneBlock( block ) );
|
|
259
|
+
createSuccessNotice( __( 'Image inserted.' ), {
|
|
260
|
+
type: 'snackbar',
|
|
261
|
+
} );
|
|
262
|
+
setShowExternalUploadModal( false );
|
|
263
|
+
} }
|
|
264
|
+
/>
|
|
265
|
+
) }
|
|
266
|
+
</>
|
|
267
|
+
);
|
|
268
|
+
}
|
|
@@ -67,25 +67,19 @@ function InserterMenu(
|
|
|
67
67
|
insertionIndex: __experimentalInsertionIndex,
|
|
68
68
|
shouldFocusBlock,
|
|
69
69
|
} );
|
|
70
|
-
const { showPatterns, inserterItems
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
enableOpenverseMediaCategory:
|
|
84
|
-
getSettings().enableOpenverseMediaCategory,
|
|
85
|
-
};
|
|
86
|
-
},
|
|
87
|
-
[ destinationRootClientId ]
|
|
88
|
-
);
|
|
70
|
+
const { showPatterns, inserterItems } = useSelect(
|
|
71
|
+
( select ) => {
|
|
72
|
+
const { __experimentalGetAllowedPatterns, getInserterItems } =
|
|
73
|
+
select( blockEditorStore );
|
|
74
|
+
return {
|
|
75
|
+
showPatterns: !! __experimentalGetAllowedPatterns(
|
|
76
|
+
destinationRootClientId
|
|
77
|
+
).length,
|
|
78
|
+
inserterItems: getInserterItems( destinationRootClientId ),
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
[ destinationRootClientId ]
|
|
82
|
+
);
|
|
89
83
|
const hasReusableBlocks = useMemo( () => {
|
|
90
84
|
return inserterItems.some(
|
|
91
85
|
( { category } ) => category === 'reusable'
|
|
@@ -93,7 +87,7 @@ function InserterMenu(
|
|
|
93
87
|
}, [ inserterItems ] );
|
|
94
88
|
|
|
95
89
|
const mediaCategories = useMediaCategories( destinationRootClientId );
|
|
96
|
-
const showMedia = !! mediaCategories.length
|
|
90
|
+
const showMedia = !! mediaCategories.length;
|
|
97
91
|
|
|
98
92
|
const onInsert = useCallback(
|
|
99
93
|
( blocks, meta, shouldForceFocusBlock ) => {
|
|
@@ -32,6 +32,7 @@ export default function QuickInserter( {
|
|
|
32
32
|
isAppender,
|
|
33
33
|
prioritizePatterns,
|
|
34
34
|
selectBlockOnInsert,
|
|
35
|
+
orderInitialBlockItems,
|
|
35
36
|
} ) {
|
|
36
37
|
const [ filterValue, setFilterValue ] = useState( '' );
|
|
37
38
|
const [ destinationRootClientId, onInsertBlocks ] = useInsertionPoint( {
|
|
@@ -124,6 +125,7 @@ export default function QuickInserter( {
|
|
|
124
125
|
isDraggable={ false }
|
|
125
126
|
prioritizePatterns={ prioritizePatterns }
|
|
126
127
|
selectBlockOnInsert={ selectBlockOnInsert }
|
|
128
|
+
orderInitialBlockItems={ orderInitialBlockItems }
|
|
127
129
|
/>
|
|
128
130
|
</div>
|
|
129
131
|
|
|
@@ -46,6 +46,7 @@ function InserterSearchResults( {
|
|
|
46
46
|
shouldFocusBlock = true,
|
|
47
47
|
prioritizePatterns,
|
|
48
48
|
selectBlockOnInsert,
|
|
49
|
+
orderInitialBlockItems,
|
|
49
50
|
} ) {
|
|
50
51
|
const debouncedSpeak = useDebounce( speak, 500 );
|
|
51
52
|
|
|
@@ -88,8 +89,12 @@ function InserterSearchResults( {
|
|
|
88
89
|
if ( maxBlockTypesToShow === 0 ) {
|
|
89
90
|
return [];
|
|
90
91
|
}
|
|
92
|
+
let orderedItems = orderBy( blockTypes, 'frecency', 'desc' );
|
|
93
|
+
if ( ! filterValue && orderInitialBlockItems ) {
|
|
94
|
+
orderedItems = orderInitialBlockItems( orderedItems );
|
|
95
|
+
}
|
|
91
96
|
const results = searchBlockItems(
|
|
92
|
-
|
|
97
|
+
orderedItems,
|
|
93
98
|
blockTypeCategories,
|
|
94
99
|
blockTypeCollections,
|
|
95
100
|
filterValue
|
|
@@ -104,6 +109,7 @@ function InserterSearchResults( {
|
|
|
104
109
|
blockTypeCategories,
|
|
105
110
|
blockTypeCollections,
|
|
106
111
|
maxBlockTypes,
|
|
112
|
+
orderInitialBlockItems,
|
|
107
113
|
] );
|
|
108
114
|
|
|
109
115
|
// Announce search results on change.
|
|
@@ -35,6 +35,7 @@ $block-inserter-tabs-height: 44px;
|
|
|
35
35
|
.components-popover__content {
|
|
36
36
|
border: none;
|
|
37
37
|
outline: none;
|
|
38
|
+
box-shadow: $shadow-popover;
|
|
38
39
|
|
|
39
40
|
.block-editor-inserter__quick-inserter > * {
|
|
40
41
|
border-left: $border-width solid $gray-400;
|
|
@@ -42,10 +43,12 @@ $block-inserter-tabs-height: 44px;
|
|
|
42
43
|
|
|
43
44
|
&:first-child {
|
|
44
45
|
border-top: $border-width solid $gray-400;
|
|
46
|
+
border-radius: $radius-block-ui $radius-block-ui 0 0;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
&:last-child {
|
|
48
50
|
border-bottom: $border-width solid $gray-400;
|
|
51
|
+
border-radius: 0 0 $radius-block-ui $radius-block-ui;
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
&.components-button {
|
|
@@ -660,6 +663,17 @@ $block-inserter-tabs-height: 44px;
|
|
|
660
663
|
margin: 0 auto;
|
|
661
664
|
max-width: 100%;
|
|
662
665
|
}
|
|
666
|
+
|
|
667
|
+
.block-editor-inserter__media-list__item-preview-spinner {
|
|
668
|
+
display: flex;
|
|
669
|
+
height: 100%;
|
|
670
|
+
width: 100%;
|
|
671
|
+
position: absolute;
|
|
672
|
+
justify-content: center;
|
|
673
|
+
background: rgba($white, 0.7);
|
|
674
|
+
align-items: center;
|
|
675
|
+
pointer-events: none;
|
|
676
|
+
}
|
|
663
677
|
}
|
|
664
678
|
|
|
665
679
|
&:focus .block-editor-inserter__media-list__item-preview {
|
|
@@ -686,3 +700,14 @@ $block-inserter-tabs-height: 44px;
|
|
|
686
700
|
height: 100%;
|
|
687
701
|
}
|
|
688
702
|
}
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
.block-editor-inserter-media-tab-media-preview-inserter-external-image-modal {
|
|
706
|
+
@include break-small() {
|
|
707
|
+
max-width: $break-mobile;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
p {
|
|
711
|
+
margin: 0;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
@@ -7,6 +7,7 @@ import classnames from 'classnames';
|
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
9
|
import { Button, Spinner, Notice, TextControl } from '@wordpress/components';
|
|
10
|
+
import { keyboardReturn } from '@wordpress/icons';
|
|
10
11
|
import { __ } from '@wordpress/i18n';
|
|
11
12
|
import { useRef, useState, useEffect } from '@wordpress/element';
|
|
12
13
|
import { focus } from '@wordpress/dom';
|
|
@@ -112,7 +113,6 @@ function LinkControl( {
|
|
|
112
113
|
settings = DEFAULT_LINK_SETTINGS,
|
|
113
114
|
onChange = noop,
|
|
114
115
|
onRemove,
|
|
115
|
-
onCancel,
|
|
116
116
|
noDirectEntry = false,
|
|
117
117
|
showSuggestions = true,
|
|
118
118
|
showInitialSuggestions,
|
|
@@ -190,8 +190,6 @@ function LinkControl( {
|
|
|
190
190
|
isEndingEditWithFocus.current = false;
|
|
191
191
|
}, [ isEditingLink, isCreatingPage ] );
|
|
192
192
|
|
|
193
|
-
const hasLinkValue = value?.url?.trim()?.length > 0;
|
|
194
|
-
|
|
195
193
|
/**
|
|
196
194
|
* Cancels editing state and marks that focus may need to be restored after
|
|
197
195
|
* the next render, if focus was within the wrapper when editing finished.
|
|
@@ -237,29 +235,6 @@ function LinkControl( {
|
|
|
237
235
|
}
|
|
238
236
|
};
|
|
239
237
|
|
|
240
|
-
const resetInternalValues = () => {
|
|
241
|
-
setInternalUrlInputValue( value?.url );
|
|
242
|
-
setInternalTextInputValue( value?.title );
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
const handleCancel = ( event ) => {
|
|
246
|
-
event.preventDefault();
|
|
247
|
-
event.stopPropagation();
|
|
248
|
-
|
|
249
|
-
// Ensure that any unsubmitted input changes are reset.
|
|
250
|
-
resetInternalValues();
|
|
251
|
-
|
|
252
|
-
if ( hasLinkValue ) {
|
|
253
|
-
// If there is a link then exist editing mode and show preview.
|
|
254
|
-
stopEditing();
|
|
255
|
-
} else {
|
|
256
|
-
// If there is no link value, then remove the link entirely.
|
|
257
|
-
onRemove?.();
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
onCancel?.();
|
|
261
|
-
};
|
|
262
|
-
|
|
263
238
|
const currentUrlInputValue = propInputValue || internalUrlInputValue;
|
|
264
239
|
|
|
265
240
|
const currentInputIsEmpty = ! currentUrlInputValue?.trim()?.length;
|
|
@@ -272,9 +247,8 @@ function LinkControl( {
|
|
|
272
247
|
// Only show text control once a URL value has been committed
|
|
273
248
|
// and it isn't just empty whitespace.
|
|
274
249
|
// See https://github.com/WordPress/gutenberg/pull/33849/#issuecomment-932194927.
|
|
275
|
-
const showTextControl =
|
|
250
|
+
const showTextControl = value?.url?.trim()?.length > 0 && hasTextControl;
|
|
276
251
|
|
|
277
|
-
const isEditing = ( isEditingLink || ! value ) && ! isCreatingPage;
|
|
278
252
|
return (
|
|
279
253
|
<div
|
|
280
254
|
tabIndex={ -1 }
|
|
@@ -287,7 +261,7 @@ function LinkControl( {
|
|
|
287
261
|
</div>
|
|
288
262
|
) }
|
|
289
263
|
|
|
290
|
-
{
|
|
264
|
+
{ ( isEditingLink || ! value ) && ! isCreatingPage && (
|
|
291
265
|
<>
|
|
292
266
|
<div
|
|
293
267
|
className={ classnames( {
|
|
@@ -325,7 +299,17 @@ function LinkControl( {
|
|
|
325
299
|
createSuggestionButtonText
|
|
326
300
|
}
|
|
327
301
|
useLabel={ showTextControl }
|
|
328
|
-
|
|
302
|
+
>
|
|
303
|
+
<div className="block-editor-link-control__search-actions">
|
|
304
|
+
<Button
|
|
305
|
+
onClick={ handleSubmit }
|
|
306
|
+
label={ __( 'Submit' ) }
|
|
307
|
+
icon={ keyboardReturn }
|
|
308
|
+
className="block-editor-link-control__search-submit"
|
|
309
|
+
disabled={ currentInputIsEmpty } // Disallow submitting empty values.
|
|
310
|
+
/>
|
|
311
|
+
</div>
|
|
312
|
+
</LinkControlSearchInput>
|
|
329
313
|
</div>
|
|
330
314
|
{ errorMessage && (
|
|
331
315
|
<Notice
|
|
@@ -350,34 +334,15 @@ function LinkControl( {
|
|
|
350
334
|
/>
|
|
351
335
|
) }
|
|
352
336
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
<
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
) }
|
|
363
|
-
|
|
364
|
-
{ isEditing && (
|
|
365
|
-
<div className="block-editor-link-control__search-actions">
|
|
366
|
-
<Button
|
|
367
|
-
variant="primary"
|
|
368
|
-
onClick={ handleSubmit }
|
|
369
|
-
className="xblock-editor-link-control__search-submit"
|
|
370
|
-
disabled={ currentInputIsEmpty } // Disallow submitting empty values.
|
|
371
|
-
>
|
|
372
|
-
{ __( 'Apply' ) }
|
|
373
|
-
</Button>
|
|
374
|
-
<Button variant="tertiary" onClick={ handleCancel }>
|
|
375
|
-
{ __( 'Cancel' ) }
|
|
376
|
-
</Button>
|
|
377
|
-
</div>
|
|
378
|
-
) }
|
|
379
|
-
</div>
|
|
380
|
-
|
|
337
|
+
{ showSettingsDrawer && (
|
|
338
|
+
<div className="block-editor-link-control__tools">
|
|
339
|
+
<LinkControlSettingsDrawer
|
|
340
|
+
value={ value }
|
|
341
|
+
settings={ settings }
|
|
342
|
+
onChange={ onChange }
|
|
343
|
+
/>
|
|
344
|
+
</div>
|
|
345
|
+
) }
|
|
381
346
|
{ renderControlBottom && renderControlBottom() }
|
|
382
347
|
</div>
|
|
383
348
|
);
|
|
@@ -64,6 +64,7 @@ $preview-image-height: 140px;
|
|
|
64
64
|
width: calc(100% - #{$grid-unit-20 * 2});
|
|
65
65
|
display: block;
|
|
66
66
|
padding: 11px $grid-unit-20;
|
|
67
|
+
padding-right: ( $button-size * $block-editor-link-control-number-of-actions ); // width of reset and submit buttons
|
|
67
68
|
margin: 0;
|
|
68
69
|
position: relative;
|
|
69
70
|
border: 1px solid $gray-300;
|
|
@@ -76,10 +77,20 @@ $preview-image-height: 140px;
|
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
.block-editor-link-control__search-actions {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
position: absolute;
|
|
81
|
+
/*
|
|
82
|
+
* Actions must be positioned on top of URLInput, since the input will grow
|
|
83
|
+
* when suggestions are rendered.
|
|
84
|
+
*
|
|
85
|
+
* Compensate for:
|
|
86
|
+
* - Border (1px)
|
|
87
|
+
* - Vertically, for the difference in height between the input (40px) and
|
|
88
|
+
* the icon buttons.
|
|
89
|
+
* - Horizontally, pad to the minimum of: default input padding, or the
|
|
90
|
+
* equivalent of the vertical padding.
|
|
91
|
+
*/
|
|
92
|
+
top: 1px + ( ( 40px - $button-size ) * 0.5 );
|
|
93
|
+
right: $grid-unit-20 + 1px + min($grid-unit-10, ( 40px - $button-size ) * 0.5);
|
|
83
94
|
}
|
|
84
95
|
|
|
85
96
|
.components-button .block-editor-link-control__search-submit .has-icon {
|
|
@@ -426,10 +437,9 @@ $preview-image-height: 140px;
|
|
|
426
437
|
padding: 10px;
|
|
427
438
|
}
|
|
428
439
|
|
|
429
|
-
.block-editor-link-
|
|
440
|
+
.block-editor-link-control__tools {
|
|
430
441
|
display: flex;
|
|
431
442
|
align-items: center;
|
|
432
|
-
justify-content: space-between;
|
|
433
443
|
border-top: $border-width solid $gray-300;
|
|
434
444
|
margin: 0;
|
|
435
445
|
padding: $grid-unit-20;
|
|
@@ -469,8 +479,14 @@ $preview-image-height: 140px;
|
|
|
469
479
|
position: absolute;
|
|
470
480
|
left: auto;
|
|
471
481
|
bottom: auto;
|
|
482
|
+
/*
|
|
483
|
+
* Position spinner to the left of the actions.
|
|
484
|
+
*
|
|
485
|
+
* Compensate for:
|
|
486
|
+
* - Input padding right ($button-size)
|
|
487
|
+
*/
|
|
472
488
|
top: calc(50% - #{$spinner-size} / 2);
|
|
473
|
-
right: $
|
|
489
|
+
right: $button-size;
|
|
474
490
|
}
|
|
475
491
|
}
|
|
476
492
|
|