UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

103 lines (102 loc) 3.33 kB
import { findShortCodes, findEmojis } from "../../common/emoji.js"; import { h, resolveDynamicComponent } from "vue"; import { ICON_SIZE_MODIFIERS } from "../icon/icon_constants.js"; import DtEmoji from "../emoji/emoji.vue.js"; const COMMENT_TYPE = h(resolveDynamicComponent(null)).type; const _sfc_main = { compatConfig: { MODE: 3 }, name: "DtEmojiTextWrapper", components: { DtEmoji }, props: { /** * Element type (tag name) to use for the wrapper. */ elementType: { type: String, default: "div" }, /** * The icon size to render the emojis at: 100 to 800 */ size: { type: String, default: "500", validator: (t) => Object.keys(ICON_SIZE_MODIFIERS).includes(t) } }, data() { return { loadingEmojiJson: true }; }, async created() { this.loadingEmojiJson = false; }, methods: { /** * Replaces the valid codes from the text content with a DtEmoji component. * @returns {Array<VNode|string>} */ replaceDtEmojis(replaceList, textContent) { if (!replaceList.length) return textContent; const escapedReplaceList = replaceList.map( (item) => item.replace(/\*/g, "\\*") ); const regexp = new RegExp(`(${escapedReplaceList.join("|")})`, "g"); const items = textContent.split(regexp); return items.filter((item) => item.trim() !== "").map((item) => { if (replaceList.includes(item)) { return h(DtEmoji, { code: item, size: this.size }); } return h("span", { class: "d-emoji-text-wrapper__text" }, item); }); }, /** * Recursively search the Vue virtual DOM to find text * @param VNode * @returns {VNode|*} */ searchVNodes(VNode) { var _a; if (typeof VNode === "string") return this.searchCodes(VNode); if (VNode.type === COMMENT_TYPE) return VNode; if (typeof VNode.type === "symbol") return this.searchCodes(VNode.children); if ((_a = VNode.props) == null ? void 0 : _a.innerHTML) return this.searchVNodes(VNode.props.innerHTML); const children = Array.isArray(VNode.children) ? VNode.children : [VNode.children]; return h(VNode.type, VNode.props, children.map((VNodeChild) => this.searchVNodes(VNodeChild))); }, // TODO: Find a way to crawl vue components replaceVueComponentVNodeContent(VNode) { }, /** * Find codes in text. * @param textContent string * @returns {Array<VNode|string>|string} */ searchCodes(textContent) { const shortcodes = findShortCodes(textContent); const emojis = findEmojis(textContent); const replaceList = [...shortcodes, ...emojis]; if (replaceList.length === 0) return textContent; return this.replaceDtEmojis(replaceList, textContent); } }, render() { const defaultSlotContent = this.$slots.default ? this.$slots.default() : []; return h( this.elementType, { "data-qa": "emoji-text-wrapper", class: "d-emoji-text-wrapper" }, this.loadingEmojiJson ? defaultSlotContent : defaultSlotContent.map((VNode) => this.searchVNodes(VNode)) ); } }; const DtEmojiTextWrapper = _sfc_main; export { DtEmojiTextWrapper as default }; //# sourceMappingURL=emoji_text_wrapper.vue.js.map