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

Remove Popover from LinkControl component #19638

Merged
merged 3 commits into from
Jan 14, 2020
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
154 changes: 63 additions & 91 deletions packages/block-editor/src/components/link-control/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,14 @@
* External dependencies
*/
import classnames from 'classnames';
import { isFunction, noop, startsWith } from 'lodash';
import { noop, startsWith } from 'lodash';

/**
* WordPress dependencies
*/
import {
Button,
ExternalLink,
Popover,
} from '@wordpress/components';
import { Button, ExternalLink } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

import {
useCallback,
useState,
Fragment,
} from '@wordpress/element';
import { useCallback, useState, Fragment } from '@wordpress/element';

import {
safeDecodeURI,
Expand All @@ -28,8 +19,8 @@ import {
getProtocol,
} from '@wordpress/url';

import { withInstanceId, compose } from '@wordpress/compose';
import { withSelect } from '@wordpress/data';
import { useInstanceId } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
Expand All @@ -41,16 +32,13 @@ import LinkControlSearchInput from './search-input';
const MODE_EDIT = 'edit';
// const MODE_SHOW = 'show';

function LinkControl( {
className,
export function LinkControl( {
value,
settings,
fetchSearchSuggestions,
instanceId,
onClose = noop,
onChange = noop,
fetchSearchSuggestions,
} ) {
// State
const instanceId = useInstanceId( LinkControl );
const [ inputValue, setInputValue ] = useState( '' );
const [ isEditingLink, setIsEditingLink ] = useState( ! value || ! value.url );

Expand Down Expand Up @@ -83,11 +71,6 @@ function LinkControl( {
}
};

const closeLinkUI = () => {
resetInput();
onClose();
};

const resetInput = () => {
setInputValue( '' );
};
Expand Down Expand Up @@ -176,77 +159,66 @@ function LinkControl( {
};

return (
<Popover
className={ classnames( 'block-editor-link-control', className ) }
onClose={ closeLinkUI }
position="bottom center"
focusOnMount="firstElement"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these props no longer needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They seem unnecessary in my testing.

>
<div className="block-editor-link-control__popover-inner">
<div className="block-editor-link-control__search">

{ ( ! isEditingLink ) && (
<Fragment>
<p className="screen-reader-text" id={ `current-link-label-${ instanceId }` }>
{ __( 'Currently selected' ) }:
</p>
<div
aria-labelledby={ `current-link-label-${ instanceId }` }
aria-selected="true"
className={ classnames( 'block-editor-link-control__search-item', {
'is-current': true,
} ) }
<div className="block-editor-link-control">
{ ( ! isEditingLink ) && (
<Fragment>
<p className="screen-reader-text" id={ `current-link-label-${ instanceId }` }>
{ __( 'Currently selected' ) }:
</p>
<div
aria-labelledby={ `current-link-label-${ instanceId }` }
aria-selected="true"
className={ classnames( 'block-editor-link-control__search-item', {
'is-current': true,
} ) }
>
<span className="block-editor-link-control__search-item-header">
<ExternalLink
className="block-editor-link-control__search-item-title"
href={ value.url }
>
<span className="block-editor-link-control__search-item-header">
<ExternalLink
className="block-editor-link-control__search-item-title"
href={ value.url }
>
{ value.title }
</ExternalLink>
<span className="block-editor-link-control__search-item-info">{ filterURLForDisplay( safeDecodeURI( value.url ) ) || '' }</span>
</span>

<Button isSecondary onClick={ setMode( MODE_EDIT ) } className="block-editor-link-control__search-item-action block-editor-link-control__search-item-action--edit">
{ __( 'Edit' ) }
</Button>
</div>
</Fragment>
) }

{ isEditingLink && (
<LinkControlSearchInput
value={ inputValue }
onChange={ onInputChange }
onSelect={ ( suggestion ) => {
setIsEditingLink( false );
onChange( { ...value, ...suggestion } );
} }
renderSuggestions={ renderSearchResults }
fetchSuggestions={ getSearchHandler }
onReset={ resetInput }
/>
) }

{ ! isEditingLink && (
<LinkControlSettingsDrawer value={ value } settings={ settings } onChange={ onChange } />
) }
</div>
</div>
</Popover>
{ value.title }
</ExternalLink>
<span className="block-editor-link-control__search-item-info">{ filterURLForDisplay( safeDecodeURI( value.url ) ) || '' }</span>
</span>

<Button isSecondary onClick={ setMode( MODE_EDIT ) } className="block-editor-link-control__search-item-action block-editor-link-control__search-item-action--edit">
{ __( 'Edit' ) }
</Button>
</div>
</Fragment>
) }

{ isEditingLink && (
<LinkControlSearchInput
value={ inputValue }
onChange={ onInputChange }
onSelect={ ( suggestion ) => {
setIsEditingLink( false );
onChange( { ...value, ...suggestion } );
} }
renderSuggestions={ renderSearchResults }
fetchSuggestions={ getSearchHandler }
onReset={ resetInput }
/>
) }

{ ! isEditingLink && (
<LinkControlSettingsDrawer value={ value } settings={ settings } onChange={ onChange } />
) }
</div>
);
}

export default compose(
withInstanceId,
withSelect( ( select, ownProps ) => {
if ( ownProps.fetchSearchSuggestions && isFunction( ownProps.fetchSearchSuggestions ) ) {
return;
}

function ConnectedLinkControl( props ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like that I had to do that to make unit tests pass (test the unconnected component). Ideally, we'd find a way to easily mock useSelect

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like that I had to do that to make unit tests pass (test the unconnected component). Ideally, we'd find a way to easily mock useSelect

Follow-up at #19705

const { fetchSearchSuggestions } = useSelect( ( select ) => {
const { getSettings } = select( 'core/block-editor' );
return {
fetchSearchSuggestions: getSettings().__experimentalFetchLinkSuggestions,
};
} )
)( LinkControl );
}, [] );

return <LinkControl fetchSearchSuggestions={ fetchSearchSuggestions } { ...props } />;
}

export default ConnectedLinkControl;
4 changes: 2 additions & 2 deletions packages/block-editor/src/components/link-control/style.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.block-editor-link-control__search {
.block-editor-link-control {
position: relative;
min-width: $modal-min-width;
}

// LinkControl popover.
.block-editor-link-control__search .block-editor-link-control__search-input {
.block-editor-link-control .block-editor-link-control__search-input {
// Specificity override.
&.block-editor-link-control__search-input input[type="text"] {
width: calc(100% - #{$grid-size-large*2});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Basic rendering should display with required props 1`] = `"<span><div tabindex=\\"-1\\"><div><div><div class=\\"components-popover block-editor-link-control\\"><div class=\\"components-popover__content\\" tabindex=\\"-1\\"><div class=\\"block-editor-link-control__popover-inner\\"><div class=\\"block-editor-link-control__search\\"><form><div class=\\"components-base-control block-editor-url-input block-editor-link-control__search-input\\"><div class=\\"components-base-control__field\\"><input type=\\"text\\" aria-label=\\"URL\\" required=\\"\\" placeholder=\\"Search or type url\\" role=\\"combobox\\" aria-expanded=\\"false\\" aria-autocomplete=\\"list\\" aria-owns=\\"block-editor-url-input-suggestions-0\\" value=\\"\\"></div></div><button type=\\"reset\\" disabled=\\"\\" class=\\"components-button block-editor-link-control__search-reset has-icon\\" aria-label=\\"Reset\\"><svg aria-hidden=\\"true\\" role=\\"img\\" focusable=\\"false\\" xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"20\\" height=\\"20\\" viewBox=\\"0 0 20 20\\" class=\\"dashicon dashicons-no-alt\\"><path d=\\"M14.95 6.46L11.41 10l3.54 3.54-1.41 1.41L10 11.42l-3.53 3.53-1.42-1.42L8.58 10 5.05 6.47l1.42-1.42L10 8.58l3.54-3.53z\\"></path></svg></button></form></div></div></div></div></div></div></div></span>"`;
exports[`Basic rendering should display with required props 1`] = `"<div class=\\"block-editor-link-control\\"><form><div class=\\"components-base-control block-editor-url-input block-editor-link-control__search-input\\"><div class=\\"components-base-control__field\\"><input type=\\"text\\" aria-label=\\"URL\\" required=\\"\\" placeholder=\\"Search or type url\\" role=\\"combobox\\" aria-expanded=\\"false\\" aria-autocomplete=\\"list\\" aria-owns=\\"block-editor-url-input-suggestions-0\\" value=\\"\\"></div></div><button type=\\"reset\\" disabled=\\"\\" class=\\"components-button block-editor-link-control__search-reset has-icon\\" aria-label=\\"Reset\\"><svg aria-hidden=\\"true\\" role=\\"img\\" focusable=\\"false\\" xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"20\\" height=\\"20\\" viewBox=\\"0 0 20 20\\" class=\\"dashicon dashicons-no-alt\\"><path d=\\"M14.95 6.46L11.41 10l3.54 3.54-1.41 1.41L10 11.42l-3.53 3.53-1.42-1.42L8.58 10 5.05 6.47l1.42-1.42L10 8.58l3.54-3.53z\\"></path></svg></button></form></div>"`;
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { UP, DOWN, ENTER } from '@wordpress/keycodes';
/**
* Internal dependencies
*/
import LinkControl from '../index';
import { LinkControl } from '../index';
import { fauxEntitySuggestions, fetchFauxEntitySuggestions } from './fixtures';

/**
Expand Down
35 changes: 19 additions & 16 deletions packages/block-library/src/button/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
withFallbackStyles,
ToolbarButton,
ToolbarGroup,
Popover,
} from '@wordpress/components';
import {
BlockControls,
Expand Down Expand Up @@ -96,23 +97,25 @@ function URLPicker( { isSelected, url, title, setAttributes, opensInNewTab, onTo
setIsURLPickerOpen( true );
};
const linkControl = isURLPickerOpen && (
<LinkControl
className="wp-block-navigation-link__inline-link-input"
value={ { url, title, opensInNewTab } }
onChange={ ( { title: newTitle = '', url: newURL = '', opensInNewTab: newOpensInNewTab } ) => {
setAttributes( {
title: escape( newTitle ),
url: newURL,
} );
<Popover position="bottom center">
<LinkControl
className="wp-block-navigation-link__inline-link-input"
value={ { url, title, opensInNewTab } }
onChange={ ( { title: newTitle = '', url: newURL = '', opensInNewTab: newOpensInNewTab } ) => {
setAttributes( {
title: escape( newTitle ),
url: newURL,
} );

if ( opensInNewTab !== newOpensInNewTab ) {
onToggleOpenInNewTab( newOpensInNewTab );
}
} }
onClose={ () => {
setIsURLPickerOpen( false );
} }
/>
if ( opensInNewTab !== newOpensInNewTab ) {
onToggleOpenInNewTab( newOpensInNewTab );
}
} }
onClose={ () => {
setIsURLPickerOpen( false );
} }
/>
</Popover>
);
return (
<>
Expand Down
33 changes: 18 additions & 15 deletions packages/block-library/src/navigation-link/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
KeyboardShortcuts,
PanelBody,
Path,
Popover,
SVG,
TextareaControl,
TextControl,
Expand Down Expand Up @@ -164,21 +165,23 @@ function NavigationLinkEdit( {
] }
/>
{ isLinkOpen && (
<LinkControl
className="wp-block-navigation-link__inline-link-input"
value={ link }
onChange={ ( {
title: newTitle = '',
url: newURL = '',
opensInNewTab: newOpensInNewTab,
} = {} ) => setAttributes( {
title: escape( newTitle ),
url: newURL,
label: label || escape( newTitle ),
opensInNewTab: newOpensInNewTab,
} ) }
onClose={ () => setIsLinkOpen( false ) }
/>
<Popover position="bottom center">
<LinkControl
className="wp-block-navigation-link__inline-link-input"
value={ link }
onChange={ ( {
title: newTitle = '',
url: newURL = '',
opensInNewTab: newOpensInNewTab,
} = {} ) => setAttributes( {
title: escape( newTitle ),
url: newURL,
label: label || escape( newTitle ),
opensInNewTab: newOpensInNewTab,
} ) }
onClose={ () => setIsLinkOpen( false ) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should have been moved to the Popover. LinkControl no longer has an onClose prop with the changes from this pull request.

Fix at: #19885

/>
</Popover>
) }
</div>
<InnerBlocks
Expand Down