diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index c25ed5cd1187a8..412e10fa4d89b1 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -6,8 +6,14 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { Button, Spinner, Notice, TextControl } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; +import { + Button, + Spinner, + Notice, + TextControl, + VisuallyHidden, +} from '@wordpress/components'; +import { __, sprintf } from '@wordpress/i18n'; import { useRef, useState, useEffect } from '@wordpress/element'; import { focus } from '@wordpress/dom'; import { ENTER } from '@wordpress/keycodes'; @@ -15,7 +21,8 @@ import { isShallowEqualObjects } from '@wordpress/is-shallow-equal'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as preferencesStore } from '@wordpress/preferences'; import { keyboardReturn } from '@wordpress/icons'; - +import { useInstanceId } from '@wordpress/compose'; +import { speak } from '@wordpress/a11y'; /** * Internal dependencies */ @@ -201,11 +208,24 @@ function LinkControl( { const { createPage, isCreatingPage, errorMessage } = useCreatePage( createSuggestion ); + function setEditingMode( nextEditingMode ) { + setIsEditingLink( nextEditingMode ); + + speak( + nextEditingMode + ? __( 'Entering link edit mode' ) + : __( 'Leaving link edit mode' ), + 'assertive' + ); + } + useEffect( () => { if ( forceIsEditingLink === undefined ) { return; } + // Do not announcement automatic mode state change + // via speak(). setIsEditingLink( forceIsEditingLink ); }, [ forceIsEditingLink ] ); @@ -243,7 +263,7 @@ function LinkControl( { wrapperNode.current.ownerDocument.activeElement ); - setIsEditingLink( false ); + setEditingMode( false ); }; const handleSelectSuggestion = ( updatedValue ) => { @@ -335,23 +355,54 @@ function LinkControl( { const showTextControl = hasLinkValue && hasTextControl; const isEditing = ( isEditingLink || ! value ) && ! isCreatingPage; + const isCreating = isEditingLink && ! value && ! isCreatingPage; const isDisabled = ! valueHasChanges || currentInputIsEmpty; const showSettings = !! settings?.length && isEditingLink && hasLinkValue; + const dialogTitleId = useInstanceId( + LinkControl, + `block-editor-link-control___title` + ); + const dialogDescritionId = useInstanceId( + LinkControl, + `block-editor-link-control___description` + ); + + const isPreviewing = value && ! isEditingLink && ! isCreatingPage; return (
{ isCreatingPage && (
- { __( 'Creating' ) }… + + { __( 'Creating' ) }…
) } { isEditing && ( <> + +

+ { sprintf( + // translators: %s: action name for the link mode (edit or create). + __( '%s Link' ), + isCreating ? __( 'Create' ) : __( 'Edit' ) + ) } +

+ +

+ { sprintf( + // translators: %s: action name for the link action (edit or create). + __( '%s the link' ), + isCreating ? __( 'Creating' ) : __( 'Editing' ) + ) } +

+
) } - - ) } - { value && ! isEditingLink && ! isCreatingPage && ( - setIsEditingLink( true ) } - hasRichPreviews={ hasRichPreviews } - hasUnlinkControl={ shownUnlinkControl } - additionalControls={ () => { - // Expose the "Opens in new tab" settings in the preview - // as it is the most common setting to change. - if ( - settings?.find( - ( setting ) => setting.id === 'opensInNewTab' - ) - ) { - return ( - id === 'opensInNewTab' - ) } - onChange={ onChange } - /> - ); - } - } } - onRemove={ () => { - onRemove(); - setIsEditingLink( true ); - } } - /> - ) } + { showSettings && ( +
+ { ! currentInputIsEmpty && ( + + + + ) } +
+ ) } - { showSettings && ( -
- { ! currentInputIsEmpty && ( - - - + { showActions && ( +
+ + +
) } -
+ ) } - { showActions && ( -
- - -
+ { isPreviewing && ( + <> + +

{ __( 'Preview Link' ) }

+

+ { __( 'Previewing the currently selected link.' ) } +

+
+ setEditingMode( true ) } + hasRichPreviews={ hasRichPreviews } + hasUnlinkControl={ shownUnlinkControl } + additionalControls={ () => { + // Expose the "Opens in new tab" settings in the preview + // as it is the most common setting to change. + if ( + settings?.find( + ( setting ) => + setting.id === 'opensInNewTab' + ) + ) { + return ( + id === 'opensInNewTab' + ) } + onChange={ onChange } + /> + ); + } + } } + onRemove={ () => { + onRemove(); + setEditingMode( true ); + } } + /> + ) } { renderControlBottom && renderControlBottom() } diff --git a/packages/block-editor/src/components/link-control/link-preview.js b/packages/block-editor/src/components/link-control/link-preview.js index 8272602cde908d..c9fc88fe9a1d1e 100644 --- a/packages/block-editor/src/components/link-control/link-preview.js +++ b/packages/block-editor/src/components/link-control/link-preview.js @@ -10,6 +10,7 @@ import { __ } from '@wordpress/i18n'; import { Button, ExternalLink, + VisuallyHidden, __experimentalText as Text, } from '@wordpress/components'; import { filterURLForDisplay, safeDecodeURI } from '@wordpress/url'; @@ -20,7 +21,6 @@ import { __unstableStripHTML as stripHTML } from '@wordpress/dom'; * Internal dependencies */ import { ViewerSlot } from './viewer-slot'; - import useRichUrlData from './use-rich-url-data'; export default function LinkPreview( { @@ -84,28 +84,43 @@ export default function LinkPreview( { > { icon } - +
{ ! isEmptyURL ? ( <> - - { displayTitle } - + +
Link title
+
+
+ + { displayTitle } + +
{ value?.url && displayTitle !== displayURL && ( - - { displayURL } - + <> + +
Link URL
+
+
+ { displayURL } +
+ ) } ) : ( - - { __( 'Link is empty' ) } - + <> + +
Link value
+
+
+ { __( 'Link is empty' ) } +
+ ) } - +