Install frimousse via npm
mainTo use the unstyled emoji picker in your React project, install the frimousse package using npm.
npm i frimousserepository·main·Indexed 23 days ago
https://github.com/liveblocks/frimousseA lightweight, unstyled, and composable emoji picker for React. It is dependency-free, tree-shakable, and uses virtualization for high performance. The library provides a composable API via EmojiPicker.Root and its sub-components (Search, Viewport, Loading, Empty, and List), as well as hooks like useActiveEmoji and useSkinTone. It supports React versions 18 and 19 and TypeScript 5.1+.
To use the unstyled emoji picker in your React project, install the frimousse package using npm.
npm i frimousseshadcn CLI.If you are using shadcn/ui, you can install a pre-built version of the emoji picker that integrates with your existing shadcn/ui variables using the shadcn CLI.
npx shadcn@latest add https://frimousse.liveblocks.io/r/emoji-pickerFrimousse is unstyled and composable. You build your UI by importing EmojiPicker parts and arranging them within a EmojiPicker.Root.
Key parts include:
EmojiPicker.Root: The provider/container for the picker.EmojiPicker.Search: The search input field.EmojiPicker.Viewport: A container for the loading, empty, and list states.EmojiPicker.Loading: Shown while emoji data is being fetched.EmojiPicker.Empty: Shown when no results match the search.EmojiPicker.List: The virtualized list of emojis.You can style these parts using Tailwind CSS, CSS-in-JS, or by targeting the [frimousse-*] attributes present on each part.
import { EmojiPicker } from "frimousse";
export function MyEmojiPicker() {
return (
<EmojiPicker.Root>
<EmojiPicker.Search />
<EmojiPicker.Viewport>
<EmojiPicker.Loading>Loading…</EmojiPicker.Loading>
<EmojiPicker.Empty>No emoji found.</EmojiPicker.Empty>
<EmojiPicker.List />
</EmojiPicker.Viewport>
</EmojiPicker.Root>
);
}The emoji picker store is distributed via a React Context. To access the store within your component tree, wrap your components in the EmojiPickerStoreProvider and consume the state using the useEmojiPickerStore hook.
If you attempt to use useEmojiPickerStore outside of a provider, it will throw an error: "EmojiPicker.Root is missing."
Frimousse requires the following environments:
The EmojiPickerRoot component is the main entry point for the emoji picker. You can customize its behavior, locale, skin tone, and data source using the following props:
onEmojiSelect: Callback function invoked when an emoji is selected. Receives the selected Emoji object.locale: The locale for the emoji picker (e.g., "en"). Defaults to "en".skinTone: The default skin tone for the picker. Defaults to "none".columns: The number of columns in the emoji list. Defaults to 10.emojiVersion: Manually control which emoji version is visible. Defaults to the most recent version supported by the browser.emojibaseUrl: The base URL for fetching Emojibase data. Defaults to "https://cdn.jsdelivr.net/npm/emojibase-data". You can point this to a CDN like "https://unpkg.com/emojibase-data" or a self-hosted location.sticky: Whether category headers should be sticky. Defaults to true.The searchEmojis function filters and ranks a list of emojis based on a search string. It uses a scoring mechanism where matches in the emoji label are weighted higher (score of 10) than matches in the tags (score of 1). The results are returned in descending order of their score.
emojis: An array of EmojiDataEmoji objects to search through.search (optional): The search string. If omitted, the full list is returned.The getEmojiPickerData function transforms raw emoji data into a structured format optimized for rendering an emoji picker UI, supporting categorization, grid columns, searching, and skin tones.
data: The source EmojiData containing all emojis and categories.columns: The number of emojis to display per row (used for chunking).skinTone: A SkinTone value (e.g., from the SkinTone type) to apply to compatible emojis. If undefined or 'none', the default emoji is used.search: The current search string to filter emojis.Returns an EmojiPickerData object containing:
count: Total number of emojis matching the search.categories: An array of EmojiPickerDataCategory describing category labels and their position in the grid.categoriesStartRowIndices: Indices indicating where each category begins in the rows array.rows: An array of EmojiPickerDataRow containing chunks of emojis grouped by category.skinTones: The available skin tones from the source data.Given an emoji object that contains skin tone information, getEmojibaseSkinToneVariations returns a mapping of skin tone keys to their corresponding emoji characters.
This is useful for implementing emoji pickers that allow users to select different skin tones for a single emoji base.
The store provides several selector functions to easily access and derive state. These are useful for optimizing component re-renders.
$search(state): Returns the current search string.$activeEmoji(state): Returns the currently active EmojiPickerEmoji if an interaction is occurring, otherwise undefined.$isEmpty(state): Returns true if data is undefined or the count is 0.$isLoading(state): Returns true if essential layout data (like rowHeight or viewportHeight) or the data itself is missing.$rowsCount(state): Returns the number of rows in the data.$categoriesCount(state): Returns the number of categories.$categoriesRowsStartIndices(state): Returns the starting row indices for each category.$skinTones(state): Returns the available skin tones.Additionally, use sameEmojiPickerEmoji(a, b) and sameEmojiPickerRow(a, b) to perform equality checks between emoji and row objects.
Use getSkinToneVariations(emoji) to retrieve an array of all available skin tone variations for a given emoji. Each object in the returned array contains the skinTone name and the resulting emoji string.
The variations are generated by iterating through the SKIN_TONES constant.