From 0d3dec6c9168e0f00aced799b88e6a1659629508 Mon Sep 17 00:00:00 2001 From: frankievx Date: Mon, 18 Jul 2016 03:10:54 -0500 Subject: [PATCH 01/41] Add onCloseResetsInput to the readme to understand usage --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e50a42c6..e1f8e577 100644 --- a/README.md +++ b/README.md @@ -296,6 +296,7 @@ function cleanInput(inputValue) { onBlurResetsInput | bool | true | whether to clear input on blur or not onChange | func | undefined | onChange handler: `function(newValue) {}` onClose | func | undefined | handler for when the menu closes: `function () {}` + onCloseResetInput | bool | true | whether to clear input when closing the menu through the arrow onFocus | func | undefined | onFocus handler: `function(event) {}` onInputChange | func | undefined | onInputChange handler: `function(inputValue) {}` onOpen | func | undefined | handler for when the menu opens: `function () {}` From f515711074847fc9d5a75febb2c98f9b4dad50b3 Mon Sep 17 00:00:00 2001 From: frankievx Date: Mon, 18 Jul 2016 03:19:25 -0500 Subject: [PATCH 02/41] Implement onCloseResetsInput feature --- src/Select.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Select.js b/src/Select.js index 21748bb9..795f4d4e 100644 --- a/src/Select.js +++ b/src/Select.js @@ -70,6 +70,7 @@ const Select = React.createClass({ onBlurResetsInput: React.PropTypes.bool, // whether input is cleared on blur onChange: React.PropTypes.func, // onChange handler: function (newValue) {} onClose: React.PropTypes.func, // fires when the menu is closed + onCloseResetsInput: React.PropTypes.bool, // whether input is cleared when menu is closed through the arrow onFocus: React.PropTypes.func, // onFocus handler: function (event) {} onInputChange: React.PropTypes.func, // onInputChange handler: function (inputValue) {} onMenuScrollToBottom: React.PropTypes.func, // fires when the menu is scrolled to the bottom; can be used to paginate options @@ -126,6 +127,7 @@ const Select = React.createClass({ multi: false, noResultsText: 'No results found', onBlurResetsInput: true, + onCloseResetsInput: true, openAfterFocus: false, optionComponent: Option, pageSize: 5, @@ -344,11 +346,19 @@ const Select = React.createClass({ }, closeMenu () { - this.setState({ - isOpen: false, - isPseudoFocused: this.state.isFocused && !this.props.multi, - inputValue: '', - }); + if(this.props.onCloseResetsInput) { + this.setState({ + isOpen: false, + isPseudoFocused: this.state.isFocused && !this.props.multi, + inputValue: '' + }); + } else { + this.setState({ + isOpen: false, + isPseudoFocused: this.state.isFocused && !this.props.multi, + inputValue: this.state.inputValue + }); + } this.hasScrolledToOption = false; }, From a40af0e32c87e1c60dd08fcccfb002049cf02b08 Mon Sep 17 00:00:00 2001 From: frankievx Date: Mon, 18 Jul 2016 03:24:17 -0500 Subject: [PATCH 03/41] Add tests to cover new onCloseResetsInput feature --- test/Select-test.js | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/Select-test.js b/test/Select-test.js index 748541e3..f59b2f0c 100644 --- a/test/Select-test.js +++ b/test/Select-test.js @@ -2651,6 +2651,40 @@ describe('Select', () => { expect(eventHandler, 'was called once'); }); }); + + describe('with onCloseResetsInput=true', () => { + beforeEach(() => { + instance = createControl({ + options: defaultOptions, + onCloseResetsInput: true + }); + typeSearchText('test'); + }); + + it('should clear the search input after calling onBlur', () => { + const domNode = ReactDOM.findDOMNode(instance); + TestUtils.Simulate.mouseDown(domNode.querySelector('.Select-control')); + TestUtils.Simulate.keyDown(domNode.querySelector('input'), { keyCode: 27, key: 'Escape' }); + expect(ReactDOM.findDOMNode(instance).querySelector('input').value, 'to equal', ''); + }); + }); + + describe('with onCloseResetsInput=false', () => { + beforeEach(() => { + instance = createControl({ + options: defaultOptions, + onCloseResetsInput: false + }); + typeSearchText('test'); + }); + + it('should clear the search input after calling onClose', () => { + const domNode = ReactDOM.findDOMNode(instance); + TestUtils.Simulate.mouseDown(domNode.querySelector('.Select-control')); + TestUtils.Simulate.keyDown(domNode.querySelector('input'), { keyCode: 27, key: 'Escape' }); + expect(ReactDOM.findDOMNode(instance).querySelector('input').value, 'to equal', 'test'); + }); + }); describe('optionRenderer', () => { From 90dfe43695063eb4eb4b4d3c23f97b467a9ead99 Mon Sep 17 00:00:00 2001 From: frankievx Date: Mon, 18 Jul 2016 04:05:54 -0500 Subject: [PATCH 04/41] Run Build --- dist/react-select.js | 20 +++++++++++++++----- dist/react-select.min.js | 4 ++-- examples/dist/bundle.js | 20 +++++++++++++++----- examples/dist/standalone.js | 20 +++++++++++++++----- lib/Select.js | 20 +++++++++++++++----- 5 files changed, 62 insertions(+), 22 deletions(-) diff --git a/dist/react-select.js b/dist/react-select.js index e08f97fe..00e6d544 100644 --- a/dist/react-select.js +++ b/dist/react-select.js @@ -427,6 +427,7 @@ var Select = _react2['default'].createClass({ onBlurResetsInput: _react2['default'].PropTypes.bool, // whether input is cleared on blur onChange: _react2['default'].PropTypes.func, // onChange handler: function (newValue) {} onClose: _react2['default'].PropTypes.func, // fires when the menu is closed + onCloseResetsInput: _react2['default'].PropTypes.bool, // whether input is cleared when menu is closed through the arrow onFocus: _react2['default'].PropTypes.func, // onFocus handler: function (event) {} onInputChange: _react2['default'].PropTypes.func, // onInputChange handler: function (inputValue) {} onMenuScrollToBottom: _react2['default'].PropTypes.func, // fires when the menu is scrolled to the bottom; can be used to paginate options @@ -483,6 +484,7 @@ var Select = _react2['default'].createClass({ multi: false, noResultsText: 'No results found', onBlurResetsInput: true, + onCloseResetsInput: true, openAfterFocus: false, optionComponent: _Option2['default'], pageSize: 5, @@ -701,11 +703,19 @@ var Select = _react2['default'].createClass({ }, closeMenu: function closeMenu() { - this.setState({ - isOpen: false, - isPseudoFocused: this.state.isFocused && !this.props.multi, - inputValue: '' - }); + if (this.props.onCloseResetsInput) { + this.setState({ + isOpen: false, + isPseudoFocused: this.state.isFocused && !this.props.multi, + inputValue: '' + }); + } else { + this.setState({ + isOpen: false, + isPseudoFocused: this.state.isFocused && !this.props.multi, + inputValue: this.state.inputValue + }); + } this.hasScrolledToOption = false; }, diff --git a/dist/react-select.min.js b/dist/react-select.min.js index 61cf493e..71fc7882 100644 --- a/dist/react-select.min.js +++ b/dist/react-select.min.js @@ -1,2 +1,2 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.Select=e()}}(function(){return function e(t,u,s){function o(i,a){if(!u[i]){if(!t[i]){var r="function"==typeof require&&require;if(!a&&r)return r(i,!0);if(n)return n(i,!0);var l=new Error("Cannot find module '"+i+"'");throw l.code="MODULE_NOT_FOUND",l}var p=u[i]={exports:{}};t[i][0].call(p.exports,function(e){var u=t[i][1][e];return o(u?u:e)},p,p.exports,e,t,u,s)}return u[i].exports}for(var n="function"==typeof require&&require,i=0;i=0;--u){var s=t.slice(0,u);if(e[s]&&(t===s||e[s].complete))return e[s]}}function a(e,t){if(e&&"function"==typeof e.then)return e.then(function(e){t(null,e)},function(e){t(e)})}var r=Object.assign||function(e){for(var t=1;ta.bottom||i.topt.offsetHeight&&!(t.scrollHeight-t.offsetHeight-t.scrollTop)&&this.props.onMenuScrollToBottom()}},handleRequired:function(e,t){return!e||(t?0===e.length:0===Object.keys(e).length)},getOptionLabel:function(e){return e[this.props.labelKey]},getValueArray:function(e,t){var u=this,s="object"==typeof t?t:this.props;if(s.multi){if("string"==typeof e&&(e=e.split(s.delimiter)),!Array.isArray(e)){if(null===e||void 0===e)return[];e=[e]}return e.map(function(e){return u.expandValue(e,s)}).filter(function(e){return e})}var o=this.expandValue(e,s);return o?[o]:[]},expandValue:function(e,t){if("string"!=typeof e&&"number"!=typeof e)return e;var u=t.options,s=t.valueKey;if(u)for(var o=0;o0?u-=1:u=t.length-1;else if("start"===e)u=0;else if("end"===e)u=t.length-1;else if("page_up"===e){var o=u-this.props.pageSize;u=o<0?0:o}else if("page_down"===e){var o=u+this.props.pageSize;u=o>t.length-1?t.length-1:o}u===-1&&(u=0),this.setState({focusedIndex:t[u].index,focusedOption:t[u].option})}},selectFocusedOption:function(){if(this._focusedOption)return this.selectValue(this._focusedOption)},renderLoading:function(){if(this.props.isLoading)return l["default"].createElement("span",{className:"Select-loading-zone","aria-hidden":"true"},l["default"].createElement("span",{className:"Select-loading"}))},renderValue:function(e,t){var u=this,s=this.props.valueRenderer||this.getOptionLabel,o=this.props.valueComponent;if(!e.length)return this.state.inputValue?null:l["default"].createElement("div",{className:"Select-placeholder"},this.props.placeholder);var n=this.props.onValueClick?this.handleValueClick:null;return this.props.multi?e.map(function(e,t){return l["default"].createElement(o,{id:u._instancePrefix+"-value-"+t,instancePrefix:u._instancePrefix,disabled:u.props.disabled||e.clearableValue===!1,key:"value-"+t+"-"+e[u.props.valueKey],onClick:n,onRemove:u.removeValue,value:e},s(e),l["default"].createElement("span",{className:"Select-aria-only"}," "))}):this.state.inputValue?void 0:(t&&(n=null),l["default"].createElement(o,{id:this._instancePrefix+"-value-item",disabled:this.props.disabled,instancePrefix:this._instancePrefix,onClick:n,value:e[0]},s(e[0])))},renderInput:function(e,t){if(this.props.inputRenderer)return this.props.inputRenderer();var u,s=(0,E["default"])("Select-input",this.props.inputProps.className),o=!!this.state.isOpen,i=(0,E["default"])((u={},n(u,this._instancePrefix+"-list",o),n(u,this._instancePrefix+"-backspace-remove-message",this.props.multi&&!this.props.disabled&&this.state.isFocused&&!this.state.inputValue),u)),r=a({},this.props.inputProps,{role:"combobox","aria-expanded":""+o,"aria-owns":i,"aria-haspopup":""+o,"aria-activedescendant":o?this._instancePrefix+"-option-"+t:this._instancePrefix+"-value","aria-labelledby":this.props["aria-labelledby"],"aria-label":this.props["aria-label"],className:s,tabIndex:this.props.tabIndex,onBlur:this.handleInputBlur,onChange:this.handleInputChange,onFocus:this.handleInputFocus,ref:"input",required:this.state.required,value:this.state.inputValue});if(this.props.disabled||!this.props.searchable){var p=(0,b["default"])(this.props.inputProps,"inputClassName");return l["default"].createElement("div",a({},p,{role:"combobox","aria-expanded":o,"aria-owns":o?this._instancePrefix+"-list":this._instancePrefix+"-value","aria-activedescendant":o?this._instancePrefix+"-option-"+t:this._instancePrefix+"-value",className:s,tabIndex:this.props.tabIndex||0,onBlur:this.handleInputBlur,onFocus:this.handleInputFocus,ref:"input","aria-readonly":""+!!this.props.disabled,style:{border:0,width:1,display:"inline-block"}}))}return this.props.autosize?l["default"].createElement(f["default"],a({},r,{minWidth:"5px"})):l["default"].createElement("div",{className:s},l["default"].createElement("input",r))},renderClear:function(){if(this.props.clearable&&this.props.value&&(!this.props.multi||this.props.value.length)&&!this.props.disabled&&!this.props.isLoading)return l["default"].createElement("span",{className:"Select-clear-zone",title:this.props.multi?this.props.clearAllText:this.props.clearValueText,"aria-label":this.props.multi?this.props.clearAllText:this.props.clearValueText,onMouseDown:this.clearValue,onTouchStart:this.handleTouchStart,onTouchMove:this.handleTouchMove,onTouchEnd:this.handleTouchEndClearValue},l["default"].createElement("span",{className:"Select-clear",dangerouslySetInnerHTML:{__html:"×"}}))},renderArrow:function(){return l["default"].createElement("span",{className:"Select-arrow-zone",onMouseDown:this.handleMouseDownOnArrow},l["default"].createElement("span",{className:"Select-arrow",onMouseDown:this.handleMouseDownOnArrow}))},filterOptions:function(e){var t=this,u=this.state.inputValue,s=this.props.options||[];return"function"==typeof this.props.filterOptions?this.props.filterOptions.call(this,s,u,e):this.props.filterOptions?(this.props.ignoreAccents&&(u=(0,m["default"])(u)),this.props.ignoreCase&&(u=u.toLowerCase()),e&&(e=e.map(function(e){return e[t.props.valueKey]})),s.filter(function(s){if(e&&e.indexOf(s[t.props.valueKey])>-1)return!1;if(t.props.filterOption)return t.props.filterOption.call(t,s,u);if(!u)return!0;var o=String(s[t.props.valueKey]),n=String(s[t.props.labelKey]);return t.props.ignoreAccents&&("label"!==t.props.matchProp&&(o=(0,m["default"])(o)),"value"!==t.props.matchProp&&(n=(0,m["default"])(n))),t.props.ignoreCase&&("label"!==t.props.matchProp&&(o=o.toLowerCase()),"value"!==t.props.matchProp&&(n=n.toLowerCase())),"start"===t.props.matchPos?"label"!==t.props.matchProp&&o.substr(0,u.length)===u||"value"!==t.props.matchProp&&n.substr(0,u.length)===u:"label"!==t.props.matchProp&&o.indexOf(u)>=0||"value"!==t.props.matchProp&&n.indexOf(u)>=0})):s},renderMenu:function(e,t,u){var s=this;if(!e||!e.length)return this.props.noResultsText?l["default"].createElement("div",{className:"Select-noresults"},this.props.noResultsText):null;if(this.props.menuRenderer)return this.props.menuRenderer({focusedOption:u,focusOption:this.focusOption,labelKey:this.props.labelKey,options:e,selectValue:this.selectValue,valueArray:t});var o=function(){var o=s.props.optionComponent,n=s.props.optionRenderer||s.getOptionLabel;return{v:e.map(function(e,i){var a=t&&t.indexOf(e)>-1,r=e===u,p=r?"focused":null,d=(0,E["default"])(s.props.optionClassName,{"Select-option":!0,"is-selected":a,"is-focused":r,"is-disabled":e.disabled});return l["default"].createElement(o,{instancePrefix:s._instancePrefix,optionIndex:i,className:d,isDisabled:e.disabled,isFocused:r,key:"option-"+i+"-"+e[s.props.valueKey],onSelect:s.selectValue,onFocus:s.focusOption,option:e,isSelected:a,ref:p},n(e))})}}();return"object"==typeof o?o.v:void 0},renderHiddenField:function(e){var t=this;if(this.props.name){if(this.props.joinValues){var u=e.map(function(e){return i(e[t.props.valueKey])}).join(this.props.delimiter);return l["default"].createElement("input",{type:"hidden",ref:"value",name:this.props.name,value:u,disabled:this.props.disabled})}return e.map(function(e,u){return l["default"].createElement("input",{key:"hidden."+u,type:"hidden",ref:"value"+u,name:t.props.name,value:i(e[t.props.valueKey]),disabled:t.props.disabled})})}},getFocusableOptionIndex:function(e){var t=this._visibleOptions;if(!t.length)return null;var u=this.state.focusedOption||e;if(u&&!u.disabled){var s=t.indexOf(u);if(s!==-1)return s}for(var o=0;o=0;--u){var s=t.slice(0,u);if(e[s]&&(t===s||e[s].complete))return e[s]}}function a(e,t){if(e&&"function"==typeof e.then)return e.then(function(e){t(null,e)},function(e){t(e)})}var r=Object.assign||function(e){for(var t=1;ta.bottom||i.topt.offsetHeight&&!(t.scrollHeight-t.offsetHeight-t.scrollTop)&&this.props.onMenuScrollToBottom()}},handleRequired:function(e,t){return!e||(t?0===e.length:0===Object.keys(e).length)},getOptionLabel:function(e){return e[this.props.labelKey]},getValueArray:function(e,t){var u=this,s="object"==typeof t?t:this.props;if(s.multi){if("string"==typeof e&&(e=e.split(s.delimiter)),!Array.isArray(e)){if(null===e||void 0===e)return[];e=[e]}return e.map(function(e){return u.expandValue(e,s)}).filter(function(e){return e})}var o=this.expandValue(e,s);return o?[o]:[]},expandValue:function(e,t){if("string"!=typeof e&&"number"!=typeof e)return e;var u=t.options,s=t.valueKey;if(u)for(var o=0;o0?u-=1:u=t.length-1;else if("start"===e)u=0;else if("end"===e)u=t.length-1;else if("page_up"===e){var o=u-this.props.pageSize;u=o<0?0:o}else if("page_down"===e){var o=u+this.props.pageSize;u=o>t.length-1?t.length-1:o}u===-1&&(u=0),this.setState({focusedIndex:t[u].index,focusedOption:t[u].option})}},selectFocusedOption:function(){if(this._focusedOption)return this.selectValue(this._focusedOption)},renderLoading:function(){if(this.props.isLoading)return l["default"].createElement("span",{className:"Select-loading-zone","aria-hidden":"true"},l["default"].createElement("span",{className:"Select-loading"}))},renderValue:function(e,t){var u=this,s=this.props.valueRenderer||this.getOptionLabel,o=this.props.valueComponent;if(!e.length)return this.state.inputValue?null:l["default"].createElement("div",{className:"Select-placeholder"},this.props.placeholder);var n=this.props.onValueClick?this.handleValueClick:null;return this.props.multi?e.map(function(e,t){return l["default"].createElement(o,{id:u._instancePrefix+"-value-"+t,instancePrefix:u._instancePrefix,disabled:u.props.disabled||e.clearableValue===!1,key:"value-"+t+"-"+e[u.props.valueKey],onClick:n,onRemove:u.removeValue,value:e},s(e),l["default"].createElement("span",{className:"Select-aria-only"}," "))}):this.state.inputValue?void 0:(t&&(n=null),l["default"].createElement(o,{id:this._instancePrefix+"-value-item",disabled:this.props.disabled,instancePrefix:this._instancePrefix,onClick:n,value:e[0]},s(e[0])))},renderInput:function(e,t){if(this.props.inputRenderer)return this.props.inputRenderer();var u,s=(0,E["default"])("Select-input",this.props.inputProps.className),o=!!this.state.isOpen,i=(0,E["default"])((u={},n(u,this._instancePrefix+"-list",o),n(u,this._instancePrefix+"-backspace-remove-message",this.props.multi&&!this.props.disabled&&this.state.isFocused&&!this.state.inputValue),u)),r=a({},this.props.inputProps,{role:"combobox","aria-expanded":""+o,"aria-owns":i,"aria-haspopup":""+o,"aria-activedescendant":o?this._instancePrefix+"-option-"+t:this._instancePrefix+"-value","aria-labelledby":this.props["aria-labelledby"],"aria-label":this.props["aria-label"],className:s,tabIndex:this.props.tabIndex,onBlur:this.handleInputBlur,onChange:this.handleInputChange,onFocus:this.handleInputFocus,ref:"input",required:this.state.required,value:this.state.inputValue});if(this.props.disabled||!this.props.searchable){var p=(0,b["default"])(this.props.inputProps,"inputClassName");return l["default"].createElement("div",a({},p,{role:"combobox","aria-expanded":o,"aria-owns":o?this._instancePrefix+"-list":this._instancePrefix+"-value","aria-activedescendant":o?this._instancePrefix+"-option-"+t:this._instancePrefix+"-value",className:s,tabIndex:this.props.tabIndex||0,onBlur:this.handleInputBlur,onFocus:this.handleInputFocus,ref:"input","aria-readonly":""+!!this.props.disabled,style:{border:0,width:1,display:"inline-block"}}))}return this.props.autosize?l["default"].createElement(f["default"],a({},r,{minWidth:"5px"})):l["default"].createElement("div",{className:s},l["default"].createElement("input",r))},renderClear:function(){if(this.props.clearable&&this.props.value&&(!this.props.multi||this.props.value.length)&&!this.props.disabled&&!this.props.isLoading)return l["default"].createElement("span",{className:"Select-clear-zone",title:this.props.multi?this.props.clearAllText:this.props.clearValueText,"aria-label":this.props.multi?this.props.clearAllText:this.props.clearValueText,onMouseDown:this.clearValue,onTouchStart:this.handleTouchStart,onTouchMove:this.handleTouchMove,onTouchEnd:this.handleTouchEndClearValue},l["default"].createElement("span",{className:"Select-clear",dangerouslySetInnerHTML:{__html:"×"}}))},renderArrow:function(){return l["default"].createElement("span",{className:"Select-arrow-zone",onMouseDown:this.handleMouseDownOnArrow},l["default"].createElement("span",{className:"Select-arrow",onMouseDown:this.handleMouseDownOnArrow}))},filterOptions:function(e){var t=this,u=this.state.inputValue,s=this.props.options||[];return"function"==typeof this.props.filterOptions?this.props.filterOptions.call(this,s,u,e):this.props.filterOptions?(this.props.ignoreAccents&&(u=(0,m["default"])(u)),this.props.ignoreCase&&(u=u.toLowerCase()),e&&(e=e.map(function(e){return e[t.props.valueKey]})),s.filter(function(s){if(e&&e.indexOf(s[t.props.valueKey])>-1)return!1;if(t.props.filterOption)return t.props.filterOption.call(t,s,u);if(!u)return!0;var o=String(s[t.props.valueKey]),n=String(s[t.props.labelKey]);return t.props.ignoreAccents&&("label"!==t.props.matchProp&&(o=(0,m["default"])(o)),"value"!==t.props.matchProp&&(n=(0,m["default"])(n))),t.props.ignoreCase&&("label"!==t.props.matchProp&&(o=o.toLowerCase()),"value"!==t.props.matchProp&&(n=n.toLowerCase())),"start"===t.props.matchPos?"label"!==t.props.matchProp&&o.substr(0,u.length)===u||"value"!==t.props.matchProp&&n.substr(0,u.length)===u:"label"!==t.props.matchProp&&o.indexOf(u)>=0||"value"!==t.props.matchProp&&n.indexOf(u)>=0})):s},renderMenu:function(e,t,u){var s=this;if(!e||!e.length)return this.props.noResultsText?l["default"].createElement("div",{className:"Select-noresults"},this.props.noResultsText):null;if(this.props.menuRenderer)return this.props.menuRenderer({focusedOption:u,focusOption:this.focusOption,labelKey:this.props.labelKey,options:e,selectValue:this.selectValue,valueArray:t});var o=function(){var o=s.props.optionComponent,n=s.props.optionRenderer||s.getOptionLabel;return{v:e.map(function(e,i){var a=t&&t.indexOf(e)>-1,r=e===u,p=r?"focused":null,d=(0,E["default"])(s.props.optionClassName,{"Select-option":!0,"is-selected":a,"is-focused":r,"is-disabled":e.disabled});return l["default"].createElement(o,{instancePrefix:s._instancePrefix,optionIndex:i,className:d,isDisabled:e.disabled,isFocused:r,key:"option-"+i+"-"+e[s.props.valueKey],onSelect:s.selectValue,onFocus:s.focusOption,option:e,isSelected:a,ref:p},n(e))})}}();return"object"==typeof o?o.v:void 0},renderHiddenField:function(e){var t=this;if(this.props.name){if(this.props.joinValues){var u=e.map(function(e){return i(e[t.props.valueKey])}).join(this.props.delimiter);return l["default"].createElement("input",{type:"hidden",ref:"value",name:this.props.name,value:u,disabled:this.props.disabled})}return e.map(function(e,u){return l["default"].createElement("input",{key:"hidden."+u,type:"hidden",ref:"value"+u,name:t.props.name,value:i(e[t.props.valueKey]),disabled:t.props.disabled})})}},getFocusableOptionIndex:function(e){var t=this._visibleOptions;if(!t.length)return null;var u=this.state.focusedOption||e;if(u&&!u.disabled){var s=t.indexOf(u);if(s!==-1)return s}for(var o=0;o Date: Tue, 19 Jul 2016 09:47:41 -0700 Subject: [PATCH 05/41] Added an optional instance id property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will allow synchronization of component id’s on both the server and the client. --- src/Select.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Select.js b/src/Select.js index 21748bb9..19400426 100644 --- a/src/Select.js +++ b/src/Select.js @@ -53,6 +53,7 @@ const Select = React.createClass({ ignoreCase: React.PropTypes.bool, // whether to perform case-insensitive filtering inputProps: React.PropTypes.object, // custom attributes for the Input inputRenderer: React.PropTypes.func, // returns a custom input component + instanceId: React.PropTypes.string, // set the components instanceId isLoading: React.PropTypes.bool, // whether the Select is loading externally or not (such as options being loaded) joinValues: React.PropTypes.bool, // joins multiple values into a single form field with the delimiter (legacy mode) labelKey: React.PropTypes.string, // path of the label value in option objects @@ -143,6 +144,7 @@ const Select = React.createClass({ getInitialState () { return { + instanceId: this.props.instanceId || ++instanceId, inputValue: '', isFocused: false, isLoading: false, @@ -152,8 +154,9 @@ const Select = React.createClass({ }; }, - componentWillMount () { - this._instancePrefix = 'react-select-' + (++instanceId) + '-'; + componentWillMount() { + const { instanceId } = this.state; + this._instancePrefix = 'react-select-' + (instanceId) + '-'; const valueArray = this.getValueArray(this.props.value); if (this.props.required) { From f9d1c351e4964c8d43643f573cd9bf65777cb3e4 Mon Sep 17 00:00:00 2001 From: nhducit Date: Wed, 20 Jul 2016 17:31:14 +0700 Subject: [PATCH 06/41] Update Select.js --- src/Select.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Select.js b/src/Select.js index 21748bb9..ce4e5e45 100644 --- a/src/Select.js +++ b/src/Select.js @@ -714,7 +714,7 @@ const Select = React.createClass({ onRemove={this.removeValue} value={value} > - {renderLabel(value)} + {renderLabel(value, 1)}   ); @@ -729,7 +729,7 @@ const Select = React.createClass({ onClick={onClick} value={valueArray[0]} > - {renderLabel(valueArray[0])} + {renderLabel(valueArray[0], 1)} ); } @@ -904,7 +904,7 @@ const Select = React.createClass({ isSelected={isSelected} ref={optionRef} > - {renderLabel(option)} + {renderLabel(option, 1)} ); }); From 17431188606fc8a9dd757dd95b7508624bdc0d6e Mon Sep 17 00:00:00 2001 From: Peter Brant Date: Thu, 21 Jul 2016 20:36:05 +0200 Subject: [PATCH 07/41] Apply less changes to scss versions --- scss/control.scss | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scss/control.scss b/scss/control.scss index e7b41ff1..88ee6fc5 100644 --- a/scss/control.scss +++ b/scss/control.scss @@ -105,8 +105,8 @@ white-space: nowrap; } -.has-value.Select--single:not(.is-focused) > .Select-control > .Select-value, -.has-value.is-pseudo-focused.Select--single > .Select-control > .Select-value { +.has-value.Select--single > .Select-control .Select-value, +.has-value.is-pseudo-focused.Select--single > .Select-control .Select-value { .Select-value-label { color: $select-text-color; } @@ -114,8 +114,10 @@ cursor: pointer; text-decoration: none; - &:hover { + &:hover, + &:focus { color: $select-link-hover-color; + outline: none; text-decoration: underline; } } @@ -207,6 +209,14 @@ .Select--multi .Select-multi-value-wrapper { display: inline-block; } +.Select .Select-aria-only { + display: inline-block; + height: 1px; + width: 1px; + margin: -1px; + clip: rect(0,0,0,0); + overflow: hidden; +} // arrow indicator From be6a2b4888b9fbb02b38500d1176ce9cde06535f Mon Sep 17 00:00:00 2001 From: Jochen Berger Date: Fri, 22 Jul 2016 08:57:40 +0200 Subject: [PATCH 08/41] replace blacklist dependency by using the spread operator --- package.json | 1 - src/Select.js | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/package.json b/package.json index c5d9f049..b8ccaac0 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "url": "https://github.com/JedWatson/react-select.git" }, "dependencies": { - "blacklist": "^1.1.2", "classnames": "^2.2.4", "react-input-autosize": "^1.1.0" }, diff --git a/src/Select.js b/src/Select.js index 21748bb9..5031419c 100644 --- a/src/Select.js +++ b/src/Select.js @@ -2,7 +2,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import Input from 'react-input-autosize'; import classNames from 'classnames'; -import blacklist from 'blacklist'; import stripDiacritics from './utils/stripDiacritics'; @@ -770,7 +769,7 @@ const Select = React.createClass({ }); if (this.props.disabled || !this.props.searchable) { - const divProps = blacklist(this.props.inputProps, 'inputClassName'); + const { inputClassName, ...divProps } = this.props.inputProps; return (
Date: Mon, 25 Jul 2016 14:09:26 -0600 Subject: [PATCH 09/41] update npm badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e50a42c6..d5c08cdb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![NPM](https://badge.fury.io/js/react-select.png)](https://www.npmjs.com/package/react-select) +[![NPM](https://img.shields.io/npm/v/react-select.svg)](https://www.npmjs.com/package/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) From 107ce1af73ecdc53574c8870096fad4a5db0fe0c Mon Sep 17 00:00:00 2001 From: Jevin Anderson Date: Wed, 27 Jul 2016 15:37:50 -0700 Subject: [PATCH 10/41] Updated solution to incorporate @JedWatson's suggestion --- src/Select.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Select.js b/src/Select.js index 19400426..c4c3f17e 100644 --- a/src/Select.js +++ b/src/Select.js @@ -144,7 +144,6 @@ const Select = React.createClass({ getInitialState () { return { - instanceId: this.props.instanceId || ++instanceId, inputValue: '', isFocused: false, isLoading: false, @@ -155,8 +154,7 @@ const Select = React.createClass({ }, componentWillMount() { - const { instanceId } = this.state; - this._instancePrefix = 'react-select-' + (instanceId) + '-'; + this._instancePrefix = 'react-select-' + (this.props.instanceId || ++instanceId) + '-'; const valueArray = this.getValueArray(this.props.value); if (this.props.required) { From e8bcab847c31a59a1afd5bc7723452307adf8497 Mon Sep 17 00:00:00 2001 From: Johnny Nguyen Date: Wed, 27 Jul 2016 19:23:46 -0700 Subject: [PATCH 11/41] Use preferred callback refs --- src/Async.js | 4 ++-- src/Select.js | 42 +++++++++++++++++++++--------------------- test/Select-test.js | 20 ++++++++++---------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/Async.js b/src/Async.js index e636b82b..5de2bcef 100644 --- a/src/Async.js +++ b/src/Async.js @@ -88,7 +88,7 @@ const Async = React.createClass({ } }, focus () { - this.refs.select.focus(); + this.select.focus(); }, resetState () { this._currentRequestId = -1; @@ -153,7 +153,7 @@ const Async = React.createClass({ return ( component input = input.getInput(); @@ -365,7 +365,7 @@ const Select = React.createClass({ handleInputBlur (event) { // The check for menu.contains(activeElement) is necessary to prevent IE11's scrollbar from closing the menu in certain contexts. - if (this.refs.menu && (this.refs.menu === document.activeElement || this.refs.menu.contains(document.activeElement))) { + if (this.menu && (this.menu === document.activeElement || this.menu.contains(document.activeElement))) { this.focus(); return; } @@ -763,7 +763,7 @@ const Select = React.createClass({ onBlur: this.handleInputBlur, onChange: this.handleInputChange, onFocus: this.handleInputFocus, - ref: 'input', + ref: ref => this.input = ref, required: this.state.required, value: this.state.inputValue }); @@ -781,7 +781,7 @@ const Select = React.createClass({ tabIndex={this.props.tabIndex || 0} onBlur={this.handleInputBlur} onFocus={this.handleInputFocus} - ref="input" + ref={ref => this.input = ref} aria-readonly={'' + !!this.props.disabled} style={{ border: 0, width: 1, display:'inline-block' }}/> ); @@ -926,7 +926,7 @@ const Select = React.createClass({ return ( this.value = ref} name={this.props.name} value={value} disabled={this.props.disabled} /> @@ -967,8 +967,8 @@ const Select = React.createClass({ } return ( -
-
this.menuContainer = ref} className="Select-menu-outer" style={this.props.menuContainerStyle}> +
this.menu = ref} role="listbox" className="Select-menu" id={this._instancePrefix + '-list'} style={this.props.menuStyle} onScroll={this.handleMenuScroll} onMouseDown={this.handleMouseDownOnMenu}> @@ -1018,11 +1018,11 @@ const Select = React.createClass({ } return ( -
this.wrapper = ref} className={className} style={this.props.wrapperStyle}> {this.renderHiddenField(valueArray)} -
this.control = ref} className="Select-control" style={this.props.style} onKeyDown={this.handleKeyDown} diff --git a/test/Select-test.js b/test/Select-test.js index 748541e3..bc847ba3 100644 --- a/test/Select-test.js +++ b/test/Select-test.js @@ -46,12 +46,12 @@ class PropsWrapper extends React.Component { } getChild() { - return this.refs.child; + return this.child; } render() { var Component = this.props.childComponent; // eslint-disable-line react/prop-types - return ; + return this.child = ref} />; } } @@ -119,7 +119,7 @@ describe('Select', () => { var findAndFocusInputControl = () => { // Focus on the input, such that mouse events are accepted - var searchInstance = ReactDOM.findDOMNode(instance.refs.input); + var searchInstance = ReactDOM.findDOMNode(instance.input); searchInputNode = null; if (searchInstance) { searchInputNode = searchInstance.querySelector('input'); @@ -2233,7 +2233,7 @@ describe('Select', () => { it('adds the className on to the auto-size input', () => { - expect(ReactDOM.findDOMNode(instance.refs.input), + expect(ReactDOM.findDOMNode(instance.input), 'to have attributes', { class: ['extra-class-name', 'Select-input'] }); @@ -2487,12 +2487,12 @@ describe('Select', () => { }); clickArrowToOpen(); - instance.refs.menu.focus(); + instance.menu.focus(); - var inputFocus = sinon.spy( instance.refs.input, 'focus' ); + var inputFocus = sinon.spy( instance.input, 'focus' ); instance.handleInputBlur(); - expect( instance.refs.input.focus, 'was called once' ); + expect( instance.input.focus, 'was called once' ); } ); it( 'should not focus the input when menu is not active', () => { @@ -2500,10 +2500,10 @@ describe('Select', () => { options: defaultOptions }); - var inputFocus = sinon.spy( instance.refs.input, 'focus' ); + var inputFocus = sinon.spy( instance.input, 'focus' ); instance.handleInputBlur(); - expect( instance.refs.input.focus, 'was not called' ); + expect( instance.input.focus, 'was not called' ); } ); }); @@ -3236,7 +3236,7 @@ describe('Select', () => { }); it('creates a plain input instead of an autosizable input', () => { - const inputNode = ReactDOM.findDOMNode(instance.refs.input); + const inputNode = ReactDOM.findDOMNode(instance.input); expect(inputNode.tagName, 'to equal', 'INPUT'); }); }); From 38ca948ef602822045dec32754b24ca9eda4049d Mon Sep 17 00:00:00 2001 From: Johnny Nguyen Date: Wed, 27 Jul 2016 20:25:50 -0700 Subject: [PATCH 12/41] Additional test coverage for onBlur --- test/Select-test.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/Select-test.js b/test/Select-test.js index bc847ba3..131b7a14 100644 --- a/test/Select-test.js +++ b/test/Select-test.js @@ -2505,6 +2505,20 @@ describe('Select', () => { expect( instance.input.focus, 'was not called' ); } ); + + it( 'should set onBlurredState', () => { + instance = createControl({ + options: defaultOptions + }); + + var inputFocus = sinon.spy( instance.input, 'focus' ); + instance.handleInputBlur(); + + expect( instance.state.isFocused, 'to be false'); + expect( instance.state.isOpen, 'to be false'); + expect( instance.state.isPseudoFocused, 'to be false'); + + } ); }); describe('with onBlurResetsInput=true', () => { From 15ba7d26b3c3236b8c2582e31550b88d6ef4ac51 Mon Sep 17 00:00:00 2001 From: Johnny Nguyen Date: Thu, 28 Jul 2016 20:20:39 -0700 Subject: [PATCH 13/41] Add ref tests --- test/Select-test.js | 46 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/test/Select-test.js b/test/Select-test.js index 131b7a14..09485ac4 100644 --- a/test/Select-test.js +++ b/test/Select-test.js @@ -202,7 +202,7 @@ describe('Select', () => { { value: 'ten', label: 'ten' } ]; - describe('with simple options', () => { + describe('has refs', () => { beforeEach(() => { options = [ { value: 'one', label: 'One' }, @@ -215,9 +215,53 @@ describe('Select', () => { value: 'one', options: options, simpleValue: true, + joinValues: true, }); }); + it('input', () => { + expect(instance.input, 'not to equal', undefined); + }); + + it('value', () => { + typeSearchText('o'); + expect(instance.value, 'not to equal', undefined); + }); + + it('menuContainer', () => { + clickArrowToOpen(); + expect(instance.menuContainer, 'not to equal', undefined); + }); + + it('menu', () => { + clickArrowToOpen(); + expect(instance.menu, 'not to equal', undefined); + }); + + it('wrapper', () => { + expect(instance.wrapper, 'not to equal', undefined); + }); + + it('control', () => { + expect(instance.control, 'not to equal', undefined); + }); + }); + + describe('with simple options', () => { + beforeEach(() => { + options = [ + { value: 'one', label: 'One' }, + { value: 'two', label: 'Two' }, + { value: 'three', label: 'Three' } + ]; + + instance = createControl({ + name: 'form-field-name', + value: 'one', + options: options, + simpleValue: true, + }); + }); it('should assign the given name', () => { var selectInputElement = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'input')[0]; From adc82bd495a493b5f99968953fe20dcbf819f713 Mon Sep 17 00:00:00 2001 From: Hanwen Cheng Date: Fri, 5 Aug 2016 17:21:40 +0200 Subject: [PATCH 14/41] fix value check in renderClear --- lib/Select.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Select.js b/lib/Select.js index 1101da81..04a25157 100644 --- a/lib/Select.js +++ b/lib/Select.js @@ -866,7 +866,7 @@ var Select = _react2['default'].createClass({ }, renderClear: function renderClear() { - if (!this.props.clearable || !this.props.value || this.props.multi && !this.props.value.length || this.props.disabled || this.props.isLoading) return; + if (!this.props.clearable || !this.props.value && this.props.value !== 0 || this.props.multi && !this.props.value.length || this.props.disabled || this.props.isLoading) return; return _react2['default'].createElement( 'span', { className: 'Select-clear-zone', title: this.props.multi ? this.props.clearAllText : this.props.clearValueText, From ee69b9855af2d0f14a847307a331e16b7d5ee485 Mon Sep 17 00:00:00 2001 From: Forbes Lindesay Date: Sun, 21 Aug 2016 00:59:47 +0100 Subject: [PATCH 15/41] Remove unused `isLoading` entry in getInitialState --- src/Select.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Select.js b/src/Select.js index 5031419c..24988760 100644 --- a/src/Select.js +++ b/src/Select.js @@ -144,7 +144,6 @@ const Select = React.createClass({ return { inputValue: '', isFocused: false, - isLoading: false, isOpen: false, isPseudoFocused: false, required: false, From 189c0e28b47b89f9ec0a598cf73f7604e0d1ac26 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 21 Aug 2016 17:37:55 +1000 Subject: [PATCH 16/41] Adding Supported by Thinkmill badge Giving Thinkmill credit for being able to commit time to this at work :) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d5c08cdb..e78c62d4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![NPM](https://img.shields.io/npm/v/react-select.svg)](https://www.npmjs.com/package/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) React-Select ============ From c76f0011ba94441ce44a354093a9a2f23592e44e Mon Sep 17 00:00:00 2001 From: Max Stoiber Date: Sun, 21 Aug 2016 18:04:18 +1000 Subject: [PATCH 17/41] Fix link to Thinkmill --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e78c62d4..ca507470 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![NPM](https://img.shields.io/npm/v/react-select.svg)](https://www.npmjs.com/package/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) +[![Supported by Thinkmill](https://thinkmill.github.io/badge/heart.svg)](http://thinkmill.com.au/?utm_source=github&utm_medium=badge&utm_campaign=react-select) React-Select ============ From d5af3aa18eb311cf00c8fc5e664b3a232d4ea10b Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 28 Aug 2016 13:10:32 +0100 Subject: [PATCH 18/41] Fix tests that click `clear` --- test/Select-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Select-test.js b/test/Select-test.js index 748541e3..cf354c40 100644 --- a/test/Select-test.js +++ b/test/Select-test.js @@ -1720,7 +1720,7 @@ describe('Select', () => { describe('on clicking `clear`', () => { beforeEach(() => { - TestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(instance).querySelector('.Select-clear')); + TestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(instance).querySelector('.Select-clear'), { button: 0 }); }); it('calls onChange with empty', () => { @@ -1771,7 +1771,7 @@ describe('Select', () => { }); it('calls onChange with a custom resetValue', () => { - TestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(instance).querySelector('.Select-clear')); + TestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(instance).querySelector('.Select-clear'), { button: 0 }); expect(onChange, 'was called with', 'reset'); }); }); From 27938a0588eeceec4c74f62b2338d77593753124 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 28 Aug 2016 13:23:18 +0100 Subject: [PATCH 19/41] Default reset value to [] when multi=true --- src/Select.js | 13 +++++++++++-- test/Select-test.js | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Select.js b/src/Select.js index 5031419c..064b1148 100644 --- a/src/Select.js +++ b/src/Select.js @@ -130,7 +130,6 @@ const Select = React.createClass({ pageSize: 5, placeholder: 'Select...', required: false, - resetValue: null, scrollMenuIntoView: true, searchable: true, simpleValue: false, @@ -580,13 +579,23 @@ const Select = React.createClass({ } event.stopPropagation(); event.preventDefault(); - this.setValue(this.props.resetValue); + this.setValue(this.getResetValue()); this.setState({ isOpen: false, inputValue: '', }, this.focus); }, + getResetValue() { + if (this.props.resetValue !== undefined) { + return this.props.resetValue; + } else if (this.props.multi) { + return []; + } else { + return null; + } + }, + focusOption (option) { this.setState({ focusedOption: option diff --git a/test/Select-test.js b/test/Select-test.js index cf354c40..29142ac2 100644 --- a/test/Select-test.js +++ b/test/Select-test.js @@ -1565,6 +1565,30 @@ describe('Select', () => { }); + describe('with multi=true and clearable=true', () => { + beforeEach(() => { + + options = [ + { value: 0, label: 'Zero' }, + { value: 1, label: 'One' } + ]; + + wrapper = createControlWithWrapper({ + value: [0], + options: options, + multi: true, + clearable: true + }); + + }); + + it('calls onChange with an empty list when cleared', () => { + + TestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(instance).querySelector('.Select-clear'), { button: 0 }); + expect(onChange, 'was called with', []); + }); + }); + describe('with multi=true and searchable=false', () => { beforeEach(() => { From a069b0c4525aacd2a021af6fb8e60dbf5c639a6f Mon Sep 17 00:00:00 2001 From: nhducit Date: Mon, 29 Aug 2016 14:35:03 +0700 Subject: [PATCH 20/41] Fix typo, change "1" -> "i" --- src/Select.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Select.js b/src/Select.js index ce4e5e45..53ead0f7 100644 --- a/src/Select.js +++ b/src/Select.js @@ -714,7 +714,7 @@ const Select = React.createClass({ onRemove={this.removeValue} value={value} > - {renderLabel(value, 1)} + {renderLabel(value, i)}   ); @@ -729,7 +729,7 @@ const Select = React.createClass({ onClick={onClick} value={valueArray[0]} > - {renderLabel(valueArray[0], 1)} + {renderLabel(valueArray[0], i)} ); } @@ -904,7 +904,7 @@ const Select = React.createClass({ isSelected={isSelected} ref={optionRef} > - {renderLabel(option, 1)} + {renderLabel(option, i)} ); }); From a21714c3d950f914ac0d9000ab4ed569b02996b1 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 30 Aug 2016 22:27:21 +1000 Subject: [PATCH 21/41] Updating bower dependency react-select-autosize to ^1.1.0, fixes #1167 --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 383552e0..19cc3692 100644 --- a/bower.json +++ b/bower.json @@ -17,7 +17,7 @@ ], "dependencies": { "classnames": "^2.2.0", - "react-input-autosize": "^0.6.5" + "react-input-autosize": "^1.1.0" }, "keywords": [ "react", From b6f1d881718ffbebd2134aaf219167c4fe510c8e Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 30 Aug 2016 22:35:04 +1000 Subject: [PATCH 22/41] Ensuring stringifyValue returns a string, closes #1155 --- src/Select.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Select.js b/src/Select.js index d0ef85af..7969171e 100644 --- a/src/Select.js +++ b/src/Select.js @@ -10,10 +10,14 @@ import Option from './Option'; import Value from './Value'; function stringifyValue (value) { - if (typeof value === 'object') { + if (typeof value === 'string') { + return value; + } else if (typeof value === 'object') { return JSON.stringify(value); + } else if (value || value === 0) { + return String(value); } else { - return value; + return ''; } } From 36869b271d7bce94870c3249e7d57072df44bbc5 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 30 Aug 2016 22:44:11 +1000 Subject: [PATCH 23/41] Updating dependencies --- package.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index b8ccaac0..00f053a8 100644 --- a/package.json +++ b/package.json @@ -18,27 +18,27 @@ "babel": "^5.8.23", "babel-eslint": "^4.1.3", "chai": "^3.5.0", - "coveralls": "^2.11.9", + "coveralls": "^2.11.12", "eslint": "^1.10.3", "eslint-plugin-react": "^3.15.0", "gulp": "^3.9.1", "isomorphic-fetch": "^2.2.1", - "istanbul": "^0.4.3", - "jsdom": "^8.4.1", - "mocha": "^2.4.5", + "istanbul": "^0.4.5", + "jsdom": "^9.4.2", + "mocha": "^3.0.2", "react": "^15.0", - "react-addons-shallow-compare": "^15.0.1", + "react-addons-shallow-compare": "^15.0", "react-addons-test-utils": "^15.0", "react-component-gulp-tasks": "^0.7.7", "react-dom": "^15.0", "react-gravatar": "^2.4.5", - "react-virtualized": "^6.3.0", - "react-virtualized-select": "^0.0.4", - "sinon": "^1.17.3", - "unexpected": "^10.13.2", + "react-virtualized": "^7.22.1", + "react-virtualized-select": "^1.3.0", + "sinon": "^1.17.5", + "unexpected": "^10.16.0", "unexpected-dom": "^3.1.0", "unexpected-react": "^3.2.3", - "unexpected-sinon": "^10.2.0" + "unexpected-sinon": "^10.4.0" }, "peerDependencies": { "react": "^0.14 || ^15.0.0-rc || ^15.0", From 7122ec9fcce0d4526a529307cd902dd98ec4a730 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 30 Aug 2016 22:52:29 +1000 Subject: [PATCH 24/41] Patching fix from #1146 to src/Select --- src/Select.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Select.js b/src/Select.js index 3f389821..fdf650f4 100644 --- a/src/Select.js +++ b/src/Select.js @@ -813,7 +813,7 @@ const Select = React.createClass({ }, renderClear () { - if (!this.props.clearable || !this.props.value || (this.props.multi && !this.props.value.length) || this.props.disabled || this.props.isLoading) return; + if (!this.props.clearable || (!this.props.value || this.props.value === 0) || (this.props.multi && !this.props.value.length) || this.props.disabled || this.props.isLoading) return; return ( Date: Tue, 30 Aug 2016 23:08:18 +1000 Subject: [PATCH 25/41] Fixing breaking issue rendering a single label Index should not be added unless the component is in `multi` mode --- src/Select.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Select.js b/src/Select.js index 70673b79..19717a1a 100644 --- a/src/Select.js +++ b/src/Select.js @@ -751,7 +751,7 @@ const Select = React.createClass({ onClick={onClick} value={valueArray[0]} > - {renderLabel(valueArray[0], i)} + {renderLabel(valueArray[0])} ); } From c25d8462c8da6975a8807adb40d753747fb722b0 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 1 Sep 2016 21:05:29 +1000 Subject: [PATCH 26/41] All but one test passing - TODO: Select with props onBlur should focus on the input when the menu is active --- test/Select-test.js | 58 ++++++++++++++++++++++----------------------- test/Value-test.js | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/test/Select-test.js b/test/Select-test.js index 731eddb5..6601b659 100644 --- a/test/Select-test.js +++ b/test/Select-test.js @@ -114,7 +114,7 @@ describe('Select', () => { var clickArrowToOpen = () => { var selectArrow = ReactDOM.findDOMNode(instance).querySelector('.Select-arrow'); - TestUtils.Simulate.mouseDown(selectArrow); + TestUtils.Simulate.mouseDown(selectArrow, { button: 0 }); }; var findAndFocusInputControl = () => { @@ -269,13 +269,13 @@ describe('Select', () => { }); it('should show the options on mouse click', function () { - TestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(instance).querySelector('.Select-control')); + TestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(instance).querySelector('.Select-control'), { button: 0 }); var node = ReactDOM.findDOMNode(instance); expect(node, 'queried for', '.Select-option', 'to have length', 3); }); it('should display the labels on mouse click', () => { - TestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(instance).querySelector('.Select-control')); + TestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(instance).querySelector('.Select-control'), { button: 0 }); var node = ReactDOM.findDOMNode(instance); expect(node, 'queried for', '.Select-option:nth-child(1)', 'to have items satisfying', 'to have text', 'One'); expect(node, 'queried for', '.Select-option:nth-child(2)', 'to have items satisfying', 'to have text', 'Two'); @@ -357,7 +357,7 @@ describe('Select', () => { }); it('should focus the first value on mouse click', () => { - TestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(instance).querySelector('.Select-control')); + TestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(instance).querySelector('.Select-control'), { button: 0 }); expect(ReactDOM.findDOMNode(instance), 'queried for', '.Select-option.is-focused', 'to have items satisfying', 'to have text', 'One'); @@ -365,7 +365,7 @@ describe('Select', () => { it('should move the focused value to the second value when down pressed', () => { var selectControl = getSelectControl(instance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); expect(ReactDOM.findDOMNode(instance), 'queried for', '.Select-option.is-focused', 'to have items satisfying', @@ -374,7 +374,7 @@ describe('Select', () => { it('should move the focused value to the second value when down pressed', () => { var selectControl = getSelectControl(instance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); expect(ReactDOM.findDOMNode(instance), 'queried for', '.Select-option.is-focused', @@ -384,7 +384,7 @@ describe('Select', () => { it('should loop round to top item when down is pressed on the last item', () => { var selectControl = getSelectControl(instance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); @@ -395,7 +395,7 @@ describe('Select', () => { it('should loop round to bottom item when up is pressed on the first item', () => { var selectControl = getSelectControl(instance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 38, key: 'ArrowUp' }); expect(ReactDOM.findDOMNode(instance), 'queried for', '.Select-option.is-focused', 'to have items satisfying', @@ -404,7 +404,7 @@ describe('Select', () => { it('should move the focused value to the second item when up pressed twice', () => { var selectControl = getSelectControl(instance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 38, key: 'ArrowUp' }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 38, key: 'ArrowUp' }); expect(ReactDOM.findDOMNode(instance), 'queried for', '.Select-option.is-focused', @@ -414,7 +414,7 @@ describe('Select', () => { it('should move the focused value to the end when pressing end', () => { var selectControl = getSelectControl(instance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 35, key: 'End' }); expect(ReactDOM.findDOMNode(instance), 'queried for', '.Select-option.is-focused', 'to have items satisfying', @@ -433,7 +433,7 @@ describe('Select', () => { it('should move the focused value to the end if page down is pressed and number of items is less than page size', () => { var selectControl = getSelectControl(instance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 34, key: 'PageDown' }); expect(ReactDOM.findDOMNode(instance), 'queried for', '.Select-option.is-focused', 'to have items satisfying', @@ -450,7 +450,7 @@ describe('Select', () => { }); var selectControl = getSelectControl(longerListInstance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 34, key: 'PageDown' }); expect(ReactDOM.findDOMNode(longerListInstance), 'queried for', '.Select-option.is-focused', 'to have items satisfying', @@ -468,7 +468,7 @@ describe('Select', () => { }); var selectControl = getSelectControl(longerListInstance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 34, key: 'PageDown' }); expect(ReactDOM.findDOMNode(longerListInstance), 'queried for', '.Select-option.is-focused', 'to have items satisfying', @@ -477,7 +477,7 @@ describe('Select', () => { it('should move the focused value to the start if page up is pressed and number of items is less than page size', () => { var selectControl = getSelectControl(instance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 34, key: 'PageDown' }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 33, key: 'PageUp' }); expect(ReactDOM.findDOMNode(instance), 'queried for', '.Select-option.is-focused', @@ -495,7 +495,7 @@ describe('Select', () => { }); var selectControl = getSelectControl(longerListInstance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 35, key: 'End' }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 33, key: 'PageUp' }); expect(ReactDOM.findDOMNode(longerListInstance), 'queried for', '.Select-option.is-focused', @@ -514,7 +514,7 @@ describe('Select', () => { }); var selectControl = getSelectControl(longerListInstance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 35, key: 'End' }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 33, key: 'PageUp' }); expect(ReactDOM.findDOMNode(longerListInstance), 'queried for', '.Select-option.is-focused', @@ -525,7 +525,7 @@ describe('Select', () => { it('should clear the selection on escape', () => { var selectControl = getSelectControl(instance); - TestUtils.Simulate.mouseDown(selectControl); + TestUtils.Simulate.mouseDown(selectControl, { button: 0 }); TestUtils.Simulate.keyDown(selectControl, { keyCode: 27, key: 'Escape' }); expect(ReactDOM.findDOMNode(instance), 'to contain no elements matching', '.Select-option'); @@ -552,16 +552,16 @@ describe('Select', () => { it('should close the options one the second click on the arrow', () => { var selectArrow = ReactDOM.findDOMNode(instance).querySelector('.Select-arrow'); - TestUtils.Simulate.mouseDown(selectArrow); + TestUtils.Simulate.mouseDown(selectArrow, { button: 0 }); expect(ReactDOM.findDOMNode(instance).querySelectorAll('.Select-option'), 'to have length', 3); - TestUtils.Simulate.mouseDown(selectArrow); + TestUtils.Simulate.mouseDown(selectArrow, { button: 0 }); expect(ReactDOM.findDOMNode(instance), 'to contain no elements matching', '.Select-option'); }); it('should ignore a right mouse click on the arrow', () => { var selectArrow = ReactDOM.findDOMNode(instance).querySelector('.Select-arrow'); - TestUtils.Simulate.mouseDown(selectArrow, { type: 'mousedown', button: 1 }); + TestUtils.Simulate.mouseDown(selectArrow, { button: 1 }); expect(ReactDOM.findDOMNode(instance), 'to contain no elements matching', '.Select-option'); }); @@ -2113,7 +2113,7 @@ describe('Select', () => { it('should close the opened menu if disabled=true', function(){ findAndFocusInputControl(); - TestUtils.Simulate.mouseDown(getSelectControl(instance)); + TestUtils.Simulate.mouseDown(getSelectControl(instance), { button: 0 }); expect(node, 'queried for', '.Select-option', 'to have length', 4); ReactDOM.render(