devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
199 lines (198 loc) • 7.48 kB
JavaScript
/**
* DevExtreme (esm/__internal/ui/chat/messagebox.js)
* Version: 24.2.7
* Build date: Mon Apr 28 2025
*
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
import _extends from "@babel/runtime/helpers/esm/extends";
import messageLocalization from "../../../common/core/localization/message";
import $ from "../../../core/renderer";
import Button from "../../../ui/button";
import DOMComponent from "../../core/widget/dom_component";
import TextArea from "../../ui/m_text_area";
const CHAT_MESSAGEBOX_CLASS = "dx-chat-messagebox";
const CHAT_MESSAGEBOX_TEXTAREA_CLASS = "dx-chat-messagebox-textarea";
const CHAT_MESSAGEBOX_BUTTON_CLASS = "dx-chat-messagebox-button";
export const TYPING_END_DELAY = 2e3;
class MessageBox extends DOMComponent {
_getDefaultOptions() {
return _extends({}, super._getDefaultOptions(), {
activeStateEnabled: true,
focusStateEnabled: true,
hoverStateEnabled: true,
onMessageEntered: void 0,
onTypingStart: void 0,
onTypingEnd: void 0
})
}
_init() {
super._init();
this._createMessageEnteredAction();
this._createTypingStartAction();
this._createTypingEndAction()
}
_initMarkup() {
$(this.element()).addClass("dx-chat-messagebox");
super._initMarkup();
this._renderTextArea();
this._renderButton()
}
_renderTextArea() {
const {
activeStateEnabled: activeStateEnabled,
focusStateEnabled: focusStateEnabled,
hoverStateEnabled: hoverStateEnabled
} = this.option();
const $textArea = $("<div>").addClass("dx-chat-messagebox-textarea").appendTo(this.element());
this._textArea = this._createComponent($textArea, TextArea, {
activeStateEnabled: activeStateEnabled,
focusStateEnabled: focusStateEnabled,
hoverStateEnabled: hoverStateEnabled,
stylingMode: "outlined",
placeholder: messageLocalization.format("dxChat-textareaPlaceholder"),
autoResizeEnabled: true,
valueChangeEvent: "input",
maxHeight: "8em",
onInput: e => {
const shouldButtonBeDisabled = !this._isValuableTextEntered();
this._toggleButtonDisableState(shouldButtonBeDisabled);
this._triggerTypingStartAction(e);
this._updateTypingEndTimeout()
},
onEnterKey: e => {
var _e$event;
if (!(null !== (_e$event = e.event) && void 0 !== _e$event && _e$event.shiftKey)) {
this._sendHandler(e)
}
}
});
this._textArea.registerKeyHandler("enter", (event => {
if (!event.shiftKey && this._isValuableTextEntered()) {
event.preventDefault()
}
}))
}
_renderButton() {
const {
activeStateEnabled: activeStateEnabled,
focusStateEnabled: focusStateEnabled,
hoverStateEnabled: hoverStateEnabled
} = this.option();
const $button = $("<div>").addClass("dx-chat-messagebox-button").appendTo(this.element());
this._button = this._createComponent($button, Button, {
activeStateEnabled: activeStateEnabled,
focusStateEnabled: focusStateEnabled,
hoverStateEnabled: hoverStateEnabled,
icon: "sendfilled",
type: "default",
stylingMode: "text",
disabled: true,
elementAttr: {
"aria-label": messageLocalization.format("dxChat-sendButtonAriaLabel")
},
onClick: e => {
this._sendHandler(e)
}
})
}
_createMessageEnteredAction() {
this._messageEnteredAction = this._createActionByOption("onMessageEntered", {
excludeValidators: ["disabled"]
})
}
_createTypingStartAction() {
this._typingStartAction = this._createActionByOption("onTypingStart", {
excludeValidators: ["disabled"]
})
}
_createTypingEndAction() {
this._typingEndAction = this._createActionByOption("onTypingEnd", {
excludeValidators: ["disabled"]
})
}
_triggerTypingStartAction(e) {
if (!this._typingEndTimeoutId) {
var _this$_typingStartAct;
null === (_this$_typingStartAct = this._typingStartAction) || void 0 === _this$_typingStartAct || _this$_typingStartAct.call(this, {
event: e.event
})
}
}
_updateTypingEndTimeout() {
clearTimeout(this._typingEndTimeoutId);
this._typingEndTimeoutId = setTimeout((() => {
var _this$_typingEndActio;
null === (_this$_typingEndActio = this._typingEndAction) || void 0 === _this$_typingEndActio || _this$_typingEndActio.call(this);
this._clearTypingEndTimeout()
}), 2e3)
}
_clearTypingEndTimeout() {
clearTimeout(this._typingEndTimeoutId);
this._typingEndTimeoutId = void 0
}
_sendHandler(e) {
var _this$_typingEndActio2, _this$_messageEntered;
if (!this._isValuableTextEntered()) {
return
}
this._clearTypingEndTimeout();
null === (_this$_typingEndActio2 = this._typingEndAction) || void 0 === _this$_typingEndActio2 || _this$_typingEndActio2.call(this);
const {
text: text
} = this._textArea.option();
this._textArea.reset();
this._toggleButtonDisableState(true);
null === (_this$_messageEntered = this._messageEnteredAction) || void 0 === _this$_messageEntered || _this$_messageEntered.call(this, {
text: text,
event: e.event
})
}
_toggleButtonDisableState(state) {
this._button.option("disabled", state)
}
_isValuableTextEntered() {
const {
text: text
} = this._textArea.option();
return !!(null !== text && void 0 !== text && text.trim())
}
_optionChanged(args) {
const {
name: name,
value: value
} = args;
switch (name) {
case "activeStateEnabled":
case "focusStateEnabled":
case "hoverStateEnabled":
this._button.option(name, value);
this._textArea.option(name, value);
break;
case "onMessageEntered":
this._createMessageEnteredAction();
break;
case "onTypingStart":
this._createTypingStartAction();
break;
case "onTypingEnd":
this._createTypingEndAction();
break;
default:
super._optionChanged(args)
}
}
_clean() {
this._clearTypingEndTimeout();
super._clean()
}
updateInputAria(emptyViewId) {
this._textArea.option({
inputAttr: {
"aria-labelledby": emptyViewId
}
})
}
}
export default MessageBox;