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

Block Editor: LinkControl: Resolve error when undefined value, "view" state #19856

Merged
merged 3 commits into from
Jan 28, 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
28 changes: 24 additions & 4 deletions packages/block-editor/src/components/link-control/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
# Link Control

Renders a link control. A link control is a controlled input which maintains
a value associated with a link (HTML anchor element) and relevant settings
for how that link is expected to behave.

## Props

### value

- Type: `Object`
- Required: No

Current link value.

A link value contains is composed as a union of the default properties and any custom settings values.

Default properties include:

- `url` (`string`): Link URL.
- `title` (`string`, optional): Link title.
- `opensInNewTab` (`boolean`, optional): Whether link should open in a new browser tab.This value is only assigned if not providing a custom `settings` prop.

### settings

- Type: `Array`
Expand All @@ -33,14 +47,20 @@ An array of settings objects. Each object will used to render a `ToggleControl`
- Type: `Function`
- Required: No

Use this callback to take an action after a user set or updated a link.
The function callback will receive the selected item.
Value change handler, called with the updated value if the user selects a new link or updates settings.

```jsx
<LinkControl
onChange={ ( item ) => {
console.log( `The item selected has the ${ item.id } id.` );
onChange={ ( nextValue ) => {
console.log( `The selected item URL: ${ nextValue.url }.` );
}
/>
```

### showInitialSuggestions

- Type: `boolean`
- Required: No
- Default: `false`

Whether to present initial suggestions immediately.
96 changes: 75 additions & 21 deletions packages/block-editor/src/components/link-control/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,62 @@ import LinkControlSettingsDrawer from './settings-drawer';
import LinkControlSearchItem from './search-item';
import LinkControlSearchInput from './search-input';

/**
* Default properties associated with a link control value.
*
* @typedef WPLinkControlDefaultValue
*
* @property {string} url Link URL.
* @property {string=} title Link title.
* @property {boolean=} opensInNewTab Whether link should open in a new browser
* tab. This value is only assigned if not
* providing a custom `settings` prop.
*/

/**
* Custom settings values associated with a link.
*
* @typedef {{[setting:string]:any}} WPLinkControlSettingsValue
*/

/**
* Custom settings values associated with a link.
*
* @typedef WPLinkControlSetting
*
* @property {string} id Identifier to use as property for setting value.
* @property {string} title Human-readable label to show in user interface.
*/

/**
* Properties associated with a link control value, composed as a union of the
* default properties and any custom settings values.
*
* @typedef {WPLinkControlDefaultValue&WPLinkControlSettingsValue} WPLinkControlValue
*/

/** @typedef {(nextValue:WPLinkControlValue)=>void} WPLinkControlOnChangeProp */

/**
* @typedef WPLinkControlProps
*
* @property {(WPLinkControlSetting[])=} settings An array of settings objects. Each object will used to
* render a `ToggleControl` for that setting.
* @property {(search:string)=>Promise=} fetchSearchSuggestions Fetches suggestions for a given search term,
* returning a promise resolving once fetch is complete.
Comment on lines +71 to +72
Copy link
Member Author

Choose a reason for hiding this comment

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

This shouldn't have been included. It's not (any longer) a prop for the component.

* @property {WPLinkControlValue=} value Current link value.
* @property {WPLinkControlOnChangeProp=} onChange Value change handler, called with the updated value if
* the user selects a new link or updates settings.
* @property {boolean=} showInitialSuggestions Whether to present initial suggestions immediately.
*/

/**
* Renders a link control. A link control is a controlled input which maintains
* a value associated with a link (HTML anchor element) and relevant settings
* for how that link is expected to behave.
*
* @param {WPLinkControlProps} props Component props.
*/
function LinkControl( {
value,
settings,
Expand Down Expand Up @@ -157,7 +213,19 @@ function LinkControl( {

return (
<div className="block-editor-link-control">
{ ( ! isEditingLink ) && (
{ isEditingLink || ! value ?
<LinkControlSearchInput
value={ inputValue }
onChange={ onInputChange }
onSelect={ ( suggestion ) => {
setIsEditingLink( false );
onChange( { ...value, ...suggestion } );
} }
renderSuggestions={ renderSearchResults }
fetchSuggestions={ getSearchHandler }
onReset={ resetInput }
showInitialSuggestions={ showInitialSuggestions }
/> :
<Fragment>
<p className="screen-reader-text" id={ `current-link-label-${ instanceId }` }>
{ __( 'Currently selected' ) }:
Expand Down Expand Up @@ -191,27 +259,13 @@ function LinkControl( {
{ __( 'Edit' ) }
</Button>
</div>
<LinkControlSettingsDrawer
value={ value }
settings={ settings }
onChange={ onChange }
/>
</Fragment>
) }

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

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