@syncfusion/ej2-inputs
Version:
A package of Essential JS 2 input components such as Textbox, Color-picker, Masked-textbox, Numeric-textbox, Slider, Upload, and Form-validator that is used to get input from the users.
520 lines (519 loc) • 26.7 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
///<reference path='../textarea/textarea-model.d.ts'/>
import { EventHandler, Property, createElement } from '@syncfusion/ej2-base';
import { TextArea } from '../textarea/textarea';
import { CaretPositionHelper } from './caret-helper';
export var ChatMessageRole;
(function (ChatMessageRole) {
ChatMessageRole["System"] = "system";
ChatMessageRole["User"] = "user";
ChatMessageRole["Assistant"] = "assistant";
})(ChatMessageRole || (ChatMessageRole = {}));
var SmartTextArea = /** @class */ (function (_super) {
__extends(SmartTextArea, _super);
/**
* Constructor for creating the widget
*
* @private
* @param {SmartTextArea} options - Specifies Smart text area model
* @param {string | HTMLTextAreaElement} element - Specifies target element
*/
function SmartTextArea(options, element) {
return _super.call(this, options, element) || this;
}
SmartTextArea.prototype.render = function () {
_super.prototype.render.call(this);
if (!(this.element instanceof HTMLTextAreaElement)) {
return;
}
this.textArea = this.element;
var smartTextArea = createElement('smart-textarea');
smartTextArea.classList.add('e-smart-textarea');
this.textArea.after(smartTextArea);
if (this.showSuggestionOnPopup !== 'None') {
var suggestionState = this.showSuggestionOnPopup === 'Enable' ? 'false' : 'true';
this.textArea.setAttribute('data-inline-suggestions', suggestionState);
}
this.suggestionDisplay = this.shouldShowInlineSuggestions(this.textArea) ?
new InlineSuggestion(smartTextArea, this.textArea) : new ContextSuggestion(smartTextArea, this.textArea);
};
SmartTextArea.prototype.wireEvents = function () {
var _this = this;
_super.prototype.wireEvents.call(this);
EventHandler.add(this.element, 'keyup', this.handleKeyUp, this);
EventHandler.add(this.element, 'keydown', this.handleKeyDown, this);
EventHandler.add(this.element, 'mousedown', this.removeExistingOrPendingSuggestion, this);
EventHandler.add(this.element, 'focusout', this.removeExistingOrPendingSuggestion, this);
this.element.addEventListener('scroll', (function () { return _this.suggestionDisplay.reject(); }), {
passive: true
});
};
SmartTextArea.prototype.unWireEvents = function () {
var _this = this;
_super.prototype.unWireEvents.call(this);
EventHandler.remove(this.element, 'keyup', this.handleKeyUp);
EventHandler.remove(this.element, 'keydown', this.handleKeyDown);
EventHandler.remove(this.element, 'mousedown', this.removeExistingOrPendingSuggestion);
EventHandler.remove(this.element, 'focusout', this.removeExistingOrPendingSuggestion);
this.element.removeEventListener('scroll', (function () { return _this.suggestionDisplay.reject(); }));
};
SmartTextArea.prototype.keydownHandler = function () {
// Overridden to prevent default behavior
};
SmartTextArea.prototype.shouldShowInlineSuggestions = function (textArea) {
var inlineSuggestions = textArea.getAttribute('data-inline-suggestions');
if (inlineSuggestions) {
return inlineSuggestions.toLowerCase() === 'true';
}
return !('ontouchstart' in window);
};
SmartTextArea.prototype.handleKeyDown = function (event) {
switch (event.key) {
case 'Tab':
if (this.suggestionDisplay.isShowing()) {
this.suggestionDisplay.accept();
event.preventDefault();
}
break;
case 'Alt':
case 'Control':
case 'Shift':
case 'Command':
break;
default:
if (this.suggestionDisplay.isShowing() && this.suggestionDisplay.currentSuggestion.startsWith(event.key)) {
CaretPositionHelper.insertCharacter(this.textArea, event.key);
event.preventDefault();
this.suggestionDisplay.show(this.suggestionDisplay.currentSuggestion.substring(event.key.length));
CaretPositionHelper.adjustScrollToCaretPosition(this.textArea);
}
else {
this.removeExistingOrPendingSuggestion();
}
break;
}
};
SmartTextArea.prototype.handleKeyUp = function () {
var _this = this;
if (!this.suggestionDisplay.isShowing()) {
clearTimeout(this.typingDebounceTimeout);
this.typingDebounceTimeout = setTimeout(function () { return _this.handleTypingPaused(); }, 350);
}
};
SmartTextArea.prototype.handleTypingPaused = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (document.activeElement !== this.textArea) {
return [2 /*return*/];
}
if (!(this.textArea.selectionStart === this.textArea.selectionEnd &&
(this.textArea.selectionStart === this.textArea.value.length ||
this.textArea.value[this.textArea.selectionStart] === '\n'))) return [3 /*break*/, 2];
return [4 /*yield*/, this.requestSuggestionAsync()];
case 1:
_a.sent();
_a.label = 2;
case 2: return [2 /*return*/];
}
});
});
};
SmartTextArea.prototype.removeExistingOrPendingSuggestion = function () {
clearTimeout(this.typingDebounceTimeout);
if (this.pendingSuggestionAbort) {
this.pendingSuggestionAbort.abort();
this.pendingSuggestionAbort = null;
}
this.suggestionDisplay.reject();
};
SmartTextArea.prototype.createSuggestionPrompt = function (textBefore, textAfter) {
var stringBuilder = 'Predict what text the user in the given ROLE would insert at the cursor position indicated by ^^^.\nOnly give predictions for which you have' +
' an EXTREMELY high confidence that the user would insert that EXACT text.\nDo not make up new information. If you are not sure, ' +
'just reply with NO_PREDICTION.\n\nRULES:\n1. Reply with OK:, then in square brackets the predicted text, then END_INSERTION, and no other output.\n2. ' +
'When a specific value or quantity cannot be inferred and would need to be provided, use the word NEED_INFO.\n3. ' +
'If there is not enough information to predict any words that the user would type next, just reply with the word NO_PREDICTION.' +
'\n4. NEVER invent new information. If you can not be sure what the user is about to type, ALWAYS stop the prediction with END_INSERTION.';
var userPhrases = this.UserPhrases;
if (userPhrases && userPhrases.length > 0) {
stringBuilder += '\nAlways try to use variations on the following phrases as part of the predictions:\n';
for (var _i = 0, userPhrases_1 = userPhrases; _i < userPhrases_1.length; _i++) {
var phrase = userPhrases_1[_i];
stringBuilder += "- " + phrase + "\n";
}
}
var chatMessageList = [
{ role: ChatMessageRole.System, content: stringBuilder },
{ role: ChatMessageRole.User, content: 'ROLE: Family member sending a text\nUSER_TEXT: Hey, it is a nice day - the weather is ^^^' },
{ role: ChatMessageRole.Assistant, content: 'OK:[great!]END_INSERTION' },
{ role: ChatMessageRole.User, content: 'ROLE: Customer service assistant\nUSER_TEXT: You can find more information on^^^\n\nAlternatively, phone us.' },
{ role: ChatMessageRole.Assistant, content: 'OK:[ our website at NEED_INFO]END_INSERTION' },
{ role: ChatMessageRole.User, content: 'ROLE: Casual\nUSER_TEXT: Oh I see!\n\nWell sure thing, we can' },
{ role: ChatMessageRole.Assistant, content: 'OK:[ help you out with that!]END_INSERTION' },
{ role: ChatMessageRole.User, content: 'ROLE: Storyteller\nUSER_TEXT: Sir Digby Chicken Caesar, also know^^^' },
{ role: ChatMessageRole.Assistant, content: 'OK:[n as NEED_INFO]END_INSERTION' },
{ role: ChatMessageRole.User, content: 'ROLE: Customer support agent\nUSER_TEXT: Goodbye for now.^^^' },
{ role: ChatMessageRole.Assistant, content: 'NO_PREDICTION END_INSERTION' },
{ role: ChatMessageRole.User, content: 'ROLE: Pirate\nUSER_TEXT: Have you found^^^' },
{ role: ChatMessageRole.Assistant, content: 'OK:[ the treasure, me hearties?]END_INSERTION' },
{ role: ChatMessageRole.User, content: "ROLE: " + this.userRole + "\nUSER_TEXT: " + textBefore + "^^^" + textAfter }
];
return {
messages: chatMessageList,
temperature: 0.0,
maxTokens: 400,
stopSequences: ['END_INSERTION', 'NEED_INFO'],
frequencyPenalty: 0.0,
presencePenalty: 0.0
};
};
SmartTextArea.prototype.requestSuggestionAsync = function () {
return __awaiter(this, void 0, void 0, function () {
var requestDetails, suggestionData, chatConfig, insertSuggestion, response;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (this.pendingSuggestionAbort) {
this.pendingSuggestionAbort.abort();
return [2 /*return*/];
}
this.pendingSuggestionAbort = new AbortController();
requestDetails = {
textAreaValue: this.textArea.value,
cursorPosition: this.textArea.selectionStart
};
suggestionData = {
textBefore: requestDetails.textAreaValue.substring(0, requestDetails.cursorPosition),
textAfter: requestDetails.textAreaValue.substring(requestDetails.cursorPosition)
};
chatConfig = this.createSuggestionPrompt(suggestionData.textBefore, suggestionData.textAfter);
if (!(typeof this.aiSuggestionHandler === 'function')) return [3 /*break*/, 2];
return [4 /*yield*/, this.aiSuggestionHandler(chatConfig)];
case 1:
response = _a.sent();
insertSuggestion = this.validateSuggestion(response, suggestionData.textBefore);
_a.label = 2;
case 2:
if (insertSuggestion && requestDetails.textAreaValue === this.textArea.value &&
requestDetails.cursorPosition === this.textArea.selectionStart) {
if (!insertSuggestion.endsWith(' ')) {
insertSuggestion += ' ';
}
this.suggestionDisplay.show(insertSuggestion);
}
return [2 /*return*/];
}
});
});
};
SmartTextArea.prototype.validateSuggestion = function (response, textBefore) {
var suggestion;
if (typeof response !== 'string' || response.length <= 5 || response.indexOf('OK:[') !== 0) {
return '';
}
var endIndex = this.indexOfAny(response, ['.', '?', '!']);
if (endIndex > 0 && response.length > endIndex + 1 && response[endIndex + 1] === ' ') {
response = response.substring(0, endIndex + 1);
}
suggestion = response.substring(4).replace(/[\]\s]+$/, '');
if (textBefore.length > 0 && textBefore[textBefore.length - 1] === ' ') {
suggestion = suggestion.replace(/^\s+/, '');
}
return suggestion;
};
SmartTextArea.prototype.indexOfAny = function (str, chars) {
for (var i = 0; i < str.length; i++) {
if (chars.indexOf(str["" + i]) !== -1) {
return i;
}
}
return -1;
};
SmartTextArea.prototype.getModuleName = function () {
return 'smarttextarea';
};
SmartTextArea.prototype.destroy = function () {
_super.prototype.destroy.call(this);
this.textArea = null;
this.suggestionDisplay = null;
this.typingDebounceTimeout = null;
};
__decorate([
Property('')
], SmartTextArea.prototype, "userRole", void 0);
__decorate([
Property([])
], SmartTextArea.prototype, "UserPhrases", void 0);
__decorate([
Property()
], SmartTextArea.prototype, "aiSuggestionHandler", void 0);
__decorate([
Property('None')
], SmartTextArea.prototype, "showSuggestionOnPopup", void 0);
return SmartTextArea;
}(TextArea));
export { SmartTextArea };
var InlineSuggestion = /** @class */ (function () {
function InlineSuggestion(smartTextArea, textArea) {
this.owner = smartTextArea;
this.textArea = textArea;
this.latestSuggestionText = '';
this.suggestionStartPos = null;
this.suggestionEndPos = null;
this.virtualCaret = null;
this.originalValueProperty = this.getOriginalValueProperty(textArea, 'value');
}
Object.defineProperty(InlineSuggestion.prototype, "value", {
get: function () {
var value = this.originalValueProperty.get.call(this.textArea);
return this.isShowing() ? value.substring(0, this.suggestionStartPos) + value.substring(this.suggestionEndPos) : value;
},
set: function (newValue) {
this.originalValueProperty.set.call(this.textArea, newValue);
},
enumerable: true,
configurable: true
});
InlineSuggestion.prototype.getOriginalValueProperty = function (obj, property) {
while (obj) {
var descriptor = Object.getOwnPropertyDescriptor(obj, property);
if (descriptor) {
return descriptor;
}
obj = Object.getPrototypeOf(obj);
}
throw new Error("Property " + property + " not found on object or its prototype chain");
};
Object.defineProperty(InlineSuggestion.prototype, "valueIncludingSuggestion", {
get: function () {
return this.originalValueProperty.get.call(this.textArea);
},
set: function (newValue) {
this.originalValueProperty.set.call(this.textArea, newValue);
},
enumerable: true,
configurable: true
});
InlineSuggestion.prototype.isShowing = function () {
return this.suggestionStartPos !== null;
};
InlineSuggestion.prototype.show = function (suggestionText) {
this.latestSuggestionText = suggestionText;
this.suggestionStartPos = this.textArea.selectionStart;
this.suggestionEndPos = this.suggestionStartPos + suggestionText.length;
this.textArea.setAttribute('data-suggestion-visible', '');
this.valueIncludingSuggestion = this.valueIncludingSuggestion.substring(0, this.suggestionStartPos) +
suggestionText +
this.valueIncludingSuggestion.substring(this.suggestionStartPos);
this.textArea.setSelectionRange(this.suggestionStartPos, this.suggestionEndPos);
if (!this.virtualCaret) {
this.virtualCaret = new VirtualCaret(this.owner, this.textArea);
}
this.virtualCaret.show();
};
Object.defineProperty(InlineSuggestion.prototype, "currentSuggestion", {
get: function () {
return this.latestSuggestionText;
},
enumerable: true,
configurable: true
});
InlineSuggestion.prototype.accept = function () {
this.textArea.setSelectionRange(this.suggestionEndPos, this.suggestionEndPos);
this.suggestionStartPos = null;
this.suggestionEndPos = null;
if (this.virtualCaret) {
this.virtualCaret.hide();
}
this.textArea.removeAttribute('data-suggestion-visible');
CaretPositionHelper.adjustScrollToCaretPosition(this.textArea);
};
InlineSuggestion.prototype.reject = function () {
if (!this.isShowing()) {
return;
}
var selectionStart = this.textArea.selectionStart;
var selectionEnd = this.textArea.selectionEnd;
this.valueIncludingSuggestion = this.valueIncludingSuggestion.substring(0, this.suggestionStartPos) +
this.valueIncludingSuggestion.substring(this.suggestionEndPos);
if (this.suggestionStartPos === selectionStart && this.suggestionEndPos === selectionEnd) {
this.textArea.setSelectionRange(selectionStart, selectionStart);
}
this.suggestionStartPos = null;
this.suggestionEndPos = null;
this.textArea.removeAttribute('data-suggestion-visible');
if (this.virtualCaret) {
this.virtualCaret.hide();
}
};
return InlineSuggestion;
}());
var ContextSuggestion = /** @class */ (function () {
function ContextSuggestion(container, textArea) {
var _this = this;
this.latestSuggestionText = '';
this.showing = false;
this.textArea = textArea;
this.suggestionElement = document.createElement('div');
this.suggestionElement.classList.add('smart-textarea-suggestion-overlay');
this.suggestionElement.addEventListener('mousedown', function (event) { return _this.handleSuggestionClicked(event); });
this.suggestionElement.addEventListener('touchend', function (event) { return _this.handleSuggestionClicked(event); });
this.suggestionPrefixElement = document.createElement('span');
this.suggestionTextElement = document.createElement('span');
this.suggestionElement.appendChild(this.suggestionPrefixElement);
this.suggestionElement.appendChild(this.suggestionTextElement);
this.suggestionPrefixElement.style.opacity = '0.3';
var computedStyle = window.getComputedStyle(this.textArea);
this.suggestionElement.style.font = computedStyle.font;
this.suggestionElement.style.marginTop = 1.4 * parseFloat(computedStyle.fontSize) + "px";
container.appendChild(this.suggestionElement);
}
Object.defineProperty(ContextSuggestion.prototype, "currentSuggestion", {
get: function () {
return this.latestSuggestionText;
},
enumerable: true,
configurable: true
});
ContextSuggestion.prototype.show = function (suggestionText) {
this.latestSuggestionText = suggestionText;
this.suggestionPrefixElement.textContent = suggestionText[0] !== ' ' ? this.getPrefixText(this.textArea, 20) : '';
this.suggestionTextElement.textContent = suggestionText;
var position = CaretPositionHelper.getTextAreaPosition(this.textArea);
var style = this.suggestionElement.style;
style.minWidth = null;
this.suggestionElement.classList.add('smart-textarea-suggestion-overlay-visible');
style.zIndex = this.textArea.style.zIndex + 1;
style.top = position.top + "px";
var leftPosition = position.left - this.suggestionPrefixElement.offsetWidth;
if (!style.left || Math.abs(parseFloat(style.left) - leftPosition) > 10) {
style.left = leftPosition + "px";
}
this.showing = true;
var computedStyle = window.getComputedStyle(this.suggestionElement);
var lineHeight = parseFloat(computedStyle.lineHeight);
var paddingTop = parseFloat(computedStyle.paddingTop);
var paddingBottom = parseFloat(computedStyle.paddingBottom);
var lines = Math.round((this.suggestionElement.offsetHeight - paddingTop - paddingBottom) / lineHeight);
if (lines > 2) {
var elementWidth = this.suggestionElement.offsetWidth;
style.minWidth = "calc(min(70vw, " + (lines * elementWidth) / 2 + "px))";
}
var rect = this.suggestionElement.getBoundingClientRect();
if (rect.right > document.body.clientWidth - 20) {
style.left = "calc(" + (parseFloat(style.left) - (rect.right - document.body.clientWidth)) + "px - 2rem)";
}
};
ContextSuggestion.prototype.accept = function () {
if (this.showing) {
CaretPositionHelper.insertCharacter(this.textArea, this.currentSuggestion);
CaretPositionHelper.adjustScrollToCaretPosition(this.textArea);
this.hide();
}
};
ContextSuggestion.prototype.reject = function () {
this.hide();
};
ContextSuggestion.prototype.hide = function () {
if (this.showing) {
this.showing = false;
this.suggestionElement.classList.remove('smart-textarea-suggestion-overlay-visible');
}
};
ContextSuggestion.prototype.isShowing = function () {
return this.showing;
};
ContextSuggestion.prototype.handleSuggestionClicked = function (event) {
event.preventDefault();
event.stopImmediatePropagation();
this.accept();
};
ContextSuggestion.prototype.getPrefixText = function (textArea, maxLength) {
var value = textArea.value;
var selectionStart = textArea.selectionStart;
for (var i = selectionStart - 1; i > selectionStart - maxLength; i--) {
if (i < 0 || /\s/.test(value["" + i])) {
return value.substring(i + 1, selectionStart);
}
}
return '';
};
return ContextSuggestion;
}());
var VirtualCaret = /** @class */ (function () {
function VirtualCaret(smartTextArea, textArea) {
this.textArea = textArea;
this.caretDiv = document.createElement('div');
this.caretDiv.classList.add('smart-textarea-caret');
smartTextArea.appendChild(this.caretDiv);
}
VirtualCaret.prototype.show = function () {
var textAreaPosition = CaretPositionHelper.getTextAreaPosition(this.textArea);
var caretStyle = this.caretDiv.style;
caretStyle.display = 'block';
caretStyle.top = textAreaPosition.top + 'px';
caretStyle.left = textAreaPosition.left + 'px';
caretStyle.height = textAreaPosition.height + 'px';
caretStyle.zIndex = this.textArea.style.zIndex;
caretStyle.backgroundColor = textAreaPosition.elemStyle.caretColor;
};
VirtualCaret.prototype.hide = function () {
this.caretDiv.style.display = 'none';
};
return VirtualCaret;
}());