@atlaskit/emoji 67.1.0 → 67.2.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 (131) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cjs/api/EmojiResource.js +29 -24
  3. package/dist/cjs/api/media/TokenManager.js +4 -4
  4. package/dist/cjs/components/common/CachingEmoji.js +14 -6
  5. package/dist/cjs/components/common/Emoji.js +48 -12
  6. package/dist/cjs/components/common/EmojiActions.js +60 -24
  7. package/dist/cjs/components/common/EmojiErrorMessage.js +12 -7
  8. package/dist/cjs/components/common/EmojiPlaceholder.js +1 -0
  9. package/dist/cjs/components/common/{EmojiButton.js → EmojiRadioButton.js} +28 -19
  10. package/dist/cjs/components/common/EmojiUploadPicker.js +80 -37
  11. package/dist/cjs/components/common/EmojiUploadPreview.js +11 -2
  12. package/dist/cjs/components/common/FileChooser.js +2 -2
  13. package/dist/cjs/components/common/ResourcedEmojiComponent.js +4 -0
  14. package/dist/cjs/components/common/RetryableButton.js +7 -3
  15. package/dist/cjs/components/common/TonePreviewButton.js +44 -0
  16. package/dist/cjs/components/common/ToneSelector.js +53 -25
  17. package/dist/cjs/components/common/styles.js +45 -16
  18. package/dist/cjs/components/i18n.js +44 -4
  19. package/dist/cjs/components/picker/CategorySelector.js +112 -90
  20. package/dist/cjs/components/picker/CategoryTracker.js +0 -28
  21. package/dist/cjs/components/picker/EmojiPickerCategoryHeading.js +2 -1
  22. package/dist/cjs/components/picker/EmojiPickerComponent.js +13 -7
  23. package/dist/cjs/components/picker/EmojiPickerEmojiRow.js +32 -4
  24. package/dist/cjs/components/picker/EmojiPickerList.js +140 -51
  25. package/dist/cjs/components/picker/EmojiPickerListSearch.js +16 -3
  26. package/dist/cjs/components/picker/EmojiPickerVirtualItems.js +5 -2
  27. package/dist/cjs/components/picker/VirtualList.js +196 -14
  28. package/dist/cjs/components/picker/styles.js +43 -51
  29. package/dist/cjs/context/EmojiPickerListContext.js +33 -0
  30. package/dist/cjs/hooks/useEmojiPickerListContext.js +12 -0
  31. package/dist/cjs/util/constants.js +40 -1
  32. package/dist/cjs/util/shared-styles.js +3 -4
  33. package/dist/cjs/version.json +1 -1
  34. package/dist/es2019/api/EmojiResource.js +29 -24
  35. package/dist/es2019/api/media/TokenManager.js +4 -4
  36. package/dist/es2019/components/common/CachingEmoji.js +10 -3
  37. package/dist/es2019/components/common/Emoji.js +44 -11
  38. package/dist/es2019/components/common/EmojiActions.js +54 -23
  39. package/dist/es2019/components/common/EmojiErrorMessage.js +7 -3
  40. package/dist/es2019/components/common/EmojiPlaceholder.js +1 -0
  41. package/dist/es2019/components/common/EmojiRadioButton.js +54 -0
  42. package/dist/es2019/components/common/EmojiUploadPicker.js +75 -36
  43. package/dist/es2019/components/common/EmojiUploadPreview.js +11 -2
  44. package/dist/es2019/components/common/FileChooser.js +1 -1
  45. package/dist/es2019/components/common/ResourcedEmojiComponent.js +4 -0
  46. package/dist/es2019/components/common/RetryableButton.js +7 -3
  47. package/dist/es2019/components/common/TonePreviewButton.js +34 -0
  48. package/dist/es2019/components/common/ToneSelector.js +55 -21
  49. package/dist/es2019/components/common/styles.js +41 -10
  50. package/dist/es2019/components/i18n.js +44 -4
  51. package/dist/es2019/components/picker/CategorySelector.js +114 -89
  52. package/dist/es2019/components/picker/CategoryTracker.js +0 -24
  53. package/dist/es2019/components/picker/EmojiPickerCategoryHeading.js +2 -2
  54. package/dist/es2019/components/picker/EmojiPickerComponent.js +14 -7
  55. package/dist/es2019/components/picker/EmojiPickerEmojiRow.js +51 -21
  56. package/dist/es2019/components/picker/EmojiPickerList.js +102 -21
  57. package/dist/es2019/components/picker/EmojiPickerListSearch.js +14 -4
  58. package/dist/es2019/components/picker/EmojiPickerVirtualItems.js +4 -1
  59. package/dist/es2019/components/picker/VirtualList.js +193 -12
  60. package/dist/es2019/components/picker/styles.js +20 -28
  61. package/dist/es2019/context/EmojiPickerListContext.js +17 -0
  62. package/dist/es2019/hooks/useEmojiPickerListContext.js +3 -0
  63. package/dist/es2019/util/constants.js +31 -0
  64. package/dist/es2019/util/shared-styles.js +1 -2
  65. package/dist/es2019/version.json +1 -1
  66. package/dist/esm/api/EmojiResource.js +29 -24
  67. package/dist/esm/api/media/TokenManager.js +4 -4
  68. package/dist/esm/components/common/CachingEmoji.js +14 -6
  69. package/dist/esm/components/common/Emoji.js +48 -12
  70. package/dist/esm/components/common/EmojiActions.js +61 -25
  71. package/dist/esm/components/common/EmojiErrorMessage.js +7 -3
  72. package/dist/esm/components/common/EmojiPlaceholder.js +1 -0
  73. package/dist/esm/components/common/EmojiRadioButton.js +52 -0
  74. package/dist/esm/components/common/EmojiUploadPicker.js +77 -36
  75. package/dist/esm/components/common/EmojiUploadPreview.js +11 -2
  76. package/dist/esm/components/common/FileChooser.js +1 -1
  77. package/dist/esm/components/common/ResourcedEmojiComponent.js +4 -0
  78. package/dist/esm/components/common/RetryableButton.js +7 -3
  79. package/dist/esm/components/common/TonePreviewButton.js +33 -0
  80. package/dist/esm/components/common/ToneSelector.js +49 -18
  81. package/dist/esm/components/common/styles.js +40 -12
  82. package/dist/esm/components/i18n.js +44 -4
  83. package/dist/esm/components/picker/CategorySelector.js +114 -95
  84. package/dist/esm/components/picker/CategoryTracker.js +0 -28
  85. package/dist/esm/components/picker/EmojiPickerCategoryHeading.js +2 -2
  86. package/dist/esm/components/picker/EmojiPickerComponent.js +13 -7
  87. package/dist/esm/components/picker/EmojiPickerEmojiRow.js +32 -4
  88. package/dist/esm/components/picker/EmojiPickerList.js +141 -52
  89. package/dist/esm/components/picker/EmojiPickerListSearch.js +17 -4
  90. package/dist/esm/components/picker/EmojiPickerVirtualItems.js +5 -2
  91. package/dist/esm/components/picker/VirtualList.js +195 -12
  92. package/dist/esm/components/picker/styles.js +37 -45
  93. package/dist/esm/context/EmojiPickerListContext.js +21 -0
  94. package/dist/esm/hooks/useEmojiPickerListContext.js +5 -0
  95. package/dist/esm/util/constants.js +31 -0
  96. package/dist/esm/util/shared-styles.js +1 -2
  97. package/dist/esm/version.json +1 -1
  98. package/dist/types/api/EmojiResource.d.ts +2 -0
  99. package/dist/types/components/common/Emoji.d.ts +7 -1
  100. package/dist/types/components/common/EmojiActions.d.ts +3 -2
  101. package/dist/types/components/common/{EmojiButton.d.ts → EmojiRadioButton.d.ts} +3 -4
  102. package/dist/types/components/common/EmojiUploadPicker.d.ts +6 -4
  103. package/dist/types/components/common/RetryableButton.d.ts +1 -0
  104. package/dist/types/components/common/TonePreviewButton.d.ts +14 -0
  105. package/dist/types/components/common/ToneSelector.d.ts +8 -5
  106. package/dist/types/components/common/internal-types.d.ts +9 -0
  107. package/dist/types/components/common/styles.d.ts +2 -1
  108. package/dist/types/components/i18n.d.ts +40 -0
  109. package/dist/types/components/picker/CategorySelector.d.ts +3 -10
  110. package/dist/types/components/picker/CategoryTracker.d.ts +0 -2
  111. package/dist/types/components/picker/EmojiPickerCategoryHeading.d.ts +2 -1
  112. package/dist/types/components/picker/EmojiPickerEmojiRow.d.ts +5 -0
  113. package/dist/types/components/picker/EmojiPickerList.d.ts +10 -5
  114. package/dist/types/components/picker/EmojiPickerListSearch.d.ts +1 -0
  115. package/dist/types/components/picker/EmojiPickerVirtualItems.d.ts +1 -1
  116. package/dist/types/components/picker/VirtualList.d.ts +2 -0
  117. package/dist/types/components/picker/styles.d.ts +1 -1
  118. package/dist/types/context/EmojiPickerListContext.d.ts +10 -0
  119. package/dist/types/hooks/useEmojiPickerListContext.d.ts +1 -0
  120. package/dist/types/util/constants.d.ts +27 -0
  121. package/dist/types/util/shared-styles.d.ts +1 -1
  122. package/dist/types/util/type-helpers.d.ts +1 -1
  123. package/package.json +9 -6
  124. package/report.api.md +52 -1
  125. package/README.md +0 -3
  126. package/dist/es2019/components/common/EmojiButton.js +0 -49
  127. package/dist/esm/components/common/EmojiButton.js +0 -43
  128. /package/dist/cjs/{components/hooks.js → hooks/useIsMounted.js} +0 -0
  129. /package/dist/es2019/{components/hooks.js → hooks/useIsMounted.js} +0 -0
  130. /package/dist/esm/{components/hooks.js → hooks/useIsMounted.js} +0 -0
  131. /package/dist/types/{components/hooks.d.ts → hooks/useIsMounted.d.ts} +0 -0
@@ -5,9 +5,11 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.emojiErrorMessageTooltipTestId = exports.emojiErrorMessageTestId = exports.emojiErrorIconTestId = exports.default = void 0;
8
- var _react = require("@emotion/react");
8
+ var _react = require("react");
9
+ var _react2 = require("@emotion/react");
9
10
  var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip"));
10
11
  var _error = _interopRequireDefault(require("@atlaskit/icon/glyph/error"));
12
+ var _visuallyHidden = _interopRequireDefault(require("@atlaskit/visually-hidden"));
11
13
  /** @jsx jsx */
12
14
 
13
15
  var emojiErrorMessageTestId = 'emoji-error-message';
@@ -20,24 +22,27 @@ var EmojiErrorMessage = function EmojiErrorMessage(props) {
20
22
  var messageStyles = props.messageStyles,
21
23
  message = props.message,
22
24
  tooltip = props.tooltip;
23
- return tooltip ? (0, _react.jsx)("div", {
25
+ var visualContent = tooltip ? (0, _react2.jsx)("div", {
24
26
  css: messageStyles,
25
27
  "data-testid": emojiErrorMessageTestId
26
- }, (0, _react.jsx)(_tooltip.default, {
28
+ }, (0, _react2.jsx)(_tooltip.default, {
27
29
  content: message,
28
30
  position: "top",
29
31
  testId: emojiErrorMessageTooltipTestId
30
- }, (0, _react.jsx)(_error.default, {
32
+ }, (0, _react2.jsx)(_error.default, {
31
33
  label: "Error",
32
34
  size: "medium",
33
35
  testId: emojiErrorIconTestId
34
- }))) : (0, _react.jsx)("div", {
36
+ }))) : (0, _react2.jsx)("div", {
35
37
  css: messageStyles,
36
38
  "data-testid": emojiErrorMessageTestId
37
- }, (0, _react.jsx)(_error.default, {
39
+ }, (0, _react2.jsx)(_error.default, {
38
40
  label: "Error",
39
41
  size: "small"
40
- }), " ", message);
42
+ }), message);
43
+ return (0, _react2.jsx)(_react.Fragment, null, (0, _react2.jsx)(_visuallyHidden.default, {
44
+ role: "alert"
45
+ }, message), visualContent);
41
46
  };
42
47
  var _default = EmojiErrorMessage;
43
48
  exports.default = _default;
@@ -42,6 +42,7 @@ var EmojiPlaceholder = function EmojiPlaceholder(props) {
42
42
  return (0, _react.jsx)("span", {
43
43
  "data-testid": emojiPlaceholderTestId(shortName),
44
44
  "aria-busy": loading,
45
+ role: "status",
45
46
  "aria-label": shortName,
46
47
  className: _styles.placeholder,
47
48
  css: loading ? [_styles.placeholderContainer, _styles.placeholderContainerAnimated] : _styles.placeholderContainer,
@@ -5,12 +5,14 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.default = exports.EmojiButton = void 0;
8
+ exports.default = exports.EmojiRadioButton = void 0;
9
9
  var _react = _interopRequireWildcard(require("react"));
10
10
  var _react2 = require("@emotion/react");
11
11
  var _mouse = require("../../util/mouse");
12
12
  var _styles = require("./styles");
13
13
  var _Emoji = _interopRequireDefault(require("./Emoji"));
14
+ var _constants = require("../../util/constants");
15
+ var _visuallyHidden = _interopRequireDefault(require("@atlaskit/visually-hidden"));
14
16
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
15
17
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
18
  /** @jsx jsx */
@@ -23,34 +25,41 @@ var handleMouseDown = function handleMouseDown(props, event) {
23
25
  }
24
26
  };
25
27
  var handleKeyPress = function handleKeyPress(props, event) {
26
- var onSelected = props.onSelected;
27
- if (onSelected && (event.key === 'Enter' || event.key === ' ')) {
28
+ if (_constants.TONESELECTOR_KEYBOARD_KEYS_SUPPORTED.includes(event.key)) {
29
+ var onSelected = props.onSelected;
28
30
  event.preventDefault();
29
- onSelected();
31
+ if (onSelected) {
32
+ onSelected();
33
+ }
30
34
  }
31
35
  };
32
- var EmojiButton = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
36
+ var EmojiRadioButton = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
33
37
  var emoji = props.emoji,
34
38
  selectOnHover = props.selectOnHover,
35
39
  ariaLabelText = props.ariaLabelText,
36
- ariaExpanded = props.ariaExpanded,
37
- shouldHideButton = props.shouldHideButton;
38
- return (0, _react2.jsx)("button", {
39
- ref: ref,
40
- "aria-expanded": ariaExpanded,
41
- css: shouldHideButton ? _styles.hiddenToneButton : _styles.emojiButton,
40
+ defaultChecked = props.defaultChecked;
41
+ return (0, _react2.jsx)("label", {
42
+ css: _styles.emojiButton,
42
43
  onMouseDown: function onMouseDown(event) {
43
- handleMouseDown(props, event);
44
+ return handleMouseDown(props, event);
44
45
  },
45
46
  onKeyDown: function onKeyDown(event) {
46
- handleKeyPress(props, event);
47
- },
48
- "aria-label": ariaLabelText
49
- }, (0, _react2.jsx)(_Emoji.default, {
47
+ return handleKeyPress(props, event);
48
+ }
49
+ }, (0, _react2.jsx)(_visuallyHidden.default, null, ariaLabelText), (0, _react2.jsx)("input", {
50
+ ref: ref,
51
+ "data-testid": ariaLabelText,
52
+ type: "radio",
53
+ name: "skin-tone",
54
+ css: _styles.emojiRadio,
55
+ defaultChecked: defaultChecked
56
+ }), (0, _react2.jsx)(_Emoji.default, {
50
57
  emoji: emoji,
51
- selectOnHover: selectOnHover
58
+ selectOnHover: selectOnHover,
59
+ shouldBeInteractive: false,
60
+ "aria-hidden": true
52
61
  }));
53
62
  });
54
- exports.EmojiButton = EmojiButton;
55
- var _default = /*#__PURE__*/(0, _react.memo)(EmojiButton);
63
+ exports.EmojiRadioButton = EmojiRadioButton;
64
+ var _default = /*#__PURE__*/(0, _react.memo)(EmojiRadioButton);
56
65
  exports.default = _default;
@@ -5,16 +5,17 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.uploadEmojiNameInputTestId = exports.default = void 0;
8
+ exports.uploadEmojiNameInputTestId = exports.uploadEmojiComponentTestId = exports.default = exports.cancelEmojiUploadPickerTestId = void 0;
9
9
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
10
10
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
11
11
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
12
- var _react = _interopRequireWildcard(require("react"));
12
+ var _react = require("react");
13
13
  var _react2 = require("@emotion/react");
14
14
  var _reactIntlNext = require("react-intl-next");
15
15
  var _textfield = _interopRequireDefault(require("@atlaskit/textfield"));
16
16
  var _cross = _interopRequireDefault(require("@atlaskit/icon/glyph/cross"));
17
17
  var _standardButton = _interopRequireDefault(require("@atlaskit/button/standard-button"));
18
+ var _reactFocusLock = _interopRequireDefault(require("react-focus-lock"));
18
19
  var ImageUtil = _interopRequireWildcard(require("../../util/image"));
19
20
  var _logger = _interopRequireDefault(require("../../util/logger"));
20
21
  var _i18n = require("../i18n");
@@ -29,6 +30,10 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
29
30
 
30
31
  var uploadEmojiNameInputTestId = 'upload-emoji-name-input';
31
32
  exports.uploadEmojiNameInputTestId = uploadEmojiNameInputTestId;
33
+ var uploadEmojiComponentTestId = 'upload-emoji-component';
34
+ exports.uploadEmojiComponentTestId = uploadEmojiComponentTestId;
35
+ var cancelEmojiUploadPickerTestId = 'cancel-emoji-upload-picker';
36
+ exports.cancelEmojiUploadPickerTestId = cancelEmojiUploadPickerTestId;
32
37
  var disallowedReplacementsMap = new Map([[':', ''], ['!', ''], ['@', ''], ['#', ''], ['%', ''], ['^', ''], ['&', ''], ['*', ''], ['(', ''], [')', ''], [' ', '_']]);
33
38
  var sanitizeName = function sanitizeName(name) {
34
39
  // prevent / replace certain characters, allow others
@@ -42,7 +47,7 @@ var toEmojiName = function toEmojiName(uploadName) {
42
47
  var name = uploadName.split('_').join(' ');
43
48
  return "".concat(name.substr(0, 1).toLocaleUpperCase()).concat(name.substr(1));
44
49
  };
45
- var ChooseEmojiFile = function ChooseEmojiFile(props) {
50
+ var ChooseEmojiFile = /*#__PURE__*/(0, _react.memo)(function (props) {
46
51
  var _props$name = props.name,
47
52
  name = _props$name === void 0 ? '' : _props$name,
48
53
  onChooseFile = props.onChooseFile,
@@ -54,13 +59,31 @@ var ChooseEmojiFile = function ChooseEmojiFile(props) {
54
59
  var formatMessage = intl.formatMessage;
55
60
  var disableChooser = !name;
56
61
  var fileChooserButtonDescriptionId = 'choose.emoji.file.button.screen.reader.description.id';
57
- var onKeyDownHandler = function onKeyDownHandler(event) {
62
+ var inputRef = (0, _react.useRef)(null);
63
+ var onKeyDownHandler = (0, _react.useCallback)(function (event) {
58
64
  if (event.key === 'Escape') {
59
65
  onUploadCancelled();
60
66
  }
61
- };
67
+ }, [onUploadCancelled]);
68
+ var setInputFocus = (0, _react.useCallback)(function () {
69
+ var _inputRef$current, _document$activeEleme, _inputRef$current2;
70
+ (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
71
+ if (((_document$activeEleme = document.activeElement) === null || _document$activeEleme === void 0 ? void 0 : _document$activeEleme.id) !== ((_inputRef$current2 = inputRef.current) === null || _inputRef$current2 === void 0 ? void 0 : _inputRef$current2.id)) {
72
+ setInputFocus();
73
+ }
74
+ }, []);
75
+
76
+ // make sure input has focus after update
77
+ (0, _react.useEffect)(function () {
78
+ window.requestAnimationFrame(setInputFocus);
79
+ }, [setInputFocus]);
80
+ var cancelLabel = formatMessage(_i18n.messages.cancelLabel);
81
+ var emojiPlaceholder = formatMessage(_i18n.messages.emojiPlaceholder);
82
+ var emojiNameAriaLabel = formatMessage(_i18n.messages.emojiNameAriaLabel);
83
+ var emojiChooseFileTitle = formatMessage(_i18n.messages.emojiChooseFileTitle);
62
84
  return (0, _react2.jsx)("div", {
63
- css: _styles.emojiUpload
85
+ css: _styles.emojiUpload,
86
+ "data-testid": uploadEmojiComponentTestId
64
87
  }, (0, _react2.jsx)("div", {
65
88
  css: _styles.emojiUploadTop
66
89
  }, (0, _react2.jsx)("span", {
@@ -71,27 +94,30 @@ var ChooseEmojiFile = function ChooseEmojiFile(props) {
71
94
  css: _styles.closeEmojiUploadButton
72
95
  }, (0, _react2.jsx)(_standardButton.default, {
73
96
  onClick: onUploadCancelled,
74
- "aria-describedby": formatMessage(_i18n.messages.cancelLabel),
97
+ "aria-label": cancelLabel,
75
98
  appearance: "subtle",
76
99
  spacing: "none",
77
- shouldFitContainer: true
100
+ shouldFitContainer: true,
101
+ testId: cancelEmojiUploadPickerTestId
78
102
  }, (0, _react2.jsx)(_cross.default, {
79
103
  size: "small",
80
- label: formatMessage(_i18n.messages.cancelLabel)
104
+ label: cancelLabel
81
105
  })))), (0, _react2.jsx)("div", {
82
106
  css: _styles.uploadChooseFileRow
83
107
  }, (0, _react2.jsx)("span", {
84
108
  css: _styles.uploadChooseFileEmojiName
85
109
  }, (0, _react2.jsx)(_textfield.default, {
86
- placeholder: formatMessage(_i18n.messages.emojiPlaceholder),
87
- "aria-label": formatMessage(_i18n.messages.emojiNameAriaLabel),
110
+ placeholder: emojiPlaceholder,
111
+ "aria-label": emojiNameAriaLabel,
88
112
  maxLength: maxNameLength,
89
113
  onChange: onNameChange,
90
114
  onKeyDown: onKeyDownHandler,
91
115
  value: name,
92
116
  isCompact: true,
93
117
  autoFocus: true,
94
- testId: uploadEmojiNameInputTestId
118
+ testId: uploadEmojiNameInputTestId,
119
+ ref: inputRef,
120
+ id: "new-emoji-name-input"
95
121
  })), (0, _react2.jsx)("span", {
96
122
  css: _styles.uploadChooseFileBrowse
97
123
  }, (0, _react2.jsx)(_reactIntlNext.FormattedMessage, _i18n.messages.emojiChooseFileScreenReaderDescription, function (screenReaderDescription) {
@@ -99,7 +125,7 @@ var ChooseEmojiFile = function ChooseEmojiFile(props) {
99
125
  hidden: true,
100
126
  id: fileChooserButtonDescriptionId
101
127
  }, screenReaderDescription), (0, _react2.jsx)(_FileChooser.default, {
102
- label: formatMessage(_i18n.messages.emojiChooseFileTitle),
128
+ label: emojiChooseFileTitle,
103
129
  onChange: onChooseFile,
104
130
  onClick: onClick,
105
131
  accept: "image/png,image/jpeg,image/gif",
@@ -112,8 +138,9 @@ var ChooseEmojiFile = function ChooseEmojiFile(props) {
112
138
  messageStyles: _styles.emojiChooseFileErrorMessage,
113
139
  message: errorMessage
114
140
  })));
115
- };
141
+ });
116
142
  var EmojiUploadPicker = function EmojiUploadPicker(props) {
143
+ var _document$activeEleme2;
117
144
  var errorMessage = props.errorMessage,
118
145
  initialUploadName = props.initialUploadName,
119
146
  onUploadEmoji = props.onUploadEmoji,
@@ -140,6 +167,8 @@ var EmojiUploadPicker = function EmojiUploadPicker(props) {
140
167
  _useState10 = (0, _slicedToArray2.default)(_useState9, 2),
141
168
  previewImage = _useState10[0],
142
169
  setPreviewImage = _useState10[1];
170
+ // document is undefined during ssr rendering and throws an error
171
+ var lastFocusedElementId = (0, _react.useRef)(typeof document !== 'undefined' ? (_document$activeEleme2 = document.activeElement) === null || _document$activeEleme2 === void 0 ? void 0 : _document$activeEleme2.id : '');
143
172
  (0, _react.useEffect)(function () {
144
173
  if (errorMessage) {
145
174
  setUploadStatus(_internalTypes.UploadStatus.Error);
@@ -155,13 +184,18 @@ var EmojiUploadPicker = function EmojiUploadPicker(props) {
155
184
  setName(sanitizeName(initialUploadName));
156
185
  }
157
186
  }, [initialUploadName]);
158
- var onNameChange = function onNameChange(event) {
187
+ var clearUploadPicker = (0, _react.useCallback)(function () {
188
+ setName(undefined);
189
+ setPreviewImage(undefined);
190
+ setUploadStatus(_internalTypes.UploadStatus.Waiting);
191
+ }, []);
192
+ var onNameChange = (0, _react.useCallback)(function (event) {
159
193
  var newName = sanitizeName(event.target.value);
160
194
  if (name !== newName) {
161
195
  setName(newName);
162
196
  }
163
- };
164
- var onAddEmoji = function onAddEmoji() {
197
+ }, [name]);
198
+ var onAddEmoji = (0, _react.useCallback)(function () {
165
199
  if (uploadStatus === _internalTypes.UploadStatus.Uploading) {
166
200
  return;
167
201
  }
@@ -191,13 +225,16 @@ var EmojiUploadPicker = function EmojiUploadPicker(props) {
191
225
  });
192
226
  });
193
227
  }
194
- };
195
- var errorOnUpload = function errorOnUpload(event) {
228
+ }, [clearUploadPicker, filename, name, onUploadEmoji, previewImage, uploadStatus]);
229
+ var cancelChooseFile = (0, _react.useCallback)(function () {
230
+ setPreviewImage(undefined);
231
+ }, []);
232
+ var errorOnUpload = (0, _react.useCallback)(function (event) {
196
233
  (0, _logger.default)('File load error: ', event);
197
234
  setChooseEmojiErrorMessage(_i18n.messages.emojiUploadFailed);
198
235
  cancelChooseFile();
199
- };
200
- var onFileLoad = function onFileLoad(file) {
236
+ }, [cancelChooseFile]);
237
+ var onFileLoad = (0, _react.useCallback)(function (file) {
201
238
  return /*#__PURE__*/function () {
202
239
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(f) {
203
240
  return _regenerator.default.wrap(function _callee$(_context) {
@@ -228,11 +265,8 @@ var EmojiUploadPicker = function EmojiUploadPicker(props) {
228
265
  return _ref.apply(this, arguments);
229
266
  };
230
267
  }();
231
- };
232
- var cancelChooseFile = function cancelChooseFile() {
233
- setPreviewImage(undefined);
234
- };
235
- var onChooseFile = function onChooseFile(event) {
268
+ }, [cancelChooseFile]);
269
+ var onChooseFile = (0, _react.useCallback)(function (event) {
236
270
  var files = event.target.files;
237
271
  if (files.length) {
238
272
  var reader = new FileReader();
@@ -249,17 +283,25 @@ var EmojiUploadPicker = function EmojiUploadPicker(props) {
249
283
  } else {
250
284
  cancelChooseFile();
251
285
  }
252
- };
253
- var clearUploadPicker = function clearUploadPicker() {
254
- setName(undefined);
255
- setPreviewImage(undefined);
256
- setUploadStatus(_internalTypes.UploadStatus.Waiting);
257
- };
258
- var cancelUpload = function cancelUpload() {
286
+ }, [cancelChooseFile, errorOnUpload, onFileLoad]);
287
+ var cancelUpload = (0, _react.useCallback)(function () {
259
288
  clearUploadPicker();
260
289
  onUploadCancelled();
261
- };
262
- return (0, _react2.jsx)(_react.default.Fragment, null, name && previewImage ? (0, _react2.jsx)(_EmojiUploadPreview.default, {
290
+
291
+ // using setTimeout here to allow the UI to update before setting focus
292
+ setTimeout(function (lastFocus) {
293
+ if (lastFocus) {
294
+ var _document$getElementB;
295
+ (_document$getElementB = document.getElementById(lastFocus)) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.focus();
296
+ }
297
+ }, 0, lastFocusedElementId.current);
298
+ }, [clearUploadPicker, onUploadCancelled]);
299
+ var chooseErrorMessage = (0, _react.useMemo)(function () {
300
+ return chooseEmojiErrorMessage ? (0, _react2.jsx)(_reactIntlNext.FormattedMessage, chooseEmojiErrorMessage) : undefined;
301
+ }, [chooseEmojiErrorMessage]);
302
+ return (0, _react2.jsx)(_reactFocusLock.default, {
303
+ noFocusGuards: true
304
+ }, name && previewImage ? (0, _react2.jsx)(_EmojiUploadPreview.default, {
263
305
  errorMessage: errorMessage,
264
306
  name: name,
265
307
  onAddEmoji: onAddEmoji,
@@ -272,9 +314,10 @@ var EmojiUploadPicker = function EmojiUploadPicker(props) {
272
314
  onClick: onFileChooserClicked,
273
315
  onNameChange: onNameChange,
274
316
  onUploadCancelled: cancelUpload,
275
- errorMessage: chooseEmojiErrorMessage ? (0, _react2.jsx)(_reactIntlNext.FormattedMessage, chooseEmojiErrorMessage) : undefined,
317
+ errorMessage: chooseErrorMessage,
276
318
  intl: intl
277
319
  }));
278
320
  };
279
- var _default = (0, _reactIntlNext.injectIntl)(EmojiUploadPicker);
321
+ var EmojiUploadPickerComponent = (0, _reactIntlNext.injectIntl)( /*#__PURE__*/(0, _react.memo)(EmojiUploadPicker));
322
+ var _default = EmojiUploadPickerComponent;
280
323
  exports.default = _default;
@@ -22,12 +22,14 @@ var _EmojiErrorMessage = _interopRequireDefault(require("./EmojiErrorMessage"));
22
22
  var _internalTypes = require("./internal-types");
23
23
  var _RetryableButton = _interopRequireDefault(require("./RetryableButton"));
24
24
  var _styles = require("./styles");
25
+ var _visuallyHidden = _interopRequireDefault(require("@atlaskit/visually-hidden"));
25
26
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
26
27
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
27
28
  var uploadPreviewTestId = 'upload-preview';
28
29
  exports.uploadPreviewTestId = uploadPreviewTestId;
29
30
  var cancelUploadButtonTestId = 'cancel-upload-button';
30
31
  exports.cancelUploadButtonTestId = cancelUploadButtonTestId;
32
+ var addEmojiButtonDescriptionId = 'add.emoji.button.screen.reader.description.id';
31
33
  var EmojiUploadPreview = /*#__PURE__*/function (_PureComponent) {
32
34
  (0, _inherits2.default)(EmojiUploadPreview, _PureComponent);
33
35
  var _super = _createSuper(EmojiUploadPreview);
@@ -84,12 +86,19 @@ var EmojiUploadPreview = /*#__PURE__*/function (_PureComponent) {
84
86
  messageStyles: _styles.emojiPreviewErrorMessage,
85
87
  message: errorMessage,
86
88
  tooltip: true
87
- }) : null, (0, _react2.jsx)(_RetryableButton.default, {
89
+ }) : null, !errorMessage && (0, _react2.jsx)(_visuallyHidden.default, {
90
+ id: addEmojiButtonDescriptionId
91
+ }, (0, _react2.jsx)(_reactIntlNext.FormattedMessage, (0, _extends2.default)({}, _i18n.messages.emojiPreview, {
92
+ values: {
93
+ emoji: name
94
+ }
95
+ }))), (0, _react2.jsx)(_RetryableButton.default, {
88
96
  label: formatMessage(_i18n.messages.addEmojiLabel),
89
97
  onSubmit: onAddEmoji,
90
98
  appearance: "primary",
91
99
  loading: uploading,
92
- error: !!errorMessage
100
+ error: !!errorMessage,
101
+ ariaDescribedby: addEmojiButtonDescriptionId
93
102
  }), (0, _react2.jsx)(_customThemeButton.default, {
94
103
  onClick: onUploadCancelled,
95
104
  appearance: "subtle",
@@ -7,7 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.fileUploadInputTestId = exports.default = exports.chooseFileButtonTestId = void 0;
9
9
  var _react = _interopRequireWildcard(require("react"));
10
- var _customThemeButton = _interopRequireDefault(require("@atlaskit/button/custom-theme-button"));
10
+ var _standardButton = _interopRequireDefault(require("@atlaskit/button/standard-button"));
11
11
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
12
12
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
13
13
  var chooseFileButtonTestId = 'choose-file-button';
@@ -31,7 +31,7 @@ var FileChooser = function FileChooser(props) {
31
31
  }
32
32
  filePickerRef.current.click();
33
33
  };
34
- return /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_customThemeButton.default, {
34
+ return /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(_standardButton.default, {
35
35
  onClick: handleOnChooseFile,
36
36
  isDisabled: isDisabled,
37
37
  "aria-describedby": ariaDescribedBy,
@@ -149,6 +149,10 @@ var ResourcedEmojiComponent = function ResourcedEmojiComponent(props) {
149
149
  }
150
150
  fetchOrGetEmoji(resolvedEmojiProvider, emojiId, optimistic);
151
151
  }, [resolvedEmojiProvider, emojiId, optimistic, fetchOrGetEmoji]);
152
+
153
+ /**
154
+ * Setting resolved emoji provider for optimistic rendering
155
+ */
152
156
  (0, _react.useEffect)(function () {
153
157
  Promise.resolve(emojiProvider).then(function (emojiProvider) {
154
158
  setResolvedEmojiProvider(emojiProvider);
@@ -29,19 +29,23 @@ var RetryButton = function RetryButton(props) {
29
29
  css: _styles.uploadRetryButton,
30
30
  appearance: "warning",
31
31
  onClick: onSubmit,
32
- testId: retryUploadButtonTestId
32
+ testId: retryUploadButtonTestId,
33
+ autoFocus: true
33
34
  }, retryLabel);
34
35
  });
35
36
  };
36
37
  var UploadButton = function UploadButton(props) {
37
38
  var appearance = props.appearance,
38
39
  onSubmit = props.onSubmit,
39
- label = props.label;
40
+ label = props.label,
41
+ ariaDescribedby = props.ariaDescribedby;
40
42
  return (0, _react.jsx)(_customThemeButton.default, {
41
43
  css: _styles.uploadEmojiButton,
42
44
  appearance: appearance,
43
45
  onClick: onSubmit,
44
- testId: uploadEmojiButtonTestId
46
+ testId: uploadEmojiButtonTestId,
47
+ "aria-describedby": ariaDescribedby,
48
+ autoFocus: true
45
49
  }, label);
46
50
  };
47
51
  var RetryableButton = function RetryableButton(props) {
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.tonePreviewTestId = exports.default = exports.TonePreviewButton = void 0;
8
+ var _react = require("react");
9
+ var _react2 = require("@emotion/react");
10
+ var _styles = require("./styles");
11
+ var _Emoji = _interopRequireDefault(require("./Emoji"));
12
+ /** @jsx jsx */
13
+
14
+ var tonePreviewTestId = 'tone-preview';
15
+ exports.tonePreviewTestId = tonePreviewTestId;
16
+ var TonePreviewButton = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
17
+ var emoji = props.emoji,
18
+ selectOnHover = props.selectOnHover,
19
+ ariaLabelText = props.ariaLabelText,
20
+ ariaExpanded = props.ariaExpanded,
21
+ onSelected = props.onSelected,
22
+ _props$isVisible = props.isVisible,
23
+ isVisible = _props$isVisible === void 0 ? true : _props$isVisible;
24
+ return (0, _react2.jsx)("button", {
25
+ ref: ref,
26
+ css: [_styles.emojiButton, !isVisible && _styles.hidden],
27
+ onClick: onSelected,
28
+ "aria-label": ariaLabelText,
29
+ "aria-expanded": ariaExpanded,
30
+ "aria-controls": "emoji-picker-tone-selector",
31
+ style: {
32
+ overflow: 'hidden'
33
+ },
34
+ "data-testid": tonePreviewTestId
35
+ }, (0, _react2.jsx)(_Emoji.default, {
36
+ emoji: emoji,
37
+ selectOnHover: selectOnHover,
38
+ shouldBeInteractive: false,
39
+ "aria-hidden": true
40
+ }));
41
+ });
42
+ exports.TonePreviewButton = TonePreviewButton;
43
+ var _default = /*#__PURE__*/(0, _react.memo)(TonePreviewButton);
44
+ exports.default = _default;
@@ -1,22 +1,25 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- var _typeof = require("@babel/runtime/helpers/typeof");
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
- exports.default = exports.ToneSelectorInternal = void 0;
7
+ exports.toneSelectorTestId = exports.default = exports.ToneSelectorInternal = void 0;
9
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
9
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
11
- var _react = _interopRequireWildcard(require("react"));
12
- var _EmojiButton = _interopRequireDefault(require("./EmojiButton"));
10
+ var _react = require("@emotion/react");
11
+ var _react2 = require("react");
13
12
  var _analyticsNext = require("@atlaskit/analytics-next");
14
13
  var _analytics = require("../../util/analytics");
15
14
  var _setSkinToneAriaLabelText = require("./setSkinToneAriaLabelText");
16
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
17
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
15
+ var _EmojiRadioButton = _interopRequireDefault(require("./EmojiRadioButton"));
16
+ var _reactIntlNext = require("react-intl-next");
17
+ var _i18n = require("../i18n");
18
+ var _styles = require("./styles");
18
19
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
19
20
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
21
+ var toneSelectorTestId = 'tone-selector';
22
+ exports.toneSelectorTestId = toneSelectorTestId;
20
23
  var extractAllTones = function extractAllTones(emoji) {
21
24
  if (emoji.skinVariations) {
22
25
  return [emoji].concat((0, _toConsumableArray2.default)(emoji.skinVariations));
@@ -26,24 +29,39 @@ var extractAllTones = function extractAllTones(emoji) {
26
29
  var ToneSelectorInternal = function ToneSelectorInternal(props) {
27
30
  var createAnalyticsEvent = props.createAnalyticsEvent,
28
31
  emoji = props.emoji,
29
- previewEmojiId = props.previewEmojiId,
30
- onToneSelected = props.onToneSelected;
31
- var isMounted = (0, _react.useRef)(false);
32
- var firstToneButtonRef = (0, _react.useRef)(null);
33
- var emojiToneCollection = (0, _react.useMemo)(function () {
34
- return extractAllTones(emoji).map(function (tone, index) {
32
+ onToneSelected = props.onToneSelected,
33
+ onToneClose = props.onToneClose,
34
+ selectedTone = props.selectedTone,
35
+ isVisible = props.isVisible;
36
+ var isMounted = (0, _react2.useRef)(false);
37
+ var selectedToneRadioRef = (0, _react2.useRef)(null);
38
+ var _useIntl = (0, _reactIntlNext.useIntl)(),
39
+ formatMessage = _useIntl.formatMessage;
40
+ var emojiToneCollection = (0, _react2.useMemo)(function () {
41
+ var selectedToneIndex = -1;
42
+ var toneColletion = extractAllTones(emoji).map(function (tone, index) {
43
+ var isSelected = index === selectedTone;
44
+ if (isSelected) {
45
+ selectedToneIndex = index;
46
+ }
35
47
  return _objectSpread(_objectSpread({}, tone), {}, {
36
- focused: tone.id !== previewEmojiId,
48
+ isSelected: isSelected,
37
49
  label: (0, _setSkinToneAriaLabelText.setSkinToneAriaLabelText)(tone.name),
38
- toneId: index
50
+ toneIndex: index
39
51
  });
40
52
  });
41
- }, [emoji, previewEmojiId]);
42
- (0, _react.useEffect)(function () {
43
- if (firstToneButtonRef.current) {
44
- firstToneButtonRef.current.focus();
53
+
54
+ // push description of selected tone to the end of the array
55
+ // so that it gets rendered last/rightmost
56
+ toneColletion.push(toneColletion.splice(selectedToneIndex, 1)[0]);
57
+ return toneColletion;
58
+ }, [emoji, selectedTone]);
59
+ (0, _react2.useEffect)(function () {
60
+ if (isVisible) {
61
+ var _selectedToneRadioRef;
62
+ (_selectedToneRadioRef = selectedToneRadioRef.current) === null || _selectedToneRadioRef === void 0 ? void 0 : _selectedToneRadioRef.focus();
45
63
  }
46
- }, [firstToneButtonRef]);
64
+ }, [isVisible, selectedToneRadioRef]);
47
65
  var fireAnalyticsEvent = function fireAnalyticsEvent(event) {
48
66
  if (createAnalyticsEvent) {
49
67
  (0, _analytics.createAndFireEventInElementsChannel)(event)(createAnalyticsEvent);
@@ -51,6 +69,10 @@ var ToneSelectorInternal = function ToneSelectorInternal(props) {
51
69
  };
52
70
  var onToneSelectedHandler = function onToneSelectedHandler(toneValue) {
53
71
  return function () {
72
+ if (selectedTone === toneValue && onToneClose) {
73
+ onToneClose();
74
+ return;
75
+ }
54
76
  onToneSelected(toneValue);
55
77
  var toneList = ['default', 'light', 'mediumLight', 'medium', 'mediumDark', 'dark'];
56
78
  fireAnalyticsEvent((0, _analytics.toneSelectedEvent)({
@@ -62,19 +84,25 @@ var ToneSelectorInternal = function ToneSelectorInternal(props) {
62
84
  fireAnalyticsEvent((0, _analytics.toneSelectorOpenedEvent)({}));
63
85
  }
64
86
  isMounted.current = true;
65
- return /*#__PURE__*/_react.default.createElement("div", null, emojiToneCollection.map(function (tone) {
66
- return /*#__PURE__*/_react.default.createElement(_EmojiButton.default, {
67
- ref: tone.focused ? firstToneButtonRef : null,
68
- shouldHideButton: tone.id === previewEmojiId,
87
+ return (0, _react.jsx)("div", {
88
+ role: "radiogroup",
89
+ "data-testid": toneSelectorTestId,
90
+ id: "emoji-picker-tone-selector",
91
+ "aria-label": formatMessage(_i18n.messages.emojiSelectSkinToneListAriaLabelText),
92
+ css: !isVisible && _styles.hidden
93
+ }, emojiToneCollection.map(function (tone) {
94
+ return (0, _react.jsx)(_EmojiRadioButton.default, {
95
+ ref: tone.isSelected ? selectedToneRadioRef : null,
96
+ defaultChecked: tone.isSelected,
69
97
  ariaLabelText: tone.label,
70
98
  key: "".concat(tone.id),
71
- onSelected: onToneSelectedHandler(tone.toneId),
72
99
  emoji: tone,
100
+ onSelected: onToneSelectedHandler(tone.toneIndex),
73
101
  selectOnHover: true
74
102
  });
75
103
  }));
76
104
  };
77
105
  exports.ToneSelectorInternal = ToneSelectorInternal;
78
106
  var ToneSelector = (0, _analyticsNext.withAnalyticsEvents)()(ToneSelectorInternal);
79
- var _default = ToneSelector;
107
+ var _default = /*#__PURE__*/(0, _react2.memo)(ToneSelector);
80
108
  exports.default = _default;