Implement allowCreate and newOptionCreator in 1.x#1187
Conversation
8ea9b8f to
a0a91e8
Compare
|
Wow, this is looking awesome! |
|
This looks fantastic @bvaughn! Wanted to throw a couple of more advanced cases at you to see how we could support them (not required for now, just wondering how they might impact the design) 1. Integration with
|
|
Thanks @JedWatson! Glad to hear it lines up with what you were thinking more or less. Both of the use cases you brought up are interesting. I haven't dug into Async calls to The UI interrupt for |
|
Gut feeling regarding async
|
|
@bvaughn 👏 this is awesome to 💯! I noticed that when a new option is selected the |
|
Hey @Stenerson. Nice catch. I'll fix that momentarily. :) |
|
@JedWatson I'm going to try to finish up writing I fly back to the states in 2 weeks though so maybe I can pick up one or both of them on the return trip. Sound reasonable? (Do you think what's here- once test coverage is added- is okay to proceed with for now?) |
19b11a1 to
cd37659
Compare
Added new Creatable HOC that wraps Select and adds support for creating new options. This HOC provides reasonable default behavior (eg create a new option on ENTER/TAB/comma) but also allows users to override defaults via props. No create-option-specific logic is inside of the base Select component and the logic within Creatable is fully customizable. Added new onInputKeyDown prop to Select (a mirror to onInputChange) that allows users to tap into key-down events and prevent default Select handling. (This is key to how new options are created.) Pulled default filterOptions and menuRenderer props out of Select and into separate modules. I think this lines up with @JedWatson's long-term goals. It was also necessary to enable better sharing between the base Select and the new Creatable HOC.
cd37659 to
7fe723f
Compare
|
Okay! Tests are in. Rebased for cleanliness. This branch should be good to go. Any objections? 😄 |
|
Confirmed that the only test failing in this branch also fails for me on |
|
🎉 Thanks @bvaughn! |
|
Hi, so is there any workaround to implement If there are any solutions, please tell me thanks. |
|
@takashi Unfortunately the two HOCs aren't composable at the moment but I'd like to create a follow up PR that adds support for that. With RC1 though, your best bet is to fork Creatable and use the default props (attached as statics on it) to reduce your forked code. |
|
@bvaughn Thanks for replying quickly. I'm glad to hear you are planning to follow up the implementation in the future. I'll fork and try to create my own from Creatable module for work around atm. thanks. |
|
Hoping that the solution is as simple as allowing users to specify which inner |
|
@takashi I'm not sure how @bvaughn or @JedWatson feel about continuing this approach but until the future PR, if you're not keen on forking to make these changes, you can implement a creatable solution using a custom filter function as discussed in #1007 and in the wiki. <Select
options={options}
onChange={ props.handleChange }
filterOptions={(options, filterValue, excludeOptions) => {
let lowerFilterValue = filterValue.toLowerCase();
let filteredOptions = options.filter(option => {
let optionValue = String(option.value).toLowerCase();
let optionLabel = String(option.label).toLowerCase();
return (optionValue.indexOf(lowerFilterValue) > -1 || optionLabel.indexOf(lowerFilterValue) > -1);
});
// This is the important part
if (filterValue.length > 0) {
filteredOptions = filteredOptions.concat({create: true, value: filterValue, label: `Add "${filterValue}"?`});
}
return filteredOptions;
}}
/>Then in your change handler function handleChange(option) {
if (option.create) {
// Do something here for the added option
console.log(option); // {create: true, value: "New Option", label: 'Add "New Option"?'}
} else {
// Do something here for a "normal" selection
console.log(option); // {value: 121, label: "Existing Option"}
}
} |
|
@bvaughn Great Job! |
|
Hi @deepakbansal1010. Thanks! The simplest thing would be to wait for RC2 to be released and then you can snag it directly from unpkg.com/react-select. Alternately you can check out this project and build it yourself to get a copy sooner: # shallow clone
git clone git@github.com:JedWatson/react-select.git --depth 1
cd react-select
# install dependencies
npm i
# build project
npm run build
# built source will be available in the 'dist' folder |
|
@bvaughn Thank you for your quick response. This will definitely help. |
|
@deepakbansal1010 RC2 will also include a new |
|
Ohh that's really nice! Thanks Again 🙂 @bvaughn |
(Note that 1 test is failing in this branch but I'm fairly confident it is unrelated to this change set.)
Party time!🎈😎 Resolves issues #343, #586, #658, #712, #725, #795, #811, #815, #838, #897, #960, #987, #1007, and #1088.
TODO items remaining for this PR:
CreatableHOC.High level overview
CreatableHOC that wrapsSelectand adds support for creating new options. This HOC provides reasonable default behavior (eg create a new option on ENTER/TAB/comma) but also allows users to override defaults via props. No create-option-specific logic is inside of the baseSelectcomponent and the logic withinCreatableis fully customizable.onInputKeyDownprop toSelect(a mirror toonInputChange) that allows users to tap into key-down events and prevent defaultSelecthandling. (This is key to how new options are created.)filterOptionsandmenuRendererprops out ofSelectand into separate modules. I think this lines up with @JedWatson's long-term goals. It was also necessary to enable better sharing between the baseSelectand the newCreatableHOC.Documentation (snippet added to
README)The
Creatablecomponent enables users to create new tags within react-select. It decorates aSelectand so it supports all of the default properties (eg single/multi mode, filtering, etc) in addition to a couple of custom ones (shown below). The easiest way to use it is like so:Creatable properties
isOptionUnique({ option: Object, options: Array, labelKey: string, valueKey: string }): booleanisValidNewOption({ label: string }): booleannewOptionCreator({ label: string, labelKey: string, valueKey: string }): ObjectshouldKeyDownEventCreateNewOptionkeyCode) should result in the creation of a new option. ENTER, TAB and comma keys create new options by dfeault. Expected signature:({ keyCode: number }): booleanDemo