|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707 |
- 'use strict';
-
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
-
- var _extends2 = require('babel-runtime/helpers/extends');
-
- var _extends3 = _interopRequireDefault(_extends2);
-
- var _typeof2 = require('babel-runtime/helpers/typeof');
-
- var _typeof3 = _interopRequireDefault(_typeof2);
-
- var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
-
- var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
-
- 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 _createClass2 = require('babel-runtime/helpers/createClass');
-
- var _createClass3 = _interopRequireDefault(_createClass2);
-
- var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
-
- var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
-
- var _inherits2 = require('babel-runtime/helpers/inherits');
-
- var _inherits3 = _interopRequireDefault(_inherits2);
-
- var _simpleAssign = require('simple-assign');
-
- var _simpleAssign2 = _interopRequireDefault(_simpleAssign);
-
- var _react = require('react');
-
- var _react2 = _interopRequireDefault(_react);
-
- var _propTypes = require('prop-types');
-
- var _propTypes2 = _interopRequireDefault(_propTypes);
-
- var _reactDom = require('react-dom');
-
- var _reactDom2 = _interopRequireDefault(_reactDom);
-
- var _keycode = require('keycode');
-
- var _keycode2 = _interopRequireDefault(_keycode);
-
- var _TextField = require('../TextField');
-
- var _TextField2 = _interopRequireDefault(_TextField);
-
- var _Menu = require('../Menu');
-
- var _Menu2 = _interopRequireDefault(_Menu);
-
- var _MenuItem = require('../MenuItem');
-
- var _MenuItem2 = _interopRequireDefault(_MenuItem);
-
- var _Divider = require('../Divider');
-
- var _Divider2 = _interopRequireDefault(_Divider);
-
- var _Popover = require('../Popover/Popover');
-
- var _Popover2 = _interopRequireDefault(_Popover);
-
- var _propTypes3 = require('../utils/propTypes');
-
- var _propTypes4 = _interopRequireDefault(_propTypes3);
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- function getStyles(props, context, state) {
- var anchorEl = state.anchorEl;
- var fullWidth = props.fullWidth;
-
-
- var styles = {
- root: {
- display: 'inline-block',
- position: 'relative',
- width: fullWidth ? '100%' : 256
- },
- menu: {
- width: '100%'
- },
- list: {
- display: 'block',
- width: fullWidth ? '100%' : 256
- },
- innerDiv: {
- overflow: 'hidden'
- }
- };
-
- if (anchorEl && fullWidth) {
- styles.popover = {
- width: anchorEl.clientWidth
- };
- }
-
- return styles;
- }
-
- var AutoComplete = function (_Component) {
- (0, _inherits3.default)(AutoComplete, _Component);
-
- function AutoComplete() {
- var _ref;
-
- var _temp, _this, _ret;
-
- (0, _classCallCheck3.default)(this, AutoComplete);
-
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
-
- return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, (_ref = AutoComplete.__proto__ || (0, _getPrototypeOf2.default)(AutoComplete)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
- anchorEl: null,
- focusTextField: true,
- open: false,
- searchText: undefined
- }, _this.handleRequestClose = function () {
- // Only take into account the Popover clickAway when we are
- // not focusing the TextField.
- if (!_this.state.focusTextField) {
- _this.close();
- }
- }, _this.handleMouseDown = function (event) {
- // Keep the TextField focused
- event.preventDefault();
- }, _this.handleItemClick = function (event, child) {
- var dataSource = _this.props.dataSource;
- var index = parseInt(child.key, 10);
- var chosenRequest = dataSource[index];
- var searchText = _this.chosenRequestText(chosenRequest);
-
- var updateInput = function updateInput() {
- return _this.props.onUpdateInput(searchText, _this.props.dataSource, {
- source: 'click'
- });
- };
- _this.timerClickCloseId = function () {
- return setTimeout(function () {
- _this.timerClickCloseId = null;
- _this.close();
- _this.props.onNewRequest(chosenRequest, index);
- }, _this.props.menuCloseDelay);
- };
-
- if (typeof _this.props.searchText !== 'undefined') {
- updateInput();
- _this.timerClickCloseId();
- } else {
- _this.setState({
- searchText: searchText
- }, function () {
- updateInput();
- _this.timerClickCloseId();
- });
- }
- }, _this.chosenRequestText = function (chosenRequest) {
- if (typeof chosenRequest === 'string') {
- return chosenRequest;
- } else {
- return chosenRequest[_this.props.dataSourceConfig.text];
- }
- }, _this.handleEscKeyDown = function () {
- _this.close();
- }, _this.handleKeyDown = function (event) {
- if (_this.props.onKeyDown) _this.props.onKeyDown(event);
-
- switch ((0, _keycode2.default)(event)) {
- case 'enter':
- _this.close();
- var searchText = _this.state.searchText;
- if (searchText !== '') {
- _this.props.onNewRequest(searchText, -1);
- }
- break;
-
- case 'esc':
- _this.close();
- break;
-
- case 'down':
- event.preventDefault();
- _this.setState({
- open: true,
- focusTextField: false,
- anchorEl: _reactDom2.default.findDOMNode(_this.refs.searchTextField)
- });
- break;
-
- default:
- break;
- }
- }, _this.handleChange = function (event) {
- var searchText = event.target.value;
-
- // Make sure that we have a new searchText.
- // Fix an issue with a Cordova Webview
- if (searchText === _this.state.searchText) {
- return;
- }
-
- var state = {
- open: true,
- anchorEl: _reactDom2.default.findDOMNode(_this.refs.searchTextField)
- };
-
- if (_this.props.searchText === undefined) {
- state.searchText = searchText;
- }
-
- _this.setState(state);
-
- _this.props.onUpdateInput(searchText, _this.props.dataSource, {
- source: 'change'
- });
- }, _this.handleBlur = function (event) {
- if (_this.state.focusTextField && _this.timerClickCloseId === null) {
- _this.timerBlurClose = setTimeout(function () {
- _this.close();
- }, 0);
- }
-
- if (_this.props.onBlur) {
- _this.props.onBlur(event);
- }
- }, _this.handleFocus = function (event) {
- if (!_this.state.open && _this.props.openOnFocus) {
- _this.setState({
- open: true,
- anchorEl: _reactDom2.default.findDOMNode(_this.refs.searchTextField)
- });
- }
-
- _this.setState({
- focusTextField: true
- });
-
- if (_this.props.onFocus) {
- _this.props.onFocus(event);
- }
- }, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
- }
-
- (0, _createClass3.default)(AutoComplete, [{
- key: 'componentWillMount',
- value: function componentWillMount() {
- this.requestsList = [];
- this.setState({
- open: this.props.open,
- searchText: this.props.searchText || ''
- });
- this.timerClickCloseId = null;
- }
- }, {
- key: 'componentWillReceiveProps',
- value: function componentWillReceiveProps(nextProps) {
- if (this.props.searchText !== nextProps.searchText) {
- this.setState({
- searchText: nextProps.searchText
- });
- }
- if (this.props.open !== nextProps.open) {
- this.setState({
- open: nextProps.open,
- anchorEl: _reactDom2.default.findDOMNode(this.refs.searchTextField)
- });
- }
- }
- }, {
- key: 'componentWillUnmount',
- value: function componentWillUnmount() {
- clearTimeout(this.timerClickCloseId);
- clearTimeout(this.timerBlurClose);
- }
- }, {
- key: 'close',
- value: function close() {
- this.setState({
- open: false,
- anchorEl: null
- });
-
- if (this.props.onClose) {
- this.props.onClose();
- }
- }
- }, {
- key: 'blur',
- value: function blur() {
- this.refs.searchTextField.blur();
- }
- }, {
- key: 'focus',
- value: function focus() {
- this.refs.searchTextField.focus();
- }
- }, {
- key: 'render',
- value: function render() {
- var _this2 = this;
-
- var _props = this.props,
- anchorOrigin = _props.anchorOrigin,
- animated = _props.animated,
- animation = _props.animation,
- dataSource = _props.dataSource,
- dataSourceConfig = _props.dataSourceConfig,
- disableFocusRipple = _props.disableFocusRipple,
- errorStyle = _props.errorStyle,
- floatingLabelText = _props.floatingLabelText,
- filter = _props.filter,
- fullWidth = _props.fullWidth,
- style = _props.style,
- hintText = _props.hintText,
- maxSearchResults = _props.maxSearchResults,
- menuCloseDelay = _props.menuCloseDelay,
- textFieldStyle = _props.textFieldStyle,
- menuStyle = _props.menuStyle,
- menuProps = _props.menuProps,
- listStyle = _props.listStyle,
- targetOrigin = _props.targetOrigin,
- onBlur = _props.onBlur,
- onClose = _props.onClose,
- onFocus = _props.onFocus,
- onKeyDown = _props.onKeyDown,
- onNewRequest = _props.onNewRequest,
- onUpdateInput = _props.onUpdateInput,
- openOnFocus = _props.openOnFocus,
- popoverProps = _props.popoverProps,
- searchTextProp = _props.searchText,
- other = (0, _objectWithoutProperties3.default)(_props, ['anchorOrigin', 'animated', 'animation', 'dataSource', 'dataSourceConfig', 'disableFocusRipple', 'errorStyle', 'floatingLabelText', 'filter', 'fullWidth', 'style', 'hintText', 'maxSearchResults', 'menuCloseDelay', 'textFieldStyle', 'menuStyle', 'menuProps', 'listStyle', 'targetOrigin', 'onBlur', 'onClose', 'onFocus', 'onKeyDown', 'onNewRequest', 'onUpdateInput', 'openOnFocus', 'popoverProps', 'searchText']);
-
- var _ref2 = popoverProps || {},
- popoverStyle = _ref2.style,
- popoverOther = (0, _objectWithoutProperties3.default)(_ref2, ['style']);
-
- var _state = this.state,
- open = _state.open,
- anchorEl = _state.anchorEl,
- searchText = _state.searchText,
- focusTextField = _state.focusTextField;
- var prepareStyles = this.context.muiTheme.prepareStyles;
-
- var styles = getStyles(this.props, this.context, this.state);
-
- var requestsList = [];
-
- dataSource.every(function (item, index) {
- switch (typeof item === 'undefined' ? 'undefined' : (0, _typeof3.default)(item)) {
- case 'string':
- if (filter(searchText, item, item)) {
- requestsList.push({
- text: item,
- value: _react2.default.createElement(_MenuItem2.default, {
- innerDivStyle: styles.innerDiv,
- value: item,
- primaryText: item,
- disableFocusRipple: disableFocusRipple,
- key: index
- })
- });
- }
- break;
-
- case 'object':
- if (item && typeof item[_this2.props.dataSourceConfig.text] === 'string') {
- var itemText = item[_this2.props.dataSourceConfig.text];
- if (!_this2.props.filter(searchText, itemText, item)) break;
-
- var itemValue = item[_this2.props.dataSourceConfig.value];
- if (itemValue && itemValue.type && (itemValue.type.muiName === _MenuItem2.default.muiName || itemValue.type.muiName === _Divider2.default.muiName)) {
- requestsList.push({
- text: itemText,
- value: _react2.default.cloneElement(itemValue, {
- key: index,
- disableFocusRipple: disableFocusRipple
- })
- });
- } else {
- requestsList.push({
- text: itemText,
- value: _react2.default.createElement(_MenuItem2.default, {
- innerDivStyle: styles.innerDiv,
- primaryText: itemText,
- disableFocusRipple: disableFocusRipple,
- key: index
- })
- });
- }
- }
- break;
-
- default:
- // Do nothing
- }
-
- return !(maxSearchResults && maxSearchResults > 0 && requestsList.length === maxSearchResults);
- });
-
- this.requestsList = requestsList;
-
- var menu = open && requestsList.length > 0 && _react2.default.createElement(
- _Menu2.default,
- (0, _extends3.default)({
- ref: 'menu',
- autoWidth: false,
- disableAutoFocus: focusTextField,
- onEscKeyDown: this.handleEscKeyDown,
- initiallyKeyboardFocused: true,
- onItemClick: this.handleItemClick,
- onMouseDown: this.handleMouseDown,
- style: (0, _simpleAssign2.default)(styles.menu, menuStyle),
- listStyle: (0, _simpleAssign2.default)(styles.list, listStyle)
- }, menuProps),
- requestsList.map(function (i) {
- return i.value;
- })
- );
-
- return _react2.default.createElement(
- 'div',
- { style: prepareStyles((0, _simpleAssign2.default)(styles.root, style)) },
- _react2.default.createElement(_TextField2.default, (0, _extends3.default)({
- ref: 'searchTextField',
- autoComplete: 'off',
- onBlur: this.handleBlur,
- onFocus: this.handleFocus,
- onKeyDown: this.handleKeyDown,
- floatingLabelText: floatingLabelText,
- hintText: hintText,
- fullWidth: fullWidth,
- multiLine: false,
- errorStyle: errorStyle,
- style: textFieldStyle
- }, other, {
- // value and onChange are idiomatic properties often leaked.
- // We prevent their overrides in order to reduce potential bugs.
- value: searchText,
- onChange: this.handleChange
- })),
- _react2.default.createElement(
- _Popover2.default,
- (0, _extends3.default)({
- style: (0, _simpleAssign2.default)({}, styles.popover, popoverStyle),
- canAutoPosition: false,
- anchorOrigin: anchorOrigin,
- targetOrigin: targetOrigin,
- open: open,
- anchorEl: anchorEl,
- useLayerForClickAway: false,
- onRequestClose: this.handleRequestClose,
- animated: animated,
- animation: animation
- }, popoverOther),
- menu
- )
- );
- }
- }]);
- return AutoComplete;
- }(_react.Component);
-
- AutoComplete.defaultProps = {
- anchorOrigin: {
- vertical: 'bottom',
- horizontal: 'left'
- },
- animated: true,
- dataSourceConfig: {
- text: 'text',
- value: 'value'
- },
- disableFocusRipple: true,
- filter: function filter(searchText, key) {
- return searchText !== '' && key.indexOf(searchText) !== -1;
- },
- fullWidth: false,
- open: false,
- openOnFocus: false,
- onUpdateInput: function onUpdateInput() {},
- onNewRequest: function onNewRequest() {},
- menuCloseDelay: 300,
- targetOrigin: {
- vertical: 'top',
- horizontal: 'left'
- }
- };
- AutoComplete.contextTypes = {
- muiTheme: _propTypes2.default.object.isRequired
- };
- AutoComplete.propTypes = process.env.NODE_ENV !== "production" ? {
- /**
- * Location of the anchor for the auto complete.
- */
- anchorOrigin: _propTypes4.default.origin,
- /**
- * If true, the auto complete is animated as it is toggled.
- */
- animated: _propTypes2.default.bool,
- /**
- * Override the default animation component used.
- */
- animation: _propTypes2.default.func,
- /**
- * Array of strings or nodes used to populate the list.
- */
- dataSource: _propTypes2.default.array.isRequired,
- /**
- * Config for objects list dataSource.
- *
- * @typedef {Object} dataSourceConfig
- *
- * @property {string} text `dataSource` element key used to find a string to be matched for search
- * and shown as a `TextField` input value after choosing the result.
- * @property {string} value `dataSource` element key used to find a string to be shown in search results.
- */
- dataSourceConfig: _propTypes2.default.object,
- /**
- * Disables focus ripple when true.
- */
- disableFocusRipple: _propTypes2.default.bool,
- /**
- * Override style prop for error.
- */
- errorStyle: _propTypes2.default.object,
- /**
- * The error content to display.
- */
- errorText: _propTypes2.default.node,
- /**
- * Callback function used to filter the auto complete.
- *
- * @param {string} searchText The text to search for within `dataSource`.
- * @param {string} key `dataSource` element, or `text` property on that element if it's not a string.
- * @returns {boolean} `true` indicates the auto complete list will include `key` when the input is `searchText`.
- */
- filter: _propTypes2.default.func,
- /**
- * The content to use for adding floating label element.
- */
- floatingLabelText: _propTypes2.default.node,
- /**
- * If true, the field receives the property `width: 100%`.
- */
- fullWidth: _propTypes2.default.bool,
- /**
- * The hint content to display.
- */
- hintText: _propTypes2.default.node,
- /**
- * Override style for list.
- */
- listStyle: _propTypes2.default.object,
- /**
- * The max number of search results to be shown.
- * By default it shows all the items which matches filter.
- */
- maxSearchResults: _propTypes2.default.number,
- /**
- * Delay for closing time of the menu.
- */
- menuCloseDelay: _propTypes2.default.number,
- /**
- * Props to be passed to menu.
- */
- menuProps: _propTypes2.default.object,
- /**
- * Override style for menu.
- */
- menuStyle: _propTypes2.default.object,
- /** @ignore */
- onBlur: _propTypes2.default.func,
- /**
- * Callback function fired when the menu is closed.
- */
- onClose: _propTypes2.default.func,
- /** @ignore */
- onFocus: _propTypes2.default.func,
- /** @ignore */
- onKeyDown: _propTypes2.default.func,
- /**
- * Callback function that is fired when a list item is selected, or enter is pressed in the `TextField`.
- *
- * @param {string} chosenRequest Either the `TextField` input value, if enter is pressed in the `TextField`,
- * or the dataSource object corresponding to the list item that was selected.
- * @param {number} index The index in `dataSource` of the list item selected, or `-1` if enter is pressed in the
- * `TextField`.
- */
- onNewRequest: _propTypes2.default.func,
- /**
- * Callback function that is fired when the user updates the `TextField`.
- *
- * @param {string} searchText The auto-complete's `searchText` value.
- * @param {array} dataSource The auto-complete's `dataSource` array.
- * @param {object} params Additional information linked the update.
- */
- onUpdateInput: _propTypes2.default.func,
- /**
- * Auto complete menu is open if true.
- */
- open: _propTypes2.default.bool,
- /**
- * If true, the list item is showed when a focus event triggers.
- */
- openOnFocus: _propTypes2.default.bool,
- /**
- * Props to be passed to popover.
- */
- popoverProps: _propTypes2.default.object,
- /**
- * Text being input to auto complete.
- */
- searchText: _propTypes2.default.string,
- /**
- * Override the inline-styles of the root element.
- */
- style: _propTypes2.default.object,
- /**
- * Origin for location of target.
- */
- targetOrigin: _propTypes4.default.origin,
- /**
- * Override the inline-styles of AutoComplete's TextField element.
- */
- textFieldStyle: _propTypes2.default.object
- } : {};
-
-
- AutoComplete.levenshteinDistance = function (searchText, key) {
- var current = [];
- var prev = void 0;
- var value = void 0;
-
- for (var i = 0; i <= key.length; i++) {
- for (var j = 0; j <= searchText.length; j++) {
- if (i && j) {
- if (searchText.charAt(j - 1) === key.charAt(i - 1)) value = prev;else value = Math.min(current[j], current[j - 1], prev) + 1;
- } else {
- value = i + j;
- }
- prev = current[j];
- current[j] = value;
- }
- }
- return current.pop();
- };
-
- AutoComplete.noFilter = function () {
- return true;
- };
-
- AutoComplete.defaultFilter = AutoComplete.caseSensitiveFilter = function (searchText, key) {
- return searchText !== '' && key.indexOf(searchText) !== -1;
- };
-
- AutoComplete.caseInsensitiveFilter = function (searchText, key) {
- return key.toLowerCase().indexOf(searchText.toLowerCase()) !== -1;
- };
-
- AutoComplete.levenshteinDistanceFilter = function (distanceLessThan) {
- if (distanceLessThan === undefined) {
- return AutoComplete.levenshteinDistance;
- } else if (typeof distanceLessThan !== 'number') {
- throw 'Error: AutoComplete.levenshteinDistanceFilter is a filter generator, not a filter!';
- }
-
- return function (s, k) {
- return AutoComplete.levenshteinDistance(s, k) < distanceLessThan;
- };
- };
-
- AutoComplete.fuzzyFilter = function (searchText, key) {
- var compareString = key.toLowerCase();
- searchText = searchText.toLowerCase();
-
- var searchTextIndex = 0;
- for (var index = 0; index < key.length; index++) {
- if (compareString[index] === searchText[searchTextIndex]) {
- searchTextIndex += 1;
- }
- }
-
- return searchTextIndex === searchText.length;
- };
-
- AutoComplete.Item = _MenuItem2.default;
- AutoComplete.Divider = _Divider2.default;
-
- exports.default = AutoComplete;
|