Created
August 15, 2025 21:57
-
-
Save wodin/410deb2f85cdf5c90d6c783fc5ab9324 to your computer and use it in GitHub Desktop.
Emoji Picker
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // https://stackblitz.com/edit/react-aria-emoji-picker?file=src%2FEmojiPicker.tsx | |
| import { | |
| Autocomplete, | |
| Button, | |
| GridLayout, | |
| ListBox, | |
| ListBoxItem, | |
| Select, | |
| SelectValue, | |
| Size, | |
| useFilter, | |
| Virtualizer, | |
| } from 'react-aria-components'; | |
| import { Popover } from './components/Popover'; | |
| import { SearchField } from './components/SearchField'; | |
| import _emojis from 'emojibase-data/en/compact.json'; | |
| import { Smile } from 'lucide-react'; | |
| import './EmojiPicker.css'; | |
| const emojis = _emojis.filter((e) => !e.label.startsWith('regional indicator')); | |
| export function EmojiPicker() { | |
| let { contains } = useFilter({ sensitivity: 'base' }); | |
| return ( | |
| <Select aria-label="Emoji" className="emoji-picker"> | |
| <Button> | |
| <SelectValue> | |
| {({ isPlaceholder, defaultChildren }) => | |
| isPlaceholder ? ( | |
| <Smile size={22} style={{ display: 'block' }} /> | |
| ) : ( | |
| defaultChildren | |
| ) | |
| } | |
| </SelectValue> | |
| </Button> | |
| <Popover> | |
| <Autocomplete filter={contains}> | |
| <div className="emoji-picker-popover"> | |
| <SearchField aria-label="Search" autoFocus /> | |
| <Virtualizer | |
| layout={GridLayout} | |
| layoutOptions={{ | |
| minItemSize: new Size(32, 32), | |
| maxItemSize: new Size(32, 32), | |
| minSpace: new Size(4, 4), | |
| preserveAspectRatio: true, | |
| }} | |
| > | |
| <ListBox items={emojis} aria-label="Emoji list" layout="grid"> | |
| {(item) => <EmojiItem id={item.unicode} item={item} />} | |
| </ListBox> | |
| </Virtualizer> | |
| </div> | |
| </Autocomplete> | |
| </Popover> | |
| </Select> | |
| ); | |
| } | |
| function EmojiItem({ id, item }: { id: string; item: (typeof emojis)[0] }) { | |
| return ( | |
| <ListBoxItem | |
| id={id} | |
| value={item} | |
| textValue={item.label + (item.tags || []).join(' ')} | |
| > | |
| {item.unicode} | |
| </ListBoxItem> | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment