From 538ae5117d2ebc01bec8966d79bb82eba81dd1ad Mon Sep 17 00:00:00 2001 From: Yarchik Date: Tue, 23 Jun 2026 00:29:26 +0100 Subject: [PATCH] fix: strip and replace emoji that have a skin tone modifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `strip()` and `replace()` left skin-tone-modified emoji in place, even though `which()` and `unemojify()` recognise them: strip('X👍🏽Y') // 'X👍🏽Y' (expected 'XY') replace('👍🏽', () => 'Z') // '👍🏽' (expected 'Z') which('👍🏽') // '+1' (recognised) `replace()` looked the character up with `findByCode(character)` on the raw character, while `which()` first normalises the skin tone with `findByCode(skinTone(emoji, 'none'))`. Apply the same normalisation in `replace()` (which `strip()` delegates to). `skin-tone` is already a dependency, and the base table contains no skin-tone scalars, so plain emoji are unaffected. --- src/replace.test.ts | 5 +++++ src/replace.ts | 3 ++- src/strip.test.ts | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/replace.test.ts b/src/replace.test.ts index d1a4ca7..751e947 100644 --- a/src/replace.test.ts +++ b/src/replace.test.ts @@ -61,4 +61,9 @@ describe('replace', () => { it('ignores known existing complex emojis', () => { expect(replace('Some 🍕❤️‍💋‍☕ emoji', '')).toBe('Some ❤️‍💋‍☕ emoji') }) + + it('replaces an emoji that has a skin tone modifier', () => { + expect(replace('👍🏽', () => 'Z')).toBe('Z') + expect(replace('thumbs 👍🏽 up', '')).toBe('thumbs up') + }) }) diff --git a/src/replace.ts b/src/replace.ts index e11cc69..d70ce80 100644 --- a/src/replace.ts +++ b/src/replace.ts @@ -1,4 +1,5 @@ import { assert } from '@sindresorhus/is' +import skinTone from 'skin-tone' import { Emoji } from './data.js' import { findByCode } from './findByCode.js' @@ -31,7 +32,7 @@ export const replace = ( return characters .map((character, index) => { - const found = findByCode(character) + const found = findByCode(skinTone(character, 'none')) if (!found) { return character } diff --git a/src/strip.test.ts b/src/strip.test.ts index 904b212..6179c88 100644 --- a/src/strip.test.ts +++ b/src/strip.test.ts @@ -22,4 +22,9 @@ describe('strip', () => { it('preserves spaces around emoji when preserveSpaces is true', () => { expect(strip('a ☕ c', { preserveSpaces: true })).toBe('a c') }) + + it('removes an emoji that has a skin tone modifier', () => { + expect(strip('X👍🏽Y')).toBe('XY') + expect(strip('a👋🏿b✋🏼c')).toBe('abc') + }) })