import { useState, useMemo } from 'react'; interface KaomojiItem { emoji: string; tags: string[]; } interface Category { name: string; tabLabel: string; items: KaomojiItem[]; } const KAOMOJI_CATEGORIES: Category[] = [ { name: 'Bear (Kuma)', tabLabel: 'Bear', items: [ { emoji: 'ʕ•ᴥ•ʔ', tags: ['bear', 'kuma', 'animal', 'happy', 'neutral', 'cute'] }, { emoji: 'ʕっ•ᴥ•ʔっ', tags: ['bear', 'kuma', 'hug', 'love', 'happy', 'cute'] }, { emoji: 'ʕ•ᴥ•ʔノ♡', tags: ['bear', 'kuma', 'love', 'wave', 'happy', 'cute'] }, { emoji: 'ʕ º ᴥ º ʔ', tags: ['bear', 'kuma', 'surprised', 'shocked', 'gasp'] }, { emoji: 'ʕ◕ᴥ◕ʔ', tags: ['bear', 'kuma', 'cute', 'happy', 'smile'] }, { emoji: 'ʕ ; ᴥ ; ʔ', tags: ['bear', 'kuma', 'sad', 'crying', 'tear'] }, { emoji: 'ʕಠᴥಠʔ', tags: ['bear', 'kuma', 'angry', 'mad', 'glare'] }, { emoji: 'ʕ*ノᴥノʔ', tags: ['bear', 'kuma', 'shy', 'blush', 'cute'] }, { emoji: 'ʕ⊙ᴥ⊙ʔ', tags: ['bear', 'kuma', 'shocked', 'surprised', 'gasp'] }, { emoji: 'ʕ/•ᴥ•ʔ/', tags: ['bear', 'kuma', 'happy', 'celebrate', 'dance'] }, { emoji: 'ʕ·ᴥ·ʔ', tags: ['bear', 'kuma', 'small', 'cute', 'neutral'] }, { emoji: '⊂( ̄(エ) ̄)⊃', tags: ['bear', 'kuma', 'big', 'hug', 'animal'] }, { emoji: '(● ̄(エ) ̄●)', tags: ['bear', 'kuma', 'chubby', 'cute', 'neutral'] }, { emoji: 'ʕ •ᴥ•ʔゝ☆', tags: ['bear', 'kuma', 'magic', 'star', 'happy'] }, { emoji: 'ʕ•ᴥ•ʔ/', tags: ['bear', 'kuma', 'wave', 'hello', 'happy'] }, { emoji: 'ʕっ•ᴥ•ʔ', tags: ['bear', 'kuma', 'reach', 'cute'] }, { emoji: 'ʕ ⊃・ ェ ・ ʔ⊃', tags: ['bear', 'kuma', 'hug', 'reach'] }, { emoji: 'ʕ ꈍ ᴥ ꈍ ʔ', tags: ['bear', 'kuma', 'shy', 'happy', 'smug'] }, { emoji: 'ʕ ·(ェ)· ʔ', tags: ['bear', 'kuma', 'classic', 'neutral'] }, ] }, { name: 'Happy / Laughing', tabLabel: 'Joy', items: [ { emoji: '(^_^)', tags: ['happy', 'smile', 'classic', 'joy'] }, { emoji: '(^o^)', tags: ['happy', 'laugh', 'excited', 'joy'] }, { emoji: '(*^ω^*)', tags: ['happy', 'cute', 'smile', 'blush'] }, { emoji: '(≧▽≦)', tags: ['happy', 'laugh', 'excited', 'joy', 'grin'] }, { emoji: '(✿◠‿◠)', tags: ['happy', 'flower', 'cute', 'smile', 'peace'] }, { emoji: '(•‿•)', tags: ['happy', 'smile', 'cute'] }, { emoji: '(o^^o)', tags: ['happy', 'cute', 'blush', 'smile'] }, { emoji: '( ‘‿’ )', tags: ['happy', 'smile', 'cute'] }, { emoji: '\(〇‿〇)/', tags: ['happy', 'celebrate', 'excited', 'dance'] }, { emoji: '(◕‿◕)', tags: ['happy', 'smile', 'cute'] }, { emoji: '(>ω<)', tags: ['happy', 'excited', 'cute', 'joy'] }, { emoji: '(★ω★)', tags: ['happy', 'excited', 'star', 'sparkle', 'eyes'] }, { emoji: '(*^.^*)', tags: ['happy', 'smile', 'cute', 'shy'] }, ] }, { name: 'Sad / Crying', tabLabel: 'Sad', items: [ { emoji: '(T_T)', tags: ['sad', 'crying', 'tear', 'classic'] }, { emoji: '(ಥ﹏ಥ)', tags: ['sad', 'crying', 'tear', 'cute', 'pity'] }, { emoji: '(;_;)', tags: ['sad', 'crying', 'tear'] }, { emoji: '(._.)', tags: ['sad', 'depressed', 'down', 'neutral'] }, { emoji: '(._. )', tags: ['sad', 'depressed', 'down', 'shy'] }, { emoji: '(╥﹏╥)', tags: ['sad', 'crying', 'tear', 'heavy'] }, { emoji: '((>_<))', tags: ['sad', 'worried', 'frustrated', 'nervous'] }, { emoji: '(#>_<)', tags: ['sad', 'frustrated', 'mad', 'angry'] }, { emoji: '(;﹏;)', tags: ['sad', 'crying', 'tear'] }, ] }, { name: 'Angry / Glaring', tabLabel: 'Mad', items: [ { emoji: '(ಠ_ಠ)', tags: ['angry', 'mad', 'glare', 'disapproval', 'look'] }, { emoji: '(╯°□°)╯︵ ┻━┻', tags: ['angry', 'mad', 'table', 'flip', 'rage'] }, { emoji: '┬─┬ノ( º _ ºノ)', tags: ['neutral', 'table', 'put', 'back', 'calm'] }, { emoji: '(#`д´)ノ', tags: ['angry', 'mad', 'yell', 'shake'] }, { emoji: '(¬_¬)', tags: ['suspicious', 'glare', 'annoyed', 'side-eye'] }, { emoji: '( ̄︿ ̄)', tags: ['annoyed', 'disappointed', 'unhappy'] }, { emoji: '(╬ಠ益ಠ)', tags: ['angry', 'mad', 'rage', 'furious'] }, { emoji: '(凸ಠ益ಠ)凸', tags: ['angry', 'mad', 'middle', 'finger', 'rage'] }, ] }, { name: 'Shy / Cute', tabLabel: 'Shy', items: [ { emoji: '(*n_n*)', tags: ['shy', 'blush', 'cute', 'smile'] }, { emoji: '(*ノ∀`*)', tags: ['shy', 'blush', 'embarrassed', 'cute'] }, { emoji: '(ノωヽ)', tags: ['shy', 'blush', 'embarrassed', 'hide', 'cute'] }, { emoji: '( ꈍ ꈍ )', tags: ['cute', 'shy', 'blush', 'happy'] }, { emoji: '(⁄ ⁄•⁄ω⁄•⁄ ⁄)', tags: ['cute', 'shy', 'blush', 'super', 'embarrassed'] }, { emoji: '(❤ω❤)', tags: ['love', 'cute', 'excited', 'heart'] }, ] }, { name: 'Cats & Animals', tabLabel: 'Pets', items: [ { emoji: '(=^·^=)', tags: ['cat', 'animal', 'cute', 'happy'] }, { emoji: '(=^·ェ·^=)', tags: ['cat', 'animal', 'cute'] }, { emoji: '(=^ ◡ ^=)', tags: ['cat', 'animal', 'happy', 'smile'] }, { emoji: '(=^·^=)ノ', tags: ['cat', 'animal', 'wave', 'hello'] }, { emoji: '(◕ᴥ◕)', tags: ['animal', 'cute', 'seal'] }, { emoji: '(=^ ᆺ ^=)', tags: ['cat', 'animal', 'cute'] }, ] }, { name: 'Action & Funny', tabLabel: 'Misc', items: [ { emoji: '¯\\_(ツ)_/¯', tags: ['funny', 'shrug', 'meh', 'whatever'] }, { emoji: '( ͡° ͜ʖ ͡°)', tags: ['funny', 'lenny', 'smug', 'face'] }, { emoji: '(ง •̀_•́)ง', tags: ['action', 'fight', 'determined', 'fist'] }, { emoji: '(′-′)ノ(._.)', tags: ['action', 'pat', 'comfort', 'friend'] }, { emoji: '(/°▽°)/', tags: ['action', 'happy', 'throw', 'hands'] }, { emoji: '(°ロ°)', tags: ['surprised', 'shocked', 'gasp'] }, { emoji: 'ヽ(°〇°)ノ', tags: ['surprised', 'shocked', 'amaze'] }, ] } ]; interface EmojiPickerProps { onSelect: (emoji: string) => void; onClose: () => void; } export function EmojiPicker({ onSelect, onClose }: EmojiPickerProps) { const [search, setSearch] = useState(''); const [activeTab, setActiveTab] = useState('All'); // Search logic (checks emoji or tags matching) const searchResults = useMemo(() => { if (!search) return []; const query = search.toLowerCase().trim(); const results: KaomojiItem[] = []; const seen = new Set(); for (const cat of KAOMOJI_CATEGORIES) { for (const item of cat.items) { if (seen.has(item.emoji)) continue; const matchesEmoji = item.emoji.includes(query); const matchesTags = item.tags.some(tag => tag.includes(query)); if (matchesEmoji || matchesTags) { results.push(item); seen.add(item.emoji); } } } return results; }, [search]); // Tab filter logic const displayedItems = useMemo(() => { if (activeTab === 'All') { const all: KaomojiItem[] = []; const seen = new Set(); for (const cat of KAOMOJI_CATEGORIES) { for (const item of cat.items) { if (!seen.has(item.emoji)) { all.push(item); seen.add(item.emoji); } } } return all; } const cat = KAOMOJI_CATEGORIES.find(c => c.tabLabel === activeTab); return cat ? cat.items : []; }, [activeTab]); return (
KAOMOJI PICKER
setSearch(e.target.value)} placeholder="search (happy, bear, sad, table...)" className="w-full px-2 py-1 mb-2 text-xs bg-gb-bg-s text-gb-fg border border-gb-bg-t outline-none focus:border-gb-orange" autoFocus /> {/* Tabs list (only shown if not searching) */} {!search && (
{KAOMOJI_CATEGORIES.map(cat => ( ))}
)} {/* Emoticons grid */}
{search ? ( searchResults.map((item) => ( )) ) : ( displayedItems.map((item) => ( )) )}
{search && searchResults.length === 0 && (
[no matches found]
)}
); }