@wordpress/block-editor 11.3.2 → 11.4.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/README.md +4 -4
- package/build/components/block-actions/index.js +2 -7
- package/build/components/block-actions/index.js.map +1 -1
- package/build/components/block-alignment-control/use-available-alignments.js +5 -3
- package/build/components/block-alignment-control/use-available-alignments.js.map +1 -1
- package/build/components/block-popover/inbetween.js +10 -33
- package/build/components/block-popover/inbetween.js.map +1 -1
- package/build/components/block-tools/selected-block-popover.js +2 -2
- package/build/components/block-tools/selected-block-popover.js.map +1 -1
- package/build/components/block-types-list/index.native.js +2 -0
- package/build/components/block-types-list/index.native.js.map +1 -1
- package/build/components/colors-gradients/control.js +6 -3
- package/build/components/colors-gradients/control.js.map +1 -1
- package/build/components/font-appearance-control/index.js +0 -3
- package/build/components/font-appearance-control/index.js.map +1 -1
- package/build/components/global-styles/hooks.js +106 -45
- package/build/components/global-styles/hooks.js.map +1 -1
- package/build/components/global-styles/index.js +24 -0
- package/build/components/global-styles/index.js.map +1 -1
- package/build/components/global-styles/typography-panel.js +421 -0
- package/build/components/global-styles/typography-panel.js.map +1 -0
- package/build/components/global-styles/use-global-styles-output.js +6 -2
- package/build/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build/components/iframe/index.js +17 -11
- package/build/components/iframe/index.js.map +1 -1
- package/build/components/image-editor/aspect-ratio-dropdown.js +2 -1
- package/build/components/image-editor/aspect-ratio-dropdown.js.map +1 -1
- package/build/components/image-size-control/index.js +6 -11
- package/build/components/image-size-control/index.js.map +1 -1
- package/build/components/inserter/block-patterns-tab.js +9 -15
- package/build/components/inserter/block-patterns-tab.js.map +1 -1
- package/build/components/inserter/block-types-tab.native.js +4 -1
- package/build/components/inserter/block-types-tab.native.js.map +1 -1
- package/build/components/inserter/reusable-blocks-tab.native.js +4 -1
- package/build/components/inserter/reusable-blocks-tab.native.js.map +1 -1
- package/build/components/inserter/search-results.native.js +4 -1
- package/build/components/inserter/search-results.native.js.map +1 -1
- package/build/components/link-control/index.js +15 -15
- package/build/components/link-control/index.js.map +1 -1
- package/build/components/link-control/settings-drawer.js +72 -30
- package/build/components/link-control/settings-drawer.js.map +1 -1
- package/build/components/link-control/settings.js +52 -0
- package/build/components/link-control/settings.js.map +1 -0
- package/build/components/list-view/index.js +6 -1
- package/build/components/list-view/index.js.map +1 -1
- package/build/components/off-canvas-editor/block-contents.js +5 -4
- package/build/components/off-canvas-editor/block-contents.js.map +1 -1
- package/build/components/off-canvas-editor/leaf-more-menu.js +116 -0
- package/build/components/off-canvas-editor/leaf-more-menu.js.map +1 -0
- package/build/components/off-canvas-editor/link-ui.js +1 -0
- package/build/components/off-canvas-editor/link-ui.js.map +1 -1
- package/build/components/provider/index.js +2 -2
- package/build/components/provider/index.js.map +1 -1
- package/build/components/rich-text/index.js +0 -2
- package/build/components/rich-text/index.js.map +1 -1
- package/build/components/url-input/index.js +2 -2
- package/build/components/url-input/index.js.map +1 -1
- package/build/components/url-popover/index.js +6 -1
- package/build/components/url-popover/index.js.map +1 -1
- package/build/hooks/dimensions.js +8 -2
- package/build/hooks/dimensions.js.map +1 -1
- package/build/hooks/font-family.js +2 -76
- package/build/hooks/font-family.js.map +1 -1
- package/build/hooks/font-size.js +3 -51
- package/build/hooks/font-size.js.map +1 -1
- package/build/hooks/gap.js +2 -1
- package/build/hooks/gap.js.map +1 -1
- package/build/hooks/index.js +2 -0
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/line-height.js +0 -42
- package/build/hooks/line-height.js.map +1 -1
- package/build/hooks/metadata.js +6 -0
- package/build/hooks/metadata.js.map +1 -1
- package/build/hooks/position.js +6 -1
- package/build/hooks/position.js.map +1 -1
- package/build/hooks/typography.js +112 -127
- package/build/hooks/typography.js.map +1 -1
- package/build/index.js +6 -6
- package/build/index.js.map +1 -1
- package/build/layouts/flow.js +23 -2
- package/build/layouts/flow.js.map +1 -1
- package/build/lock-unlock.js +19 -0
- package/build/lock-unlock.js.map +1 -0
- package/build/{experiments.js → private-apis.js} +12 -19
- package/build/private-apis.js.map +1 -0
- package/build/{experiments.native.js → private-apis.native.js} +9 -19
- package/build/private-apis.native.js.map +1 -0
- package/build/store/index.js +3 -3
- package/build/store/index.js.map +1 -1
- package/build/store/selectors.js +18 -1
- package/build/store/selectors.js.map +1 -1
- package/build-module/components/block-actions/index.js +2 -7
- package/build-module/components/block-actions/index.js.map +1 -1
- package/build-module/components/block-alignment-control/use-available-alignments.js +5 -3
- package/build-module/components/block-alignment-control/use-available-alignments.js.map +1 -1
- package/build-module/components/block-popover/inbetween.js +10 -33
- package/build-module/components/block-popover/inbetween.js.map +1 -1
- package/build-module/components/block-tools/selected-block-popover.js +1 -1
- package/build-module/components/block-tools/selected-block-popover.js.map +1 -1
- package/build-module/components/block-types-list/index.native.js +2 -0
- package/build-module/components/block-types-list/index.native.js.map +1 -1
- package/build-module/components/colors-gradients/control.js +6 -3
- package/build-module/components/colors-gradients/control.js.map +1 -1
- package/build-module/components/font-appearance-control/index.js +2 -1
- package/build-module/components/font-appearance-control/index.js.map +1 -1
- package/build-module/components/global-styles/hooks.js +100 -46
- package/build-module/components/global-styles/hooks.js.map +1 -1
- package/build-module/components/global-styles/index.js +2 -1
- package/build-module/components/global-styles/index.js.map +1 -1
- package/build-module/components/global-styles/typography-panel.js +400 -0
- package/build-module/components/global-styles/typography-panel.js.map +1 -0
- package/build-module/components/global-styles/use-global-styles-output.js +6 -2
- package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build-module/components/iframe/index.js +17 -11
- package/build-module/components/iframe/index.js.map +1 -1
- package/build-module/components/image-editor/aspect-ratio-dropdown.js +2 -1
- package/build-module/components/image-editor/aspect-ratio-dropdown.js.map +1 -1
- package/build-module/components/image-size-control/index.js +7 -12
- package/build-module/components/image-size-control/index.js.map +1 -1
- package/build-module/components/inserter/block-patterns-tab.js +9 -15
- package/build-module/components/inserter/block-patterns-tab.js.map +1 -1
- package/build-module/components/inserter/block-types-tab.native.js +3 -1
- package/build-module/components/inserter/block-types-tab.native.js.map +1 -1
- package/build-module/components/inserter/reusable-blocks-tab.native.js +3 -1
- package/build-module/components/inserter/reusable-blocks-tab.native.js.map +1 -1
- package/build-module/components/inserter/search-results.native.js +3 -1
- package/build-module/components/inserter/search-results.native.js.map +1 -1
- package/build-module/components/link-control/index.js +16 -16
- package/build-module/components/link-control/index.js.map +1 -1
- package/build-module/components/link-control/settings-drawer.js +68 -30
- package/build-module/components/link-control/settings-drawer.js.map +1 -1
- package/build-module/components/link-control/settings.js +43 -0
- package/build-module/components/link-control/settings.js.map +1 -0
- package/build-module/components/list-view/index.js +6 -1
- package/build-module/components/list-view/index.js.map +1 -1
- package/build-module/components/off-canvas-editor/block-contents.js +4 -3
- package/build-module/components/off-canvas-editor/block-contents.js.map +1 -1
- package/build-module/components/off-canvas-editor/leaf-more-menu.js +99 -0
- package/build-module/components/off-canvas-editor/leaf-more-menu.js.map +1 -0
- package/build-module/components/off-canvas-editor/link-ui.js +1 -0
- package/build-module/components/off-canvas-editor/link-ui.js.map +1 -1
- package/build-module/components/provider/index.js +1 -1
- package/build-module/components/provider/index.js.map +1 -1
- package/build-module/components/rich-text/index.js +0 -2
- package/build-module/components/rich-text/index.js.map +1 -1
- package/build-module/components/url-input/index.js +2 -2
- package/build-module/components/url-input/index.js.map +1 -1
- package/build-module/components/url-popover/index.js +6 -2
- package/build-module/components/url-popover/index.js.map +1 -1
- package/build-module/hooks/dimensions.js +7 -1
- package/build-module/hooks/dimensions.js.map +1 -1
- package/build-module/hooks/font-family.js +3 -69
- package/build-module/hooks/font-family.js.map +1 -1
- package/build-module/hooks/font-size.js +6 -47
- package/build-module/hooks/font-size.js.map +1 -1
- package/build-module/hooks/gap.js +3 -2
- package/build-module/hooks/gap.js.map +1 -1
- package/build-module/hooks/index.js +1 -0
- package/build-module/hooks/index.js.map +1 -1
- package/build-module/hooks/line-height.js +0 -38
- package/build-module/hooks/line-height.js.map +1 -1
- package/build-module/hooks/metadata.js +6 -0
- package/build-module/hooks/metadata.js.map +1 -1
- package/build-module/hooks/position.js +5 -1
- package/build-module/hooks/position.js.map +1 -1
- package/build-module/hooks/typography.js +110 -123
- package/build-module/hooks/typography.js.map +1 -1
- package/build-module/index.js +1 -1
- package/build-module/index.js.map +1 -1
- package/build-module/layouts/flow.js +23 -2
- package/build-module/layouts/flow.js.map +1 -1
- package/build-module/lock-unlock.js +9 -0
- package/build-module/lock-unlock.js.map +1 -0
- package/build-module/private-apis.js +19 -0
- package/build-module/private-apis.js.map +1 -0
- package/build-module/private-apis.native.js +15 -0
- package/build-module/private-apis.native.js.map +1 -0
- package/build-module/store/index.js +1 -1
- package/build-module/store/index.js.map +1 -1
- package/build-module/store/selectors.js +18 -1
- package/build-module/store/selectors.js.map +1 -1
- package/build-style/style-rtl.css +35 -22
- package/build-style/style.css +35 -22
- package/package.json +31 -31
- package/src/components/block-actions/index.js +0 -9
- package/src/components/block-alignment-control/use-available-alignments.js +17 -12
- package/src/components/block-popover/inbetween.js +21 -53
- package/src/components/block-tools/selected-block-popover.js +1 -1
- package/src/components/block-types-list/index.native.js +2 -0
- package/src/components/colors-gradients/control.js +3 -0
- package/src/components/font-appearance-control/index.js +1 -1
- package/src/components/global-styles/hooks.js +186 -66
- package/src/components/global-styles/index.js +5 -0
- package/src/components/global-styles/typography-panel.js +403 -0
- package/src/components/global-styles/use-global-styles-output.js +6 -2
- package/src/components/iframe/index.js +20 -18
- package/src/components/image-editor/aspect-ratio-dropdown.js +1 -0
- package/src/components/image-size-control/index.js +10 -12
- package/src/components/image-size-control/style.scss +3 -21
- package/src/components/inserter/block-patterns-tab.js +9 -23
- package/src/components/inserter/block-types-tab.native.js +2 -0
- package/src/components/inserter/reusable-blocks-tab.native.js +2 -0
- package/src/components/inserter/search-results.native.js +2 -0
- package/src/components/link-control/index.js +22 -22
- package/src/components/link-control/settings-drawer.js +85 -30
- package/src/components/link-control/settings.js +41 -0
- package/src/components/link-control/style.scss +39 -7
- package/src/components/link-control/test/index.js +213 -4
- package/src/components/list-view/index.js +5 -0
- package/src/components/off-canvas-editor/block-contents.js +3 -2
- package/src/components/off-canvas-editor/leaf-more-menu.js +115 -0
- package/src/components/off-canvas-editor/link-ui.js +1 -0
- package/src/components/provider/index.js +1 -1
- package/src/components/rich-text/index.js +0 -2
- package/src/components/url-input/index.js +3 -2
- package/src/components/url-popover/index.js +8 -2
- package/src/hooks/dimensions.js +13 -1
- package/src/hooks/font-family.js +0 -58
- package/src/hooks/font-size.js +1 -36
- package/src/hooks/gap.js +9 -2
- package/src/hooks/index.js +1 -0
- package/src/hooks/line-height.js +0 -33
- package/src/hooks/metadata.js +4 -0
- package/src/hooks/position.js +7 -1
- package/src/hooks/typography.js +133 -212
- package/src/index.js +1 -1
- package/src/layouts/flow.js +16 -1
- package/src/lock-unlock.js +10 -0
- package/src/private-apis.js +19 -0
- package/src/private-apis.native.js +15 -0
- package/src/store/index.js +1 -1
- package/src/store/selectors.js +16 -1
- package/tsconfig.json +20 -1
- package/build/experiments.js.map +0 -1
- package/build/experiments.native.js.map +0 -1
- package/build/hooks/font-appearance.js +0 -188
- package/build/hooks/font-appearance.js.map +0 -1
- package/build/hooks/letter-spacing.js +0 -129
- package/build/hooks/letter-spacing.js.map +0 -1
- package/build/hooks/text-decoration.js +0 -130
- package/build/hooks/text-decoration.js.map +0 -1
- package/build/hooks/text-transform.js +0 -130
- package/build/hooks/text-transform.js.map +0 -1
- package/build-module/experiments.js +0 -25
- package/build-module/experiments.js.map +0 -1
- package/build-module/experiments.native.js +0 -23
- package/build-module/experiments.native.js.map +0 -1
- package/build-module/hooks/font-appearance.js +0 -161
- package/build-module/hooks/font-appearance.js.map +0 -1
- package/build-module/hooks/letter-spacing.js +0 -107
- package/build-module/hooks/letter-spacing.js.map +0 -1
- package/build-module/hooks/text-decoration.js +0 -108
- package/build-module/hooks/text-decoration.js.map +0 -1
- package/build-module/hooks/text-transform.js +0 -108
- package/build-module/hooks/text-transform.js.map +0 -1
- package/src/experiments.js +0 -27
- package/src/experiments.native.js +0 -25
- package/src/hooks/font-appearance.js +0 -146
- package/src/hooks/letter-spacing.js +0 -101
- package/src/hooks/text-decoration.js +0 -102
- package/src/hooks/text-transform.js +0 -101
|
@@ -6,7 +6,7 @@ import classnames from 'classnames';
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
|
-
import { Button, Spinner, Notice
|
|
9
|
+
import { Button, Spinner, Notice } from '@wordpress/components';
|
|
10
10
|
import { __ } from '@wordpress/i18n';
|
|
11
11
|
import { useRef, useState, useEffect } from '@wordpress/element';
|
|
12
12
|
import { focus } from '@wordpress/dom';
|
|
@@ -136,6 +136,8 @@ function LinkControl( {
|
|
|
136
136
|
const textInputRef = useRef();
|
|
137
137
|
const isEndingEditWithFocus = useRef( false );
|
|
138
138
|
|
|
139
|
+
const [ settingsOpen, setSettingsOpen ] = useState( false );
|
|
140
|
+
|
|
139
141
|
const [ internalUrlInputValue, setInternalUrlInputValue ] =
|
|
140
142
|
useInternalInputValue( value?.url || '' );
|
|
141
143
|
|
|
@@ -201,6 +203,7 @@ function LinkControl( {
|
|
|
201
203
|
wrapperNode.current.ownerDocument.activeElement
|
|
202
204
|
);
|
|
203
205
|
|
|
206
|
+
setSettingsOpen( false );
|
|
204
207
|
setIsEditingLink( false );
|
|
205
208
|
};
|
|
206
209
|
|
|
@@ -267,7 +270,7 @@ function LinkControl( {
|
|
|
267
270
|
const shownUnlinkControl =
|
|
268
271
|
onRemove && value && ! isEditingLink && ! isCreatingPage;
|
|
269
272
|
|
|
270
|
-
const
|
|
273
|
+
const showSettings = !! settings?.length;
|
|
271
274
|
|
|
272
275
|
// Only show text control once a URL value has been committed
|
|
273
276
|
// and it isn't just empty whitespace.
|
|
@@ -275,6 +278,7 @@ function LinkControl( {
|
|
|
275
278
|
const showTextControl = hasLinkValue && hasTextControl;
|
|
276
279
|
|
|
277
280
|
const isEditing = ( isEditingLink || ! value ) && ! isCreatingPage;
|
|
281
|
+
|
|
278
282
|
return (
|
|
279
283
|
<div
|
|
280
284
|
tabIndex={ -1 }
|
|
@@ -295,18 +299,6 @@ function LinkControl( {
|
|
|
295
299
|
'has-text-control': showTextControl,
|
|
296
300
|
} ) }
|
|
297
301
|
>
|
|
298
|
-
{ showTextControl && (
|
|
299
|
-
<TextControl
|
|
300
|
-
__nextHasNoMarginBottom
|
|
301
|
-
ref={ textInputRef }
|
|
302
|
-
className="block-editor-link-control__field block-editor-link-control__text-content"
|
|
303
|
-
label="Text"
|
|
304
|
-
value={ internalTextInputValue }
|
|
305
|
-
onChange={ setInternalTextInputValue }
|
|
306
|
-
onKeyDown={ handleSubmitWithEnter }
|
|
307
|
-
/>
|
|
308
|
-
) }
|
|
309
|
-
|
|
310
302
|
<LinkControlSearchInput
|
|
311
303
|
currentLink={ value }
|
|
312
304
|
className="block-editor-link-control__field block-editor-link-control__search-input"
|
|
@@ -350,18 +342,26 @@ function LinkControl( {
|
|
|
350
342
|
/>
|
|
351
343
|
) }
|
|
352
344
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
345
|
+
{ isEditing && (
|
|
346
|
+
<div className="block-editor-link-control__tools">
|
|
347
|
+
{ ( showSettings || showTextControl ) && (
|
|
356
348
|
<LinkControlSettingsDrawer
|
|
349
|
+
settingsOpen={ settingsOpen }
|
|
350
|
+
setSettingsOpen={ setSettingsOpen }
|
|
351
|
+
showTextControl={ showTextControl }
|
|
352
|
+
showSettings={ showSettings }
|
|
353
|
+
textInputRef={ textInputRef }
|
|
354
|
+
internalTextInputValue={ internalTextInputValue }
|
|
355
|
+
setInternalTextInputValue={
|
|
356
|
+
setInternalTextInputValue
|
|
357
|
+
}
|
|
358
|
+
handleSubmitWithEnter={ handleSubmitWithEnter }
|
|
357
359
|
value={ value }
|
|
358
360
|
settings={ settings }
|
|
359
361
|
onChange={ onChange }
|
|
360
362
|
/>
|
|
361
|
-
|
|
362
|
-
) }
|
|
363
|
+
) }
|
|
363
364
|
|
|
364
|
-
{ isEditing && (
|
|
365
365
|
<div className="block-editor-link-control__search-actions">
|
|
366
366
|
<Button
|
|
367
367
|
variant="primary"
|
|
@@ -375,8 +375,8 @@ function LinkControl( {
|
|
|
375
375
|
{ __( 'Cancel' ) }
|
|
376
376
|
</Button>
|
|
377
377
|
</div>
|
|
378
|
-
|
|
379
|
-
|
|
378
|
+
</div>
|
|
379
|
+
) }
|
|
380
380
|
|
|
381
381
|
{ renderControlBottom && renderControlBottom() }
|
|
382
382
|
</div>
|
|
@@ -1,41 +1,96 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
TextControl,
|
|
7
|
+
__unstableMotion as motion,
|
|
8
|
+
__unstableAnimatePresence as AnimatePresence,
|
|
9
|
+
} from '@wordpress/components';
|
|
10
|
+
import { settings as settingsIcon } from '@wordpress/icons';
|
|
11
|
+
import { useReducedMotion, useInstanceId } from '@wordpress/compose';
|
|
4
12
|
import { __ } from '@wordpress/i18n';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
13
|
+
import { Fragment } from '@wordpress/element';
|
|
14
|
+
/**
|
|
15
|
+
* Internal dependencies
|
|
16
|
+
*/
|
|
17
|
+
import Settings from './settings';
|
|
8
18
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
19
|
+
function LinkSettingsDrawer( {
|
|
20
|
+
settingsOpen,
|
|
21
|
+
setSettingsOpen,
|
|
22
|
+
showTextControl,
|
|
23
|
+
showSettings,
|
|
24
|
+
textInputRef,
|
|
25
|
+
internalTextInputValue,
|
|
26
|
+
setInternalTextInputValue,
|
|
27
|
+
handleSubmitWithEnter,
|
|
28
|
+
value,
|
|
29
|
+
settings,
|
|
30
|
+
onChange,
|
|
31
|
+
} ) {
|
|
32
|
+
const prefersReducedMotion = useReducedMotion();
|
|
33
|
+
const MaybeAnimatePresence = prefersReducedMotion
|
|
34
|
+
? Fragment
|
|
35
|
+
: AnimatePresence;
|
|
36
|
+
const MaybeMotionDiv = prefersReducedMotion ? 'div' : motion.div;
|
|
13
37
|
|
|
14
|
-
const
|
|
15
|
-
onChange( {
|
|
16
|
-
...value,
|
|
17
|
-
[ setting.id ]: newValue,
|
|
18
|
-
} );
|
|
19
|
-
};
|
|
38
|
+
const id = useInstanceId( LinkSettingsDrawer );
|
|
20
39
|
|
|
21
|
-
const
|
|
22
|
-
<ToggleControl
|
|
23
|
-
className="block-editor-link-control__setting"
|
|
24
|
-
key={ setting.id }
|
|
25
|
-
label={ setting.title }
|
|
26
|
-
onChange={ handleSettingChange( setting ) }
|
|
27
|
-
checked={ value ? !! value[ setting.id ] : false }
|
|
28
|
-
/>
|
|
29
|
-
) );
|
|
40
|
+
const settingsDrawerId = `link-control-settings-drawer-${ id }`;
|
|
30
41
|
|
|
31
42
|
return (
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
<>
|
|
44
|
+
<Button
|
|
45
|
+
className="block-editor-link-control__drawer-toggle"
|
|
46
|
+
aria-expanded={ settingsOpen }
|
|
47
|
+
onClick={ () => setSettingsOpen( ! settingsOpen ) }
|
|
48
|
+
icon={ settingsIcon }
|
|
49
|
+
label={ __( 'Toggle link settings' ) }
|
|
50
|
+
aria-controls={ settingsDrawerId }
|
|
51
|
+
/>
|
|
52
|
+
<MaybeAnimatePresence>
|
|
53
|
+
{ settingsOpen && (
|
|
54
|
+
<MaybeMotionDiv
|
|
55
|
+
className="block-editor-link-control__drawer"
|
|
56
|
+
hidden={ ! settingsOpen }
|
|
57
|
+
id={ settingsDrawerId }
|
|
58
|
+
initial="collapsed"
|
|
59
|
+
animate="open"
|
|
60
|
+
exit="collapsed"
|
|
61
|
+
variants={ {
|
|
62
|
+
open: { opacity: 1, height: 'auto' },
|
|
63
|
+
collapsed: { opacity: 0, height: 0 },
|
|
64
|
+
} }
|
|
65
|
+
transition={ {
|
|
66
|
+
duration: 0.1,
|
|
67
|
+
} }
|
|
68
|
+
>
|
|
69
|
+
<div className="block-editor-link-control__drawer-inner">
|
|
70
|
+
{ showTextControl && (
|
|
71
|
+
<TextControl
|
|
72
|
+
__nextHasNoMarginBottom
|
|
73
|
+
ref={ textInputRef }
|
|
74
|
+
className="block-editor-link-control__setting block-editor-link-control__text-content"
|
|
75
|
+
label="Text"
|
|
76
|
+
value={ internalTextInputValue }
|
|
77
|
+
onChange={ setInternalTextInputValue }
|
|
78
|
+
onKeyDown={ handleSubmitWithEnter }
|
|
79
|
+
/>
|
|
80
|
+
) }
|
|
81
|
+
{ showSettings && (
|
|
82
|
+
<Settings
|
|
83
|
+
value={ value }
|
|
84
|
+
settings={ settings }
|
|
85
|
+
onChange={ onChange }
|
|
86
|
+
/>
|
|
87
|
+
) }
|
|
88
|
+
</div>
|
|
89
|
+
</MaybeMotionDiv>
|
|
90
|
+
) }
|
|
91
|
+
</MaybeAnimatePresence>
|
|
92
|
+
</>
|
|
38
93
|
);
|
|
39
|
-
}
|
|
94
|
+
}
|
|
40
95
|
|
|
41
|
-
export default
|
|
96
|
+
export default LinkSettingsDrawer;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
import { ToggleControl, VisuallyHidden } from '@wordpress/components';
|
|
6
|
+
|
|
7
|
+
const noop = () => {};
|
|
8
|
+
|
|
9
|
+
const LinkControlSettings = ( { value, onChange = noop, settings } ) => {
|
|
10
|
+
if ( ! settings || ! settings.length ) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const handleSettingChange = ( setting ) => ( newValue ) => {
|
|
15
|
+
onChange( {
|
|
16
|
+
...value,
|
|
17
|
+
[ setting.id ]: newValue,
|
|
18
|
+
} );
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const theSettings = settings.map( ( setting ) => (
|
|
22
|
+
<ToggleControl
|
|
23
|
+
className="block-editor-link-control__setting"
|
|
24
|
+
key={ setting.id }
|
|
25
|
+
label={ setting.title }
|
|
26
|
+
onChange={ handleSettingChange( setting ) }
|
|
27
|
+
checked={ value ? !! value[ setting.id ] : false }
|
|
28
|
+
/>
|
|
29
|
+
) );
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<fieldset className="block-editor-link-control__settings">
|
|
33
|
+
<VisuallyHidden as="legend">
|
|
34
|
+
{ __( 'Currently selected link settings' ) }
|
|
35
|
+
</VisuallyHidden>
|
|
36
|
+
{ theSettings }
|
|
37
|
+
</fieldset>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default LinkControlSettings;
|
|
@@ -80,6 +80,7 @@ $preview-image-height: 140px;
|
|
|
80
80
|
flex-direction: row-reverse; // put "Cancel" on the left but retain DOM order.
|
|
81
81
|
justify-content: flex-start;
|
|
82
82
|
gap: $grid-unit-10;
|
|
83
|
+
order: 20;
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
.components-button .block-editor-link-control__search-submit .has-icon {
|
|
@@ -427,12 +428,48 @@ $preview-image-height: 140px;
|
|
|
427
428
|
}
|
|
428
429
|
|
|
429
430
|
.block-editor-link-control__drawer {
|
|
431
|
+
display: flex; // allow for ordering.
|
|
432
|
+
order: 30;
|
|
433
|
+
flex-direction: column;
|
|
434
|
+
flex-basis: 100%; // occupy full width.
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Inner div required to avoid padding/margin
|
|
438
|
+
// causing janky animation.
|
|
439
|
+
.block-editor-link-control__drawer-inner {
|
|
440
|
+
display: flex; // allow for ordering.
|
|
441
|
+
flex-direction: column;
|
|
442
|
+
flex-basis: 100%; // occupy full width.
|
|
443
|
+
margin-top: $grid-unit-20;
|
|
444
|
+
padding-top: $grid-unit-20;
|
|
445
|
+
position: relative;
|
|
446
|
+
|
|
447
|
+
&::after {
|
|
448
|
+
content: "";
|
|
449
|
+
display: block;
|
|
450
|
+
height: 1px;
|
|
451
|
+
background-color: $gray-300;
|
|
452
|
+
position: absolute;
|
|
453
|
+
left: -$grid-unit-20;
|
|
454
|
+
right: -$grid-unit-20;
|
|
455
|
+
top: 0;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.block-editor-link-control__tools {
|
|
430
460
|
display: flex;
|
|
461
|
+
flex-wrap: wrap;
|
|
431
462
|
align-items: center;
|
|
432
463
|
justify-content: space-between;
|
|
433
|
-
border-top: $border-width solid $gray-300;
|
|
434
464
|
margin: 0;
|
|
435
465
|
padding: $grid-unit-20;
|
|
466
|
+
|
|
467
|
+
// To hide the horizontal scrollbar on toggle.
|
|
468
|
+
// Margin and padding are needed to prevent cutoff of the toggle button focus outline.
|
|
469
|
+
// See: https://github.com/WordPress/gutenberg/pull/47986
|
|
470
|
+
margin-top: calc(var(--wp-admin-border-width-focus) * -1);
|
|
471
|
+
padding-top: var(--wp-admin-border-width-focus);
|
|
472
|
+
overflow: hidden;
|
|
436
473
|
}
|
|
437
474
|
|
|
438
475
|
.block-editor-link-control__unlink {
|
|
@@ -444,11 +481,6 @@ $preview-image-height: 140px;
|
|
|
444
481
|
flex: 1;
|
|
445
482
|
margin: 0;
|
|
446
483
|
|
|
447
|
-
|
|
448
|
-
:last-child {
|
|
449
|
-
margin-bottom: 0;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
484
|
.is-alternate & {
|
|
453
485
|
border-top: $border-width solid $gray-900;
|
|
454
486
|
}
|
|
@@ -457,7 +489,7 @@ $preview-image-height: 140px;
|
|
|
457
489
|
.block-editor-link-control__setting {
|
|
458
490
|
margin-bottom: $grid-unit-20;
|
|
459
491
|
|
|
460
|
-
:last-child {
|
|
492
|
+
&.block-editor-link-control__setting:last-child {
|
|
461
493
|
margin-bottom: 0;
|
|
462
494
|
}
|
|
463
495
|
}
|
|
@@ -53,6 +53,11 @@ jest.mock( '@wordpress/data/src/components/use-dispatch', () => ( {
|
|
|
53
53
|
|
|
54
54
|
jest.useRealTimers();
|
|
55
55
|
|
|
56
|
+
jest.mock( '@wordpress/compose', () => ( {
|
|
57
|
+
...jest.requireActual( '@wordpress/compose' ),
|
|
58
|
+
useReducedMotion: jest.fn( () => true ),
|
|
59
|
+
} ) );
|
|
60
|
+
|
|
56
61
|
beforeEach( () => {
|
|
57
62
|
// Setup a DOM element as a render target.
|
|
58
63
|
mockFetchSearchSuggestions.mockImplementation( fetchFauxEntitySuggestions );
|
|
@@ -137,7 +142,122 @@ describe( 'Basic rendering', () => {
|
|
|
137
142
|
// Search Input UI.
|
|
138
143
|
const searchInput = screen.getByRole( 'combobox', { name: 'URL' } );
|
|
139
144
|
|
|
140
|
-
expect( searchInput ).
|
|
145
|
+
expect( searchInput ).toBeVisible();
|
|
146
|
+
} );
|
|
147
|
+
|
|
148
|
+
it( 'should have aria-owns attribute to follow the ARIA 1.0 pattern', () => {
|
|
149
|
+
render( <LinkControl /> );
|
|
150
|
+
|
|
151
|
+
// Search Input UI.
|
|
152
|
+
const searchInput = screen.getByRole( 'combobox', { name: 'URL' } );
|
|
153
|
+
|
|
154
|
+
expect( searchInput ).toBeVisible();
|
|
155
|
+
// Make sure we use the ARIA 1.0 pattern with aria-owns.
|
|
156
|
+
// See https://github.com/WordPress/gutenberg/issues/47147
|
|
157
|
+
expect( searchInput ).not.toHaveAttribute( 'aria-controls' );
|
|
158
|
+
expect( searchInput ).toHaveAttribute( 'aria-owns' );
|
|
159
|
+
} );
|
|
160
|
+
|
|
161
|
+
it( 'should have aria-selected attribute only on the highlighted item', async () => {
|
|
162
|
+
const user = userEvent.setup();
|
|
163
|
+
|
|
164
|
+
let resolver;
|
|
165
|
+
mockFetchSearchSuggestions.mockImplementation(
|
|
166
|
+
() =>
|
|
167
|
+
new Promise( ( resolve ) => {
|
|
168
|
+
resolver = resolve;
|
|
169
|
+
} )
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
render( <LinkControl /> );
|
|
173
|
+
|
|
174
|
+
// Search Input UI.
|
|
175
|
+
const searchInput = screen.getByRole( 'combobox', { name: 'URL' } );
|
|
176
|
+
|
|
177
|
+
// Simulate searching for a term.
|
|
178
|
+
await user.type( searchInput, 'Hello' );
|
|
179
|
+
|
|
180
|
+
// Wait for the spinner SVG icon to be rendered.
|
|
181
|
+
expect( await screen.findByRole( 'presentation' ) ).toBeVisible();
|
|
182
|
+
// Check the suggestions list is not rendered yet.
|
|
183
|
+
expect( screen.queryByRole( 'listbox' ) ).not.toBeInTheDocument();
|
|
184
|
+
|
|
185
|
+
// Make the search suggestions fetch return a response.
|
|
186
|
+
resolver( fauxEntitySuggestions );
|
|
187
|
+
|
|
188
|
+
const resultsList = await screen.findByRole( 'listbox', {
|
|
189
|
+
name: 'Search results for "Hello"',
|
|
190
|
+
} );
|
|
191
|
+
|
|
192
|
+
// Check the suggestions list is rendered.
|
|
193
|
+
expect( resultsList ).toBeVisible();
|
|
194
|
+
// Check the spinner SVG icon is not rendered any longer.
|
|
195
|
+
expect( screen.queryByRole( 'presentation' ) ).not.toBeInTheDocument();
|
|
196
|
+
|
|
197
|
+
const searchResultElements =
|
|
198
|
+
within( resultsList ).getAllByRole( 'option' );
|
|
199
|
+
|
|
200
|
+
expect( searchResultElements ).toHaveLength(
|
|
201
|
+
// The fauxEntitySuggestions length plus the 'Press ENTER to add this link' button.
|
|
202
|
+
fauxEntitySuggestions.length + 1
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
// Step down into the search results, highlighting the first result item.
|
|
206
|
+
triggerArrowDown( searchInput );
|
|
207
|
+
|
|
208
|
+
const firstSearchSuggestion = searchResultElements[ 0 ];
|
|
209
|
+
const secondSearchSuggestion = searchResultElements[ 1 ];
|
|
210
|
+
|
|
211
|
+
let selectedSearchResultElement = screen.getByRole( 'option', {
|
|
212
|
+
selected: true,
|
|
213
|
+
} );
|
|
214
|
+
|
|
215
|
+
// We should have highlighted the first item using the keyboard.
|
|
216
|
+
expect( selectedSearchResultElement ).toEqual( firstSearchSuggestion );
|
|
217
|
+
|
|
218
|
+
// Check the aria-selected attribute is set only on the highlighted item.
|
|
219
|
+
expect( firstSearchSuggestion ).toHaveAttribute(
|
|
220
|
+
'aria-selected',
|
|
221
|
+
'true'
|
|
222
|
+
);
|
|
223
|
+
// Check the aria-selected attribute is omitted on the non-highlighted items.
|
|
224
|
+
expect( secondSearchSuggestion ).not.toHaveAttribute( 'aria-selected' );
|
|
225
|
+
|
|
226
|
+
// Step down into the search results, highlighting the second result item.
|
|
227
|
+
triggerArrowDown( searchInput );
|
|
228
|
+
|
|
229
|
+
selectedSearchResultElement = screen.getByRole( 'option', {
|
|
230
|
+
selected: true,
|
|
231
|
+
} );
|
|
232
|
+
|
|
233
|
+
// We should have highlighted the first item using the keyboard.
|
|
234
|
+
expect( selectedSearchResultElement ).toEqual( secondSearchSuggestion );
|
|
235
|
+
|
|
236
|
+
// Check the aria-selected attribute is omitted on non-highlighted items.
|
|
237
|
+
expect( firstSearchSuggestion ).not.toHaveAttribute( 'aria-selected' );
|
|
238
|
+
// Check the aria-selected attribute is set only on the highlighted item.
|
|
239
|
+
expect( secondSearchSuggestion ).toHaveAttribute(
|
|
240
|
+
'aria-selected',
|
|
241
|
+
'true'
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
// Step up into the search results, highlighting the first result item.
|
|
245
|
+
triggerArrowUp( searchInput );
|
|
246
|
+
|
|
247
|
+
selectedSearchResultElement = screen.getByRole( 'option', {
|
|
248
|
+
selected: true,
|
|
249
|
+
} );
|
|
250
|
+
|
|
251
|
+
// We should be back to highlighting the first search result again.
|
|
252
|
+
expect( selectedSearchResultElement ).toEqual( firstSearchSuggestion );
|
|
253
|
+
|
|
254
|
+
// Check the aria-selected attribute is set only on the highlighted item.
|
|
255
|
+
expect( firstSearchSuggestion ).toHaveAttribute(
|
|
256
|
+
'aria-selected',
|
|
257
|
+
'true'
|
|
258
|
+
);
|
|
259
|
+
// Check the aria-selected attribute is omitted on non-highlighted items.
|
|
260
|
+
expect( secondSearchSuggestion ).not.toHaveAttribute( 'aria-selected' );
|
|
141
261
|
} );
|
|
142
262
|
|
|
143
263
|
it( 'should not render protocol in links', async () => {
|
|
@@ -559,7 +679,7 @@ describe( 'Manual link entry', () => {
|
|
|
559
679
|
} );
|
|
560
680
|
|
|
561
681
|
// Verify the UI hasn't allowed submission.
|
|
562
|
-
expect( searchInput ).
|
|
682
|
+
expect( searchInput ).toBeVisible();
|
|
563
683
|
expect( submitButton ).toBeDisabled();
|
|
564
684
|
expect( submitButton ).toBeVisible();
|
|
565
685
|
}
|
|
@@ -601,7 +721,7 @@ describe( 'Manual link entry', () => {
|
|
|
601
721
|
} );
|
|
602
722
|
|
|
603
723
|
// Verify the UI hasn't allowed submission.
|
|
604
|
-
expect( searchInput ).
|
|
724
|
+
expect( searchInput ).toBeVisible();
|
|
605
725
|
expect( submitButton ).toBeDisabled();
|
|
606
726
|
expect( submitButton ).toBeVisible();
|
|
607
727
|
}
|
|
@@ -674,6 +794,8 @@ describe( 'Manual link entry', () => {
|
|
|
674
794
|
|
|
675
795
|
await user.click( editButton );
|
|
676
796
|
|
|
797
|
+
await toggleSettingsDrawer( user );
|
|
798
|
+
|
|
677
799
|
let searchInput = screen.getByRole( 'combobox', {
|
|
678
800
|
name: 'URL',
|
|
679
801
|
} );
|
|
@@ -706,6 +828,8 @@ describe( 'Manual link entry', () => {
|
|
|
706
828
|
|
|
707
829
|
await user.click( editButton );
|
|
708
830
|
|
|
831
|
+
await toggleSettingsDrawer( user );
|
|
832
|
+
|
|
709
833
|
// Re-query the inputs as they have been replaced.
|
|
710
834
|
searchInput = screen.getByRole( 'combobox', {
|
|
711
835
|
name: 'URL',
|
|
@@ -1534,6 +1658,62 @@ describe( 'Selecting links', () => {
|
|
|
1534
1658
|
} );
|
|
1535
1659
|
|
|
1536
1660
|
describe( 'Addition Settings UI', () => {
|
|
1661
|
+
it( 'should not show a means to toggle the link settings when not editing a link', async () => {
|
|
1662
|
+
const selectedLink = fauxEntitySuggestions[ 0 ];
|
|
1663
|
+
|
|
1664
|
+
const LinkControlConsumer = () => {
|
|
1665
|
+
const [ link ] = useState( selectedLink );
|
|
1666
|
+
|
|
1667
|
+
return <LinkControl value={ link } />;
|
|
1668
|
+
};
|
|
1669
|
+
|
|
1670
|
+
render( <LinkControlConsumer /> );
|
|
1671
|
+
|
|
1672
|
+
const settingsToggle = screen.queryByRole( 'button', {
|
|
1673
|
+
name: 'Toggle link settings',
|
|
1674
|
+
ariaControls: 'link-settings-1',
|
|
1675
|
+
} );
|
|
1676
|
+
|
|
1677
|
+
expect( settingsToggle ).not.toBeInTheDocument();
|
|
1678
|
+
} );
|
|
1679
|
+
it( 'should provides a means to toggle the link settings', async () => {
|
|
1680
|
+
const selectedLink = fauxEntitySuggestions[ 0 ];
|
|
1681
|
+
|
|
1682
|
+
const LinkControlConsumer = () => {
|
|
1683
|
+
const [ link ] = useState( selectedLink );
|
|
1684
|
+
|
|
1685
|
+
return <LinkControl value={ link } forceIsEditingLink />;
|
|
1686
|
+
};
|
|
1687
|
+
|
|
1688
|
+
render( <LinkControlConsumer /> );
|
|
1689
|
+
|
|
1690
|
+
const user = userEvent.setup();
|
|
1691
|
+
|
|
1692
|
+
const settingsToggle = screen.queryByRole( 'button', {
|
|
1693
|
+
name: 'Toggle link settings',
|
|
1694
|
+
ariaControls: 'link-settings-1',
|
|
1695
|
+
} );
|
|
1696
|
+
|
|
1697
|
+
expect( settingsToggle ).toHaveAttribute( 'aria-expanded', 'false' );
|
|
1698
|
+
|
|
1699
|
+
expect( settingsToggle ).toBeVisible();
|
|
1700
|
+
|
|
1701
|
+
await user.click( settingsToggle );
|
|
1702
|
+
|
|
1703
|
+
expect( settingsToggle ).toHaveAttribute( 'aria-expanded', 'true' );
|
|
1704
|
+
|
|
1705
|
+
const newTabSettingInput = screen.getByRole( 'checkbox', {
|
|
1706
|
+
name: 'Open in new tab',
|
|
1707
|
+
} );
|
|
1708
|
+
|
|
1709
|
+
expect( newTabSettingInput ).toBeVisible();
|
|
1710
|
+
|
|
1711
|
+
await user.click( settingsToggle );
|
|
1712
|
+
|
|
1713
|
+
expect( settingsToggle ).toHaveAttribute( 'aria-expanded', 'false' );
|
|
1714
|
+
expect( newTabSettingInput ).not.toBeVisible();
|
|
1715
|
+
} );
|
|
1716
|
+
|
|
1537
1717
|
it( 'should display "New Tab" setting (in "off" mode) by default when a link is selected', async () => {
|
|
1538
1718
|
const selectedLink = fauxEntitySuggestions[ 0 ];
|
|
1539
1719
|
const expectedSettingText = 'Open in new tab';
|
|
@@ -1541,11 +1721,15 @@ describe( 'Addition Settings UI', () => {
|
|
|
1541
1721
|
const LinkControlConsumer = () => {
|
|
1542
1722
|
const [ link ] = useState( selectedLink );
|
|
1543
1723
|
|
|
1544
|
-
return <LinkControl value={ link } />;
|
|
1724
|
+
return <LinkControl value={ link } forceIsEditingLink />;
|
|
1545
1725
|
};
|
|
1546
1726
|
|
|
1547
1727
|
render( <LinkControlConsumer /> );
|
|
1548
1728
|
|
|
1729
|
+
const user = userEvent.setup();
|
|
1730
|
+
|
|
1731
|
+
await toggleSettingsDrawer( user );
|
|
1732
|
+
|
|
1549
1733
|
const newTabSettingLabel = screen.getByText( expectedSettingText );
|
|
1550
1734
|
expect( newTabSettingLabel ).toBeVisible();
|
|
1551
1735
|
|
|
@@ -1578,12 +1762,17 @@ describe( 'Addition Settings UI', () => {
|
|
|
1578
1762
|
<LinkControl
|
|
1579
1763
|
value={ { ...link, newTab: false, noFollow: true } }
|
|
1580
1764
|
settings={ customSettings }
|
|
1765
|
+
forceIsEditingLink
|
|
1581
1766
|
/>
|
|
1582
1767
|
);
|
|
1583
1768
|
};
|
|
1584
1769
|
|
|
1585
1770
|
render( <LinkControlConsumer /> );
|
|
1586
1771
|
|
|
1772
|
+
const user = userEvent.setup();
|
|
1773
|
+
|
|
1774
|
+
await toggleSettingsDrawer( user );
|
|
1775
|
+
|
|
1587
1776
|
expect( screen.queryAllByRole( 'checkbox' ) ).toHaveLength( 2 );
|
|
1588
1777
|
|
|
1589
1778
|
expect(
|
|
@@ -1932,6 +2121,10 @@ describe( 'Controlling link title text', () => {
|
|
|
1932
2121
|
/>
|
|
1933
2122
|
);
|
|
1934
2123
|
|
|
2124
|
+
const user = userEvent.setup();
|
|
2125
|
+
|
|
2126
|
+
await toggleSettingsDrawer( user );
|
|
2127
|
+
|
|
1935
2128
|
expect(
|
|
1936
2129
|
screen.queryByRole( 'textbox', { name: 'Text' } )
|
|
1937
2130
|
).toBeVisible();
|
|
@@ -1958,6 +2151,10 @@ describe( 'Controlling link title text', () => {
|
|
|
1958
2151
|
/>
|
|
1959
2152
|
);
|
|
1960
2153
|
|
|
2154
|
+
const user = userEvent.setup();
|
|
2155
|
+
|
|
2156
|
+
await toggleSettingsDrawer( user );
|
|
2157
|
+
|
|
1961
2158
|
const textInput = screen.queryByRole( 'textbox', {
|
|
1962
2159
|
name: 'Text',
|
|
1963
2160
|
} );
|
|
@@ -1980,6 +2177,8 @@ describe( 'Controlling link title text', () => {
|
|
|
1980
2177
|
/>
|
|
1981
2178
|
);
|
|
1982
2179
|
|
|
2180
|
+
await toggleSettingsDrawer( user );
|
|
2181
|
+
|
|
1983
2182
|
const textInput = screen.queryByRole( 'textbox', { name: 'Text' } );
|
|
1984
2183
|
|
|
1985
2184
|
await user.clear( textInput );
|
|
@@ -2014,6 +2213,8 @@ describe( 'Controlling link title text', () => {
|
|
|
2014
2213
|
/>
|
|
2015
2214
|
);
|
|
2016
2215
|
|
|
2216
|
+
await toggleSettingsDrawer( user );
|
|
2217
|
+
|
|
2017
2218
|
const textInput = screen.queryByRole( 'textbox', { name: 'Text' } );
|
|
2018
2219
|
|
|
2019
2220
|
expect( textInput ).toBeVisible();
|
|
@@ -2037,3 +2238,11 @@ describe( 'Controlling link title text', () => {
|
|
|
2037
2238
|
).not.toBeInTheDocument();
|
|
2038
2239
|
} );
|
|
2039
2240
|
} );
|
|
2241
|
+
|
|
2242
|
+
async function toggleSettingsDrawer( user ) {
|
|
2243
|
+
const settingsToggle = screen.queryByRole( 'button', {
|
|
2244
|
+
name: 'Toggle link settings',
|
|
2245
|
+
} );
|
|
2246
|
+
|
|
2247
|
+
await user.click( settingsToggle );
|
|
2248
|
+
}
|
|
@@ -174,6 +174,11 @@ function ListView(
|
|
|
174
174
|
[ isMounted.current, draggedClientIds, expandedState, expand, collapse ]
|
|
175
175
|
);
|
|
176
176
|
|
|
177
|
+
// If there are no blocks to show, do not render the list view.
|
|
178
|
+
if ( ! clientIdsTree.length ) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
|
|
177
182
|
return (
|
|
178
183
|
<AsyncModeProvider value={ true }>
|
|
179
184
|
<ListViewDropIndicator
|