Package Exports
- @metalmind/mm-emoji
- @metalmind/mm-emoji/styles.css
Readme
@metalmind/mm-emoji
A lightweight, stylable, reusable React emoji picker component inspired by Slack's emoji picker.
Features
- 🎨 Fully Styled - Beautiful default styling with light and dark themes
- 🔍 Search - Real-time emoji search with keyword matching
- 📝 Recently Used - Automatically tracks recently used emojis
- ⭐ Frequently Used - Shows your most-used emojis
- 🎨 Skin Tones - Full support for skin tone variants
- ⌨️ Keyboard Navigation - Full keyboard support (coming soon)
- ♿ Accessible - WCAG compliant with proper ARIA labels
- 📦 Lightweight - Small bundle size with tree-shaking support
- 🎯 TypeScript - Full TypeScript support with type definitions
- 🔧 Customizable - Extensive styling and behavior customization
Installation
npm install @metalmind/mm-emojiOr with yarn:
yarn add @metalmind/mm-emojiOr with pnpm:
pnpm add @metalmind/mm-emojiQuick Start
import { EmojiPicker, EmojiData } from '@metalmind/mm-emoji';
import { useState } from 'react';
function App() {
const [selectedEmoji, setSelectedEmoji] = useState<string>('');
const [showPicker, setShowPicker] = useState(false);
const handleEmojiSelect = (emoji: EmojiData) => {
setSelectedEmoji(emoji.emoji);
setShowPicker(false);
};
return (
<div>
<button onClick={() => setShowPicker(!showPicker)}>
{selectedEmoji || 'Select Emoji'}
</button>
{showPicker && (
<EmojiPicker onEmojiSelect={handleEmojiSelect} />
)}
</div>
);
}API Reference
Props
Required Props
| Prop | Type | Description |
|---|---|---|
onEmojiSelect |
(emoji: EmojiData) => void |
Callback function called when an emoji is selected |
Optional Props
| Prop | Type | Default | Description |
|---|---|---|---|
presetEmoji |
string | EmojiData |
- | Initial emoji to highlight in the picker |
theme |
'light' | 'dark' | 'auto' |
'light' |
Color theme for the picker |
width |
number | string |
376 |
Width of the picker (px or CSS value) |
height |
number | string |
435 |
Height of the picker (px or CSS value) |
className |
string |
'' |
Additional CSS class name |
styles |
EmojiPickerStyles |
{} |
Style overrides for different parts |
autoFocus |
boolean |
true |
Auto-focus search input on mount |
showPreview |
boolean |
true |
Show emoji preview on hover |
showSkinTones |
boolean |
true |
Enable skin tone picker |
enableFrequentlyUsed |
boolean |
true |
Show frequently used section |
maxFrequentRows |
number |
2 |
Maximum rows for frequently used emojis |
storageKey |
string |
'mm-emoji' |
localStorage key prefix |
customStorage |
StorageAdapter |
- | Custom storage implementation |
searchPlaceholder |
string |
'Search emojis...' |
Search input placeholder text |
searchDebounce |
number |
300 |
Search debounce delay (ms) |
Types
interface EmojiData {
emoji: string; // The actual emoji character
name: string; // Display name
shortcode: string; // :shortcode: format
unicode: string; // Unicode codepoint(s)
category: string; // Category name
keywords: string[]; // Search keywords
skinTone?: number; // Skin tone variant
supportsSkinTone?: boolean; // Whether supports skin tones
}
interface EmojiPickerStyles {
picker?: React.CSSProperties;
search?: React.CSSProperties;
categories?: React.CSSProperties;
emojiGrid?: React.CSSProperties;
preview?: React.CSSProperties;
skinTonePicker?: React.CSSProperties;
}Usage Examples
Basic Usage
import { EmojiPicker } from '@metalmind/mm-emoji';
<EmojiPicker onEmojiSelect={(emoji) => console.log(emoji.emoji)} />With Preset Emoji
<EmojiPicker
onEmojiSelect={handleSelect}
presetEmoji="😀"
/>Dark Theme
<EmojiPicker
onEmojiSelect={handleSelect}
theme="dark"
/>Auto Theme (System Preference)
<EmojiPicker
onEmojiSelect={handleSelect}
theme="auto"
/>Custom Size
<EmojiPicker
onEmojiSelect={handleSelect}
width={400}
height={500}
/>Custom Styling
<EmojiPicker
onEmojiSelect={handleSelect}
styles={{
picker: {
borderRadius: '16px',
boxShadow: '0 8px 32px rgba(0,0,0,0.1)',
},
search: {
backgroundColor: '#f0f0f0',
},
}}
/>Without Preview
<EmojiPicker
onEmojiSelect={handleSelect}
showPreview={false}
/>Custom Storage
import { StorageAdapter } from '@metalmind/mm-emoji';
const customStorage: StorageAdapter = {
getItem: (key) => {
// Your custom get logic
return sessionStorage.getItem(key);
},
setItem: (key, value) => {
// Your custom set logic
sessionStorage.setItem(key, value);
},
removeItem: (key) => {
sessionStorage.removeItem(key);
},
};
<EmojiPicker
onEmojiSelect={handleSelect}
customStorage={customStorage}
/>Theming
The component supports extensive theming via CSS variables:
:root {
--emoji-picker-bg: #ffffff;
--emoji-picker-border: #e0e0e0;
--emoji-picker-text: #1d1c1d;
--emoji-picker-text-secondary: #616061;
--emoji-picker-hover: #f0f0f0;
--emoji-picker-active: #1264a3;
--emoji-picker-shadow: rgba(0, 0, 0, 0.1);
--emoji-picker-radius: 8px;
}Browser Support
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
Development
# Install dependencies
npm install
# Run development mode
npm run dev
# Build library
npm run build
# Run tests
npm test
# Run linter
npm run lint
# Format code
npm run formatContributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
MIT © Metalmind AB
Links
Acknowledgments
- Inspired by Slack's emoji picker
- Emoji data from unicode-emoji-json
- Built with React, TypeScript, and Vite