UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Office 365.

324 lines • 15 kB
import * as tslib_1 from "tslib"; import * as React from 'react'; import { BaseComponent, css, getRTL, createRef } from '../../Utilities'; import { Callout } from '../../Callout'; import { SuggestionsControl } from './Suggestions/SuggestionsControl'; import * as stylesImport from './BaseFloatingPicker.scss'; // tslint:disable-next-line:no-any var styles = stylesImport; var BaseFloatingPicker = /** @class */ (function (_super) { tslib_1.__extends(BaseFloatingPicker, _super); function BaseFloatingPicker(basePickerProps) { var _this = _super.call(this, basePickerProps) || this; _this.root = createRef(); _this.SuggestionsControlOfProperType = SuggestionsControl; _this.onQueryStringChanged = function (queryString) { if (queryString !== _this.state.queryString) { _this.setState({ queryString: queryString, moreSuggestionsAvailable: true, isMostRecentlyUsedVisible: false, }); _this.showPicker(); if (queryString === '') { _this.updateSuggestionWithZeroState(); } else { _this.updateValue(queryString); } } }; _this.hidePicker = function () { if (_this.props.onSuggestionsHidden && _this.isSuggestionsShown) { _this.props.onSuggestionsHidden(); } _this.setState({ suggestionsVisible: false, }); }; _this.showPicker = function (updateValue) { if (updateValue === void 0) { updateValue = false; } if (_this.props.onSuggestionsShown && !_this.isSuggestionsShown) { _this.props.onSuggestionsShown(); } _this.setState({ suggestionsVisible: true, }); // If updateValue AND // Either suggestionsVisible is undefined (first time the suggestions is set to visble) // OR the inputElement value is different than the query string if (updateValue && (_this.state.suggestionsVisible === undefined || (_this.props.inputElement && _this.props.inputElement.value !== _this.state.queryString))) { if (_this.state.queryString === '') { _this.updateSuggestionWithZeroState(); } else { _this.updateValue(_this.state.queryString); } } }; _this.completeSuggestion = function () { if (_this.suggestionsControl && _this.suggestionsControl.hasSuggestionSelected()) { _this.onChange(_this.suggestionsControl.currentSuggestion.item); } }; _this.onSuggestionClick = function (ev, item, index) { _this.onChange(item); }; _this.onSuggestionRemove = function (ev, item, index) { if (_this.props.onRemoveSuggestion) { _this.props.onRemoveSuggestion(item); } if (_this.suggestionsControl) { _this.suggestionsControl.removeSuggestion(index); } }; _this.onKeyDown = function (ev) { if (!_this.state.suggestionsVisible || (_this.props.inputElement && !_this.props.inputElement.contains(ev.target))) { return; } var keyCode = ev.which; switch (keyCode) { case 27 /* escape */: _this.hidePicker(); ev.preventDefault(); ev.stopPropagation(); break; case 9 /* tab */: case 13 /* enter */: if (!ev.shiftKey && !ev.ctrlKey && _this.suggestionsControl && _this.suggestionsControl.handleKeyDown(keyCode)) { ev.preventDefault(); ev.stopPropagation(); } else { _this._onValidateInput(); } break; case 46 /* del */: if (_this.props.onRemoveSuggestion && _this.suggestionsControl && _this.suggestionsControl.hasSuggestionSelected && _this.suggestionsControl.currentSuggestion) { _this.props.onRemoveSuggestion(_this.suggestionsControl.currentSuggestion.item); _this.suggestionsControl.removeSuggestion(); _this.forceUpdate(); } ev.stopPropagation(); break; case 38 /* up */: if (_this.suggestionsControl && _this.suggestionsControl.handleKeyDown(keyCode)) { ev.preventDefault(); ev.stopPropagation(); } break; case 40 /* down */: if (_this.suggestionsControl && _this.suggestionsControl.handleKeyDown(keyCode)) { ev.preventDefault(); ev.stopPropagation(); } break; } }; _this._onValidateInput = function () { if (_this.state.queryString && _this.props.onValidateInput && _this.props.createGenericItem) { var itemToConvert = _this.props.createGenericItem(_this.state.queryString, _this.props.onValidateInput(_this.state.queryString)); var convertedItems = _this.suggestionStore.convertSuggestionsToSuggestionItems([itemToConvert]); _this.onChange(convertedItems[0].item); } }; _this.suggestionStore = basePickerProps.suggestionsStore; _this.state = { queryString: '', suggestedDisplayValue: '', isMostRecentlyUsedVisible: false, moreSuggestionsAvailable: false, didBind: false, }; return _this; } Object.defineProperty(BaseFloatingPicker.prototype, "inputText", { get: function () { return this.state.queryString; }, enumerable: true, configurable: true }); Object.defineProperty(BaseFloatingPicker.prototype, "suggestions", { // tslint:disable-next-line:no-any get: function () { return this.suggestionStore.suggestions; }, enumerable: true, configurable: true }); BaseFloatingPicker.prototype.forceResolveSuggestion = function () { if (this.suggestionsControl && this.suggestionsControl.hasSuggestionSelected()) { this.completeSuggestion(); } else { this._onValidateInput(); } }; Object.defineProperty(BaseFloatingPicker.prototype, "isSuggestionsShown", { get: function () { return this.state.suggestionsVisible === undefined ? false : this.state.suggestionsVisible; }, enumerable: true, configurable: true }); BaseFloatingPicker.prototype.componentDidMount = function () { this._bindToInputElement(); this._onResolveSuggestions = this._async.debounce(this._onResolveSuggestions, this.props.resolveDelay); }; BaseFloatingPicker.prototype.componentDidUpdate = function () { this._bindToInputElement(); }; BaseFloatingPicker.prototype.componentWillUnmount = function () { this._unbindFromInputElement(); }; BaseFloatingPicker.prototype.updateSuggestions = function (suggestions, forceUpdate) { if (forceUpdate === void 0) { forceUpdate = false; } this.suggestionStore.updateSuggestions(suggestions); if (forceUpdate) { this.forceUpdate(); } }; BaseFloatingPicker.prototype.render = function () { var className = this.props.className; return (React.createElement("div", { ref: this.root, className: css('ms-BasePicker', className ? className : '') }, this.renderSuggestions())); }; BaseFloatingPicker.prototype.renderSuggestions = function () { var TypedSuggestionsControl = this.SuggestionsControlOfProperType; return this.state.suggestionsVisible ? (React.createElement(Callout, { className: styles.callout, isBeakVisible: false, gapSpace: 5, target: this.props.inputElement, onDismiss: this.hidePicker, directionalHint: getRTL() ? (6 /* bottomRightEdge */) : (4 /* bottomLeftEdge */), calloutWidth: this.props.calloutWidth ? this.props.calloutWidth : 0 }, React.createElement(TypedSuggestionsControl, tslib_1.__assign({ onRenderSuggestion: this.props.onRenderSuggestionsItem, onSuggestionClick: this.onSuggestionClick, onSuggestionRemove: this.onSuggestionRemove, suggestions: this.suggestionStore.getSuggestions(), ref: this._resolveRef('suggestionsControl'), completeSuggestion: this.completeSuggestion, shouldLoopSelection: false }, this.props.pickerSuggestionsProps)))) : null; }; BaseFloatingPicker.prototype.onSuggestionSelect = function () { if (this.suggestionsControl && this.suggestionsControl.currentSuggestion) { var currentValue = this.state.queryString; var itemValue = this._getTextFromItem(this.suggestionsControl.currentSuggestion.item, currentValue); this.setState({ suggestedDisplayValue: itemValue }); } }; BaseFloatingPicker.prototype.onSelectionChange = function () { this.forceUpdate(); }; BaseFloatingPicker.prototype.updateValue = function (updatedValue) { if (this.props.onInputChanged) { this.props.onInputChanged(updatedValue); } this._onResolveSuggestions(updatedValue); }; BaseFloatingPicker.prototype.updateSuggestionWithZeroState = function () { if (this.props.onZeroQuerySuggestion) { var onEmptyInputFocus = this.props.onZeroQuerySuggestion; var suggestions = onEmptyInputFocus(this.props.selectedItems); this.updateSuggestionsList(suggestions); } else { this.hidePicker(); } }; BaseFloatingPicker.prototype.updateSuggestionsList = function (suggestions, updatedValue) { var _this = this; var suggestionsArray = suggestions; var suggestionsPromiseLike = suggestions; // Check to see if the returned value is an array, if it is then just pass it into the next function. // If the returned value is not an array then check to see if it's a promise or PromiseLike. If it is then resolve it asynchronously. if (Array.isArray(suggestionsArray)) { if (updatedValue !== undefined) { this.resolveNewValue(updatedValue, suggestionsArray); } else { this.updateSuggestions(suggestionsArray, true /*forceUpdate*/); } } else if (suggestionsPromiseLike && suggestionsPromiseLike.then) { this.setState({ suggestionsLoading: true }); this._updateSuggestionsVisible(updatedValue !== undefined && updatedValue !== ''); // Ensure that the promise will only use the callback if it was the most recent one. var promise_1 = (this.currentPromise = suggestionsPromiseLike); promise_1.then(function (newSuggestions) { if (promise_1 === _this.currentPromise) { if (updatedValue !== undefined) { _this.resolveNewValue(updatedValue, newSuggestions); } else { _this.updateSuggestions(newSuggestions); _this.setState({ suggestionsLoading: false }); _this._updateSuggestionsVisible(newSuggestions.length > 0); } if (_this.loadingTimer) { _this._async.clearTimeout(_this.loadingTimer); _this.loadingTimer = undefined; } } }); } }; BaseFloatingPicker.prototype.resolveNewValue = function (updatedValue, suggestions) { this.updateSuggestions(suggestions); var itemValue = undefined; if (this.suggestionsControl && this.suggestionsControl.currentSuggestion) { itemValue = this._getTextFromItem(this.suggestionsControl.currentSuggestion.item, updatedValue); } this.setState({ suggestionsLoading: false, suggestedDisplayValue: itemValue }); this._updateSuggestionsVisible(updatedValue !== ''); }; BaseFloatingPicker.prototype.onChange = function (item) { if (this.props.onChange) { this.props.onChange(item); } }; BaseFloatingPicker.prototype._onResolveSuggestions = function (updatedValue) { var suggestions = this.props.onResolveSuggestions(updatedValue, this.props.selectedItems); if (suggestions !== null) { this.updateSuggestionsList(suggestions, updatedValue); } }; BaseFloatingPicker.prototype._getTextFromItem = function (item, currentValue) { if (this.props.getTextFromItem) { return this.props.getTextFromItem(item, currentValue); } else { return ''; } }; BaseFloatingPicker.prototype._updateSuggestionsVisible = function (shouldShow) { if (shouldShow) { this.showPicker(); } else { this.hidePicker(); } }; BaseFloatingPicker.prototype._bindToInputElement = function () { if (this.props.inputElement && !this.state.didBind) { this.props.inputElement.addEventListener('keydown', this.onKeyDown); this.setState({ didBind: true }); } }; BaseFloatingPicker.prototype._unbindFromInputElement = function () { if (this.props.inputElement && this.state.didBind) { this.props.inputElement.removeEventListener('keydown', this.onKeyDown); this.setState({ didBind: false }); } }; return BaseFloatingPicker; }(BaseComponent)); export { BaseFloatingPicker }; //# sourceMappingURL=BaseFloatingPicker.js.map