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
Show file tree
Hide file tree
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
Expand Up @@ -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:
Expand Down
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
Expand Up @@ -106,6 +106,7 @@ function LinkControl( {
value,
settings,
onChange = noop,
onRemove,
noDirectEntry = false,
showSuggestions = true,
showInitialSuggestions,
Expand Down Expand Up @@ -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>
);
}
Expand Down
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
Expand Up @@ -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;
Expand Down
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
Expand Up @@ -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', () => {
Expand Down
9 changes: 9 additions & 0 deletions packages/format-library/src/link/inline.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
isCollapsed,
applyFormat,
useAnchorRef,
removeFormat,
} from '@wordpress/rich-text';
import { __experimentalLinkControl as LinkControl } from '@wordpress/block-editor';

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -139,6 +147,7 @@ function InlineLinkUI( {
<LinkControl
value={ linkValue }
onChange={ onChangeLink }
onRemove={ removeLink }
forceIsEditingLink={ addingLink }
hasRichPreviews
/>
Expand Down