office-ui-fabric-react
Version:
Reusable React components for building experiences for Office 365.
273 lines • 13.2 kB
JavaScript
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