textual-emoji-picker
A searchable, categorised emoji picker widget for Textual TUI applications.
Drop it into any Textual app as an embedded widget or push it as a modal screen. Covers the full Unicode 15 emoji set (3 600+ emoji) with skin-tone support and real-time search.
┌─────────────────────────────────────────┐
│ Search emoji… │
│ 🏳 🏻 🏼 🏽 🏾 🏿 │
│ │
│ 😀 😃 😄 😁 😆 😅 🤣 😂 │
│ 🙂 🙃 🫠 😉 😊 😇 🥰 😍 │
│ 😘 😗 ☺ 😚 😙 🥲 😋 😛 │
│ 😜 🤪 😝 🤑 🤗 🤭 🫢 🫣 │
│ 🤫 🤔 🫡 🤐 🤨 😐 😑 😶 │
│ │
│ Press Enter or click to select │
└─────────────────────────────────────────┘
Install
pip install textual-emoji-picker
Requires Python 3.11+ and Textual 1.0+.
Usage
As an embedded widget
from textual.app import App, ComposeResult
from textual_emoji_picker import EmojiPicker
class MyApp(App[None]):
def compose(self) -> ComposeResult:
yield EmojiPicker()
def on_emoji_picker_emoji_selected(self, event: EmojiPicker.EmojiSelected) -> None:
self.notify(f"You picked: {event.emoji}")
def on_emoji_picker_cancelled(self, event: EmojiPicker.Cancelled) -> None:
self.notify("Cancelled")
As a modal screen
from textual.app import App
from textual_emoji_picker import EmojiPickerScreen
class MyApp(App[None]):
async def action_pick_emoji(self) -> None:
emoji = await self.push_screen_wait(EmojiPickerScreen())
if emoji:
self.notify(f"You picked: {emoji}")
Constructor options
EmojiPicker(
# Restrict to specific Unicode groups. None = all groups.
# Available: "smileys-emotion", "people-body", "animals-nature",
# "food-drink", "travel-places", "activities",
# "objects", "symbols", "flags"
categories=["smileys-emotion", "people-body"],
# Default Fitzpatrick skin tone. 1 = neutral (no modifier), 2–6 = light to dark.
default_skin_tone=1,
# Exclude emoji introduced after this version (avoids rendering boxes in
# terminals with older font coverage). None = no filter.
max_emoji_version=14.0,
# Show a "recently used" category (in-memory only in v0.1).
show_recent=False,
)
EmojiPickerScreen accepts the same keyword arguments and forwards them to the inner EmojiPicker.
Keyboard navigation
| Key | Action |
|---|---|
| Type anything | Filter emoji by name |
| Arrow keys | Navigate the emoji grid |
| Enter | Select the focused emoji |
| Tab / Shift+Tab | Move between search bar, skin-tone row, and grid |
| Escape | Cancel (posts Cancelled / dismisses modal with "") |
Skin tones
Select a skin tone swatch to apply a Fitzpatrick modifier to any compatible emoji (hands, gestures, people). Face emoji, hearts, and objects are not modified. Selecting the neutral swatch returns to the unmodified base emoji.
Emoji data
Emoji are sourced from the emoji library (Unicode 15 / Emoji 15.1, ~3 600 fully-qualified emoji). Category and display order follow the Unicode CLDR emoji-test.txt specification.
Feature comparison with emoji-mart
emoji-mart is the reference web emoji picker. This package is a TUI analogue — the goals and constraints differ, but the feature roadmap is informed by emoji-mart.
| Feature | emoji-mart (web) | textual-emoji-picker (TUI) |
|---|---|---|
| Full Unicode emoji set | Yes (14/15) | Yes (15, ~3 600) |
| Search by name | Yes | Yes |
| Category navigation | Yes (tabs) | v0.2 |
| Skin-tone selector | Yes (per emoji + global) | Yes (global selector) |
| Recently used | Yes | v0.2 (in-memory), v0.3 (persisted) |
| Custom emoji | Yes (image/GIF/SVG) | v0.4 (text/string only) |
| i18n / locale names | Yes (22 locales) | v0.3 |
| Emoji version filter | UI toggle | max_emoji_version kwarg |
| Preview on hover | Yes | Status-bar label (v0.2) |
| Per-line count | perLine option |
v0.2 (reactive to widget width) |
| Image spritesheets | Yes | Out of scope (terminal renders native glyphs) |
| GIF/pixel rendering | Yes | Out of scope |
| Hover positioning | Pixel-accurate | Out of scope |
Changelog
v0.1.0
EmojiPicker(Widget)andEmojiPickerScreen(ModalScreen[str]).- Full Unicode 15 emoji set (filtered to
max_emoji_version=14.0by default). - Real-time search by CLDR name (English).
- Skin-tone selector (Fitzpatrick modifiers, global).
- Keyboard-navigable grid.
EmojiSelectedandCancelledmessage API.
License
MIT. Emoji data sourced from the emoji library (New BSD) and Unicode CLDR (emoji-test.txt, Unicode Data Files License).
Metadata
Release files for textual-emoji-picker 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| textual_emoji_picker-0.2.0.tar.gz | 98.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| textual_emoji_picker-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 132.2 kB
Release files / textual_emoji_picker-0.2.0.tar.gz
| Download URL | textual_emoji_picker-0.2.0.tar.gz |
|---|---|
| Size | 98.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c8c35ef660114eb1d3cb68cf7cce25148e2eac8d20c9eba525a9d97007bc37f7
|
|
BLAKE2b-256 checksum How to use checksums |
373787d504f7bbd79e735ede4926ec1514504c845ea903bffc80e6d352810281
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 6, 2026.
Transparency logRelease files / textual_emoji_picker-0.2.0-py3-none-any.whl
| Download URL | textual_emoji_picker-0.2.0-py3-none-any.whl |
|---|---|
| Size | 33.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
90504438726d33aafb4bab1664b4bf54b2668ec7d522c500d69781c4b0faab7f
|
|
BLAKE2b-256 checksum How to use checksums |
4ffc1e58248472b6e8347d3b31d4b8a7f07bf1ccca2aee854488b2d6cfc518e4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 6, 2026.
Transparency log