react-emoji-text 1.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +408 -0
- package/dist/adapters/emoji-mart.cjs +9 -0
- package/dist/adapters/emoji-mart.d.cts +7 -0
- package/dist/adapters/emoji-mart.d.cts.map +1 -0
- package/dist/adapters/emoji-mart.d.mts +7 -0
- package/dist/adapters/emoji-mart.d.mts.map +1 -0
- package/dist/adapters/emoji-mart.mjs +10 -0
- package/dist/adapters/emoji-mart.mjs.map +1 -0
- package/dist/adapters/emojibase.cjs +71 -0
- package/dist/adapters/emojibase.d.cts +38 -0
- package/dist/adapters/emojibase.d.cts.map +1 -0
- package/dist/adapters/emojibase.d.mts +38 -0
- package/dist/adapters/emojibase.d.mts.map +1 -0
- package/dist/adapters/emojibase.mjs +72 -0
- package/dist/adapters/emojibase.mjs.map +1 -0
- package/dist/compat/index.cjs +93 -0
- package/dist/compat/index.d.cts +32 -0
- package/dist/compat/index.d.cts.map +1 -0
- package/dist/compat/index.d.mts +32 -0
- package/dist/compat/index.d.mts.map +1 -0
- package/dist/compat/index.mjs +90 -0
- package/dist/compat/index.mjs.map +1 -0
- package/dist/core.cjs +10 -0
- package/dist/core.d.cts +4 -0
- package/dist/core.d.mts +4 -0
- package/dist/core.mjs +2 -0
- package/dist/index-B39vk6JI.d.mts +23 -0
- package/dist/index-B39vk6JI.d.mts.map +1 -0
- package/dist/index-DPd10zCJ.d.cts +23 -0
- package/dist/index-DPd10zCJ.d.cts.map +1 -0
- package/dist/index-DXKnU6tZ.d.cts +398 -0
- package/dist/index-DXKnU6tZ.d.cts.map +1 -0
- package/dist/index-UT6qWHp1.d.mts +398 -0
- package/dist/index-UT6qWHp1.d.mts.map +1 -0
- package/dist/index.cjs +18 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.mjs +5 -0
- package/dist/indexes-3fK5ySH8.d.cts +20 -0
- package/dist/indexes-3fK5ySH8.d.cts.map +1 -0
- package/dist/indexes-BMCSN-X0.d.mts +20 -0
- package/dist/indexes-BMCSN-X0.d.mts.map +1 -0
- package/dist/react/index.cjs +8 -0
- package/dist/react/index.d.cts +2 -0
- package/dist/react/index.d.mts +2 -0
- package/dist/react/index.mjs +3 -0
- package/dist/react-9EdWn0Gg.mjs +196 -0
- package/dist/react-9EdWn0Gg.mjs.map +1 -0
- package/dist/react-C8xGkPhi.cjs +211 -0
- package/dist/render-C7VPZ7if.cjs +140 -0
- package/dist/render-DzloPAWX.mjs +119 -0
- package/dist/render-DzloPAWX.mjs.map +1 -0
- package/dist/tokenize-BUKMZ9Yg.mjs +313 -0
- package/dist/tokenize-BUKMZ9Yg.mjs.map +1 -0
- package/dist/tokenize-CyKMb3O9.cjs +364 -0
- package/dist/types-Dyzdpq-R.d.cts +92 -0
- package/dist/types-Dyzdpq-R.d.cts.map +1 -0
- package/dist/types-o0mRO30y.d.mts +92 -0
- package/dist/types-o0mRO30y.d.mts.map +1 -0
- package/package.json +108 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { n as tokenizeWithIndexes, o as buildIndexes } from "./tokenize-BUKMZ9Yg.mjs";
|
|
2
|
+
import { i as resolveImageUrlFn, n as renderTokenDefault, r as createTokenKeyFactory, t as isOnlyEmoji } from "./render-DzloPAWX.mjs";
|
|
3
|
+
import { Children, Fragment, createContext, createElement, isValidElement, use, useMemo } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/react/provider.tsx
|
|
6
|
+
const EmojiContext = createContext(void 0);
|
|
7
|
+
function EmojiProvider({ data, customEmojis, set = "native", defaultSkin, ascii = true, getImageUrl, imageUrlTemplate, sprite, extraAliases, children }) {
|
|
8
|
+
const indexes = useMemo(() => buildIndexes(data, customEmojis, extraAliases), [
|
|
9
|
+
data,
|
|
10
|
+
customEmojis,
|
|
11
|
+
extraAliases
|
|
12
|
+
]);
|
|
13
|
+
const resolvedGetImageUrl = useMemo(() => resolveImageUrlFn({
|
|
14
|
+
getImageUrl,
|
|
15
|
+
sprite,
|
|
16
|
+
imageUrlTemplate
|
|
17
|
+
}), [
|
|
18
|
+
getImageUrl,
|
|
19
|
+
sprite,
|
|
20
|
+
imageUrlTemplate
|
|
21
|
+
]);
|
|
22
|
+
return /* @__PURE__ */ jsx(EmojiContext, {
|
|
23
|
+
value: useMemo(() => ({
|
|
24
|
+
indexes,
|
|
25
|
+
config: {
|
|
26
|
+
data,
|
|
27
|
+
customEmojis,
|
|
28
|
+
set,
|
|
29
|
+
defaultSkin,
|
|
30
|
+
ascii,
|
|
31
|
+
getImageUrl: resolvedGetImageUrl,
|
|
32
|
+
imageUrlTemplate,
|
|
33
|
+
sprite,
|
|
34
|
+
extraAliases
|
|
35
|
+
},
|
|
36
|
+
resolvedGetImageUrl
|
|
37
|
+
}), [
|
|
38
|
+
indexes,
|
|
39
|
+
data,
|
|
40
|
+
customEmojis,
|
|
41
|
+
set,
|
|
42
|
+
defaultSkin,
|
|
43
|
+
ascii,
|
|
44
|
+
resolvedGetImageUrl,
|
|
45
|
+
imageUrlTemplate,
|
|
46
|
+
sprite,
|
|
47
|
+
extraAliases
|
|
48
|
+
]),
|
|
49
|
+
children
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function useEmojiContext() {
|
|
53
|
+
const context = use(EmojiContext);
|
|
54
|
+
if (!context) throw new Error("useEmojiContext must be used within an EmojiProvider");
|
|
55
|
+
return context;
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/react/use-tokens.ts
|
|
59
|
+
function useTokens(text, overrides) {
|
|
60
|
+
const { config, indexes: contextIndexes } = useEmojiContext();
|
|
61
|
+
const data = overrides?.data ?? config.data;
|
|
62
|
+
const customEmojis = overrides?.customEmojis ?? config.customEmojis;
|
|
63
|
+
const ascii = overrides?.ascii ?? config.ascii;
|
|
64
|
+
const defaultSkin = overrides?.defaultSkin ?? config.defaultSkin;
|
|
65
|
+
const extraAliases = overrides?.extraAliases ?? config.extraAliases;
|
|
66
|
+
const indexes = data === config.data && customEmojis === config.customEmojis && extraAliases === config.extraAliases ? contextIndexes : void 0;
|
|
67
|
+
return useMemo(() => {
|
|
68
|
+
return tokenizeWithIndexes(text, {
|
|
69
|
+
data,
|
|
70
|
+
customEmojis,
|
|
71
|
+
ascii,
|
|
72
|
+
defaultSkin,
|
|
73
|
+
extraAliases,
|
|
74
|
+
indexes
|
|
75
|
+
});
|
|
76
|
+
}, [
|
|
77
|
+
text,
|
|
78
|
+
data,
|
|
79
|
+
customEmojis,
|
|
80
|
+
ascii,
|
|
81
|
+
defaultSkin,
|
|
82
|
+
extraAliases,
|
|
83
|
+
indexes
|
|
84
|
+
]);
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/react/emoji-text.tsx
|
|
88
|
+
function EmojiTextEmoji(_props) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
EmojiTextEmoji.displayName = "EmojiText.Emoji";
|
|
92
|
+
function EmojiTextUnknown(_props) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
EmojiTextUnknown.displayName = "EmojiText.Unknown";
|
|
96
|
+
function collectSlots(children) {
|
|
97
|
+
const slots = {};
|
|
98
|
+
collectSlotChildren(children, slots);
|
|
99
|
+
return slots;
|
|
100
|
+
}
|
|
101
|
+
function collectSlotChildren(children, slots) {
|
|
102
|
+
Children.forEach(children, (child) => {
|
|
103
|
+
if (!isValidElement(child)) return;
|
|
104
|
+
if (child.type === Fragment) {
|
|
105
|
+
collectSlotChildren(child.props.children, slots);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const renderer = child.props.children;
|
|
109
|
+
if (child.type === EmojiTextEmoji && typeof renderer === "function") {
|
|
110
|
+
slots.emoji = renderer;
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (child.type === EmojiTextUnknown && typeof renderer === "function") slots.unknown = renderer;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function TokenNode({ token, slots, defaultRenderOptions }) {
|
|
117
|
+
if (token.type === "emoji" && slots.emoji) return slots.emoji(token);
|
|
118
|
+
if (token.type === "unknown" && slots.unknown) return slots.unknown(token);
|
|
119
|
+
return renderTokenDefault(token, defaultRenderOptions);
|
|
120
|
+
}
|
|
121
|
+
function EmojiTextRoot({ as = "span", className, emojiClassName, onlyEmojiClassName, ref, children, text, data: dataProp, customEmojis: customEmojisProp, set: setProp, defaultSkin: defaultSkinProp, ascii: asciiProp, getImageUrl: getImageUrlProp, imageUrlTemplate: imageUrlTemplateProp, sprite: spriteProp, extraAliases: extraAliasesProp, ...htmlProps }) {
|
|
122
|
+
const context = useEmojiContext();
|
|
123
|
+
const set = setProp ?? context.config.set ?? "native";
|
|
124
|
+
const hasImageOverride = getImageUrlProp !== void 0 || imageUrlTemplateProp !== void 0 || spriteProp !== void 0;
|
|
125
|
+
const resolvedGetImageUrl = useMemo(() => hasImageOverride ? resolveImageUrlFn({
|
|
126
|
+
getImageUrl: getImageUrlProp,
|
|
127
|
+
imageUrlTemplate: imageUrlTemplateProp,
|
|
128
|
+
sprite: spriteProp
|
|
129
|
+
}) : context.resolvedGetImageUrl, [
|
|
130
|
+
context.resolvedGetImageUrl,
|
|
131
|
+
getImageUrlProp,
|
|
132
|
+
hasImageOverride,
|
|
133
|
+
imageUrlTemplateProp,
|
|
134
|
+
spriteProp
|
|
135
|
+
]);
|
|
136
|
+
const tokenOverrides = useMemo(() => ({
|
|
137
|
+
ascii: asciiProp,
|
|
138
|
+
customEmojis: customEmojisProp,
|
|
139
|
+
data: dataProp,
|
|
140
|
+
defaultSkin: defaultSkinProp,
|
|
141
|
+
extraAliases: extraAliasesProp
|
|
142
|
+
}), [
|
|
143
|
+
asciiProp,
|
|
144
|
+
customEmojisProp,
|
|
145
|
+
dataProp,
|
|
146
|
+
defaultSkinProp,
|
|
147
|
+
extraAliasesProp
|
|
148
|
+
]);
|
|
149
|
+
const sourceText = text ?? (typeof children === "string" ? children : "");
|
|
150
|
+
const slots = useMemo(() => collectSlots(children), [children]);
|
|
151
|
+
const tokens = useTokens(sourceText, tokenOverrides);
|
|
152
|
+
const onlyEmoji = useMemo(() => isOnlyEmoji(tokens), [tokens]);
|
|
153
|
+
const defaultRenderOptions = useMemo(() => ({
|
|
154
|
+
emojiClassName,
|
|
155
|
+
getImageUrl: resolvedGetImageUrl,
|
|
156
|
+
set,
|
|
157
|
+
sprite: hasImageOverride ? spriteProp : context.config.sprite
|
|
158
|
+
}), [
|
|
159
|
+
context.config.sprite,
|
|
160
|
+
emojiClassName,
|
|
161
|
+
hasImageOverride,
|
|
162
|
+
resolvedGetImageUrl,
|
|
163
|
+
set,
|
|
164
|
+
spriteProp
|
|
165
|
+
]);
|
|
166
|
+
const wrapperClassName = useMemo(() => [className, onlyEmoji && onlyEmojiClassName].filter(Boolean).join(" ") || void 0, [
|
|
167
|
+
className,
|
|
168
|
+
onlyEmoji,
|
|
169
|
+
onlyEmojiClassName
|
|
170
|
+
]);
|
|
171
|
+
const renderedContent = useMemo(() => {
|
|
172
|
+
const createKey = createTokenKeyFactory();
|
|
173
|
+
return tokens.map((token) => /* @__PURE__ */ jsx(TokenNode, {
|
|
174
|
+
token,
|
|
175
|
+
slots,
|
|
176
|
+
defaultRenderOptions
|
|
177
|
+
}, createKey(token)));
|
|
178
|
+
}, [
|
|
179
|
+
tokens,
|
|
180
|
+
slots,
|
|
181
|
+
defaultRenderOptions
|
|
182
|
+
]);
|
|
183
|
+
return createElement(as, {
|
|
184
|
+
...htmlProps,
|
|
185
|
+
className: wrapperClassName,
|
|
186
|
+
ref
|
|
187
|
+
}, ...renderedContent);
|
|
188
|
+
}
|
|
189
|
+
const EmojiText = Object.assign(EmojiTextRoot, {
|
|
190
|
+
Emoji: EmojiTextEmoji,
|
|
191
|
+
Unknown: EmojiTextUnknown
|
|
192
|
+
});
|
|
193
|
+
//#endregion
|
|
194
|
+
export { useTokens as n, EmojiProvider as r, EmojiText as t };
|
|
195
|
+
|
|
196
|
+
//# sourceMappingURL=react-9EdWn0Gg.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-9EdWn0Gg.mjs","names":[],"sources":["../src/react/provider.tsx","../src/react/use-tokens.ts","../src/react/emoji-text.tsx"],"sourcesContent":["'use client';\n\nimport { type ReactNode, createContext, use, useMemo } from 'react';\nimport { buildIndexes, type EmojiIndexes } from '../core/indexes';\nimport type {\n CustomEmojiCategory,\n EmojiConfig,\n EmojiData,\n EmojiSet,\n GetImageUrl,\n SkinTone,\n SpriteConfig,\n} from '../core/types';\nimport { resolveImageUrlFn } from './image-url';\n\nexport interface EmojiContextValue {\n indexes: EmojiIndexes;\n config: EmojiConfig;\n resolvedGetImageUrl?: GetImageUrl;\n}\n\nconst EmojiContext = createContext<EmojiContextValue | undefined>(undefined);\n\nexport interface EmojiProviderProps {\n data: EmojiData;\n customEmojis?: CustomEmojiCategory[];\n set?: EmojiSet;\n defaultSkin?: SkinTone;\n ascii?: boolean;\n getImageUrl?: GetImageUrl;\n imageUrlTemplate?: string;\n sprite?: SpriteConfig;\n extraAliases?: Record<string, string>;\n children: ReactNode;\n}\n\nexport function EmojiProvider({\n data,\n customEmojis,\n set = 'native',\n defaultSkin,\n ascii = true,\n getImageUrl,\n imageUrlTemplate,\n sprite,\n extraAliases,\n children,\n}: EmojiProviderProps) {\n const indexes = useMemo(\n () => buildIndexes(data, customEmojis, extraAliases),\n [data, customEmojis, extraAliases],\n );\n\n const resolvedGetImageUrl = useMemo(\n () => resolveImageUrlFn({ getImageUrl, sprite, imageUrlTemplate }),\n [getImageUrl, sprite, imageUrlTemplate],\n );\n\n const value = useMemo<EmojiContextValue>(\n () => ({\n indexes,\n config: {\n data,\n customEmojis,\n set,\n defaultSkin,\n ascii,\n getImageUrl: resolvedGetImageUrl,\n imageUrlTemplate,\n sprite,\n extraAliases,\n },\n resolvedGetImageUrl,\n }),\n [\n indexes,\n data,\n customEmojis,\n set,\n defaultSkin,\n ascii,\n resolvedGetImageUrl,\n imageUrlTemplate,\n sprite,\n extraAliases,\n ],\n );\n\n return <EmojiContext value={value}>{children}</EmojiContext>;\n}\n\nexport function useEmojiContext(): EmojiContextValue {\n const context = use(EmojiContext);\n if (!context) {\n throw new Error('useEmojiContext must be used within an EmojiProvider');\n }\n return context;\n}\n","'use client';\n\nimport { useMemo } from 'react';\nimport { tokenizeWithIndexes } from '../core/tokenize';\nimport type { Token, TokenizeOptions } from '../core/types';\nimport { useEmojiContext } from './provider';\n\nexport function useTokens(text: string, overrides?: Partial<TokenizeOptions>): Token[] {\n const { config, indexes: contextIndexes } = useEmojiContext();\n const data = overrides?.data ?? config.data;\n const customEmojis = overrides?.customEmojis ?? config.customEmojis;\n const ascii = overrides?.ascii ?? config.ascii;\n const defaultSkin = overrides?.defaultSkin ?? config.defaultSkin;\n const extraAliases = overrides?.extraAliases ?? config.extraAliases;\n const indexes =\n data === config.data &&\n customEmojis === config.customEmojis &&\n extraAliases === config.extraAliases\n ? contextIndexes\n : undefined;\n\n return useMemo(() => {\n const options: TokenizeOptions = {\n data,\n customEmojis,\n ascii,\n defaultSkin,\n extraAliases,\n };\n return tokenizeWithIndexes(text, { ...options, indexes });\n }, [text, data, customEmojis, ascii, defaultSkin, extraAliases, indexes]);\n}\n","'use client';\n\nimport {\n Children,\n Fragment,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n createElement,\n isValidElement,\n useMemo,\n} from 'react';\nimport type {\n CustomEmojiCategory,\n EmojiData,\n EmojiToken,\n EmojiSet,\n GetImageUrl,\n SkinTone,\n SpriteConfig,\n Token,\n TokenizeOptions,\n UnknownToken,\n} from '../core/types';\nimport { resolveImageUrlFn } from './image-url';\nimport { createTokenKeyFactory } from './keys';\nimport { useEmojiContext } from './provider';\nimport type { DefaultRenderOptions } from './render';\nimport { isOnlyEmoji, renderTokenDefault } from './render';\nimport { useTokens } from './use-tokens';\n\ninterface EmojiTextBaseProps {\n as?: keyof HTMLElementTagNameMap;\n className?: string;\n emojiClassName?: string;\n onlyEmojiClassName?: string;\n ref?: Ref<HTMLElement>;\n}\n\ntype EmojiTextContentProps =\n | {\n children: string;\n text?: never;\n }\n | {\n children?: ReactNode;\n text: string;\n };\n\nexport type EmojiTextProps = EmojiTextBaseProps & EmojiTextContentProps;\n\nexport type EmojiTextComponentProps = EmojiTextProps &\n Omit<HTMLAttributes<HTMLElement>, 'children'> & {\n data?: EmojiData;\n customEmojis?: CustomEmojiCategory[];\n set?: EmojiSet;\n defaultSkin?: SkinTone;\n ascii?: boolean;\n getImageUrl?: GetImageUrl;\n imageUrlTemplate?: string;\n sprite?: SpriteConfig;\n extraAliases?: Record<string, string>;\n };\n\nexport interface EmojiTextEmojiProps {\n children: (token: EmojiToken) => ReactNode;\n}\n\nexport interface EmojiTextUnknownProps {\n children: (token: UnknownToken) => ReactNode;\n}\n\ninterface EmojiTextSlots {\n emoji?: EmojiTextEmojiProps['children'];\n unknown?: EmojiTextUnknownProps['children'];\n}\n\ntype SlotChild = ReactNode | EmojiTextEmojiProps['children'] | EmojiTextUnknownProps['children'];\n\nfunction EmojiTextEmoji(_props: EmojiTextEmojiProps) {\n return null;\n}\n\nEmojiTextEmoji.displayName = 'EmojiText.Emoji';\n\nfunction EmojiTextUnknown(_props: EmojiTextUnknownProps) {\n return null;\n}\n\nEmojiTextUnknown.displayName = 'EmojiText.Unknown';\n\nfunction collectSlots(children: ReactNode): EmojiTextSlots {\n const slots: EmojiTextSlots = {};\n collectSlotChildren(children, slots);\n return slots;\n}\n\nfunction collectSlotChildren(children: ReactNode, slots: EmojiTextSlots) {\n Children.forEach(children, (child) => {\n if (!isValidElement<{ children?: SlotChild }>(child)) return;\n\n if (child.type === Fragment) {\n collectSlotChildren(child.props.children as ReactNode, slots);\n return;\n }\n\n const renderer = child.props.children;\n\n if (child.type === EmojiTextEmoji && typeof renderer === 'function') {\n slots.emoji = renderer as EmojiTextEmojiProps['children'];\n return;\n }\n\n if (child.type === EmojiTextUnknown && typeof renderer === 'function') {\n slots.unknown = renderer as EmojiTextUnknownProps['children'];\n }\n });\n}\n\ninterface TokenNodeProps {\n token: Token;\n slots: EmojiTextSlots;\n defaultRenderOptions: DefaultRenderOptions;\n}\n\nfunction TokenNode({ token, slots, defaultRenderOptions }: TokenNodeProps) {\n if (token.type === 'emoji' && slots.emoji) {\n return slots.emoji(token);\n }\n\n if (token.type === 'unknown' && slots.unknown) {\n return slots.unknown(token);\n }\n\n return renderTokenDefault(token, defaultRenderOptions);\n}\n\nfunction EmojiTextRoot({\n as = 'span',\n className,\n emojiClassName,\n onlyEmojiClassName,\n ref,\n children,\n text,\n data: dataProp,\n customEmojis: customEmojisProp,\n set: setProp,\n defaultSkin: defaultSkinProp,\n ascii: asciiProp,\n getImageUrl: getImageUrlProp,\n imageUrlTemplate: imageUrlTemplateProp,\n sprite: spriteProp,\n extraAliases: extraAliasesProp,\n ...htmlProps\n}: EmojiTextComponentProps) {\n const context = useEmojiContext();\n const set = setProp ?? context.config.set ?? 'native';\n const hasImageOverride =\n getImageUrlProp !== undefined || imageUrlTemplateProp !== undefined || spriteProp !== undefined;\n\n const resolvedGetImageUrl = useMemo(\n () =>\n hasImageOverride\n ? resolveImageUrlFn({\n getImageUrl: getImageUrlProp,\n imageUrlTemplate: imageUrlTemplateProp,\n sprite: spriteProp,\n })\n : context.resolvedGetImageUrl,\n [\n context.resolvedGetImageUrl,\n getImageUrlProp,\n hasImageOverride,\n imageUrlTemplateProp,\n spriteProp,\n ],\n );\n\n const tokenOverrides = useMemo<Partial<TokenizeOptions>>(\n () => ({\n ascii: asciiProp,\n customEmojis: customEmojisProp,\n data: dataProp,\n defaultSkin: defaultSkinProp,\n extraAliases: extraAliasesProp,\n }),\n [asciiProp, customEmojisProp, dataProp, defaultSkinProp, extraAliasesProp],\n );\n\n const sourceText = text ?? (typeof children === 'string' ? children : '');\n const slots = useMemo(() => collectSlots(children), [children]);\n const tokens = useTokens(sourceText, tokenOverrides);\n const onlyEmoji = useMemo(() => isOnlyEmoji(tokens), [tokens]);\n const defaultRenderOptions = useMemo<DefaultRenderOptions>(\n () => ({\n emojiClassName,\n getImageUrl: resolvedGetImageUrl,\n set,\n sprite: hasImageOverride ? spriteProp : context.config.sprite,\n }),\n [context.config.sprite, emojiClassName, hasImageOverride, resolvedGetImageUrl, set, spriteProp],\n );\n\n const wrapperClassName = useMemo(\n () => [className, onlyEmoji && onlyEmojiClassName].filter(Boolean).join(' ') || undefined,\n [className, onlyEmoji, onlyEmojiClassName],\n );\n\n const renderedContent = useMemo(() => {\n const createKey = createTokenKeyFactory();\n return tokens.map((token) => (\n <TokenNode\n key={createKey(token)}\n token={token}\n slots={slots}\n defaultRenderOptions={defaultRenderOptions}\n />\n ));\n }, [tokens, slots, defaultRenderOptions]);\n\n return createElement(as, { ...htmlProps, className: wrapperClassName, ref }, ...renderedContent);\n}\n\nexport const EmojiText = Object.assign(EmojiTextRoot, {\n Emoji: EmojiTextEmoji,\n Unknown: EmojiTextUnknown,\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
const require_tokenize = require("./tokenize-CyKMb3O9.cjs");
|
|
2
|
+
const require_render = require("./render-C7VPZ7if.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
//#region src/react/provider.tsx
|
|
6
|
+
const EmojiContext = (0, react.createContext)(void 0);
|
|
7
|
+
function EmojiProvider({ data, customEmojis, set = "native", defaultSkin, ascii = true, getImageUrl, imageUrlTemplate, sprite, extraAliases, children }) {
|
|
8
|
+
const indexes = (0, react.useMemo)(() => require_tokenize.buildIndexes(data, customEmojis, extraAliases), [
|
|
9
|
+
data,
|
|
10
|
+
customEmojis,
|
|
11
|
+
extraAliases
|
|
12
|
+
]);
|
|
13
|
+
const resolvedGetImageUrl = (0, react.useMemo)(() => require_render.resolveImageUrlFn({
|
|
14
|
+
getImageUrl,
|
|
15
|
+
sprite,
|
|
16
|
+
imageUrlTemplate
|
|
17
|
+
}), [
|
|
18
|
+
getImageUrl,
|
|
19
|
+
sprite,
|
|
20
|
+
imageUrlTemplate
|
|
21
|
+
]);
|
|
22
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmojiContext, {
|
|
23
|
+
value: (0, react.useMemo)(() => ({
|
|
24
|
+
indexes,
|
|
25
|
+
config: {
|
|
26
|
+
data,
|
|
27
|
+
customEmojis,
|
|
28
|
+
set,
|
|
29
|
+
defaultSkin,
|
|
30
|
+
ascii,
|
|
31
|
+
getImageUrl: resolvedGetImageUrl,
|
|
32
|
+
imageUrlTemplate,
|
|
33
|
+
sprite,
|
|
34
|
+
extraAliases
|
|
35
|
+
},
|
|
36
|
+
resolvedGetImageUrl
|
|
37
|
+
}), [
|
|
38
|
+
indexes,
|
|
39
|
+
data,
|
|
40
|
+
customEmojis,
|
|
41
|
+
set,
|
|
42
|
+
defaultSkin,
|
|
43
|
+
ascii,
|
|
44
|
+
resolvedGetImageUrl,
|
|
45
|
+
imageUrlTemplate,
|
|
46
|
+
sprite,
|
|
47
|
+
extraAliases
|
|
48
|
+
]),
|
|
49
|
+
children
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function useEmojiContext() {
|
|
53
|
+
const context = (0, react.use)(EmojiContext);
|
|
54
|
+
if (!context) throw new Error("useEmojiContext must be used within an EmojiProvider");
|
|
55
|
+
return context;
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/react/use-tokens.ts
|
|
59
|
+
function useTokens(text, overrides) {
|
|
60
|
+
const { config, indexes: contextIndexes } = useEmojiContext();
|
|
61
|
+
const data = overrides?.data ?? config.data;
|
|
62
|
+
const customEmojis = overrides?.customEmojis ?? config.customEmojis;
|
|
63
|
+
const ascii = overrides?.ascii ?? config.ascii;
|
|
64
|
+
const defaultSkin = overrides?.defaultSkin ?? config.defaultSkin;
|
|
65
|
+
const extraAliases = overrides?.extraAliases ?? config.extraAliases;
|
|
66
|
+
const indexes = data === config.data && customEmojis === config.customEmojis && extraAliases === config.extraAliases ? contextIndexes : void 0;
|
|
67
|
+
return (0, react.useMemo)(() => {
|
|
68
|
+
return require_tokenize.tokenizeWithIndexes(text, {
|
|
69
|
+
data,
|
|
70
|
+
customEmojis,
|
|
71
|
+
ascii,
|
|
72
|
+
defaultSkin,
|
|
73
|
+
extraAliases,
|
|
74
|
+
indexes
|
|
75
|
+
});
|
|
76
|
+
}, [
|
|
77
|
+
text,
|
|
78
|
+
data,
|
|
79
|
+
customEmojis,
|
|
80
|
+
ascii,
|
|
81
|
+
defaultSkin,
|
|
82
|
+
extraAliases,
|
|
83
|
+
indexes
|
|
84
|
+
]);
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/react/emoji-text.tsx
|
|
88
|
+
function EmojiTextEmoji(_props) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
EmojiTextEmoji.displayName = "EmojiText.Emoji";
|
|
92
|
+
function EmojiTextUnknown(_props) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
EmojiTextUnknown.displayName = "EmojiText.Unknown";
|
|
96
|
+
function collectSlots(children) {
|
|
97
|
+
const slots = {};
|
|
98
|
+
collectSlotChildren(children, slots);
|
|
99
|
+
return slots;
|
|
100
|
+
}
|
|
101
|
+
function collectSlotChildren(children, slots) {
|
|
102
|
+
react.Children.forEach(children, (child) => {
|
|
103
|
+
if (!(0, react.isValidElement)(child)) return;
|
|
104
|
+
if (child.type === react.Fragment) {
|
|
105
|
+
collectSlotChildren(child.props.children, slots);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const renderer = child.props.children;
|
|
109
|
+
if (child.type === EmojiTextEmoji && typeof renderer === "function") {
|
|
110
|
+
slots.emoji = renderer;
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (child.type === EmojiTextUnknown && typeof renderer === "function") slots.unknown = renderer;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function TokenNode({ token, slots, defaultRenderOptions }) {
|
|
117
|
+
if (token.type === "emoji" && slots.emoji) return slots.emoji(token);
|
|
118
|
+
if (token.type === "unknown" && slots.unknown) return slots.unknown(token);
|
|
119
|
+
return require_render.renderTokenDefault(token, defaultRenderOptions);
|
|
120
|
+
}
|
|
121
|
+
function EmojiTextRoot({ as = "span", className, emojiClassName, onlyEmojiClassName, ref, children, text, data: dataProp, customEmojis: customEmojisProp, set: setProp, defaultSkin: defaultSkinProp, ascii: asciiProp, getImageUrl: getImageUrlProp, imageUrlTemplate: imageUrlTemplateProp, sprite: spriteProp, extraAliases: extraAliasesProp, ...htmlProps }) {
|
|
122
|
+
const context = useEmojiContext();
|
|
123
|
+
const set = setProp ?? context.config.set ?? "native";
|
|
124
|
+
const hasImageOverride = getImageUrlProp !== void 0 || imageUrlTemplateProp !== void 0 || spriteProp !== void 0;
|
|
125
|
+
const resolvedGetImageUrl = (0, react.useMemo)(() => hasImageOverride ? require_render.resolveImageUrlFn({
|
|
126
|
+
getImageUrl: getImageUrlProp,
|
|
127
|
+
imageUrlTemplate: imageUrlTemplateProp,
|
|
128
|
+
sprite: spriteProp
|
|
129
|
+
}) : context.resolvedGetImageUrl, [
|
|
130
|
+
context.resolvedGetImageUrl,
|
|
131
|
+
getImageUrlProp,
|
|
132
|
+
hasImageOverride,
|
|
133
|
+
imageUrlTemplateProp,
|
|
134
|
+
spriteProp
|
|
135
|
+
]);
|
|
136
|
+
const tokenOverrides = (0, react.useMemo)(() => ({
|
|
137
|
+
ascii: asciiProp,
|
|
138
|
+
customEmojis: customEmojisProp,
|
|
139
|
+
data: dataProp,
|
|
140
|
+
defaultSkin: defaultSkinProp,
|
|
141
|
+
extraAliases: extraAliasesProp
|
|
142
|
+
}), [
|
|
143
|
+
asciiProp,
|
|
144
|
+
customEmojisProp,
|
|
145
|
+
dataProp,
|
|
146
|
+
defaultSkinProp,
|
|
147
|
+
extraAliasesProp
|
|
148
|
+
]);
|
|
149
|
+
const sourceText = text ?? (typeof children === "string" ? children : "");
|
|
150
|
+
const slots = (0, react.useMemo)(() => collectSlots(children), [children]);
|
|
151
|
+
const tokens = useTokens(sourceText, tokenOverrides);
|
|
152
|
+
const onlyEmoji = (0, react.useMemo)(() => require_render.isOnlyEmoji(tokens), [tokens]);
|
|
153
|
+
const defaultRenderOptions = (0, react.useMemo)(() => ({
|
|
154
|
+
emojiClassName,
|
|
155
|
+
getImageUrl: resolvedGetImageUrl,
|
|
156
|
+
set,
|
|
157
|
+
sprite: hasImageOverride ? spriteProp : context.config.sprite
|
|
158
|
+
}), [
|
|
159
|
+
context.config.sprite,
|
|
160
|
+
emojiClassName,
|
|
161
|
+
hasImageOverride,
|
|
162
|
+
resolvedGetImageUrl,
|
|
163
|
+
set,
|
|
164
|
+
spriteProp
|
|
165
|
+
]);
|
|
166
|
+
const wrapperClassName = (0, react.useMemo)(() => [className, onlyEmoji && onlyEmojiClassName].filter(Boolean).join(" ") || void 0, [
|
|
167
|
+
className,
|
|
168
|
+
onlyEmoji,
|
|
169
|
+
onlyEmojiClassName
|
|
170
|
+
]);
|
|
171
|
+
const renderedContent = (0, react.useMemo)(() => {
|
|
172
|
+
const createKey = require_render.createTokenKeyFactory();
|
|
173
|
+
return tokens.map((token) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TokenNode, {
|
|
174
|
+
token,
|
|
175
|
+
slots,
|
|
176
|
+
defaultRenderOptions
|
|
177
|
+
}, createKey(token)));
|
|
178
|
+
}, [
|
|
179
|
+
tokens,
|
|
180
|
+
slots,
|
|
181
|
+
defaultRenderOptions
|
|
182
|
+
]);
|
|
183
|
+
return (0, react.createElement)(as, {
|
|
184
|
+
...htmlProps,
|
|
185
|
+
className: wrapperClassName,
|
|
186
|
+
ref
|
|
187
|
+
}, ...renderedContent);
|
|
188
|
+
}
|
|
189
|
+
const EmojiText = Object.assign(EmojiTextRoot, {
|
|
190
|
+
Emoji: EmojiTextEmoji,
|
|
191
|
+
Unknown: EmojiTextUnknown
|
|
192
|
+
});
|
|
193
|
+
//#endregion
|
|
194
|
+
Object.defineProperty(exports, "EmojiProvider", {
|
|
195
|
+
enumerable: true,
|
|
196
|
+
get: function() {
|
|
197
|
+
return EmojiProvider;
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
Object.defineProperty(exports, "EmojiText", {
|
|
201
|
+
enumerable: true,
|
|
202
|
+
get: function() {
|
|
203
|
+
return EmojiText;
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
Object.defineProperty(exports, "useTokens", {
|
|
207
|
+
enumerable: true,
|
|
208
|
+
get: function() {
|
|
209
|
+
return useTokens;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
2
|
+
//#region src/react/image-url.ts
|
|
3
|
+
function interpolateTemplate(template, values) {
|
|
4
|
+
return Object.entries(values).reduce((result, [key, value]) => result.split(`{${key}}`).join(value), template);
|
|
5
|
+
}
|
|
6
|
+
function resolveImageUrlFn({ getImageUrl, sprite, imageUrlTemplate }) {
|
|
7
|
+
if (getImageUrl) return getImageUrl;
|
|
8
|
+
if (sprite) return void 0;
|
|
9
|
+
if (!imageUrlTemplate) return void 0;
|
|
10
|
+
return (_emoji, context) => interpolateTemplate(imageUrlTemplate, {
|
|
11
|
+
set: context.set,
|
|
12
|
+
skin: String(context.skin),
|
|
13
|
+
unified: context.unified
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/react/keys.ts
|
|
18
|
+
function tokenKeyBase(token) {
|
|
19
|
+
switch (token.type) {
|
|
20
|
+
case "text": return `text:${token.value}`;
|
|
21
|
+
case "unknown": return `unknown:${token.match}`;
|
|
22
|
+
case "emoji": return [
|
|
23
|
+
"emoji",
|
|
24
|
+
token.emoji.id,
|
|
25
|
+
token.source,
|
|
26
|
+
token.shortcode ?? "",
|
|
27
|
+
token.match,
|
|
28
|
+
token.native
|
|
29
|
+
].join(":");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function createTokenKeyFactory() {
|
|
33
|
+
const seen = /* @__PURE__ */ new Map();
|
|
34
|
+
return (token) => {
|
|
35
|
+
const base = tokenKeyBase(token);
|
|
36
|
+
const occurrence = seen.get(base) ?? 0;
|
|
37
|
+
seen.set(base, occurrence + 1);
|
|
38
|
+
return occurrence === 0 ? base : `${base}:${occurrence}`;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/react/render.tsx
|
|
43
|
+
function renderTokenDefault(token, options) {
|
|
44
|
+
switch (token.type) {
|
|
45
|
+
case "text": return token.value;
|
|
46
|
+
case "emoji": return renderEmojiDefault(token, options);
|
|
47
|
+
case "unknown": return renderUnknownDefault(token);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function renderEmojiDefault(token, options) {
|
|
51
|
+
if (token.source === "custom") {
|
|
52
|
+
const src = token.emoji.skins[0]?.src;
|
|
53
|
+
if (!src) return token.match;
|
|
54
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
55
|
+
src,
|
|
56
|
+
alt: token.shortcode ?? token.emoji.id,
|
|
57
|
+
className: options.emojiClassName,
|
|
58
|
+
style: emojiImageStyle
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (options.set === "native") return token.native;
|
|
62
|
+
const skinEntry = getResolvedSkinEntry(token);
|
|
63
|
+
if (options.getImageUrl) {
|
|
64
|
+
const context = {
|
|
65
|
+
set: options.set,
|
|
66
|
+
skin: token.skin ?? 1,
|
|
67
|
+
unified: skinEntry?.unified ?? ""
|
|
68
|
+
};
|
|
69
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
70
|
+
src: options.getImageUrl(token.emoji, context),
|
|
71
|
+
alt: token.native,
|
|
72
|
+
className: options.emojiClassName,
|
|
73
|
+
style: emojiImageStyle
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (options.sprite && skinEntry) return renderSpriteEmoji(token, skinEntry, options.sprite, options.emojiClassName);
|
|
77
|
+
return token.native;
|
|
78
|
+
}
|
|
79
|
+
function getResolvedSkinEntry(token) {
|
|
80
|
+
if (token.skin) return token.emoji.skins[token.skin - 1] ?? token.emoji.skins[0];
|
|
81
|
+
return token.emoji.skins.find((skin) => skin.native === token.native) ?? token.emoji.skins[0];
|
|
82
|
+
}
|
|
83
|
+
function findSpriteCoordinates(sprite, unified) {
|
|
84
|
+
return sprite.sheet[unified] ?? sprite.sheet[unified.toLowerCase()] ?? sprite.sheet[unified.toUpperCase()];
|
|
85
|
+
}
|
|
86
|
+
function renderSpriteEmoji(token, skinEntry, sprite, emojiClassName) {
|
|
87
|
+
const coordinates = findSpriteCoordinates(sprite, skinEntry.unified);
|
|
88
|
+
if (!coordinates) return token.native;
|
|
89
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
90
|
+
role: "img",
|
|
91
|
+
"aria-label": token.native,
|
|
92
|
+
className: emojiClassName,
|
|
93
|
+
style: {
|
|
94
|
+
backgroundImage: `url(${sprite.src})`,
|
|
95
|
+
backgroundPosition: `-${coordinates.x * sprite.size}px -${coordinates.y * sprite.size}px`,
|
|
96
|
+
backgroundSize: `${sprite.columns * sprite.size}px auto`,
|
|
97
|
+
display: "inline-block",
|
|
98
|
+
height: `${sprite.size}px`,
|
|
99
|
+
verticalAlign: "-0.1em",
|
|
100
|
+
width: `${sprite.size}px`
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
function renderUnknownDefault(token) {
|
|
105
|
+
return token.match;
|
|
106
|
+
}
|
|
107
|
+
const emojiImageStyle = {
|
|
108
|
+
display: "inline",
|
|
109
|
+
height: "1em",
|
|
110
|
+
verticalAlign: "-0.1em",
|
|
111
|
+
width: "1em"
|
|
112
|
+
};
|
|
113
|
+
function isOnlyEmoji(tokens) {
|
|
114
|
+
return tokens.some((token) => token.type === "emoji") && tokens.every((token) => token.type === "emoji" || token.type === "text" && token.value.trim() === "");
|
|
115
|
+
}
|
|
116
|
+
//#endregion
|
|
117
|
+
Object.defineProperty(exports, "createTokenKeyFactory", {
|
|
118
|
+
enumerable: true,
|
|
119
|
+
get: function() {
|
|
120
|
+
return createTokenKeyFactory;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
Object.defineProperty(exports, "isOnlyEmoji", {
|
|
124
|
+
enumerable: true,
|
|
125
|
+
get: function() {
|
|
126
|
+
return isOnlyEmoji;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
Object.defineProperty(exports, "renderTokenDefault", {
|
|
130
|
+
enumerable: true,
|
|
131
|
+
get: function() {
|
|
132
|
+
return renderTokenDefault;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
Object.defineProperty(exports, "resolveImageUrlFn", {
|
|
136
|
+
enumerable: true,
|
|
137
|
+
get: function() {
|
|
138
|
+
return resolveImageUrlFn;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
//#region src/react/image-url.ts
|
|
3
|
+
function interpolateTemplate(template, values) {
|
|
4
|
+
return Object.entries(values).reduce((result, [key, value]) => result.split(`{${key}}`).join(value), template);
|
|
5
|
+
}
|
|
6
|
+
function resolveImageUrlFn({ getImageUrl, sprite, imageUrlTemplate }) {
|
|
7
|
+
if (getImageUrl) return getImageUrl;
|
|
8
|
+
if (sprite) return void 0;
|
|
9
|
+
if (!imageUrlTemplate) return void 0;
|
|
10
|
+
return (_emoji, context) => interpolateTemplate(imageUrlTemplate, {
|
|
11
|
+
set: context.set,
|
|
12
|
+
skin: String(context.skin),
|
|
13
|
+
unified: context.unified
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/react/keys.ts
|
|
18
|
+
function tokenKeyBase(token) {
|
|
19
|
+
switch (token.type) {
|
|
20
|
+
case "text": return `text:${token.value}`;
|
|
21
|
+
case "unknown": return `unknown:${token.match}`;
|
|
22
|
+
case "emoji": return [
|
|
23
|
+
"emoji",
|
|
24
|
+
token.emoji.id,
|
|
25
|
+
token.source,
|
|
26
|
+
token.shortcode ?? "",
|
|
27
|
+
token.match,
|
|
28
|
+
token.native
|
|
29
|
+
].join(":");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function createTokenKeyFactory() {
|
|
33
|
+
const seen = /* @__PURE__ */ new Map();
|
|
34
|
+
return (token) => {
|
|
35
|
+
const base = tokenKeyBase(token);
|
|
36
|
+
const occurrence = seen.get(base) ?? 0;
|
|
37
|
+
seen.set(base, occurrence + 1);
|
|
38
|
+
return occurrence === 0 ? base : `${base}:${occurrence}`;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/react/render.tsx
|
|
43
|
+
function renderTokenDefault(token, options) {
|
|
44
|
+
switch (token.type) {
|
|
45
|
+
case "text": return token.value;
|
|
46
|
+
case "emoji": return renderEmojiDefault(token, options);
|
|
47
|
+
case "unknown": return renderUnknownDefault(token);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function renderEmojiDefault(token, options) {
|
|
51
|
+
if (token.source === "custom") {
|
|
52
|
+
const src = token.emoji.skins[0]?.src;
|
|
53
|
+
if (!src) return token.match;
|
|
54
|
+
return /* @__PURE__ */ jsx("img", {
|
|
55
|
+
src,
|
|
56
|
+
alt: token.shortcode ?? token.emoji.id,
|
|
57
|
+
className: options.emojiClassName,
|
|
58
|
+
style: emojiImageStyle
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (options.set === "native") return token.native;
|
|
62
|
+
const skinEntry = getResolvedSkinEntry(token);
|
|
63
|
+
if (options.getImageUrl) {
|
|
64
|
+
const context = {
|
|
65
|
+
set: options.set,
|
|
66
|
+
skin: token.skin ?? 1,
|
|
67
|
+
unified: skinEntry?.unified ?? ""
|
|
68
|
+
};
|
|
69
|
+
return /* @__PURE__ */ jsx("img", {
|
|
70
|
+
src: options.getImageUrl(token.emoji, context),
|
|
71
|
+
alt: token.native,
|
|
72
|
+
className: options.emojiClassName,
|
|
73
|
+
style: emojiImageStyle
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (options.sprite && skinEntry) return renderSpriteEmoji(token, skinEntry, options.sprite, options.emojiClassName);
|
|
77
|
+
return token.native;
|
|
78
|
+
}
|
|
79
|
+
function getResolvedSkinEntry(token) {
|
|
80
|
+
if (token.skin) return token.emoji.skins[token.skin - 1] ?? token.emoji.skins[0];
|
|
81
|
+
return token.emoji.skins.find((skin) => skin.native === token.native) ?? token.emoji.skins[0];
|
|
82
|
+
}
|
|
83
|
+
function findSpriteCoordinates(sprite, unified) {
|
|
84
|
+
return sprite.sheet[unified] ?? sprite.sheet[unified.toLowerCase()] ?? sprite.sheet[unified.toUpperCase()];
|
|
85
|
+
}
|
|
86
|
+
function renderSpriteEmoji(token, skinEntry, sprite, emojiClassName) {
|
|
87
|
+
const coordinates = findSpriteCoordinates(sprite, skinEntry.unified);
|
|
88
|
+
if (!coordinates) return token.native;
|
|
89
|
+
return /* @__PURE__ */ jsx("span", {
|
|
90
|
+
role: "img",
|
|
91
|
+
"aria-label": token.native,
|
|
92
|
+
className: emojiClassName,
|
|
93
|
+
style: {
|
|
94
|
+
backgroundImage: `url(${sprite.src})`,
|
|
95
|
+
backgroundPosition: `-${coordinates.x * sprite.size}px -${coordinates.y * sprite.size}px`,
|
|
96
|
+
backgroundSize: `${sprite.columns * sprite.size}px auto`,
|
|
97
|
+
display: "inline-block",
|
|
98
|
+
height: `${sprite.size}px`,
|
|
99
|
+
verticalAlign: "-0.1em",
|
|
100
|
+
width: `${sprite.size}px`
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
function renderUnknownDefault(token) {
|
|
105
|
+
return token.match;
|
|
106
|
+
}
|
|
107
|
+
const emojiImageStyle = {
|
|
108
|
+
display: "inline",
|
|
109
|
+
height: "1em",
|
|
110
|
+
verticalAlign: "-0.1em",
|
|
111
|
+
width: "1em"
|
|
112
|
+
};
|
|
113
|
+
function isOnlyEmoji(tokens) {
|
|
114
|
+
return tokens.some((token) => token.type === "emoji") && tokens.every((token) => token.type === "emoji" || token.type === "text" && token.value.trim() === "");
|
|
115
|
+
}
|
|
116
|
+
//#endregion
|
|
117
|
+
export { resolveImageUrlFn as i, renderTokenDefault as n, createTokenKeyFactory as r, isOnlyEmoji as t };
|
|
118
|
+
|
|
119
|
+
//# sourceMappingURL=render-DzloPAWX.mjs.map
|