UNPKG

backpack-ui

Version:
1,004 lines (853 loc) 32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _promise = require("babel-runtime/core-js/promise"); var _promise2 = _interopRequireDefault(_promise); var _regenerator = require("babel-runtime/regenerator"); var _regenerator2 = _interopRequireDefault(_regenerator); var _slicedToArray2 = require("babel-runtime/helpers/slicedToArray"); var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); var _asyncToGenerator2 = require("babel-runtime/helpers/asyncToGenerator"); var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); var _getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of"); var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck"); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn"); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _createClass2 = require("babel-runtime/helpers/createClass"); var _createClass3 = _interopRequireDefault(_createClass2); var _inherits2 = require("babel-runtime/helpers/inherits"); var _inherits3 = _interopRequireDefault(_inherits2); var _react = require("react"); var _react2 = _interopRequireDefault(_react); var _propTypes = require("prop-types"); var _propTypes2 = _interopRequireDefault(_propTypes); var _fuzzy = require("fuzzy"); var _fuzzy2 = _interopRequireDefault(_fuzzy); var _radium = require("radium"); var _styles = require("./styles"); var _styles2 = _interopRequireDefault(_styles); var _typeaheadDropdown = require("./typeaheadDropdown"); var _typeaheadDropdown2 = _interopRequireDefault(_typeaheadDropdown); var _typeaheadStatus = require("./typeaheadStatus"); var _typeaheadStatus2 = _interopRequireDefault(_typeaheadStatus); var _createClassList = require("./utils/createClassList"); var _createClassList2 = _interopRequireDefault(_createClassList); var _accessor = require("./utils/accessor"); var _accessor2 = _interopRequireDefault(_accessor); var _keyEvent = require("./utils/keyEvent"); var _keyEvent2 = _interopRequireDefault(_keyEvent); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A "typeahead", an auto-completing text input * * Renders an text input that shows options nearby that you can use the * keyboard or mouse to select. Requires CSS for MASSIVE DAMAGE. */ var count = 0; var Typeahead = function (_Component) { (0, _inherits3.default)(Typeahead, _Component); (0, _createClass3.default)(Typeahead, null, [{ key: "getInstanceCount", value: function getInstanceCount() { return ++count; // eslint-disable-line no-plusplus } }]); function Typeahead(props) { (0, _classCallCheck3.default)(this, Typeahead); var _this = (0, _possibleConstructorReturn3.default)(this, (Typeahead.__proto__ || (0, _getPrototypeOf2.default)(Typeahead)).call(this, props)); _this.state = { // The options matching the entry value // searchResults: this.getOptionsForValue(props.initialValue, props.options), searchResults: [], // This should be called something else, "entryValue" entryValue: props.value || props.initialValue, // A valid typeahead value selection: props.value, // Index of the selection selectionIndex: null, // Keep track of the focus state of the input element, to determine // whether to show options when empty (if showOptionsWhenEmpty is true) isFocused: false, // true when focused, false onOptionSelected showResults: false, isDropdownVisible: false }; _this.previousInputValue = null; _this.onKeyUp = _this.onKeyUp.bind(_this); _this.onMouseOver = _this.onMouseOver.bind(_this); _this.onMouseOut = _this.onMouseOut.bind(_this); _this.onEnter = _this.onEnter.bind(_this); _this.onEscape = _this.onEscape.bind(_this); _this.onBackspace = _this.onBackspace.bind(_this); _this.onTab = _this.onTab.bind(_this); _this.onChange = _this.onChange.bind(_this); _this.onKeyDown = _this.onKeyDown.bind(_this); _this.onFocus = _this.onFocus.bind(_this); _this.onBlur = _this.onBlur.bind(_this); _this.onOptionSelected = _this.onOptionSelected.bind(_this); _this.onTextEntryUpdated = _this.onTextEntryUpdated.bind(_this); _this.getOptionsForValue = _this.getOptionsForValue.bind(_this); _this.setEntryText = _this.setEntryText.bind(_this); _this.getSelection = _this.getSelection.bind(_this); _this.getCustomValue = _this.getCustomValue.bind(_this); _this.setSelectedIndex = _this.setSelectedIndex.bind(_this); _this.showDropdown = _this.showDropdown.bind(_this); _this.hideDropdown = _this.hideDropdown.bind(_this); _this.focus = _this.focus.bind(_this); _this.hasCustomValue = _this.hasCustomValue.bind(_this); _this.countTruncatedResults = _this.countTruncatedResults.bind(_this); _this.areResultsTruncated = _this.areResultsTruncated.bind(_this); _this.resultsTruncatedMessage = _this.resultsTruncatedMessage.bind(_this); _this.handleWindowClose = _this.handleWindowClose.bind(_this); _this.hasHint = _this.hasHint.bind(_this); _this.generateSearchFunction = _this.generateSearchFunction.bind(_this); _this.shouldSkipSearch = _this.shouldSkipSearch.bind(_this); _this.eventMap = _this.eventMap.bind(_this); _this.nav = _this.nav.bind(_this); _this.navDown = _this.navDown.bind(_this); _this.navUp = _this.navUp.bind(_this); _this.renderIncrementalSearchResults = _this.renderIncrementalSearchResults.bind(_this); _this.renderHiddenInput = _this.renderHiddenInput.bind(_this); _this.renderAriaMessageForOptions = _this.renderAriaMessageForOptions.bind(_this); _this.renderAriaMessageForIncomingOptions = _this.renderAriaMessageForIncomingOptions.bind(_this); return _this; } (0, _createClass3.default)(Typeahead, [{ key: "componentWillMount", value: function componentWillMount() { var uniqueId = Typeahead.getInstanceCount(); this.activeDescendantId = "typeaheadActiveDescendant-" + uniqueId; this.optionsId = "typeaheadOptions-" + uniqueId; } }, { key: "componentDidMount", value: function componentDidMount() { if (typeof window !== "undefined") { // The `focus` event does not bubble, so we must capture it instead. // This closes Typeahead's dropdown whenever something else gains focus. window.addEventListener("focus", this.handleWindowClose, true); // If we click anywhere outside of Typeahead, close the dropdown. window.addEventListener("click", this.handleWindowClose, false); } } }, { key: "componentWillReceiveProps", value: function componentWillReceiveProps(nextProps) { var options = nextProps.options; var entryValue = this.state.entryValue; this.setState({ searchResults: this.getOptionsForValue(entryValue, options) }); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { var entryValue = this.state.entryValue; if (entryValue !== prevState.entryValue && !prevState.isDropdownVisible) { this.showDropdown(); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (typeof window !== "undefined") { window.removeEventListener("focus", this.handleWindowClose, true); window.removeEventListener("click", this.handleWindowClose, false); } } }, { key: "onMouseOver", value: function onMouseOver(event, index) { this.setState({ selectionIndex: index }); } }, { key: "onMouseOut", value: function onMouseOut() { this.setState({ selectionIndex: null }); } }, { key: "onKeyUp", value: function onKeyUp(e) { var _this2 = this; var query = e.target.value; clearTimeout(this.searchTimer); if (this.props.validate) { this.props.validate(query, this.state.searchResults); } if (e.key === "Backspace" && query === "") { return; } if (e.key !== "Enter" && e.key !== "ArrowUp" && e.key !== "ArrowDown") { this.searchTimer = setTimeout(function () { _this2.props.dataSource(query).then(function (json) { var results = []; if (_this2.props.filterResults) { results = _this2.props.filterResults(json); } else { results = json.places.map(function (place) { return place.attributes.name; }); } if (_this2.props.validate) { _this2.props.validate(query, results); } _this2.props.onKeyUp(json.places); _this2.setState({ searchResults: results }); }); }, 200); } } }, { key: "onEnter", value: function onEnter(event) { var selection = this.getSelection(); if (!selection) { return this.props.onKeyDown(event); } return this.onOptionSelected(event, selection); } }, { key: "onEscape", value: function onEscape() { this.setState({ isDropdownVisible: false, selectionIndex: null }); } }, { key: "onBackspace", value: function onBackspace() { if (this.state.selectionIndex !== null) { this.setState({ selectionIndex: null }); } } }, { key: "onTab", value: function onTab(event) { var option = this.getSelection(); if (!option && this.hasCustomValue()) { option = this.getCustomValue(); } if (option) { return this.onOptionSelected(event, option); } return null; } }, { key: "onChange", value: function onChange(event) { if (this.props.onChange) { this.props.onChange(event); } this.onTextEntryUpdated(); } }, { key: "onKeyDown", value: function onKeyDown(event) { /** * If there are no visible elements, don't perform selector * navigation. Just pass this up to the upstream onKeydown handler. * Also skip if the user is pressing the shift key, since none of * our handlers are looking for shift */ if (!this.hasHint() || event.shiftKey) { return this.props.onKeyDown(event); } var handler = this.eventMap()[event.keyCode]; if (handler) { handler(event); } else { return this.props.onKeyDown(event); } // Don't propagate the keystroke back to the DOM/browser if (event.keyCode !== _keyEvent2.default.DOM_VK_BACKSPACE && event.keyCode !== _keyEvent2.default.DOM_VK_TAB) { event.preventDefault(); } return null; } }, { key: "onFocus", value: function onFocus(event) { var _this3 = this; this.setState({ isFocused: true, showResults: true, isDropdownVisible: true }, function () { _this3.onTextEntryUpdated(); }); if (this.props.onFocus) { return this.props.onFocus(event); } return null; } }, { key: "onBlur", value: function () { var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(event) { var _this4 = this; var thereAreSearchResults, thereIsInput, noSpecificSelectionIsPending, insertFirstSearchResult, _state$searchResults, option, optionString; return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: this.setState({ isFocused: false }, function () { _this4.onTextEntryUpdated(); }); thereAreSearchResults = this.state.searchResults.length > 0; thereIsInput = event.target.value !== ""; /** * If the user is not hovering or arrow-keying over any particular option, we may safely * select the topmost option among the search results. It'll either be the one * that they've already selected, or they otherwise are not disclosing any specific preference. */ noSpecificSelectionIsPending = [null, -1].includes(this.state.selectionIndex); insertFirstSearchResult = [this.props.forceSelection, noSpecificSelectionIsPending, thereAreSearchResults, thereIsInput].every(Boolean); if (!insertFirstSearchResult) { _context.next = 12; break; } // Force selection of the first search result. _state$searchResults = (0, _slicedToArray3.default)(this.state.searchResults, 1), option = _state$searchResults[0]; optionString = this.displayOption(option, 0); _context.next = 10; return this.setSelectedOption(option); case 10: if (this.props.validate) { this.props.validate(optionString, this.state.searchResults); } this.props.onOptionSelected(event, option); case 12: if (!this.props.onBlur) { _context.next = 14; break; } return _context.abrupt("return", this.props.onBlur(event)); case 14: return _context.abrupt("return", null); case 15: case "end": return _context.stop(); } } }, _callee, this); })); function onBlur(_x) { return _ref.apply(this, arguments); } return onBlur; }() }, { key: "onOptionSelected", value: function onOptionSelected(event, option) { var optionString = this.displayOption(option, 0); this.inputElement.focus(); this.setSelectedOption(option); this.inputElement.blur(); if (this.props.validate) { this.props.validate(optionString, this.state.searchResults); } return this.props.onOptionSelected(event, option); } }, { key: "onTextEntryUpdated", value: function onTextEntryUpdated() { var options = this.props.options; var value = this.inputElement.value; this.setState({ searchResults: this.getOptionsForValue(value, options), selection: "", entryValue: value }); } }, { key: "setSelectedOption", value: function () { var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(option) { var _this5 = this; var optionString, formInputOptionString, results; return _regenerator2.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: optionString = this.displayOption(option, 0); formInputOptionString = this.formInputOption(option); this.inputElement.value = optionString; results = this.getOptionsForValue(optionString, this.props.options); _context2.next = 6; return new _promise2.default(function (resolve) { _this5.setState({ searchResults: results, selection: formInputOptionString, selectionIndex: results.indexOf(optionString), entryValue: optionString, showResults: false }, resolve); }); case 6: case "end": return _context2.stop(); } } }, _callee2, this); })); function setSelectedOption(_x2) { return _ref2.apply(this, arguments); } return setSelectedOption; }() }, { key: "getOptionsForValue", value: function getOptionsForValue(value, options) { if (this.shouldSkipSearch(value)) { return []; } var searchOptions = this.generateSearchFunction(); return searchOptions(value, options); } }, { key: "setEntryText", value: function setEntryText(value) { this.inputElement.value = value; this.onTextEntryUpdated(); } }, { key: "getSelection", value: function getSelection() { var index = this.state.selectionIndex; if (this.hasCustomValue()) { if (index === 0) { return this.state.entryValue; } index -= 1; } return this.state.searchResults[index]; } }, { key: "getCustomValue", value: function getCustomValue() { var entryValue = this.state.entryValue; if (this.hasCustomValue()) { return entryValue; } return null; } }, { key: "setSelectedIndex", value: function setSelectedIndex(index, callback) { this.setState({ selectionIndex: index }, callback); } }, { key: "showDropdown", value: function showDropdown() { this.setState({ isDropdownVisible: true }); } }, { key: "hideDropdown", value: function hideDropdown() { this.setState({ isDropdownVisible: false }); } }, { key: "focus", value: function focus() { this.inputElement.focus(); } }, { key: "hasCustomValue", value: function hasCustomValue() { var allowCustomValues = this.props.allowCustomValues; var _state = this.state, entryValue = _state.entryValue, searchResults = _state.searchResults; if (allowCustomValues > 0 && entryValue.length >= allowCustomValues && searchResults.indexOf(entryValue) < 0) { return true; } return false; } }, { key: "countTruncatedResults", value: function countTruncatedResults() { var maxVisible = this.props.maxVisible; var searchResults = this.state.searchResults; return parseInt(searchResults.length, 10) - parseInt(maxVisible, 10); } }, { key: "areResultsTruncated", value: function areResultsTruncated() { var maxVisible = this.props.maxVisible; var searchResults = this.state.searchResults; return !!maxVisible && searchResults.length > maxVisible; } }, { key: "resultsTruncatedMessage", value: function resultsTruncatedMessage() { var areResultsTruncated = this.areResultsTruncated(); var countTruncatedResults = this.countTruncatedResults(); var message = this.props.resultsTruncatedMessage; return areResultsTruncated ? message || "There are " + countTruncatedResults + " more results." : ""; } }, { key: "handleWindowClose", value: function handleWindowClose(event) { var target = event.target; if (target !== window && !this.typeahead.contains(target)) { this.hideDropdown(); } } }, { key: "hasHint", value: function hasHint() { return this.state.searchResults.length > 0 || this.hasCustomValue(); } }, { key: "generateSearchFunction", value: function generateSearchFunction() { var _props = this.props, searchOptions = _props.searchOptions, filterOption = _props.filterOption; if (typeof searchOptions === "function") { return searchOptions; } else if (typeof filterOption === "function") { return function (value, options) { return options.filter(function (o) { return filterOption(value, o); }); }; } var mapper = void 0; if (typeof filterOption === "string") { mapper = _accessor2.default.generateAccessor(filterOption); } else { mapper = _accessor2.default.identityFunction; } return function (value, options) { return _fuzzy2.default.filter(value, options, { extract: mapper }).map(function (res) { return options[res.index]; }); }; } }, { key: "shouldSkipSearch", value: function shouldSkipSearch(input) { var showOptionsWhenEmpty = this.props.showOptionsWhenEmpty; var isFocused = this.state.isFocused; var emptyValue = !input || input.trim().length === 0; return !(showOptionsWhenEmpty && isFocused) && emptyValue; } }, { key: "eventMap", value: function eventMap() { var events = {}; events[_keyEvent2.default.DOM_VK_UP] = this.navUp; events[_keyEvent2.default.DOM_VK_DOWN] = this.navDown; events[_keyEvent2.default.DOM_VK_RETURN] = this.onEnter; events[_keyEvent2.default.DOM_VK_ENTER] = this.onEnter; events[_keyEvent2.default.DOM_VK_ESCAPE] = this.onEscape; events[_keyEvent2.default.DOM_VK_BACKSPACE] = this.onBackspace; events[_keyEvent2.default.DOM_VK_TAB] = this.onTab; return events; } }, { key: "nav", value: function nav(delta) { if (!this.hasHint()) { return; } var setIndex = delta === 1 ? 0 : delta; var newIndex = this.state.selectionIndex === null ? setIndex : this.state.selectionIndex + delta; var length = this.props.maxVisible ? this.state.searchResults.slice(0, this.props.maxVisible).length : this.state.searchResults.length; if (this.hasCustomValue()) { length += 1; } if (newIndex < 0) { newIndex += length; } else if (newIndex >= length) { newIndex -= length; } this.setState({ selectionIndex: newIndex, entryValue: this.state.searchResults[newIndex] }); } }, { key: "navDown", value: function navDown() { if (this.state.isDropdownVisible) { this.nav(1); } else { this.showDropdown(); } } }, { key: "navUp", value: function navUp() { if (this.state.isDropdownVisible) { this.nav(-1); } else { this.showDropdown(); } } }, { key: "renderIncrementalSearchResults", value: function renderIncrementalSearchResults() { var _this6 = this; // Nothing has been entered into the textbox if (this.shouldSkipSearch(this.state.entryValue)) { return ""; } // Something was just selected if (this.state.selection) { return ""; } var ListComponent = this.props.customListComponent; return _react2.default.createElement(ListComponent, { ref: function ref(node) { return _this6.dropdown = node; }, id: this.optionsId, isVisible: this.state.isDropdownVisible, activeDescendantId: this.activeDescendantId, options: this.props.maxVisible ? this.state.searchResults.slice(0, this.props.maxVisible) : this.state.searchResults, areResultsTruncated: this.areResultsTruncated(), resultsTruncatedMessage: this.resultsTruncatedMessage(), onOptionSelected: this.onOptionSelected, allowCustomValues: this.props.allowCustomValues, customValue: this.getCustomValue(), customClasses: this.props.customClasses, selectionIndex: this.state.selectionIndex, disableDefaultClassNames: this.props.disableDefaultClassNames, displayOption: _accessor2.default.generateOptionToStringFor(this.props.displayOption), onMouseOver: this.onMouseOver }); } }, { key: "renderHiddenInput", value: function renderHiddenInput() { var name = this.props.name; var selection = this.state.selection; if (!name) { return null; } return _react2.default.createElement("input", { type: "hidden", name: name, value: selection }); } }, { key: "renderAriaMessageForOptions", value: function renderAriaMessageForOptions() { var inputValue = this.state.entryValue; var options = this.state.searchResults; var selectedOption = options[this.state.selectionIndex]; return _react2.default.createElement( _typeaheadStatus2.default, null, selectedOption || inputValue ); } }, { key: "renderAriaMessageForIncomingOptions", value: function renderAriaMessageForIncomingOptions() { var maxVisible = this.props.maxVisible; var searchResults = this.state.searchResults; var options = searchResults || []; var totalOptions = options.length ? options.length : 0; var numberOfSuggestions = maxVisible && maxVisible < options.length ? maxVisible : totalOptions; var suggestionText = numberOfSuggestions + " suggestion" + (numberOfSuggestions !== 1 ? "s are" : " is") + " available."; var instructionText = numberOfSuggestions > 0 ? "Use up and down arrows to select." : ""; return _react2.default.createElement( _typeaheadStatus2.default, null, suggestionText + " " + instructionText ); } }, { key: "render", value: function render() { var _this7 = this; var _props2 = this.props, className = _props2.className, customClasses = _props2.customClasses, disableDefaultClassNames = _props2.disableDefaultClassNames, textarea = _props2.textarea, disabled = _props2.disabled, placeholder = _props2.placeholder, onKeyPress = _props2.onKeyPress, autoFocus = _props2.autoFocus, required = _props2.required, inputId = _props2.inputId, inputName = _props2.inputName; var InputElement = textarea ? "textarea" : "input"; var containerClassList = (0, _createClassList2.default)(className, "typeahead", disableDefaultClassNames); var inputClassList = (0, _createClassList2.default)(customClasses.input, "input", disableDefaultClassNames); var value = this.props.value; if (this.props.forceSelection && this.props.value !== this.props.initialValue && this.state.searchResults.indexOf(this.props.value) === -1 && this.state.selectionIndex === null) { value = this.state.entryValue; } return _react2.default.createElement( "div", { className: containerClassList, ref: function ref(node) { return _this7.typeahead = node; }, onMouseOut: this.onMouseOut, style: this.props.style }, _react2.default.createElement(_radium.Style, { rules: _styles2.default }), this.renderHiddenInput(), _react2.default.createElement(InputElement, { ref: function ref(node) { return _this7.inputElement = node; }, className: inputClassList, type: "text", role: "combobox", "aria-owns": this.optionsId, "aria-controls": this.optionsId, "aria-expanded": this.state.isDropdownVisible, "aria-autocomplete": "both", "aria-activedescendant": this.activeDescendantId, autoCapitalize: "none", autoComplete: "off", autoCorrect: "off", autoFocus: autoFocus, required: required, spellCheck: false, id: inputId, name: inputName, disabled: disabled, placeholder: placeholder, value: value, onChange: this.onChange, onKeyDown: this.onKeyDown, onKeyPress: onKeyPress, onKeyUp: this.onKeyUp // eslint-disable-line react/jsx-no-bind , onFocus: this.onFocus, onBlur: this.onBlur }), this.state.showResults && this.renderIncrementalSearchResults(), this.renderAriaMessageForOptions(), this.renderAriaMessageForIncomingOptions() ); } }, { key: "displayOption", get: function get() { return _accessor2.default.generateOptionToStringFor(this.props.inputDisplayOption || this.props.displayOption); } }, { key: "formInputOption", get: function get() { return _accessor2.default.generateOptionToStringFor(this.props.formInputOption || this.displayOption); } }]); return Typeahead; }(_react.Component); Typeahead.propTypes = { name: _propTypes2.default.string, className: _propTypes2.default.string, customClasses: _propTypes2.default.shape({ hover: _propTypes2.default.string, input: _propTypes2.default.string, listAnchor: _propTypes2.default.string, listItem: _propTypes2.default.string, results: _propTypes2.default.string, resultsTruncated: _propTypes2.default.string, customAdd: _propTypes2.default.string }), dataSource: _propTypes2.default.func, maxVisible: _propTypes2.default.number, resultsTruncatedMessage: _propTypes2.default.string, options: _propTypes2.default.arrayOf(_propTypes2.default.string), allowCustomValues: _propTypes2.default.number, initialValue: _propTypes2.default.string, value: _propTypes2.default.string, placeholder: _propTypes2.default.string, disabled: _propTypes2.default.bool, textarea: _propTypes2.default.bool, inputId: _propTypes2.default.string, inputName: _propTypes2.default.string, autoFocus: _propTypes2.default.bool, required: _propTypes2.default.bool, onOptionSelected: _propTypes2.default.func, onChange: _propTypes2.default.func, onKeyDown: _propTypes2.default.func, onKeyPress: _propTypes2.default.func, onKeyUp: _propTypes2.default.func, onFocus: _propTypes2.default.func, onBlur: _propTypes2.default.func, filterResults: _propTypes2.default.func, validate: _propTypes2.default.func, forceSelection: _propTypes2.default.bool, filterOption: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.func]), searchOptions: _propTypes2.default.func, displayOption: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.func]), inputDisplayOption: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.func]), formInputOption: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.func]), disableDefaultClassNames: _propTypes2.default.bool, customListComponent: _propTypes2.default.oneOfType([_propTypes2.default.element, _propTypes2.default.func]), showOptionsWhenEmpty: _propTypes2.default.bool, style: _propTypes2.default.objectOf(_propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number, _propTypes2.default.object])) }; Typeahead.defaultProps = { options: [], className: null, customClasses: {}, allowCustomValues: 0, initialValue: "", value: "", placeholder: "", disabled: false, textarea: false, inputId: "typeaheadInput", inputName: "typeaheadInput", autoFocus: false, required: false, onOptionSelected: function onOptionSelected() {}, onChange: function onChange() {}, onKeyDown: function onKeyDown() {}, onKeyPress: function onKeyPress() {}, onKeyUp: function onKeyUp() {}, onFocus: function onFocus() {}, onBlur: function onBlur() {}, filterResults: null, validate: null, forceSelection: false, filterOption: null, searchOptions: null, inputDisplayOption: null, disableDefaultClassNames: false, customListComponent: _typeaheadDropdown2.default, showOptionsWhenEmpty: false, maxVisible: 0, displayOption: null, formInputOption: null, name: null, resultsTruncatedMessage: null, style: null, dataSource: function dataSource() { return new _promise2.default(function (resolve) { return resolve([]); }); } }; exports.default = Typeahead;