-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Adds support for browser autofill #2174
Conversation
If I understand this correctly, finishing this without the autocomplete styling would be a lot easier (since that is already done)? Recreating the native autocomplete styling seems unnecessarily complicated. It doesn't seem necessary, and getting the styling right across platforms (browser, OS) might be really hard. Maybe we can start with a PR without the styling and get that merged (or we publish a fork for a while and test that in production). Meanwhile, do a second PR that deals with the styling. If the project owners find that unnecessary or too risky, it can be left out. |
Thanks for working ont his @mmintel! Just a heads up, you seem to be working in the |
@JedWatson I am only working on the src files, the changes from the dist files come from |
4dd08e5
to
02cf4f5
Compare
Gotcha, that's definitely worse. Hopefully you can get the proper styles working then. |
Turns out it's more than complicated to get the styling right, but finally I found this "hacky" way to detect autofill suggestions: https://medium.com/@brunn/detecting-autofilled-fields-in-javascript-aed598d25da7. Still working on it but it looks much better now. |
@JedWatson @jzaefferer I pushed my recent changes including some unit tests that "should normally" work but I need to test them without a So I was trying to set the wrapper like this: wrapper = createControlWithWrapper({
value: false,
autoComplete: 'test',
multi: false,
name: 'field',
options: options,
simpleValue: true,
}); And I am always getting this error message:
when I set it like this it works but is not what I am trying to test: wrapper = createControlWithWrapper({
value: 2,
...
}); same result when I try to change the It's crashing here: var simulateAutoFill = (text) => {
TestUtils.Simulate.change(getHiddenInput(instance), { target: { value: text } });
}; because Help really appreciated! :) |
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.
Overall looking pretty good. There's some parts I don't understand, so I hope other contributors can review this as well.
src/Select.js
Outdated
this.setState({ | ||
isOpen: false, | ||
inputValue: this.handleInputValueChange(''), | ||
}, this.focus); | ||
} | ||
|
||
setAutofill () { | ||
const hasValue = this.getValueArray(this.props.value).length; |
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.
Why is this line here? hasValue
isn't used, getValueArray
doesn't seems to have any side effects.
var options = [ | ||
{ value: 'UK', label: 'United Kingdom' }, | ||
{ value: 'ES', label: 'Spain' }, | ||
{ value: 'DE', label: 'Germany' }, |
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.
We should probably add a few more countries here, so that users and other contributors can also test this with their specific autofill country.
displayName: 'AutoCompleteField', | ||
propTypes: { | ||
label: PropTypes.string, | ||
searchable: PropTypes.bool, |
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.
This isn't used. autoComplete
is used, but missing
selectValue: newValue, | ||
}); | ||
}, | ||
toggleCheckbox (e) { |
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.
This looks like it was copied from another demo, but isn't needed here.
less/control.less
Outdated
&.is-autofill.is-focused .Select-input, | ||
&.is-autofill.is-focused:not(.is-open) > .Select-control { | ||
@media (-webkit-min-device-pixel-ratio:0) { | ||
background-color: #faffbd; |
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.
Let's add a comment here explaining this particular color value, like
// simulate Chrome's native autofill styling
src/Select.js
Outdated
@@ -59,10 +64,17 @@ class Select extends React.Component { | |||
'onOptionRef', | |||
'removeValue', | |||
'selectValue', | |||
'setAutofill', |
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.
Looks like these four don't have to be here, since they're all called directly, and not used as event handlers. So no need for binding them.
src/Select.js
Outdated
].forEach((fn) => this[fn] = this[fn].bind(this)); | ||
|
||
this.autoCompleteEnabled = !this.props.multi && this.props.autoComplete; |
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.
This looks like it should be a method that get's called where needed, since these props could change and the constructor runs only once.
src/Select.js
Outdated
@@ -147,6 +162,22 @@ class Select extends React.Component { | |||
this.toggleTouchOutsideEvent(false); | |||
} | |||
|
|||
handleAutoFillAnimation ({ target, animationName }) { |
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.
target
isn't used, can it be removed?
src/Select.js
Outdated
@@ -1084,6 +1185,7 @@ Select.propTypes = { | |||
'aria-labelledby': PropTypes.string, // HTML ID of an element that should be used as the label (for assistive tech) | |||
arrowRenderer: PropTypes.func, // Create drop-down caret element | |||
autoBlur: PropTypes.bool, // automatically blur the component when an option is selected | |||
autoComplete: PropTypes.string, // support for form auto completion |
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.
comment indent doesn't line up anymore
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.
Some more little stuff
var AutoCompleteField = createClass({ | ||
displayName: 'AutoCompleteField', | ||
propTypes: { | ||
autoComplete: PropTypes.string, |
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 you were a bit too eager here. The label
prop is still in use.
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.
Ah right
// reveal hidden input for testing | ||
document.querySelector('[autocomplete="country"]').classList.remove('Select-hidden'); | ||
}, | ||
getDefaultProps () { |
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.
While we're here, this is not needed
import createClass from 'create-react-class'; | ||
import PropTypes from 'prop-types'; | ||
import Select from 'react-select'; | ||
import { COUNTRIES } from '../data/countries'; |
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.
Let's use module.exports = ...
in that file (or export default
?!) and import countries = ...
here.
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 implemented it this way because other files in /data had the same structure
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.
ok mark as resolved
return ( | ||
<div className="section"> | ||
<h3 className="section-heading">{this.props.label} <a href="https://github.com/JedWatson/react-select/tree/master/examples/src/components/AutoComplete.js">(Source)</a></h3> | ||
<div style={{ display: 'flex', justifyContent: 'flex-end' }}> |
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 still find this strange - its part of the example, so lets use normal layout here.
src/Select.js
Outdated
@@ -147,6 +157,26 @@ class Select extends React.Component { | |||
this.toggleTouchOutsideEvent(false); | |||
} | |||
|
|||
isAutoCompleteEnabled() { | |||
return !this.props.multi && this.props.autoComplete; |
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 wonder if this should also check for autoComplete !== 'off'
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.
Good idea
Could you look into those? Also for new props a readme update would be great. Since this is currently mostly-Chrome, do you see any way to make this work in other browsers as well? |
@jzaefferer I updated the README and resolved the conflicts. However I don't know how to test this with Safari and Firefox, because for me autofill doesn't work at all in those browsers. In Safari it just shows me an icon for autofill suggestions but that doesn't do anything (although the information in my contacts are filled in correctly). Firefox doesn't give me any suggestions, also there seem to be no way to edit saved autofill values in Firefox. Also tried this with other forms to validate it's not only a problem with react-select. |
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.
With all the unrelated changes to the README its impossible to review the relevant changes. Can you please undo those?
README.md
Outdated
[![Build Status](https://travis-ci.org/JedWatson/react-select.svg?branch=master)](https://travis-ci.org/JedWatson/react-select) | ||
[![Coverage Status](https://coveralls.io/repos/JedWatson/react-select/badge.svg?branch=master&service=github)](https://coveralls.io/github/JedWatson/react-select?branch=master) | ||
[![Supported by Thinkmill](https://thinkmill.github.io/badge/heart.svg)](http://thinkmill.com.au/?utm_source=github&utm_medium=badge&utm_campaign=react-select) | ||
[![NPM](https://img.shields.io/npm/v/react-select.svg)](https://www.npmjs.com/package/react-select) [![CDNJS](https://img.shields.io/cdnjs/v/react-select.svg)](https://cdnjs.com/libraries/react-select) [![Build Status](https://travis-ci.org/JedWatson/react-select.svg?branch=master)](https://travis-ci.org/JedWatson/react-select) [![Coverage Status](https://coveralls.io/repos/JedWatson/react-select/badge.svg?branch=master&service=github)](https://coveralls.io/github/JedWatson/react-select?branch=master) [![Supported by Thinkmill](https://thinkmill.github.io/badge/heart.svg)](http://thinkmill.com.au/?utm_source=github&utm_medium=badge&utm_campaign=react-select) |
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.
Why did these change?
README.md
Outdated
|
||
React-Select | ||
============ | ||
# React-Select |
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.
Or this? Or the various other minor changes that are unrelated? I don't think we should mix a more general cleanup into this PR.
8952889
to
ca4f169
Compare
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.
A few more details that should improve the documentation
README.md
Outdated
/> | ||
``` | ||
|
||
You can use the `onAutoFill` callback to react to autofill state changes. |
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's the usecase for that?
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.
if you want to react to autofill state change on another level.. for example if you want to transport an is-autofilled
to a parent node.
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.
to autofill state changes, for example to adjust the styling of a wrapper component.
?
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.
Looks good to me!
@JedWatson would you mind to review this again? We've put a lot of work into this in the last weeks and also implemented this in one of our projects successfully. The "coveralls" check is complaining about a decreased coverage but I've implemented some tests to make sure autoComplete is working so that should not be the problem. You will find a quick explanation in the README and you can try it out yourself in the examples. Please let us know :) |
Looks like this branch has conflicts again. Would be nice to know if this could get merged at some point soon - the longer this stays open, the more conflicts will pile up. |
@JedWatson @jzaefferer please merge this. How can I help? we need it. |
@JedWatson @jzaefferer @mmintel I have resolved the conflicts and tested it, my work is here: Can we get this merged in please? I'll raise my own PR if that is what you wish. |
looks like I missed this one line after reviewing my diff remove dist restore old dist revert this Merge remote-tracking branch 'origin/master'
looks like I missed this one line after reviewing my diff remove dist restore old dist revert this Merge remote-tracking branch 'origin/master' Merge branch 'master' of https://github.com/davidcoleman007/react-select restore dist
Any updates on when this PR will get merge? |
@CarlosOlave I have raised a clean PR with no conflicts which is also still pending: |
Hi all, I'm closing this issue in favor of #2395 which is more up to date with a newer PR. In an effort to sustain the However, if you feel this issue is still relevant, please leave a comment and we'll do our best to get back to you, and we'll re-open it if necessary. |
Hi there,
I am preparing a fix for #1397, if you'd like to help me you can find my progress over here: https://github.com/sevenval/react-select.
What I basically changed was just updating the inputValue when the hidden input changes. To help with styling I am also adding a class "is-autofilled" in that case.
The autofilling itself is already working but I still have some styling issues. The problem is that Chrome ignores many css rules when autofill was applied. It's really hard to recreate the "natural autoComplete behaviour" because Chrome already applies the yellow background to inputs when it's just "suggesting" values, but I didn't find a way to react to those suggestions via javascript.
Also it currently only works
autosize={false}
because this adds awidth="5px"
on the input field, still have to figure out why this is needed and how I can optimize this.Cheers!