-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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, | ||
|
@@ -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 | ||
|
@@ -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 ); | ||
|
||
|
@@ -83,11 +71,6 @@ function LinkControl( { | |
} | ||
}; | ||
|
||
const closeLinkUI = () => { | ||
resetInput(); | ||
onClose(); | ||
}; | ||
|
||
const resetInput = () => { | ||
setInputValue( '' ); | ||
}; | ||
|
@@ -176,77 +159,66 @@ function LinkControl( { | |
}; | ||
|
||
return ( | ||
<Popover | ||
className={ classnames( 'block-editor-link-control', className ) } | ||
onClose={ closeLinkUI } | ||
position="bottom center" | ||
focusOnMount="firstElement" | ||
> | ||
<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 ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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; |
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 |
---|---|---|
|
@@ -15,6 +15,7 @@ import { | |
KeyboardShortcuts, | ||
PanelBody, | ||
Path, | ||
Popover, | ||
SVG, | ||
TextareaControl, | ||
TextControl, | ||
|
@@ -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> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it not need a position here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seemed to work without it, maybe it was the default, I'll check. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I restored this |
||
<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 ) } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should have been moved to the Fix at: #19885 |
||
/> | ||
</Popover> | ||
) } | ||
</div> | ||
<InnerBlocks | ||
|
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.