/** A generous, categorized emoji set with shortcodes + search keywords. * Powers the picker, composer autocomplete, reactions, and `:shortcode:` parsing. */ export interface Emoji { e: string; // the emoji n: string; // canonical shortcode name (no colons) k?: string; // extra search keywords c: EmojiCategory; } export type EmojiCategory = | "Frequent" | "Smileys" | "Gestures" | "People" | "Animals" | "Food" | "Activity" | "Travel" | "Objects" | "Symbols" | "Flags"; export const EMOJI_CATEGORIES: EmojiCategory[] = [ "Frequent", "Smileys", "Gestures", "People", "Animals", "Food", "Activity", "Travel", "Objects", "Symbols", "Flags", ]; export const EMOJIS: Emoji[] = [ // Smileys { e: "๐Ÿ˜€", n: "grinning", c: "Smileys" }, { e: "๐Ÿ˜ƒ", n: "smiley", c: "Smileys" }, { e: "๐Ÿ˜„", n: "smile", c: "Smileys" }, { e: "๐Ÿ˜", n: "grin", c: "Smileys" }, { e: "๐Ÿ˜†", n: "laughing", k: "haha", c: "Smileys" }, { e: "๐Ÿ˜…", n: "sweat_smile", c: "Smileys" }, { e: "๐Ÿคฃ", n: "rofl", k: "lol laugh", c: "Smileys" }, { e: "๐Ÿ˜‚", n: "joy", k: "lol cry laugh", c: "Smileys" }, { e: "๐Ÿ™‚", n: "slightly_smiling", c: "Smileys" }, { e: "๐Ÿ™ƒ", n: "upside_down", c: "Smileys" }, { e: "๐Ÿ˜‰", n: "wink", c: "Smileys" }, { e: "๐Ÿ˜Š", n: "blush", c: "Smileys" }, { e: "๐Ÿ˜‡", n: "innocent", k: "angel", c: "Smileys" }, { e: "๐Ÿฅฐ", n: "smiling_hearts", k: "love", c: "Smileys" }, { e: "๐Ÿ˜", n: "heart_eyes", k: "love", c: "Smileys" }, { e: "๐Ÿ˜˜", n: "kissing_heart", c: "Smileys" }, { e: "๐Ÿ˜œ", n: "stuck_out_tongue_wink", c: "Smileys" }, { e: "๐Ÿคช", n: "zany", c: "Smileys" }, { e: "๐Ÿคจ", n: "raised_eyebrow", k: "skeptic", c: "Smileys" }, { e: "๐Ÿง", n: "monocle", c: "Smileys" }, { e: "๐Ÿค“", n: "nerd", c: "Smileys" }, { e: "๐Ÿ˜Ž", n: "sunglasses", k: "cool", c: "Smileys" }, { e: "๐Ÿฅณ", n: "partying", k: "celebrate party", c: "Smileys" }, { e: "๐Ÿ˜", n: "smirk", c: "Smileys" }, { e: "๐Ÿ˜’", n: "unamused", c: "Smileys" }, { e: "๐Ÿ˜ž", n: "disappointed", c: "Smileys" }, { e: "๐Ÿ˜”", n: "pensive", c: "Smileys" }, { e: "๐Ÿ˜Ÿ", n: "worried", c: "Smileys" }, { e: "๐Ÿ˜ข", n: "cry", k: "sad tear", c: "Smileys" }, { e: "๐Ÿ˜ญ", n: "sob", k: "cry sad", c: "Smileys" }, { e: "๐Ÿ˜ค", n: "huff", c: "Smileys" }, { e: "๐Ÿ˜ ", n: "angry", c: "Smileys" }, { e: "๐Ÿ˜ก", n: "rage", k: "mad angry", c: "Smileys" }, { e: "๐Ÿคฌ", n: "cursing", c: "Smileys" }, { e: "๐Ÿคฏ", n: "mind_blown", k: "explode", c: "Smileys" }, { e: "๐Ÿ˜ณ", n: "flushed", c: "Smileys" }, { e: "๐Ÿฅต", n: "hot", c: "Smileys" }, { e: "๐Ÿฅถ", n: "cold", c: "Smileys" }, { e: "๐Ÿ˜ฑ", n: "scream", k: "shock", c: "Smileys" }, { e: "๐Ÿ˜จ", n: "fearful", c: "Smileys" }, { e: "๐Ÿ˜ฐ", n: "anxious", c: "Smileys" }, { e: "๐Ÿค”", n: "thinking", k: "hmm", c: "Smileys" }, { e: "๐Ÿคซ", n: "shush", c: "Smileys" }, { e: "๐Ÿค", n: "zipper_mouth", c: "Smileys" }, { e: "๐Ÿ˜ด", n: "sleeping", k: "zzz tired", c: "Smileys" }, { e: "๐Ÿฅฑ", n: "yawn", k: "tired bored", c: "Smileys" }, { e: "๐Ÿค’", n: "sick", k: "ill", c: "Smileys" }, { e: "๐Ÿค•", n: "hurt", c: "Smileys" }, { e: "๐Ÿคฎ", n: "vomit", c: "Smileys" }, { e: "๐Ÿ˜ท", n: "mask", c: "Smileys" }, { e: "๐Ÿค—", n: "hug", c: "Smileys" }, { e: "๐Ÿคญ", n: "hand_over_mouth", c: "Smileys" }, { e: "๐Ÿ˜ฌ", n: "grimace", c: "Smileys" }, { e: "๐Ÿ™„", n: "eye_roll", c: "Smileys" }, // Gestures { e: "๐Ÿ‘", n: "+1", k: "thumbsup like yes", c: "Gestures" }, { e: "๐Ÿ‘Ž", n: "-1", k: "thumbsdown no", c: "Gestures" }, { e: "๐Ÿ‘", n: "clap", k: "applause", c: "Gestures" }, { e: "๐Ÿ™Œ", n: "raised_hands", k: "hooray celebrate", c: "Gestures" }, { e: "๐Ÿ‘‹", n: "wave", k: "hi hello bye", c: "Gestures" }, { e: "๐Ÿค", n: "handshake", k: "deal", c: "Gestures" }, { e: "๐Ÿ™", n: "pray", k: "please thanks", c: "Gestures" }, { e: "โœŒ๏ธ", n: "victory", k: "peace", c: "Gestures" }, { e: "๐Ÿคž", n: "crossed_fingers", k: "luck", c: "Gestures" }, { e: "๐Ÿ‘Œ", n: "ok_hand", c: "Gestures" }, { e: "๐Ÿค™", n: "call_me", c: "Gestures" }, { e: "๐Ÿ’ช", n: "muscle", k: "strong flex", c: "Gestures" }, { e: "๐Ÿ‘Š", n: "fist_bump", c: "Gestures" }, { e: "โœŠ", n: "raised_fist", c: "Gestures" }, { e: "๐ŸคŸ", n: "love_you", c: "Gestures" }, { e: "๐Ÿ‘‰", n: "point_right", c: "Gestures" }, { e: "๐Ÿ‘ˆ", n: "point_left", c: "Gestures" }, { e: "๐Ÿ‘†", n: "point_up", c: "Gestures" }, { e: "๐Ÿซก", n: "salute", c: "Gestures" }, { e: "๐Ÿซถ", n: "heart_hands", c: "Gestures" }, { e: "๐ŸคŒ", n: "pinched", c: "Gestures" }, // People / Activity { e: "๐ŸŽ‰", n: "tada", k: "party celebrate hooray", c: "Activity" }, { e: "๐ŸŽŠ", n: "confetti", c: "Activity" }, { e: "๐Ÿฅณ", n: "party", c: "Activity" }, { e: "๐Ÿ†", n: "trophy", k: "win", c: "Activity" }, { e: "๐Ÿฅ‡", n: "1st_place", c: "Activity" }, { e: "โšฝ", n: "soccer", c: "Activity" }, { e: "๐Ÿ€", n: "basketball", c: "Activity" }, { e: "๐ŸŽฏ", n: "dart", k: "target bullseye", c: "Activity" }, { e: "๐ŸŽฎ", n: "video_game", c: "Activity" }, { e: "๐ŸŽธ", n: "guitar", c: "Activity" }, { e: "๐ŸŽง", n: "headphones", k: "music", c: "Activity" }, { e: "๐Ÿš€", n: "rocket", k: "ship launch fast", c: "Travel" }, // Animals { e: "๐Ÿถ", n: "dog", c: "Animals" }, { e: "๐Ÿฑ", n: "cat", c: "Animals" }, { e: "๐Ÿฆ„", n: "unicorn", c: "Animals" }, { e: "๐Ÿ", n: "bee", c: "Animals" }, { e: "๐Ÿฆ‹", n: "butterfly", c: "Animals" }, { e: "๐Ÿข", n: "turtle", c: "Animals" }, { e: "๐Ÿผ", n: "panda", c: "Animals" }, { e: "๐Ÿฆ", n: "lion", c: "Animals" }, { e: "๐Ÿง", n: "penguin", c: "Animals" }, // Food { e: "๐Ÿ•", n: "pizza", c: "Food" }, { e: "๐Ÿ”", n: "burger", c: "Food" }, { e: "๐ŸŒฎ", n: "taco", c: "Food" }, { e: "๐Ÿฃ", n: "sushi", c: "Food" }, { e: "๐Ÿœ", n: "ramen", k: "noodles", c: "Food" }, { e: "โ˜•", n: "coffee", c: "Food" }, { e: "๐Ÿบ", n: "beer", c: "Food" }, { e: "๐Ÿฅ‚", n: "clink", k: "cheers", c: "Food" }, { e: "๐ŸŽ‚", n: "cake", k: "birthday", c: "Food" }, { e: "๐Ÿฉ", n: "donut", c: "Food" }, { e: "๐ŸŽ", n: "apple", c: "Food" }, { e: "๐Ÿฅ‘", n: "avocado", c: "Food" }, // Travel / weather { e: "๐ŸŒ", n: "earth", c: "Travel" }, { e: "โœˆ๏ธ", n: "airplane", c: "Travel" }, { e: "๐Ÿš—", n: "car", c: "Travel" }, { e: "๐Ÿ ", n: "house", k: "home", c: "Travel" }, { e: "๐Ÿ—๏ธ", n: "construction", k: "site build", c: "Travel" }, { e: "๐ŸŒฉ๏ธ", n: "storm", k: "thunder weather", c: "Travel" }, { e: "โ˜€๏ธ", n: "sun", c: "Travel" }, { e: "๐ŸŒˆ", n: "rainbow", c: "Travel" }, { e: "๐Ÿ”ฅ", n: "fire", k: "lit hot flame", c: "Objects" }, // Objects { e: "๐Ÿ’ก", n: "bulb", k: "idea", c: "Objects" }, { e: "๐Ÿ“Œ", n: "pin", c: "Objects" }, { e: "๐Ÿ“Ž", n: "paperclip", c: "Objects" }, { e: "๐Ÿ“ˆ", n: "chart_up", k: "growth", c: "Objects" }, { e: "๐Ÿ“‰", n: "chart_down", c: "Objects" }, { e: "๐Ÿ“…", n: "calendar", c: "Objects" }, { e: "๐Ÿ“", n: "ruler", c: "Objects" }, { e: "๐Ÿ› ๏ธ", n: "tools", c: "Objects" }, { e: "๐Ÿ”ง", n: "wrench", c: "Objects" }, { e: "๐Ÿ’ฐ", n: "money", c: "Objects" }, { e: "๐Ÿ“ฑ", n: "phone", c: "Objects" }, { e: "๐Ÿ’ป", n: "laptop", c: "Objects" }, { e: "โš™๏ธ", n: "gear", k: "settings", c: "Objects" }, { e: "๐Ÿ”’", n: "lock", c: "Objects" }, { e: "๐Ÿ”‘", n: "key", c: "Objects" }, { e: "๐ŸŽ", n: "gift", c: "Objects" }, { e: "๐Ÿค–", n: "robot", k: "bot ai", c: "Objects" }, { e: "โšก", n: "zap", k: "fast bolt", c: "Objects" }, // Symbols { e: "โค๏ธ", n: "heart", k: "love red", c: "Symbols" }, { e: "๐Ÿงก", n: "orange_heart", c: "Symbols" }, { e: "๐Ÿ’›", n: "yellow_heart", c: "Symbols" }, { e: "๐Ÿ’š", n: "green_heart", c: "Symbols" }, { e: "๐Ÿ’™", n: "blue_heart", c: "Symbols" }, { e: "๐Ÿ’œ", n: "purple_heart", c: "Symbols" }, { e: "๐Ÿ–ค", n: "black_heart", c: "Symbols" }, { e: "๐Ÿ’ฏ", n: "100", k: "hundred perfect", c: "Symbols" }, { e: "โœ…", n: "white_check_mark", k: "tick done yes check", c: "Symbols" }, { e: "โ˜‘๏ธ", n: "check", k: "tick done", c: "Symbols" }, { e: "โœ”๏ธ", n: "heavy_check", k: "tick", c: "Symbols" }, { e: "โŒ", n: "x", k: "cross no wrong", c: "Symbols" }, { e: "โญ", n: "star", c: "Symbols" }, { e: "๐ŸŒŸ", n: "glowing_star", c: "Symbols" }, { e: "โœจ", n: "sparkles", c: "Symbols" }, { e: "โ—", n: "exclamation", c: "Symbols" }, { e: "โ“", n: "question", c: "Symbols" }, { e: "โš ๏ธ", n: "warning", c: "Symbols" }, { e: "๐Ÿ‘€", n: "eyes", k: "look watch", c: "Symbols" }, { e: "๐ŸŽˆ", n: "balloon", c: "Symbols" }, { e: "๐Ÿ’ฅ", n: "boom", c: "Symbols" }, ]; // name โ†’ emoji map for :shortcode: parsing const NAME_MAP: Record = (() => { const m: Record = {}; for (const em of EMOJIS) m[em.n] = em.e; // common aliases m["thumbsup"] = "๐Ÿ‘"; m["thumbsdown"] = "๐Ÿ‘Ž"; m["heart"] = "โค๏ธ"; m["fire"] = "๐Ÿ”ฅ"; m["check"] = "โœ…"; m["tick"] = "โœ…"; m["done"] = "โœ…"; m["rocket"] = "๐Ÿš€"; m["party"] = "๐ŸŽ‰"; m["smile"] = "๐Ÿ˜„"; m["laugh"] = "๐Ÿ˜‚"; m["ok"] = "๐Ÿ‘Œ"; m["eyes"] = "๐Ÿ‘€"; m["100"] = "๐Ÿ’ฏ"; return m; })(); /** Replace :shortcode: tokens in a string with their emoji. */ export function replaceShortcodes(text: string): string { return text.replace(/:([a-z0-9_+-]{1,30}):/gi, (whole, name) => NAME_MAP[name.toLowerCase()] ?? whole); } export function shortcodeToEmoji(name: string): string | undefined { return NAME_MAP[name.toLowerCase()]; } /** Fuzzy search across name + keywords. */ export function searchEmojis(query: string, limit = 40): Emoji[] { const q = query.toLowerCase().trim(); if (!q) return EMOJIS.slice(0, limit); return EMOJIS.filter((e) => e.n.includes(q) || (e.k && e.k.includes(q))).slice(0, limit); } export const FREQUENT: string[] = ["๐Ÿ‘", "๐ŸŽ‰", "๐Ÿ”ฅ", "โค๏ธ", "๐Ÿ˜‚", "๐Ÿ™Œ", "๐Ÿ‘€", "โœ…", "๐Ÿš€", "๐Ÿ’ฏ", "๐Ÿ™", "๐Ÿ‘"];