Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Unlink button to LinkControl popover #32541

Merged
merged 7 commits into from
Jun 30, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/block-editor/src/components/link-control/README.md
Original file line number Diff line number Diff line change
@@ -127,6 +127,14 @@ This `suggestion` will then be _automatically_ passed to the `onChange` handler

As a result of the above, this prop is often used to allow on the fly creation of new entities (eg: `Posts`, `Pages`) based on the text the user has entered into the link search UI. As an example, the Navigation Block uses `createSuggestion` to create Pages on the fly from within the Block itself.

### onRemove

- Type: `Function`
- Required: No
- Default: null

An optional handler, which when passed will trigger the display of an `Unlink` UI within the control. This handler is expected to remove the current `value` of the control thus resetting it back to a default state. The key use case for this is allowing users to remove a link from the control without relying on there being an "unlink" control in the block toolbar.

#### Search `suggestion` values

A `suggestion` should have the following shape:
23 changes: 18 additions & 5 deletions packages/block-editor/src/components/link-control/index.js
Original file line number Diff line number Diff line change
@@ -106,6 +106,7 @@ function LinkControl( {
value,
settings,
onChange = noop,
onRemove,
noDirectEntry = false,
showSuggestions = true,
showInitialSuggestions,
@@ -260,11 +261,23 @@ function LinkControl( {
/>
) }

<LinkControlSettingsDrawer
value={ value }
settings={ settings }
onChange={ onChange }
/>
<div className="block-editor-link-control__tools">
<LinkControlSettingsDrawer
value={ value }
settings={ settings }
onChange={ onChange }
/>
{ onRemove && value && ! isEditingLink && ! isCreatingPage && (
<Button
className="block-editor-link-control__unlink"
isDestructive
variant="link"
onClick={ onRemove }
>
{ __( 'Unlink' ) }
</Button>
) }
</div>
</div>
);
}
15 changes: 14 additions & 1 deletion packages/block-editor/src/components/link-control/style.scss
Original file line number Diff line number Diff line change
@@ -380,10 +380,23 @@ $preview-image-height: 140px;
padding: 10px;
}

.block-editor-link-control__settings {
.block-editor-link-control__tools {
display: flex;
align-items: center;
border-top: $border-width solid $gray-300;
margin: 0;
padding: $grid-unit-20 $grid-unit-30;
}

.block-editor-link-control__unlink {
padding-left: $grid-unit-20;
padding-right: $grid-unit-20;
}

.block-editor-link-control__settings {
flex: 1;
margin: 0;


:last-child {
margin-bottom: 0;
43 changes: 43 additions & 0 deletions packages/block-editor/src/components/link-control/test/index.js
Original file line number Diff line number Diff line change
@@ -227,6 +227,49 @@ describe( 'Basic rendering', () => {
expect( isEditing() ).toBe( false );
} );
} );

describe( 'Unlinking', () => {
it( 'should not show "Unlink" button if no onRemove handler is provided', () => {
act( () => {
render(
<LinkControl value={ { url: 'https://example.com' } } />,
container
);
} );

const unLinkButton = queryByRole( container, 'button', {
name: 'Unlink',
} );

expect( unLinkButton ).toBeNull();
expect( unLinkButton ).not.toBeInTheDocument();
} );

it( 'should show "Unlink" button if a onRemove handler is provided', () => {
const mockOnRemove = jest.fn();
act( () => {
render(
<LinkControl
value={ { url: 'https://example.com' } }
onRemove={ mockOnRemove }
/>,
container
);
} );

const unLinkButton = queryByRole( container, 'button', {
name: 'Unlink',
} );
expect( unLinkButton ).toBeTruthy();
expect( unLinkButton ).toBeInTheDocument();

act( () => {
Simulate.click( unLinkButton );
} );

expect( mockOnRemove ).toHaveBeenCalled();
} );
} );
} );

describe( 'Searching for a link', () => {
9 changes: 9 additions & 0 deletions packages/format-library/src/link/inline.js
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ import {
isCollapsed,
applyFormat,
useAnchorRef,
removeFormat,
} from '@wordpress/rich-text';
import { __experimentalLinkControl as LinkControl } from '@wordpress/block-editor';

@@ -48,6 +49,13 @@ function InlineLinkUI( {
...nextLinkValue,
};

function removeLink() {
const newValue = removeFormat( value, 'core/link' );
onChange( newValue );
stopAddingLink();
speak( __( 'Link removed.' ), 'assertive' );
}

function onChangeLink( nextValue ) {
// Merge with values from state, both for the purpose of assigning the
// next state value, and for use in constructing the new link format if
@@ -139,6 +147,7 @@ function InlineLinkUI( {
<LinkControl
value={ linkValue }
onChange={ onChangeLink }
onRemove={ removeLink }
forceIsEditingLink={ addingLink }
hasRichPreviews
/>