npm package: @metalmind/mm-emoji
Description: A lightweight, stylable, reusable React emoji picker component inspired by Slack's emoji picker
Author: Metalmind AB
Latest version: 0.1.0

# @metalmind/mm-emoji

A lightweight, stylable, reusable React emoji picker component inspired by Slack's emoji picker.

[![npm version](https://img.shields.io/npm/v/@metalmind/mm-emoji.svg)](https://www.npmjs.com/package/@metalmind/mm-emoji)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## 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

```bash
npm install @metalmind/mm-emoji
```

Or with yarn:

```bash
yarn add @metalmind/mm-emoji
```

Or with pnpm:

```bash
pnpm add @metalmind/mm-emoji
```

## Quick Start

```tsx
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

```typescript
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

```tsx
import { EmojiPicker } from '@metalmind/mm-emoji';

<EmojiPicker onEmojiSelect={(emoji) => console.log(emoji.emoji)} />
```

### With Preset Emoji

```tsx
<EmojiPicker
  onEmojiSelect={handleSelect}
  presetEmoji="😀"
/>
```

### Dark Theme

```tsx
<EmojiPicker
  onEmojiSelect={handleSelect}
  theme="dark"
/>
```

### Auto Theme (System Preference)

```tsx
<EmojiPicker
  onEmojiSelect={handleSelect}
  theme="auto"
/>
```

### Custom Size

```tsx
<EmojiPicker
  onEmojiSelect={handleSelect}
  width={400}
  height={500}
/>
```

### Custom Styling

```tsx
<EmojiPicker
  onEmojiSelect={handleSelect}
  styles={{
    picker: {
      borderRadius: '16px',
      boxShadow: '0 8px 32px rgba(0,0,0,0.1)',
    },
    search: {
      backgroundColor: '#f0f0f0',
    },
  }}
/>
```

### Without Preview

```tsx
<EmojiPicker
  onEmojiSelect={handleSelect}
  showPreview={false}
/>
```

### Custom Storage

```tsx
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:

```css
: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

```bash
# 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 format
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

MIT © [Metalmind AB](https://github.com/Metalmind-AB)

## Links

- [GitHub Repository](https://github.com/Metalmind-AB/mm_emoji)
- [Issues](https://github.com/Metalmind-AB/mm_emoji/issues)
- [npm Package](https://www.npmjs.com/package/@metalmind/mm-emoji)

## Acknowledgments

- Inspired by Slack's emoji picker
- Emoji data from [unicode-emoji-json](https://github.com/muan/unicode-emoji-json)
- Built with React, TypeScript, and Vite