UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

303 lines (300 loc) • 12 kB
/** * DevExtreme (cjs/__internal/ui/chat/messagebox.js) * Version: 25.1.3 * Build date: Wed Jun 25 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.TYPING_END_DELAY = exports.CHAT_MESSAGEBOX_TEXTAREA_CLASS = exports.CHAT_MESSAGEBOX_INPUT_CONTAINER_CLASS = exports.CHAT_MESSAGEBOX_CLASS = exports.CHAT_MESSAGEBOX_BUTTON_CLASS = void 0; var _message = _interopRequireDefault(require("../../../common/core/localization/message")); var _devices = _interopRequireDefault(require("../../../core/devices")); var _renderer = _interopRequireDefault(require("../../../core/renderer")); var _button = _interopRequireDefault(require("../../../ui/button")); var _dom_component = _interopRequireDefault(require("../../core/widget/dom_component")); var _editing_preview = _interopRequireDefault(require("../../ui/chat/editing_preview")); var _m_text_area = _interopRequireDefault(require("../../ui/m_text_area")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function(n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]) } } return n }, _extends.apply(null, arguments) } const CHAT_MESSAGEBOX_CLASS = exports.CHAT_MESSAGEBOX_CLASS = "dx-chat-messagebox"; const CHAT_MESSAGEBOX_INPUT_CONTAINER_CLASS = exports.CHAT_MESSAGEBOX_INPUT_CONTAINER_CLASS = "dx-chat-messagebox-input-container"; const CHAT_MESSAGEBOX_TEXTAREA_CLASS = exports.CHAT_MESSAGEBOX_TEXTAREA_CLASS = "dx-chat-messagebox-textarea"; const CHAT_MESSAGEBOX_BUTTON_CLASS = exports.CHAT_MESSAGEBOX_BUTTON_CLASS = "dx-chat-messagebox-button"; const TYPING_END_DELAY = exports.TYPING_END_DELAY = 2e3; const ESCAPE_KEY = "escape"; const isMobile = () => "desktop" !== _devices.default.current().deviceType; class MessageBox extends _dom_component.default { _getDefaultOptions() { return _extends({}, super._getDefaultOptions(), { activeStateEnabled: true, focusStateEnabled: true, hoverStateEnabled: true, onMessageEntered: void 0, onTypingStart: void 0, onTypingEnd: void 0, onMessageEditCanceled: void 0, onMessageUpdating: void 0, text: "" }) } _init() { super._init(); this._createMessageEnteredAction(); this._createTypingStartAction(); this._createTypingEndAction() } _initMarkup() { (0, _renderer.default)(this.element()).addClass(CHAT_MESSAGEBOX_CLASS); super._initMarkup(); if (this.option("text")) { this._renderEditingPreview() } this._renderInputContainer() } _renderInputContainer() { const $messageBox = (0, _renderer.default)("<div>").addClass(CHAT_MESSAGEBOX_INPUT_CONTAINER_CLASS).appendTo(this.element()); this._renderTextArea($messageBox); this._renderButton($messageBox) } _cancelMessageEdit() { const { onMessageEditCanceled: onMessageEditCanceled } = this.option(); this.option("text", ""); this._textArea.focus(); null === onMessageEditCanceled || void 0 === onMessageEditCanceled || onMessageEditCanceled() } _renderEditingPreview() { const $editingPreview = (0, _renderer.default)("<div>").prependTo(this.element()); const { activeStateEnabled: activeStateEnabled, focusStateEnabled: focusStateEnabled, hoverStateEnabled: hoverStateEnabled, text: text } = this.option(); this._editingPreview = this._createComponent($editingPreview, _editing_preview.default, { activeStateEnabled: activeStateEnabled, focusStateEnabled: focusStateEnabled, hoverStateEnabled: hoverStateEnabled, text: text, onCancel: () => this._cancelMessageEdit() }) } _renderTextArea($parent) { const { activeStateEnabled: activeStateEnabled, focusStateEnabled: focusStateEnabled, hoverStateEnabled: hoverStateEnabled } = this.option(); const $textArea = (0, _renderer.default)("<div>").addClass(CHAT_MESSAGEBOX_TEXTAREA_CLASS); $parent.append($textArea); this._textArea = this._createComponent($textArea, _m_text_area.default, { activeStateEnabled: activeStateEnabled, focusStateEnabled: focusStateEnabled, hoverStateEnabled: hoverStateEnabled, stylingMode: "outlined", placeholder: _message.default.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 (isMobile()) { return } 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() && !isMobile()) { event.preventDefault() } })); this._textArea.registerKeyHandler("escape", (() => { if (this.option("text")) { this._cancelMessageEdit() } })) } _renderButton($parent) { const { activeStateEnabled: activeStateEnabled, focusStateEnabled: focusStateEnabled, hoverStateEnabled: hoverStateEnabled } = this.option(); const $button = (0, _renderer.default)("<div>").addClass(CHAT_MESSAGEBOX_BUTTON_CLASS); $parent.append($button); this._button = this._createComponent($button, _button.default, { activeStateEnabled: activeStateEnabled, focusStateEnabled: focusStateEnabled, hoverStateEnabled: hoverStateEnabled, icon: "sendfilled", type: "default", stylingMode: "text", disabled: true, elementAttr: { "aria-label": _message.default.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() }), TYPING_END_DELAY) } _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(); const { text: previewText } = this.option(); if (previewText) { const { onMessageUpdating: onMessageUpdating } = this.option(); null === onMessageUpdating || void 0 === onMessageUpdating || onMessageUpdating({ text: text }); return } 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": var _this$_editingPreview; this._button.option(name, value); this._textArea.option(name, value); null === (_this$_editingPreview = this._editingPreview) || void 0 === _this$_editingPreview || _this$_editingPreview.option(name, value); break; case "onMessageEntered": this._createMessageEnteredAction(); break; case "onTypingStart": this._createTypingStartAction(); break; case "onTypingEnd": this._createTypingEndAction(); break; case "text": this._updateEditingPreview(value); this._updateInputContainer(value); break; default: super._optionChanged(args) } } _clean() { this._clearTypingEndTimeout(); super._clean() } updateInputAria(emptyViewId) { this._textArea.option({ inputAttr: { "aria-labelledby": emptyViewId } }) } _updateEditingPreview(text) { if (this._editingPreview) { this._editingPreview.option("text", text); if (!text) { this._editingPreview = null } } else { this._renderEditingPreview() } } _updateInputContainer(value) { this._textArea.option("value", value); const shouldButtonBeDisabled = !this._isValuableTextEntered(); this._toggleButtonDisableState(shouldButtonBeDisabled) } } var _default = exports.default = MessageBox;