jedwatson / react-select Goto Github PK
View Code? Open in Web Editor NEWThe Select Component for React.js
Home Page: https://react-select.com/
License: MIT License
The Select Component for React.js
Home Page: https://react-select.com/
License: MIT License
http://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html
A component should not sync its state with its props, the 2 must be separate, like in any form input element in React, i.e an input element created using: <input value={apple} type={text}/>
will always have the value 'apple' no matter what the user does.
The only way to change the value of the input component is by updating its props. <input value={this.state.x} type={text} onChange={this.handleChange} />
However this is not true in the case of react-select, as it syncs its state with props and the state can also be changed by user-input (multiple sources of truth).
The render method must use values from props instead of state. State maybe used to support access to value in the handleChange event, analogous to (this.refs.myInputElement.getDOMNode().value)
This component is currently only tested in browsers I have on hand; latest Safari, Chrome and Firefox on Mac.
It would be great to get a proper support matrix (and tests) going, so people know what to expect and changes can be tested.
None of the javascript involved is particularly special, and we avoided fancy css as well (e.g. flex-box layout) that would have blocked older browsers, so in theory it should be as well supported as React is, and hopefully any issues will be only css / style related.
If you pass the disabled
prop to the <Select />
element, it's completely ignored.
This should:
<input />
element.<Input />
element from react-autosize at all, and only display the placeholder instead.<Select />
element.If you are OK with it, I can provide a PR for this.
Am I the only crazy one having this problem? The React-Autocomplete Input is undefined in the standalone version. I'm not using Require in my project so it is not easy for me to grab the React-Autocomplete files to complete the dependency. Is it possible to have everything needed included in the standalone build including React-Autocomplete?
I was all fired up to hack and send you a PR for another issue I found, but I can't get my fork to build. I ran npm install
and then I get this error on gulp dev
:
/Users/seanhess/sources/react-select/node_modules/gulp-less/index.js:68
}).done(undefined, cb);
^
TypeError: undefined is not a function
at DestroyableTransform._transform (/Users/seanhess/sources/react-select/node_modules/gulp-less/index.js:68:8)
at DestroyableTransform.Transform._read (/Users/seanhess/sources/react-select/node_modules/gulp-less/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:184:10)
at DestroyableTransform.Transform._write (/Users/seanhess/sources/react-select/node_modules/gulp-less/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:172:12)
at doWrite (/Users/seanhess/sources/react-select/node_modules/gulp-less/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:237:10)
at writeOrBuffer (/Users/seanhess/sources/react-select/node_modules/gulp-less/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:227:5)
at DestroyableTransform.Writable.write (/Users/seanhess/sources/react-select/node_modules/gulp-less/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:194:11)
at write (/Users/seanhess/sources/react-select/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:623:24)
at flow (/Users/seanhess/sources/react-select/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:632:7)
at DestroyableTransform.pipeOnReadable (/Users/seanhess/sources/react-select/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:664:5)
at DestroyableTransform.emit (events.js:104:17)
When you've got an option selected and it's async-loading options, the loading indicator and the 'clear' cross overlap. We need to position the loading indicator correctly when there's a value set.
Might require adding has-value
and is-loading
to the main selectClass
class set.
I'm interested in using this plugin as a regular dropdown (like in the react-dropdown
module, purely for styling purposes) and would love a way to disable the input field and autocomplete functionality. Is this something you would be interested in adding?
The height of the component is incorrect in Safari, it looks right in Chrome though. May be a line-height issue.
@jossmac would you mind having a look at this?
I've noticed that when you're navigating the list of options with the keyboard, it is possible to focus an option that's lower than the scrollHeight of the menu.
It should make sure that the currently focused option is always scrolled into view.
My thoughts on the current behaviour of the select component:
I'm using the react-select component in my application and whenever it is referenced in my Jest tests I get an error that says "RangeError: Maximum call stack size exceeded".
Here is a basic test I've written using Jest based on the react-select example.
/** @jsx React.DOM */
'use strict';
jest.autoMockOff();
var React = require("react/addons");
var Select = require("react-select");
var TestUtils = React.addons.TestUtils;
describe("Select test", function() {
var Select = require('react-select');
var options = [
{ value: 'one', label: 'One' },
{ value: 'two', label: 'Two' }
];
function logChange(val) {
console.log("Selected: " + val);
}
// Render an instance of the component
var instance = TestUtils.renderIntoDocument(
<Select
name="form-field-name"
value="one"
options={options}
onChange={logChange}/>
);
});
By simplifying the test to this level, I can assume the range error is happening within react-select. I also see Issue #73 there are no tests for react-select.
Does anyone else have a similar issue? I'm quite surprised the basic example implementation of the component won't pass a simple unit test.
From what I can see in the code here:
filterOptions: function(options, values) {
var filterValue = this._optionsFilterString;
var exclude = (values || this.state.values).map(function(i) {
return i.value;
});
var filterOption = function(op) {
if (this.props.multi && _.contains(exclude, op.value)) return false;
return (
!filterValue
|| op.value.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0
|| op.label.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0
);
}
return _.filter(options, filterOption, this);
},
(Lines 318-332 currently)
There's no way to edit how the filtering is done, but I'd like to restrict the results to options whose values start with the current value of the text box. I realize I can very easily edit this section of the code to do that, but it would be cool if this option came from a prop (like match={both/start} or something like that). https://github.com/rackt/react-autocomplete has that option and it's been pretty useful.
It would be nice to have an option to pass custom data that would be passed on to handleSelect.
something like:
options.push({
label: 'label',
value: 'value',
id: 494949494
});
id
being the value i want to get back later on selection/deletion.
I'm having the problem with both react-select 0.3.3 and 0.3.4 in combinaison with React 0.12.2
In the chrome console:
e=React.createElement(Select, {name: 'a', options: [{label:'1', value: '1'}]})
ReactElement {type: function, key: null, ref: null, _owner: null, _context: Object…}
React.render(e, document.getElementById('test_element'))
react.js:18108 Warning: React.createElement: type should not be null or undefined. It should be a string (for DOM elements) or a ReactClass (for composite components).
e.type
react.js:6691 function (props) {
// This constructor is overridden by mocks. The argument is used
// by mocks to assert on what gets mounted. This will later be used
// by the stand-alone class implementation.
}
Great lib, thx. However I want our single-select box to blur when an option is selected rather than remain focused with cursor in the input. To accomplish this right now it seems I not only have to ...querySelector('.Select-input input').blur()
in the onChange
handler but I have to put it in a timeout. Is there an easier way to accomplish this and/or get it as an option?
Is there a way of having option groups, like the standard optgroup element in html select?
Replicate by clicking the first select on the demo page, putting your mouse cursor over the first option, and pressing ArrowDown. When you get to the bottom of the visible window and ArrowDown once more, the window scrolls causing the mouseEnter handler to fire on the top option and focus goes from Tasmania (which just scrolled into view) back up to the top option.
They way I've seen this handled is to keep a flag that tells whether or not the user is using the keyboard on the component, and then check it in the mouseEnter handler. Would look something like this:
var ex = {
usingKeyboardOn: function() {
if (this.usingKeyboard) { return; }
document.removeEventListener("keydown", this.usingKeyboardOn, true);
document.addEventListener("wheel", this.usingKeyboardOff, true);
document.addEventListener("mousemove", this.usingKeyboardOff, true);
this.usingKeyboard = true;
},
usingKeyboardOff: function() {
if (!this.usingKeyboard) { return; }
document.addEventListener("keydown", this.usingKeyboardOn, true);
document.removeEventListener("wheel", this.usingKeyboardOff, true);
document.removeEventListener("mousemove", this.usingKeyboardOff, true);
this.usingKeyboard = false;
},
handleMouseEnter: function(op) {
if (!this.usingKeyboard) { this.focusOption(op); }
},
}
please add 'var' in props.
https://github.com/JedWatson/react-select/blob/master/src/Select.js#L492
If you set the value on the component before the options are available (e.g. from a parent component's state, which got them from an async store), when the options are finally retrieved and the component is rerendered, the select placeholder stays stuck on the option value rather than displaying the option label. This doesn't seem to be an issue when using the async prop.
3 sec delay example:
... but should be called only once. Looks like there is a bug.
https://github.com/JedWatson/react-select/blob/master/lib/Select.js#L367 this code might break if values is number instead of string.
Thanks for the component.
For example, I might pass an options array that looks like this:
var options = [
{ value: '1', label: 'Red' },
];
If the app gets some new data and I need to re-render the component, I might pass a new options array that looks like this:
var options = [
{ value: '1', label: 'Red' },
{ value: '2', label: 'Blue' }
];
After the re-render, the new option's html will have a label of "2" instead of "Blue".
The problem appears to lie in initValuesArray
, which in this case is getting triggered by componentWillReceiveProps
. initValuesArray
is passed a new value from newProps
, but it attempts to look up the label in this.state.options
, which has not yet been updated with the new props. It seems like getStateFromValue
should have two parameters, one for the value and one for the options array.
I could try to submit a pull request if you agree. Or am I misunderstanding something about how the component should be used?
When typing in select field, it would be great if it auto highlighted the first option listed in the search results. This should then get auto populated in the field if the user presses either TAB or ENTER and should also move to the next field.
This would have to only occur when 1 or more characters are typed AND search results are displayed. Because if the field is not mandatory and the users presses TAB without typing it should remain blank.
Perhaps the results could bold the matching parts of the search string? eg.
Search: Sou
Results: New South Wales
doesn't fire
HTML options tag doesn't allow value to be any other type than string. But this component should allow this because it is usually more convenient to make values as integer ids. Developers shouldn't always make conversion from string to int and vice versa themselves.
Currently, you have to hit down arrow to highlight the first choice and then hit return to select it. First choice should be highlighted by default.
It would be great if option labels weren't limited to only strings. I'd like to be able to pass in any React element and have it rendered as a regular option. The use case that I'm specifically thinking of is a bootstrap "badge" to show a count next to the select option
http://getbootstrap.com/components/#badges
I made this change in a branch locally and would be happy to submit the PR!
Currently trying to figure out how to get Browserify to correctly bundle a standalone version that can be published to Bower from the gulp task.
I haven't had chance to reduce this error down, but I think it's when Select is rendered inside a flexbox container.
Adding position:relative
to .Select
makes it display as expected.
I was puzzled to see react-select pulling reactify when installing it via npm.
Forgive my ignorance on Browserify (webpack user here), but even after reading the related discussion on #8 I don't see how the library should depend on a build-related piece. That decision is up to the developers making use of react-select, and they are able to set such dependency in the package.json of their respective projects.
Therefore I believe reactify should be removed from the dependencies
section of react-select's package.json.
I may be missing some of this info, but I can't seem to find it anywhere.
I have a component.
<Select
multi={true}
options={this.state.storeList}
value={this.state.stores}
onChange={this._onChange} />
{(this.state.stores.length > 0) ?
<Select multi={true} autoload={false} asyncOptions={this.loadOptions} />
: <div>Please select a store</div> }
When stores are selected you can then filter down the inventory based on stores. This works fine until someone clears some of the selected stores. Then the inventory select is out of date. I guess I need to force a re render on the select component or give it new options? Is there a good workflow for this?
Also is there a plan to add a remote search api? Like if someone enters a string hits a server to give back results? Thanks.
It should open the context menu as expected, or otherwise allow the event to continue to its default handler.
When user type in the input, if he knows what to type, he may expect to select the right option when type in the value and hit Enter
.
For example, If there's a list of countries I need to select ['China', 'Japan', 'USA'], when I finish typing China
and I expect to select China
when I hit Enter. Currently I need to arrow key down and select it or by mouse click.
I'm creating this issue to roll together #26, #35 and #38 as a central place for feedback and ideas.
It appears there are several issues relating to the build process and use of JSX, including:
reactify
) are included for the Browserify build process, when you're using Webpack (#35).js
as the script extension means Webpack needs special config to process the JSX (#26)The simplest way to side-step these issues is to avoid JSX in this and any other packaged component, however I'd much prefer to just figure out how to solve this problem and have a great build and packaging process that works everywhere and doesn't have these issues.
In addition, I've created a common gulp tasks package (react-component-gulp-tasks) and a react component generator (generator-react-component) with the hopes of solving the problems of how to build and maintain react components for other developers too. It would be great to get some consistency in this space, imo.
To recap, my requirements for the build process / tasks are:
I would also prefer not to have to rename my javascript files to .jsx
files. This is a purely personal preference; I'm willing to be pragmatic but ideally with the right pre-processor setup, you should be able to switch between using JSX or ES6 syntax in a file, and vanilla Javascript, without changing the extension.
I'd really appreciate everyone's input into how these requirements can be met, hopefully we can achieve all of them.
Not sure if this is misconfiguration or an issue with Browserify / Watchify.
When building the example files, using browserify.require
files with Watchify, with the following error thrown:
Uncaught Error: Cannot find module '[...]/react-select/node_modules/react/react.js'
The issue appears to be the use of watchify.args
, which is equivalent to { cache: {}, packageCache: {}, fullPaths: true }
, and specifically the combination of the fullPaths: true
option and require('react')
.
It's possible that exposing multiple packages in a bundle using browserify:require
doesn't work with watchify
; this would be a shame though, because it's useful to be able to develop both the react-select
component (as exposed from ./lib/select.js
) and the example app.js
file at the same time, using Watchify.
To reproduce, npm install
then
gulp build-examples
./examples/index.html
in a browser (works)gulp watch-examples
./examples/index.html
in a browser (breaks)cc @cgiffard
The select is not responding at all on iOS 7 (tested on iPad Air 1).
I will let you know if I find a fix for that.
Alright, this one is pretty freaking obscure, so pardon me as I try to explain this. I also will try to put together a simplified test case and hopefully even fix it, but I thought I would log it here :)
The issue does not present itself on the example page due to the relatively small height of the page; however, should you shrink your browser window so that the page is forced to scroll, scroll partially down the page, open the "States Select" and try to manually drag the scroll bar (via the handle) The select menu will close immediately due to handleInputBlur being called.
While I recognize the use case of clicking a scroll bar manually is probably few and far between, it is unexpected behavior.
If anyone has experienced this and knows a fix that does NOT involve patching react-select, I'd love to not need to go hacking around what I imagine is going to be a pretty nasty browser API issue.
That's a nice component but how come there are no tests?
I think this is related to issue #35
I'm rendering components server-side in Node and when firing up the server trying to use the npm module I get the following error:
/node_modules/react-select/src/Select.js:439
return <div key={'option-' + op.value}
^
SyntaxError: Unexpected token <
at Module._compile (module.js:439:25)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/src/app/components/thiscomponent.jsx:3:11)
at Module._compile (module.js:456:26)
at Object.require.extensions.(anonymous function) [as .jsx] (/node_modules/node-jsx/index.js:26:12)
at Module.load (module.js:356:32)
It would appear that the .js extension is not compiling correctly.
The only fix I could come up with was hardcoding the react-select module (and dependencies. auto-text-resize had same syntax issue) into my apps components and renaming the extensions .jsx. Now everything works.
Is there something we can do, or I can help with to get this working node side?
Thanks for the rad component!
I looked through the set of open issues but did not not see an open one concerning the error that I receiving.. sorry if this is has been asked before..
I installed the package via NPM and when I require it in my module.
var Select = require('react-select');
i get "Cannot find module "react-select" MODULE NOT FOUND"
I am using webpack.
Any advice?
In multiselect mode, pressing backspace to edit filter text you've typed immediately deletes all your filter text and the last item you added to the select
Possible fix:
case 8: // backspace
if (!this.state.inputValue) {
this.popValue();
}
I've noticed that for the remote select field in the example, blurring the field after selecting a value will clear the value. This is not the case for the basic example, which works as expected.
the files are named *.js and lack the required jsx header,
this is fine when you use reactify, but i'm using webpack and hot loader, what makes them un-readable as js file.
to solve the problem I've changed them to jsx with :"@jsx React.DOM",
Is there any better way?
It would be nice to have an option to end the multiselect, I mean, after selecting 3 elements (for example) it would be nice to end the selection (if user wants to).
On Google Chrome 37.0.2062.120 m - windows, when I select an item with the mouse in the demo (http://jedwatson.github.io/react-select/), I sometimes get a strange flicker (the cursor flickers, and sometimes a word gets selected too).
I cannot take a screengrab, because as soon as chrome loses focus, it is resolved.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.