From 87393d59780cf86b6db7a3bae0302c580a1a0894 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 3 Jan 2020 11:22:09 +0100 Subject: [PATCH 1/6] Refactor LinkControl API --- .../src/components/link-control/README.md | 33 +------- .../src/components/link-control/index.js | 75 +++++++++---------- .../link-control/settings-drawer.js | 12 +-- .../src/components/link-control/test/index.js | 22 +++--- .../block-library/src/navigation-link/edit.js | 56 ++++---------- 5 files changed, 71 insertions(+), 127 deletions(-) diff --git a/packages/block-editor/src/components/link-control/README.md b/packages/block-editor/src/components/link-control/README.md index af25dfc2f42fe3..ce4c27ff31d4ad 100644 --- a/packages/block-editor/src/components/link-control/README.md +++ b/packages/block-editor/src/components/link-control/README.md @@ -7,12 +7,12 @@ - Type: `String` - Required: Yes -### currentLink +### value - Type: `Object` - Required: Yes -### currentSettings +### settings - Type: `Array` - Required: No @@ -22,12 +22,11 @@ { id: 'newTab', title: 'Open in New Tab', - checked: false, }, ]; ``` -An array of settings objects. Each object will used to render a `ToggleControl` for that setting. See also `onSettingsChange`. +An array of settings objects. Each object will used to render a `ToggleControl` for that setting. ### fetchSearchSuggestions @@ -65,7 +64,7 @@ through of its function parameter. - Type: `Function` - Required: No -### onLinkChange +### onChange - Type: `Function` - Required: No @@ -81,29 +80,5 @@ The function callback will receive the selected item, or Null. : console.warn( 'No Item selected.' ); } /> -``` - -### onSettingsChange - -- Type: `Function` -- Required: No -- Args: - - `id` - the `id` property of the setting that changed (eg: `newTab`). - - `value` - the `checked` value of the control. - - `settings` - the current settings object. - -Called when any of the settings supplied as `currentSettings` are changed/toggled. May be used to attribute a Block's `attributes` with the current state of the control. - -``` - setAttributes( { [ setting ]: value } ) } -/> ``` diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index 18ae9da7c5401b..b792385cf951dc 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -17,7 +17,6 @@ import { __ } from '@wordpress/i18n'; import { useCallback, useState, - useEffect, Fragment, } from '@wordpress/element'; @@ -44,40 +43,29 @@ const MODE_EDIT = 'edit'; function LinkControl( { className, - currentLink, - currentSettings, + value, + settings, fetchSearchSuggestions, instanceId, onClose = noop, onChangeMode = noop, onKeyDown = noop, onKeyPress = noop, - onLinkChange = noop, - onSettingsChange = noop, + onChange = noop, } ) { // State const [ inputValue, setInputValue ] = useState( '' ); - const [ isEditingLink, setIsEditingLink ] = useState( false ); - - // Effects - useEffect( () => { - // If we have a link then stop editing mode - if ( currentLink ) { - setIsEditingLink( false ); - } else { - setIsEditingLink( true ); - } - }, [ currentLink ] ); + const [ isEditingLink, setIsEditingLink ] = useState( ! value || ! value.url ); // Handlers /** * onChange LinkControlSearchInput event handler * - * @param {string} value Current value returned by the search. + * @param {string} val Current value returned by the search. */ - const onInputChange = ( value = '' ) => { - setInputValue( value ); + const onInputChange = ( val = '' ) => { + setInputValue( val ); }; // Utils @@ -94,8 +82,8 @@ function LinkControl( { // Populate input searcher whether // the current link has a title. - if ( currentLink && currentLink.title ) { - setInputValue( currentLink.title ); + if ( value && value.title ) { + setInputValue( value.title ); } if ( isFunction( onChangeMode ) ) { @@ -112,10 +100,10 @@ function LinkControl( { setInputValue( '' ); }; - const handleDirectEntry = ( value ) => { + const handleDirectEntry = ( val ) => { let type = 'URL'; - const protocol = getProtocol( value ) || ''; + const protocol = getProtocol( val ) || ''; if ( protocol.includes( 'mailto' ) ) { type = 'mailto'; @@ -132,20 +120,20 @@ function LinkControl( { return Promise.resolve( [ { id: '-1', - title: value, + title: val, url: type === 'URL' ? prependHTTP( value ) : value, type, } ] ); }; - const handleEntitySearch = async ( value ) => { + const handleEntitySearch = async ( val ) => { const results = await Promise.all( [ - fetchSearchSuggestions( value ), - handleDirectEntry( value ), + fetchSearchSuggestions( val ), + handleDirectEntry( val ), ] ); - const couldBeURL = ! value.includes( ' ' ); + const couldBeURL = ! val.includes( ' ' ); // If it's potentially a URL search then concat on a URL search suggestion // just for good measure. That way once the actual results run out we always @@ -154,15 +142,15 @@ function LinkControl( { }; // Effects - const getSearchHandler = useCallback( ( value ) => { - const protocol = getProtocol( value ) || ''; + const getSearchHandler = useCallback( ( val ) => { + const protocol = getProtocol( val ) || ''; const isMailto = protocol.includes( 'mailto' ); - const isInternal = startsWith( value, '#' ); + const isInternal = startsWith( val, '#' ); const isTel = protocol.includes( 'tel' ); - const handleManualEntry = isInternal || isMailto || isTel || isURL( value ) || ( value && value.includes( 'www.' ) ); + const handleManualEntry = isInternal || isMailto || isTel || isURL( val ) || ( val && val.includes( 'www.' ) ); - return ( handleManualEntry ) ? handleDirectEntry( value ) : handleEntitySearch( value ); + return ( handleManualEntry ) ? handleDirectEntry( val ) : handleEntitySearch( val ); }, [ handleDirectEntry, fetchSearchSuggestions ] ); // Render Components @@ -181,7 +169,10 @@ function LinkControl( { key={ `${ suggestion.id }-${ suggestion.type }` } itemProps={ buildSuggestionItemProps( suggestion, index ) } suggestion={ suggestion } - onClick={ () => onLinkChange( suggestion ) } + onClick={ () => { + setIsEditingLink( false ); + onChange( { ...value, ...suggestion } ); + } } isSelected={ index === selectedSuggestion } isURL={ manualLinkEntryTypes.includes( suggestion.type.toLowerCase() ) } searchTerm={ inputValue } @@ -202,7 +193,7 @@ function LinkControl( {
- { ( ! isEditingLink && currentLink ) && ( + { ( ! isEditingLink ) && (

{ __( 'Currently selected' ) }: @@ -215,14 +206,13 @@ function LinkControl( { } ) } > - - { currentLink.title } + { value.title } - { filterURLForDisplay( safeDecodeURI( currentLink.url ) ) || '' } + { filterURLForDisplay( safeDecodeURI( value.url ) ) || '' }

diff --git a/packages/block-editor/src/components/link-control/settings-drawer.js b/packages/block-editor/src/components/link-control/settings-drawer.js index 3d9f957e207a83..4ed4ad573eb571 100644 --- a/packages/block-editor/src/components/link-control/settings-drawer.js +++ b/packages/block-editor/src/components/link-control/settings-drawer.js @@ -15,17 +15,19 @@ const defaultSettings = [ { id: 'newTab', title: __( 'Open in New Tab' ), - checked: false, }, ]; -const LinkControlSettingsDrawer = ( { settings = defaultSettings, onSettingChange = noop } ) => { +const LinkControlSettingsDrawer = ( { value, onChange = noop, settings = defaultSettings } ) => { if ( ! settings || ! settings.length ) { return null; } - const handleSettingChange = ( setting ) => ( value ) => { - onSettingChange( setting.id, value, settings ); + const handleSettingChange = ( setting ) => ( newValue ) => { + onChange( { + ...settings, + [ setting.id ]: newValue, + } ); }; const theSettings = settings.map( ( setting ) => ( @@ -34,7 +36,7 @@ const LinkControlSettingsDrawer = ( { settings = defaultSettings, onSettingChang key={ setting.id } label={ setting.title } onChange={ handleSettingChange( setting ) } - checked={ setting.checked } /> + checked={ value ? value[ setting.id ] : false } /> ) ); return ( diff --git a/packages/block-editor/src/components/link-control/test/index.js b/packages/block-editor/src/components/link-control/test/index.js index 5a69142b5f495e..c37e96302ff291 100644 --- a/packages/block-editor/src/components/link-control/test/index.js +++ b/packages/block-editor/src/components/link-control/test/index.js @@ -318,7 +318,7 @@ describe( 'Selecting links', () => { return ( ); @@ -350,8 +350,8 @@ describe( 'Selecting links', () => { return ( setLink( suggestion ) } + value={ link } + onChange={ ( suggestion ) => setLink( suggestion ) } fetchSearchSuggestions={ fetchFauxEntitySuggestions } onChangeMode={ spyOnEditMode( 'edit' ) } /> @@ -398,8 +398,8 @@ describe( 'Selecting links', () => { return ( setLink( suggestion ) } + value={ link } + onChange={ ( suggestion ) => setLink( suggestion ) } fetchSearchSuggestions={ fetchFauxEntitySuggestions } /> ); @@ -458,8 +458,8 @@ describe( 'Selecting links', () => { return ( setLink( suggestion ) } + value={ link } + onChange={ ( suggestion ) => setLink( suggestion ) } fetchSearchSuggestions={ fetchFauxEntitySuggestions } /> ); @@ -547,7 +547,7 @@ describe( 'Addition Settings UI', () => { return ( ); @@ -577,12 +577,10 @@ describe( 'Addition Settings UI', () => { { id: 'newTab', title: 'Open in New Tab', - checked: false, }, { id: 'noFollow', title: 'No follow', - checked: true, }, ]; @@ -593,9 +591,9 @@ describe( 'Addition Settings UI', () => { return ( ); }; diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js index 5356a873d74934..6e55241874f5c5 100644 --- a/packages/block-library/src/navigation-link/edit.js +++ b/packages/block-library/src/navigation-link/edit.js @@ -42,35 +42,6 @@ import { } from '@wordpress/block-editor'; import { Fragment, useState, useEffect } from '@wordpress/element'; -/** - * It updates the link attribute when the - * link settings changes. - * - * @param {Function} setter Setter attribute function. - */ -const updateLinkSetting = ( setter ) => ( setting, value ) => { - setter( { [ setting ]: value } ); -}; - -/** - * Updates the link attribute when it changes - * through of the `onLinkChange` LinkControl callback. - * - * @param {Function} setter Setter attribute function. - * @param {string} label Link label. - */ -const updateLink = ( setter, label ) => ( { title: newTitle = '', url: newURL = '' } = {} ) => { - setter( { - title: escape( newTitle ), - url: newURL, - } ); - - // Set the item label as well if it isn't already defined. - if ( ! label ) { - setter( { label: escape( newTitle ) } ); - } -}; - function NavigationLinkEdit( { attributes, hasDescendants, @@ -80,7 +51,11 @@ function NavigationLinkEdit( { insertLinkBlock, } ) { const { label, opensInNewTab, title, url, nofollow, description } = attributes; - const link = title ? { title: unescape( title ), url } : null; + const link = { + title: title ? unescape( title ) : '', + url, + opensInNewTab, + }; const [ isLinkOpen, setIsLinkOpen ] = useState( ! label && isSelected ); let onCloseTimerId = null; @@ -221,19 +196,20 @@ function NavigationLinkEdit( { className="wp-block-navigation-link__inline-link-input" onKeyDown={ handleLinkControlOnKeyDown } onKeyPress={ ( event ) => event.stopPropagation() } - currentLink={ link } - onLinkChange={ updateLink( setAttributes, label ) } + value={ link } + onChange={ ( { + title: newTitle = '', + url: newURL = '', + opensInNewTab: newTab, + } = {} ) => setAttributes( { + title: escape( newTitle ), + url: newURL, + label: label || escape( newTitle ), + opensInNewTab: newTab, + } ) } onClose={ () => { onCloseTimerId = setTimeout( () => setIsLinkOpen( false ), 100 ); } } - currentSettings={ [ - { - id: 'opensInNewTab', - title: __( 'Open in new tab' ), - checked: opensInNewTab, - }, - ] } - onSettingsChange={ updateLinkSetting( setAttributes ) } /> ) } From 6d0b0827072ebab8118d07683ccbd4d8e7d06efc Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 3 Jan 2020 11:33:12 +0100 Subject: [PATCH 2/6] Fix typos --- packages/block-editor/src/components/link-control/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index b792385cf951dc..8b9ec438af081e 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -82,7 +82,7 @@ function LinkControl( { // Populate input searcher whether // the current link has a title. - if ( value && value.title ) { + if ( value && value.title && mode === 'edit' ) { setInputValue( value.title ); } @@ -113,7 +113,7 @@ function LinkControl( { type = 'tel'; } - if ( startsWith( value, '#' ) ) { + if ( startsWith( val, '#' ) ) { type = 'internal'; } @@ -121,7 +121,7 @@ function LinkControl( { [ { id: '-1', title: val, - url: type === 'URL' ? prependHTTP( value ) : value, + url: type === 'URL' ? prependHTTP( val ) : val, type, } ] ); From 7085e0907ddfc2863aa3fc9b8f68327d5a1ce045 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 3 Jan 2020 11:47:42 +0100 Subject: [PATCH 3/6] Simplify popover closing/opening --- .../link-control/settings-drawer.js | 2 +- .../block-library/src/navigation-link/edit.js | 38 ++++--------------- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/packages/block-editor/src/components/link-control/settings-drawer.js b/packages/block-editor/src/components/link-control/settings-drawer.js index 4ed4ad573eb571..d9b427497d6653 100644 --- a/packages/block-editor/src/components/link-control/settings-drawer.js +++ b/packages/block-editor/src/components/link-control/settings-drawer.js @@ -25,7 +25,7 @@ const LinkControlSettingsDrawer = ( { value, onChange = noop, settings = default const handleSettingChange = ( setting ) => ( newValue ) => { onChange( { - ...settings, + ...value, [ setting.id ]: newValue, } ); }; diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js index 6e55241874f5c5..069c782f4743a9 100644 --- a/packages/block-library/src/navigation-link/edit.js +++ b/packages/block-library/src/navigation-link/edit.js @@ -54,40 +54,20 @@ function NavigationLinkEdit( { const link = { title: title ? unescape( title ) : '', url, - opensInNewTab, + newTab: opensInNewTab, }; - const [ isLinkOpen, setIsLinkOpen ] = useState( ! label && isSelected ); - - let onCloseTimerId = null; + const [ isLinkOpen, setIsLinkOpen ] = useState( ! url && isSelected ); /** - * It's a kind of hack to handle closing the LinkControl popover - * clicking on the ToolbarButton link. + * This hack shouldn't be necessary but due to a focus loss happening + * when selecting a suggestion in the link popover, we force close on block unselection. */ useEffect( () => { if ( ! isSelected ) { setIsLinkOpen( false ); } - - return () => { - // Clear LinkControl.OnClose timeout. - if ( onCloseTimerId ) { - clearTimeout( onCloseTimerId ); - } - }; }, [ isSelected ] ); - /** - * Opens the LinkControl popup - */ - const openLinkControl = () => { - if ( isLinkOpen ) { - return; - } - - setIsLinkOpen( ! isLinkOpen ); - }; - /** * `onKeyDown` LinkControl handler. * It takes over to stop the event propagation to make the @@ -115,7 +95,7 @@ function NavigationLinkEdit( { setIsLinkOpen( true ), } } /> setIsLinkOpen( true ) } /> setAttributes( { title: escape( newTitle ), url: newURL, label: label || escape( newTitle ), opensInNewTab: newTab, } ) } - onClose={ () => { - onCloseTimerId = setTimeout( () => setIsLinkOpen( false ), 100 ); - } } + onClose={ () => setIsLinkOpen( false ) } /> ) } From db1d7442bd1817bf5daf6923dfdd9be0a04e46df Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 3 Jan 2020 12:02:35 +0100 Subject: [PATCH 4/6] Fix onKeyDown and onKeyPress on the root component --- .../src/components/link-control/README.md | 10 ------- .../src/components/link-control/index.js | 4 --- .../components/link-control/search-input.js | 27 +++++++++++++++---- .../block-library/src/navigation-link/edit.js | 26 ------------------ 4 files changed, 22 insertions(+), 45 deletions(-) diff --git a/packages/block-editor/src/components/link-control/README.md b/packages/block-editor/src/components/link-control/README.md index ce4c27ff31d4ad..529d1f281c5673 100644 --- a/packages/block-editor/src/components/link-control/README.md +++ b/packages/block-editor/src/components/link-control/README.md @@ -54,16 +54,6 @@ through of its function parameter. - Type: `Function` - Required: No -### onKeyDown - -- Type: `Function` -- Required: No - -### onKeyPress - -- Type: `Function` -- Required: No - ### onChange - Type: `Function` diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index 8b9ec438af081e..a2f17fa0f70dc6 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -49,8 +49,6 @@ function LinkControl( { instanceId, onClose = noop, onChangeMode = noop, - onKeyDown = noop, - onKeyPress = noop, onChange = noop, } ) { // State @@ -233,8 +231,6 @@ function LinkControl( { renderSuggestions={ renderSearchResults } fetchSuggestions={ getSearchHandler } onReset={ resetInput } - onKeyDown={ onKeyDown } - onKeyPress={ onKeyPress } /> ) } diff --git a/packages/block-editor/src/components/link-control/search-input.js b/packages/block-editor/src/components/link-control/search-input.js index 615f062b3fe017..9360ef00801378 100644 --- a/packages/block-editor/src/components/link-control/search-input.js +++ b/packages/block-editor/src/components/link-control/search-input.js @@ -4,13 +4,32 @@ */ import { __ } from '@wordpress/i18n'; import { Button } from '@wordpress/components'; -import { ENTER } from '@wordpress/keycodes'; +import { LEFT, + RIGHT, + UP, + DOWN, + BACKSPACE, + ENTER, +} from '@wordpress/keycodes'; /** * Internal dependencies */ import { URLInput } from '../'; +const handleLinkControlOnKeyDown = ( event ) => { + const { keyCode } = event; + + if ( [ LEFT, DOWN, RIGHT, UP, BACKSPACE, ENTER ].indexOf( keyCode ) > -1 ) { + // Stop the key event from propagating up to ObserveTyping.startTypingInTextField. + event.stopPropagation(); + } +}; + +const handleLinkControlOnKeyPress = ( event ) => { + event.stopPropagation(); +}; + const LinkControlSearchInput = ( { value, onChange, @@ -18,8 +37,6 @@ const LinkControlSearchInput = ( { renderSuggestions, fetchSuggestions, onReset, - onKeyDown, - onKeyPress, } ) => { const selectItemHandler = ( selection, suggestion ) => { onChange( selection ); @@ -44,9 +61,9 @@ const LinkControlSearchInput = ( { if ( event.keyCode === ENTER ) { return; } - onKeyDown( event ); + handleLinkControlOnKeyDown( event ); } } - onKeyPress={ onKeyPress } + onKeyPress={ handleLinkControlOnKeyPress } placeholder={ __( 'Search or type url' ) } __experimentalRenderSuggestions={ renderSuggestions } __experimentalFetchLinkSuggestions={ fetchSuggestions } diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js index 069c782f4743a9..5ef5dcf91b7054 100644 --- a/packages/block-library/src/navigation-link/edit.js +++ b/packages/block-library/src/navigation-link/edit.js @@ -23,12 +23,6 @@ import { ToolbarGroup, } from '@wordpress/components'; import { - LEFT, - RIGHT, - UP, - DOWN, - BACKSPACE, - ENTER, rawShortcut, displayShortcut, } from '@wordpress/keycodes'; @@ -68,24 +62,6 @@ function NavigationLinkEdit( { } }, [ isSelected ] ); - /** - * `onKeyDown` LinkControl handler. - * It takes over to stop the event propagation to make the - * navigation work, avoiding undesired behaviors. - * For instance, it will block to move between link blocks - * when the LinkControl is focused. - * - * @param {Event} event - */ - const handleLinkControlOnKeyDown = ( event ) => { - const { keyCode } = event; - - if ( [ LEFT, DOWN, RIGHT, UP, BACKSPACE, ENTER ].indexOf( keyCode ) > -1 ) { - // Stop the key event from propagating up to ObserveTyping.startTypingInTextField. - event.stopPropagation(); - } - }; - const itemLabelPlaceholder = __( 'Add linkā€¦' ); return ( @@ -174,8 +150,6 @@ function NavigationLinkEdit( { { isLinkOpen && ( event.stopPropagation() } value={ link } onChange={ ( { title: newTitle = '', From 65c32c0c51e1b514415d121330e241533e2978c7 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 3 Jan 2020 12:04:33 +0100 Subject: [PATCH 5/6] Remove useless onModeChange callback --- .../src/components/link-control/README.md | 14 -------------- .../src/components/link-control/index.js | 6 ------ .../src/components/link-control/test/index.js | 3 --- 3 files changed, 23 deletions(-) diff --git a/packages/block-editor/src/components/link-control/README.md b/packages/block-editor/src/components/link-control/README.md index 529d1f281c5673..9ce5951076d77a 100644 --- a/packages/block-editor/src/components/link-control/README.md +++ b/packages/block-editor/src/components/link-control/README.md @@ -35,20 +35,6 @@ An array of settings objects. Each object will used to render a `ToggleControl` ## Event handlers -### onChangeMode - -- Type: `Function` -- Required: No - -Use this callback to know when the LinkControl component changes its mode to `edit` or `show` -through of its function parameter. - -```es6 - { console.log( `Mode change to ${ mode } mode.` ) } -/> -``` - ### onClose - Type: `Function` diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index a2f17fa0f70dc6..ac69db9b655fe1 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -48,7 +48,6 @@ function LinkControl( { fetchSearchSuggestions, instanceId, onClose = noop, - onChangeMode = noop, onChange = noop, } ) { // State @@ -71,7 +70,6 @@ function LinkControl( { /** * Handler function which switches the mode of the component, * between `edit` and `show` mode. - * Also, it calls `onChangeMode` callback function. * * @param {string} mode Component mode: `show` or `edit`. */ @@ -83,10 +81,6 @@ function LinkControl( { if ( value && value.title && mode === 'edit' ) { setInputValue( value.title ); } - - if ( isFunction( onChangeMode ) ) { - onChangeMode( mode ); - } }; const closeLinkUI = () => { diff --git a/packages/block-editor/src/components/link-control/test/index.js b/packages/block-editor/src/components/link-control/test/index.js index c37e96302ff291..ca91c9791384c9 100644 --- a/packages/block-editor/src/components/link-control/test/index.js +++ b/packages/block-editor/src/components/link-control/test/index.js @@ -343,7 +343,6 @@ describe( 'Selecting links', () => { it( 'should hide "selected" link UI and display search UI prepopulated with previously selected link title when "Change" button is clicked', () => { const selectedLink = first( fauxEntitySuggestions ); - const spyOnEditMode = jest.fn(); const LinkControlConsumer = () => { const [ link, setLink ] = useState( selectedLink ); @@ -353,7 +352,6 @@ describe( 'Selecting links', () => { value={ link } onChange={ ( suggestion ) => setLink( suggestion ) } fetchSearchSuggestions={ fetchFauxEntitySuggestions } - onChangeMode={ spyOnEditMode( 'edit' ) } /> ); }; @@ -380,7 +378,6 @@ describe( 'Selecting links', () => { expect( searchInput ).not.toBeNull(); expect( searchInput.value ).toBe( selectedLink.title ); // prepopulated with previous link's title expect( currentLinkUI ).toBeNull(); - expect( spyOnEditMode ).toHaveBeenCalled(); } ); describe( 'Selection using mouse click', () => { From 424820b8f2d6d01dd14b959d452e2bdd806df581 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 3 Jan 2020 12:09:30 +0000 Subject: [PATCH 6/6] Experiment with text inside link control as well as via Direct Manipulation --- .../src/components/link-control/index.js | 63 +++++++++++++++---- .../src/components/link-control/style.scss | 4 ++ .../block-library/src/navigation-link/edit.js | 2 + 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index ac69db9b655fe1..a84a16b0f3a91c 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -11,6 +11,7 @@ import { Button, ExternalLink, Popover, + TextControl, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; @@ -30,7 +31,14 @@ import { import { withInstanceId, compose } from '@wordpress/compose'; import { withSelect } from '@wordpress/data'; - +import { + LEFT, + RIGHT, + UP, + DOWN, + BACKSPACE, + ENTER, +} from '@wordpress/keycodes'; /** * Internal dependencies */ @@ -49,6 +57,8 @@ function LinkControl( { instanceId, onClose = noop, onChange = noop, + text = '', + onTextChange = noop, } ) { // State const [ inputValue, setInputValue ] = useState( '' ); @@ -133,6 +143,19 @@ function LinkControl( { return couldBeURL ? results[ 0 ].concat( results[ 1 ] ) : results[ 0 ]; }; + const handleTextControlOnKeyDown = ( event ) => { + const { keyCode } = event; + + if ( [ LEFT, DOWN, RIGHT, UP, BACKSPACE, ENTER ].indexOf( keyCode ) > -1 ) { + // Stop the key event from propagating up to ObserveTyping.startTypingInTextField. + event.stopPropagation(); + } + }; + + const handleTextControlOnKeyPress = ( event ) => { + event.stopPropagation(); + }; + // Effects const getSearchHandler = useCallback( ( val ) => { const protocol = getProtocol( val ) || ''; @@ -215,17 +238,33 @@ function LinkControl( { ) } { isEditingLink && ( - { - setIsEditingLink( false ); - onChange( { ...value, ...suggestion } ); - } } - renderSuggestions={ renderSearchResults } - fetchSuggestions={ getSearchHandler } - onReset={ resetInput } - /> + <> + { + setIsEditingLink( false ); + onChange( { ...value, ...suggestion } ); + } } + renderSuggestions={ renderSearchResults } + fetchSuggestions={ getSearchHandler } + onReset={ resetInput } + /> + + { + if ( event.keyCode === ENTER ) { + return; + } + handleTextControlOnKeyDown( event ); + } } + onKeyPress={ handleTextControlOnKeyPress } + /> + ) } { ! isEditingLink && ( diff --git a/packages/block-editor/src/components/link-control/style.scss b/packages/block-editor/src/components/link-control/style.scss index ef01a96da4bfcb..57662bfe4c97f1 100644 --- a/packages/block-editor/src/components/link-control/style.scss +++ b/packages/block-editor/src/components/link-control/style.scss @@ -30,6 +30,10 @@ } } +.block-editor-link-control__text-content { + margin: $grid-size-large; +} + .block-editor-link-control__search-reset { position: absolute; top: 19px; // has to be hard coded as form expands with search suggestions diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js index 5ef5dcf91b7054..1cd6f76bb602b4 100644 --- a/packages/block-library/src/navigation-link/edit.js +++ b/packages/block-library/src/navigation-link/edit.js @@ -162,6 +162,8 @@ function NavigationLinkEdit( { opensInNewTab: newTab, } ) } onClose={ () => setIsLinkOpen( false ) } + text={ label } + onTextChange={ ( labelValue ) => setAttributes( { label: labelValue } ) } /> ) }