Skip to content

Commit

Permalink
Refactor LinkControl component to support React 17 (#32552)
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad authored Jun 10, 2021
1 parent f3d6bbf commit 183069a
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 35 deletions.
41 changes: 22 additions & 19 deletions packages/block-editor/src/components/link-control/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { keyboardReturn } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
import { useRef, useState, useEffect } from '@wordpress/element';
import { focus } from '@wordpress/dom';
import { ENTER } from '@wordpress/keycodes';

/**
* Internal dependencies
Expand Down Expand Up @@ -148,26 +149,14 @@ function LinkControl( {
isMounting.current = false;
return;
}
// When `isEditingLink` changes, a focus loss could occur
// since the link input may be removed from the DOM. To avoid this,
// reinstate focus to a suitable target if focus has in-fact been lost.
// Note that the check is necessary because while typically unsetting
// edit mode would render the read-only mode's link element, it isn't
// guaranteed. The link input may continue to be shown if the next value
// is still unassigned after calling `onChange`.
const hadFocusLoss = ! wrapperNode.current.contains(
wrapperNode.current.ownerDocument.activeElement
);

if ( hadFocusLoss ) {
// Prefer to focus a natural focusable descendent of the wrapper,
// but settle for the wrapper if there are no other options.
const nextFocusTarget =
focus.focusable.find( wrapperNode.current )[ 0 ] ||
wrapperNode.current;
// When switching between editable and non editable LinkControl
// move focus to the first element to avoid focus loss.
const nextFocusTarget =
focus.focusable.find( wrapperNode.current )[ 0 ] ||
wrapperNode.current;

nextFocusTarget.focus();
}
nextFocusTarget.focus();

isEndingEditWithFocus.current = false;
}, [ isEditingLink ] );
Expand All @@ -193,6 +182,13 @@ function LinkControl( {
stopEditing();
};

const handleSubmitButton = () => {
if ( currentInputValue !== value?.url ) {
onChange( { url: currentInputValue } );
}
stopEditing();
};

return (
<div
tabIndex={ -1 }
Expand Down Expand Up @@ -228,7 +224,14 @@ function LinkControl( {
>
<div className="block-editor-link-control__search-actions">
<Button
type="submit"
onClick={ () => handleSubmitButton() }
onKeyDown={ ( event ) => {
const { keyCode } = event;
if ( keyCode === ENTER ) {
event.preventDefault();
handleSubmitButton();
}
} }
label={ __( 'Submit' ) }
icon={ keyboardReturn }
className="block-editor-link-control__search-submit"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,6 @@ const LinkControlSearchInput = forwardRef(
setFocusedSuggestion( suggestion );
};

const onFormSubmit = ( event ) => {
event.preventDefault();
onSuggestionSelected( focusedSuggestion || { url: value } );
};

const handleRenderSuggestions = ( props ) =>
renderSuggestions( {
...props,
Expand Down Expand Up @@ -118,7 +113,7 @@ const LinkControlSearchInput = forwardRef(
};

return (
<form onSubmit={ onFormSubmit }>
<div>
<URLInput
className={ className }
value={ value }
Expand All @@ -132,10 +127,15 @@ const LinkControlSearchInput = forwardRef(
__experimentalShowInitialSuggestions={
showInitialSuggestions
}
onSubmit={ ( suggestion ) => {
onSuggestionSelected(
suggestion || focusedSuggestion || { url: value }
);
} }
ref={ ref }
/>
{ children }
</form>
</div>
);
}
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Basic rendering should render 1`] = `"<div tabindex=\\"-1\\" class=\\"block-editor-link-control\\"><div class=\\"block-editor-link-control__search-input-wrapper\\"><form><div class=\\"components-base-control block-editor-url-input block-editor-link-control__search-input css-wdf2ti-Wrapper e1puf3u0\\"><div class=\\"components-base-control__field css-11vcxb9-StyledField e1puf3u1\\"><input required=\\"\\" class=\\"block-editor-url-input__input\\" type=\\"text\\" placeholder=\\"Search or type url\\" role=\\"combobox\\" aria-label=\\"URL\\" aria-expanded=\\"false\\" aria-autocomplete=\\"list\\" aria-owns=\\"block-editor-url-input-suggestions-0\\" value=\\"\\"></div></div><div class=\\"block-editor-link-control__search-actions\\"><button type=\\"submit\\" class=\\"components-button block-editor-link-control__search-submit has-icon\\" aria-label=\\"Submit\\"><svg width=\\"24\\" height=\\"24\\" xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"-2 -2 24 24\\" role=\\"img\\" aria-hidden=\\"true\\" focusable=\\"false\\"><path d=\\"M6.734 16.106l2.176-2.38-1.093-1.028-3.846 4.158 3.846 4.157 1.093-1.027-2.176-2.38h2.811c1.125 0 2.25.03 3.374 0 1.428-.001 3.362-.25 4.963-1.277 1.66-1.065 2.868-2.906 2.868-5.859 0-2.479-1.327-4.896-3.65-5.93-1.82-.813-3.044-.8-4.806-.788l-.567.002v1.5c.184 0 .368 0 .553-.002 1.82-.007 2.704-.014 4.21.657 1.854.827 2.76 2.657 2.76 4.561 0 2.472-.973 3.824-2.178 4.596-1.258.807-2.864 1.04-4.163 1.04h-.02c-1.115.03-2.229 0-3.344 0H6.734z\\"></path></svg></button></div></form></div><fieldset class=\\"block-editor-link-control__settings\\"><legend class=\\"components-visually-hidden\\">Currently selected link settings</legend><div class=\\"components-base-control components-toggle-control block-editor-link-control__setting css-wdf2ti-Wrapper e1puf3u0\\"><div class=\\"components-base-control__field css-11vcxb9-StyledField e1puf3u1\\"><span class=\\"components-form-toggle\\"><input class=\\"components-form-toggle__input\\" id=\\"inspector-toggle-control-0\\" type=\\"checkbox\\"><span class=\\"components-form-toggle__track\\"></span><span class=\\"components-form-toggle__thumb\\"></span></span><label for=\\"inspector-toggle-control-0\\" class=\\"components-toggle-control__label\\">Open in new tab</label></div></div></fieldset></div>"`;

exports[`Rich link previews should display a rich preview when data is available 1`] = `
.emotion-2 {
-webkit-box-orient: vertical;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ describe( 'Basic rendering', () => {
const searchInput = getURLInput();

expect( searchInput ).not.toBeNull();
expect( container.innerHTML ).toMatchSnapshot();
} );

it( 'should not render protocol in links', async () => {
Expand Down Expand Up @@ -947,7 +946,6 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
const searchResultElements = container.querySelectorAll(
'[role="listbox"] [role="option"]'
);
const form = container.querySelector( 'form' );
const createButton = first(
Array.from( searchResultElements ).filter( ( result ) =>
result.innerHTML.includes( 'Create:' )
Expand All @@ -964,7 +962,7 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
} );

await act( async () => {
Simulate.submit( form );
Simulate.keyDown( searchInput, { keyCode: ENTER } );
} );

await eventLoopTick();
Expand Down Expand Up @@ -1394,7 +1392,6 @@ describe( 'Selecting links', () => {
// Search Input UI
const searchInput = getURLInput();
searchInput.focus();
const form = container.querySelector( 'form' );

// Simulate searching for a term
act( () => {
Expand Down Expand Up @@ -1460,9 +1457,6 @@ describe( 'Selecting links', () => {
act( () => {
Simulate.keyDown( searchInput, { keyCode: ENTER } );
} );
act( () => {
Simulate.submit( form );
} );

// Check that the suggestion selected via is now shown as selected
const currentLink = container.querySelector(
Expand Down
16 changes: 16 additions & 0 deletions packages/block-editor/src/components/url-input/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,15 @@ class URLInput extends Component {
}
break;
}

// Submitting while loading should trigger onSubmit
case ENTER: {
if ( this.props.onSubmit ) {
this.props.onSubmit();
}

break;
}
}

return;
Expand Down Expand Up @@ -332,7 +341,14 @@ class URLInput extends Component {
if ( this.state.selectedSuggestion !== null ) {
event.stopPropagation();
this.selectLink( suggestion );

if ( this.props.onSubmit ) {
this.props.onSubmit( suggestion );
}
} else if ( this.props.onSubmit ) {
this.props.onSubmit();
}

break;
}
}
Expand Down

0 comments on commit 183069a

Please sign in to comment.