UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

1 lines 9.36 kB
{"version":3,"file":"index.cjs","names":["emojiPattern","emojiJsonLocal"],"sources":["../../../common/emoji/index.js"],"sourcesContent":["import { emojiPattern } from 'regex-combined-emojis';\nimport emojiJsonLocal from 'emoji-toolkit/emoji_strategy.json' with { type: 'json' };\n\nexport const emojiRegex = new RegExp(emojiPattern, 'g');\nexport const emojiVersion = '9.0';\nexport const defaultEmojiAssetUrl = 'https://cdn.jsdelivr.net/joypixels/assets/' + emojiVersion + '/png/unicode/32/';\nexport let customEmojiAssetUrl = null;\n\n// Used for emoji 16px and smaller\nexport let emojiImageUrlSmall = defaultEmojiAssetUrl;\nexport let emojiFileExtensionSmall = '.png';\n\n// Used for emoji larger than 16px\nexport let emojiImageUrlLarge = defaultEmojiAssetUrl;\nexport let emojiFileExtensionLarge = '.png';\n\nexport const emojiJson = emojiJsonLocal;\n\nexport const emojiShortCodeRegex = /(^| |(?<=:))(:\\w+:)/g;\n\nexport function getEmojiData () {\n return emojiJson;\n}\n\nexport function setEmojiAssetUrlSmall (url, fileExtension = '.png') {\n if (!url.endsWith('/')) {\n url = url + '/';\n }\n emojiImageUrlSmall = url;\n emojiFileExtensionSmall = fileExtension;\n}\n\nexport function setEmojiAssetUrlLarge (url, fileExtension = '.svg') {\n if (!url.endsWith('/')) {\n url = url + '/';\n }\n emojiImageUrlLarge = url;\n emojiFileExtensionLarge = fileExtension;\n}\n\nexport function setCustomEmojiUrl (url) {\n customEmojiAssetUrl = url;\n}\n\nexport function setCustomEmojiJson (json) {\n validateCustomEmojiJson(json);\n}\n\n/**\n * Validate custom emoji json\n */\nexport function validateCustomEmojiJson (json) {\n const customEmojiProps = [\n 'custom',\n 'date_added',\n 'image',\n ];\n const customEmojiRequiredProps = [\n 'date_added',\n 'image',\n 'unicode_output',\n 'shortname',\n 'shortname_alternates',\n 'custom',\n 'name',\n ];\n\n /**\n * Update single emoji properties.\n * If the property exists in emojiData, it'll add the values if the property is an array, otherwise will overwrite.\n * If not exists, will add the property to the emojiData object.\n */\n const _updateNativeEmojiData = (emojiData, propName, propValue) => {\n if (emojiData[propName] === undefined) {\n if (!customEmojiProps.includes(propName)) {\n return;\n }\n\n // new property to add\n emojiData[propName] = propValue;\n } else {\n if (Array.isArray(emojiData[propName])) {\n emojiData[propName] = emojiData[propName].concat(propValue);\n } else {\n emojiData[propName] = propValue;\n }\n }\n };\n\n Object.entries(json).forEach((item) => {\n const [customEmojiKey, customEmojiValue] = item;\n\n if (customEmojiKey in emojiJson) {\n // custom emoji exists in emoji json which means to update some data in the native emoji\n const emojiData = emojiJson[customEmojiKey];\n\n for (const customEmojiPropertyName in customEmojiValue) {\n const customEmojiPropertyValue = customEmojiValue[customEmojiPropertyName];\n\n _updateNativeEmojiData(emojiData, customEmojiPropertyName, customEmojiPropertyValue);\n }\n } else {\n // new custom emoji\n const _validateRequiredProps = () =>\n customEmojiRequiredProps.every((val) => {\n return customEmojiValue[val] !== undefined;\n });\n\n if (_validateRequiredProps()) {\n emojiJson[customEmojiKey] = customEmojiValue;\n } else {\n console.error(\n 'The following custom emoji doesn\\'t contain the required properties:',\n customEmojiValue,\n );\n }\n }\n });\n}\n\n// recursively searches the emoji data object containing data for all emojis\n// and returns the object with the specified shortcode.\nexport function shortcodeToEmojiData (shortcode) {\n // eslint-disable-next-line complexity\n function f (o, key) {\n if (!o || typeof o !== 'object') {\n return;\n }\n if ('shortname' in o) {\n if (o.shortname === shortcode || o.shortname_alternates.includes(shortcode)) {\n o.key = key;\n reference = o;\n return true;\n }\n }\n Object.keys(o).some(function (k) {\n return f(o[k], k);\n });\n }\n\n let reference;\n f(getEmojiData(), null);\n return reference;\n}\n\nexport function getEmojiShortCode (emoji) {\n if (emoji.startsWith(':')) return emoji;\n\n const unicode = unicodeToString(emoji);\n return emojiJson[unicode]?.shortname;\n}\n\n// Takes in an emoji unicode character(s) and converts it to an emoji string in the format the emoji data object expects\n// as a key. There can be multiple unicode characters in an emoji to denote the emoji itself, skin tone, gender\n// and such. Note that this function does NOT return variation selectors (fe0f) or zero width joiners (200d), as these\n// are not included as part of the key in the emoji.json.\n//\n// Example:\n// return value for smile emoji (no skin tone): 1f600\n// return value for left facing fist (light skin tone): 1f91b-1f3fb\nexport function unicodeToString (emoji) {\n let key = '';\n for (const codePoint of emoji) {\n const codepoint = codePoint.codePointAt(0).toString(16).padStart(4, '0');\n\n // skip 200d and fe0f as these are not included in emoji_strategy.json keys\n if (['200d', 'fe0f'].includes(codepoint)) continue;\n if (key !== '') { key = key + '-'; }\n key = key + codepoint;\n }\n return key;\n}\n\n// Takes in unicode in string form ex: '1f91b-1f3fb' and converts it to an actual unicode character.\nexport function stringToUnicode (str) {\n const uChars = str.split('-');\n let result = '';\n uChars.forEach((uChar) => {\n result = result + String.fromCodePoint(parseInt(uChar, 16));\n });\n return result;\n}\n\n// Takes in a code (which could be unicode or shortcode) and returns the emoji data for it.\nexport function codeToEmojiData (code) {\n code = code?.trim();\n if (code.startsWith(':') && code.endsWith(':')) {\n return shortcodeToEmojiData(code);\n } else {\n const unicodeString = unicodeToString(code);\n const result = emojiJson[unicodeString];\n if (result) result.key = unicodeString;\n return result;\n }\n}\n\n// Finds every shortcode in slot text\n// filters only the existing codes in emojiJson\n// removes duplicates.\n// @returns {string[]}\nexport function findShortCodes (textContent) {\n const shortcodes = (\n textContent.match(emojiShortCodeRegex) || []\n ).map(code => code.trim());\n return filterValidShortCodes(shortcodes);\n}\n\nexport function filterValidShortCodes (shortcodes) {\n const filtered = shortcodes ? shortcodes.filter(code => shortcodeToEmojiData(code)) : [];\n return new Set(filtered);\n}\n\n// Finds every emoji in slot text\n// removes duplicates\n// @returns {string[]}\nexport function findEmojis (textContent) {\n const matches = [...textContent.matchAll(emojiRegex)];\n const emojis = matches.length ? matches.map(match => match[0]) : [];\n return new Set(emojis);\n}\n"],"mappings":"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"}