text: 'use strict';
  
  var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  
  function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
  
  var _react = require('react');
  
  var _react2 = _interopRequireDefault(_react);
  
  var _createReactClass = require('create-react-class');
  
  var _createReactClass2 = _interopRequireDefault(_createReactClass);
  
  var _propTypes = require('prop-types');
  
  var _propTypes2 = _interopRequireDefault(_propTypes);
  
  var _Select = require('./Select');
  
  var _Select2 = _interopRequireDefault(_Select);
  
  var _utilsDefaultFilterOptions = require('./utils/defaultFilterOptions');
  
  var _utilsDefaultFilterOptions2 = _interopRequireDefault(_utilsDefaultFilterOptions);
  
  var _utilsDefaultMenuRenderer = require('./utils/defaultMenuRenderer');
  
  var _utilsDefaultMenuRenderer2 = _interopRequireDefault(_utilsDefaultMenuRenderer);
  
  var Creatable = (0, _createReactClass2['default'])({
  	displayName: 'CreatableSelect',
  
  	propTypes: {
  		// Child function responsible for creating the inner Select component
  		// This component can be used to compose HOCs (eg Creatable and Async)
  		// (props: Object): PropTypes.element
  		children: _propTypes2['default'].func,
  
  		// See Select.propTypes.filterOptions
  		filterOptions: _propTypes2['default'].any,
  
  		// Searches for any matching option within the set of options.
  		// This function prevents duplicate options from being created.
  		// ({ option: Object, options: Array, labelKey: string, valueKey: string }): boolean
  		isOptionUnique: _propTypes2['default'].func,
  
  		// Determines if the current input text represents a valid option.
  		// ({ label: string }): boolean
  		isValidNewOption: _propTypes2['default'].func,
  
  		// See Select.propTypes.menuRenderer
  		menuRenderer: _propTypes2['default'].any,
  
  		// Factory to create new option.
  		// ({ label: string, labelKey: string, valueKey: string }): Object
  		newOptionCreator: _propTypes2['default'].func,
  
  		// input change handler: function (inputValue) {}
  		onInputChange: _propTypes2['default'].func,
  
  		// input keyDown handler: function (event) {}
  		onInputKeyDown: _propTypes2['default'].func,
  
  		// new option click handler: function (option) {}
  		onNewOptionClick: _propTypes2['default'].func,
  
  		// See Select.propTypes.options
  		options: _propTypes2['default'].array,
  
  		// Creates prompt/placeholder option text.
  		// (filterText: string): string
  		promptTextCreator: _propTypes2['default'].func,
  
  		// Decides if a keyDown event (eg its `keyCode`) should result in the creation of a new option.
  		shouldKeyDownEventCreateNewOption: _propTypes2['default'].func
  	},
  
  	// Default prop methods
  	statics: {
  		isOptionUnique: isOptionUnique,
  		isValidNewOption: isValidNewOption,
  		newOptionCreator: newOptionCreator,
  		promptTextCreator: promptTextCreator,
  		shouldKeyDownEventCreateNewOption: shouldKeyDownEventCreateNewOption
  	},
  
  	getDefaultProps: function getDefaultProps() {
  		return {
  			filterOptions: _utilsDefaultFilterOptions2['default'],
  			isOptionUnique: isOptionUnique,
  			isValidNewOption: isValidNewOption,
  			menuRenderer: _utilsDefaultMenuRenderer2['default'],
  			newOptionCreator: newOptionCreator,
  			promptTextCreator: promptTextCreator,
  			shouldKeyDownEventCreateNewOption: shouldKeyDownEventCreateNewOption
  		};
  	},
  
  	createNewOption: function createNewOption() {
  		var _props = this.props;
  		var isValidNewOption = _props.isValidNewOption;
  		var newOptionCreator = _props.newOptionCreator;
  		var onNewOptionClick = _props.onNewOptionClick;
  		var _props$options = _props.options;
  		var options = _props$options === undefined ? [] : _props$options;
  		var shouldKeyDownEventCreateNewOption = _props.shouldKeyDownEventCreateNewOption;
  
  		if (isValidNewOption({ label: this.inputValue })) {
  			var option = newOptionCreator({ label: this.inputValue, labelKey: this.labelKey, valueKey: this.valueKey });
  			var _isOptionUnique = this.isOptionUnique({ option: option });
  
  			// Don't add the same option twice.
  			if (_isOptionUnique) {
  				if (onNewOptionClick) {
  					onNewOptionClick(option);
  				} else {
  					options.unshift(option);
  
  					this.select.selectValue(option);
  				}
  			}
  		}
  	},
  
  	filterOptions: function filterOptions() {
  		var _props2 = this.props;
  		var filterOptions = _props2.filterOptions;
  		var isValidNewOption = _props2.isValidNewOption;
  		var options = _props2.options;
  		var promptTextCreator = _props2.promptTextCreator;
  
  		// TRICKY Check currently selected options as well.
  		// Don't display a create-prompt for a value that's selected.
  		// This covers async edge-cases where a newly-created Option isn't yet in the async-loaded array.
  		var excludeOptions = arguments[2] || [];
  
  		var filteredOptions = filterOptions.apply(undefined, arguments) || [];
  
  		if (isValidNewOption({ label: this.inputValue })) {
  			var _newOptionCreator = this.props.newOptionCreator;
  
  			var option = _newOptionCreator({
  				label: this.inputValue,
  				labelKey: this.labelKey,
  				valueKey: this.valueKey
  			});
  
  			// TRICKY Compare to all options (not just filtered options) in case option has already been selected).
  			// For multi-selects, this would remove it from the filtered list.
  			var _isOptionUnique2 = this.isOptionUnique({
  				option: option,
  				options: excludeOptions.concat(filteredOptions)
  			});
  
  			if (_isOptionUnique2) {
  				var _prompt = promptTextCreator(this.inputValue);
  
  				this._createPlaceholderOption = _newOptionCreator({
  					label: _prompt,
  					labelKey: this.labelKey,
  					valueKey: this.valueKey
  				});
  
  				filteredOptions.unshift(this._createPlaceholderOption);
  			}
  		}
  
  		return filteredOptions;
  	},
  
  	isOptionUnique: function isOptionUnique(_ref2) {
  		var option = _ref2.option;
  		var options = _ref2.options;
  		var isOptionUnique = this.props.isOptionUnique;
  
  		options = options || this.select.filterOptions();
  
  		return isOptionUnique({
  			labelKey: this.labelKey,
  			option: option,
  			options: options,
  			valueKey: this.valueKey
  		});
  	},
  
  	menuRenderer: function menuRenderer(params) {
  		var menuRenderer = this.props.menuRenderer;
  
  		return menuRenderer(_extends({}, params, {
  			onSelect: this.onOptionSelect,
  			selectValue: this.onOptionSelect
  		}));
  	},
  
  	onInputChange: function onInputChange(input) {
  		var onInputChange = this.props.onInputChange;
  
  		if (onInputChange) {
  			onInputChange(input);
  		}
  
  		// This value may be needed in between Select mounts (when this.select is null)
  		this.inputValue = input;
  	},
  
  	onInputKeyDown: function onInputKeyDown(event) {
  		var _props3 = this.props;
  		var shouldKeyDownEventCreateNewOption = _props3.shouldKeyDownEventCreateNewOption;
  		var onInputKeyDown = _props3.onInputKeyDown;
  
  		var focusedOption = this.select.getFocusedOption();
  
  		if (focusedOption && focusedOption === this._createPlaceholderOption && shouldKeyDownEventCreateNewOption({ keyCode: event.keyCode })) {
  			this.createNewOption();
  
  			// Prevent decorated Select from doing anything additional with this keyDown event
  			event.preventDefault();
  		} else if (onInputKeyDown) {
  			onInputKeyDown(event);
  		}
  	},
  
  	onOptionSelect: function onOptionSelect(option, event) {
  		if (option === this._createPlaceholderOption) {
  			this.createNewOption();
  		} else {
  			this.select.selectValue(option);
  		}
  	},
  
  	focus: function focus() {
  		this.select.focus();
  	},
  
  	render: function render() {
  		var _this = this;
  
  		var _props4 = this.props;
  		var newOptionCreator = _props4.newOptionCreator;
  		var shouldKeyDownEventCreateNewOption = _props4.shouldKeyDownEventCreateNewOption;
  
  		var restProps = _objectWithoutProperties(_props4, ['newOptionCreator', 'shouldKeyDownEventCreateNewOption']);
  
  		var children = this.props.children;
  
  		// We can't use destructuring default values to set the children,
  		// because it won't apply work if `children` is null. A falsy check is
  		// more reliable in real world use-cases.
  		if (!children) {
  			children = defaultChildren;
  		}
  
  		var props = _extends({}, restProps, {
  			allowCreate: true,
  			filterOptions: this.filterOptions,
  			menuRenderer: this.menuRenderer,
  			onInputChange: this.onInputChange,
  			onInputKeyDown: this.onInputKeyDown,
  			ref: function ref(_ref) {
  				_this.select = _ref;
  
  				// These values may be needed in between Select mounts (when this.select is null)
  				if (_ref) {
  					_this.labelKey = _ref.props.labelKey;
  					_this.valueKey = _ref.props.valueKey;
  				}
  			}
  		});
  
  		return children(props);
  	}
  });
  
  function defaultChildren(props) {
  	return _react2['default'].createElement(_Select2['default'], props);
  };
  
  function isOptionUnique(_ref3) {
  	var option = _ref3.option;
  	var options = _ref3.options;
  	var labelKey = _ref3.labelKey;
  	var valueKey = _ref3.valueKey;
  
  	return options.filter(function (existingOption) {
  		return existingOption[labelKey] === option[labelKey] || existingOption[valueKey] === option[valueKey];
  	}).length === 0;
  };
  
  function isValidNewOption(_ref4) {
  	var label = _ref4.label;
  
  	return !!label;
  };
  
  function newOptionCreator(_ref5) {
  	var label = _ref5.label;
  	var labelKey = _ref5.labelKey;
  	var valueKey = _ref5.valueKey;
  
  	var option = {};
  	option[valueKey] = label;
  	option[labelKey] = label;
  	option.className = 'Select-create-option-placeholder';
  	return option;
  };
  
  function promptTextCreator(label) {
  	return 'Create option "' + label + '"';
  }
  
  function shouldKeyDownEventCreateNewOption(_ref6) {
  	var keyCode = _ref6.keyCode;
  
  	switch (keyCode) {
  		case 9: // TAB
  		case 13: // ENTER
  		case 188:
  			// COMMA
  			return true;
  	}
  
  	return false;
  };
  
  module.exports = Creatable;