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.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +408 -0
  3. package/dist/adapters/emoji-mart.cjs +9 -0
  4. package/dist/adapters/emoji-mart.d.cts +7 -0
  5. package/dist/adapters/emoji-mart.d.cts.map +1 -0
  6. package/dist/adapters/emoji-mart.d.mts +7 -0
  7. package/dist/adapters/emoji-mart.d.mts.map +1 -0
  8. package/dist/adapters/emoji-mart.mjs +10 -0
  9. package/dist/adapters/emoji-mart.mjs.map +1 -0
  10. package/dist/adapters/emojibase.cjs +71 -0
  11. package/dist/adapters/emojibase.d.cts +38 -0
  12. package/dist/adapters/emojibase.d.cts.map +1 -0
  13. package/dist/adapters/emojibase.d.mts +38 -0
  14. package/dist/adapters/emojibase.d.mts.map +1 -0
  15. package/dist/adapters/emojibase.mjs +72 -0
  16. package/dist/adapters/emojibase.mjs.map +1 -0
  17. package/dist/compat/index.cjs +93 -0
  18. package/dist/compat/index.d.cts +32 -0
  19. package/dist/compat/index.d.cts.map +1 -0
  20. package/dist/compat/index.d.mts +32 -0
  21. package/dist/compat/index.d.mts.map +1 -0
  22. package/dist/compat/index.mjs +90 -0
  23. package/dist/compat/index.mjs.map +1 -0
  24. package/dist/core.cjs +10 -0
  25. package/dist/core.d.cts +4 -0
  26. package/dist/core.d.mts +4 -0
  27. package/dist/core.mjs +2 -0
  28. package/dist/index-B39vk6JI.d.mts +23 -0
  29. package/dist/index-B39vk6JI.d.mts.map +1 -0
  30. package/dist/index-DPd10zCJ.d.cts +23 -0
  31. package/dist/index-DPd10zCJ.d.cts.map +1 -0
  32. package/dist/index-DXKnU6tZ.d.cts +398 -0
  33. package/dist/index-DXKnU6tZ.d.cts.map +1 -0
  34. package/dist/index-UT6qWHp1.d.mts +398 -0
  35. package/dist/index-UT6qWHp1.d.mts.map +1 -0
  36. package/dist/index.cjs +18 -0
  37. package/dist/index.d.cts +5 -0
  38. package/dist/index.d.mts +5 -0
  39. package/dist/index.mjs +5 -0
  40. package/dist/indexes-3fK5ySH8.d.cts +20 -0
  41. package/dist/indexes-3fK5ySH8.d.cts.map +1 -0
  42. package/dist/indexes-BMCSN-X0.d.mts +20 -0
  43. package/dist/indexes-BMCSN-X0.d.mts.map +1 -0
  44. package/dist/react/index.cjs +8 -0
  45. package/dist/react/index.d.cts +2 -0
  46. package/dist/react/index.d.mts +2 -0
  47. package/dist/react/index.mjs +3 -0
  48. package/dist/react-9EdWn0Gg.mjs +196 -0
  49. package/dist/react-9EdWn0Gg.mjs.map +1 -0
  50. package/dist/react-C8xGkPhi.cjs +211 -0
  51. package/dist/render-C7VPZ7if.cjs +140 -0
  52. package/dist/render-DzloPAWX.mjs +119 -0
  53. package/dist/render-DzloPAWX.mjs.map +1 -0
  54. package/dist/tokenize-BUKMZ9Yg.mjs +313 -0
  55. package/dist/tokenize-BUKMZ9Yg.mjs.map +1 -0
  56. package/dist/tokenize-CyKMb3O9.cjs +364 -0
  57. package/dist/types-Dyzdpq-R.d.cts +92 -0
  58. package/dist/types-Dyzdpq-R.d.cts.map +1 -0
  59. package/dist/types-o0mRO30y.d.mts +92 -0
  60. package/dist/types-o0mRO30y.d.mts.map +1 -0
  61. package/package.json +108 -0
@@ -0,0 +1,364 @@
1
+ //#region src/core/ascii.ts
2
+ const CURATED_ASCII = {
3
+ ":)": "slightly_smiling_face",
4
+ ":-)": "slightly_smiling_face",
5
+ ":(": "slightly_frowning_face",
6
+ ":-(": "slightly_frowning_face",
7
+ ";)": "wink",
8
+ ";-)": "wink",
9
+ ":P": "stuck_out_tongue",
10
+ ":-P": "stuck_out_tongue",
11
+ ":p": "stuck_out_tongue",
12
+ ":-p": "stuck_out_tongue",
13
+ ":D": "grinning",
14
+ ":-D": "grinning",
15
+ "<3": "heart",
16
+ ":|": "neutral_face",
17
+ ":-|": "neutral_face",
18
+ ":/": "confused",
19
+ ":-/": "confused",
20
+ ":'(": "cry",
21
+ ":O": "open_mouth",
22
+ ":-O": "open_mouth",
23
+ ":o": "open_mouth",
24
+ ":-o": "open_mouth",
25
+ ">:(": "angry",
26
+ "B)": "sunglasses",
27
+ "B-)": "sunglasses"
28
+ };
29
+ function buildAsciiIndex(data) {
30
+ const index = /* @__PURE__ */ new Map();
31
+ for (const [ascii, emojiId] of Object.entries(data.aliases)) if (/^[^a-zA-Z0-9]/.test(ascii) && ascii.length <= 4) index.set(ascii, emojiId);
32
+ for (const [ascii, emojiId] of Object.entries(CURATED_ASCII)) if (!index.has(ascii) && data.emojis[emojiId]) index.set(ascii, emojiId);
33
+ return index;
34
+ }
35
+ function buildAsciiCandidates(asciiIndex) {
36
+ return Array.from(asciiIndex.keys()).sort((first, second) => second.length - first.length);
37
+ }
38
+ const BOUNDARY_BEFORE = /(?:^|[\s\n])$/;
39
+ const BOUNDARY_AFTER = /^(?:[\s\n]|$)/;
40
+ function matchAscii(input, position, asciiIndex, asciiCandidates = buildAsciiCandidates(asciiIndex)) {
41
+ const before = input.slice(0, position);
42
+ if (position > 0 && !BOUNDARY_BEFORE.test(before)) return;
43
+ for (const ascii of asciiCandidates) {
44
+ if (!input.startsWith(ascii, position)) continue;
45
+ const after = input.slice(position + ascii.length);
46
+ if (BOUNDARY_AFTER.test(after)) {
47
+ const emojiId = asciiIndex.get(ascii);
48
+ if (emojiId) return {
49
+ ascii,
50
+ emojiId
51
+ };
52
+ }
53
+ }
54
+ }
55
+ //#endregion
56
+ //#region src/core/indexes.ts
57
+ function unifiedToNative(unified) {
58
+ return unified.split("-").map((hex) => String.fromCodePoint(Number.parseInt(hex, 16))).join("");
59
+ }
60
+ function escapeRegex(value) {
61
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
62
+ }
63
+ function buildIndexes(data, customEmojis, extraAliases) {
64
+ const unicodeMap = /* @__PURE__ */ new Map();
65
+ const emojiMap = /* @__PURE__ */ new Map();
66
+ const shortcodeIndex = /* @__PURE__ */ new Map();
67
+ const unicodeChars = [];
68
+ for (const [emojiId, emoji] of Object.entries(data.emojis)) {
69
+ emojiMap.set(emojiId, emoji);
70
+ shortcodeIndex.set(emojiId, { emojiId });
71
+ if (emoji.aliases) for (const alias of emoji.aliases) shortcodeIndex.set(alias, { emojiId });
72
+ for (const skin of emoji.skins) {
73
+ const native = skin.native ?? unifiedToNative(skin.unified);
74
+ unicodeMap.set(native, emojiId);
75
+ unicodeChars.push(escapeRegex(native));
76
+ }
77
+ }
78
+ for (const [alias, emojiId] of Object.entries(data.aliases)) if (!shortcodeIndex.has(alias)) shortcodeIndex.set(alias, { emojiId });
79
+ if (customEmojis) for (const category of customEmojis) for (const emoji of category.emojis) {
80
+ const entry = {
81
+ id: emoji.id,
82
+ name: emoji.name,
83
+ keywords: emoji.keywords ?? [],
84
+ skins: emoji.skins.map((skin) => ({
85
+ unified: "",
86
+ native: "",
87
+ src: skin.src
88
+ }))
89
+ };
90
+ emojiMap.set(emoji.id, entry);
91
+ shortcodeIndex.set(emoji.id, {
92
+ emojiId: emoji.id,
93
+ isCustom: true
94
+ });
95
+ }
96
+ if (extraAliases) for (const [alias, emojiId] of Object.entries(extraAliases)) {
97
+ const cleanAlias = alias.replace(/^:|:$/g, "");
98
+ const resolvedEmojiId = emojiMap.has(emojiId) ? emojiId : shortcodeIndex.get(emojiId)?.emojiId ?? emojiId;
99
+ const isCustom = shortcodeIndex.get(resolvedEmojiId)?.isCustom;
100
+ shortcodeIndex.set(cleanAlias, {
101
+ emojiId: resolvedEmojiId,
102
+ isCustom
103
+ });
104
+ }
105
+ unicodeChars.sort((first, second) => second.length - first.length);
106
+ const unicodeRegex = unicodeChars.length > 0 ? new RegExp(unicodeChars.join("|"), "y") : /(?!)/y;
107
+ const asciiIndex = buildAsciiIndex(data);
108
+ return {
109
+ asciiCandidates: buildAsciiCandidates(asciiIndex),
110
+ unicodeRegex,
111
+ unicodeMap,
112
+ shortcodeIndex,
113
+ asciiIndex,
114
+ emojiMap
115
+ };
116
+ }
117
+ //#endregion
118
+ //#region src/core/skin.ts
119
+ const SKIN_TONE_MODIFIERS = {
120
+ "1f3fb": 2,
121
+ "1f3fc": 3,
122
+ "1f3fd": 4,
123
+ "1f3fe": 5,
124
+ "1f3ff": 6
125
+ };
126
+ function detectSkinToneFromUnified(unified) {
127
+ const normalizedUnified = unified.toLowerCase();
128
+ for (const [modifier, tone] of Object.entries(SKIN_TONE_MODIFIERS)) if (normalizedUnified.includes(modifier)) return tone;
129
+ }
130
+ function resolveSkin(emoji, explicitSkin, defaultSkin) {
131
+ const tone = explicitSkin ?? defaultSkin;
132
+ if (!tone || tone === 1 || emoji.skins.length <= 1) return {
133
+ native: emoji.skins[0]?.native ?? "",
134
+ skin: explicitSkin
135
+ };
136
+ const skinIndex = tone - 1;
137
+ return {
138
+ native: (emoji.skins[skinIndex] ?? emoji.skins[0])?.native ?? emoji.skins[0]?.native ?? "",
139
+ skin: tone
140
+ };
141
+ }
142
+ function skinToneShortcodeToTone(shortcode) {
143
+ const toneMatch = /^skin-tone-([1-6])$/.test(shortcode) ? shortcode.charAt(shortcode.length - 1) : void 0;
144
+ if (toneMatch) return Number.parseInt(toneMatch, 10);
145
+ }
146
+ //#endregion
147
+ //#region src/core/tokenize.ts
148
+ const SHORTCODE_RE = /^:([a-zA-Z0-9_+-]+):/;
149
+ const SKIN_TONE_SHORTCODE_RE = /^:skin-tone-([1-6]):/;
150
+ const indexCache = /* @__PURE__ */ new WeakMap();
151
+ function getIndexes(options) {
152
+ if (options.indexes) return options.indexes;
153
+ const cachedEntries = indexCache.get(options.data);
154
+ const cachedEntry = cachedEntries?.find((entry) => entry.customEmojis === options.customEmojis && entry.extraAliases === options.extraAliases);
155
+ if (cachedEntry) return cachedEntry.indexes;
156
+ const indexes = buildIndexes(options.data, options.customEmojis, options.extraAliases);
157
+ const nextEntry = {
158
+ customEmojis: options.customEmojis,
159
+ extraAliases: options.extraAliases,
160
+ indexes
161
+ };
162
+ if (cachedEntries) cachedEntries.push(nextEntry);
163
+ else indexCache.set(options.data, [nextEntry]);
164
+ return indexes;
165
+ }
166
+ function tryMatchUnicode(input, position, indexes) {
167
+ indexes.unicodeRegex.lastIndex = position;
168
+ const regexResult = indexes.unicodeRegex.exec(input);
169
+ if (regexResult) {
170
+ const native = regexResult[0];
171
+ const emojiId = indexes.unicodeMap.get(native);
172
+ if (emojiId) return {
173
+ native,
174
+ emojiId,
175
+ unified: (indexes.emojiMap.get(emojiId)?.skins.find((skinEntry) => skinEntry.native === native))?.unified
176
+ };
177
+ }
178
+ }
179
+ function tryMatchShortcode(input, position, indexes) {
180
+ const remaining = input.slice(position);
181
+ const regexResult = SHORTCODE_RE.exec(remaining);
182
+ if (regexResult?.[1]) {
183
+ const shortcode = regexResult[1];
184
+ const entry = indexes.shortcodeIndex.get(shortcode);
185
+ if (entry) return {
186
+ shortcode,
187
+ emojiId: entry.emojiId,
188
+ fullMatch: regexResult[0],
189
+ isCustom: entry.isCustom
190
+ };
191
+ }
192
+ }
193
+ function tryMatchUnknownShortcode(input, position) {
194
+ const remaining = input.slice(position);
195
+ const regexResult = SHORTCODE_RE.exec(remaining);
196
+ if (regexResult?.[1]) return {
197
+ shortcode: regexResult[1],
198
+ fullMatch: regexResult[0]
199
+ };
200
+ }
201
+ function tokenize(input, options) {
202
+ return tokenizeWithIndexes(input, options);
203
+ }
204
+ function tokenizeWithIndexes(input, options) {
205
+ const indexes = getIndexes(options);
206
+ const tokens = [];
207
+ const ascii = options.ascii ?? true;
208
+ let position = 0;
209
+ let textBuffer = "";
210
+ function flushText() {
211
+ if (textBuffer.length > 0) {
212
+ tokens.push({
213
+ type: "text",
214
+ value: textBuffer
215
+ });
216
+ textBuffer = "";
217
+ }
218
+ }
219
+ while (position < input.length) {
220
+ let matched = false;
221
+ const unicodeResult = tryMatchUnicode(input, position, indexes);
222
+ if (unicodeResult) {
223
+ flushText();
224
+ const detectedSkin = detectSkinToneFromUnified(unicodeResult.unified ?? "");
225
+ const emoji = indexes.emojiMap.get(unicodeResult.emojiId);
226
+ if (emoji) {
227
+ const resolved = resolveSkin(emoji, detectedSkin, options.defaultSkin);
228
+ tokens.push({
229
+ type: "emoji",
230
+ emoji,
231
+ native: resolved.native || unicodeResult.native,
232
+ skin: resolved.skin,
233
+ match: unicodeResult.native,
234
+ source: "unicode"
235
+ });
236
+ }
237
+ position += unicodeResult.native.length;
238
+ matched = true;
239
+ }
240
+ if (!matched) {
241
+ const shortcodeResult = tryMatchShortcode(input, position, indexes);
242
+ if (shortcodeResult) {
243
+ flushText();
244
+ let skinTone;
245
+ let totalLength = shortcodeResult.fullMatch.length;
246
+ const afterShortcode = input.slice(position + totalLength);
247
+ const skinRegexResult = SKIN_TONE_SHORTCODE_RE.exec(afterShortcode);
248
+ if (skinRegexResult?.[1]) {
249
+ skinTone = skinToneShortcodeToTone(`skin-tone-${skinRegexResult[1]}`);
250
+ totalLength += skinRegexResult[0].length;
251
+ }
252
+ const emoji = indexes.emojiMap.get(shortcodeResult.emojiId);
253
+ if (emoji) {
254
+ const isCustom = shortcodeResult.isCustom;
255
+ const resolved = resolveSkin(emoji, skinTone, options.defaultSkin);
256
+ tokens.push({
257
+ type: "emoji",
258
+ emoji,
259
+ native: resolved.native,
260
+ skin: resolved.skin,
261
+ shortcode: shortcodeResult.shortcode,
262
+ match: input.slice(position, position + totalLength),
263
+ source: isCustom ? "custom" : "shortcode"
264
+ });
265
+ }
266
+ position += totalLength;
267
+ matched = true;
268
+ }
269
+ }
270
+ if (!matched) {
271
+ const unknownResult = tryMatchUnknownShortcode(input, position);
272
+ if (unknownResult) {
273
+ flushText();
274
+ tokens.push({
275
+ type: "unknown",
276
+ shortcode: unknownResult.shortcode,
277
+ match: unknownResult.fullMatch
278
+ });
279
+ position += unknownResult.fullMatch.length;
280
+ matched = true;
281
+ }
282
+ }
283
+ if (!matched && ascii) {
284
+ const asciiResult = matchAscii(input, position, indexes.asciiIndex, indexes.asciiCandidates);
285
+ if (asciiResult) {
286
+ flushText();
287
+ const emoji = indexes.emojiMap.get(asciiResult.emojiId);
288
+ if (emoji) {
289
+ const resolved = resolveSkin(emoji, void 0, options.defaultSkin);
290
+ tokens.push({
291
+ type: "emoji",
292
+ emoji,
293
+ native: resolved.native,
294
+ match: asciiResult.ascii,
295
+ source: "ascii"
296
+ });
297
+ }
298
+ position += asciiResult.ascii.length;
299
+ matched = true;
300
+ }
301
+ }
302
+ if (!matched) {
303
+ textBuffer += input[position];
304
+ position += 1;
305
+ }
306
+ }
307
+ flushText();
308
+ return tokens;
309
+ }
310
+ //#endregion
311
+ Object.defineProperty(exports, "buildAsciiCandidates", {
312
+ enumerable: true,
313
+ get: function() {
314
+ return buildAsciiCandidates;
315
+ }
316
+ });
317
+ Object.defineProperty(exports, "buildAsciiIndex", {
318
+ enumerable: true,
319
+ get: function() {
320
+ return buildAsciiIndex;
321
+ }
322
+ });
323
+ Object.defineProperty(exports, "buildIndexes", {
324
+ enumerable: true,
325
+ get: function() {
326
+ return buildIndexes;
327
+ }
328
+ });
329
+ Object.defineProperty(exports, "detectSkinToneFromUnified", {
330
+ enumerable: true,
331
+ get: function() {
332
+ return detectSkinToneFromUnified;
333
+ }
334
+ });
335
+ Object.defineProperty(exports, "matchAscii", {
336
+ enumerable: true,
337
+ get: function() {
338
+ return matchAscii;
339
+ }
340
+ });
341
+ Object.defineProperty(exports, "resolveSkin", {
342
+ enumerable: true,
343
+ get: function() {
344
+ return resolveSkin;
345
+ }
346
+ });
347
+ Object.defineProperty(exports, "skinToneShortcodeToTone", {
348
+ enumerable: true,
349
+ get: function() {
350
+ return skinToneShortcodeToTone;
351
+ }
352
+ });
353
+ Object.defineProperty(exports, "tokenize", {
354
+ enumerable: true,
355
+ get: function() {
356
+ return tokenize;
357
+ }
358
+ });
359
+ Object.defineProperty(exports, "tokenizeWithIndexes", {
360
+ enumerable: true,
361
+ get: function() {
362
+ return tokenizeWithIndexes;
363
+ }
364
+ });
@@ -0,0 +1,92 @@
1
+ //#region src/core/types.d.ts
2
+ interface EmojiSkin {
3
+ unified: string;
4
+ native: string;
5
+ src?: string;
6
+ }
7
+ interface EmojiEntry {
8
+ id: string;
9
+ name: string;
10
+ keywords: string[];
11
+ skins: EmojiSkin[];
12
+ aliases?: string[];
13
+ }
14
+ interface CustomEmoji {
15
+ id: string;
16
+ name: string;
17
+ keywords?: string[];
18
+ skins: Array<{
19
+ src: string;
20
+ }>;
21
+ }
22
+ interface CustomEmojiCategory {
23
+ id: string;
24
+ name: string;
25
+ emojis: CustomEmoji[];
26
+ }
27
+ interface SpriteConfig {
28
+ src: string;
29
+ size: number;
30
+ columns: number;
31
+ sheet: Record<string, {
32
+ x: number;
33
+ y: number;
34
+ }>;
35
+ }
36
+ type EmojiSet = 'native' | 'apple' | 'google' | 'twitter' | 'facebook';
37
+ type SkinTone = 1 | 2 | 3 | 4 | 5 | 6;
38
+ type EmojiSource = 'unicode' | 'shortcode' | 'ascii' | 'custom';
39
+ interface EmojiImageContext {
40
+ set: EmojiSet;
41
+ skin: SkinTone;
42
+ unified: string;
43
+ }
44
+ type GetImageUrl = (emoji: EmojiEntry, context: EmojiImageContext) => string;
45
+ interface EmojiConfig {
46
+ data: EmojiData;
47
+ customEmojis?: CustomEmojiCategory[];
48
+ set?: EmojiSet;
49
+ defaultSkin?: SkinTone;
50
+ ascii?: boolean;
51
+ getImageUrl?: GetImageUrl;
52
+ imageUrlTemplate?: string;
53
+ sprite?: SpriteConfig;
54
+ extraAliases?: Record<string, string>;
55
+ }
56
+ interface EmojiData {
57
+ emojis: Record<string, EmojiEntry>;
58
+ aliases: Record<string, string>;
59
+ categories: Array<{
60
+ id: string;
61
+ emojis: string[];
62
+ }>;
63
+ }
64
+ type TextToken = {
65
+ type: 'text';
66
+ value: string;
67
+ };
68
+ type EmojiToken = {
69
+ type: 'emoji';
70
+ emoji: EmojiEntry;
71
+ native: string;
72
+ skin?: SkinTone;
73
+ shortcode?: string;
74
+ match: string;
75
+ source: EmojiSource;
76
+ };
77
+ type UnknownToken = {
78
+ type: 'unknown';
79
+ shortcode: string;
80
+ match: string;
81
+ };
82
+ type Token = TextToken | EmojiToken | UnknownToken;
83
+ interface TokenizeOptions {
84
+ data: EmojiData;
85
+ customEmojis?: CustomEmojiCategory[];
86
+ ascii?: boolean;
87
+ defaultSkin?: SkinTone;
88
+ extraAliases?: Record<string, string>;
89
+ }
90
+ //#endregion
91
+ export { UnknownToken as _, EmojiEntry as a, EmojiSkin as c, GetImageUrl as d, SkinTone as f, TokenizeOptions as g, Token as h, EmojiData as i, EmojiSource as l, TextToken as m, CustomEmojiCategory as n, EmojiImageContext as o, SpriteConfig as p, EmojiConfig as r, EmojiSet as s, CustomEmoji as t, EmojiToken as u };
92
+ //# sourceMappingURL=types-Dyzdpq-R.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-Dyzdpq-R.d.cts","names":[],"sources":["../src/core/types.ts"],"mappings":";UAAiB,SAAA;EACf,OAAA;EACA,MAAA;EACA,GAAA;AAAA;AAAA,UAGe,UAAA;EACf,EAAA;EACA,IAAA;EACA,QAAA;EACA,KAAA,EAAO,SAAA;EACP,OAAA;AAAA;AAAA,UAGe,WAAA;EACf,EAAA;EACA,IAAA;EACA,QAAA;EACA,KAAA,EAAO,KAAA;IAAQ,GAAA;EAAA;AAAA;AAAA,UAGA,mBAAA;EACf,EAAA;EACA,IAAA;EACA,MAAA,EAAQ,WAAA;AAAA;AAAA,UAGO,YAAA;EACf,GAAA;EACA,IAAA;EACA,OAAA;EACA,KAAA,EAAO,MAAA;IAAiB,CAAA;IAAW,CAAA;EAAA;AAAA;AAAA,KAGzB,QAAA;AAAA,KACA,QAAA;AAAA,KACA,WAAA;AAAA,UAEK,iBAAA;EACf,GAAA,EAAK,QAAA;EACL,IAAA,EAAM,QAAA;EACN,OAAA;AAAA;AAAA,KAGU,WAAA,IAAe,KAAA,EAAO,UAAA,EAAY,OAAA,EAAS,iBAAA;AAAA,UAEtC,WAAA;EACf,IAAA,EAAM,SAAA;EACN,YAAA,GAAe,mBAAA;EACf,GAAA,GAAM,QAAA;EACN,WAAA,GAAc,QAAA;EACd,KAAA;EACA,WAAA,GAAc,WAAA;EACd,gBAAA;EACA,MAAA,GAAS,YAAA;EACT,YAAA,GAAe,MAAA;AAAA;AAAA,UAGA,SAAA;EACf,MAAA,EAAQ,MAAA,SAAe,UAAA;EACvB,OAAA,EAAS,MAAA;EACT,UAAA,EAAY,KAAA;IAAQ,EAAA;IAAY,MAAA;EAAA;AAAA;AAAA,KAGtB,SAAA;EACV,IAAA;EACA,KAAA;AAAA;AAAA,KAGU,UAAA;EACV,IAAA;EACA,KAAA,EAAO,UAAA;EACP,MAAA;EACA,IAAA,GAAO,QAAA;EACP,SAAA;EACA,KAAA;EACA,MAAA,EAAQ,WAAA;AAAA;AAAA,KAGE,YAAA;EACV,IAAA;EACA,SAAA;EACA,KAAA;AAAA;AAAA,KAGU,KAAA,GAAQ,SAAA,GAAY,UAAA,GAAa,YAAA;AAAA,UAE5B,eAAA;EACf,IAAA,EAAM,SAAA;EACN,YAAA,GAAe,mBAAA;EACf,KAAA;EACA,WAAA,GAAc,QAAA;EACd,YAAA,GAAe,MAAA;AAAA"}
@@ -0,0 +1,92 @@
1
+ //#region src/core/types.d.ts
2
+ interface EmojiSkin {
3
+ unified: string;
4
+ native: string;
5
+ src?: string;
6
+ }
7
+ interface EmojiEntry {
8
+ id: string;
9
+ name: string;
10
+ keywords: string[];
11
+ skins: EmojiSkin[];
12
+ aliases?: string[];
13
+ }
14
+ interface CustomEmoji {
15
+ id: string;
16
+ name: string;
17
+ keywords?: string[];
18
+ skins: Array<{
19
+ src: string;
20
+ }>;
21
+ }
22
+ interface CustomEmojiCategory {
23
+ id: string;
24
+ name: string;
25
+ emojis: CustomEmoji[];
26
+ }
27
+ interface SpriteConfig {
28
+ src: string;
29
+ size: number;
30
+ columns: number;
31
+ sheet: Record<string, {
32
+ x: number;
33
+ y: number;
34
+ }>;
35
+ }
36
+ type EmojiSet = 'native' | 'apple' | 'google' | 'twitter' | 'facebook';
37
+ type SkinTone = 1 | 2 | 3 | 4 | 5 | 6;
38
+ type EmojiSource = 'unicode' | 'shortcode' | 'ascii' | 'custom';
39
+ interface EmojiImageContext {
40
+ set: EmojiSet;
41
+ skin: SkinTone;
42
+ unified: string;
43
+ }
44
+ type GetImageUrl = (emoji: EmojiEntry, context: EmojiImageContext) => string;
45
+ interface EmojiConfig {
46
+ data: EmojiData;
47
+ customEmojis?: CustomEmojiCategory[];
48
+ set?: EmojiSet;
49
+ defaultSkin?: SkinTone;
50
+ ascii?: boolean;
51
+ getImageUrl?: GetImageUrl;
52
+ imageUrlTemplate?: string;
53
+ sprite?: SpriteConfig;
54
+ extraAliases?: Record<string, string>;
55
+ }
56
+ interface EmojiData {
57
+ emojis: Record<string, EmojiEntry>;
58
+ aliases: Record<string, string>;
59
+ categories: Array<{
60
+ id: string;
61
+ emojis: string[];
62
+ }>;
63
+ }
64
+ type TextToken = {
65
+ type: 'text';
66
+ value: string;
67
+ };
68
+ type EmojiToken = {
69
+ type: 'emoji';
70
+ emoji: EmojiEntry;
71
+ native: string;
72
+ skin?: SkinTone;
73
+ shortcode?: string;
74
+ match: string;
75
+ source: EmojiSource;
76
+ };
77
+ type UnknownToken = {
78
+ type: 'unknown';
79
+ shortcode: string;
80
+ match: string;
81
+ };
82
+ type Token = TextToken | EmojiToken | UnknownToken;
83
+ interface TokenizeOptions {
84
+ data: EmojiData;
85
+ customEmojis?: CustomEmojiCategory[];
86
+ ascii?: boolean;
87
+ defaultSkin?: SkinTone;
88
+ extraAliases?: Record<string, string>;
89
+ }
90
+ //#endregion
91
+ export { UnknownToken as _, EmojiEntry as a, EmojiSkin as c, GetImageUrl as d, SkinTone as f, TokenizeOptions as g, Token as h, EmojiData as i, EmojiSource as l, TextToken as m, CustomEmojiCategory as n, EmojiImageContext as o, SpriteConfig as p, EmojiConfig as r, EmojiSet as s, CustomEmoji as t, EmojiToken as u };
92
+ //# sourceMappingURL=types-o0mRO30y.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-o0mRO30y.d.mts","names":[],"sources":["../src/core/types.ts"],"mappings":";UAAiB,SAAA;EACf,OAAA;EACA,MAAA;EACA,GAAA;AAAA;AAAA,UAGe,UAAA;EACf,EAAA;EACA,IAAA;EACA,QAAA;EACA,KAAA,EAAO,SAAA;EACP,OAAA;AAAA;AAAA,UAGe,WAAA;EACf,EAAA;EACA,IAAA;EACA,QAAA;EACA,KAAA,EAAO,KAAA;IAAQ,GAAA;EAAA;AAAA;AAAA,UAGA,mBAAA;EACf,EAAA;EACA,IAAA;EACA,MAAA,EAAQ,WAAA;AAAA;AAAA,UAGO,YAAA;EACf,GAAA;EACA,IAAA;EACA,OAAA;EACA,KAAA,EAAO,MAAA;IAAiB,CAAA;IAAW,CAAA;EAAA;AAAA;AAAA,KAGzB,QAAA;AAAA,KACA,QAAA;AAAA,KACA,WAAA;AAAA,UAEK,iBAAA;EACf,GAAA,EAAK,QAAA;EACL,IAAA,EAAM,QAAA;EACN,OAAA;AAAA;AAAA,KAGU,WAAA,IAAe,KAAA,EAAO,UAAA,EAAY,OAAA,EAAS,iBAAA;AAAA,UAEtC,WAAA;EACf,IAAA,EAAM,SAAA;EACN,YAAA,GAAe,mBAAA;EACf,GAAA,GAAM,QAAA;EACN,WAAA,GAAc,QAAA;EACd,KAAA;EACA,WAAA,GAAc,WAAA;EACd,gBAAA;EACA,MAAA,GAAS,YAAA;EACT,YAAA,GAAe,MAAA;AAAA;AAAA,UAGA,SAAA;EACf,MAAA,EAAQ,MAAA,SAAe,UAAA;EACvB,OAAA,EAAS,MAAA;EACT,UAAA,EAAY,KAAA;IAAQ,EAAA;IAAY,MAAA;EAAA;AAAA;AAAA,KAGtB,SAAA;EACV,IAAA;EACA,KAAA;AAAA;AAAA,KAGU,UAAA;EACV,IAAA;EACA,KAAA,EAAO,UAAA;EACP,MAAA;EACA,IAAA,GAAO,QAAA;EACP,SAAA;EACA,KAAA;EACA,MAAA,EAAQ,WAAA;AAAA;AAAA,KAGE,YAAA;EACV,IAAA;EACA,SAAA;EACA,KAAA;AAAA;AAAA,KAGU,KAAA,GAAQ,SAAA,GAAY,UAAA,GAAa,YAAA;AAAA,UAE5B,eAAA;EACf,IAAA,EAAM,SAAA;EACN,YAAA,GAAe,mBAAA;EACf,KAAA;EACA,WAAA,GAAc,QAAA;EACd,YAAA,GAAe,MAAA;AAAA"}
package/package.json ADDED
@@ -0,0 +1,108 @@
1
+ {
2
+ "name": "react-emoji-text",
3
+ "version": "1.0.0-alpha.0",
4
+ "description": "A modern React renderer that converts plain text into rendered emojis, with adapters for @emoji-mart/data and emojibase",
5
+ "keywords": [
6
+ "emoji",
7
+ "emoji-mart",
8
+ "emojibase",
9
+ "emoticon",
10
+ "react",
11
+ "renderer",
12
+ "shortcode",
13
+ "text",
14
+ "unicode"
15
+ ],
16
+ "license": "MIT",
17
+ "author": "drenther",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/drenther/react-emoji-text.git",
21
+ "directory": "packages/react-emoji-text"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "README.md",
26
+ "LICENSE"
27
+ ],
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "main": "./dist/index.cjs",
31
+ "module": "./dist/index.mjs",
32
+ "types": "./dist/index.d.mts",
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.mts",
36
+ "import": "./dist/index.mjs",
37
+ "require": "./dist/index.cjs"
38
+ },
39
+ "./core": {
40
+ "types": "./dist/core.d.mts",
41
+ "import": "./dist/core.mjs",
42
+ "require": "./dist/core.cjs"
43
+ },
44
+ "./react": {
45
+ "types": "./dist/react/index.d.mts",
46
+ "import": "./dist/react/index.mjs",
47
+ "require": "./dist/react/index.cjs"
48
+ },
49
+ "./compat": {
50
+ "types": "./dist/compat/index.d.mts",
51
+ "import": "./dist/compat/index.mjs",
52
+ "require": "./dist/compat/index.cjs"
53
+ },
54
+ "./adapters/emoji-mart": {
55
+ "types": "./dist/adapters/emoji-mart.d.mts",
56
+ "import": "./dist/adapters/emoji-mart.mjs",
57
+ "require": "./dist/adapters/emoji-mart.cjs"
58
+ },
59
+ "./adapters/emojibase": {
60
+ "types": "./dist/adapters/emojibase.d.mts",
61
+ "import": "./dist/adapters/emojibase.mjs",
62
+ "require": "./dist/adapters/emojibase.cjs"
63
+ },
64
+ "./package.json": {
65
+ "default": "./package.json"
66
+ }
67
+ },
68
+ "devDependencies": {
69
+ "@emoji-mart/data": "1.2.1",
70
+ "@testing-library/jest-dom": "6.9.1",
71
+ "@testing-library/react": "16.3.2",
72
+ "@types/react": "19.2.14",
73
+ "@types/react-dom": "19.2.3",
74
+ "@vitest/coverage-v8": "4.1.5",
75
+ "emojibase-data": "17.0.0",
76
+ "happy-dom": "20.9.0",
77
+ "react": "19.2.5",
78
+ "react-dom": "19.2.5",
79
+ "tsdown": "0.21.10",
80
+ "typescript": "6.0.3",
81
+ "vitest": "4.1.5"
82
+ },
83
+ "peerDependencies": {
84
+ "@emoji-mart/data": ">=1.2.0",
85
+ "emojibase-data": ">=16.0.0",
86
+ "react": ">=19.0.0",
87
+ "react-dom": ">=19.0.0"
88
+ },
89
+ "peerDependenciesMeta": {
90
+ "@emoji-mart/data": {
91
+ "optional": true
92
+ },
93
+ "emojibase-data": {
94
+ "optional": true
95
+ }
96
+ },
97
+ "engines": {
98
+ "node": ">=24.15.0"
99
+ },
100
+ "scripts": {
101
+ "build": "tsdown",
102
+ "dev": "tsdown --watch",
103
+ "test": "vitest run",
104
+ "test:watch": "vitest",
105
+ "test:coverage": "vitest run --coverage",
106
+ "typecheck": "tsc --noEmit"
107
+ }
108
+ }