feat: add custom emoji category support#32
feat: add custom emoji category support#32mjcampagna wants to merge 23 commits intoliveblocks:mainfrom
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
7097db9 to
2bf6ab4
Compare
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-019cf809-1bbe-7158-a32f-d7f240e4c1ce
2bf6ab4 to
51ef08a
Compare
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
feat: add custom emoji category support
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
Custom emojis have emoji=undefined, so comparing by emoji string made all custom emojis highlight simultaneously. Compare by id for custom emojis, fall back to emoji string for native emojis. Amp-Thread-ID: https://ampcode.com/threads/T-019cf8a1-c9b3-73c2-9875-c764ee274352 Co-authored-by: Amp <amp@ampcode.com>
Adds a 'frequently' prop to EmojiPicker.Root that accepts EmojiPickerEmoji[] and prepends them as a 'Frequently Used' category at the top of the picker. Hidden during search. Amp-Thread-ID: https://ampcode.com/threads/T-019cf8a1-c9b3-73c2-9875-c764ee274352 Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019cf8a1-c9b3-73c2-9875-c764ee274352 Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019cf809-1bbe-7158-a32f-d7f240e4c1ce Co-authored-by: Amp <amp@ampcode.com>
…lues Amp-Thread-ID: https://ampcode.com/threads/T-019cf809-1bbe-7158-a32f-d7f240e4c1ce Co-authored-by: Amp <amp@ampcode.com>
e6908d3 to
69e817f
Compare
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
Amp-Thread-ID: https://ampcode.com/threads/T-019cf809-1bbe-7158-a32f-d7f240e4c1ce Co-authored-by: Amp <amp@ampcode.com>
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
|
@ym-project Thanks for the quick feedback. I've made updates. Let me know if you need anything else. |
Unfortunately I'm not a contributor. I was just passing by :) |
Extract all custom emoji logic out of upstream files and into new isolated modules (custom-emoji-types.ts, data/custom-emoji.ts, utils/emoji-identity.ts) so the feature can be removed by deleting those files and reverting a small number of upstream call sites. - Restore upstream EmojiPickerEmoji and EmojiPickerRootProps shapes; extend via type intersection (CustomEmojiRootProps) instead of in-place mutation - Extract buildFrequentlyUsedRows and buildCustomCategoryRows out of getEmojiPickerData into src/data/custom-emoji.ts - Extract isSameEmoji identity check into src/utils/emoji-identity.ts - Re-export EmojiPickerRootProps from index.ts as the merged alias so the public API is unchanged - Widen EmojiPickerEmoji with id?, url?, emoji? to eliminate type casts - Add isolation principles to AGENTS.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the stale 3-file modification list with an accurate description of the isolated structure: new files, upstream touch points, and a step-by-step guide for removing the feature entirely. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When searchLabel is provided, search results from native and custom emojis are merged into a single flat category ranked by relevance (label +10, tag +1), replacing the default per-category display. When omitted, upstream search behaviour is preserved. - Add searchLabel to CustomEmojiRootProps - Add scoreEmoji() shared scoring helper to custom-emoji.ts - Refactor searchCustomEmojis() to use scoreEmoji() - Add buildUnifiedSearchRows() to custom-emoji.ts - Add early-return unified search branch in getEmojiPickerData() - Wire searchLabel through EmojiPickerDataHandler and EmojiPickerRoot - Update AGENTS.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously, unified search was activated by providing searchLabel. Now unifiedSearch boolean controls the feature and searchLabel is an independent optional label (defaults to empty string). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- src/utils/__tests__/emoji-identity.test.ts: isSameEmoji (native, custom, cross-type, undefined inputs) - src/data/__tests__/custom-emoji.test.ts: scoreEmoji, buildFrequentlyUsedRows, buildCustomCategoryRows, buildUnifiedSearchRows - src/data/__tests__/emoji-picker.test.ts: custom categories, frequently used, unified search (enabled/disabled/label) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without this, useActiveEmoji() always returns undefined when hovering custom emojis — sameEmojiPickerEmoji compared by emoji string, and custom emojis have emoji: undefined, so undefined === undefined always returned true, suppressing selector updates. Mirrors the logic in isSameEmoji (src/utils/emoji-identity.ts). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without the guard, transitioning from no hover (undefined) to a custom emoji called sameEmojiPickerEmoji(undefined, customEmoji). The id check didn't fire (a?.id is undefined), falling through to undefined === undefined → true, still suppressing the update. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…moji, and prop reference Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
Searching by shortcode (e.g. "white_check_mark") now matches native and
custom emojis even when the shortcode doesn't appear in the label or tags.
- Normalize underscores to spaces in search text so shortcode-style
queries ("waving_hand") work as phrase matches against labels
- Extend scoreEmoji() with a shortcodes parameter (scored +10); custom
emojis use their id as a shortcode, native emojis use emojibase data
- Add src/data/shortcodes.ts: fetches en/shortcodes/emojibase.json on
mount (sessionStorage-cached), exposes getShortcodesForEmoji() keyed
by Unicode hexcode (variation selectors stripped)
- Kick off loadShortcodes() in EmojiPickerDataHandler alongside the
existing getEmojiData() call (fire-and-forget, degrades gracefully)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |

Summary
Adds support for image-based custom emoji categories, frequently used emojis, and unified cross-type search — all as opt-in props on
<EmojiPicker.Root>.New Props
customCustomCategory[]frequentlyEmojiPickerEmoji[]frequentlyLabelstring"Frequently Used"unifiedSearchbooleanfalsetrue, all search results are merged into one ranked list.searchLabelstring""unifiedSearchis active.New Types
Both are exported from the package.
EmojiPickerRootPropsis augmented via intersection (not mutation) so the public type includes all new props.New Exports
CustomEmoji— type for individual custom emojiCustomCategory— type for a custom emoji categoryscoreEmoji(label, tags, searchText): number— the search scoring function, exported for consumer useArchitecture
All new code lives in dedicated files:
src/custom-emoji-types.ts— new types andCustomEmojiRootPropsinterfacesrc/data/custom-emoji.ts—buildFrequentlyUsedRows,buildCustomCategoryRows,buildUnifiedSearchRows,scoreEmojisrc/utils/emoji-identity.ts—isSameEmojifor comparing native and custom emojisUpstream files (
src/types.ts,src/data/emoji-picker.ts,src/components/emoji-picker.tsx,src/store.ts) are touched minimally — each change is a delegation call or an optional-param addition at a single call site.Search Scoring
Custom emoji search mirrors the upstream
searchEmojisscoring (+10 label match, +1 per tag match).scoreEmojiis extracted as a shared helper to reduce duplication within our own code.Unified Search
When
unifiedSearchis enabled,buildUnifiedSearchRowsmerges native and custom emoji results into a single score-ranked list instead of displaying them in separate categories.Type Widening
EmojiPickerEmojiis widened to{ emoji?: string; label: string; url?: string; id?: string }to accommodate both native and custom emojis without casts. The upstreamEmojiPickerRootPropsexport is shadowed insrc/index.tsby an augmented version that includesCustomEmojiRootProps.Bug Fixes
sameEmojiPickerEmojiinstore.ts: fixed two bugs where custom emojis (withemoji: undefined) would always compare as equal, suppressinguseActiveEmoji()updates. Now guards forundefinedfirst and compares custom emojis byid.Tests
New test files:
src/data/__tests__/custom-emoji.test.ts— 15 tests forscoreEmoji,buildFrequentlyUsedRows,buildCustomCategoryRows,buildUnifiedSearchRowssrc/utils/__tests__/emoji-identity.test.ts— 4 tests forisSameEmojiExtended:
src/data/__tests__/emoji-picker.test.ts— 9 new tests for custom categories, frequently used, and unified searchDocs
See
CUSTOM-EMOJIS.mdfor full usage documentation including examples, prop reference, and type definitions.