@dialpad/dialtone-vue 2.130.0 → 2.130.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"message-input.js","sources":["../../recipes/conversation_view/message_input/message_input.vue"],"sourcesContent":["<!-- eslint-disable vue/no-restricted-class -->\n<template>\n <div\n data-qa=\"dt-message-input\"\n role=\"presentation\"\n :class=\"['d-d-flex', 'd-fd-column', 'd-bar8', 'd-baw1', 'd-ba', 'd-c-text',\n { 'd-bc-bold d-bs-sm': hasFocus, 'd-bc-default': !hasFocus }]\"\n @click=\"$refs.richTextEditor?.focusEditor()\"\n @drag-enter=\"onDrag\"\n @drag-over=\"onDrag\"\n @drop=\"onDrop\"\n @keydown.enter.exact=\"onSend\"\n @paste=\"onPaste\"\n >\n <!-- Some wrapper to restrict the height and show the scrollbar -->\n <div\n class=\"d-of-auto d-mx16 d-mt8 d-mb4\"\n :style=\"{ 'max-height': maxHeight }\"\n >\n <dt-rich-text-editor\n ref=\"richTextEditor\"\n v-model=\"internalInputValue\"\n :editable=\"editable\"\n :input-aria-label=\"inputAriaLabel\"\n :input-class=\"inputClass\"\n :output-format=\"outputFormat\"\n :auto-focus=\"autoFocus\"\n :link=\"link\"\n :placeholder=\"placeholder\"\n :mention-suggestion=\"mentionSuggestion\"\n :channel-suggestion=\"channelSuggestion\"\n :slash-command-suggestion=\"slashCommandSuggestion\"\n :allow-blockquote=\"allowBlockquote\"\n :allow-bold=\"allowBold\"\n :allow-bullet-list=\"allowBulletList\"\n :allow-italic=\"allowItalic\"\n :allow-strike=\"allowStrike\"\n :allow-underline=\"allowUnderline\"\n v-bind=\"$attrs\"\n @focus=\"onFocus\"\n @blur=\"onBlur\"\n @input=\"onInput($event)\"\n @selected-command=\"onSelectedCommand\"\n />\n </div>\n <!-- @slot Slot for attachment carousel -->\n <slot name=\"middle\" />\n <!-- Section for the bottom UI -->\n <section class=\"d-d-flex d-jc-space-between d-mx8 d-my4\">\n <!-- Left content -->\n <div class=\"d-d-flex\">\n <dt-tooltip\n v-if=\"showImagePicker\"\n placement=\"top-start\"\n :message=\"showImagePicker.tooltipLabel\"\n :offset=\"[-4, -4]\"\n >\n <template #anchor>\n <dt-button\n data-qa=\"dt-message-input-image-btn\"\n size=\"sm\"\n circle\n :kind=\"imagePickerFocus ? 'default' : 'muted'\"\n importance=\"clear\"\n :aria-label=\"showImagePicker.ariaLabel\"\n @click=\"onSelectImage\"\n @mouseenter=\"imagePickerFocus = true\"\n @mouseleave=\"imagePickerFocus = false\"\n @focus=\"imagePickerFocus = true\"\n @blur=\"imagePickerFocus = false\"\n >\n <template #icon>\n <dt-icon\n name=\"image\"\n size=\"300\"\n />\n </template>\n </dt-button>\n <dt-input\n ref=\"messageInputImageUpload\"\n data-qa=\"dt-message-input-image-input\"\n accept=\"image/*, video/*\"\n type=\"file\"\n class=\"d-ps-absolute\"\n multiple\n hidden\n @input=\"onImageUpload\"\n />\n </template>\n </dt-tooltip>\n <dt-popover\n v-if=\"showEmojiPicker\"\n data-qa=\"dt-message-input-emoji-picker-popover\"\n :open=\"emojiPickerOpened\"\n initial-focus-element=\"#searchInput\"\n padding=\"none\"\n @opened=\"(open) => { emojiPickerOpened = open }\"\n >\n <template #anchor>\n <dt-tooltip\n :message=\"emojiTooltipMessage\"\n :offset=\"[0, -4]\"\n >\n <template #anchor>\n <dt-button\n data-qa=\"dt-message-input-emoji-picker-btn\"\n size=\"sm\"\n circle\n :kind=\"emojiPickerHovered ? 'default' : 'muted'\"\n importance=\"clear\"\n :aria-label=\"emojiButtonAriaLabel\"\n :offset=\"[0, 0]\"\n @click=\"toggleEmojiPicker\"\n @mouseenter=\"emojiPickerFocus = true\"\n @mouseleave=\"emojiPickerFocus = false\"\n @focus=\"emojiPickerFocus = true\"\n @blur=\"emojiPickerFocus = false\"\n >\n <template #icon>\n <dt-icon\n :name=\"!emojiPickerHovered ? 'satisfied' : 'very-satisfied'\"\n size=\"300\"\n />\n </template>\n </dt-button>\n </template>\n </dt-tooltip>\n </template>\n <template #content>\n <dt-emoji-picker\n v-bind=\"emojiPickerProps\"\n @skin-tone=\"onSkinTone\"\n @selected-emoji=\"onSelectEmoji\"\n />\n </template>\n </dt-popover>\n <!-- @slot Slot for emojiGiphy picker -->\n <slot name=\"emojiGiphyPicker\" />\n </div>\n <!-- Right content -->\n <div class=\"d-d-flex\">\n <!-- Optionally displayed remaining character counter -->\n <dt-tooltip\n v-if=\"Boolean(showCharacterLimit)\"\n class=\"dt-message-input--remaining-char-tooltip\"\n placement=\"top-end\"\n :enabled=\"characterLimitTooltipEnabled\"\n :message=\"showCharacterLimit.message\"\n :offset=\"[10, -8]\"\n >\n <template #anchor>\n <p\n v-show=\"displayCharacterLimitWarning\"\n class=\"d-fc-error d-mr16 dt-message-input--remaining-char\"\n data-qa=\"dt-message-input-character-limit\"\n >\n {{ showCharacterLimit.count - inputLength }}\n </p>\n </template>\n </dt-tooltip>\n\n <!-- Cancel button for edit mode -->\n <dt-button\n v-if=\"showCancel\"\n data-qa=\"dt-message-input-cancel-button\"\n class=\"dt-message-input--cancel-button\"\n size=\"sm\"\n kind=\"muted\"\n importance=\"clear\"\n :aria-label=\"showCancel.ariaLabel\"\n @click=\"onCancel\"\n >\n <p>{{ showCancel.text }}</p>\n </dt-button>\n\n <!-- Send button -->\n <dt-tooltip\n v-if=\"showSend\"\n placement=\"top-end\"\n :enabled=\"!showSend\"\n :message=\"showSend.tooltipLabel\"\n :show=\"!isSendDisabled && sendButtonFocus\"\n :offset=\"[6, -8]\"\n >\n <template #anchor>\n <!-- Right positioned UI - send button -->\n <dt-button\n data-qa=\"dt-message-input-send-btn\"\n size=\"sm\"\n kind=\"default\"\n importance=\"primary\"\n :class=\"[\n {\n 'message-input-button__disabled d-fc-muted': isSendDisabled,\n 'd-btn--circle': showSend.icon,\n },\n ]\"\n :aria-label=\"showSend.ariaLabel\"\n :aria-disabled=\"isSendDisabled\"\n @click=\"onSend\"\n @mouseenter=\"sendButtonFocus = true\"\n @mouseleave=\"sendButtonFocus = false\"\n @focus=\"sendButtonFocus = true\"\n @blur=\"sendButtonFocus = false\"\n >\n <template\n v-if=\"showSend.icon\"\n #icon\n >\n <dt-icon\n :name=\"showSend.icon\"\n size=\"300\"\n />\n </template>\n <template\n v-if=\"showSend.text\"\n >\n <p>{{ showSend.text }}</p>\n </template>\n </dt-button>\n </template>\n </dt-tooltip>\n </div>\n </section>\n </div>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport {\n DtRichTextEditor,\n RICH_TEXT_EDITOR_OUTPUT_FORMATS,\n RICH_TEXT_EDITOR_AUTOFOCUS_TYPES,\n} from '@/components/rich_text_editor';\nimport { DtButton } from '@/components/button';\nimport { DtIcon } from '@/components/icon';\nimport { DtEmojiPicker } from '@/components/emoji_picker';\nimport { DtPopover } from '@/components/popover';\nimport { DtInput } from '@/components/input';\nimport { DtTooltip } from '@/components/tooltip';\n\nexport default {\n name: 'DtRecipeMessageInput',\n\n components: {\n DtButton,\n DtEmojiPicker,\n DtIcon,\n DtInput,\n DtPopover,\n DtRichTextEditor,\n DtTooltip,\n },\n\n mixins: [],\n\n inheritAttrs: false,\n\n props: {\n /**\n * Value of the input. The object format should match TipTap's JSON\n * document structure: https://tiptap.dev/guide/output#option-1-json\n */\n value: {\n type: [Object, String],\n default: '',\n },\n\n /**\n * Whether the input is editable\n */\n editable: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Descriptive label for the input element\n */\n inputAriaLabel: {\n type: String,\n required: true,\n default: '',\n },\n\n /**\n * Additional class name for the input element. Only accepts a String value\n * because this is passed to the editor via options. For multiple classes,\n * join them into one string, e.g. \"d-p8 d-hmx96\"\n */\n inputClass: {\n type: String,\n default: '',\n },\n\n /**\n * Whether the input should receive focus after the component has been\n * mounted. Either one of `start`, `end`, `all` or a Boolean or a Number.\n * - `start` Sets the focus to the beginning of the input\n * - `end` Sets the focus to the end of the input\n * - `all` Selects the whole contents of the input\n * - `Number` Sets the focus to a specific position in the input\n * - `true` Defaults to `start`\n * - `false` Disables autofocus\n * @values true, false, start, end, all, number\n */\n autoFocus: {\n type: [Boolean, String, Number],\n default: false,\n validator (autoFocus) {\n if (typeof autoFocus === 'string') {\n return RICH_TEXT_EDITOR_AUTOFOCUS_TYPES.includes(autoFocus);\n }\n return true;\n },\n },\n\n /**\n * The output format that the editor uses when emitting the \"@input\" event.\n * One of `text`, `json`, `html`. See https://tiptap.dev/guide/output for\n * examples.\n * @values text, json, html\n */\n outputFormat: {\n type: String,\n default: 'text',\n validator (outputFormat) {\n return RICH_TEXT_EDITOR_OUTPUT_FORMATS.includes(outputFormat);\n },\n },\n\n /**\n * Enables the Link extension and optionally passes configurations to it\n */\n link: {\n type: [Boolean, Object],\n default: false,\n },\n\n /**\n * Placeholder text\n */\n placeholder: {\n type: String,\n default: '',\n },\n\n /**\n * Disable Send Button\n */\n disableSend: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Content area needs to dynamically adjust height based on the conversation area height.\n * can be vh|px|rem|em|%\n */\n maxHeight: {\n type: String,\n default: 'unset',\n },\n\n // Emoji picker props\n showEmojiPicker: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Props to pass into the emoji picker.\n */\n emojiPickerProps: {\n type: Object,\n default: () => ({}),\n validate (emojiPickerProps) {\n return [\n 'searchNoResultsLabel',\n 'searchResultsLabel',\n 'searchPlaceholderLabel',\n 'skinSelectorButtonTooltipLabel',\n 'tabSetLabels',\n ].every(prop => emojiPickerProps[prop] != null);\n },\n },\n\n /**\n * Emoji button tooltip label\n */\n emojiTooltipMessage: {\n type: String,\n default: 'Emoji',\n },\n\n // Aria label for buttons\n /**\n * Emoji button aria label\n */\n emojiButtonAriaLabel: {\n type: String,\n default: 'emoji button',\n },\n\n /**\n * Enable character Limit warning\n */\n showCharacterLimit: {\n type: [Boolean, Object],\n default: () => ({ count: 1500, warning: 500, message: '' }),\n },\n\n showImagePicker: {\n type: [Boolean, Object],\n default: () => ({ tooltipLabel: 'Attach Image', ariaLabel: 'image button' }),\n },\n\n /**\n * Send button defaults.\n */\n showSend: {\n type: [Boolean, Object],\n default: () => ({ icon: 'send' }),\n },\n\n /**\n * Cancel button defaults.\n */\n showCancel: {\n type: [Boolean, Object],\n default: () => ({ text: 'Cancel' }),\n },\n\n /**\n * suggestion object containing the items query function.\n * The valid keys passed into this object can be found here: https://tiptap.dev/api/utilities/suggestion\n *\n * The only required key is the items function which is used to query the contacts for suggestion.\n * items({ query }) => { return [ContactObject]; }\n * ContactObject format:\n * { name: string, avatarSrc: string, id: string }\n *\n * When null, it does not add the plugin.\n */\n mentionSuggestion: {\n type: Object,\n default: null,\n },\n\n /**\n * suggestion object containing the items query function.\n * The valid keys passed into this object can be found here: https://tiptap.dev/api/utilities/suggestion\n *\n * The only required key is the items function which is used to query the channels for suggestion.\n * items({ query }) => { return [ChannelObject]; }\n * ChannelObject format:\n * { name: string, id: string, locked: boolean }\n *\n * When null, it does not add the plugin. Setting locked to true will display a lock rather than hash.\n */\n channelSuggestion: {\n type: Object,\n default: null,\n },\n\n /**\n * suggestion object containing the items query function.\n * The valid keys passed into this object can be found here: https://tiptap.dev/api/utilities/suggestion\n *\n * The only required key is the items function which is used to query the slash commands for suggestion.\n * items({ query }) => { return [SlashCommandObject]; }\n * SlashCommandObject format:\n * { command: string, description: string, parametersExample?: string }\n * The \"parametersExample\" parameter is optional, and describes an example\n * of the parameters that command can take.\n *\n * When null, it does not add the plugin.\n */\n slashCommandSuggestion: {\n type: Object,\n default: null,\n },\n\n /**\n * Whether the input allows for block quote.\n */\n allowBlockquote: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether the input allows for bold to be introduced in the text.\n */\n allowBold: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether the input allows for bullet list to be introduced in the text.\n */\n allowBulletList: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether the input allows for italic to be introduced in the text.\n */\n allowItalic: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether the input allows for strike to be introduced in the text.\n */\n allowStrike: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether the input allows for underline to be introduced in the text.\n */\n allowUnderline: {\n type: Boolean,\n default: true,\n },\n },\n\n emits: [\n /**\n * Fires when send button is clicked\n *\n * @event submit\n * @type {String}\n */\n 'submit',\n\n /**\n * Fires when media is selected from image button\n *\n * @event select-media\n * @type {Array}\n */\n 'select-media',\n\n /**\n * Fires when media is dropped into the message input\n *\n * @event add-media\n * @type {Array}\n */\n 'add-media',\n\n /**\n * Fires when media is pasted into the message input\n *\n * @event paste-media\n * @type {Array}\n */\n 'paste-media',\n\n /**\n * Fires when cancel button is pressed (only on edit mode)\n *\n * @event cancel\n * @type {Boolean}\n */\n 'cancel',\n\n /**\n * Fires when skin tone is selected from the emoji picker\n *\n * @event skin-tone\n * @type {String}\n */\n 'skin-tone',\n\n /**\n * Fires when emoji is selected from the emoji picker\n *\n * @event selected-emoji\n * @type {String}\n */\n 'selected-emoji',\n\n /**\n * Fires when a slash command is selected\n *\n * @event selected-command\n * @type {String}\n */\n 'selected-command',\n\n /**\n * Native focus event\n * @event input\n * @type {String|JSON}\n */\n 'focus',\n\n /**\n * Native blur event\n * @event input\n * @type {String|JSON}\n */\n 'blur',\n\n /**\n * Native input event\n * @event input\n * @type {String|JSON}\n */\n 'input',\n\n /**\n * Event to sync the value with the parent\n * @event update:value\n * @type {String|JSON}\n */\n 'update:value',\n ],\n\n data () {\n return {\n internalInputValue: this.value, // internal input content\n hasFocus: false,\n imagePickerFocus: false,\n emojiPickerFocus: false,\n sendButtonFocus: false,\n emojiPickerOpened: false,\n };\n },\n\n computed: {\n inputLength () {\n return this.internalInputValue.length;\n },\n\n displayCharacterLimitWarning () {\n return Boolean(this.showCharacterLimit) &&\n ((this.showCharacterLimit.count - this.inputLength) <= this.showCharacterLimit.warning);\n },\n\n characterLimitTooltipEnabled () {\n return this.showCharacterLimit.message && (this.showCharacterLimit.count - this.inputLength < 0);\n },\n\n isSendDisabled () {\n return this.disableSend ||\n (this.showCharacterLimit && this.inputLength > this.showCharacterLimit.count);\n },\n\n computedCloseButtonProps () {\n return {\n ariaLabel: 'Close',\n };\n },\n\n emojiPickerHovered () {\n return this.emojiPickerFocus || this.emojiPickerOpened;\n },\n },\n\n watch: {\n value (newValue) {\n this.internalInputValue = newValue;\n },\n },\n\n methods: {\n onDrag (e) {\n e.stopPropagation();\n e.preventDefault();\n },\n\n onDrop (e) {\n e.stopPropagation();\n e.preventDefault();\n\n const dt = e.dataTransfer;\n const files = Array.from(dt.files);\n this.$emit('add-media', files);\n },\n\n onPaste (e) {\n if (e.clipboardData.files.length) {\n e.stopPropagation();\n e.preventDefault();\n const files = [...e.clipboardData.files];\n this.$emit('paste-media', files);\n }\n },\n\n onSkinTone (skinTone) {\n this.$emit('skin-tone', skinTone);\n },\n\n onSelectEmoji (emoji) {\n if (!emoji) {\n this.emojiPickerOpened = false;\n return;\n }\n\n // Insert emoji into the editor\n this.$refs.richTextEditor.editor.commands.insertContent({\n type: 'emoji',\n attrs: {\n code: emoji.shortname,\n },\n });\n this.emojiPickerOpened = false;\n this.$emit('selected-emoji', emoji);\n },\n\n onSelectedCommand (command) {\n this.$emit('selected-command', command);\n },\n\n onSelectImage () {\n this.$refs.messageInputImageUpload.$refs.input.click();\n },\n\n onImageUpload () {\n this.$emit('select-media', this.$refs.messageInputImageUpload.$refs.input.files);\n },\n\n toggleEmojiPicker () {\n this.emojiPickerOpened = !this.emojiPickerOpened;\n },\n\n onSend () {\n if (this.isSendDisabled) {\n return;\n }\n this.$emit('submit', this.internalInputValue);\n },\n\n onCancel () {\n this.$emit('cancel');\n },\n\n onFocus (event) {\n this.hasFocus = true;\n this.$refs.richTextEditor?.focusEditor();\n this.$emit('focus', event);\n },\n\n onBlur (event) {\n this.hasFocus = false;\n this.$emit('blur', event);\n },\n\n onInput (event) {\n this.$emit('input', event);\n this.$emit('update:value', event);\n },\n },\n};\n</script>\n\n<style lang=\"less\">\n.dt-message-input--remaining-char-tooltip {\n margin-top: auto;\n margin-bottom: auto;\n}\n.dt-message-input--remaining-char {\n font-size: 1.2rem;\n}\n\n.message-input-button__disabled {\n background-color: unset;\n color: var(--theme-sidebar-icon-color);\n cursor: default;\n}\n\n.dt-message-input--cancel-button {\n margin-right: var(--dt-space-300);\n}\n</style>\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"message-input.js","sources":["../../recipes/conversation_view/message_input/message_input.vue"],"sourcesContent":["<!-- eslint-disable vue/no-restricted-class -->\n<template>\n <div\n data-qa=\"dt-message-input\"\n role=\"presentation\"\n :class=\"['d-d-flex', 'd-fd-column', 'd-bar8', 'd-baw1', 'd-ba', 'd-c-text',\n { 'd-bc-bold d-bs-sm': hasFocus, 'd-bc-default': !hasFocus }]\"\n @click=\"$refs.richTextEditor?.focusEditor()\"\n @drag-enter=\"onDrag\"\n @drag-over=\"onDrag\"\n @drop=\"onDrop\"\n @keydown.enter.exact=\"onSend\"\n @paste=\"onPaste\"\n >\n <!-- Some wrapper to restrict the height and show the scrollbar -->\n <div\n class=\"d-of-auto d-mx16 d-mt8 d-mb4\"\n :style=\"{ 'max-height': maxHeight }\"\n >\n <dt-rich-text-editor\n ref=\"richTextEditor\"\n v-model=\"internalInputValue\"\n :editable=\"editable\"\n :input-aria-label=\"inputAriaLabel\"\n :input-class=\"inputClass\"\n :output-format=\"outputFormat\"\n :auto-focus=\"autoFocus\"\n :link=\"link\"\n :placeholder=\"placeholder\"\n :mention-suggestion=\"mentionSuggestion\"\n :channel-suggestion=\"channelSuggestion\"\n :slash-command-suggestion=\"slashCommandSuggestion\"\n :allow-blockquote=\"allowBlockquote\"\n :allow-bold=\"allowBold\"\n :allow-bullet-list=\"allowBulletList\"\n :allow-italic=\"allowItalic\"\n :allow-strike=\"allowStrike\"\n :allow-underline=\"allowUnderline\"\n v-bind=\"$attrs\"\n @focus=\"onFocus\"\n @blur=\"onBlur\"\n @input=\"onInput($event)\"\n @selected-command=\"onSelectedCommand\"\n />\n </div>\n <!-- @slot Slot for attachment carousel -->\n <slot name=\"middle\" />\n <!-- Section for the bottom UI -->\n <section class=\"d-d-flex d-jc-space-between d-mx8 d-my4\">\n <!-- Left content -->\n <div class=\"d-d-flex\">\n <dt-tooltip\n v-if=\"showImagePicker\"\n placement=\"top-start\"\n :message=\"showImagePicker.tooltipLabel\"\n :offset=\"[-4, -4]\"\n >\n <template #anchor>\n <dt-button\n data-qa=\"dt-message-input-image-btn\"\n size=\"sm\"\n circle\n :kind=\"imagePickerFocus ? 'default' : 'muted'\"\n importance=\"clear\"\n :aria-label=\"showImagePicker.ariaLabel\"\n @click=\"onSelectImage\"\n @mouseenter=\"imagePickerFocus = true\"\n @mouseleave=\"imagePickerFocus = false\"\n @focus=\"imagePickerFocus = true\"\n @blur=\"imagePickerFocus = false\"\n >\n <template #icon>\n <dt-icon\n name=\"image\"\n size=\"300\"\n />\n </template>\n </dt-button>\n <dt-input\n ref=\"messageInputImageUpload\"\n data-qa=\"dt-message-input-image-input\"\n accept=\"image/*, video/*\"\n type=\"file\"\n class=\"d-ps-absolute\"\n multiple\n hidden\n @input=\"onImageUpload\"\n />\n </template>\n </dt-tooltip>\n <dt-popover\n v-if=\"showEmojiPicker\"\n data-qa=\"dt-message-input-emoji-picker-popover\"\n :open.sync=\"emojiPickerOpened\"\n initial-focus-element=\"#searchInput\"\n padding=\"none\"\n >\n <template #anchor=\"{ attrs }\">\n <dt-button\n v-dt-tooltip=\"emojiTooltipMessage\"\n v-bind=\"attrs\"\n data-qa=\"dt-message-input-emoji-picker-btn\"\n size=\"sm\"\n circle\n :kind=\"emojiPickerHovered ? 'default' : 'muted'\"\n importance=\"clear\"\n :aria-label=\"emojiButtonAriaLabel\"\n @click=\"toggleEmojiPicker\"\n @mouseenter=\"emojiPickerFocus = true\"\n @mouseleave=\"emojiPickerFocus = false\"\n @focus=\"emojiPickerFocus = true\"\n @blur=\"emojiPickerFocus = false\"\n >\n <template #icon>\n <dt-icon\n :name=\"!emojiPickerHovered ? 'satisfied' : 'very-satisfied'\"\n size=\"300\"\n />\n </template>\n </dt-button>\n </template>\n <template\n #content=\"{ close }\"\n >\n <dt-emoji-picker\n v-bind=\"emojiPickerProps\"\n @skin-tone=\"onSkinTone\"\n @selected-emoji=\"(emoji) => { close(); onSelectEmoji(emoji); }\"\n />\n </template>\n </dt-popover>\n <!-- @slot Slot for emojiGiphy picker -->\n <slot name=\"emojiGiphyPicker\" />\n </div>\n <!-- Right content -->\n <div class=\"d-d-flex\">\n <!-- Optionally displayed remaining character counter -->\n <dt-tooltip\n v-if=\"Boolean(showCharacterLimit)\"\n class=\"dt-message-input--remaining-char-tooltip\"\n placement=\"top-end\"\n :enabled=\"characterLimitTooltipEnabled\"\n :message=\"showCharacterLimit.message\"\n :offset=\"[10, -8]\"\n >\n <template #anchor>\n <p\n v-show=\"displayCharacterLimitWarning\"\n class=\"d-fc-error d-mr16 dt-message-input--remaining-char\"\n data-qa=\"dt-message-input-character-limit\"\n >\n {{ showCharacterLimit.count - inputLength }}\n </p>\n </template>\n </dt-tooltip>\n\n <!-- Cancel button for edit mode -->\n <dt-button\n v-if=\"showCancel\"\n data-qa=\"dt-message-input-cancel-button\"\n class=\"dt-message-input--cancel-button\"\n size=\"sm\"\n kind=\"muted\"\n importance=\"clear\"\n :aria-label=\"showCancel.ariaLabel\"\n @click=\"onCancel\"\n >\n <p>{{ showCancel.text }}</p>\n </dt-button>\n\n <!-- Send button -->\n <dt-tooltip\n v-if=\"showSend\"\n placement=\"top-end\"\n :enabled=\"!showSend\"\n :message=\"showSend.tooltipLabel\"\n :show=\"!isSendDisabled && sendButtonFocus\"\n :offset=\"[6, -8]\"\n >\n <template #anchor>\n <!-- Right positioned UI - send button -->\n <dt-button\n data-qa=\"dt-message-input-send-btn\"\n size=\"sm\"\n kind=\"default\"\n importance=\"primary\"\n :class=\"[\n {\n 'message-input-button__disabled d-fc-muted': isSendDisabled,\n 'd-btn--circle': showSend.icon,\n },\n ]\"\n :aria-label=\"showSend.ariaLabel\"\n :aria-disabled=\"isSendDisabled\"\n @click=\"onSend\"\n @mouseenter=\"sendButtonFocus = true\"\n @mouseleave=\"sendButtonFocus = false\"\n @focus=\"sendButtonFocus = true\"\n @blur=\"sendButtonFocus = false\"\n >\n <template\n v-if=\"showSend.icon\"\n #icon\n >\n <dt-icon\n :name=\"showSend.icon\"\n size=\"300\"\n />\n </template>\n <template\n v-if=\"showSend.text\"\n >\n <p>{{ showSend.text }}</p>\n </template>\n </dt-button>\n </template>\n </dt-tooltip>\n </div>\n </section>\n </div>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport {\n DtRichTextEditor,\n RICH_TEXT_EDITOR_OUTPUT_FORMATS,\n RICH_TEXT_EDITOR_AUTOFOCUS_TYPES,\n} from '@/components/rich_text_editor';\nimport { DtButton } from '@/components/button';\nimport { DtIcon } from '@/components/icon';\nimport { DtEmojiPicker } from '@/components/emoji_picker';\nimport { DtPopover } from '@/components/popover';\nimport { DtInput } from '@/components/input';\nimport { DtTooltip } from '@/components/tooltip';\n\nexport default {\n name: 'DtRecipeMessageInput',\n\n components: {\n DtButton,\n DtEmojiPicker,\n DtIcon,\n DtInput,\n DtPopover,\n DtRichTextEditor,\n DtTooltip,\n },\n\n mixins: [],\n\n inheritAttrs: false,\n\n props: {\n /**\n * Value of the input. The object format should match TipTap's JSON\n * document structure: https://tiptap.dev/guide/output#option-1-json\n */\n value: {\n type: [Object, String],\n default: '',\n },\n\n /**\n * Whether the input is editable\n */\n editable: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Descriptive label for the input element\n */\n inputAriaLabel: {\n type: String,\n required: true,\n default: '',\n },\n\n /**\n * Additional class name for the input element. Only accepts a String value\n * because this is passed to the editor via options. For multiple classes,\n * join them into one string, e.g. \"d-p8 d-hmx96\"\n */\n inputClass: {\n type: String,\n default: '',\n },\n\n /**\n * Whether the input should receive focus after the component has been\n * mounted. Either one of `start`, `end`, `all` or a Boolean or a Number.\n * - `start` Sets the focus to the beginning of the input\n * - `end` Sets the focus to the end of the input\n * - `all` Selects the whole contents of the input\n * - `Number` Sets the focus to a specific position in the input\n * - `true` Defaults to `start`\n * - `false` Disables autofocus\n * @values true, false, start, end, all, number\n */\n autoFocus: {\n type: [Boolean, String, Number],\n default: false,\n validator (autoFocus) {\n if (typeof autoFocus === 'string') {\n return RICH_TEXT_EDITOR_AUTOFOCUS_TYPES.includes(autoFocus);\n }\n return true;\n },\n },\n\n /**\n * The output format that the editor uses when emitting the \"@input\" event.\n * One of `text`, `json`, `html`. See https://tiptap.dev/guide/output for\n * examples.\n * @values text, json, html\n */\n outputFormat: {\n type: String,\n default: 'text',\n validator (outputFormat) {\n return RICH_TEXT_EDITOR_OUTPUT_FORMATS.includes(outputFormat);\n },\n },\n\n /**\n * Enables the Link extension and optionally passes configurations to it\n */\n link: {\n type: [Boolean, Object],\n default: false,\n },\n\n /**\n * Placeholder text\n */\n placeholder: {\n type: String,\n default: '',\n },\n\n /**\n * Disable Send Button\n */\n disableSend: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Content area needs to dynamically adjust height based on the conversation area height.\n * can be vh|px|rem|em|%\n */\n maxHeight: {\n type: String,\n default: 'unset',\n },\n\n // Emoji picker props\n showEmojiPicker: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Props to pass into the emoji picker.\n */\n emojiPickerProps: {\n type: Object,\n default: () => ({}),\n validate (emojiPickerProps) {\n return [\n 'searchNoResultsLabel',\n 'searchResultsLabel',\n 'searchPlaceholderLabel',\n 'skinSelectorButtonTooltipLabel',\n 'tabSetLabels',\n ].every(prop => emojiPickerProps[prop] != null);\n },\n },\n\n /**\n * Emoji button tooltip label\n */\n emojiTooltipMessage: {\n type: String,\n default: 'Emoji',\n },\n\n // Aria label for buttons\n /**\n * Emoji button aria label\n */\n emojiButtonAriaLabel: {\n type: String,\n default: 'emoji button',\n },\n\n /**\n * Enable character Limit warning\n */\n showCharacterLimit: {\n type: [Boolean, Object],\n default: () => ({ count: 1500, warning: 500, message: '' }),\n },\n\n showImagePicker: {\n type: [Boolean, Object],\n default: () => ({ tooltipLabel: 'Attach Image', ariaLabel: 'image button' }),\n },\n\n /**\n * Send button defaults.\n */\n showSend: {\n type: [Boolean, Object],\n default: () => ({ icon: 'send' }),\n },\n\n /**\n * Cancel button defaults.\n */\n showCancel: {\n type: [Boolean, Object],\n default: () => ({ text: 'Cancel' }),\n },\n\n /**\n * suggestion object containing the items query function.\n * The valid keys passed into this object can be found here: https://tiptap.dev/api/utilities/suggestion\n *\n * The only required key is the items function which is used to query the contacts for suggestion.\n * items({ query }) => { return [ContactObject]; }\n * ContactObject format:\n * { name: string, avatarSrc: string, id: string }\n *\n * When null, it does not add the plugin.\n */\n mentionSuggestion: {\n type: Object,\n default: null,\n },\n\n /**\n * suggestion object containing the items query function.\n * The valid keys passed into this object can be found here: https://tiptap.dev/api/utilities/suggestion\n *\n * The only required key is the items function which is used to query the channels for suggestion.\n * items({ query }) => { return [ChannelObject]; }\n * ChannelObject format:\n * { name: string, id: string, locked: boolean }\n *\n * When null, it does not add the plugin. Setting locked to true will display a lock rather than hash.\n */\n channelSuggestion: {\n type: Object,\n default: null,\n },\n\n /**\n * suggestion object containing the items query function.\n * The valid keys passed into this object can be found here: https://tiptap.dev/api/utilities/suggestion\n *\n * The only required key is the items function which is used to query the slash commands for suggestion.\n * items({ query }) => { return [SlashCommandObject]; }\n * SlashCommandObject format:\n * { command: string, description: string, parametersExample?: string }\n * The \"parametersExample\" parameter is optional, and describes an example\n * of the parameters that command can take.\n *\n * When null, it does not add the plugin.\n */\n slashCommandSuggestion: {\n type: Object,\n default: null,\n },\n\n /**\n * Whether the input allows for block quote.\n */\n allowBlockquote: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether the input allows for bold to be introduced in the text.\n */\n allowBold: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether the input allows for bullet list to be introduced in the text.\n */\n allowBulletList: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether the input allows for italic to be introduced in the text.\n */\n allowItalic: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether the input allows for strike to be introduced in the text.\n */\n allowStrike: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Whether the input allows for underline to be introduced in the text.\n */\n allowUnderline: {\n type: Boolean,\n default: true,\n },\n },\n\n emits: [\n /**\n * Fires when send button is clicked\n *\n * @event submit\n * @type {String}\n */\n 'submit',\n\n /**\n * Fires when media is selected from image button\n *\n * @event select-media\n * @type {Array}\n */\n 'select-media',\n\n /**\n * Fires when media is dropped into the message input\n *\n * @event add-media\n * @type {Array}\n */\n 'add-media',\n\n /**\n * Fires when media is pasted into the message input\n *\n * @event paste-media\n * @type {Array}\n */\n 'paste-media',\n\n /**\n * Fires when cancel button is pressed (only on edit mode)\n *\n * @event cancel\n * @type {Boolean}\n */\n 'cancel',\n\n /**\n * Fires when skin tone is selected from the emoji picker\n *\n * @event skin-tone\n * @type {String}\n */\n 'skin-tone',\n\n /**\n * Fires when emoji is selected from the emoji picker\n *\n * @event selected-emoji\n * @type {String}\n */\n 'selected-emoji',\n\n /**\n * Fires when a slash command is selected\n *\n * @event selected-command\n * @type {String}\n */\n 'selected-command',\n\n /**\n * Native focus event\n * @event input\n * @type {String|JSON}\n */\n 'focus',\n\n /**\n * Native blur event\n * @event input\n * @type {String|JSON}\n */\n 'blur',\n\n /**\n * Native input event\n * @event input\n * @type {String|JSON}\n */\n 'input',\n\n /**\n * Event to sync the value with the parent\n * @event update:value\n * @type {String|JSON}\n */\n 'update:value',\n ],\n\n data () {\n return {\n internalInputValue: this.value, // internal input content\n hasFocus: false,\n imagePickerFocus: false,\n emojiPickerFocus: false,\n sendButtonFocus: false,\n emojiPickerOpened: false,\n };\n },\n\n computed: {\n inputLength () {\n return this.internalInputValue.length;\n },\n\n displayCharacterLimitWarning () {\n return Boolean(this.showCharacterLimit) &&\n ((this.showCharacterLimit.count - this.inputLength) <= this.showCharacterLimit.warning);\n },\n\n characterLimitTooltipEnabled () {\n return this.showCharacterLimit.message && (this.showCharacterLimit.count - this.inputLength < 0);\n },\n\n isSendDisabled () {\n return this.disableSend ||\n (this.showCharacterLimit && this.inputLength > this.showCharacterLimit.count);\n },\n\n computedCloseButtonProps () {\n return {\n ariaLabel: 'Close',\n };\n },\n\n emojiPickerHovered () {\n return this.emojiPickerFocus || this.emojiPickerOpened;\n },\n },\n\n watch: {\n value (newValue) {\n this.internalInputValue = newValue;\n },\n\n emojiPickerOpened (newValue) {\n if (!newValue) {\n this.$refs.richTextEditor?.focusEditor();\n }\n },\n },\n\n methods: {\n onDrag (e) {\n e.stopPropagation();\n e.preventDefault();\n },\n\n onDrop (e) {\n e.stopPropagation();\n e.preventDefault();\n\n const dt = e.dataTransfer;\n const files = Array.from(dt.files);\n this.$emit('add-media', files);\n },\n\n onPaste (e) {\n if (e.clipboardData.files.length) {\n e.stopPropagation();\n e.preventDefault();\n const files = [...e.clipboardData.files];\n this.$emit('paste-media', files);\n }\n },\n\n onSkinTone (skinTone) {\n this.$emit('skin-tone', skinTone);\n },\n\n onSelectEmoji (emoji) {\n if (!emoji) {\n return;\n }\n\n // Insert emoji into the editor\n this.$refs.richTextEditor.editor.commands.insertContent({\n type: 'emoji',\n attrs: {\n code: emoji.shortname,\n },\n });\n this.$emit('selected-emoji', emoji);\n },\n\n onSelectedCommand (command) {\n this.$emit('selected-command', command);\n },\n\n onSelectImage () {\n this.$refs.messageInputImageUpload.$refs.input.click();\n },\n\n onImageUpload () {\n this.$emit('select-media', this.$refs.messageInputImageUpload.$refs.input.files);\n },\n\n toggleEmojiPicker () {\n this.emojiPickerOpened = !this.emojiPickerOpened;\n },\n\n onSend () {\n if (this.isSendDisabled) {\n return;\n }\n this.$emit('submit', this.internalInputValue);\n },\n\n onCancel () {\n this.$emit('cancel');\n },\n\n onFocus (event) {\n this.hasFocus = true;\n this.$refs.richTextEditor?.focusEditor();\n this.$emit('focus', event);\n },\n\n onBlur (event) {\n this.hasFocus = false;\n this.$emit('blur', event);\n },\n\n onInput (event) {\n this.$emit('input', event);\n this.$emit('update:value', event);\n },\n },\n};\n</script>\n\n<style lang=\"less\">\n.dt-message-input--remaining-char-tooltip {\n margin-top: auto;\n margin-bottom: auto;\n}\n.dt-message-input--remaining-char {\n font-size: 1.2rem;\n}\n\n.message-input-button__disabled {\n background-color: unset;\n color: var(--theme-sidebar-icon-color);\n cursor: default;\n}\n\n.dt-message-input--cancel-button {\n margin-right: var(--dt-space-300);\n}\n</style>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4OA,MAAA,YAAA;AAAA,EACA,MAAA;AAAA,EAEA,YAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,QAAA,CAAA;AAAA,EAEA,cAAA;AAAA,EAEA,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,OAAA;AAAA,MACA,MAAA,CAAA,QAAA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,UAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,gBAAA;AAAA,MACA,MAAA;AAAA,MACA,UAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,YAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaA,WAAA;AAAA,MACA,MAAA,CAAA,SAAA,QAAA,MAAA;AAAA,MACA,SAAA;AAAA,MACA,UAAA,WAAA;AACA,YAAA,OAAA,cAAA,UAAA;AACA,iBAAA,iCAAA,SAAA,SAAA;AAAA,QACA;AACA,eAAA;AAAA,MACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,cAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,MACA,UAAA,cAAA;AACA,eAAA,gCAAA,SAAA,YAAA;AAAA,MACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,MAAA;AAAA,MACA,MAAA,CAAA,SAAA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,aAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,aAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA,IAGA,iBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,kBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA,OAAA,CAAA;AAAA,MACA,SAAA,kBAAA;AACA,eAAA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACA,EAAA,MAAA,UAAA,iBAAA,IAAA,KAAA,IAAA;AAAA,MACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,qBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,sBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,oBAAA;AAAA,MACA,MAAA,CAAA,SAAA,MAAA;AAAA,MACA,SAAA,OAAA,EAAA,OAAA,MAAA,SAAA,KAAA,SAAA;IACA;AAAA,IAEA,iBAAA;AAAA,MACA,MAAA,CAAA,SAAA,MAAA;AAAA,MACA,SAAA,OAAA,EAAA,cAAA,gBAAA,WAAA,eAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,UAAA;AAAA,MACA,MAAA,CAAA,SAAA,MAAA;AAAA,MACA,SAAA,OAAA,EAAA,MAAA;IACA;AAAA;AAAA;AAAA;AAAA,IAKA,YAAA;AAAA,MACA,MAAA,CAAA,SAAA,MAAA;AAAA,MACA,SAAA,OAAA,EAAA,MAAA;IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaA,mBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaA,mBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAeA,wBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,iBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,iBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,aAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,aAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAKA,gBAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA;AAAA,EACA;AAAA,EAEA,OAAA;AACA,WAAA;AAAA,MACA,oBAAA,KAAA;AAAA;AAAA,MACA,UAAA;AAAA,MACA,kBAAA;AAAA,MACA,kBAAA;AAAA,MACA,iBAAA;AAAA,MACA,mBAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,UAAA;AAAA,IACA,cAAA;AACA,aAAA,KAAA,mBAAA;AAAA,IACA;AAAA,IAEA,+BAAA;AACA,aAAA,QAAA,KAAA,kBAAA,KACA,KAAA,mBAAA,QAAA,KAAA,eAAA,KAAA,mBAAA;AAAA,IACA;AAAA,IAEA,+BAAA;AACA,aAAA,KAAA,mBAAA,WAAA,KAAA,mBAAA,QAAA,KAAA,cAAA;AAAA,IACA;AAAA,IAEA,iBAAA;AACA,aAAA,KAAA,eACA,KAAA,sBAAA,KAAA,cAAA,KAAA,mBAAA;AAAA,IACA;AAAA,IAEA,2BAAA;AACA,aAAA;AAAA,QACA,WAAA;AAAA,MACA;AAAA,IACA;AAAA,IAEA,qBAAA;AACA,aAAA,KAAA,oBAAA,KAAA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,OAAA;AAAA,IACA,MAAA,UAAA;AACA,WAAA,qBAAA;AAAA,IACA;AAAA,IAEA,kBAAA,UAAA;;AACA,UAAA,CAAA,UAAA;AACA,mBAAA,MAAA,mBAAA,mBAAA;AAAA,MACA;AAAA,IACA;AAAA,EACA;AAAA,EAEA,SAAA;AAAA,IACA,OAAA,GAAA;AACA,QAAA,gBAAA;AACA,QAAA,eAAA;AAAA,IACA;AAAA,IAEA,OAAA,GAAA;AACA,QAAA,gBAAA;AACA,QAAA,eAAA;AAEA,YAAA,KAAA,EAAA;AACA,YAAA,QAAA,MAAA,KAAA,GAAA,KAAA;AACA,WAAA,MAAA,aAAA,KAAA;AAAA,IACA;AAAA,IAEA,QAAA,GAAA;AACA,UAAA,EAAA,cAAA,MAAA,QAAA;AACA,UAAA,gBAAA;AACA,UAAA,eAAA;AACA,cAAA,QAAA,CAAA,GAAA,EAAA,cAAA,KAAA;AACA,aAAA,MAAA,eAAA,KAAA;AAAA,MACA;AAAA,IACA;AAAA,IAEA,WAAA,UAAA;AACA,WAAA,MAAA,aAAA,QAAA;AAAA,IACA;AAAA,IAEA,cAAA,OAAA;AACA,UAAA,CAAA,OAAA;AACA;AAAA,MACA;AAGA,WAAA,MAAA,eAAA,OAAA,SAAA,cAAA;AAAA,QACA,MAAA;AAAA,QACA,OAAA;AAAA,UACA,MAAA,MAAA;AAAA,QACA;AAAA,MACA,CAAA;AACA,WAAA,MAAA,kBAAA,KAAA;AAAA,IACA;AAAA,IAEA,kBAAA,SAAA;AACA,WAAA,MAAA,oBAAA,OAAA;AAAA,IACA;AAAA,IAEA,gBAAA;AACA,WAAA,MAAA,wBAAA,MAAA,MAAA,MAAA;AAAA,IACA;AAAA,IAEA,gBAAA;AACA,WAAA,MAAA,gBAAA,KAAA,MAAA,wBAAA,MAAA,MAAA,KAAA;AAAA,IACA;AAAA,IAEA,oBAAA;AACA,WAAA,oBAAA,CAAA,KAAA;AAAA,IACA;AAAA,IAEA,SAAA;AACA,UAAA,KAAA,gBAAA;AACA;AAAA,MACA;AACA,WAAA,MAAA,UAAA,KAAA,kBAAA;AAAA,IACA;AAAA,IAEA,WAAA;AACA,WAAA,MAAA,QAAA;AAAA,IACA;AAAA,IAEA,QAAA,OAAA;;AACA,WAAA,WAAA;AACA,iBAAA,MAAA,mBAAA,mBAAA;AACA,WAAA,MAAA,SAAA,KAAA;AAAA,IACA;AAAA,IAEA,OAAA,OAAA;AACA,WAAA,WAAA;AACA,WAAA,MAAA,QAAA,KAAA;AAAA,IACA;AAAA,IAEA,QAAA,OAAA;AACA,WAAA,MAAA,SAAA,KAAA;AACA,WAAA,MAAA,gBAAA,KAAA;AAAA,IACA;AAAA,EACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -306,21 +306,21 @@ const suggestionOptions = {
306
306
  }
307
307
  };
308
308
  const EmojiPluginKey = new state.PluginKey("emoji");
309
- const inputShortCodeRegex = /:\w+:$/;
310
- const emojiShortCodeRegex = /:\w+:/g;
309
+ const inputShortCodeRegex = new RegExp("(^| |(?<=:))(:\\w+:)$");
311
310
  const inputUnicodeRegex = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])$/;
312
311
  const pasteUnicodeRegex = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/g;
313
312
  const inputRuleMatch = (match) => {
314
313
  if (match && common_emoji.codeToEmojiData(match[0])) {
314
+ const text = match[2] || match[0];
315
315
  return {
316
316
  index: match.index,
317
- text: match[0],
317
+ text,
318
318
  match
319
319
  };
320
320
  }
321
321
  };
322
322
  const shortCodePasteMatch = (text) => {
323
- const matches = [...text.matchAll(emojiShortCodeRegex)];
323
+ const matches = [...text.matchAll(common_emoji.emojiShortCodeRegex)];
324
324
  return matches.filter((match) => common_emoji.codeToEmojiData(match[0])).map((match) => ({
325
325
  index: match.index,
326
326
  text: match[0],
@@ -373,6 +373,8 @@ const Emoji = core.Node.create({
373
373
  core.nodeInputRule({
374
374
  find: (text) => {
375
375
  const match = text.match(inputShortCodeRegex);
376
+ if (!match)
377
+ return;
376
378
  return inputRuleMatch(match);
377
379
  },
378
380
  type: this.type,
@@ -385,6 +387,8 @@ const Emoji = core.Node.create({
385
387
  core.nodeInputRule({
386
388
  find: (text) => {
387
389
  const match = text.match(inputUnicodeRegex);
390
+ if (!match)
391
+ return;
388
392
  return inputRuleMatch(match);
389
393
  },
390
394
  type: this.type,
@@ -567,7 +571,7 @@ function autolink(options) {
567
571
  });
568
572
  }
569
573
  const defaultAttributes = {
570
- class: "d-link d-c-text d-d-inline-block",
574
+ class: "d-link d-c-text d-d-inline-block d-wb-break-all",
571
575
  rel: "noopener noreferrer nofollow"
572
576
  };
573
577
  const Link = core.Mark.create({
@@ -892,7 +896,7 @@ const SlashCommandPlugin = Mention.extend({
892
896
  command: {
893
897
  default: ""
894
898
  },
895
- paramentersExample: {
899
+ parametersExample: {
896
900
  default: ""
897
901
  },
898
902
  description: {
@@ -1438,7 +1442,14 @@ const _sfc_main = {
1438
1442
  * @event focus
1439
1443
  * @type {FocusEvent}
1440
1444
  */
1441
- "focus"
1445
+ "focus",
1446
+ /**
1447
+ * Fires when a slash command is selected
1448
+ *
1449
+ * @event selected-command
1450
+ * @type {String}
1451
+ */
1452
+ "selected-command"
1442
1453
  ],
1443
1454
  data() {
1444
1455
  return {
@@ -1607,14 +1618,16 @@ const _sfc_main = {
1607
1618
  this.editor.commands.setContent(this.internalValue, true);
1608
1619
  },
1609
1620
  parseEmojis() {
1610
- const matches = [...this.value.matchAll(emojiRegex()), ...this.value.matchAll(emojiShortCodeRegex)];
1621
+ const matches = new Set(
1622
+ [...this.value.matchAll(emojiRegex()), ...this.value.matchAll(common_emoji.emojiShortCodeRegex)].map((match) => match[0].trim())
1623
+ );
1611
1624
  if (!matches)
1612
1625
  return;
1613
1626
  matches.forEach((match) => {
1614
- const emoji = common_emoji.codeToEmojiData(match[0]);
1627
+ const emoji = common_emoji.codeToEmojiData(match);
1615
1628
  if (!emoji)
1616
1629
  return;
1617
- this.internalValue = this.internalValue.replace(new RegExp(` ${match[0]}`), ` <emoji-component code="${emoji.shortname}"></emoji-component>`);
1630
+ this.internalValue = this.internalValue.replace(new RegExp(`${match}`, "g"), `<emoji-component code="${emoji.shortname}"></emoji-component>`);
1618
1631
  });
1619
1632
  },
1620
1633
  parseChannels() {