@atlaskit/emoji 71.4.3 → 71.4.5
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/CHANGELOG.md +21 -0
- package/dist/cjs/components/common/Emoji.js +16 -7
- package/dist/cjs/components/common/ProductivityColorSelector.js +8 -1
- package/dist/cjs/util/analytics/analytics.js +1 -1
- package/dist/cjs/util/emojiIdToEmoji.js +61 -49
- package/dist/es2019/components/common/Emoji.js +15 -6
- package/dist/es2019/components/common/ProductivityColorSelector.js +6 -1
- package/dist/es2019/util/analytics/analytics.js +1 -1
- package/dist/es2019/util/emojiIdToEmoji.js +46 -40
- package/dist/esm/components/common/Emoji.js +16 -7
- package/dist/esm/components/common/ProductivityColorSelector.js +8 -1
- package/dist/esm/util/analytics/analytics.js +1 -1
- package/dist/esm/util/emojiIdToEmoji.js +61 -49
- package/dist/types/util/emojiIdToEmoji.d.ts +2 -2
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @atlaskit/emoji
|
|
2
2
|
|
|
3
|
+
## 71.4.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`3d5270635bf55`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3d5270635bf55) -
|
|
8
|
+
Select color should not close picker on some pages
|
|
9
|
+
- [`4cb7dec82c494`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4cb7dec82c494) -
|
|
10
|
+
Place emoji tooltip above the emoji renderer by setting position to top
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
|
|
13
|
+
## 71.4.4
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [`e3db0f49354a5`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e3db0f49354a5) -
|
|
18
|
+
Use Twemoji for flag emoji and apply Unicode 14 emoji presentation selectors for native emoji
|
|
19
|
+
rendering.
|
|
20
|
+
- [`ff291d024e356`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/ff291d024e356) -
|
|
21
|
+
EDITOR-7032 Show emoji shortName (with fallback to name) in tooltip on hover renderer
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
|
|
3
24
|
## 71.4.3
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
|
@@ -501,29 +501,38 @@ var EmojiNodeWrapper = exports.EmojiNodeWrapper = /*#__PURE__*/(0, _react.forwar
|
|
|
501
501
|
var ariaLabel = intl && (0, _platformFeatureFlags.fg)('platform_change_emoji_button_label') ? intl.formatMessage(_i18n.messages.changeEmojiShortnameButtonLabel, {
|
|
502
502
|
shortName: (_emoji$name = emoji.name) !== null && _emoji$name !== void 0 ? _emoji$name : emoji.shortName
|
|
503
503
|
}) : editorEmoji ? undefined : emoji.shortName;
|
|
504
|
-
|
|
504
|
+
var tooltipContent = showTooltip && (0, _expValEquals.expValEquals)('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? emoji.shortName || emoji.name || undefined : undefined;
|
|
505
|
+
var emojiSpan = /*#__PURE__*/_react.default.createElement("span", (0, _extends2.default)({
|
|
505
506
|
role: editorEmoji ? undefined : shouldBeInteractive ? 'button' : ariaLabel ? 'img' : 'presentation',
|
|
506
507
|
"aria-label": ariaLabel,
|
|
507
508
|
ref: ref,
|
|
508
509
|
"data-testid": "".concat(type, "-emoji-").concat(emoji.shortName),
|
|
509
510
|
"data-emoji-type": type,
|
|
510
|
-
tabIndex: shouldBeInteractive ? tabIndex || 0 : undefined,
|
|
511
|
+
tabIndex: shouldBeInteractive ? tabIndex || 0 : tooltipContent ? 0 : undefined,
|
|
511
512
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
512
513
|
className: (0, _runtime.ax)([type === 'sprite' ? "_19pk1n1a _2hwxidpf _otyr1n1a _18u0idpf _1e0c1o8l _jr50g2xd _ylp71o8l _pkaxgktf _1hdcgktf _109tnkob _tn8j1dpa _3naf1dpa _nt751r31 _49pcglyw _1hvw1o36 _7ehi1y54 _491113zc" : type === 'unicode' ? "_19pk1n1a _2hwxidpf _otyr1n1a _18u0idpf _bfhk1j28 _1e0c1o8l _s7n4nkob _tn8j1dpa _3naf1dpa _160jewfl _1theewfl _1kogh2mm _qyp0ewfl _nt751r31 _49pcglyw _1hvw1o36 _7ehi1y54 _491113zc" : "_2rkofajl _19pk1n1a _2hwxidpf _otyr1n1a _18u0idpf _bfhk1j28 _1e0c1o8l _s7n4nkob _v4pn1ule _tn8j1dpa _3naf1dpa _160jewfl _1theewfl _1kogh2mm _qyp0ewfl _nt751r31 _49pcglyw _1hvw1o36 _7ehi1y54 _491113zc", className]),
|
|
513
|
-
onKeyDown: function
|
|
514
|
+
onKeyDown: shouldBeInteractive || !(0, _expValEquals.expValEquals)('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? function (event) {
|
|
514
515
|
return handleKeyDown(props, event);
|
|
515
|
-
},
|
|
516
|
-
onMouseDown: function
|
|
516
|
+
} : undefined,
|
|
517
|
+
onMouseDown: shouldBeInteractive || !(0, _expValEquals.expValEquals)('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? function (event) {
|
|
517
518
|
handleMouseDown(props, event);
|
|
518
|
-
},
|
|
519
|
+
} : undefined,
|
|
519
520
|
onMouseEnter: function onMouseEnter(event) {
|
|
520
521
|
handleMouseMove(props, event);
|
|
521
522
|
},
|
|
522
523
|
onFocus: function onFocus(event) {
|
|
523
524
|
handleFocus(props, event);
|
|
524
525
|
},
|
|
525
|
-
title: showTooltip ? emoji.shortName : undefined
|
|
526
|
+
title: showTooltip && !(0, _expValEquals.expValEquals)('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? emoji.shortName : undefined
|
|
526
527
|
}, other), children);
|
|
528
|
+
if (tooltipContent) {
|
|
529
|
+
return /*#__PURE__*/_react.default.createElement(_tooltip.default, {
|
|
530
|
+
content: tooltipContent,
|
|
531
|
+
position: "top",
|
|
532
|
+
tag: "span"
|
|
533
|
+
}, emojiSpan);
|
|
534
|
+
}
|
|
535
|
+
return emojiSpan;
|
|
527
536
|
});
|
|
528
537
|
var Emoji = exports.Emoji = function Emoji(props) {
|
|
529
538
|
var emoji = props.emoji;
|
|
@@ -50,6 +50,13 @@ var ProductivityColorSelector = exports.ProductivityColorSelector = function Pro
|
|
|
50
50
|
var stopPickerDismissal = function stopPickerDismissal(event) {
|
|
51
51
|
event.stopPropagation();
|
|
52
52
|
};
|
|
53
|
+
var selectColorOnMouseDown = function selectColorOnMouseDown(color) {
|
|
54
|
+
return function (event) {
|
|
55
|
+
stopPickerDismissal(event);
|
|
56
|
+
event.preventDefault();
|
|
57
|
+
onColorSelected(color);
|
|
58
|
+
};
|
|
59
|
+
};
|
|
53
60
|
return /*#__PURE__*/React.createElement("fieldset", {
|
|
54
61
|
id: productivityColorSelectorId,
|
|
55
62
|
"data-testid": productivityColorSelectorTestId,
|
|
@@ -94,7 +101,7 @@ var ProductivityColorSelector = exports.ProductivityColorSelector = function Pro
|
|
|
94
101
|
},
|
|
95
102
|
onClick: stopPickerDismissal,
|
|
96
103
|
onKeyDown: handleKeyDown,
|
|
97
|
-
onMouseDown:
|
|
104
|
+
onMouseDown: selectColorOnMouseDown(color),
|
|
98
105
|
testId: "productivity-color-".concat(color),
|
|
99
106
|
value: color,
|
|
100
107
|
label: /*#__PURE__*/React.createElement("span", {
|
|
@@ -20,7 +20,7 @@ var createEvent = function createEvent(eventType, action, actionSubject, actionS
|
|
|
20
20
|
actionSubjectId: actionSubjectId,
|
|
21
21
|
attributes: _objectSpread({
|
|
22
22
|
packageName: "@atlaskit/emoji",
|
|
23
|
-
packageVersion: "71.4.
|
|
23
|
+
packageVersion: "71.4.4"
|
|
24
24
|
}, attributes)
|
|
25
25
|
};
|
|
26
26
|
};
|
|
@@ -11,36 +11,25 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
11
11
|
var KEYCAP_COMBINING = 0x20e3;
|
|
12
12
|
var VARIATION_SELECTOR_16 = 0xfe0f;
|
|
13
13
|
var VARIATION_SELECTOR_15 = 0xfe0e;
|
|
14
|
+
var EMOJI_MODIFIER_START = 0x1f3fb;
|
|
15
|
+
var EMOJI_MODIFIER_END = 0x1f3ff;
|
|
16
|
+
var REGIONAL_INDICATOR_START = 0x1f1e6;
|
|
17
|
+
var REGIONAL_INDICATOR_END = 0x1f1ff;
|
|
18
|
+
var FLAG_BASES = new Set([0x1f38c, 0x1f3c1, 0x1f3f3, 0x1f3f4, 0x1f6a9]);
|
|
14
19
|
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
var
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* e.g. `"1f44d"`, `"1f44d-1f3fb"`, `"1f468-200d-1f469-200d-1f467"`) into its
|
|
29
|
-
* corresponding Unicode string.
|
|
30
|
-
*
|
|
31
|
-
* Special handling:
|
|
32
|
-
* - Keycap sequences: U+20E3 (COMBINING ENCLOSING KEYCAP) must be preceded by
|
|
33
|
-
* U+FE0F (VARIATION SELECTOR-16) to form a well-defined keycap emoji.
|
|
34
|
-
* - Text-default emoji (characters whose default presentation is text) must be
|
|
35
|
-
* followed by U+FE0F to force emoji presentation.
|
|
36
|
-
*
|
|
37
|
-
* @returns The Unicode string for the emoji, or `undefined` if the input is
|
|
38
|
-
* invalid (empty string, non-hex segments, or out-of-range code points).
|
|
39
|
-
*/
|
|
40
|
-
function emojiIdToEmoji(id) {
|
|
41
|
-
if (!id) {
|
|
42
|
-
return undefined;
|
|
43
|
-
}
|
|
20
|
+
// Emoji variation bases from Unicode 14.0 emoji-variation-sequences.txt.
|
|
21
|
+
// These are the code points with a defined U+FE0F emoji-style variant.
|
|
22
|
+
var EMOJI_VARIATION_BASES = new Set([0x0023, 0x002a, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00a9, 0x00ae, 0x203c, 0x2049, 0x2122, 0x2139, 0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x21a9, 0x21aa, 0x2328, 0x23cf, 0x23ed, 0x23ee, 0x23ef, 0x23f1, 0x23f2, 0x23f8, 0x23f9, 0x23fa, 0x24c2, 0x25aa, 0x25ab, 0x25b6, 0x25c0, 0x25fb, 0x25fc, 0x2600, 0x2601, 0x2602, 0x2603, 0x2604, 0x260e, 0x2611, 0x2618, 0x261d, 0x2620, 0x2622, 0x2623, 0x2626, 0x262a, 0x262e, 0x262f, 0x2638, 0x2639, 0x263a, 0x2640, 0x2642, 0x265f, 0x2660, 0x2663, 0x2665, 0x2666, 0x2668, 0x267b, 0x267e, 0x2692, 0x2694, 0x2695, 0x2696, 0x2697, 0x2699, 0x269b, 0x269c, 0x26a0, 0x26a7, 0x26b0, 0x26b1, 0x26c8, 0x26cf, 0x26d1, 0x26d3, 0x26e9, 0x26f0, 0x26f1, 0x26f4, 0x26f7, 0x26f8, 0x26f9, 0x2702, 0x2708, 0x2709, 0x270c, 0x270d, 0x270f, 0x2712, 0x2714, 0x2716, 0x271d, 0x2721, 0x2733, 0x2734, 0x2744, 0x2747, 0x2763, 0x2764, 0x27a1, 0x2934, 0x2935, 0x2b05, 0x2b06, 0x2b07, 0x3030, 0x303d, 0x3297, 0x3299, 0x1f170, 0x1f171, 0x1f17e, 0x1f17f, 0x1f202, 0x1f237, 0x1f321, 0x1f324, 0x1f325, 0x1f326, 0x1f327, 0x1f328, 0x1f329, 0x1f32a, 0x1f32b, 0x1f32c, 0x1f336, 0x1f37d, 0x1f396, 0x1f397, 0x1f399, 0x1f39a, 0x1f39b, 0x1f39e, 0x1f39f, 0x1f3cb, 0x1f3cc, 0x1f3cd, 0x1f3ce, 0x1f3d4, 0x1f3d5, 0x1f3d6, 0x1f3d7, 0x1f3d8, 0x1f3d9, 0x1f3da, 0x1f3db, 0x1f3dc, 0x1f3dd, 0x1f3de, 0x1f3df, 0x1f3f3, 0x1f3f5, 0x1f3f7, 0x1f43f, 0x1f441, 0x1f4fd, 0x1f549, 0x1f54a, 0x1f56f, 0x1f570, 0x1f573, 0x1f574, 0x1f575, 0x1f576, 0x1f577, 0x1f578, 0x1f579, 0x1f587, 0x1f58a, 0x1f58b, 0x1f58c, 0x1f58d, 0x1f590, 0x1f5a5, 0x1f5a8, 0x1f5b1, 0x1f5b2, 0x1f5bc, 0x1f5c2, 0x1f5c3, 0x1f5c4, 0x1f5d1, 0x1f5d2, 0x1f5d3, 0x1f5dc, 0x1f5dd, 0x1f5de, 0x1f5e1, 0x1f5e3, 0x1f5e8, 0x1f5ef, 0x1f5f3, 0x1f5fa, 0x1f6cb, 0x1f6cd, 0x1f6ce, 0x1f6cf, 0x1f6e0, 0x1f6e1, 0x1f6e2, 0x1f6e3, 0x1f6e4, 0x1f6e5, 0x1f6e9, 0x1f6f0, 0x1f6f3, 0x231a, 0x231b, 0x23e9, 0x23ea, 0x23f3, 0x25fd, 0x25fe, 0x2614, 0x2615, 0x2648, 0x2649, 0x264a, 0x264b, 0x264c, 0x264d, 0x264e, 0x264f, 0x2650, 0x2651, 0x2652, 0x2653, 0x267f, 0x2693, 0x26a1, 0x26aa, 0x26ab, 0x26bd, 0x26be, 0x26c4, 0x26c5, 0x26d4, 0x26ea, 0x26f2, 0x26f3, 0x26f5, 0x26fa, 0x26fd, 0x2753, 0x2757, 0x2b1b, 0x2b1c, 0x2b50, 0x2b55, 0x1f004, 0x1f21a, 0x1f22f, 0x1f30d, 0x1f30e, 0x1f30f, 0x1f315, 0x1f31c, 0x1f378, 0x1f393, 0x1f3a7, 0x1f3ac, 0x1f3ad, 0x1f3ae, 0x1f3c2, 0x1f3c4, 0x1f3c6, 0x1f3ca, 0x1f3e0, 0x1f3ed, 0x1f408, 0x1f415, 0x1f41f, 0x1f426, 0x1f442, 0x1f446, 0x1f447, 0x1f448, 0x1f449, 0x1f44d, 0x1f44e, 0x1f453, 0x1f46a, 0x1f47d, 0x1f4a3, 0x1f4b0, 0x1f4b3, 0x1f4bb, 0x1f4bf, 0x1f4cb, 0x1f4da, 0x1f4df, 0x1f4e4, 0x1f4e5, 0x1f4e6, 0x1f4ea, 0x1f4eb, 0x1f4ec, 0x1f4ed, 0x1f4f7, 0x1f4f9, 0x1f4fa, 0x1f4fb, 0x1f508, 0x1f50d, 0x1f512, 0x1f513, 0x1f550, 0x1f551, 0x1f552, 0x1f553, 0x1f554, 0x1f555, 0x1f556, 0x1f557, 0x1f558, 0x1f559, 0x1f55a, 0x1f55b, 0x1f55c, 0x1f55d, 0x1f55e, 0x1f55f, 0x1f560, 0x1f561, 0x1f562, 0x1f563, 0x1f564, 0x1f565, 0x1f566, 0x1f567, 0x1f610, 0x1f687, 0x1f68d, 0x1f691, 0x1f694, 0x1f698, 0x1f6ad, 0x1f6b2, 0x1f6b9, 0x1f6ba, 0x1f6bc]);
|
|
23
|
+
var isEmojiModifier = function isEmojiModifier(codePoint) {
|
|
24
|
+
return typeof codePoint === 'number' && codePoint >= EMOJI_MODIFIER_START && codePoint <= EMOJI_MODIFIER_END;
|
|
25
|
+
};
|
|
26
|
+
var shouldAddEmojiPresentationSelector = function shouldAddEmojiPresentationSelector(codePoint, nextCodePoint) {
|
|
27
|
+
return EMOJI_VARIATION_BASES.has(codePoint) && nextCodePoint !== VARIATION_SELECTOR_16 && nextCodePoint !== VARIATION_SELECTOR_15 && nextCodePoint !== KEYCAP_COMBINING && !isEmojiModifier(nextCodePoint);
|
|
28
|
+
};
|
|
29
|
+
var isRegionalIndicator = function isRegionalIndicator(codePoint) {
|
|
30
|
+
return codePoint >= REGIONAL_INDICATOR_START && codePoint <= REGIONAL_INDICATOR_END;
|
|
31
|
+
};
|
|
32
|
+
var parseEmojiIdCodePoints = function parseEmojiIdCodePoints(id) {
|
|
44
33
|
var segments = id.split('-');
|
|
45
34
|
var codePoints = [];
|
|
46
35
|
var _iterator = _createForOfIteratorHelper(segments),
|
|
@@ -51,19 +40,53 @@ function emojiIdToEmoji(id) {
|
|
|
51
40
|
if (!/^[0-9a-fA-F]+$/.test(segment)) {
|
|
52
41
|
return undefined;
|
|
53
42
|
}
|
|
54
|
-
var
|
|
55
|
-
// Valid Unicode scalar values:
|
|
56
|
-
if (isNaN(
|
|
43
|
+
var cp = parseInt(segment, 16);
|
|
44
|
+
// Valid Unicode scalar values: U+0000–U+10FFFF, excluding surrogates.
|
|
45
|
+
if (isNaN(cp) || cp < 0 || cp > 0x10ffff || cp >= 0xd800 && cp <= 0xdfff) {
|
|
57
46
|
return undefined;
|
|
58
47
|
}
|
|
59
|
-
codePoints.push(
|
|
48
|
+
codePoints.push(cp);
|
|
60
49
|
}
|
|
61
50
|
} catch (err) {
|
|
62
51
|
_iterator.e(err);
|
|
63
52
|
} finally {
|
|
64
53
|
_iterator.f();
|
|
65
54
|
}
|
|
66
|
-
|
|
55
|
+
return codePoints.length ? codePoints : undefined;
|
|
56
|
+
};
|
|
57
|
+
var isFlagEmoji = function isFlagEmoji(codePoints) {
|
|
58
|
+
if (codePoints.length === 2 && codePoints.every(isRegionalIndicator)) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
return FLAG_BASES.has(codePoints[0]);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Converts an emoji ID (a hyphen-separated string of hex Unicode code points,
|
|
66
|
+
* e.g. `"1f44d"`, `"1f44d-1f3fb"`, `"1f468-200d-1f469-200d-1f467"`) into its
|
|
67
|
+
* corresponding Unicode string.
|
|
68
|
+
*
|
|
69
|
+
* Special handling:
|
|
70
|
+
* - Keycap sequences: U+20E3 (COMBINING ENCLOSING KEYCAP) must be preceded by
|
|
71
|
+
* U+FE0F (VARIATION SELECTOR-16) to form a well-defined keycap emoji.
|
|
72
|
+
* - Emoji variation bases are followed by U+FE0F to force emoji presentation.
|
|
73
|
+
* - Flags return `undefined` so callers use Twemoji instead of native emoji.
|
|
74
|
+
*
|
|
75
|
+
* @returns The Unicode string for the emoji, or `undefined` if the input is
|
|
76
|
+
* invalid (empty string, non-hex segments, or out-of-range code points).
|
|
77
|
+
*/
|
|
78
|
+
function emojiIdToEmoji(id) {
|
|
79
|
+
if (!(0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_use_unicode_emojis', 'isEnabled', true)) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
if (!id) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
var codePoints = parseEmojiIdCodePoints(id);
|
|
86
|
+
if (!codePoints) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
if (isFlagEmoji(codePoints)) {
|
|
67
90
|
return undefined;
|
|
68
91
|
}
|
|
69
92
|
var processedCodePoints = [];
|
|
@@ -77,22 +100,11 @@ function emojiIdToEmoji(id) {
|
|
|
77
100
|
if (next === KEYCAP_COMBINING && cp !== VARIATION_SELECTOR_16) {
|
|
78
101
|
processedCodePoints.push(VARIATION_SELECTOR_16);
|
|
79
102
|
}
|
|
80
|
-
}
|
|
81
103
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
var lastCodePoint = processedCodePoints[processedCodePoints.length - 1];
|
|
87
|
-
var alreadyHasVariationSelector = lastCodePoint === VARIATION_SELECTOR_16 || lastCodePoint === VARIATION_SELECTOR_15 ||
|
|
88
|
-
// Keycap sequences end with U+20E3 — they already have U+FE0F inserted inline
|
|
89
|
-
// and must not have another variation selector appended at the end.
|
|
90
|
-
lastCodePoint === KEYCAP_COMBINING;
|
|
91
|
-
if (!alreadyHasVariationSelector) {
|
|
92
|
-
var baseCodePoint = codePoints[0];
|
|
93
|
-
if (codePoints.length === 1 && baseCodePoint <= 0xffff && TEXT_DEFAULT_EMOJI.has(baseCodePoint)) {
|
|
94
|
-
processedCodePoints.push(VARIATION_SELECTOR_16);
|
|
95
|
-
}
|
|
104
|
+
// Emoji variation bases need U+FE0F immediately after the base code point,
|
|
105
|
+
// including when the base appears inside a ZWJ sequence.
|
|
106
|
+
if (shouldAddEmojiPresentationSelector(cp, next)) {
|
|
107
|
+
processedCodePoints.push(VARIATION_SELECTOR_16);
|
|
96
108
|
}
|
|
97
109
|
}
|
|
98
110
|
try {
|
|
@@ -469,27 +469,36 @@ export const EmojiNodeWrapper = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
469
469
|
const ariaLabel = intl && fg('platform_change_emoji_button_label') ? intl.formatMessage(messages.changeEmojiShortnameButtonLabel, {
|
|
470
470
|
shortName: (_emoji$name = emoji.name) !== null && _emoji$name !== void 0 ? _emoji$name : emoji.shortName
|
|
471
471
|
}) : editorEmoji ? undefined : emoji.shortName;
|
|
472
|
-
|
|
472
|
+
const tooltipContent = showTooltip && expValEquals('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? emoji.shortName || emoji.name || undefined : undefined;
|
|
473
|
+
const emojiSpan = /*#__PURE__*/React.createElement("span", _extends({
|
|
473
474
|
role: editorEmoji ? undefined : shouldBeInteractive ? 'button' : ariaLabel ? 'img' : 'presentation',
|
|
474
475
|
"aria-label": ariaLabel,
|
|
475
476
|
ref: ref,
|
|
476
477
|
"data-testid": `${type}-emoji-${emoji.shortName}`,
|
|
477
478
|
"data-emoji-type": type,
|
|
478
|
-
tabIndex: shouldBeInteractive ? tabIndex || 0 : undefined,
|
|
479
|
+
tabIndex: shouldBeInteractive ? tabIndex || 0 : tooltipContent ? 0 : undefined,
|
|
479
480
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
480
481
|
className: ax([type === 'sprite' ? "_19pk1n1a _2hwxidpf _otyr1n1a _18u0idpf _1e0c1o8l _jr50g2xd _ylp71o8l _pkaxgktf _1hdcgktf _109tnkob _tn8j1dpa _3naf1dpa _nt751r31 _49pcglyw _1hvw1o36 _7ehi1y54 _491113zc" : type === 'unicode' ? "_19pk1n1a _2hwxidpf _otyr1n1a _18u0idpf _bfhk1j28 _1e0c1o8l _s7n4nkob _tn8j1dpa _3naf1dpa _160jewfl _1theewfl _1kogh2mm _qyp0ewfl _nt751r31 _49pcglyw _1hvw1o36 _7ehi1y54 _491113zc" : "_2rkofajl _19pk1n1a _2hwxidpf _otyr1n1a _18u0idpf _bfhk1j28 _1e0c1o8l _s7n4nkob _v4pn1ule _tn8j1dpa _3naf1dpa _160jewfl _1theewfl _1kogh2mm _qyp0ewfl _nt751r31 _49pcglyw _1hvw1o36 _7ehi1y54 _491113zc", className]),
|
|
481
|
-
onKeyDown: event => handleKeyDown(props, event),
|
|
482
|
-
onMouseDown: event => {
|
|
482
|
+
onKeyDown: shouldBeInteractive || !expValEquals('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? event => handleKeyDown(props, event) : undefined,
|
|
483
|
+
onMouseDown: shouldBeInteractive || !expValEquals('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? event => {
|
|
483
484
|
handleMouseDown(props, event);
|
|
484
|
-
},
|
|
485
|
+
} : undefined,
|
|
485
486
|
onMouseEnter: event => {
|
|
486
487
|
handleMouseMove(props, event);
|
|
487
488
|
},
|
|
488
489
|
onFocus: event => {
|
|
489
490
|
handleFocus(props, event);
|
|
490
491
|
},
|
|
491
|
-
title: showTooltip ? emoji.shortName : undefined
|
|
492
|
+
title: showTooltip && !expValEquals('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? emoji.shortName : undefined
|
|
492
493
|
}, other), children);
|
|
494
|
+
if (tooltipContent) {
|
|
495
|
+
return /*#__PURE__*/React.createElement(Tooltip, {
|
|
496
|
+
content: tooltipContent,
|
|
497
|
+
position: "top",
|
|
498
|
+
tag: "span"
|
|
499
|
+
}, emojiSpan);
|
|
500
|
+
}
|
|
501
|
+
return emojiSpan;
|
|
493
502
|
});
|
|
494
503
|
export const Emoji = props => {
|
|
495
504
|
const {
|
|
@@ -37,6 +37,11 @@ export const ProductivityColorSelector = ({
|
|
|
37
37
|
const stopPickerDismissal = event => {
|
|
38
38
|
event.stopPropagation();
|
|
39
39
|
};
|
|
40
|
+
const selectColorOnMouseDown = color => event => {
|
|
41
|
+
stopPickerDismissal(event);
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
onColorSelected(color);
|
|
44
|
+
};
|
|
40
45
|
return /*#__PURE__*/React.createElement("fieldset", {
|
|
41
46
|
id: productivityColorSelectorId,
|
|
42
47
|
"data-testid": productivityColorSelectorTestId,
|
|
@@ -79,7 +84,7 @@ export const ProductivityColorSelector = ({
|
|
|
79
84
|
onChange: () => onColorSelected(color),
|
|
80
85
|
onClick: stopPickerDismissal,
|
|
81
86
|
onKeyDown: handleKeyDown,
|
|
82
|
-
onMouseDown:
|
|
87
|
+
onMouseDown: selectColorOnMouseDown(color),
|
|
83
88
|
testId: `productivity-color-${color}`,
|
|
84
89
|
value: color,
|
|
85
90
|
label: /*#__PURE__*/React.createElement("span", {
|
|
@@ -2,17 +2,40 @@ import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equ
|
|
|
2
2
|
const KEYCAP_COMBINING = 0x20e3;
|
|
3
3
|
const VARIATION_SELECTOR_16 = 0xfe0f;
|
|
4
4
|
const VARIATION_SELECTOR_15 = 0xfe0e;
|
|
5
|
+
const EMOJI_MODIFIER_START = 0x1f3fb;
|
|
6
|
+
const EMOJI_MODIFIER_END = 0x1f3ff;
|
|
7
|
+
const REGIONAL_INDICATOR_START = 0x1f1e6;
|
|
8
|
+
const REGIONAL_INDICATOR_END = 0x1f1ff;
|
|
9
|
+
const FLAG_BASES = new Set([0x1f38c, 0x1f3c1, 0x1f3f3, 0x1f3f4, 0x1f6a9]);
|
|
5
10
|
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
// Emoji variation bases from Unicode 14.0 emoji-variation-sequences.txt.
|
|
12
|
+
// These are the code points with a defined U+FE0F emoji-style variant.
|
|
13
|
+
const EMOJI_VARIATION_BASES = new Set([0x0023, 0x002a, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00a9, 0x00ae, 0x203c, 0x2049, 0x2122, 0x2139, 0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x21a9, 0x21aa, 0x2328, 0x23cf, 0x23ed, 0x23ee, 0x23ef, 0x23f1, 0x23f2, 0x23f8, 0x23f9, 0x23fa, 0x24c2, 0x25aa, 0x25ab, 0x25b6, 0x25c0, 0x25fb, 0x25fc, 0x2600, 0x2601, 0x2602, 0x2603, 0x2604, 0x260e, 0x2611, 0x2618, 0x261d, 0x2620, 0x2622, 0x2623, 0x2626, 0x262a, 0x262e, 0x262f, 0x2638, 0x2639, 0x263a, 0x2640, 0x2642, 0x265f, 0x2660, 0x2663, 0x2665, 0x2666, 0x2668, 0x267b, 0x267e, 0x2692, 0x2694, 0x2695, 0x2696, 0x2697, 0x2699, 0x269b, 0x269c, 0x26a0, 0x26a7, 0x26b0, 0x26b1, 0x26c8, 0x26cf, 0x26d1, 0x26d3, 0x26e9, 0x26f0, 0x26f1, 0x26f4, 0x26f7, 0x26f8, 0x26f9, 0x2702, 0x2708, 0x2709, 0x270c, 0x270d, 0x270f, 0x2712, 0x2714, 0x2716, 0x271d, 0x2721, 0x2733, 0x2734, 0x2744, 0x2747, 0x2763, 0x2764, 0x27a1, 0x2934, 0x2935, 0x2b05, 0x2b06, 0x2b07, 0x3030, 0x303d, 0x3297, 0x3299, 0x1f170, 0x1f171, 0x1f17e, 0x1f17f, 0x1f202, 0x1f237, 0x1f321, 0x1f324, 0x1f325, 0x1f326, 0x1f327, 0x1f328, 0x1f329, 0x1f32a, 0x1f32b, 0x1f32c, 0x1f336, 0x1f37d, 0x1f396, 0x1f397, 0x1f399, 0x1f39a, 0x1f39b, 0x1f39e, 0x1f39f, 0x1f3cb, 0x1f3cc, 0x1f3cd, 0x1f3ce, 0x1f3d4, 0x1f3d5, 0x1f3d6, 0x1f3d7, 0x1f3d8, 0x1f3d9, 0x1f3da, 0x1f3db, 0x1f3dc, 0x1f3dd, 0x1f3de, 0x1f3df, 0x1f3f3, 0x1f3f5, 0x1f3f7, 0x1f43f, 0x1f441, 0x1f4fd, 0x1f549, 0x1f54a, 0x1f56f, 0x1f570, 0x1f573, 0x1f574, 0x1f575, 0x1f576, 0x1f577, 0x1f578, 0x1f579, 0x1f587, 0x1f58a, 0x1f58b, 0x1f58c, 0x1f58d, 0x1f590, 0x1f5a5, 0x1f5a8, 0x1f5b1, 0x1f5b2, 0x1f5bc, 0x1f5c2, 0x1f5c3, 0x1f5c4, 0x1f5d1, 0x1f5d2, 0x1f5d3, 0x1f5dc, 0x1f5dd, 0x1f5de, 0x1f5e1, 0x1f5e3, 0x1f5e8, 0x1f5ef, 0x1f5f3, 0x1f5fa, 0x1f6cb, 0x1f6cd, 0x1f6ce, 0x1f6cf, 0x1f6e0, 0x1f6e1, 0x1f6e2, 0x1f6e3, 0x1f6e4, 0x1f6e5, 0x1f6e9, 0x1f6f0, 0x1f6f3, 0x231a, 0x231b, 0x23e9, 0x23ea, 0x23f3, 0x25fd, 0x25fe, 0x2614, 0x2615, 0x2648, 0x2649, 0x264a, 0x264b, 0x264c, 0x264d, 0x264e, 0x264f, 0x2650, 0x2651, 0x2652, 0x2653, 0x267f, 0x2693, 0x26a1, 0x26aa, 0x26ab, 0x26bd, 0x26be, 0x26c4, 0x26c5, 0x26d4, 0x26ea, 0x26f2, 0x26f3, 0x26f5, 0x26fa, 0x26fd, 0x2753, 0x2757, 0x2b1b, 0x2b1c, 0x2b50, 0x2b55, 0x1f004, 0x1f21a, 0x1f22f, 0x1f30d, 0x1f30e, 0x1f30f, 0x1f315, 0x1f31c, 0x1f378, 0x1f393, 0x1f3a7, 0x1f3ac, 0x1f3ad, 0x1f3ae, 0x1f3c2, 0x1f3c4, 0x1f3c6, 0x1f3ca, 0x1f3e0, 0x1f3ed, 0x1f408, 0x1f415, 0x1f41f, 0x1f426, 0x1f442, 0x1f446, 0x1f447, 0x1f448, 0x1f449, 0x1f44d, 0x1f44e, 0x1f453, 0x1f46a, 0x1f47d, 0x1f4a3, 0x1f4b0, 0x1f4b3, 0x1f4bb, 0x1f4bf, 0x1f4cb, 0x1f4da, 0x1f4df, 0x1f4e4, 0x1f4e5, 0x1f4e6, 0x1f4ea, 0x1f4eb, 0x1f4ec, 0x1f4ed, 0x1f4f7, 0x1f4f9, 0x1f4fa, 0x1f4fb, 0x1f508, 0x1f50d, 0x1f512, 0x1f513, 0x1f550, 0x1f551, 0x1f552, 0x1f553, 0x1f554, 0x1f555, 0x1f556, 0x1f557, 0x1f558, 0x1f559, 0x1f55a, 0x1f55b, 0x1f55c, 0x1f55d, 0x1f55e, 0x1f55f, 0x1f560, 0x1f561, 0x1f562, 0x1f563, 0x1f564, 0x1f565, 0x1f566, 0x1f567, 0x1f610, 0x1f687, 0x1f68d, 0x1f691, 0x1f694, 0x1f698, 0x1f6ad, 0x1f6b2, 0x1f6b9, 0x1f6ba, 0x1f6bc]);
|
|
14
|
+
const isEmojiModifier = codePoint => typeof codePoint === 'number' && codePoint >= EMOJI_MODIFIER_START && codePoint <= EMOJI_MODIFIER_END;
|
|
15
|
+
const shouldAddEmojiPresentationSelector = (codePoint, nextCodePoint) => EMOJI_VARIATION_BASES.has(codePoint) && nextCodePoint !== VARIATION_SELECTOR_16 && nextCodePoint !== VARIATION_SELECTOR_15 && nextCodePoint !== KEYCAP_COMBINING && !isEmojiModifier(nextCodePoint);
|
|
16
|
+
const isRegionalIndicator = codePoint => codePoint >= REGIONAL_INDICATOR_START && codePoint <= REGIONAL_INDICATOR_END;
|
|
17
|
+
const parseEmojiIdCodePoints = id => {
|
|
18
|
+
const segments = id.split('-');
|
|
19
|
+
const codePoints = [];
|
|
20
|
+
for (const segment of segments) {
|
|
21
|
+
if (!/^[0-9a-fA-F]+$/.test(segment)) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
const cp = parseInt(segment, 16);
|
|
25
|
+
// Valid Unicode scalar values: U+0000–U+10FFFF, excluding surrogates.
|
|
26
|
+
if (isNaN(cp) || cp < 0 || cp > 0x10ffff || cp >= 0xd800 && cp <= 0xdfff) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
codePoints.push(cp);
|
|
30
|
+
}
|
|
31
|
+
return codePoints.length ? codePoints : undefined;
|
|
32
|
+
};
|
|
33
|
+
const isFlagEmoji = codePoints => {
|
|
34
|
+
if (codePoints.length === 2 && codePoints.every(isRegionalIndicator)) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return FLAG_BASES.has(codePoints[0]);
|
|
38
|
+
};
|
|
16
39
|
|
|
17
40
|
/**
|
|
18
41
|
* Converts an emoji ID (a hyphen-separated string of hex Unicode code points,
|
|
@@ -22,30 +45,24 @@ const TEXT_DEFAULT_EMOJI = new Set([0x0023, 0x002a, 0x0030, 0x0031, 0x0032, 0x00
|
|
|
22
45
|
* Special handling:
|
|
23
46
|
* - Keycap sequences: U+20E3 (COMBINING ENCLOSING KEYCAP) must be preceded by
|
|
24
47
|
* U+FE0F (VARIATION SELECTOR-16) to form a well-defined keycap emoji.
|
|
25
|
-
* -
|
|
26
|
-
*
|
|
48
|
+
* - Emoji variation bases are followed by U+FE0F to force emoji presentation.
|
|
49
|
+
* - Flags return `undefined` so callers use Twemoji instead of native emoji.
|
|
27
50
|
*
|
|
28
51
|
* @returns The Unicode string for the emoji, or `undefined` if the input is
|
|
29
52
|
* invalid (empty string, non-hex segments, or out-of-range code points).
|
|
30
53
|
*/
|
|
31
54
|
export function emojiIdToEmoji(id) {
|
|
55
|
+
if (!expValEqualsNoExposure('platform_use_unicode_emojis', 'isEnabled', true)) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
32
58
|
if (!id) {
|
|
33
59
|
return undefined;
|
|
34
60
|
}
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (!/^[0-9a-fA-F]+$/.test(segment)) {
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
const cp = parseInt(segment, 16);
|
|
42
|
-
// Valid Unicode scalar values: 0x0000–0x10FFFF, excluding surrogates 0xD800–0xDFFF
|
|
43
|
-
if (isNaN(cp) || cp < 0 || cp > 0x10ffff || cp >= 0xd800 && cp <= 0xdfff) {
|
|
44
|
-
return undefined;
|
|
45
|
-
}
|
|
46
|
-
codePoints.push(cp);
|
|
61
|
+
const codePoints = parseEmojiIdCodePoints(id);
|
|
62
|
+
if (!codePoints) {
|
|
63
|
+
return undefined;
|
|
47
64
|
}
|
|
48
|
-
if (codePoints
|
|
65
|
+
if (isFlagEmoji(codePoints)) {
|
|
49
66
|
return undefined;
|
|
50
67
|
}
|
|
51
68
|
const processedCodePoints = [];
|
|
@@ -59,22 +76,11 @@ export function emojiIdToEmoji(id) {
|
|
|
59
76
|
if (next === KEYCAP_COMBINING && cp !== VARIATION_SELECTOR_16) {
|
|
60
77
|
processedCodePoints.push(VARIATION_SELECTOR_16);
|
|
61
78
|
}
|
|
62
|
-
}
|
|
63
79
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const lastCodePoint = processedCodePoints[processedCodePoints.length - 1];
|
|
69
|
-
const alreadyHasVariationSelector = lastCodePoint === VARIATION_SELECTOR_16 || lastCodePoint === VARIATION_SELECTOR_15 ||
|
|
70
|
-
// Keycap sequences end with U+20E3 — they already have U+FE0F inserted inline
|
|
71
|
-
// and must not have another variation selector appended at the end.
|
|
72
|
-
lastCodePoint === KEYCAP_COMBINING;
|
|
73
|
-
if (!alreadyHasVariationSelector) {
|
|
74
|
-
const baseCodePoint = codePoints[0];
|
|
75
|
-
if (codePoints.length === 1 && baseCodePoint <= 0xffff && TEXT_DEFAULT_EMOJI.has(baseCodePoint)) {
|
|
76
|
-
processedCodePoints.push(VARIATION_SELECTOR_16);
|
|
77
|
-
}
|
|
80
|
+
// Emoji variation bases need U+FE0F immediately after the base code point,
|
|
81
|
+
// including when the base appears inside a ZWJ sequence.
|
|
82
|
+
if (shouldAddEmojiPresentationSelector(cp, next)) {
|
|
83
|
+
processedCodePoints.push(VARIATION_SELECTOR_16);
|
|
78
84
|
}
|
|
79
85
|
}
|
|
80
86
|
try {
|
|
@@ -492,29 +492,38 @@ export var EmojiNodeWrapper = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
492
492
|
var ariaLabel = intl && fg('platform_change_emoji_button_label') ? intl.formatMessage(messages.changeEmojiShortnameButtonLabel, {
|
|
493
493
|
shortName: (_emoji$name = emoji.name) !== null && _emoji$name !== void 0 ? _emoji$name : emoji.shortName
|
|
494
494
|
}) : editorEmoji ? undefined : emoji.shortName;
|
|
495
|
-
|
|
495
|
+
var tooltipContent = showTooltip && expValEquals('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? emoji.shortName || emoji.name || undefined : undefined;
|
|
496
|
+
var emojiSpan = /*#__PURE__*/React.createElement("span", _extends({
|
|
496
497
|
role: editorEmoji ? undefined : shouldBeInteractive ? 'button' : ariaLabel ? 'img' : 'presentation',
|
|
497
498
|
"aria-label": ariaLabel,
|
|
498
499
|
ref: ref,
|
|
499
500
|
"data-testid": "".concat(type, "-emoji-").concat(emoji.shortName),
|
|
500
501
|
"data-emoji-type": type,
|
|
501
|
-
tabIndex: shouldBeInteractive ? tabIndex || 0 : undefined,
|
|
502
|
+
tabIndex: shouldBeInteractive ? tabIndex || 0 : tooltipContent ? 0 : undefined,
|
|
502
503
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
503
504
|
className: ax([type === 'sprite' ? "_19pk1n1a _2hwxidpf _otyr1n1a _18u0idpf _1e0c1o8l _jr50g2xd _ylp71o8l _pkaxgktf _1hdcgktf _109tnkob _tn8j1dpa _3naf1dpa _nt751r31 _49pcglyw _1hvw1o36 _7ehi1y54 _491113zc" : type === 'unicode' ? "_19pk1n1a _2hwxidpf _otyr1n1a _18u0idpf _bfhk1j28 _1e0c1o8l _s7n4nkob _tn8j1dpa _3naf1dpa _160jewfl _1theewfl _1kogh2mm _qyp0ewfl _nt751r31 _49pcglyw _1hvw1o36 _7ehi1y54 _491113zc" : "_2rkofajl _19pk1n1a _2hwxidpf _otyr1n1a _18u0idpf _bfhk1j28 _1e0c1o8l _s7n4nkob _v4pn1ule _tn8j1dpa _3naf1dpa _160jewfl _1theewfl _1kogh2mm _qyp0ewfl _nt751r31 _49pcglyw _1hvw1o36 _7ehi1y54 _491113zc", className]),
|
|
504
|
-
onKeyDown: function
|
|
505
|
+
onKeyDown: shouldBeInteractive || !expValEquals('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? function (event) {
|
|
505
506
|
return handleKeyDown(props, event);
|
|
506
|
-
},
|
|
507
|
-
onMouseDown: function
|
|
507
|
+
} : undefined,
|
|
508
|
+
onMouseDown: shouldBeInteractive || !expValEquals('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? function (event) {
|
|
508
509
|
handleMouseDown(props, event);
|
|
509
|
-
},
|
|
510
|
+
} : undefined,
|
|
510
511
|
onMouseEnter: function onMouseEnter(event) {
|
|
511
512
|
handleMouseMove(props, event);
|
|
512
513
|
},
|
|
513
514
|
onFocus: function onFocus(event) {
|
|
514
515
|
handleFocus(props, event);
|
|
515
516
|
},
|
|
516
|
-
title: showTooltip ? emoji.shortName : undefined
|
|
517
|
+
title: showTooltip && !expValEquals('platform_editor_emoji_hover_show_tooltip', 'isEnabled', true) ? emoji.shortName : undefined
|
|
517
518
|
}, other), children);
|
|
519
|
+
if (tooltipContent) {
|
|
520
|
+
return /*#__PURE__*/React.createElement(Tooltip, {
|
|
521
|
+
content: tooltipContent,
|
|
522
|
+
position: "top",
|
|
523
|
+
tag: "span"
|
|
524
|
+
}, emojiSpan);
|
|
525
|
+
}
|
|
526
|
+
return emojiSpan;
|
|
518
527
|
});
|
|
519
528
|
export var Emoji = function Emoji(props) {
|
|
520
529
|
var emoji = props.emoji;
|
|
@@ -41,6 +41,13 @@ export var ProductivityColorSelector = function ProductivityColorSelector(_ref)
|
|
|
41
41
|
var stopPickerDismissal = function stopPickerDismissal(event) {
|
|
42
42
|
event.stopPropagation();
|
|
43
43
|
};
|
|
44
|
+
var selectColorOnMouseDown = function selectColorOnMouseDown(color) {
|
|
45
|
+
return function (event) {
|
|
46
|
+
stopPickerDismissal(event);
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
onColorSelected(color);
|
|
49
|
+
};
|
|
50
|
+
};
|
|
44
51
|
return /*#__PURE__*/React.createElement("fieldset", {
|
|
45
52
|
id: productivityColorSelectorId,
|
|
46
53
|
"data-testid": productivityColorSelectorTestId,
|
|
@@ -85,7 +92,7 @@ export var ProductivityColorSelector = function ProductivityColorSelector(_ref)
|
|
|
85
92
|
},
|
|
86
93
|
onClick: stopPickerDismissal,
|
|
87
94
|
onKeyDown: handleKeyDown,
|
|
88
|
-
onMouseDown:
|
|
95
|
+
onMouseDown: selectColorOnMouseDown(color),
|
|
89
96
|
testId: "productivity-color-".concat(color),
|
|
90
97
|
value: color,
|
|
91
98
|
label: /*#__PURE__*/React.createElement("span", {
|
|
@@ -14,7 +14,7 @@ var createEvent = function createEvent(eventType, action, actionSubject, actionS
|
|
|
14
14
|
actionSubjectId: actionSubjectId,
|
|
15
15
|
attributes: _objectSpread({
|
|
16
16
|
packageName: "@atlaskit/emoji",
|
|
17
|
-
packageVersion: "71.4.
|
|
17
|
+
packageVersion: "71.4.4"
|
|
18
18
|
}, attributes)
|
|
19
19
|
};
|
|
20
20
|
};
|
|
@@ -5,36 +5,25 @@ import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equ
|
|
|
5
5
|
var KEYCAP_COMBINING = 0x20e3;
|
|
6
6
|
var VARIATION_SELECTOR_16 = 0xfe0f;
|
|
7
7
|
var VARIATION_SELECTOR_15 = 0xfe0e;
|
|
8
|
+
var EMOJI_MODIFIER_START = 0x1f3fb;
|
|
9
|
+
var EMOJI_MODIFIER_END = 0x1f3ff;
|
|
10
|
+
var REGIONAL_INDICATOR_START = 0x1f1e6;
|
|
11
|
+
var REGIONAL_INDICATOR_END = 0x1f1ff;
|
|
12
|
+
var FLAG_BASES = new Set([0x1f38c, 0x1f3c1, 0x1f3f3, 0x1f3f4, 0x1f6a9]);
|
|
8
13
|
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* e.g. `"1f44d"`, `"1f44d-1f3fb"`, `"1f468-200d-1f469-200d-1f467"`) into its
|
|
23
|
-
* corresponding Unicode string.
|
|
24
|
-
*
|
|
25
|
-
* Special handling:
|
|
26
|
-
* - Keycap sequences: U+20E3 (COMBINING ENCLOSING KEYCAP) must be preceded by
|
|
27
|
-
* U+FE0F (VARIATION SELECTOR-16) to form a well-defined keycap emoji.
|
|
28
|
-
* - Text-default emoji (characters whose default presentation is text) must be
|
|
29
|
-
* followed by U+FE0F to force emoji presentation.
|
|
30
|
-
*
|
|
31
|
-
* @returns The Unicode string for the emoji, or `undefined` if the input is
|
|
32
|
-
* invalid (empty string, non-hex segments, or out-of-range code points).
|
|
33
|
-
*/
|
|
34
|
-
export function emojiIdToEmoji(id) {
|
|
35
|
-
if (!id) {
|
|
36
|
-
return undefined;
|
|
37
|
-
}
|
|
14
|
+
// Emoji variation bases from Unicode 14.0 emoji-variation-sequences.txt.
|
|
15
|
+
// These are the code points with a defined U+FE0F emoji-style variant.
|
|
16
|
+
var EMOJI_VARIATION_BASES = new Set([0x0023, 0x002a, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00a9, 0x00ae, 0x203c, 0x2049, 0x2122, 0x2139, 0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x21a9, 0x21aa, 0x2328, 0x23cf, 0x23ed, 0x23ee, 0x23ef, 0x23f1, 0x23f2, 0x23f8, 0x23f9, 0x23fa, 0x24c2, 0x25aa, 0x25ab, 0x25b6, 0x25c0, 0x25fb, 0x25fc, 0x2600, 0x2601, 0x2602, 0x2603, 0x2604, 0x260e, 0x2611, 0x2618, 0x261d, 0x2620, 0x2622, 0x2623, 0x2626, 0x262a, 0x262e, 0x262f, 0x2638, 0x2639, 0x263a, 0x2640, 0x2642, 0x265f, 0x2660, 0x2663, 0x2665, 0x2666, 0x2668, 0x267b, 0x267e, 0x2692, 0x2694, 0x2695, 0x2696, 0x2697, 0x2699, 0x269b, 0x269c, 0x26a0, 0x26a7, 0x26b0, 0x26b1, 0x26c8, 0x26cf, 0x26d1, 0x26d3, 0x26e9, 0x26f0, 0x26f1, 0x26f4, 0x26f7, 0x26f8, 0x26f9, 0x2702, 0x2708, 0x2709, 0x270c, 0x270d, 0x270f, 0x2712, 0x2714, 0x2716, 0x271d, 0x2721, 0x2733, 0x2734, 0x2744, 0x2747, 0x2763, 0x2764, 0x27a1, 0x2934, 0x2935, 0x2b05, 0x2b06, 0x2b07, 0x3030, 0x303d, 0x3297, 0x3299, 0x1f170, 0x1f171, 0x1f17e, 0x1f17f, 0x1f202, 0x1f237, 0x1f321, 0x1f324, 0x1f325, 0x1f326, 0x1f327, 0x1f328, 0x1f329, 0x1f32a, 0x1f32b, 0x1f32c, 0x1f336, 0x1f37d, 0x1f396, 0x1f397, 0x1f399, 0x1f39a, 0x1f39b, 0x1f39e, 0x1f39f, 0x1f3cb, 0x1f3cc, 0x1f3cd, 0x1f3ce, 0x1f3d4, 0x1f3d5, 0x1f3d6, 0x1f3d7, 0x1f3d8, 0x1f3d9, 0x1f3da, 0x1f3db, 0x1f3dc, 0x1f3dd, 0x1f3de, 0x1f3df, 0x1f3f3, 0x1f3f5, 0x1f3f7, 0x1f43f, 0x1f441, 0x1f4fd, 0x1f549, 0x1f54a, 0x1f56f, 0x1f570, 0x1f573, 0x1f574, 0x1f575, 0x1f576, 0x1f577, 0x1f578, 0x1f579, 0x1f587, 0x1f58a, 0x1f58b, 0x1f58c, 0x1f58d, 0x1f590, 0x1f5a5, 0x1f5a8, 0x1f5b1, 0x1f5b2, 0x1f5bc, 0x1f5c2, 0x1f5c3, 0x1f5c4, 0x1f5d1, 0x1f5d2, 0x1f5d3, 0x1f5dc, 0x1f5dd, 0x1f5de, 0x1f5e1, 0x1f5e3, 0x1f5e8, 0x1f5ef, 0x1f5f3, 0x1f5fa, 0x1f6cb, 0x1f6cd, 0x1f6ce, 0x1f6cf, 0x1f6e0, 0x1f6e1, 0x1f6e2, 0x1f6e3, 0x1f6e4, 0x1f6e5, 0x1f6e9, 0x1f6f0, 0x1f6f3, 0x231a, 0x231b, 0x23e9, 0x23ea, 0x23f3, 0x25fd, 0x25fe, 0x2614, 0x2615, 0x2648, 0x2649, 0x264a, 0x264b, 0x264c, 0x264d, 0x264e, 0x264f, 0x2650, 0x2651, 0x2652, 0x2653, 0x267f, 0x2693, 0x26a1, 0x26aa, 0x26ab, 0x26bd, 0x26be, 0x26c4, 0x26c5, 0x26d4, 0x26ea, 0x26f2, 0x26f3, 0x26f5, 0x26fa, 0x26fd, 0x2753, 0x2757, 0x2b1b, 0x2b1c, 0x2b50, 0x2b55, 0x1f004, 0x1f21a, 0x1f22f, 0x1f30d, 0x1f30e, 0x1f30f, 0x1f315, 0x1f31c, 0x1f378, 0x1f393, 0x1f3a7, 0x1f3ac, 0x1f3ad, 0x1f3ae, 0x1f3c2, 0x1f3c4, 0x1f3c6, 0x1f3ca, 0x1f3e0, 0x1f3ed, 0x1f408, 0x1f415, 0x1f41f, 0x1f426, 0x1f442, 0x1f446, 0x1f447, 0x1f448, 0x1f449, 0x1f44d, 0x1f44e, 0x1f453, 0x1f46a, 0x1f47d, 0x1f4a3, 0x1f4b0, 0x1f4b3, 0x1f4bb, 0x1f4bf, 0x1f4cb, 0x1f4da, 0x1f4df, 0x1f4e4, 0x1f4e5, 0x1f4e6, 0x1f4ea, 0x1f4eb, 0x1f4ec, 0x1f4ed, 0x1f4f7, 0x1f4f9, 0x1f4fa, 0x1f4fb, 0x1f508, 0x1f50d, 0x1f512, 0x1f513, 0x1f550, 0x1f551, 0x1f552, 0x1f553, 0x1f554, 0x1f555, 0x1f556, 0x1f557, 0x1f558, 0x1f559, 0x1f55a, 0x1f55b, 0x1f55c, 0x1f55d, 0x1f55e, 0x1f55f, 0x1f560, 0x1f561, 0x1f562, 0x1f563, 0x1f564, 0x1f565, 0x1f566, 0x1f567, 0x1f610, 0x1f687, 0x1f68d, 0x1f691, 0x1f694, 0x1f698, 0x1f6ad, 0x1f6b2, 0x1f6b9, 0x1f6ba, 0x1f6bc]);
|
|
17
|
+
var isEmojiModifier = function isEmojiModifier(codePoint) {
|
|
18
|
+
return typeof codePoint === 'number' && codePoint >= EMOJI_MODIFIER_START && codePoint <= EMOJI_MODIFIER_END;
|
|
19
|
+
};
|
|
20
|
+
var shouldAddEmojiPresentationSelector = function shouldAddEmojiPresentationSelector(codePoint, nextCodePoint) {
|
|
21
|
+
return EMOJI_VARIATION_BASES.has(codePoint) && nextCodePoint !== VARIATION_SELECTOR_16 && nextCodePoint !== VARIATION_SELECTOR_15 && nextCodePoint !== KEYCAP_COMBINING && !isEmojiModifier(nextCodePoint);
|
|
22
|
+
};
|
|
23
|
+
var isRegionalIndicator = function isRegionalIndicator(codePoint) {
|
|
24
|
+
return codePoint >= REGIONAL_INDICATOR_START && codePoint <= REGIONAL_INDICATOR_END;
|
|
25
|
+
};
|
|
26
|
+
var parseEmojiIdCodePoints = function parseEmojiIdCodePoints(id) {
|
|
38
27
|
var segments = id.split('-');
|
|
39
28
|
var codePoints = [];
|
|
40
29
|
var _iterator = _createForOfIteratorHelper(segments),
|
|
@@ -45,19 +34,53 @@ export function emojiIdToEmoji(id) {
|
|
|
45
34
|
if (!/^[0-9a-fA-F]+$/.test(segment)) {
|
|
46
35
|
return undefined;
|
|
47
36
|
}
|
|
48
|
-
var
|
|
49
|
-
// Valid Unicode scalar values:
|
|
50
|
-
if (isNaN(
|
|
37
|
+
var cp = parseInt(segment, 16);
|
|
38
|
+
// Valid Unicode scalar values: U+0000–U+10FFFF, excluding surrogates.
|
|
39
|
+
if (isNaN(cp) || cp < 0 || cp > 0x10ffff || cp >= 0xd800 && cp <= 0xdfff) {
|
|
51
40
|
return undefined;
|
|
52
41
|
}
|
|
53
|
-
codePoints.push(
|
|
42
|
+
codePoints.push(cp);
|
|
54
43
|
}
|
|
55
44
|
} catch (err) {
|
|
56
45
|
_iterator.e(err);
|
|
57
46
|
} finally {
|
|
58
47
|
_iterator.f();
|
|
59
48
|
}
|
|
60
|
-
|
|
49
|
+
return codePoints.length ? codePoints : undefined;
|
|
50
|
+
};
|
|
51
|
+
var isFlagEmoji = function isFlagEmoji(codePoints) {
|
|
52
|
+
if (codePoints.length === 2 && codePoints.every(isRegionalIndicator)) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
return FLAG_BASES.has(codePoints[0]);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Converts an emoji ID (a hyphen-separated string of hex Unicode code points,
|
|
60
|
+
* e.g. `"1f44d"`, `"1f44d-1f3fb"`, `"1f468-200d-1f469-200d-1f467"`) into its
|
|
61
|
+
* corresponding Unicode string.
|
|
62
|
+
*
|
|
63
|
+
* Special handling:
|
|
64
|
+
* - Keycap sequences: U+20E3 (COMBINING ENCLOSING KEYCAP) must be preceded by
|
|
65
|
+
* U+FE0F (VARIATION SELECTOR-16) to form a well-defined keycap emoji.
|
|
66
|
+
* - Emoji variation bases are followed by U+FE0F to force emoji presentation.
|
|
67
|
+
* - Flags return `undefined` so callers use Twemoji instead of native emoji.
|
|
68
|
+
*
|
|
69
|
+
* @returns The Unicode string for the emoji, or `undefined` if the input is
|
|
70
|
+
* invalid (empty string, non-hex segments, or out-of-range code points).
|
|
71
|
+
*/
|
|
72
|
+
export function emojiIdToEmoji(id) {
|
|
73
|
+
if (!expValEqualsNoExposure('platform_use_unicode_emojis', 'isEnabled', true)) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
if (!id) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
var codePoints = parseEmojiIdCodePoints(id);
|
|
80
|
+
if (!codePoints) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
if (isFlagEmoji(codePoints)) {
|
|
61
84
|
return undefined;
|
|
62
85
|
}
|
|
63
86
|
var processedCodePoints = [];
|
|
@@ -71,22 +94,11 @@ export function emojiIdToEmoji(id) {
|
|
|
71
94
|
if (next === KEYCAP_COMBINING && cp !== VARIATION_SELECTOR_16) {
|
|
72
95
|
processedCodePoints.push(VARIATION_SELECTOR_16);
|
|
73
96
|
}
|
|
74
|
-
}
|
|
75
97
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
var lastCodePoint = processedCodePoints[processedCodePoints.length - 1];
|
|
81
|
-
var alreadyHasVariationSelector = lastCodePoint === VARIATION_SELECTOR_16 || lastCodePoint === VARIATION_SELECTOR_15 ||
|
|
82
|
-
// Keycap sequences end with U+20E3 — they already have U+FE0F inserted inline
|
|
83
|
-
// and must not have another variation selector appended at the end.
|
|
84
|
-
lastCodePoint === KEYCAP_COMBINING;
|
|
85
|
-
if (!alreadyHasVariationSelector) {
|
|
86
|
-
var baseCodePoint = codePoints[0];
|
|
87
|
-
if (codePoints.length === 1 && baseCodePoint <= 0xffff && TEXT_DEFAULT_EMOJI.has(baseCodePoint)) {
|
|
88
|
-
processedCodePoints.push(VARIATION_SELECTOR_16);
|
|
89
|
-
}
|
|
98
|
+
// Emoji variation bases need U+FE0F immediately after the base code point,
|
|
99
|
+
// including when the base appears inside a ZWJ sequence.
|
|
100
|
+
if (shouldAddEmojiPresentationSelector(cp, next)) {
|
|
101
|
+
processedCodePoints.push(VARIATION_SELECTOR_16);
|
|
90
102
|
}
|
|
91
103
|
}
|
|
92
104
|
try {
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* Special handling:
|
|
7
7
|
* - Keycap sequences: U+20E3 (COMBINING ENCLOSING KEYCAP) must be preceded by
|
|
8
8
|
* U+FE0F (VARIATION SELECTOR-16) to form a well-defined keycap emoji.
|
|
9
|
-
* -
|
|
10
|
-
*
|
|
9
|
+
* - Emoji variation bases are followed by U+FE0F to force emoji presentation.
|
|
10
|
+
* - Flags return `undefined` so callers use Twemoji instead of native emoji.
|
|
11
11
|
*
|
|
12
12
|
* @returns The Unicode string for the emoji, or `undefined` if the input is
|
|
13
13
|
* invalid (empty string, non-hex segments, or out-of-range code points).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/emoji",
|
|
3
|
-
"version": "71.4.
|
|
3
|
+
"version": "71.4.5",
|
|
4
4
|
"description": "Fabric emoji React components",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@atlaskit/form": "^16.0.0",
|
|
39
39
|
"@atlaskit/heading": "^6.0.0",
|
|
40
40
|
"@atlaskit/icon": "^36.0.0",
|
|
41
|
-
"@atlaskit/icon-lab": "^7.
|
|
41
|
+
"@atlaskit/icon-lab": "^7.1.0",
|
|
42
42
|
"@atlaskit/image": "^4.0.0",
|
|
43
43
|
"@atlaskit/media-client": "^37.1.0",
|
|
44
44
|
"@atlaskit/media-client-react": "^6.0.0",
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"@atlaskit/spinner": "^20.0.0",
|
|
50
50
|
"@atlaskit/textfield": "^9.0.0",
|
|
51
51
|
"@atlaskit/theme": "^26.0.0",
|
|
52
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
53
|
-
"@atlaskit/tokens": "^
|
|
52
|
+
"@atlaskit/tmp-editor-statsig": "^110.1.0",
|
|
53
|
+
"@atlaskit/tokens": "^15.0.0",
|
|
54
54
|
"@atlaskit/tooltip": "^23.0.0",
|
|
55
55
|
"@atlaskit/ufo": "^1.0.0",
|
|
56
56
|
"@atlaskit/util-service-support": "^7.0.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"js-search": "^2.0.0",
|
|
62
62
|
"lru_map": "^0.4.1",
|
|
63
63
|
"react-focus-lock": "^2.9.5",
|
|
64
|
-
"react-intersection-observer": "^
|
|
64
|
+
"react-intersection-observer": "^9.16.0",
|
|
65
65
|
"react-loadable": "^5.1.0",
|
|
66
66
|
"use-debounce": "^3.4.0",
|
|
67
67
|
"uuid": "^3.1.0"
|