diff --git a/.changeset/pretty-flies-clean.md b/.changeset/pretty-flies-clean.md new file mode 100644 index 000000000..020de1dd1 --- /dev/null +++ b/.changeset/pretty-flies-clean.md @@ -0,0 +1,7 @@ +--- +'@react-pdf/layout': patch +'@react-pdf/types': patch +'@react-pdf/font': patch +--- + +feat: add withVariationSelectors option to registerEmojiSource [#2466](https://github.com/diegomura/react-pdf/issues/2466) diff --git a/packages/font/src/index.js b/packages/font/src/index.js index 240d71941..fe3b23cc0 100644 --- a/packages/font/src/index.js +++ b/packages/font/src/index.js @@ -25,8 +25,13 @@ function FontStore() { } }; - this.registerEmojiSource = ({ url, format = 'png', builder }) => { - emojiSource = { url, format, builder }; + this.registerEmojiSource = ({ + url, + format = 'png', + builder, + withVariationSelectors = false, + }) => { + emojiSource = { url, format, builder, withVariationSelectors }; }; this.registerHyphenationCallback = callback => { diff --git a/packages/layout/src/text/emoji.js b/packages/layout/src/text/emoji.js index 083777157..ab7cf6bef 100644 --- a/packages/layout/src/text/emoji.js +++ b/packages/layout/src/text/emoji.js @@ -16,7 +16,7 @@ const reflect = promise => (...args) => const makeFetchEmojiImage = () => reflect(resolveImage); /** - * When an emoji as no color, it might still have 2 parts, + * When an emoji as no variations, it might still have 2 parts, * the canonical emoji and an empty string. * ex. * (no color) Array.from('❤️') => ["❤", "️"] @@ -25,21 +25,21 @@ const makeFetchEmojiImage = () => reflect(resolveImage); * The empty string needs to be removed otherwise the generated * url will be incorect. */ -const _removeNoColor = x => x !== '️'; +const _removeVariationSelectors = x => x !== '️'; -const getCodePoints = string => +const getCodePoints = (string, withVariationSelectors) => Array.from(string) - .filter(_removeNoColor) + .filter(withVariationSelectors ? () => true : _removeVariationSelectors) .map(char => char.codePointAt(0).toString(16)) .join('-'); const buildEmojiUrl = (emoji, source) => { - const { url, format, builder } = source; + const { url, format, builder, withVariationSelectors } = source; if (typeof builder === 'function') { - return builder(getCodePoints(emoji)); + return builder(getCodePoints(emoji, withVariationSelectors)); } - return `${url}${getCodePoints(emoji)}.${format}`; + return `${url}${getCodePoints(emoji, withVariationSelectors)}.${format}`; }; export const fetchEmojis = (string, source) => { diff --git a/packages/types/font.d.ts b/packages/types/font.d.ts index 7339fbb02..e04d1ccb8 100644 --- a/packages/types/font.d.ts +++ b/packages/types/font.d.ts @@ -49,10 +49,12 @@ interface RegisteredFont { interface EmojiSourceUrl { url: string; format?: string; + withVariationSelectors?: boolean; } interface EmojiSourceBuilder { builder: (code: string) => string; + withVariationSelectors?: boolean; } type EmojiSource = EmojiSourceUrl | EmojiSourceBuilder;