UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Office 365.

273 lines • 13.2 kB
define(["require", "exports", "tslib", "react", "../../Utilities"], function (require, exports, tslib_1, React, Utilities_1) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var SELECTION_FORWARD = 'forward'; var SELECTION_BACKWARD = 'backward'; var Autofill = /** @class */ (function (_super) { tslib_1.__extends(Autofill, _super); function Autofill(props) { var _this = _super.call(this, props) || this; _this._autoFillEnabled = true; _this._value = ''; _this.state = { displayValue: props.defaultVisibleValue || '' }; return _this; } Object.defineProperty(Autofill.prototype, "cursorLocation", { get: function () { if (this._inputElement) { var inputElement = this._inputElement; if (inputElement.selectionDirection !== SELECTION_FORWARD) { return inputElement.selectionEnd; } else { return inputElement.selectionStart; } } else { return -1; } }, enumerable: true, configurable: true }); Object.defineProperty(Autofill.prototype, "isValueSelected", { get: function () { return this.inputElement.selectionStart !== this.inputElement.selectionEnd; }, enumerable: true, configurable: true }); Object.defineProperty(Autofill.prototype, "value", { get: function () { return this._value; }, enumerable: true, configurable: true }); Object.defineProperty(Autofill.prototype, "selectionStart", { get: function () { return this._inputElement ? this._inputElement.selectionStart : -1; }, enumerable: true, configurable: true }); Object.defineProperty(Autofill.prototype, "selectionEnd", { get: function () { return this._inputElement ? this._inputElement.selectionEnd : -1; }, enumerable: true, configurable: true }); Object.defineProperty(Autofill.prototype, "inputElement", { get: function () { return this._inputElement; }, enumerable: true, configurable: true }); Autofill.prototype.componentWillReceiveProps = function (nextProps) { var newValue; if (this.props.updateValueInWillReceiveProps) { newValue = this.props.updateValueInWillReceiveProps(); } newValue = this._getDisplayValue(newValue ? newValue : this._value, nextProps.suggestedDisplayValue); if (typeof newValue === 'string') { this.setState({ displayValue: newValue }); } }; Autofill.prototype.componentDidUpdate = function () { var value = this._value; var _a = this.props, suggestedDisplayValue = _a.suggestedDisplayValue, shouldSelectFullInputValueInComponentDidUpdate = _a.shouldSelectFullInputValueInComponentDidUpdate; var differenceIndex = 0; if (this._autoFillEnabled && value && suggestedDisplayValue && this._doesTextStartWith(suggestedDisplayValue, value)) { var shouldSelectFullRange = false; if (shouldSelectFullInputValueInComponentDidUpdate) { shouldSelectFullRange = shouldSelectFullInputValueInComponentDidUpdate(); } if (shouldSelectFullRange) { this._inputElement.setSelectionRange(0, suggestedDisplayValue.length, SELECTION_BACKWARD); } else { while (differenceIndex < value.length && value[differenceIndex].toLocaleLowerCase() === suggestedDisplayValue[differenceIndex].toLocaleLowerCase()) { differenceIndex++; } if (differenceIndex > 0) { this._inputElement.setSelectionRange(differenceIndex, suggestedDisplayValue.length, SELECTION_BACKWARD); } } } }; Autofill.prototype.render = function () { var displayValue = this.state.displayValue; var nativeProps = Utilities_1.getNativeProps(this.props, Utilities_1.inputProperties); return (React.createElement("input", tslib_1.__assign({}, nativeProps, { ref: this._resolveRef('_inputElement'), value: displayValue, autoCapitalize: 'off', autoComplete: 'off', onCompositionStart: this._onCompositionStart, onCompositionEnd: this._onCompositionEnd, onChange: this._onChange, onKeyDown: this._onKeyDown, onClick: this.props.onClick ? this.props.onClick : this._onClick, "data-lpignore": true }))); }; Autofill.prototype.focus = function () { this._inputElement.focus(); }; Autofill.prototype.clear = function () { this._autoFillEnabled = true; this._updateValue(''); this._inputElement.setSelectionRange(0, 0); }; // Composition events are used when the character/text requires several keystrokes to be completed. // Some examples of this are mobile text input and langauges like Japanese or Arabic. // Find out more at https://developer.mozilla.org/en-US/docs/Web/Events/compositionstart Autofill.prototype._onCompositionStart = function (ev) { this._autoFillEnabled = false; }; // Composition events are used when the character/text requires several keystrokes to be completed. // Some examples of this are mobile text input and langauges like Japanese or Arabic. // Find out more at https://developer.mozilla.org/en-US/docs/Web/Events/compositionstart Autofill.prototype._onCompositionEnd = function (ev) { var _this = this; var inputValue = this._getCurrentInputValue(); this._tryEnableAutofill(inputValue, this.value, false, true); // Due to timing, this needs to be async, otherwise no text will be selected. this._async.setTimeout(function () { return _this._updateValue(inputValue); }, 0); }; Autofill.prototype._onClick = function () { if (this._value && this._value !== '' && this._autoFillEnabled) { this._autoFillEnabled = false; } }; Autofill.prototype._onKeyDown = function (ev) { if (this.props.onKeyDown) { this.props.onKeyDown(ev); } // If the event is actively being composed, then don't alert autofill. // Right now typing does not have isComposing, once that has been fixed any should be removed. if (!ev.nativeEvent.isComposing) { switch (ev.which) { case 8 /* backspace */: this._autoFillEnabled = false; break; case 37 /* left */: case 39 /* right */: if (this._autoFillEnabled) { this._value = this.state.displayValue; this._autoFillEnabled = false; } break; default: if (!this._autoFillEnabled) { if (this.props.enableAutofillOnKeyPress.indexOf(ev.which) !== -1) { this._autoFillEnabled = true; } } break; } } }; Autofill.prototype._onChange = function (ev) { var value = this._getCurrentInputValue(ev); // Right now typing does not have isComposing, once that has been fixed any should be removed. this._tryEnableAutofill(value, this._value, ev.nativeEvent.isComposing); this._updateValue(value); }; Autofill.prototype._getCurrentInputValue = function (ev) { if (ev && ev.target && ev.target.value) { return ev.target.value; } else { return this._inputElement.value; } }; /** * Attempts to enable autofill. Whether or not autofill is enabled depends on the input value, * whether or not any text is selected, and only if the new input value is longer than the old input value. * Autofill should never be set to true if the value is composing. Once compositionEnd is called, then * it should be completed. * See https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent for more information on composition. * @param newValue * @param oldValue * @param isComposing if true then the text is actively being composed and it has not completed. * @param isComposed if the text is a composed text value. */ Autofill.prototype._tryEnableAutofill = function (newValue, oldValue, isComposing, isComposed) { if (!isComposing && newValue && this._inputElement.selectionStart === newValue.length && !this._autoFillEnabled && (newValue.length > oldValue.length || isComposed)) { this._autoFillEnabled = true; } }; Autofill.prototype._notifyInputChange = function (newValue) { if (this.props.onInputValueChange) { this.props.onInputValueChange(newValue); } }; /** * Updates the current input value as well as getting a new display value. * @param newValue The new value from the input */ Autofill.prototype._updateValue = function (newValue) { var _this = this; this._value = this.props.onInputChange ? this.props.onInputChange(newValue) : newValue; this.setState({ displayValue: this._getDisplayValue(this._value, this.props.suggestedDisplayValue) }, function () { return _this._notifyInputChange(_this._value); }); }; /** * Returns a string that should be used as the display value. * It evaluates this based on whether or not the suggested value starts with the input value * and whether or not autofill is enabled. * @param inputValue the value that the input currently has. * @param suggestedDisplayValue the possible full value */ Autofill.prototype._getDisplayValue = function (inputValue, suggestedDisplayValue) { var displayValue = inputValue; if (suggestedDisplayValue && inputValue && this._doesTextStartWith(suggestedDisplayValue, displayValue) && this._autoFillEnabled) { displayValue = suggestedDisplayValue; } return displayValue; }; Autofill.prototype._doesTextStartWith = function (text, startWith) { if (!text || !startWith) { return false; } return text.toLocaleLowerCase().indexOf(startWith.toLocaleLowerCase()) === 0; }; Autofill.defaultProps = { enableAutofillOnKeyPress: [40 /* down */, 38 /* up */] }; tslib_1.__decorate([ Utilities_1.autobind ], Autofill.prototype, "_onCompositionStart", null); tslib_1.__decorate([ Utilities_1.autobind ], Autofill.prototype, "_onCompositionEnd", null); tslib_1.__decorate([ Utilities_1.autobind ], Autofill.prototype, "_onClick", null); tslib_1.__decorate([ Utilities_1.autobind ], Autofill.prototype, "_onKeyDown", null); tslib_1.__decorate([ Utilities_1.autobind ], Autofill.prototype, "_onChange", null); tslib_1.__decorate([ Utilities_1.autobind ], Autofill.prototype, "_updateValue", null); return Autofill; }(Utilities_1.BaseComponent)); exports.Autofill = Autofill; /** * Legacy, @deprecated, do not use. */ var BaseAutoFill = /** @class */ (function (_super) { tslib_1.__extends(BaseAutoFill, _super); function BaseAutoFill() { return _super !== null && _super.apply(this, arguments) || this; } return BaseAutoFill; }(Autofill)); exports.BaseAutoFill = BaseAutoFill; }); //# sourceMappingURL=Autofill.js.map