-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
URLInput: Pass the the search result object to props.onChange #8662
Changes from 6 commits
0ae019a
3895b87
e8983cf
4ea3d51
add432d
af19bed
00378a3
7d9b96e
e5f7313
734522c
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 |
---|---|---|
@@ -0,0 +1,181 @@ | ||
# `URLInputButton` | ||
|
||
Render a URL input button that pops up an input to search for and select a post or enter any arbitrary URL. | ||
|
||
## Properties | ||
|
||
### `url: String` | ||
|
||
*Required.* This should be set to the attribute (or component state) property used to store the URL. | ||
|
||
### `onChange( url: String, post: Object ): Function` | ||
|
||
*Required.* Called when the value changes. The second parameter defaults to an empty object unless the user selects a post from the suggestions dropdown. In those cases the `post` parameter will look like this: | ||
|
||
```json | ||
{ | ||
"id": 1, | ||
"subtype": "page", | ||
"title": "Sample Page", | ||
"type": "post", | ||
"url": "https://example.com/sample-page/", | ||
"_links": { | ||
"self": [ { "embeddable": true, "href": "https://example.com/wp-json/wp/v2/pages/1" } ], | ||
"about": [ { "href": "https://example.com/wp-json/wp/v2/types/page" } ], | ||
"collection": [ { "href": "https://example.com/wp-json/gutenberg/v1/search" } ] | ||
} | ||
} | ||
``` | ||
|
||
## Example | ||
|
||
{% codetabs %} | ||
{% ES5 %} | ||
```js | ||
wp.blocks.registerBlockType( /* ... */, { | ||
// ... | ||
|
||
attributes: { | ||
url: { | ||
type: 'string' | ||
}, | ||
text: { | ||
type: 'string' | ||
} | ||
}, | ||
|
||
edit: function( props ) { | ||
return wp.element.createElement( wp.editor.URLInputButton, { | ||
className: props.className, | ||
url: props.attributes.url, | ||
onChange: function( url, post ) { | ||
props.setAttributes( { url: url, text: post.title || 'Click here' } ); | ||
} | ||
} ); | ||
}, | ||
|
||
save: function( props ) { | ||
return wp.element.createElement( 'a', { | ||
href: props.attributes.url, | ||
}, props.attributes.text ); | ||
} | ||
} ); | ||
``` | ||
{% ESNext %} | ||
```js | ||
const { registerBlockType } = wp.blocks; | ||
const { URLInputButton } = wp.editor; | ||
|
||
registerBlockType( /* ... */, { | ||
// ... | ||
|
||
attributes: { | ||
url: { | ||
type: 'string', | ||
}, | ||
text: { | ||
type: 'string', | ||
}, | ||
}, | ||
|
||
edit( { className, attributes, setAttributes } ) { | ||
return ( | ||
<URLInputButton | ||
url={ attributes.url } | ||
onChange={ ( url, post ) => setAttributes( { url, text: post.title || 'Click here' } ) } | ||
/> | ||
); | ||
}, | ||
|
||
save( { attributes } ) { | ||
return <a href={ attributes.url }>{ attributes.text }</a>; | ||
} | ||
} ); | ||
``` | ||
{% end %} | ||
|
||
# `URLInput` | ||
|
||
Renders the URL input normally wrapped by `URLInputButton`. | ||
|
||
## Properties | ||
|
||
### `value: String` | ||
|
||
*Required.* This should be set to the attribute (or component state) property used to store the URL. | ||
|
||
### `onChange( url: String, post: Object ): Function` | ||
|
||
*Required.* Called when the value changes. This is the same as the `onChange` prop described above for `URLInputButton`. | ||
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. Saying "this is the same" is a bit confusing to me–does that mean it's functionally the same or it's literally passed from 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's literally passed directly from the |
||
|
||
### `autoFocus: Boolean` | ||
|
||
*Optional.* By default, the input will gain focus when it is rendered as typically it is used in combination with a `Popover` in `URLInputBUtton`. If you are rendering the component all the time set this to `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. A comma after "rendered" would improve readability here. I also think you could tweak the second sentence:
|
||
|
||
## Example | ||
|
||
{% codetabs %} | ||
{% ES5 %} | ||
```js | ||
wp.blocks.registerBlockType( /* ... */, { | ||
// ... | ||
|
||
attributes: { | ||
url: { | ||
type: 'string' | ||
}, | ||
text: { | ||
type: 'string' | ||
} | ||
}, | ||
|
||
edit: function( props ) { | ||
return wp.element.createElement( wp.editor.URLInput, { | ||
className: props.className, | ||
value: props.attributes.url, | ||
onChange: function( url, post ) { | ||
props.setAttributes( { url: url, text: post.title || 'Click here' } ); | ||
} | ||
} ); | ||
}, | ||
|
||
save: function( props ) { | ||
return wp.element.createElement( 'a', { | ||
href: props.attributes.url, | ||
}, props.attributes.text ); | ||
} | ||
} ); | ||
``` | ||
{% ESNext %} | ||
```js | ||
const { registerBlockType } = wp.blocks; | ||
const { URLInput } = wp.editor; | ||
|
||
registerBlockType( /* ... */, { | ||
// ... | ||
|
||
attributes: { | ||
url: { | ||
type: 'string', | ||
}, | ||
text: { | ||
type: 'string', | ||
}, | ||
}, | ||
|
||
edit( { className, attributes, setAttributes } ) { | ||
return ( | ||
<URLInput | ||
className={ className } | ||
value={ attributes.url } | ||
onChange={ ( url, post ) => setAttributes( { url, text: post.title || 'Click here' } ) } | ||
/> | ||
); | ||
}, | ||
|
||
save( { attributes } ) { | ||
return <a href={ attributes.url }>{ attributes.text }</a>; | ||
} | ||
} ); | ||
``` | ||
{% end %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -131,9 +131,9 @@ class URLInput extends Component { | |
this.suggestionsRequest = request; | ||
} | ||
|
||
onChange( event ) { | ||
onChange( event, post = {} ) { | ||
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 guess this post argument is useless because it's always undefined anyway (default value). 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. Not totally sure I follow your meaning, do you mean leave out the default value or change the call to |
||
const inputValue = event.target.value; | ||
this.props.onChange( inputValue ); | ||
this.props.onChange( inputValue, post ); | ||
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. Should we make the 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 is the only place 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. oh my bad, thought |
||
this.updateSuggestions( inputValue ); | ||
} | ||
|
||
|
@@ -168,14 +168,14 @@ class URLInput extends Component { | |
if ( this.state.selectedSuggestion !== null ) { | ||
event.stopPropagation(); | ||
const post = this.state.posts[ this.state.selectedSuggestion ]; | ||
this.selectLink( post.url ); | ||
this.selectLink( post.url, post ); | ||
} | ||
} | ||
} | ||
} | ||
|
||
selectLink( link ) { | ||
this.props.onChange( link ); | ||
selectLink( link, post ) { | ||
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. Should we remove the first argument from this method, as it's already in |
||
this.props.onChange( link, post ); | ||
this.setState( { | ||
selectedSuggestion: null, | ||
showSuggestions: false, | ||
|
@@ -227,7 +227,7 @@ class URLInput extends Component { | |
className={ classnames( 'editor-url-input__suggestion', { | ||
'is-selected': index === selectedSuggestion, | ||
} ) } | ||
onClick={ () => this.selectLink( post.url ) } | ||
onClick={ () => this.selectLink( post.url, post ) } | ||
aria-selected={ index === selectedSuggestion } | ||
> | ||
{ decodeEntities( post.title ) || __( '(no title)' ) } | ||
|
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.
What does this mean? Oh, wait, I think I see. I think this should be something like:
right?
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.
I think saying this might be an improvement:
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.
Agreed, that's great 👍