diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js
index d2bac48450bb0..d16bd26d2b600 100644
--- a/packages/block-editor/src/components/link-control/index.js
+++ b/packages/block-editor/src/components/link-control/index.js
@@ -7,7 +7,6 @@ import { noop } from 'lodash';
* WordPress dependencies
*/
import { Button, Spinner, Notice } from '@wordpress/components';
-import { keyboardReturn } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
import { useRef, useState, useEffect } from '@wordpress/element';
import { focus } from '@wordpress/dom';
@@ -200,13 +199,14 @@ function LinkControl( {
>
{ isCreatingPage && (
- { __( 'Creating' ) }…
+
+ { __( 'Creating page' ) }…
) }
{ ( isEditingLink || ! value ) && ! isCreatingPage && (
<>
-
+
-
-
-
+
+
{ errorMessage && (
) }
+
+
>
) }
@@ -253,12 +260,6 @@ function LinkControl( {
onEditClick={ () => setIsEditingLink( true ) }
/>
) }
-
-
);
}
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 ef6bd09fcf270..4cf7622821919 100644
--- a/packages/block-editor/src/components/link-control/link-preview.js
+++ b/packages/block-editor/src/components/link-control/link-preview.js
@@ -7,7 +7,7 @@ import classnames from 'classnames';
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
-import { Button, ExternalLink } from '@wordpress/components';
+import { Button } from '@wordpress/components';
import { filterURLForDisplay, safeDecodeURI } from '@wordpress/url';
/**
@@ -24,31 +24,28 @@ export default function LinkPreview( { value, onEditClick } ) {
-
-
- { ( value && value.title ) || displayURL }
-
- { value && value.title && (
-
- { displayURL }
-
- ) }
-
-
+
+
+
);
diff --git a/packages/block-editor/src/components/link-control/search-create-button.js b/packages/block-editor/src/components/link-control/search-create-button.js
index 679c5df55c0fc..025f3341e3985 100644
--- a/packages/block-editor/src/components/link-control/search-create-button.js
+++ b/packages/block-editor/src/components/link-control/search-create-button.js
@@ -30,7 +30,7 @@ export const LinkControlSearchCreate = ( {
text = createInterpolateElement(
sprintf(
/* translators: %s: search term. */
- __( 'Create: %s' ),
+ __( '"%s"' ),
searchTerm
),
{ mark: }
@@ -48,16 +48,16 @@ export const LinkControlSearchCreate = ( {
) }
onClick={ onClick }
>
+
+ Create draft
+
+
+ { text }
+
-
-
-
- { text }
-
-
);
};
diff --git a/packages/block-editor/src/components/link-control/search-input.js b/packages/block-editor/src/components/link-control/search-input.js
index c8ae882ae1aba..b22d444d85eb6 100644
--- a/packages/block-editor/src/components/link-control/search-input.js
+++ b/packages/block-editor/src/components/link-control/search-input.js
@@ -123,7 +123,7 @@ const LinkControlSearchInput = forwardRef(
className={ className }
value={ value }
onChange={ onInputChange }
- placeholder={ placeholder ?? __( 'Search or type url' ) }
+ placeholder={ placeholder ?? __( 'Search or type a url…' ) }
__experimentalRenderSuggestions={
showSuggestions ? handleRenderSuggestions : null
}
diff --git a/packages/block-editor/src/components/link-control/search-item.js b/packages/block-editor/src/components/link-control/search-item.js
index 804e5c95f05af..d52c85d2a9655 100644
--- a/packages/block-editor/src/components/link-control/search-item.js
+++ b/packages/block-editor/src/components/link-control/search-item.js
@@ -7,9 +7,7 @@ import classnames from 'classnames';
* WordPress dependencies
*/
import { safeDecodeURI, filterURLForDisplay } from '@wordpress/url';
-import { __ } from '@wordpress/i18n';
import { Button, TextHighlight } from '@wordpress/components';
-import { Icon, globe } from '@wordpress/icons';
export const LinkControlSearchItem = ( {
itemProps,
@@ -30,12 +28,6 @@ export const LinkControlSearchItem = ( {
'is-entity': ! isURL,
} ) }
>
- { isURL && (
-
- ) }
-
- { ! isURL &&
- ( filterURLForDisplay(
- safeDecodeURI( suggestion.url )
- ) ||
- '' ) }
- { isURL && __( 'Press ENTER to add this link' ) }
+
+ { filterURLForDisplay( safeDecodeURI( suggestion.url ) ) }
{ shouldShowType && suggestion.type && (
diff --git a/packages/block-editor/src/components/link-control/search-results.js b/packages/block-editor/src/components/link-control/search-results.js
index cc24b81f18b17..cf2c700b4f0ca 100644
--- a/packages/block-editor/src/components/link-control/search-results.js
+++ b/packages/block-editor/src/components/link-control/search-results.js
@@ -114,6 +114,14 @@ export default function LinkControlSearchResults( {
return null;
}
+ if (
+ directLinkEntryTypes.includes(
+ suggestion.type.toLowerCase()
+ )
+ ) {
+ return null;
+ }
+
return (
.block-editor-link-control__search-item.block-editor-link-control__search-item {
- padding: 10px;
-}
-.block-editor-link-control__settings {
- border-top: $border-width solid $gray-300;
- margin: 0;
- padding: $grid-unit-20 $grid-unit-30;
+ .block-editor-link-control__search-create-description {
+ display: block;
+ font-size: 12px;
+ color: $gray-900;
- :last-child {
- margin-bottom: 0;
+ mark {
+ font-weight: normal;
+ }
}
- .is-alternate & {
- border-top: $border-width solid $gray-900;
+ .block-editor-link-control__search-create-icon {
+ position: absolute;
+ top: 12px;
+ right: 8px;
}
}
-.block-editor-link-control__setting {
- margin-bottom: $grid-unit-20;
+// ## Link Settings
+// Links can be set to open in a new window
+.block-editor-link-control__settings {
+ padding: $grid-unit-15;
+ margin: ($grid-unit-15 / 2) (-$grid-unit-15/2) (-$grid-unit-15/2) (-$grid-unit-15/2);
+ border-top: 1px solid $gray-900;
- :last-child {
- margin-bottom: 0;
+ .components-base-control__field {
+ margin: 0;
}
}
-.block-editor-link-control .block-editor-link-control__search-input .components-spinner {
- display: block;
-
- &.components-spinner { // Specificity override.
- position: absolute;
- left: auto;
- bottom: auto;
- /*
- * Position spinner to the left of the actions.
- *
- * Compensate for:
- * - Input margin ($grid-unit-20)
- * - Border (1px)
- * - Vertically, for the difference in height between the input (40px)
- * and the spinner.
- * - Horizontally, adjust for the width occupied by the icon buttons,
- * then artificially create spacing that mimics as if the spinner
- * were center-padded to the same width as an icon button.
- */
- top: $grid-unit-20 + 1px + ( ( 40px - $spinner-size ) / 2 );
- right: $grid-unit-20 + 1px + ( $button-size * $block-editor-link-control-number-of-actions ) + ( ( $button-size - $spinner-size ) / 2 );
- }
+// ## Link Preview
+// When clicking an existing link, the preview popover
+// shows the current link and a button to edit.
+.block-editor-link-control__link {
+ display: flex;
+ align-items: center;
+ flex-direction: row-reverse;
}
-.block-editor-link-control__search-item-action {
- margin-left: auto; // push to far right hand side
- flex-shrink: 0;
+.block-editor-link-control__link-current-url {
+ margin-right: $grid-unit-10;
+
+ // An extra span is required as buttons normally display
+ // with inline-flex, but this doesn't support the truncation.
+ span {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 280px;
+ }
}
diff --git a/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap b/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap
index dd0bc6f80877c..26ff6d4006ba1 100644
--- a/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap
+++ b/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Basic rendering should render 1`] = `""`;
+exports[`Basic rendering should render 1`] = `""`;
diff --git a/packages/block-editor/src/components/link-control/test/index.js b/packages/block-editor/src/components/link-control/test/index.js
index c4feb75eca8e9..9fd55ec0e2124 100644
--- a/packages/block-editor/src/components/link-control/test/index.js
+++ b/packages/block-editor/src/components/link-control/test/index.js
@@ -3,7 +3,7 @@
*/
import { render, unmountComponentAtNode } from 'react-dom';
import { act, Simulate } from 'react-dom/test-utils';
-import { queryByText, queryByRole } from '@testing-library/react';
+import { queryByText } from '@testing-library/react';
import { default as lodash, first, last, nth, uniqueId } from 'lodash';
/**
* WordPress dependencies
@@ -79,7 +79,7 @@ function getSearchResults() {
function getCurrentLink() {
return container.querySelector(
- '.block-editor-link-control__search-item.is-current'
+ '.block-editor-link-control__link.is-current'
);
}
@@ -338,8 +338,8 @@ describe( 'Searching for a link', () => {
const mockFetchSuggestionsFirstArg =
mockFetchSearchSuggestions.mock.calls[ 0 ][ 0 ];
- // Given we're mocking out the results we should always have 4 mark elements.
- expect( searchResultTextHighlightElements ).toHaveLength( 4 );
+ // Given we're mocking out the results we should always have 3 mark elements.
+ expect( searchResultTextHighlightElements ).toHaveLength( 3 );
// Make sure there are no `mark` elements which contain anything other
// than the trimmed search term (ie: no whitespace).
@@ -378,26 +378,9 @@ describe( 'Searching for a link', () => {
const searchResultElements = getSearchResults();
- const lastSearchResultItemHTML = last( searchResultElements )
- .innerHTML;
- const additionalDefaultFallbackURLSuggestionLength = 1;
-
// We should see a search result for each of the expect search suggestions
- // plus 1 additional one for the fallback URL suggestion
expect( searchResultElements ).toHaveLength(
- fauxEntitySuggestions.length +
- additionalDefaultFallbackURLSuggestionLength
- );
-
- // The last item should be a URL search suggestion
- expect( lastSearchResultItemHTML ).toEqual(
- expect.stringContaining( searchTerm )
- );
- expect( lastSearchResultItemHTML ).toEqual(
- expect.stringContaining( 'URL' )
- );
- expect( lastSearchResultItemHTML ).toEqual(
- expect.stringContaining( 'Press ENTER to add this link' )
+ fauxEntitySuggestions.length
);
}
);
@@ -456,23 +439,7 @@ describe( 'Manual link entry', () => {
await eventLoopTick();
const searchResultElements = getSearchResults();
-
- const firstSearchResultItemHTML =
- searchResultElements[ 0 ].innerHTML;
- const expectedResultsLength = 1;
-
- expect( searchResultElements ).toHaveLength(
- expectedResultsLength
- );
- expect( firstSearchResultItemHTML ).toEqual(
- expect.stringContaining( searchTerm )
- );
- expect( firstSearchResultItemHTML ).toEqual(
- expect.stringContaining( 'URL' )
- );
- expect( firstSearchResultItemHTML ).toEqual(
- expect.stringContaining( 'Press ENTER to add this link' )
- );
+ expect( searchResultElements[ 0 ] ).toBeUndefined();
}
);
@@ -483,7 +450,7 @@ describe( 'Manual link entry', () => {
[ '#internal-anchor', 'internal' ],
] )(
'should recognise "%s" as a %s link and handle as manual entry by displaying a single suggestion',
- async ( searchTerm, searchType ) => {
+ async ( searchTerm ) => {
act( () => {
render( , container );
} );
@@ -502,23 +469,7 @@ describe( 'Manual link entry', () => {
await eventLoopTick();
const searchResultElements = getSearchResults();
-
- const firstSearchResultItemHTML =
- searchResultElements[ 0 ].innerHTML;
- const expectedResultsLength = 1;
-
- expect( searchResultElements ).toHaveLength(
- expectedResultsLength
- );
- expect( firstSearchResultItemHTML ).toEqual(
- expect.stringContaining( searchTerm )
- );
- expect( firstSearchResultItemHTML ).toEqual(
- expect.stringContaining( searchType )
- );
- expect( firstSearchResultItemHTML ).toEqual(
- expect.stringContaining( 'Press ENTER to add this link' )
- );
+ expect( searchResultElements[ 0 ] ).toBeUndefined();
}
);
} );
@@ -584,7 +535,7 @@ describe( 'Default search suggestions', () => {
expect( mockFetchSearchSuggestions ).not.toHaveBeenCalled();
//
- // Click the "Edit/Change" button and check initial suggestions are not
+ // Click the "Edit" button and check initial suggestions are not
// shown.
//
const currentLinkUI = getCurrentLink();
@@ -604,8 +555,8 @@ describe( 'Default search suggestions', () => {
// search input is set to the URL value
expect( searchInput.value ).toEqual( fauxEntitySuggestions[ 0 ].url );
- // it should match any url that's like ?p= and also include a URL option
- expect( searchResultElements ).toHaveLength( 5 );
+ // it should match any url that's like ?p=
+ expect( searchResultElements ).toHaveLength( 4 );
expect( searchInput.getAttribute( 'aria-expanded' ) ).toBe( 'true' );
@@ -760,7 +711,7 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
const createButton = first(
Array.from( searchResultElements ).filter( ( result ) =>
- result.innerHTML.includes( 'Create:' )
+ result.innerHTML.includes( 'Create draft' )
)
);
@@ -803,9 +754,6 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
const currentLinkHTML = currentLink.innerHTML;
- expect( currentLinkHTML ).toEqual(
- expect.stringContaining( entityNameText )
- );
expect( currentLinkHTML ).toEqual(
expect.stringContaining( '/?p=123' )
);
@@ -857,7 +805,7 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
const createButton = first(
Array.from( searchResultElements ).filter( ( result ) =>
- result.innerHTML.includes( 'Create:' )
+ result.innerHTML.includes( 'Create draft' )
)
);
@@ -873,9 +821,6 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
const currentLinkHTML = currentLink.innerHTML;
- expect( currentLinkHTML ).toEqual(
- expect.stringContaining( 'Some new page to create' )
- );
expect( currentLinkHTML ).toEqual(
expect.stringContaining( '/?p=123' )
);
@@ -930,7 +875,7 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
const form = container.querySelector( 'form' );
const createButton = first(
Array.from( searchResultElements ).filter( ( result ) =>
- result.innerHTML.includes( 'Create:' )
+ result.innerHTML.includes( 'Create draft' )
)
);
@@ -1028,7 +973,7 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
);
const createButton = first(
Array.from( searchResultElements ).filter( ( result ) =>
- result.innerHTML.includes( 'Create:' )
+ result.innerHTML.includes( 'Create draft' )
)
);
@@ -1153,7 +1098,7 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
);
let createButton = first(
Array.from( searchResultElements ).filter( ( result ) =>
- result.innerHTML.includes( 'Create:' )
+ result.innerHTML.includes( 'Create draft' )
)
);
@@ -1217,17 +1162,10 @@ describe( 'Selecting links', () => {
// TODO: select by aria role or visible text
const currentLink = getCurrentLink();
- const currentLinkHTML = currentLink.innerHTML;
const currentLinkAnchor = currentLink.querySelector(
`[href="${ selectedLink.url }"]`
);
- expect( currentLinkHTML ).toEqual(
- expect.stringContaining( selectedLink.title )
- );
- expect(
- queryByRole( currentLink, 'button', { name: 'Edit' } )
- ).toBeTruthy();
expect( currentLinkAnchor ).not.toBeNull();
} );
@@ -1270,16 +1208,6 @@ describe( 'Selecting links', () => {
describe( 'Selection using mouse click', () => {
it.each( [
[ 'entity', 'hello world', first( fauxEntitySuggestions ) ], // entity search
- [
- 'url',
- 'https://www.wordpress.org',
- {
- id: '1',
- title: 'https://www.wordpress.org',
- url: 'https://www.wordpress.org',
- type: 'URL',
- },
- ], // url
] )(
'should display a current selected link UI when a %s suggestion for the search "%s" is clicked',
async ( type, searchTerm, selectedLink ) => {
@@ -1321,7 +1249,7 @@ describe( 'Selecting links', () => {
} );
const currentLink = container.querySelector(
- '.block-editor-link-control__search-item.is-current'
+ '.block-editor-link-control__link.is-current'
);
const currentLinkHTML = currentLink.innerHTML;
const currentLinkAnchor = currentLink.querySelector(
@@ -1329,9 +1257,6 @@ describe( 'Selecting links', () => {
);
// Check that this suggestion is now shown as selected
- expect( currentLinkHTML ).toEqual(
- expect.stringContaining( selectedLink.title )
- );
expect( currentLinkHTML ).toEqual(
expect.stringContaining( 'Edit' )
);
@@ -1343,16 +1268,6 @@ describe( 'Selecting links', () => {
describe( 'Selection using keyboard', () => {
it.each( [
[ 'entity', 'hello world', first( fauxEntitySuggestions ) ], // entity search
- [
- 'url',
- 'https://www.wordpress.org',
- {
- id: '1',
- title: 'https://www.wordpress.org',
- url: 'https://www.wordpress.org',
- type: 'URL',
- },
- ], // url
] )(
'should display a current selected link UI when an %s suggestion for the search "%s" is selected using the keyboard',
async ( type, searchTerm, selectedLink ) => {
@@ -1446,7 +1361,7 @@ describe( 'Selecting links', () => {
// Check that the suggestion selected via is now shown as selected
const currentLink = container.querySelector(
- '.block-editor-link-control__search-item.is-current'
+ '.block-editor-link-control__link.is-current'
);
const currentLinkHTML = currentLink.innerHTML;
const currentLinkAnchor = currentLink.querySelector(
@@ -1458,9 +1373,6 @@ describe( 'Selecting links', () => {
true
);
- expect( currentLinkHTML ).toEqual(
- expect.stringContaining( selectedLink.title )
- );
expect( currentLinkHTML ).toEqual(
expect.stringContaining( 'Edit' )
);
@@ -1559,6 +1471,15 @@ describe( 'Addition Settings UI', () => {
render( , container );
} );
+ // Click the "Edit" button to trigger into the editing mode.
+ const editButton = Array.from(
+ container.querySelectorAll( 'button' )
+ ).find( ( button ) => button.innerHTML.includes( 'Edit' ) );
+
+ act( () => {
+ Simulate.click( editButton );
+ } );
+
const newTabSettingLabel = Array.from(
container.querySelectorAll( 'label' )
).find(
@@ -1611,6 +1532,15 @@ describe( 'Addition Settings UI', () => {
render( , container );
} );
+ // Click the "Edit" button to trigger into the editing mode.
+ const editButton = Array.from(
+ container.querySelectorAll( 'button' )
+ ).find( ( button ) => button.innerHTML.includes( 'Edit' ) );
+
+ act( () => {
+ Simulate.click( editButton );
+ } );
+
// Grab the elements using user perceivable DOM queries
const settingsLegend = Array.from(
container.querySelectorAll( 'legend' )
diff --git a/packages/block-library/src/button/edit.js b/packages/block-library/src/button/edit.js
index fe32f2ab5d837..718f7df49e814 100644
--- a/packages/block-library/src/button/edit.js
+++ b/packages/block-library/src/button/edit.js
@@ -129,6 +129,7 @@ function URLPicker( {
position="bottom center"
onClose={ () => setIsURLPickerOpen( false ) }
anchorRef={ anchorRef?.current }
+ isAlternate={ true }
>
setIsLinkOpen( false ) }
>
%s'
+ '"%s" (page)'
);
} else {
/* translators: %s: search term. */
format = __(
- 'Create draft page: %s'
+ '"%s" (page)'
);
}
return createInterpolateElement(
diff --git a/packages/e2e-tests/specs/editor/blocks/buttons.test.js b/packages/e2e-tests/specs/editor/blocks/buttons.test.js
index 9253d29b1cbd4..eb302a3aa128f 100644
--- a/packages/e2e-tests/specs/editor/blocks/buttons.test.js
+++ b/packages/e2e-tests/specs/editor/blocks/buttons.test.js
@@ -46,9 +46,7 @@ describe( 'Buttons', () => {
await page.keyboard.press( 'Enter' );
// Make sure that the dialog is still opened, and that focus is retained
// within (focusing on the link preview).
- await page.waitForSelector(
- ':focus.block-editor-link-control__search-item-title'
- );
+ await page.waitForSelector( ':focus.block-editor-link-control__link' );
expect( await getEditedPostContent() ).toMatchSnapshot();
} );
diff --git a/packages/format-library/src/link/inline.js b/packages/format-library/src/link/inline.js
index 4c78c9d1475a9..766261702cf3c 100644
--- a/packages/format-library/src/link/inline.js
+++ b/packages/format-library/src/link/inline.js
@@ -135,6 +135,7 @@ function InlineLinkUI( {
focusOnMount={ focusOnMount.current }
onClose={ stopAddingLink }
position="bottom center"
+ isAlternate={ true }
>