@atlaskit/emoji 70.11.2 → 70.13.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 (44) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/afm-cc/tsconfig.json +0 -3
  3. package/afm-products/tsconfig.json +0 -3
  4. package/dist/cjs/api/EmojiUtils.js +8 -1
  5. package/dist/cjs/components/i18n.js +0 -10
  6. package/dist/cjs/components/picker/EmojiPickerComponent.compiled.css +0 -3
  7. package/dist/cjs/components/picker/EmojiPickerComponent.js +6 -20
  8. package/dist/cjs/components/picker/EmojiPickerList.js +10 -31
  9. package/dist/cjs/components/picker/EmojiPickerSizes.js +0 -2
  10. package/dist/cjs/components/picker/EmojiPickerVirtualItems.js +1 -15
  11. package/dist/cjs/util/analytics/analytics.js +1 -1
  12. package/dist/es2019/api/EmojiUtils.js +8 -1
  13. package/dist/es2019/components/i18n.js +0 -10
  14. package/dist/es2019/components/picker/EmojiPickerComponent.compiled.css +0 -3
  15. package/dist/es2019/components/picker/EmojiPickerComponent.js +6 -20
  16. package/dist/es2019/components/picker/EmojiPickerList.js +11 -33
  17. package/dist/es2019/components/picker/EmojiPickerSizes.js +0 -2
  18. package/dist/es2019/components/picker/EmojiPickerVirtualItems.js +0 -7
  19. package/dist/es2019/util/analytics/analytics.js +1 -1
  20. package/dist/esm/api/EmojiUtils.js +8 -1
  21. package/dist/esm/components/i18n.js +0 -10
  22. package/dist/esm/components/picker/EmojiPickerComponent.compiled.css +0 -3
  23. package/dist/esm/components/picker/EmojiPickerComponent.js +6 -20
  24. package/dist/esm/components/picker/EmojiPickerList.js +11 -32
  25. package/dist/esm/components/picker/EmojiPickerSizes.js +0 -2
  26. package/dist/esm/components/picker/EmojiPickerVirtualItems.js +0 -14
  27. package/dist/esm/util/analytics/analytics.js +1 -1
  28. package/dist/types/api/EmojiUtils.d.ts +1 -1
  29. package/dist/types/components/i18n.d.ts +0 -10
  30. package/dist/types/components/picker/EmojiPickerSizes.d.ts +0 -1
  31. package/dist/types/components/picker/EmojiPickerVirtualItems.d.ts +1 -6
  32. package/dist/types-ts4.5/api/EmojiUtils.d.ts +1 -1
  33. package/dist/types-ts4.5/components/i18n.d.ts +0 -10
  34. package/dist/types-ts4.5/components/picker/EmojiPickerSizes.d.ts +0 -1
  35. package/dist/types-ts4.5/components/picker/EmojiPickerVirtualItems.d.ts +1 -6
  36. package/package.json +1 -2
  37. package/dist/cjs/components/picker/EmojiPickerNoResults.compiled.css +0 -12
  38. package/dist/cjs/components/picker/EmojiPickerNoResults.js +0 -50
  39. package/dist/es2019/components/picker/EmojiPickerNoResults.compiled.css +0 -12
  40. package/dist/es2019/components/picker/EmojiPickerNoResults.js +0 -40
  41. package/dist/esm/components/picker/EmojiPickerNoResults.compiled.css +0 -12
  42. package/dist/esm/components/picker/EmojiPickerNoResults.js +0 -41
  43. package/dist/types/components/picker/EmojiPickerNoResults.d.ts +0 -7
  44. package/dist/types-ts4.5/components/picker/EmojiPickerNoResults.d.ts +0 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/emoji
2
2
 
3
+ ## 70.13.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`81637ec91afd1`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/81637ec91afd1) -
8
+ Represent standard emojis as native Unicode characters instead of images. Updates
9
+ EmojiNodeDataProvider to support Unicode representations.
10
+
11
+ ## 70.12.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [`5048d8b2e4dea`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/5048d8b2e4dea) -
16
+ Revert emoji empty state changes due to resolution issues
17
+
3
18
  ## 70.11.2
4
19
 
5
20
  ### Patch Changes
@@ -43,9 +43,6 @@
43
43
  {
44
44
  "path": "../../../design-system/icon/afm-cc/tsconfig.json"
45
45
  },
46
- {
47
- "path": "../../../design-system/image/afm-cc/tsconfig.json"
48
- },
49
46
  {
50
47
  "path": "../../../media/media-client/afm-cc/tsconfig.json"
51
48
  },
@@ -43,9 +43,6 @@
43
43
  {
44
44
  "path": "../../../design-system/icon/afm-products/tsconfig.json"
45
45
  },
46
- {
47
- "path": "../../../design-system/image/afm-products/tsconfig.json"
48
- },
49
46
  {
50
47
  "path": "../../../media/media-client/afm-products/tsconfig.json"
51
48
  },
@@ -9,8 +9,11 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
9
9
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
10
10
  var _utilServiceSupport = require("@atlaskit/util-service-support");
11
11
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
12
+ var _types = require("../types");
12
13
  var _typeHelpers = require("../util/type-helpers");
13
14
  var _logger = _interopRequireDefault(require("../util/logger"));
15
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
+ var _emojiIdToEmoji = require("../util/emojiIdToEmoji");
14
17
  var _excluded = ["getRatio"],
15
18
  _excluded2 = ["queryParams"],
16
19
  _excluded3 = ["representation", "altRepresentations"],
@@ -138,7 +141,11 @@ var denormaliseSkinEmoji = exports.denormaliseSkinEmoji = function denormaliseSk
138
141
  */
139
142
  var denormaliseEmojiServiceResponse = exports.denormaliseEmojiServiceResponse = function denormaliseEmojiServiceResponse(emojiData) {
140
143
  var emojis = emojiData.emojis.map(function (emoji) {
141
- var newRepresentation = denormaliseServiceRepresentation(emoji.representation, emojiData.meta);
144
+ var unicodeEmoji = (0, _emojiIdToEmoji.emojiIdToEmoji)(emoji.id);
145
+ var useUnicodeRepresentation = !!(emoji.id && emoji.type === _types.ProviderTypes.STANDARD && unicodeEmoji && (0, _platformFeatureFlags.fg)('platform_twemoji_removal_unicode_emojis'));
146
+ var newRepresentation = useUnicodeRepresentation ? {
147
+ unicodeEmoji: unicodeEmoji
148
+ } : denormaliseServiceRepresentation(emoji.representation, emojiData.meta);
142
149
  var altRepresentation = denormaliseServiceAltRepresentation(emoji.altRepresentations, emojiData.meta);
143
150
  var newSkinVariations = denormaliseSkinEmoji(emoji, emojiData.meta);
144
151
 
@@ -231,16 +231,6 @@ var messages = exports.messages = (0, _reactIntl.defineMessages)({
231
231
  defaultMessage: 'An emoji with this name exists already',
232
232
  description: 'Error message shown when the user tries to upload an emoji with a name that already exists in the custom emoji set'
233
233
  },
234
- emojiPickerNoResults: {
235
- id: 'fabric.emoji.picker.no.results',
236
- defaultMessage: 'No results',
237
- description: 'Heading shown in the emoji picker when a search query returns no matching emojis.'
238
- },
239
- emojiPickerAddCustomEmoji: {
240
- id: 'fabric.emoji.picker.add.custom.emoji',
241
- defaultMessage: 'Add custom emoji',
242
- description: 'Label for the button shown in the emoji picker no-results screen that opens the custom emoji upload panel.'
243
- },
244
234
  emojiPickerTitle: {
245
235
  id: 'fabric.emoji.picker',
246
236
  defaultMessage: 'Emoji picker',
@@ -21,16 +21,13 @@
21
21
  ._1xi2idpf{right:0}
22
22
  ._2lx21bp4{flex-direction:column}
23
23
  ._4t3i1784{height:470px}
24
- ._4t3i19lm{height:514px}
25
24
  ._4t3i1ckg{height:455px}
26
25
  ._4t3i1dsu{height:419px}
27
- ._4t3i1j8x{height:354px}
28
26
  ._4t3i1sa4{height:390px}
29
27
  ._4t3i2300{height:429px}
30
28
  ._4t3i50k7{height:499px}
31
29
  ._4t3iaq3k{height:295px}
32
30
  ._4t3ibqjm{height:310px}
33
- ._4t3iihnn{height:434px}
34
31
  ._4t3iixjv{height:375px}
35
32
  ._4t3iqbeb{height:339px}
36
33
  ._4t3iuxo9{height:var(--_19dn98e)}
@@ -76,12 +76,6 @@ var withoutPreviewHeight = {
76
76
  medium: "_4t3iixjv _1tke5x59",
77
77
  large: "_4t3i1ckg _1tke1pna"
78
78
  };
79
- var emojiPickerHeightNoResults = 354;
80
- var withNoResultsRefreshHeight = {
81
- small: "_4t3i1j8x _1tkegx0z",
82
- medium: "_4t3iihnn _1tke5x59",
83
- large: "_4t3i19lm _1tke1pna"
84
- };
85
79
  var FREQUENTLY_USED_MAX = 16;
86
80
  var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
87
81
  var onSelection = _ref.onSelection,
@@ -156,7 +150,6 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
156
150
  }, []);
157
151
  var openTime = (0, _react.useRef)(0);
158
152
  var isMounting = (0, _react.useRef)(true);
159
- var lastNonSearchCategory = (0, _react.useRef)(activeCategory);
160
153
  var previousEmojiProvider = (0, _react.useRef)(emojiProvider);
161
154
  var isProgrammaticScroll = (0, _react.useRef)(false);
162
155
  var pickerRef = (0, _react.useRef)(null);
@@ -198,11 +191,8 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
198
191
  }
199
192
  if (activeCategory !== category) {
200
193
  setActiveCategory(category);
201
- if (!query && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh')) {
202
- lastNonSearchCategory.current = category;
203
- }
204
194
  }
205
- }, [activeCategory, uploading, emojiToDelete, query]);
195
+ }, [activeCategory, uploading, emojiToDelete]);
206
196
  var calculateElapsedTime = function calculateElapsedTime() {
207
197
  return Date.now() - openTime.current;
208
198
  };
@@ -419,10 +409,6 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
419
409
  source: _types.SearchSourceTypes.PICKER
420
410
  };
421
411
  if (searchQuery !== query) {
422
- // Capture the active category before entering search so we can keep it highlighted
423
- if (!query && searchQuery && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh')) {
424
- lastNonSearchCategory.current = activeCategory;
425
- }
426
412
  setQuery(searchQuery);
427
413
  }
428
414
  updateEmojis(searchQuery, options);
@@ -430,7 +416,7 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
430
416
  // scroll to top when search, which is search results section
431
417
  scrollToTopOfList();
432
418
  }
433
- }, [activeCategory, query, filteredEmojis, selectedTone, updateEmojis, scrollToTopOfList]);
419
+ }, [query, filteredEmojis, selectedTone, updateEmojis, scrollToTopOfList]);
434
420
 
435
421
  // When the upload screen is open, intercept any file drag at the window level so it
436
422
  // cannot reach underlying page drop handlers (e.g. the Confluence editor).
@@ -651,7 +637,7 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
651
637
  role: "dialog",
652
638
  "aria-label": formatMessage(_i18n.messages.emojiPickerTitle),
653
639
  "aria-modal": true,
654
- className: (0, _runtime.ax)([(0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? "_19itahnd _2rko1mok _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm" : "_19itahnd _2rkofajl _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm", !!emojiToDelete && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? withDeleteRefreshHeight[size] : uploading && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? withUploadRefreshHeight[size] : query && filteredEmojis.length === 0 && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? withNoResultsRefreshHeight[size] : showPreview ? withPreviewHeight[size] : withoutPreviewHeight[size]]),
640
+ className: (0, _runtime.ax)([(0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? "_19itahnd _2rko1mok _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm" : "_19itahnd _2rkofajl _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm", !!emojiToDelete && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? withDeleteRefreshHeight[size] : uploading && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? withUploadRefreshHeight[size] : showPreview ? withPreviewHeight[size] : withoutPreviewHeight[size]]),
655
641
  style: {
656
642
  "--_19dn98e": (0, _runtime.ix)("".concat(emojiPickerHeight, "px")),
657
643
  "--_gsvyy7": (0, _runtime.ix)("".concat(emojiPickerWidth, "px"))
@@ -696,7 +682,7 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
696
682
  onOpenUpload: onOpenUpload,
697
683
  size: size,
698
684
  activeCategoryId: activeCategory
699
- }), showPreview && !(emojiToDelete && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh')) && !(query && filteredEmojis.length === 0 && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh')) && /*#__PURE__*/React.createElement(_EmojiPickerFooter.default, {
685
+ }), showPreview && !(emojiToDelete && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh')) && /*#__PURE__*/React.createElement(_EmojiPickerFooter.default, {
700
686
  selectedEmoji: selectedEmoji,
701
687
  uploadEnabled: isUploadSupported && !uploading,
702
688
  onOpenUpload: onOpenUpload
@@ -711,7 +697,7 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
711
697
  onKeyPress: suppressKeyPress,
712
698
  onKeyUp: suppressKeyPress,
713
699
  onKeyDown: suppressKeyPress,
714
- className: (0, _runtime.ax)([(0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? "_19itahnd _2rko1mok _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm" : "_19itahnd _2rkofajl _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm", !!emojiToDelete && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? withDeleteRefreshHeight[size] : uploading && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? withUploadRefreshHeight[size] : query && filteredEmojis.length === 0 && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? withNoResultsRefreshHeight[size] : showPreview ? withPreviewHeight[size] : withoutPreviewHeight[size]]),
700
+ className: (0, _runtime.ax)([(0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? "_19itahnd _2rko1mok _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm" : "_19itahnd _2rkofajl _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm", !!emojiToDelete && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? withDeleteRefreshHeight[size] : uploading && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? withUploadRefreshHeight[size] : showPreview ? withPreviewHeight[size] : withoutPreviewHeight[size]]),
715
701
  style: {
716
702
  "--_19dn98e": (0, _runtime.ix)("".concat(emojiPickerHeight, "px")),
717
703
  "--_gsvyy7": (0, _runtime.ix)("".concat(emojiPickerWidth, "px"))
@@ -750,7 +736,7 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
750
736
  onOpenUpload: onOpenUpload,
751
737
  size: size,
752
738
  activeCategoryId: activeCategory
753
- }), showPreview && !(emojiToDelete && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh')) && !(query && filteredEmojis.length === 0 && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh')) && /*#__PURE__*/React.createElement(_EmojiPickerFooter.default, {
739
+ }), showPreview && !(emojiToDelete && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh')) && /*#__PURE__*/React.createElement(_EmojiPickerFooter.default, {
754
740
  selectedEmoji: selectedEmoji,
755
741
  uploadEnabled: isUploadSupported && !uploading,
756
742
  onOpenUpload: onOpenUpload
@@ -8,7 +8,6 @@ Object.defineProperty(exports, "__esModule", {
8
8
  exports.RENDER_EMOJI_PICKER_LIST_TESTID = exports.EmojiPickerVirtualListInternal = void 0;
9
9
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
10
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
- var _reactIntl = require("react-intl");
12
11
  var _react = _interopRequireWildcard(require("react"));
13
12
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
13
  var _constants = require("../../util/constants");
@@ -21,7 +20,6 @@ var _utils = require("./utils");
21
20
  var _VirtualList = require("./VirtualList");
22
21
  var _EmojiPickerListContext = require("../../context/EmojiPickerListContext");
23
22
  var _EmojiPickerTabPanel = _interopRequireDefault(require("./EmojiPickerTabPanel"));
24
- var _i18n = require("../i18n");
25
23
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
26
24
  /**
27
25
  * Test id for wrapper Emoji Picker List div
@@ -70,8 +68,6 @@ var EmojiPickerVirtualListInternal = exports.EmojiPickerVirtualListInternal = /*
70
68
  onFileChooserClicked = props.onFileChooserClicked,
71
69
  onOpenUpload = props.onOpenUpload,
72
70
  activeCategoryId = props.activeCategoryId;
73
- var _useIntl = (0, _reactIntl.useIntl)(),
74
- formatMessage = _useIntl.formatMessage;
75
71
  var listRef = (0, _react.useRef)(null);
76
72
  var _useState = (0, _react.useState)([]),
77
73
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
@@ -189,27 +185,14 @@ var EmojiPickerVirtualListInternal = exports.EmojiPickerVirtualListInternal = /*
189
185
  items.push(new _EmojiPickerVirtualItems.LoadingItem());
190
186
  } else {
191
187
  if (query) {
192
- var search = (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? _categories.CategoryDescriptionMapNew.SEARCH : _categories.CategoryDescriptionMap.SEARCH;
193
- if (emojis.length === 0 && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh')) {
194
- // Show a "No results" category heading, then a no-results illustration below it
195
- items.push(new _EmojiPickerVirtualItems.CategoryHeadingItem({
196
- id: _constants.searchCategory,
197
- title: formatMessage(_i18n.messages.emojiPickerNoResults),
198
- className: categoryClassname
199
- }));
200
- items.push(new _EmojiPickerVirtualItems.NoResultsItem({
201
- onOpenUpload: onOpenUpload,
202
- uploadEnabled: uploadEnabled
203
- }));
204
- } else {
205
- // Only a single "result" category
206
- items = [].concat((0, _toConsumableArray2.default)(items), (0, _toConsumableArray2.default)(buildVirtualItemFromGroup({
207
- category: _constants.searchCategory,
208
- title: search.name,
209
- emojis: emojis,
210
- order: search.order
211
- })));
212
- }
188
+ var search = _categories.CategoryDescriptionMap.SEARCH;
189
+ // Only a single "result" category
190
+ items = [].concat((0, _toConsumableArray2.default)(items), (0, _toConsumableArray2.default)(buildVirtualItemFromGroup({
191
+ category: _constants.searchCategory,
192
+ title: search.name,
193
+ emojis: emojis,
194
+ order: search.order
195
+ })));
213
196
  } else {
214
197
  // Group by category
215
198
 
@@ -234,7 +217,7 @@ var EmojiPickerVirtualListInternal = exports.EmojiPickerVirtualListInternal = /*
234
217
  }
235
218
  }
236
219
  // eslint-disable-next-line react-hooks/exhaustive-deps
237
- }, [allEmojiGroups, loading, query, emojis, onOpenUpload, uploadEnabled, formatMessage]);
220
+ }, [allEmojiGroups, loading, query, emojis]);
238
221
  var findCategoryToActivate = function findCategoryToActivate(row) {
239
222
  var category = null;
240
223
  if (row instanceof _EmojiPickerVirtualItems.CategoryHeadingItem) {
@@ -344,12 +327,8 @@ var EmojiPickerVirtualListInternal = exports.EmojiPickerVirtualListInternal = /*
344
327
  // eslint-disable-next-line react-hooks/exhaustive-deps
345
328
  }, [virtualItems, categoriesChanged]);
346
329
  var virtualListHeight = (0, _react.useMemo)(function () {
347
- if (query && emojis.length === 0 && (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh')) {
348
- // No-results state: expand the list height to fit heading + illustration without scrolling
349
- return _EmojiPickerSizes.sizes.categoryHeadingHeight + _EmojiPickerSizes.sizes.noResultsHeight + (0, _utils.emojiPickerHeightOffset)(size);
350
- }
351
330
  return (0, _platformFeatureFlags.fg)('platform_emoji_picker_refresh') ? _EmojiPickerSizes.sizes.listHeightNew + (0, _utils.emojiPickerHeightOffset)(size) : _EmojiPickerSizes.sizes.listHeight + (0, _utils.emojiPickerHeightOffset)(size);
352
- }, [size, query, emojis.length]);
331
+ }, [size]);
353
332
  return /*#__PURE__*/_react.default.createElement(_EmojiPickerTabPanel.default, {
354
333
  showSearchResults: !!query
355
334
  }, /*#__PURE__*/_react.default.createElement(_EmojiActions.default, {
@@ -19,8 +19,6 @@ var sizes = exports.sizes = {
19
19
  // 32px height
20
20
  loadingRowHeight: 150,
21
21
  // Fills remaining space without scrolling when loading.
22
- noResultsHeight: 300,
23
- // illustration (200px) + button + padding + gap
24
22
  uploadActionHeight: 40,
25
23
  // 40px height
26
24
  emojiPerRow: 8
@@ -6,7 +6,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
6
6
  Object.defineProperty(exports, "__esModule", {
7
7
  value: true
8
8
  });
9
- exports.virtualItemRenderer = exports.NoResultsItem = exports.LoadingItem = exports.EmojisRowItem = exports.CategoryHeadingItem = exports.AbstractItem = void 0;
9
+ exports.virtualItemRenderer = exports.LoadingItem = exports.EmojisRowItem = exports.CategoryHeadingItem = exports.AbstractItem = void 0;
10
10
  require("./EmojiPickerVirtualItems.compiled.css");
11
11
  var React = _interopRequireWildcard(require("react"));
12
12
  var _runtime = require("@compiled/react/runtime");
@@ -20,7 +20,6 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/cl
20
20
  var _spinner = _interopRequireDefault(require("@atlaskit/spinner"));
21
21
  var _EmojiPickerCategoryHeading = _interopRequireDefault(require("./EmojiPickerCategoryHeading"));
22
22
  var _EmojiPickerEmojiRow = _interopRequireDefault(require("./EmojiPickerEmojiRow"));
23
- var _EmojiPickerNoResults = _interopRequireDefault(require("./EmojiPickerNoResults"));
24
23
  var _EmojiPickerSizes = require("./EmojiPickerSizes");
25
24
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
26
25
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
@@ -76,19 +75,6 @@ var CategoryHeadingItem = exports.CategoryHeadingItem = /*#__PURE__*/function (_
76
75
  (0, _inherits2.default)(CategoryHeadingItem, _AbstractItem3);
77
76
  return (0, _createClass2.default)(CategoryHeadingItem);
78
77
  }(AbstractItem);
79
- var NoResultsItem = exports.NoResultsItem = /*#__PURE__*/function (_AbstractItem4) {
80
- function NoResultsItem(props) {
81
- var _this4;
82
- (0, _classCallCheck2.default)(this, NoResultsItem);
83
- _this4 = _callSuper(this, NoResultsItem, [props, _EmojiPickerSizes.sizes.noResultsHeight]);
84
- (0, _defineProperty2.default)(_this4, "renderItem", function () {
85
- return /*#__PURE__*/React.createElement(_EmojiPickerNoResults.default, _this4.props);
86
- });
87
- return _this4;
88
- }
89
- (0, _inherits2.default)(NoResultsItem, _AbstractItem4);
90
- return (0, _createClass2.default)(NoResultsItem);
91
- }(AbstractItem);
92
78
  var virtualItemRenderer = exports.virtualItemRenderer = function virtualItemRenderer(rows, context) {
93
79
  var index = context.index,
94
80
  key = context.key;
@@ -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: "70.11.1"
23
+ packageVersion: "70.12.0"
24
24
  }, attributes)
25
25
  };
26
26
  };
@@ -1,7 +1,10 @@
1
1
  import { utils as serviceUtils } from '@atlaskit/util-service-support';
2
2
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
3
+ import { ProviderTypes } from '../types';
3
4
  import { isImageRepresentation, isSpriteServiceRepresentation, convertImageToMediaRepresentation, buildEmojiDescriptionWithAltRepresentation } from '../util/type-helpers';
4
5
  import debug from '../util/logger';
6
+ import { fg } from '@atlaskit/platform-feature-flags';
7
+ import { emojiIdToEmoji } from '../util/emojiIdToEmoji';
5
8
  export const emojiRequest = (provider, options) => {
6
9
  const {
7
10
  getRatio = getPixelRatio,
@@ -131,7 +134,11 @@ export const denormaliseSkinEmoji = (emoji, meta) => {
131
134
  */
132
135
  export const denormaliseEmojiServiceResponse = emojiData => {
133
136
  const emojis = emojiData.emojis.map(emoji => {
134
- const newRepresentation = denormaliseServiceRepresentation(emoji.representation, emojiData.meta);
137
+ const unicodeEmoji = emojiIdToEmoji(emoji.id);
138
+ const useUnicodeRepresentation = !!(emoji.id && emoji.type === ProviderTypes.STANDARD && unicodeEmoji && fg('platform_twemoji_removal_unicode_emojis'));
139
+ const newRepresentation = useUnicodeRepresentation ? {
140
+ unicodeEmoji
141
+ } : denormaliseServiceRepresentation(emoji.representation, emojiData.meta);
135
142
  const altRepresentation = denormaliseServiceAltRepresentation(emoji.altRepresentations, emojiData.meta);
136
143
  const newSkinVariations = denormaliseSkinEmoji(emoji, emojiData.meta);
137
144
 
@@ -225,16 +225,6 @@ export const messages = defineMessages({
225
225
  defaultMessage: 'An emoji with this name exists already',
226
226
  description: 'Error message shown when the user tries to upload an emoji with a name that already exists in the custom emoji set'
227
227
  },
228
- emojiPickerNoResults: {
229
- id: 'fabric.emoji.picker.no.results',
230
- defaultMessage: 'No results',
231
- description: 'Heading shown in the emoji picker when a search query returns no matching emojis.'
232
- },
233
- emojiPickerAddCustomEmoji: {
234
- id: 'fabric.emoji.picker.add.custom.emoji',
235
- defaultMessage: 'Add custom emoji',
236
- description: 'Label for the button shown in the emoji picker no-results screen that opens the custom emoji upload panel.'
237
- },
238
228
  emojiPickerTitle: {
239
229
  id: 'fabric.emoji.picker',
240
230
  defaultMessage: 'Emoji picker',
@@ -21,16 +21,13 @@
21
21
  ._1xi2idpf{right:0}
22
22
  ._2lx21bp4{flex-direction:column}
23
23
  ._4t3i1784{height:470px}
24
- ._4t3i19lm{height:514px}
25
24
  ._4t3i1ckg{height:455px}
26
25
  ._4t3i1dsu{height:419px}
27
- ._4t3i1j8x{height:354px}
28
26
  ._4t3i1sa4{height:390px}
29
27
  ._4t3i2300{height:429px}
30
28
  ._4t3i50k7{height:499px}
31
29
  ._4t3iaq3k{height:295px}
32
30
  ._4t3ibqjm{height:310px}
33
- ._4t3iihnn{height:434px}
34
31
  ._4t3iixjv{height:375px}
35
32
  ._4t3iqbeb{height:339px}
36
33
  ._4t3ivixp{height:349px}
@@ -60,12 +60,6 @@ const withoutPreviewHeight = {
60
60
  medium: "_4t3iixjv _1tke5x59",
61
61
  large: "_4t3i1ckg _1tke1pna"
62
62
  };
63
- const emojiPickerHeightNoResults = 354;
64
- const withNoResultsRefreshHeight = {
65
- small: "_4t3i1j8x _1tkegx0z",
66
- medium: "_4t3iihnn _1tke5x59",
67
- large: "_4t3i19lm _1tke1pna"
68
- };
69
63
  const FREQUENTLY_USED_MAX = 16;
70
64
  const EmojiPickerComponent = ({
71
65
  onSelection,
@@ -98,7 +92,6 @@ const EmojiPickerComponent = ({
98
92
  const emojiPickerList = useMemo(() => /*#__PURE__*/createRef(), []);
99
93
  const openTime = useRef(0);
100
94
  const isMounting = useRef(true);
101
- const lastNonSearchCategory = useRef(activeCategory);
102
95
  const previousEmojiProvider = useRef(emojiProvider);
103
96
  const isProgrammaticScroll = useRef(false);
104
97
  const pickerRef = useRef(null);
@@ -140,11 +133,8 @@ const EmojiPickerComponent = ({
140
133
  }
141
134
  if (activeCategory !== category) {
142
135
  setActiveCategory(category);
143
- if (!query && fg('platform_emoji_picker_refresh')) {
144
- lastNonSearchCategory.current = category;
145
- }
146
136
  }
147
- }, [activeCategory, uploading, emojiToDelete, query]);
137
+ }, [activeCategory, uploading, emojiToDelete]);
148
138
  const calculateElapsedTime = () => {
149
139
  return Date.now() - openTime.current;
150
140
  };
@@ -357,10 +347,6 @@ const EmojiPickerComponent = ({
357
347
  source: SearchSourceTypes.PICKER
358
348
  };
359
349
  if (searchQuery !== query) {
360
- // Capture the active category before entering search so we can keep it highlighted
361
- if (!query && searchQuery && fg('platform_emoji_picker_refresh')) {
362
- lastNonSearchCategory.current = activeCategory;
363
- }
364
350
  setQuery(searchQuery);
365
351
  }
366
352
  updateEmojis(searchQuery, options);
@@ -368,7 +354,7 @@ const EmojiPickerComponent = ({
368
354
  // scroll to top when search, which is search results section
369
355
  scrollToTopOfList();
370
356
  }
371
- }, [activeCategory, query, filteredEmojis, selectedTone, updateEmojis, scrollToTopOfList]);
357
+ }, [query, filteredEmojis, selectedTone, updateEmojis, scrollToTopOfList]);
372
358
 
373
359
  // When the upload screen is open, intercept any file drag at the window level so it
374
360
  // cannot reach underlying page drop handlers (e.g. the Confluence editor).
@@ -561,7 +547,7 @@ const EmojiPickerComponent = ({
561
547
  role: "dialog",
562
548
  "aria-label": formatMessage(messages.emojiPickerTitle),
563
549
  "aria-modal": true,
564
- className: ax([fg('platform_emoji_picker_refresh') ? "_19itahnd _2rko1mok _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iaq3k _1bsb1edt _1ul91edt _c71l1y6z _kqswh2mm" : "_19itahnd _2rkofajl _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iaq3k _1bsb1edt _1ul91edt _c71l1y6z _kqswh2mm", !!emojiToDelete && fg('platform_emoji_picker_refresh') ? withDeleteRefreshHeight[size] : uploading && fg('platform_emoji_picker_refresh') ? withUploadRefreshHeight[size] : query && filteredEmojis.length === 0 && fg('platform_emoji_picker_refresh') ? withNoResultsRefreshHeight[size] : showPreview ? withPreviewHeight[size] : withoutPreviewHeight[size]])
550
+ className: ax([fg('platform_emoji_picker_refresh') ? "_19itahnd _2rko1mok _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iaq3k _1bsb1edt _1ul91edt _c71l1y6z _kqswh2mm" : "_19itahnd _2rkofajl _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iaq3k _1bsb1edt _1ul91edt _c71l1y6z _kqswh2mm", !!emojiToDelete && fg('platform_emoji_picker_refresh') ? withDeleteRefreshHeight[size] : uploading && fg('platform_emoji_picker_refresh') ? withUploadRefreshHeight[size] : showPreview ? withPreviewHeight[size] : withoutPreviewHeight[size]])
565
551
  }, /*#__PURE__*/React.createElement("div", {
566
552
  role: "presentation",
567
553
  onKeyPress: suppressKeyPress,
@@ -602,7 +588,7 @@ const EmojiPickerComponent = ({
602
588
  onOpenUpload: onOpenUpload,
603
589
  size: size,
604
590
  activeCategoryId: activeCategory
605
- }), showPreview && !(emojiToDelete && fg('platform_emoji_picker_refresh')) && !(query && filteredEmojis.length === 0 && fg('platform_emoji_picker_refresh')) && /*#__PURE__*/React.createElement(EmojiPickerFooter, {
591
+ }), showPreview && !(emojiToDelete && fg('platform_emoji_picker_refresh')) && /*#__PURE__*/React.createElement(EmojiPickerFooter, {
606
592
  selectedEmoji: selectedEmoji,
607
593
  uploadEnabled: isUploadSupported && !uploading,
608
594
  onOpenUpload: onOpenUpload
@@ -617,7 +603,7 @@ const EmojiPickerComponent = ({
617
603
  onKeyPress: suppressKeyPress,
618
604
  onKeyUp: suppressKeyPress,
619
605
  onKeyDown: suppressKeyPress,
620
- className: ax([fg('platform_emoji_picker_refresh') ? "_19itahnd _2rko1mok _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iaq3k _1bsb1edt _1ul91edt _c71l1y6z _kqswh2mm" : "_19itahnd _2rkofajl _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iaq3k _1bsb1edt _1ul91edt _c71l1y6z _kqswh2mm", !!emojiToDelete && fg('platform_emoji_picker_refresh') ? withDeleteRefreshHeight[size] : uploading && fg('platform_emoji_picker_refresh') ? withUploadRefreshHeight[size] : query && filteredEmojis.length === 0 && fg('platform_emoji_picker_refresh') ? withNoResultsRefreshHeight[size] : showPreview ? withPreviewHeight[size] : withoutPreviewHeight[size]])
606
+ className: ax([fg('platform_emoji_picker_refresh') ? "_19itahnd _2rko1mok _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iaq3k _1bsb1edt _1ul91edt _c71l1y6z _kqswh2mm" : "_19itahnd _2rkofajl _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iaq3k _1bsb1edt _1ul91edt _c71l1y6z _kqswh2mm", !!emojiToDelete && fg('platform_emoji_picker_refresh') ? withDeleteRefreshHeight[size] : uploading && fg('platform_emoji_picker_refresh') ? withUploadRefreshHeight[size] : showPreview ? withPreviewHeight[size] : withoutPreviewHeight[size]])
621
607
  }, /*#__PURE__*/React.createElement(CategorySelector, {
622
608
  activeCategoryId: (uploading || emojiToDelete) && fg('platform_emoji_picker_refresh') ? null : activeCategory,
623
609
  dynamicCategories: dynamicCategories,
@@ -652,7 +638,7 @@ const EmojiPickerComponent = ({
652
638
  onOpenUpload: onOpenUpload,
653
639
  size: size,
654
640
  activeCategoryId: activeCategory
655
- }), showPreview && !(emojiToDelete && fg('platform_emoji_picker_refresh')) && !(query && filteredEmojis.length === 0 && fg('platform_emoji_picker_refresh')) && /*#__PURE__*/React.createElement(EmojiPickerFooter, {
641
+ }), showPreview && !(emojiToDelete && fg('platform_emoji_picker_refresh')) && /*#__PURE__*/React.createElement(EmojiPickerFooter, {
656
642
  selectedEmoji: selectedEmoji,
657
643
  uploadEnabled: isUploadSupported && !uploading,
658
644
  onOpenUpload: onOpenUpload
@@ -1,17 +1,15 @@
1
- import { useIntl } from 'react-intl';
2
1
  import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
3
2
  import { fg } from '@atlaskit/platform-feature-flags';
4
3
  import { customCategory, defaultEmojiPickerSize, frequentCategory, searchCategory, userCustomTitle, yourUploadsCategory } from '../../util/constants';
5
4
  import { CategoryDescriptionMap, CategoryDescriptionMapNew } from './categories';
6
5
  import CategoryTracker from './CategoryTracker';
7
6
  import { sizes } from './EmojiPickerSizes';
8
- import { CategoryHeadingItem, EmojisRowItem, LoadingItem, NoResultsItem, virtualItemRenderer } from './EmojiPickerVirtualItems';
7
+ import { CategoryHeadingItem, EmojisRowItem, LoadingItem, virtualItemRenderer } from './EmojiPickerVirtualItems';
9
8
  import EmojiActions from '../common/EmojiActions';
10
9
  import { emojiPickerHeightOffset, scrollToRow } from './utils';
11
10
  import { VirtualList } from './VirtualList';
12
11
  import { EmojiPickerListContextProvider } from '../../context/EmojiPickerListContext';
13
12
  import EmojiPickerTabPanel from './EmojiPickerTabPanel';
14
- import { messages } from '../i18n';
15
13
 
16
14
  /**
17
15
  * Test id for wrapper Emoji Picker List div
@@ -54,9 +52,6 @@ export const EmojiPickerVirtualListInternal = /*#__PURE__*/React.forwardRef((pro
54
52
  onOpenUpload,
55
53
  activeCategoryId
56
54
  } = props;
57
- const {
58
- formatMessage
59
- } = useIntl();
60
55
  const listRef = useRef(null);
61
56
  const [allEmojiGroups, setAllEmojiGroups] = useState([]);
62
57
  const [virtualItems, setVirtualItems] = useState([]);
@@ -158,27 +153,14 @@ export const EmojiPickerVirtualListInternal = /*#__PURE__*/React.forwardRef((pro
158
153
  items.push(new LoadingItem());
159
154
  } else {
160
155
  if (query) {
161
- const search = fg('platform_emoji_picker_refresh') ? CategoryDescriptionMapNew.SEARCH : CategoryDescriptionMap.SEARCH;
162
- if (emojis.length === 0 && fg('platform_emoji_picker_refresh')) {
163
- // Show a "No results" category heading, then a no-results illustration below it
164
- items.push(new CategoryHeadingItem({
165
- id: searchCategory,
166
- title: formatMessage(messages.emojiPickerNoResults),
167
- className: categoryClassname
168
- }));
169
- items.push(new NoResultsItem({
170
- onOpenUpload,
171
- uploadEnabled
172
- }));
173
- } else {
174
- // Only a single "result" category
175
- items = [...items, ...buildVirtualItemFromGroup({
176
- category: searchCategory,
177
- title: search.name,
178
- emojis,
179
- order: search.order
180
- })];
181
- }
156
+ const search = CategoryDescriptionMap.SEARCH;
157
+ // Only a single "result" category
158
+ items = [...items, ...buildVirtualItemFromGroup({
159
+ category: searchCategory,
160
+ title: search.name,
161
+ emojis,
162
+ order: search.order
163
+ })];
182
164
  } else {
183
165
  // Group by category
184
166
 
@@ -203,7 +185,7 @@ export const EmojiPickerVirtualListInternal = /*#__PURE__*/React.forwardRef((pro
203
185
  }
204
186
  }
205
187
  // eslint-disable-next-line react-hooks/exhaustive-deps
206
- }, [allEmojiGroups, loading, query, emojis, onOpenUpload, uploadEnabled, formatMessage]);
188
+ }, [allEmojiGroups, loading, query, emojis]);
207
189
  const findCategoryToActivate = row => {
208
190
  let category = null;
209
191
  if (row instanceof CategoryHeadingItem) {
@@ -312,12 +294,8 @@ export const EmojiPickerVirtualListInternal = /*#__PURE__*/React.forwardRef((pro
312
294
  // eslint-disable-next-line react-hooks/exhaustive-deps
313
295
  }, [virtualItems, categoriesChanged]);
314
296
  const virtualListHeight = useMemo(() => {
315
- if (query && emojis.length === 0 && fg('platform_emoji_picker_refresh')) {
316
- // No-results state: expand the list height to fit heading + illustration without scrolling
317
- return sizes.categoryHeadingHeight + sizes.noResultsHeight + emojiPickerHeightOffset(size);
318
- }
319
297
  return fg('platform_emoji_picker_refresh') ? sizes.listHeightNew + emojiPickerHeightOffset(size) : sizes.listHeight + emojiPickerHeightOffset(size);
320
- }, [size, query, emojis.length]);
298
+ }, [size]);
321
299
  return /*#__PURE__*/React.createElement(EmojiPickerTabPanel, {
322
300
  showSearchResults: !!query
323
301
  }, /*#__PURE__*/React.createElement(EmojiActions, {
@@ -13,8 +13,6 @@ export const sizes = {
13
13
  // 32px height
14
14
  loadingRowHeight: 150,
15
15
  // Fills remaining space without scrolling when loading.
16
- noResultsHeight: 300,
17
- // illustration (200px) + button + padding + gap
18
16
  uploadActionHeight: 40,
19
17
  // 40px height
20
18
  emojiPerRow: 8
@@ -7,7 +7,6 @@ import { ax, ix } from "@compiled/react/runtime";
7
7
  import Spinner from '@atlaskit/spinner';
8
8
  import EmojiPickerCategoryHeading from './EmojiPickerCategoryHeading';
9
9
  import EmojiPickerEmojiRow from './EmojiPickerEmojiRow';
10
- import EmojiPickerNoResults from './EmojiPickerNoResults';
11
10
  import { sizes } from './EmojiPickerSizes';
12
11
  const emojiPickerSpinner = null;
13
12
  export class AbstractItem {
@@ -40,12 +39,6 @@ export class CategoryHeadingItem extends AbstractItem {
40
39
  _defineProperty(this, "renderItem", () => /*#__PURE__*/React.createElement(EmojiPickerCategoryHeading, this.props));
41
40
  }
42
41
  }
43
- export class NoResultsItem extends AbstractItem {
44
- constructor(props) {
45
- super(props, sizes.noResultsHeight);
46
- _defineProperty(this, "renderItem", () => /*#__PURE__*/React.createElement(EmojiPickerNoResults, this.props));
47
- }
48
- }
49
42
  export const virtualItemRenderer = (rows, context) => {
50
43
  const {
51
44
  index,
@@ -9,7 +9,7 @@ const createEvent = (eventType, action, actionSubject, actionSubjectId, attribut
9
9
  actionSubjectId,
10
10
  attributes: {
11
11
  packageName: "@atlaskit/emoji",
12
- packageVersion: "70.11.1",
12
+ packageVersion: "70.12.0",
13
13
  ...attributes
14
14
  }
15
15
  });