react-select
Advanced tools
Comparing version 0.5.5 to 0.5.6
@@ -177,4 +177,4 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
} | ||
var menuElem = self.refs.selectMenuContainer.getDOMNode(); | ||
var controlElem = self.refs.control.getDOMNode(); | ||
var menuElem = React.findDOMNode(self.refs.selectMenuContainer); | ||
var controlElem = React.findDOMNode(self.refs.control); | ||
@@ -243,3 +243,2 @@ var eventOccuredOutsideMenu = self.clickedOutsideElement(menuElem, event); | ||
clearTimeout(this._blurTimeout); | ||
this._focusTimeout = setTimeout(function () { | ||
@@ -253,4 +252,4 @@ self.getInputNode().focus(); | ||
if (this.refs.focused && this.refs.menu) { | ||
var focusedDOM = this.refs.focused.getDOMNode(); | ||
var menuDOM = this.refs.menu.getDOMNode(); | ||
var focusedDOM = React.findDOMNode(this.refs.focused); | ||
var menuDOM = React.findDOMNode(this.refs.menu); | ||
var focusedRect = focusedDOM.getBoundingClientRect(); | ||
@@ -263,3 +262,2 @@ var menuRect = menuDOM.getBoundingClientRect(); | ||
} | ||
this._focusedOptionReveal = false; | ||
@@ -378,3 +376,3 @@ } | ||
var input = this.refs.input; | ||
return this.props.searchable ? input : input.getDOMNode(); | ||
return this.props.searchable ? input : React.findDOMNode(input); | ||
}, | ||
@@ -381,0 +379,0 @@ |
@@ -110,4 +110,4 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Select = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
} | ||
var menuElem = self.refs.selectMenuContainer.getDOMNode(); | ||
var controlElem = self.refs.control.getDOMNode(); | ||
var menuElem = React.findDOMNode(self.refs.selectMenuContainer); | ||
var controlElem = React.findDOMNode(self.refs.control); | ||
@@ -176,3 +176,2 @@ var eventOccuredOutsideMenu = self.clickedOutsideElement(menuElem, event); | ||
clearTimeout(this._blurTimeout); | ||
this._focusTimeout = setTimeout(function () { | ||
@@ -186,4 +185,4 @@ self.getInputNode().focus(); | ||
if (this.refs.focused && this.refs.menu) { | ||
var focusedDOM = this.refs.focused.getDOMNode(); | ||
var menuDOM = this.refs.menu.getDOMNode(); | ||
var focusedDOM = React.findDOMNode(this.refs.focused); | ||
var menuDOM = React.findDOMNode(this.refs.menu); | ||
var focusedRect = focusedDOM.getBoundingClientRect(); | ||
@@ -196,3 +195,2 @@ var menuRect = menuDOM.getBoundingClientRect(); | ||
} | ||
this._focusedOptionReveal = false; | ||
@@ -311,3 +309,3 @@ } | ||
var input = this.refs.input; | ||
return this.props.searchable ? input : input.getDOMNode(); | ||
return this.props.searchable ? input : React.findDOMNode(input); | ||
}, | ||
@@ -314,0 +312,0 @@ |
@@ -165,4 +165,4 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Select = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
} | ||
if (newProps.value !== this.state.value) { | ||
this.setState(this.getStateFromValue(newProps.value, newProps.options)); | ||
if (newProps.value !== this.state.value || newProps.placeholder !== this.state.placeholder) { | ||
this.setState(this.getStateFromValue(newProps.value, newProps.options, newProps.placeholder)); | ||
} | ||
@@ -210,6 +210,9 @@ }, | ||
getStateFromValue: function getStateFromValue(value, options) { | ||
getStateFromValue: function getStateFromValue(value, options, placeholder) { | ||
if (!options) { | ||
options = this.state.options; | ||
} | ||
if (!placeholder) { | ||
placeholder = this.props.placeholder; | ||
} | ||
@@ -229,3 +232,3 @@ // reset internal filter string | ||
filteredOptions: filteredOptions, | ||
placeholder: !this.props.multi && values.length ? values[0].label : this.props.placeholder, | ||
placeholder: !this.props.multi && values.length ? values[0].label : placeholder, | ||
focusedOption: !this.props.multi && values.length ? values[0] : filteredOptions[0] | ||
@@ -421,3 +424,3 @@ }; | ||
} else { | ||
this.clearValue(); | ||
this.clearValue(event); | ||
} | ||
@@ -438,3 +441,3 @@ break; | ||
// , | ||
if (this.props.allowCreate) { | ||
if (this.props.allowCreate && this.props.multi) { | ||
event.preventDefault(); | ||
@@ -663,5 +666,7 @@ event.stopPropagation(); | ||
// Add the current value to the filtered options in last resort | ||
var options = this.state.filteredOptions; | ||
if (this.props.allowCreate && this.state.inputValue.trim()) { | ||
var inputValue = this.state.inputValue; | ||
this.state.filteredOptions.unshift({ | ||
options = options.slice(); | ||
options.unshift({ | ||
value: inputValue, | ||
@@ -673,4 +678,4 @@ label: inputValue, | ||
var ops = Object.keys(this.state.filteredOptions).map(function (key) { | ||
var op = this.state.filteredOptions[key]; | ||
var ops = Object.keys(options).map(function (key) { | ||
var op = options[key]; | ||
var isSelected = this.state.value === op.value; | ||
@@ -677,0 +682,0 @@ var isFocused = focusedValue === op.value; |
@@ -1,1 +0,1 @@ | ||
!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,s,i){function o(a,r){if(!s[a]){if(!t[a]){var l="function"==typeof require&&require;if(!r&&l)return l(a,!0);if(n)return n(a,!0);var p=new Error("Cannot find module '"+a+"'");throw p.code="MODULE_NOT_FOUND",p}var u=s[a]={exports:{}};t[a][0].call(u.exports,function(e){var s=t[a][1][e];return o(s?s:e)},u,u.exports,e,t,s,i)}return s[a].exports}for(var n="function"==typeof require&&require,a=0;a<i.length;a++)o(i[a]);return o}({1:[function(e,t,s){(function(s){"use strict";var i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var s=arguments[t];for(var i in s)Object.prototype.hasOwnProperty.call(s,i)&&(e[i]=s[i])}return e},o="undefined"!=typeof window?window.React:"undefined"!=typeof s?s.React:null,n="undefined"!=typeof window?window.AutosizeInput:"undefined"!=typeof s?s.AutosizeInput:null,a="undefined"!=typeof window?window.classNames:"undefined"!=typeof s?s.classNames:null,r=e("./Value"),l=0,p=o.createClass({displayName:"Select",propTypes:{allowCreate:o.PropTypes.bool,asyncOptions:o.PropTypes.func,autoload:o.PropTypes.bool,className:o.PropTypes.string,clearable:o.PropTypes.bool,clearAllText:o.PropTypes.string,clearValueText:o.PropTypes.string,delimiter:o.PropTypes.string,disabled:o.PropTypes.bool,filterOption:o.PropTypes.func,filterOptions:o.PropTypes.func,ignoreCase:o.PropTypes.bool,inputProps:o.PropTypes.object,matchPos:o.PropTypes.string,matchProp:o.PropTypes.string,multi:o.PropTypes.bool,name:o.PropTypes.string,addLabelText:o.PropTypes.string,noResultsText:o.PropTypes.string,onBlur:o.PropTypes.func,onChange:o.PropTypes.func,onFocus:o.PropTypes.func,onOptionLabelClick:o.PropTypes.func,optionRenderer:o.PropTypes.func,options:o.PropTypes.array,placeholder:o.PropTypes.string,searchable:o.PropTypes.bool,searchPromptText:o.PropTypes.string,value:o.PropTypes.any,valueRenderer:o.PropTypes.func},getDefaultProps:function(){return{allowCreate:!1,asyncOptions:void 0,autoload:!0,className:void 0,clearable:!0,clearAllText:"Clear all",clearValueText:"Clear value",delimiter:",",disabled:!1,ignoreCase:!0,inputProps:{},matchPos:"any",matchProp:"any",name:void 0,addLabelText:"Add {label} ?",noResultsText:"No results found",onChange:void 0,onOptionLabelClick:void 0,options:void 0,placeholder:"Select...",searchable:!0,searchPromptText:"Type to search",value:void 0}},getInitialState:function(){return{isFocused:!1,isLoading:!1,isOpen:!1,options:this.props.options}},componentWillMount:function(){this._optionsCache={},this._optionsFilterString="";var e=this;this._closeMenuIfClickedOutside=function(t){if(e.state.isOpen){var s=o.findDOMNode(e.refs.selectMenuContainer),i=o.findDOMNode(e.refs.control),n=e.clickedOutsideElement(s,t),a=e.clickedOutsideElement(i,t);n&&a&&e.setState({isOpen:!1},e._unbindCloseMenuIfClickedOutside)}},this._bindCloseMenuIfClickedOutside=function(){!document.addEventListener&&document.attachEvent?document.attachEvent("onclick",this._closeMenuIfClickedOutside):document.addEventListener("click",this._closeMenuIfClickedOutside)},this._unbindCloseMenuIfClickedOutside=function(){!document.removeEventListener&&document.detachEvent?document.detachEvent("onclick",this._closeMenuIfClickedOutside):document.removeEventListener("click",this._closeMenuIfClickedOutside)},this.setState(this.getStateFromValue(this.props.value))},componentDidMount:function(){this.props.asyncOptions&&this.props.autoload&&this.autoloadAsyncOptions()},componentWillUnmount:function(){clearTimeout(this._blurTimeout),clearTimeout(this._focusTimeout),this.state.isOpen&&this._unbindCloseMenuIfClickedOutside()},componentWillReceiveProps:function(e){JSON.stringify(e.options)!==JSON.stringify(this.props.options)&&this.setState({options:e.options,filteredOptions:this.filterOptions(e.options)}),e.value!==this.state.value&&this.setState(this.getStateFromValue(e.value,e.options))},componentDidUpdate:function(){var e=this;if(!this.props.disabled&&this._focusAfterUpdate&&(clearTimeout(this._blurTimeout),this._focusTimeout=setTimeout(function(){e.getInputNode().focus(),e._focusAfterUpdate=!1},50)),this._focusedOptionReveal){if(this.refs.focused&&this.refs.menu){var t=o.findDOMNode(this.refs.focused),s=o.findDOMNode(this.refs.menu),i=t.getBoundingClientRect(),n=s.getBoundingClientRect();(i.bottom>n.bottom||i.top<n.top)&&(s.scrollTop=t.offsetTop+t.clientHeight-s.offsetHeight)}this._focusedOptionReveal=!1}},focus:function(){this.getInputNode().focus()},clickedOutsideElement:function(e,t){for(var s=t.target?t.target:t.srcElement;null!=s;){if(s===e)return!1;s=s.offsetParent}return!0},getStateFromValue:function(e,t){t||(t=this.state.options),this._optionsFilterString="";var s=this.initValuesArray(e,t),i=this.filterOptions(t,s);return{value:s.map(function(e){return e.value}).join(this.props.delimiter),values:s,inputValue:"",filteredOptions:i,placeholder:!this.props.multi&&s.length?s[0].label:this.props.placeholder,focusedOption:!this.props.multi&&s.length?s[0]:i[0]}},initValuesArray:function(e,t){return Array.isArray(e)||(e="string"==typeof e?""===e?[]:e.split(this.props.delimiter):e?[e]:[]),e.map(function(e){if("string"==typeof e){for(var s in t)if(t.hasOwnProperty(s)&&t[s]&&t[s].value===e)return t[s];return{value:e,label:e}}return e})},setValue:function(e,t){(t||void 0===t)&&(this._focusAfterUpdate=!0);var s=this.getStateFromValue(e);s.isOpen=!1,this.fireChangeEvent(s),this.setState(s)},selectValue:function(e){this.props.multi?e&&this.addValue(e):this.setValue(e),this._unbindCloseMenuIfClickedOutside()},addValue:function(e){this.setValue(this.state.values.concat(e))},popValue:function(){this.setValue(this.state.values.slice(0,this.state.values.length-1))},removeValue:function(e){this.setValue(this.state.values.filter(function(t){return t!==e}))},clearValue:function(e){e&&"mousedown"===e.type&&0!==e.button||(e.stopPropagation(),e.preventDefault(),this.setValue(null))},resetValue:function(){this.setValue(""===this.state.value?null:this.state.value)},getInputNode:function(){var e=this.refs.input;return this.props.searchable?e:o.findDOMNode(e)},fireChangeEvent:function(e){e.value!==this.state.value&&this.props.onChange&&this.props.onChange(e.value,e.values)},handleMouseDown:function(e){this.props.disabled||"mousedown"===e.type&&0!==e.button||(e.stopPropagation(),e.preventDefault(),this.state.isFocused?this.setState({isOpen:!0},this._bindCloseMenuIfClickedOutside):(this._openAfterFocus=!0,this.getInputNode().focus()))},handleMouseDownOnArrow:function(e){this.props.disabled||"mousedown"===e.type&&0!==e.button||this.state.isOpen&&(e.stopPropagation(),e.preventDefault(),this.setState({isOpen:!1},this._unbindCloseMenuIfClickedOutside))},handleInputFocus:function(e){var t=this.state.isOpen||this._openAfterFocus;this.setState({isFocused:!0,isOpen:t},function(){t?this._bindCloseMenuIfClickedOutside():this._unbindCloseMenuIfClickedOutside()}),this._openAfterFocus=!1,this.props.onFocus&&this.props.onFocus(e)},handleInputBlur:function(e){var t=this;this._blurTimeout=setTimeout(function(){t._focusAfterUpdate||t.setState({isFocused:!1})},50),this.props.onBlur&&this.props.onBlur(e)},handleKeyDown:function(e){if(!this.state.disabled){switch(e.keyCode){case 8:return void(this.state.inputValue||this.popValue());case 9:if(e.shiftKey||!this.state.isOpen||!this.state.focusedOption)return;this.selectFocusedOption();break;case 13:if(!this.state.isOpen)return;this.selectFocusedOption();break;case 27:this.state.isOpen?this.resetValue():this.clearValue();break;case 38:this.focusPreviousOption();break;case 40:this.focusNextOption();break;case 188:if(!this.props.allowCreate)return;e.preventDefault(),e.stopPropagation(),this.selectFocusedOption();break;default:return}e.preventDefault()}},_getNewFocusedOption:function(e){for(var t in e)if(e.hasOwnProperty(t)&&e[t]===this.state.focusedOption)return e[t];return e[0]},handleInputChange:function(e){if(this._optionsFilterString=e.target.value,this.props.asyncOptions)this.setState({isLoading:!0,inputValue:e.target.value}),this.loadAsyncOptions(e.target.value,{isLoading:!1,isOpen:!0},this._bindCloseMenuIfClickedOutside);else{var t=this.filterOptions(this.state.options);this.setState({isOpen:!0,inputValue:e.target.value,filteredOptions:t,focusedOption:this._getNewFocusedOption(t)},this._bindCloseMenuIfClickedOutside)}},autoloadAsyncOptions:function(){var e=this;this.loadAsyncOptions(this.props.value||"",{},function(){e.setValue(e.props.value,!1)})},loadAsyncOptions:function(e,t,s){for(var i=this._currentRequestId=l++,o=0;o<=e.length;o++){var n=e.slice(0,o);if(this._optionsCache[n]&&(e===n||this._optionsCache[n].complete)){var a=this._optionsCache[n].options,r=this.filterOptions(a),p={options:a,filteredOptions:r,focusedOption:this._getNewFocusedOption(r)};for(var u in t)t.hasOwnProperty(u)&&(p[u]=t[u]);return this.setState(p),void(s&&s.call(this,{}))}}var c=this;this.props.asyncOptions(e,function(o,n){if(o)throw o;if(c._optionsCache[e]=n,i===c._currentRequestId){var a=c.filterOptions(n.options),r={options:n.options,filteredOptions:a,focusedOption:c._getNewFocusedOption(a)};for(var l in t)t.hasOwnProperty(l)&&(r[l]=t[l]);c.setState(r),s&&s.call(c,{})}})},filterOptions:function(e,t){if(!this.props.searchable)return e;var s=this._optionsFilterString,i=(t||this.state.values).map(function(e){return e.value});if(this.props.filterOptions)return this.props.filterOptions.call(this,e,s,i);var o=function(e){if(this.props.multi&&i.indexOf(e.value)>-1)return!1;if(this.props.filterOption)return this.props.filterOption.call(this,e,s);var t=String(e.value),o=String(e.label);return this.props.ignoreCase&&(t=t.toLowerCase(),o=o.toLowerCase(),s=s.toLowerCase()),s&&"start"!==this.props.matchPos?"label"!==this.props.matchProp&&t.indexOf(s)>=0||"value"!==this.props.matchProp&&o.indexOf(s)>=0:"label"!==this.props.matchProp&&t.substr(0,s.length)===s||"value"!==this.props.matchProp&&o.substr(0,s.length)===s};return(e||[]).filter(o,this)},selectFocusedOption:function(){return this.selectValue(this.props.allowCreate&&!this.state.focusedOption?this.state.inputValue:this.state.focusedOption)},focusOption:function(e){this.setState({focusedOption:e})},focusNextOption:function(){this.focusAdjacentOption("next")},focusPreviousOption:function(){this.focusAdjacentOption("previous")},focusAdjacentOption:function(e){this._focusedOptionReveal=!0;var t=this.state.filteredOptions;if(!this.state.isOpen)return void this.setState({isOpen:!0,inputValue:"",focusedOption:this.state.focusedOption||t["next"===e?0:t.length-1]},this._bindCloseMenuIfClickedOutside);if(t.length){for(var s=-1,i=0;i<t.length;i++)if(this.state.focusedOption===t[i]){s=i;break}var o=t[0];"next"===e&&s>-1&&s<t.length-1?o=t[s+1]:"previous"===e&&(o=s>0?t[s-1]:t[t.length-1]),this.setState({focusedOption:o})}},unfocusOption:function(e){this.state.focusedOption===e&&this.setState({focusedOption:null})},buildMenu:function(){var e=this.state.focusedOption?this.state.focusedOption.value:null,t=this.props.optionRenderer||function(e){return e.label};if(this.state.filteredOptions.length>0&&(e=null==e?this.state.filteredOptions[0]:e),this.props.allowCreate&&this.state.inputValue.trim()){var s=this.state.inputValue;this.state.filteredOptions.unshift({value:s,label:s,create:!0})}var i=Object.keys(this.state.filteredOptions).map(function(s){var i=this.state.filteredOptions[s],n=this.state.value===i.value,r=e===i.value,l=a({"Select-option":!0,"is-selected":n,"is-focused":r,"is-disabled":i.disabled}),p=r?"focused":null,u=this.focusOption.bind(this,i),c=this.unfocusOption.bind(this,i),h=this.selectValue.bind(this,i),d=t(i);return i.disabled?o.createElement("div",{ref:p,key:"option-"+i.value,className:l},d):o.createElement("div",{ref:p,key:"option-"+i.value,className:l,onMouseEnter:u,onMouseLeave:c,onMouseDown:h,onClick:h},i.create?this.props.addLabelText.replace("{label}",i.label):d)},this);return i.length?i:o.createElement("div",{className:"Select-noresults"},this.props.asyncOptions&&!this.state.inputValue?this.props.searchPromptText:this.props.noResultsText)},handleOptionLabelClick:function(e,t){this.props.onOptionLabelClick&&this.props.onOptionLabelClick(e,t)},render:function(){var e=a("Select",this.props.className,{"is-multi":this.props.multi,"is-searchable":this.props.searchable,"is-open":this.state.isOpen,"is-focused":this.state.isFocused,"is-loading":this.state.isLoading,"is-disabled":this.props.disabled,"has-value":this.state.value}),t=[];this.props.multi&&this.state.values.forEach(function(e){t.push(o.createElement(r,{key:e.value,option:e,renderer:this.props.valueRenderer,optionLabelClick:!!this.props.onOptionLabelClick,onOptionLabelClick:this.handleOptionLabelClick.bind(this,e),onRemove:this.removeValue.bind(this,e),disabled:this.props.disabled}))},this),this.state.inputValue||this.props.multi&&t.length||t.push(o.createElement("div",{className:"Select-placeholder",key:"placeholder"},this.state.placeholder));var s,l,p=this.state.isLoading?o.createElement("span",{className:"Select-loading","aria-hidden":"true"}):null,u=this.props.clearable&&this.state.value&&!this.props.disabled?o.createElement("span",{className:"Select-clear",title:this.props.multi?this.props.clearAllText:this.props.clearValueText,"aria-label":this.props.multi?this.props.clearAllText:this.props.clearValueText,onMouseDown:this.clearValue,onClick:this.clearValue,dangerouslySetInnerHTML:{__html:"×"}}):null;this.state.isOpen&&(l={ref:"menu",className:"Select-menu"},this.props.multi&&(l.onMouseDown=this.handleMouseDown),s=o.createElement("div",{ref:"selectMenuContainer",className:"Select-menu-outer"},o.createElement("div",l,this.buildMenu())));var c,h={ref:"input",className:"Select-input",tabIndex:this.props.tabIndex||0,onFocus:this.handleInputFocus,onBlur:this.handleInputBlur};for(var d in this.props.inputProps)this.props.inputProps.hasOwnProperty(d)&&(h[d]=this.props.inputProps[d]);return this.props.disabled?this.props.multi&&this.state.values.length||(c=o.createElement("div",{className:"Select-input"}," ")):c=this.props.searchable?o.createElement(n,i({value:this.state.inputValue,onChange:this.handleInputChange,minWidth:"5"},h)):o.createElement("div",h," "),o.createElement("div",{ref:"wrapper",className:e},o.createElement("input",{type:"hidden",ref:"value",name:this.props.name,value:this.state.value,disabled:this.props.disabled}),o.createElement("div",{className:"Select-control",ref:"control",onKeyDown:this.handleKeyDown,onMouseDown:this.handleMouseDown,onTouchEnd:this.handleMouseDown},t,c,o.createElement("span",{className:"Select-arrow-zone",onMouseDown:this.handleMouseDownOnArrow}),o.createElement("span",{className:"Select-arrow",onMouseDown:this.handleMouseDownOnArrow}),p,u),s)}});t.exports=p}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./Value":2}],2:[function(e,t,s){(function(e){"use strict";var s="undefined"!=typeof window?window.React:"undefined"!=typeof e?e.React:null,i=s.createClass({displayName:"Value",propTypes:{disabled:s.PropTypes.bool,onOptionLabelClick:s.PropTypes.func,onRemove:s.PropTypes.func,option:s.PropTypes.object.isRequired,optionLabelClick:s.PropTypes.bool,renderer:s.PropTypes.func},blockEvent:function(e){e.stopPropagation()},handleOnRemove:function(e){this.props.disabled||this.props.onRemove(e)},render:function(){var e=this.props.option.label;return this.props.renderer&&(e=this.props.renderer(this.props.option)),this.props.optionLabelClick&&(e=s.createElement("a",{className:"Select-item-label__a",onMouseDown:this.blockEvent,onTouchEnd:this.props.onOptionLabelClick,onClick:this.props.onOptionLabelClick},e)),s.createElement("div",{className:"Select-item"},s.createElement("span",{className:"Select-item-icon",onMouseDown:this.blockEvent,onClick:this.handleOnRemove,onTouchEnd:this.handleOnRemove},"×"),s.createElement("span",{className:"Select-item-label"},e))}});t.exports=i}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}]},{},[1])(1)}); | ||
!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,s,i){function o(a,l){if(!s[a]){if(!t[a]){var r="function"==typeof require&&require;if(!l&&r)return r(a,!0);if(n)return n(a,!0);var p=new Error("Cannot find module '"+a+"'");throw p.code="MODULE_NOT_FOUND",p}var u=s[a]={exports:{}};t[a][0].call(u.exports,function(e){var s=t[a][1][e];return o(s?s:e)},u,u.exports,e,t,s,i)}return s[a].exports}for(var n="function"==typeof require&&require,a=0;a<i.length;a++)o(i[a]);return o}({1:[function(e,t,s){(function(s){"use strict";var i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var s=arguments[t];for(var i in s)Object.prototype.hasOwnProperty.call(s,i)&&(e[i]=s[i])}return e},o="undefined"!=typeof window?window.React:"undefined"!=typeof s?s.React:null,n="undefined"!=typeof window?window.AutosizeInput:"undefined"!=typeof s?s.AutosizeInput:null,a="undefined"!=typeof window?window.classNames:"undefined"!=typeof s?s.classNames:null,l=e("./Value"),r=0,p=o.createClass({displayName:"Select",propTypes:{allowCreate:o.PropTypes.bool,asyncOptions:o.PropTypes.func,autoload:o.PropTypes.bool,className:o.PropTypes.string,clearable:o.PropTypes.bool,clearAllText:o.PropTypes.string,clearValueText:o.PropTypes.string,delimiter:o.PropTypes.string,disabled:o.PropTypes.bool,filterOption:o.PropTypes.func,filterOptions:o.PropTypes.func,ignoreCase:o.PropTypes.bool,inputProps:o.PropTypes.object,matchPos:o.PropTypes.string,matchProp:o.PropTypes.string,multi:o.PropTypes.bool,name:o.PropTypes.string,addLabelText:o.PropTypes.string,noResultsText:o.PropTypes.string,onBlur:o.PropTypes.func,onChange:o.PropTypes.func,onFocus:o.PropTypes.func,onOptionLabelClick:o.PropTypes.func,optionRenderer:o.PropTypes.func,options:o.PropTypes.array,placeholder:o.PropTypes.string,searchable:o.PropTypes.bool,searchPromptText:o.PropTypes.string,value:o.PropTypes.any,valueRenderer:o.PropTypes.func},getDefaultProps:function(){return{allowCreate:!1,asyncOptions:void 0,autoload:!0,className:void 0,clearable:!0,clearAllText:"Clear all",clearValueText:"Clear value",delimiter:",",disabled:!1,ignoreCase:!0,inputProps:{},matchPos:"any",matchProp:"any",name:void 0,addLabelText:"Add {label} ?",noResultsText:"No results found",onChange:void 0,onOptionLabelClick:void 0,options:void 0,placeholder:"Select...",searchable:!0,searchPromptText:"Type to search",value:void 0}},getInitialState:function(){return{isFocused:!1,isLoading:!1,isOpen:!1,options:this.props.options}},componentWillMount:function(){this._optionsCache={},this._optionsFilterString="";var e=this;this._closeMenuIfClickedOutside=function(t){if(e.state.isOpen){var s=o.findDOMNode(e.refs.selectMenuContainer),i=o.findDOMNode(e.refs.control),n=e.clickedOutsideElement(s,t),a=e.clickedOutsideElement(i,t);n&&a&&e.setState({isOpen:!1},e._unbindCloseMenuIfClickedOutside)}},this._bindCloseMenuIfClickedOutside=function(){!document.addEventListener&&document.attachEvent?document.attachEvent("onclick",this._closeMenuIfClickedOutside):document.addEventListener("click",this._closeMenuIfClickedOutside)},this._unbindCloseMenuIfClickedOutside=function(){!document.removeEventListener&&document.detachEvent?document.detachEvent("onclick",this._closeMenuIfClickedOutside):document.removeEventListener("click",this._closeMenuIfClickedOutside)},this.setState(this.getStateFromValue(this.props.value))},componentDidMount:function(){this.props.asyncOptions&&this.props.autoload&&this.autoloadAsyncOptions()},componentWillUnmount:function(){clearTimeout(this._blurTimeout),clearTimeout(this._focusTimeout),this.state.isOpen&&this._unbindCloseMenuIfClickedOutside()},componentWillReceiveProps:function(e){JSON.stringify(e.options)!==JSON.stringify(this.props.options)&&this.setState({options:e.options,filteredOptions:this.filterOptions(e.options)}),(e.value!==this.state.value||e.placeholder!==this.state.placeholder)&&this.setState(this.getStateFromValue(e.value,e.options,e.placeholder))},componentDidUpdate:function(){var e=this;if(!this.props.disabled&&this._focusAfterUpdate&&(clearTimeout(this._blurTimeout),this._focusTimeout=setTimeout(function(){e.getInputNode().focus(),e._focusAfterUpdate=!1},50)),this._focusedOptionReveal){if(this.refs.focused&&this.refs.menu){var t=o.findDOMNode(this.refs.focused),s=o.findDOMNode(this.refs.menu),i=t.getBoundingClientRect(),n=s.getBoundingClientRect();(i.bottom>n.bottom||i.top<n.top)&&(s.scrollTop=t.offsetTop+t.clientHeight-s.offsetHeight)}this._focusedOptionReveal=!1}},focus:function(){this.getInputNode().focus()},clickedOutsideElement:function(e,t){for(var s=t.target?t.target:t.srcElement;null!=s;){if(s===e)return!1;s=s.offsetParent}return!0},getStateFromValue:function(e,t,s){t||(t=this.state.options),s||(s=this.props.placeholder),this._optionsFilterString="";var i=this.initValuesArray(e,t),o=this.filterOptions(t,i);return{value:i.map(function(e){return e.value}).join(this.props.delimiter),values:i,inputValue:"",filteredOptions:o,placeholder:!this.props.multi&&i.length?i[0].label:s,focusedOption:!this.props.multi&&i.length?i[0]:o[0]}},initValuesArray:function(e,t){return Array.isArray(e)||(e="string"==typeof e?""===e?[]:e.split(this.props.delimiter):e?[e]:[]),e.map(function(e){if("string"==typeof e){for(var s in t)if(t.hasOwnProperty(s)&&t[s]&&t[s].value===e)return t[s];return{value:e,label:e}}return e})},setValue:function(e,t){(t||void 0===t)&&(this._focusAfterUpdate=!0);var s=this.getStateFromValue(e);s.isOpen=!1,this.fireChangeEvent(s),this.setState(s)},selectValue:function(e){this.props.multi?e&&this.addValue(e):this.setValue(e),this._unbindCloseMenuIfClickedOutside()},addValue:function(e){this.setValue(this.state.values.concat(e))},popValue:function(){this.setValue(this.state.values.slice(0,this.state.values.length-1))},removeValue:function(e){this.setValue(this.state.values.filter(function(t){return t!==e}))},clearValue:function(e){e&&"mousedown"===e.type&&0!==e.button||(e.stopPropagation(),e.preventDefault(),this.setValue(null))},resetValue:function(){this.setValue(""===this.state.value?null:this.state.value)},getInputNode:function(){var e=this.refs.input;return this.props.searchable?e:o.findDOMNode(e)},fireChangeEvent:function(e){e.value!==this.state.value&&this.props.onChange&&this.props.onChange(e.value,e.values)},handleMouseDown:function(e){this.props.disabled||"mousedown"===e.type&&0!==e.button||(e.stopPropagation(),e.preventDefault(),this.state.isFocused?this.setState({isOpen:!0},this._bindCloseMenuIfClickedOutside):(this._openAfterFocus=!0,this.getInputNode().focus()))},handleMouseDownOnArrow:function(e){this.props.disabled||"mousedown"===e.type&&0!==e.button||this.state.isOpen&&(e.stopPropagation(),e.preventDefault(),this.setState({isOpen:!1},this._unbindCloseMenuIfClickedOutside))},handleInputFocus:function(e){var t=this.state.isOpen||this._openAfterFocus;this.setState({isFocused:!0,isOpen:t},function(){t?this._bindCloseMenuIfClickedOutside():this._unbindCloseMenuIfClickedOutside()}),this._openAfterFocus=!1,this.props.onFocus&&this.props.onFocus(e)},handleInputBlur:function(e){var t=this;this._blurTimeout=setTimeout(function(){t._focusAfterUpdate||t.setState({isFocused:!1})},50),this.props.onBlur&&this.props.onBlur(e)},handleKeyDown:function(e){if(!this.state.disabled){switch(e.keyCode){case 8:return void(this.state.inputValue||this.popValue());case 9:if(e.shiftKey||!this.state.isOpen||!this.state.focusedOption)return;this.selectFocusedOption();break;case 13:if(!this.state.isOpen)return;this.selectFocusedOption();break;case 27:this.state.isOpen?this.resetValue():this.clearValue(e);break;case 38:this.focusPreviousOption();break;case 40:this.focusNextOption();break;case 188:if(!this.props.allowCreate||!this.props.multi)return;e.preventDefault(),e.stopPropagation(),this.selectFocusedOption();break;default:return}e.preventDefault()}},_getNewFocusedOption:function(e){for(var t in e)if(e.hasOwnProperty(t)&&e[t]===this.state.focusedOption)return e[t];return e[0]},handleInputChange:function(e){if(this._optionsFilterString=e.target.value,this.props.asyncOptions)this.setState({isLoading:!0,inputValue:e.target.value}),this.loadAsyncOptions(e.target.value,{isLoading:!1,isOpen:!0},this._bindCloseMenuIfClickedOutside);else{var t=this.filterOptions(this.state.options);this.setState({isOpen:!0,inputValue:e.target.value,filteredOptions:t,focusedOption:this._getNewFocusedOption(t)},this._bindCloseMenuIfClickedOutside)}},autoloadAsyncOptions:function(){var e=this;this.loadAsyncOptions(this.props.value||"",{},function(){e.setValue(e.props.value,!1)})},loadAsyncOptions:function(e,t,s){for(var i=this._currentRequestId=r++,o=0;o<=e.length;o++){var n=e.slice(0,o);if(this._optionsCache[n]&&(e===n||this._optionsCache[n].complete)){var a=this._optionsCache[n].options,l=this.filterOptions(a),p={options:a,filteredOptions:l,focusedOption:this._getNewFocusedOption(l)};for(var u in t)t.hasOwnProperty(u)&&(p[u]=t[u]);return this.setState(p),void(s&&s.call(this,{}))}}var c=this;this.props.asyncOptions(e,function(o,n){if(o)throw o;if(c._optionsCache[e]=n,i===c._currentRequestId){var a=c.filterOptions(n.options),l={options:n.options,filteredOptions:a,focusedOption:c._getNewFocusedOption(a)};for(var r in t)t.hasOwnProperty(r)&&(l[r]=t[r]);c.setState(l),s&&s.call(c,{})}})},filterOptions:function(e,t){if(!this.props.searchable)return e;var s=this._optionsFilterString,i=(t||this.state.values).map(function(e){return e.value});if(this.props.filterOptions)return this.props.filterOptions.call(this,e,s,i);var o=function(e){if(this.props.multi&&i.indexOf(e.value)>-1)return!1;if(this.props.filterOption)return this.props.filterOption.call(this,e,s);var t=String(e.value),o=String(e.label);return this.props.ignoreCase&&(t=t.toLowerCase(),o=o.toLowerCase(),s=s.toLowerCase()),s&&"start"!==this.props.matchPos?"label"!==this.props.matchProp&&t.indexOf(s)>=0||"value"!==this.props.matchProp&&o.indexOf(s)>=0:"label"!==this.props.matchProp&&t.substr(0,s.length)===s||"value"!==this.props.matchProp&&o.substr(0,s.length)===s};return(e||[]).filter(o,this)},selectFocusedOption:function(){return this.selectValue(this.props.allowCreate&&!this.state.focusedOption?this.state.inputValue:this.state.focusedOption)},focusOption:function(e){this.setState({focusedOption:e})},focusNextOption:function(){this.focusAdjacentOption("next")},focusPreviousOption:function(){this.focusAdjacentOption("previous")},focusAdjacentOption:function(e){this._focusedOptionReveal=!0;var t=this.state.filteredOptions;if(!this.state.isOpen)return void this.setState({isOpen:!0,inputValue:"",focusedOption:this.state.focusedOption||t["next"===e?0:t.length-1]},this._bindCloseMenuIfClickedOutside);if(t.length){for(var s=-1,i=0;i<t.length;i++)if(this.state.focusedOption===t[i]){s=i;break}var o=t[0];"next"===e&&s>-1&&s<t.length-1?o=t[s+1]:"previous"===e&&(o=s>0?t[s-1]:t[t.length-1]),this.setState({focusedOption:o})}},unfocusOption:function(e){this.state.focusedOption===e&&this.setState({focusedOption:null})},buildMenu:function(){var e=this.state.focusedOption?this.state.focusedOption.value:null,t=this.props.optionRenderer||function(e){return e.label};this.state.filteredOptions.length>0&&(e=null==e?this.state.filteredOptions[0]:e);var s=this.state.filteredOptions;if(this.props.allowCreate&&this.state.inputValue.trim()){var i=this.state.inputValue;s=s.slice(),s.unshift({value:i,label:i,create:!0})}var n=Object.keys(s).map(function(i){var n=s[i],l=this.state.value===n.value,r=e===n.value,p=a({"Select-option":!0,"is-selected":l,"is-focused":r,"is-disabled":n.disabled}),u=r?"focused":null,c=this.focusOption.bind(this,n),h=this.unfocusOption.bind(this,n),d=this.selectValue.bind(this,n),f=t(n);return n.disabled?o.createElement("div",{ref:u,key:"option-"+n.value,className:p},f):o.createElement("div",{ref:u,key:"option-"+n.value,className:p,onMouseEnter:c,onMouseLeave:h,onMouseDown:d,onClick:d},n.create?this.props.addLabelText.replace("{label}",n.label):f)},this);return n.length?n:o.createElement("div",{className:"Select-noresults"},this.props.asyncOptions&&!this.state.inputValue?this.props.searchPromptText:this.props.noResultsText)},handleOptionLabelClick:function(e,t){this.props.onOptionLabelClick&&this.props.onOptionLabelClick(e,t)},render:function(){var e=a("Select",this.props.className,{"is-multi":this.props.multi,"is-searchable":this.props.searchable,"is-open":this.state.isOpen,"is-focused":this.state.isFocused,"is-loading":this.state.isLoading,"is-disabled":this.props.disabled,"has-value":this.state.value}),t=[];this.props.multi&&this.state.values.forEach(function(e){t.push(o.createElement(l,{key:e.value,option:e,renderer:this.props.valueRenderer,optionLabelClick:!!this.props.onOptionLabelClick,onOptionLabelClick:this.handleOptionLabelClick.bind(this,e),onRemove:this.removeValue.bind(this,e),disabled:this.props.disabled}))},this),this.state.inputValue||this.props.multi&&t.length||t.push(o.createElement("div",{className:"Select-placeholder",key:"placeholder"},this.state.placeholder));var s,r,p=this.state.isLoading?o.createElement("span",{className:"Select-loading","aria-hidden":"true"}):null,u=this.props.clearable&&this.state.value&&!this.props.disabled?o.createElement("span",{className:"Select-clear",title:this.props.multi?this.props.clearAllText:this.props.clearValueText,"aria-label":this.props.multi?this.props.clearAllText:this.props.clearValueText,onMouseDown:this.clearValue,onClick:this.clearValue,dangerouslySetInnerHTML:{__html:"×"}}):null;this.state.isOpen&&(r={ref:"menu",className:"Select-menu"},this.props.multi&&(r.onMouseDown=this.handleMouseDown),s=o.createElement("div",{ref:"selectMenuContainer",className:"Select-menu-outer"},o.createElement("div",r,this.buildMenu())));var c,h={ref:"input",className:"Select-input",tabIndex:this.props.tabIndex||0,onFocus:this.handleInputFocus,onBlur:this.handleInputBlur};for(var d in this.props.inputProps)this.props.inputProps.hasOwnProperty(d)&&(h[d]=this.props.inputProps[d]);return this.props.disabled?this.props.multi&&this.state.values.length||(c=o.createElement("div",{className:"Select-input"}," ")):c=this.props.searchable?o.createElement(n,i({value:this.state.inputValue,onChange:this.handleInputChange,minWidth:"5"},h)):o.createElement("div",h," "),o.createElement("div",{ref:"wrapper",className:e},o.createElement("input",{type:"hidden",ref:"value",name:this.props.name,value:this.state.value,disabled:this.props.disabled}),o.createElement("div",{className:"Select-control",ref:"control",onKeyDown:this.handleKeyDown,onMouseDown:this.handleMouseDown,onTouchEnd:this.handleMouseDown},t,c,o.createElement("span",{className:"Select-arrow-zone",onMouseDown:this.handleMouseDownOnArrow}),o.createElement("span",{className:"Select-arrow",onMouseDown:this.handleMouseDownOnArrow}),p,u),s)}});t.exports=p}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./Value":2}],2:[function(e,t,s){(function(e){"use strict";var s="undefined"!=typeof window?window.React:"undefined"!=typeof e?e.React:null,i=s.createClass({displayName:"Value",propTypes:{disabled:s.PropTypes.bool,onOptionLabelClick:s.PropTypes.func,onRemove:s.PropTypes.func,option:s.PropTypes.object.isRequired,optionLabelClick:s.PropTypes.bool,renderer:s.PropTypes.func},blockEvent:function(e){e.stopPropagation()},handleOnRemove:function(e){this.props.disabled||this.props.onRemove(e)},render:function(){var e=this.props.option.label;return this.props.renderer&&(e=this.props.renderer(this.props.option)),this.props.optionLabelClick&&(e=s.createElement("a",{className:"Select-item-label__a",onMouseDown:this.blockEvent,onTouchEnd:this.props.onOptionLabelClick,onClick:this.props.onOptionLabelClick},e)),s.createElement("div",{className:"Select-item"},s.createElement("span",{className:"Select-item-icon",onMouseDown:this.blockEvent,onClick:this.handleOnRemove,onTouchEnd:this.handleOnRemove},"×"),s.createElement("span",{className:"Select-item-label"},e))}});t.exports=i}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}]},{},[1])(1)}); |
# React-Select | ||
## v0.5.6 / 2015-07-27 | ||
* fixed; Allow entering of commas when allowCreate is on but multi is off, thanks [Angelo DiNardi](https://github.com/adinardi) | ||
* fixed; Times (clear) character is now rendered from string unicode character for consistent output, thanks [Nibbles](https://github.com/Siliconrob) | ||
* fixed; allowCreate bug, thanks [goodzsq](https://github.com/goodzsq) | ||
* fixed; changes to props.placeholder weren't being reflected correctly, thanks [alesn](https://github.com/alesn) | ||
* fixed; error when escape is pressedn where `clearValue` was not passed the event, thanks [Mikhail Kotelnikov](https://github.com/mkotelnikov) | ||
* added; More tests, thanks [Dave Brotherstone](https://github.com/bruderstein) | ||
## v0.5.5 / 2015-07-12 | ||
@@ -4,0 +13,0 @@ |
@@ -163,4 +163,4 @@ /* disable some rules until we refactor more completely; fixing them now would | ||
} | ||
if (newProps.value !== this.state.value) { | ||
this.setState(this.getStateFromValue(newProps.value, newProps.options)); | ||
if (newProps.value !== this.state.value || newProps.placeholder !== this.state.placeholder) { | ||
this.setState(this.getStateFromValue(newProps.value, newProps.options, newProps.placeholder)); | ||
} | ||
@@ -208,6 +208,9 @@ }, | ||
getStateFromValue: function getStateFromValue(value, options) { | ||
getStateFromValue: function getStateFromValue(value, options, placeholder) { | ||
if (!options) { | ||
options = this.state.options; | ||
} | ||
if (!placeholder) { | ||
placeholder = this.props.placeholder; | ||
} | ||
@@ -227,3 +230,3 @@ // reset internal filter string | ||
filteredOptions: filteredOptions, | ||
placeholder: !this.props.multi && values.length ? values[0].label : this.props.placeholder, | ||
placeholder: !this.props.multi && values.length ? values[0].label : placeholder, | ||
focusedOption: !this.props.multi && values.length ? values[0] : filteredOptions[0] | ||
@@ -419,3 +422,3 @@ }; | ||
} else { | ||
this.clearValue(); | ||
this.clearValue(event); | ||
} | ||
@@ -436,3 +439,3 @@ break; | ||
// , | ||
if (this.props.allowCreate) { | ||
if (this.props.allowCreate && this.props.multi) { | ||
event.preventDefault(); | ||
@@ -661,5 +664,7 @@ event.stopPropagation(); | ||
// Add the current value to the filtered options in last resort | ||
var options = this.state.filteredOptions; | ||
if (this.props.allowCreate && this.state.inputValue.trim()) { | ||
var inputValue = this.state.inputValue; | ||
this.state.filteredOptions.unshift({ | ||
options = options.slice(); | ||
options.unshift({ | ||
value: inputValue, | ||
@@ -671,4 +676,4 @@ label: inputValue, | ||
var ops = Object.keys(this.state.filteredOptions).map(function (key) { | ||
var op = this.state.filteredOptions[key]; | ||
var ops = Object.keys(options).map(function (key) { | ||
var op = options[key]; | ||
var isSelected = this.state.value === op.value; | ||
@@ -675,0 +680,0 @@ var isFocused = focusedValue === op.value; |
{ | ||
"name": "react-select", | ||
"version": "0.5.5", | ||
"version": "0.5.6", | ||
"description": "A Select control built with and for ReactJS", | ||
@@ -24,3 +24,3 @@ "main": "lib/Select.js", | ||
"istanbul": "^0.3.17", | ||
"jsdom": "^5.6.0", | ||
"jsdom": "^3.1.2", | ||
"mocha": "^2.2.5", | ||
@@ -31,3 +31,6 @@ "mocha-jsdom": "^1.0.0", | ||
"sinon": "^1.15.4", | ||
"sinon-chai": "^2.8.0" | ||
"sinon-chai": "^2.8.0", | ||
"unexpected": "^9.2.1", | ||
"unexpected-dom": "^1.1.3", | ||
"unexpected-sinon": "^6.4.1" | ||
}, | ||
@@ -47,3 +50,3 @@ "peerDependencies": { | ||
"bump:minor": "gulp bump:minor", | ||
"start": "gulp dev", | ||
"cover": "istanbul cover node_modules/.bin/_mocha -- -u exports --compilers js:babel/register -R spec", | ||
"examples": "gulp dev:server", | ||
@@ -53,16 +56,16 @@ "lint": "eslint .", | ||
"release": "gulp release", | ||
"start": "gulp dev", | ||
"test": "mocha --compilers js:babel/register", | ||
"cover": "istanbul cover node_modules/.bin/_mocha -- -u exports --compilers js:babel/register -R spec", | ||
"watch": "gulp watch:lib" | ||
}, | ||
"keywords": [ | ||
"combobox", | ||
"form", | ||
"input", | ||
"multiselect", | ||
"react", | ||
"react-component", | ||
"select", | ||
"multiselect", | ||
"combobox", | ||
"input", | ||
"form", | ||
"ui" | ||
] | ||
} |
@@ -29,3 +29,3 @@ React-Select | ||
It's loosely based on [Selectize](http://brianreavis.github.io/selectize.js/) (in terms of behaviour and user experience) and [React-Autocomplete](https://github.com/rackt/react-autocomplete) (as a native React Combobox implemenation), as well as other select controls including [Chosen](http://harvesthq.github.io/chosen/) and [Select2](http://ivaynberg.github.io/select2/). | ||
It's loosely based on [Selectize](http://brianreavis.github.io/selectize.js/) (in terms of behaviour and user experience) and [React-Autocomplete](https://github.com/rackt/react-autocomplete) (as a native React Combobox implementation), as well as other select controls including [Chosen](http://harvesthq.github.io/chosen/) and [Select2](http://ivaynberg.github.io/select2/). | ||
@@ -41,3 +41,3 @@ | ||
You can also use the standalone build by including `dist/select.js` and `dist/default.css` in your page. If you use this, make sure you have already included the following dependencies: | ||
You can also use the standalone build by including `dist/select.js` and `dist/default.css` in your page. If you use this, make sure you have already included the following dependencies: | ||
@@ -44,0 +44,0 @@ * [React](http://facebook.github.io/react/) |
@@ -160,4 +160,4 @@ /* disable some rules until we refactor more completely; fixing them now would | ||
} | ||
if (newProps.value !== this.state.value) { | ||
this.setState(this.getStateFromValue(newProps.value, newProps.options)); | ||
if (newProps.value !== this.state.value || newProps.placeholder !== this.state.placeholder) { | ||
this.setState(this.getStateFromValue(newProps.value, newProps.options, newProps.placeholder)); | ||
} | ||
@@ -205,6 +205,9 @@ }, | ||
getStateFromValue: function(value, options) { | ||
getStateFromValue: function(value, options, placeholder) { | ||
if (!options) { | ||
options = this.state.options; | ||
} | ||
if (!placeholder) { | ||
placeholder = this.props.placeholder; | ||
} | ||
@@ -222,3 +225,3 @@ // reset internal filter string | ||
filteredOptions: filteredOptions, | ||
placeholder: !this.props.multi && values.length ? values[0].label : this.props.placeholder, | ||
placeholder: !this.props.multi && values.length ? values[0].label : placeholder, | ||
focusedOption: !this.props.multi && values.length ? values[0] : filteredOptions[0] | ||
@@ -411,3 +414,3 @@ }; | ||
} else { | ||
this.clearValue(); | ||
this.clearValue(event); | ||
} | ||
@@ -425,3 +428,3 @@ break; | ||
case 188: // , | ||
if (this.props.allowCreate) { | ||
if (this.props.allowCreate && this.props.multi) { | ||
event.preventDefault(); | ||
@@ -656,5 +659,7 @@ event.stopPropagation(); | ||
// Add the current value to the filtered options in last resort | ||
var options = this.state.filteredOptions; | ||
if (this.props.allowCreate && this.state.inputValue.trim()) { | ||
var inputValue = this.state.inputValue; | ||
this.state.filteredOptions.unshift({ | ||
options = options.slice(); | ||
options.unshift({ | ||
value: inputValue, | ||
@@ -666,4 +671,4 @@ label: inputValue, | ||
var ops = Object.keys(this.state.filteredOptions).map(function(key) { | ||
var op = this.state.filteredOptions[key]; | ||
var ops = Object.keys(options).map(function(key) { | ||
var op = options[key]; | ||
var isSelected = this.state.value === op.value; | ||
@@ -670,0 +675,0 @@ var isFocused = focusedValue === op.value; |
'use strict'; | ||
/* global describe, it, beforeEach */ | ||
var jsdom = require('mocha-jsdom'); | ||
var chai = require('chai'); | ||
var expect = chai.expect; | ||
var helper = require('../testHelpers/jsdomHelper'); | ||
helper(); | ||
chai.should(); | ||
var sinon = require('sinon'); | ||
var unexpected = require('unexpected'); | ||
var unexpectedDom = require('unexpected-dom'); | ||
var unexpectedSinon = require('unexpected-sinon'); | ||
var expect = unexpected | ||
.clone() | ||
.installPlugin(unexpectedDom) | ||
.installPlugin(unexpectedSinon); | ||
@@ -15,34 +21,238 @@ var React = require('react/addons'); | ||
describe('Select test', function() { | ||
jsdom(); | ||
var options, instance; | ||
describe('Select', function() { | ||
function logChange(val) { | ||
console.log('Selected: ' + val); | ||
} | ||
describe('with simple options', function () { | ||
var options, instance, onChange; | ||
var searchInputNode; | ||
beforeEach(function() { | ||
beforeEach(function () { | ||
options = [ | ||
{ value: 'one', label: 'One' }, | ||
{ value: 'two', label: 'Two' } | ||
]; | ||
options = [ | ||
{ value: 'one', label: 'One' }, | ||
{ value: 'two', label: 'Two' }, | ||
{ value: 'three', label: 'Three' } | ||
]; | ||
onChange = sinon.spy(); | ||
// Render an instance of the component | ||
instance = TestUtils.renderIntoDocument( | ||
<Select | ||
name="form-field-name" | ||
value="one" | ||
options={options} | ||
onChange={logChange}/> | ||
); | ||
// Render an instance of the component | ||
instance = TestUtils.renderIntoDocument( | ||
<Select | ||
name="form-field-name" | ||
value="one" | ||
options={options} | ||
onChange={onChange} | ||
searchable={true} | ||
/> | ||
); | ||
// Focus on the input, such that mouse events are accepted | ||
searchInputNode = instance.getInputNode().getDOMNode().querySelector('input'); | ||
TestUtils.Simulate.focus(searchInputNode); | ||
}); | ||
}); | ||
function pressEnterToAccept() { | ||
TestUtils.Simulate.keyDown(searchInputNode, { keyCode: 13, key: 'Enter' }); | ||
} | ||
function pressTabToAccept() { | ||
TestUtils.Simulate.keyDown(searchInputNode, { keyCode: 9, key: 'Tab' }); | ||
} | ||
function typeSearchText(text) { | ||
TestUtils.Simulate.change(searchInputNode, { target: { value: text } }); | ||
} | ||
function getSelectControl(instance) { | ||
return React.findDOMNode(instance).querySelector('.Select-control'); | ||
} | ||
it('should assign the given name', function() { | ||
var selectInputElement = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'input')[0]; | ||
expect(selectInputElement.getDOMNode().name).to.equal('form-field-name'); | ||
it('should assign the given name', function () { | ||
var selectInputElement = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'input')[0]; | ||
expect(React.findDOMNode(selectInputElement).name, 'to equal', 'form-field-name'); | ||
}); | ||
it('should show the options on mouse click', function () { | ||
TestUtils.Simulate.mouseDown(React.findDOMNode(instance).querySelector('.Select-control')); | ||
var node = React.findDOMNode(instance); | ||
expect(node, 'queried for', '.Select-option', 'to have length', 3); | ||
}); | ||
it('should display the labels on mouse click', function () { | ||
TestUtils.Simulate.mouseDown(React.findDOMNode(instance).querySelector('.Select-control')); | ||
var node = React.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'); | ||
expect(node, 'queried for', '.Select-option:nth-child(3)', 'to have items satisfying', 'to have text', 'Three'); | ||
}); | ||
it('should filter after entering some text', function () { | ||
typeSearchText('T'); | ||
var node = React.findDOMNode(instance); | ||
expect(node, 'queried for', '.Select-option:nth-child(1)', 'to have items satisfying', 'to have text', 'Two'); | ||
expect(node, 'queried for', '.Select-option:nth-child(2)', 'to have items satisfying', 'to have text', 'Three'); | ||
expect(node, 'queried for', '.Select-option', 'to have length', 2); | ||
}); | ||
it('should filter case insensitively', function () { | ||
typeSearchText('t'); | ||
var node = React.findDOMNode(instance); | ||
expect(node, 'queried for', '.Select-option:nth-child(1)', 'to have items satisfying', 'to have text', 'Two'); | ||
expect(node, 'queried for', '.Select-option:nth-child(2)', 'to have items satisfying', 'to have text', 'Three'); | ||
expect(node, 'queried for', '.Select-option', 'to have length', 2); | ||
}); | ||
it('should filter using "contains"', function () { | ||
// Search 'h', should only show 'Three' | ||
typeSearchText('h'); | ||
var node = React.findDOMNode(instance); | ||
expect(node, 'queried for', '.Select-option:nth-child(1)', 'to have items satisfying', 'to have text', 'Three'); | ||
expect(node, 'queried for', '.Select-option', 'to have length', 1); | ||
}); | ||
it('should accept when enter is pressed', function () { | ||
// Search 'h', should only show 'Three' | ||
typeSearchText('h'); | ||
pressEnterToAccept(); | ||
expect(onChange, 'was called with', 'three'); | ||
}); | ||
it('should accept when tab is pressed', function () { | ||
// Search 'h', should only show 'Three' | ||
typeSearchText('h'); | ||
pressTabToAccept(); | ||
expect(onChange, 'was called with', 'three'); | ||
}); | ||
it('should focus the first value on mouse click', function () { | ||
TestUtils.Simulate.mouseDown(React.findDOMNode(instance).querySelector('.Select-control')); | ||
expect(React.findDOMNode(instance), 'queried for', '.Select-option.is-focused', | ||
'to have items satisfying', | ||
'to have text', 'One'); | ||
}); | ||
it('should move the focused value to the second value when down pressed', function () { | ||
var selectControl = getSelectControl(instance); | ||
TestUtils.Simulate.mouseDown(selectControl); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); | ||
expect(React.findDOMNode(instance), 'queried for', '.Select-option.is-focused', | ||
'to have items satisfying', | ||
'to have text', 'Two'); | ||
}); | ||
it('should move the focused value to the second value when down pressed', function () { | ||
var selectControl = getSelectControl(instance); | ||
TestUtils.Simulate.mouseDown(selectControl); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); | ||
expect(React.findDOMNode(instance), 'queried for', '.Select-option.is-focused', | ||
'to have items satisfying', | ||
'to have text', 'Three'); | ||
}); | ||
it('should loop round to top item when down is pressed on the last item', function () { | ||
var selectControl = getSelectControl(instance); | ||
TestUtils.Simulate.mouseDown(selectControl); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); | ||
expect(React.findDOMNode(instance), 'queried for', '.Select-option.is-focused', | ||
'to have items satisfying', | ||
'to have text', 'One'); | ||
}); | ||
it('should loop round to bottom item when up is pressed on the first item', function () { | ||
var selectControl = getSelectControl(instance); | ||
TestUtils.Simulate.mouseDown(selectControl); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 38, key: 'ArrowUp' }); | ||
expect(React.findDOMNode(instance), 'queried for', '.Select-option.is-focused', | ||
'to have items satisfying', | ||
'to have text', 'Three'); | ||
}); | ||
it('should clear the selection on escape', function () { | ||
var selectControl = getSelectControl(instance); | ||
TestUtils.Simulate.mouseDown(selectControl); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 27, key: 'Escape' }); | ||
expect(React.findDOMNode(instance).querySelectorAll('.Select-option'), | ||
'to have length', 0); | ||
}); | ||
it('should open the options on arrow down with the top option focused, when the options are closed', function () { | ||
var selectControl = getSelectControl(instance); | ||
var domNode = React.findDOMNode(instance); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 38, key: 'ArrowDown' }); | ||
expect(domNode, 'queried for', '.Select-option.is-focused', | ||
'to have items satisfying', | ||
'to have text', 'One'); | ||
}); | ||
it('should open the options on arrow up with the top option focused, when the options are closed', function () { | ||
var selectControl = getSelectControl(instance); | ||
var domNode = React.findDOMNode(instance); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); | ||
expect(domNode, 'queried for', '.Select-option.is-focused', | ||
'to have items satisfying', | ||
'to have text', 'One'); | ||
}); | ||
describe('after mouseEnter and leave of an option', function () { | ||
beforeEach(function () { | ||
// Show the options | ||
var selectControl = getSelectControl(instance); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); | ||
var optionTwo = React.findDOMNode(instance).querySelectorAll('.Select-option')[1]; | ||
TestUtils.SimulateNative.mouseOver(optionTwo); | ||
TestUtils.SimulateNative.mouseOut(optionTwo); | ||
}); | ||
it('should have no focused options', function () { | ||
var domNode = React.findDOMNode(instance); | ||
expect(domNode.querySelectorAll('.Select-option.is-focused'), 'to have length', 0); | ||
}); | ||
it('should focus top option after down arrow pressed', function () { | ||
var selectControl = getSelectControl(instance); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 40, key: 'ArrowDown' }); | ||
var domNode = React.findDOMNode(instance); | ||
expect(domNode, 'queried for', '.Select-option.is-focused', | ||
'to have items satisfying', | ||
'to have text', 'One'); | ||
}); | ||
it('should focus last option after up arrow pressed', function () { | ||
var selectControl = getSelectControl(instance); | ||
TestUtils.Simulate.keyDown(selectControl, { keyCode: 38, key: 'ArrowUp' }); | ||
var domNode = React.findDOMNode(instance); | ||
expect(domNode, 'queried for', '.Select-option.is-focused', | ||
'to have items satisfying', | ||
'to have text', 'Three'); | ||
}); | ||
}); | ||
}); | ||
}); |
'use strict'; | ||
/* global describe, it, beforeEach */ | ||
var jsdom = require('mocha-jsdom'); | ||
var chai = require('chai'); | ||
var helper = require('../testHelpers/jsdomHelper'); | ||
helper(); | ||
var unexpected = require('unexpected'); | ||
var unexpectedDom = require('unexpected-dom'); | ||
var unexpectedSinon = require('unexpected-sinon'); | ||
var sinon = require('sinon'); | ||
var sinonChai = require('sinon-chai'); | ||
var expect = chai.expect; | ||
chai.should(); | ||
chai.use(sinonChai); | ||
var expect = unexpected | ||
.clone() | ||
.installPlugin(unexpectedSinon) | ||
.installPlugin(unexpectedDom); | ||
@@ -21,3 +25,2 @@ var React = require('react/addons'); | ||
describe('Value component', function() { | ||
jsdom(); | ||
@@ -37,4 +40,4 @@ var props; | ||
var selectItemIcon = TestUtils.findRenderedDOMComponentWithClass(value, 'Select-item-icon'); | ||
TestUtils.Simulate.click(selectItemIcon.getDOMNode()); | ||
expect(props.onRemove).to.have.been.called; | ||
TestUtils.Simulate.click(selectItemIcon); | ||
expect(props.onRemove, 'was called'); | ||
}); | ||
@@ -44,4 +47,4 @@ | ||
var selectItemIcon = TestUtils.findRenderedDOMComponentWithClass(value, 'Select-item-icon'); | ||
TestUtils.Simulate.touchEnd(selectItemIcon.getDOMNode()); | ||
expect(props.onRemove).to.have.been.called; | ||
TestUtils.Simulate.touchEnd(selectItemIcon); | ||
expect(props.onRemove, 'was called'); | ||
}); | ||
@@ -52,3 +55,3 @@ | ||
value.blockEvent(mockEvent); | ||
expect(mockEvent.stopPropagation).to.have.been.called; | ||
expect(mockEvent.stopPropagation, 'was called'); | ||
}); | ||
@@ -60,3 +63,3 @@ | ||
var selectItemLabel = TestUtils.findRenderedDOMComponentWithClass(value, 'Select-item-label'); | ||
expect(selectItemLabel.getDOMNode().textContent).to.equal(OPTION.label); | ||
expect(React.findDOMNode(selectItemLabel), 'to have text', OPTION.label); | ||
}); | ||
@@ -81,13 +84,13 @@ | ||
it('presents the given label', function() { | ||
expect(selectItemLabelA.getDOMNode().textContent).to.equal(OPTION.label); | ||
expect(React.findDOMNode(selectItemLabelA), 'to have text', OPTION.label); | ||
}); | ||
it('calls a custom callback when the anchor is clicked', function() { | ||
TestUtils.Simulate.click(selectItemLabelA.getDOMNode()); | ||
expect(props.onOptionLabelClick).to.have.been.called; | ||
TestUtils.Simulate.click(selectItemLabelA); | ||
expect(props.onOptionLabelClick, 'was called'); | ||
}); | ||
it('calls a custom callback when the anchor is touched', function() { | ||
TestUtils.Simulate.touchEnd(selectItemLabelA.getDOMNode()); | ||
expect(props.onOptionLabelClick).to.have.been.called; | ||
TestUtils.Simulate.touchEnd(selectItemLabelA); | ||
expect(props.onOptionLabelClick, 'was called'); | ||
}); | ||
@@ -94,0 +97,0 @@ |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
870673
41
23122
17