Skip to content

Commit

Permalink
Merge branch 'master' into fix/ClearToOpen
Browse files Browse the repository at this point in the history
  • Loading branch information
JedWatson authored Dec 14, 2017
2 parents 63f1d10 + 700b79a commit fbe0567
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 17 deletions.
1 change: 1 addition & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

## v1.0.0 / 2017-11-23

* breaking; removed `getInputValue` function - [see PR](https://github.com/JedWatson/react-select/pull/2108)
* reverted spacebar-selects-option behaviour for searchable selects, thanks [Charles Lee](https://github.com/gwyneplaine) - [see PR](https://github.com/JedWatson/react-select/pull/2163)
* fixed behaviour where async doesn't handle onInputChange returning a value, thanks [Anton](https://github.com/tehbi4) - [see PR](https://github.com/JedWatson/react-select/pull/2133)
* fixed Creatable bug where the first enter keypress is ignored when `promptTextCreator` returns only the label, thanks [George Karagkiaouris](https://github.com/karaggeorge) - [see PR](https://github.com/JedWatson/react-select/pull/2140)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class App extends React.Component {
return (
<Select
name="form-field-name"
value={this.state.value}
value={this.state.selectedOption.value}
onChange={this.handleChange}
options={[
{ value: 'one', label: 'One' },
Expand Down Expand Up @@ -372,7 +372,7 @@ function onInputKeyDown(event) {
| `name` | string | undefined | field name, for hidden `<input />` tag |
| `noResultsText` | string | 'No results found' | placeholder displayed when there are no matching search results or a falsy value to hide it (can also be a react component) |
| `onBlur` | function | undefined | onBlur handler: `function(event) {}` |
| `onBlurResetsInput` | boolean | true | whether to clear input on blur or not |
| `onBlurResetsInput` | boolean | true | Whether to clear input on blur or not. If set to false, it only works if onCloseResetsInput is false as well. |
| `onChange` | function | undefined | onChange handler: `function(newOption) {}` |
| `onClose` | function | undefined | handler for when the menu closes: `function () {}` |
| `onCloseResetsInput` | boolean | true | whether to clear input when closing the menu through the arrow |
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"dependencies": {
"classnames": "^2.2.4",
"prop-types": "^15.5.8",
"react-input-autosize": "^2.1.0"
"react-input-autosize": "^2.1.2"
},
"devDependencies": {
"babel-cli": "^6.26.0",
Expand Down
6 changes: 5 additions & 1 deletion src/Creatable.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class CreatableSelect extends React.Component {

if (isValidNewOption({ label: this.inputValue })) {
const option = newOptionCreator({ label: this.inputValue, labelKey: this.labelKey, valueKey: this.valueKey });
const isOptionUnique = this.isOptionUnique({ option });
const isOptionUnique = this.isOptionUnique({ option, options });

// Don't add the same option twice.
if (isOptionUnique) {
Expand Down Expand Up @@ -201,6 +201,10 @@ function defaultChildren (props) {
};

function isOptionUnique ({ option, options, labelKey, valueKey }) {
if (!options || !options.length) {
return true;
}

return options
.filter((existingOption) =>
existingOption[labelKey] === option[labelKey] ||
Expand Down
27 changes: 14 additions & 13 deletions src/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ class Select extends React.Component {
// Used to be required but it's not any more
this.setState({ required: false });
}

if (this.state.inputValue && this.props.value !== nextProps.value) {
this.setState({ inputValue: this.handleInputValueChange('') });
}
}

componentDidUpdate (prevProps, prevState) {
Expand Down Expand Up @@ -294,21 +298,18 @@ class Select extends React.Component {
return;
}

// If the menu isn't open, let the event bubble to the main handleMouseDown
if (!this.state.isOpen) {
if (this.state.isOpen) {
// prevent default event handlers
event.stopPropagation();
event.preventDefault();
// close the menu
this.closeMenu();
} else {
// If the menu isn't open, let the event bubble to the main handleMouseDown
this.setState({
isOpen: true,
});
}

// prevent default event handlers
event.stopPropagation();
event.preventDefault();

// close the menu
if(this.state.isOpen){
this.closeMenu();
}
}

handleMouseDownOnMenu (event) {
Expand Down Expand Up @@ -578,8 +579,8 @@ class Select extends React.Component {
if (this.props.closeOnSelect) {
this.hasScrolledToOption = false;
}
const updatedValue = this.props.onSelectResetsInput ? '' : this.state.inputValue;
if (this.props.multi) {
const updatedValue = this.props.onSelectResetsInput ? '' : this.state.inputValue;
this.setState({
focusedIndex: null,
inputValue: this.handleInputValueChange(updatedValue),
Expand All @@ -594,7 +595,7 @@ class Select extends React.Component {
});
} else {
this.setState({
inputValue: this.handleInputValueChange(''),
inputValue: this.handleInputValueChange(updatedValue),
isOpen: !this.props.closeOnSelect,
isPseudoFocused: this.state.isFocused,
}, () => {
Expand Down
40 changes: 40 additions & 0 deletions test/Creatable-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,46 @@ describe('Creatable', () => {
expect(test(newOption('qux', 4)), 'to be', true);
expect(test(newOption('Foo', 11)), 'to be', true);
});

it('default: isOptionUnique function should always return true if given options are empty', () => {
const options = [];

function newOption (label, value) {
return { label, value };
};

function test (option) {
return Select.Creatable.isOptionUnique({
option,
options,
labelKey: 'label',
valueKey: 'value'
});
};

expect(test(newOption('foo', 0)), 'to be', true);
expect(test(newOption('qux', 1)), 'to be', true);
});

it('default: isOptionUnique function should not crash if given options are null or undefined', () => {
const options = null;

function newOption (label, value) {
return { label, value };
};

function test (option) {
return Select.Creatable.isOptionUnique({
option,
options,
labelKey: 'label',
valueKey: 'value'
});
};

expect(test(newOption('foo', 0)), 'to be', true);
expect(test(newOption('qux', 1)), 'to be', true);
});

it('default :isValidNewOption function should just ensure a non-empty string is provided', () => {
function test (label) {
Expand Down
28 changes: 28 additions & 0 deletions test/Select-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2246,6 +2246,34 @@ describe('Select', () => {
});
});

describe('clear the display value on receiving props', () => {
beforeEach(() => {
var wrapper = createControlWithWrapper({
options: defaultOptions,
value: 'one',
});
});
it('should clear display value if display is not empty', () => {
expect(instance.state.inputValue, 'to equal', '');
typeSearchText('and');
expect(instance.state.inputValue, 'to equal', 'and');
wrapper.setPropsForChild({
value: 'newValue',
});
expect(instance.state.inputValue, 'to equal', '');
});

it('should not clear display value if value in next props is equal to previous', () => {
expect(instance.state.inputValue, 'to equal', '');
typeSearchText('and');
expect(instance.state.inputValue, 'to equal', 'and');
wrapper.setPropsForChild({
value: 'one',
});
expect(instance.state.inputValue, 'to equal', 'and');
});
});

describe('clearable=true', () => {

beforeEach(() => {
Expand Down

0 comments on commit fbe0567

Please sign in to comment.