Skip to content

feat: pick emoji from a button in the commit and reply composers - #252

Open
hbenabdallah wants to merge 1 commit into
dev-null-sh:productionfrom
hbenabdallah:feat/emoji-picker
Open

hbenabdallah wants to merge 1 commit into
dev-null-sh:productionfrom
hbenabdallah:feat/emoji-picker

Conversation

@hbenabdallah

@hbenabdallah hbenabdallah commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adding emoji meant typing a :shortcode: from memory. The commit and reply composers now have an emoji button: search, a popular row and every emoji, inserted at the caret. The picker stays open after a click so several emoji can be added; Enter on a search picks the first result and closes it, returning to the text.

Changes

  • EmojiPickerButton (Headless UI popover, 8px radius, capped at 22rem and to the viewport) in both composers. Pressing it keeps the caret in the textarea.
  • useEmojiInsertion inserts over the selection and restores the caret in a layout effect once the body is committed, so long bodies keep the caret after the emoji.
  • Inserts use the textarea's own cap (maxRawBodyLength, maxBodyLength in issue mode), so long links don't block a pick.
  • Emoji come from the existing emoji-shortcodes.json, aliases deduplicated. No new dependency.

Validation

Local checks on 7efdc89:

  • bun run test:lint — passed with existing warnings.
  • bun run test:types — passed.
  • bun run test:unit — 132 passed.
  • bunx vp test --run --config tests/draft-images.config.ts — 305 passed.
  • bun run build — passed. git diff --check — passed.
  • Playwright (Chromium) at every viewport and theme: two clicks insert 🚀🎉 with the picker still open; Enter on "fire" inserts 🔥, closes it, focus back with the caret after it. Reply inserts 👏. A restored draft with the caret at 0 gives 🔥hello. Layout shift while opening, picking and closing: 0.
  • Chrome: a body with three 1500-character links (4580 raw characters) accepts an emoji mid-text and keeps the caret after it.

Hosted CI is separate from these local results.

Visual evidence

Local app, seeded data, base production vs this branch, two emoji clicked.

Commit composer, light

Viewport Before After
1440×900 Before 1440x900 light After 1440x900 light
1366×650 Before 1366x650 light After 1366x650 light
390×844 Before 390x844 light After 390x844 light

Commit composer, dark

Viewport Before After
1440×900 Before 1440x900 dark After 1440x900 dark
1366×650 Before 1366x650 dark After 1366x650 dark
390×844 Before 390x844 dark After 390x844 dark

Reply composer

Viewport Before After
1440×900 light Before reply 1440x900 light After reply 1440x900 light
1440×900 dark Before reply 1440x900 dark After reply 1440x900 dark
1366×650 light Before reply 1366x650 light After reply 1366x650 light
1366×650 dark Before reply 1366x650 dark After reply 1366x650 dark

Device verification

Emulation only: Playwright Chromium at 390×844 with touch and mobile mode. The picker fits the width and ends above the bottom navigation. No physical device or simulator; the on-screen keyboard and safe areas are not covered.

Independent review

Fresh read-only Claude review of base 053bb3099b486442d62f0dfdb41d1166839152b9 and head 7efdc89ec6f2f44871ab9d426c311d34932cc9fd with the captures above: CODE: PASS · VISUAL: PASS · OVERALL: PASS, no blockers. The first pass failed on picking before closing (a restored draft with the caret at 0 got the emoji at the end) and on the popover radius; both were fixed and re-reviewed.

Limitations

  • No physical-device or simulator test; the on-screen keyboard with the picker open is unverified.
  • Only insertAtSelection has unit tests; the hook and component are covered by the browser runs above.
  • The commit composer inserts through the stash directly, skipping issue.change (slash-command detection), which an emoji can't trigger.

@hbenabdallah
hbenabdallah force-pushed the feat/emoji-picker branch 3 times, most recently from 2cba01e to 9da9b13 Compare October 16, 2026 16:50
@hbenabdallah
hbenabdallah marked this pull request as ready for review October 16, 2026 17:04
@brendt

brendt commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

Please fix the conflicts :)

@hbenabdallah

Copy link
Copy Markdown
Contributor Author

Please fix the conflicts :)

Done 👌

@hbenabdallah
hbenabdallah force-pushed the feat/emoji-picker branch 9 times, most recently from 9e77a19 to aec20f9 Compare October 22, 2026 14:06
@ascendaone-com

Copy link
Copy Markdown

Hi @hbenabdallah, thanks for this. I'd started on an emoji button for the commit composer before I saw your PR, so I'd rather help get this one in than open a second one.

emoji-picker-demo

Here's how mine behaves, for comparison (commit composer, desktop, light theme, local dev data):

It reuses the reactions picker, inserts where the caret was, stays open for several picks, puts your most-used emoji first, and opens with ⌘/Ctrl+Shift+E.

A few things from my version that might be useful here, if you and the maintainers want them:

  1. Reuse the reactions picker. Since this PR was opened, feat: react to remote messages with emoji #452 added a searchable EmojiPicker in components/chat/message-reactions.tsx, with usage-based ordering. Building the composer button on that one would avoid shipping two pickers that look and search differently, and would drop most of the new emoji-picker.tsx / lib/emoji-picker.ts.
  2. Caret when opened from the keyboard. Right now, opening the picker with the keyboard inserts at the end of the text. Saving selectionStart/selectionEnd when the popover opens, and putting the caret back after the inserted emoji on close, keeps the insertion where you were typing.
  3. Docs. The repo's guidelines ask for user-visible changes to be added to KNOWLEDGE_BASE.md ("Code, emoji, and mentions" section).

Two more that are probably product decisions, so they could be a follow-up rather than part of this PR:

  • A ⌘/Ctrl+Shift+E shortcut (which would also need a row in keyboard-shortcuts-dialog.tsx and the knowledge-base shortcuts table).
  • Keeping the picker open for several picks, as X does.

My branch has these with unit tests if any of it helps: . I'm happy to open a PR against your branch, or leave it for a follow-up after this merges. Whatever's easiest for you and the maintainers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants