@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
@@ -41,6 +41,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
41
41
  _classCallCheck(this, EmojiResource);
42
42
  _this = _super.call(this);
43
43
  _defineProperty(_assertThisInitialized(_this), "activeLoaders", 0);
44
+ _defineProperty(_assertThisInitialized(_this), "initialLoaders", 0);
44
45
  _defineProperty(_assertThisInitialized(_this), "retries", new Map());
45
46
  _defineProperty(_assertThisInitialized(_this), "isInitialised", false);
46
47
  _defineProperty(_assertThisInitialized(_this), "getOptimisticImageURL", function (emojiId) {
@@ -49,8 +50,11 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
49
50
  }
50
51
  return;
51
52
  });
53
+ _defineProperty(_assertThisInitialized(_this), "isRepositoryAvailable", function (repository) {
54
+ return !!repository;
55
+ });
52
56
  _defineProperty(_assertThisInitialized(_this), "isLoaded", function () {
53
- return _this.activeLoaders === 0 && !!_this.emojiRepository;
57
+ return _this.initialLoaders !== 0 && _this.activeLoaders === 0;
54
58
  });
55
59
  _this.emojiProviderConfig = config;
56
60
  _this.recordConfig = config.recordConfig;
@@ -61,6 +65,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
61
65
  if (config.providers.length === 0) {
62
66
  throw new Error('No providers specified');
63
67
  }
68
+ _this.initialLoaders = _this.emojiProviderConfig.providers.length;
64
69
  _this.activeLoaders = _this.emojiProviderConfig.providers.length;
65
70
  _this.emojiResponses = [];
66
71
  return _this;
@@ -184,7 +189,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
184
189
  switch (_context3.prev = _context3.next) {
185
190
  case 0:
186
191
  force = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : false;
187
- if (!(force || !this.emojiRepository && !this.isInitialised)) {
192
+ if (!(force || !this.isRepositoryAvailable(this.emojiRepository) && !this.isInitialised)) {
188
193
  _context3.next = 6;
189
194
  break;
190
195
  }
@@ -218,7 +223,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
218
223
  while (1) {
219
224
  switch (_context4.prev = _context4.next) {
220
225
  case 0:
221
- if (!(this.emojiRepository && this.isLoaded())) {
226
+ if (!(this.isLoaded() && this.isRepositoryAvailable(this.emojiRepository))) {
222
227
  _context4.next = 8;
223
228
  break;
224
229
  }
@@ -256,7 +261,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
256
261
  }
257
262
  return _context4.abrupt("return");
258
263
  case 17:
259
- if (this.siteEmojiResource) {
264
+ if (this.isRepositoryAvailable(this.siteEmojiResource)) {
260
265
  _context4.next = 20;
261
266
  break;
262
267
  }
@@ -326,7 +331,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
326
331
  }, {
327
332
  key: "initSiteEmojiResource",
328
333
  value: function initSiteEmojiResource(emojiResponse, provider) {
329
- if (!this.siteEmojiResource && emojiResponse.mediaApiToken) {
334
+ if (!this.isRepositoryAvailable(this.siteEmojiResource) && emojiResponse.mediaApiToken) {
330
335
  this.siteEmojiResource = new SiteEmojiResource(provider, emojiResponse.mediaApiToken);
331
336
 
332
337
  // Prime cache type + optimistic rendering by checking first Emoji.
@@ -424,7 +429,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
424
429
  while (1) {
425
430
  switch (_context5.prev = _context5.next) {
426
431
  case 0:
427
- if (!(this.siteEmojiResource && isMediaRepresentation(emoji.representation))) {
432
+ if (!(this.isRepositoryAvailable(this.siteEmojiResource) && isMediaRepresentation(emoji.representation))) {
428
433
  _context5.next = 5;
429
434
  break;
430
435
  }
@@ -454,7 +459,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
454
459
  }, {
455
460
  key: "loadMediaEmoji",
456
461
  value: function loadMediaEmoji(emoji, useAlt) {
457
- if (!this.siteEmojiResource || !isMediaEmoji(emoji)) {
462
+ if (!this.isRepositoryAvailable(this.siteEmojiResource) || !isMediaEmoji(emoji)) {
458
463
  return emoji;
459
464
  }
460
465
  return this.siteEmojiResource.loadMediaEmoji(emoji, useAlt);
@@ -465,7 +470,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
465
470
  if (!isMediaEmoji(emoji)) {
466
471
  return true;
467
472
  }
468
- if (!this.siteEmojiResource) {
473
+ if (!this.isRepositoryAvailable(this.siteEmojiResource)) {
469
474
  // Shouldn't have a media emoji without a siteEmojiResouce, but anyway ;)
470
475
  return false;
471
476
  }
@@ -487,7 +492,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
487
492
  query: query,
488
493
  options: options
489
494
  };
490
- if (this.emojiRepository) {
495
+ if (this.isRepositoryAvailable(this.emojiRepository)) {
491
496
  var searchResults = this.emojiRepository.search(query, options);
492
497
  this.notifyResult(searchResults);
493
498
  ufoExperiences['emoji-searched'].success({
@@ -505,7 +510,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
505
510
  key: "findByShortName",
506
511
  value: function findByShortName(shortName) {
507
512
  var _this4 = this;
508
- if (this.isLoaded()) {
513
+ if (this.isLoaded() && this.isRepositoryAvailable(this.emojiRepository)) {
509
514
  // Wait for all emoji to load before looking by shortName (to ensure correct priority)
510
515
  return this.emojiRepository.findByShortName(shortName);
511
516
  }
@@ -519,7 +524,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
519
524
  var _this5 = this;
520
525
  var id = emojiId.id,
521
526
  shortName = emojiId.shortName;
522
- if (this.emojiRepository) {
527
+ if (this.isRepositoryAvailable(this.emojiRepository)) {
523
528
  if (id) {
524
529
  var emoji = this.emojiRepository.findById(id);
525
530
  if (emoji) {
@@ -528,7 +533,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
528
533
  if (this.isLoaded()) {
529
534
  // all loaded but not found by id, try server to see if
530
535
  // this is a newly uploaded emoji
531
- if (this.siteEmojiResource) {
536
+ if (this.isRepositoryAvailable(this.siteEmojiResource)) {
532
537
  return this.siteEmojiResource.findEmoji(emojiId).then(function (emoji) {
533
538
  if (!emoji) {
534
539
  // if not, fallback to searching by shortName to
@@ -557,7 +562,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
557
562
  key: "findById",
558
563
  value: function findById(id) {
559
564
  var _this6 = this;
560
- if (this.isLoaded()) {
565
+ if (this.isLoaded() && this.isRepositoryAvailable(this.emojiRepository)) {
561
566
  return this.emojiRepository.findById(id);
562
567
  }
563
568
  return this.retryIfLoading(function () {
@@ -568,7 +573,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
568
573
  key: "findInCategory",
569
574
  value: function findInCategory(categoryId) {
570
575
  var _this7 = this;
571
- if (this.isLoaded()) {
576
+ if (this.isLoaded() && this.isRepositoryAvailable(this.emojiRepository)) {
572
577
  return Promise.resolve(this.emojiRepository.findInCategory(categoryId));
573
578
  }
574
579
  return this.retryIfLoading(function () {
@@ -579,7 +584,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
579
584
  key: "getAsciiMap",
580
585
  value: function getAsciiMap() {
581
586
  var _this8 = this;
582
- if (this.isLoaded()) {
587
+ if (this.isLoaded() && this.isRepositoryAvailable(this.emojiRepository)) {
583
588
  return Promise.resolve(this.emojiRepository.getAsciiMap());
584
589
  }
585
590
  return this.retryIfLoading(function () {
@@ -590,7 +595,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
590
595
  key: "getFrequentlyUsed",
591
596
  value: function getFrequentlyUsed(options) {
592
597
  var _this9 = this;
593
- if (this.isLoaded()) {
598
+ if (this.isLoaded() && this.isRepositoryAvailable(this.emojiRepository)) {
594
599
  return Promise.resolve(this.emojiRepository.getFrequentlyUsed(options));
595
600
  }
596
601
  return this.retryIfLoading(function () {
@@ -609,7 +614,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
609
614
  key: "recordSelection",
610
615
  value: function recordSelection(emoji) {
611
616
  var recordConfig = this.recordConfig;
612
- if (this.emojiRepository) {
617
+ if (this.isRepositoryAvailable(this.emojiRepository)) {
613
618
  this.emojiRepository.used(emoji);
614
619
  }
615
620
  if (recordConfig) {
@@ -630,9 +635,9 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
630
635
  key: "deleteSiteEmoji",
631
636
  value: function deleteSiteEmoji(emoji) {
632
637
  var _this10 = this;
633
- if (this.siteEmojiResource && emoji.id) {
638
+ if (this.isRepositoryAvailable(this.siteEmojiResource) && emoji.id) {
634
639
  return this.siteEmojiResource.deleteEmoji(emoji).then(function (success) {
635
- if (success && _this10.emojiRepository) {
640
+ if (success && _this10.isRepositoryAvailable(_this10.emojiRepository)) {
636
641
  _this10.emojiRepository.delete(emoji);
637
642
  return true;
638
643
  }
@@ -672,7 +677,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
672
677
  key: "calculateDynamicCategories",
673
678
  value: function calculateDynamicCategories() {
674
679
  var _this11 = this;
675
- if (this.isLoaded()) {
680
+ if (this.isLoaded() && this.isRepositoryAvailable(this.emojiRepository)) {
676
681
  return Promise.resolve(this.emojiRepository.getDynamicCategoryList());
677
682
  }
678
683
  return this.retryIfLoading(function () {
@@ -687,7 +692,7 @@ export var EmojiResource = /*#__PURE__*/function (_ref) {
687
692
  }, {
688
693
  key: "addUnknownEmoji",
689
694
  value: function addUnknownEmoji(emoji) {
690
- if (this.emojiRepository) {
695
+ if (this.isRepositoryAvailable(this.emojiRepository)) {
691
696
  this.emojiRepository.addUnknownEmoji(emoji);
692
697
  }
693
698
  }
@@ -711,7 +716,7 @@ var UploadingEmojiResource = /*#__PURE__*/function (_EmojiResource) {
711
716
  if (!this.allowUpload) {
712
717
  return Promise.resolve(false);
713
718
  }
714
- if (this.siteEmojiResource) {
719
+ if (this.isRepositoryAvailable(this.siteEmojiResource)) {
715
720
  return this.siteEmojiResource.hasUploadToken();
716
721
  }
717
722
  return this.retryIfLoading(function () {
@@ -724,7 +729,7 @@ var UploadingEmojiResource = /*#__PURE__*/function (_EmojiResource) {
724
729
  var _this14 = this;
725
730
  var retry = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
726
731
  return this.isUploadSupported().then(function (supported) {
727
- if (!supported || !_this14.siteEmojiResource) {
732
+ if (!supported || !_this14.isRepositoryAvailable(_this14.siteEmojiResource)) {
728
733
  return Promise.reject('No media api support is configured');
729
734
  }
730
735
  return _this14.siteEmojiResource.uploadEmoji(upload, retry).then(function (emoji) {
@@ -738,7 +743,7 @@ var UploadingEmojiResource = /*#__PURE__*/function (_EmojiResource) {
738
743
  key: "prepareForUpload",
739
744
  value: function prepareForUpload() {
740
745
  var _this15 = this;
741
- if (this.siteEmojiResource) {
746
+ if (this.isRepositoryAvailable(this.siteEmojiResource)) {
742
747
  this.siteEmojiResource.prepareForUpload();
743
748
  }
744
749
  return this.retryIfLoading(function () {
@@ -50,10 +50,10 @@ var TokenManager = /*#__PURE__*/function () {
50
50
  // still valid
51
51
  return Promise.resolve(mediaApiToken);
52
52
  }
53
- if (activeTokenRefresh) {
54
- // refresh token promise already active, return that
55
- return activeTokenRefresh;
56
- }
53
+ }
54
+ if (activeTokenRefresh) {
55
+ // refresh token promise already active, return that
56
+ return activeTokenRefresh;
57
57
  }
58
58
 
59
59
  // request a new token and track the promise for future requests until completed
@@ -1,7 +1,8 @@
1
- import _extends from "@babel/runtime/helpers/extends";
2
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import _extends from "@babel/runtime/helpers/extends";
3
3
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
4
- var _excluded = ["emoji", "placeholderSize", "showTooltip", "fitToHeight", "children"];
4
+ var _excluded = ["emoji", "placeholderSize"],
5
+ _excluded2 = ["emoji", "placeholderSize", "showTooltip", "fitToHeight", "children"];
5
6
  import React, { memo, useEffect, useState } from 'react';
6
7
  import { isMediaEmoji } from '../../util/type-helpers';
7
8
  import { UfoEmojiTimings } from '../../types';
@@ -21,7 +22,9 @@ import { extractErrorInfo } from '../../util/analytics/analytics';
21
22
  export var CachingEmoji = function CachingEmoji(props) {
22
23
  // Optimisation to only render CachingMediaEmoji if necessary
23
24
  // slight performance hit, which accumulates for a large number of emoji.
24
- var emoji = props.emoji;
25
+ var emoji = props.emoji,
26
+ placeholderSize = props.placeholderSize,
27
+ restProps = _objectWithoutProperties(props, _excluded);
25
28
  // start emoji rendered experience, it may have already started earlier in `ResourcedEmoji`.
26
29
  useSampledUFOComponentExperience(ufoExperiences['emoji-rendered'].getInstance(emoji.id || emoji.shortName), SAMPLING_RATE_EMOJI_RENDERED_EXP, {
27
30
  source: 'CachingEmoji',
@@ -35,9 +38,14 @@ export var CachingEmoji = function CachingEmoji(props) {
35
38
  }, []);
36
39
  var emojiNode = function emojiNode() {
37
40
  if (isMediaEmoji(emoji)) {
38
- return /*#__PURE__*/React.createElement(CachingMediaEmoji, props);
41
+ return /*#__PURE__*/React.createElement(CachingMediaEmoji, _extends({
42
+ emoji: emoji,
43
+ placeholderSize: placeholderSize
44
+ }, restProps));
39
45
  }
40
- return /*#__PURE__*/React.createElement(Emoji, props);
46
+ return /*#__PURE__*/React.createElement(Emoji, _extends({
47
+ emoji: emoji
48
+ }, restProps));
41
49
  };
42
50
  return /*#__PURE__*/React.createElement(UfoErrorBoundary, {
43
51
  experiences: [ufoExperiences['emoji-rendered'].getInstance(props.emoji.id || props.emoji.shortName)]
@@ -54,7 +62,7 @@ export var CachingMediaEmoji = function CachingMediaEmoji(props) {
54
62
  showTooltip = props.showTooltip,
55
63
  fitToHeight = props.fitToHeight,
56
64
  children = props.children,
57
- restProps = _objectWithoutProperties(props, _excluded);
65
+ restProps = _objectWithoutProperties(props, _excluded2);
58
66
  var shortName = emoji.shortName,
59
67
  representation = emoji.representation;
60
68
  var _useState = useState(),
@@ -1,6 +1,9 @@
1
- import _extends from "@babel/runtime/helpers/extends";
2
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import _extends from "@babel/runtime/helpers/extends";
3
3
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
5
+ var _excluded = ["emoji", "fitToHeight", "selected", "selectOnHover", "className", "showTooltip", "shouldBeInteractive", "tabIndex", "onSelected", "onMouseMove", "onFocus", "onDelete", "onLoadError", "onLoadSuccess", "showDelete", "disableLazyLoad", "autoWidth"],
6
+ _excluded2 = ["emoji", "fitToHeight", "selected", "selectOnHover", "className", "showTooltip", "showDelete", "shouldBeInteractive", "tabIndex", "onSelected", "onMouseMove", "onFocus", "onDelete", "onLoadError", "onLoadSuccess", "disableLazyLoad", "autoWidth"];
4
7
  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; }
5
8
  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) { _defineProperty(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; }
6
9
  /** @jsx jsx */
@@ -48,6 +51,13 @@ var handleMouseMove = function handleMouseMove(props, event) {
48
51
  onMouseMove(toEmojiId(emoji), emoji, event);
49
52
  }
50
53
  };
54
+ var handleFocus = function handleFocus(props, event) {
55
+ var emoji = props.emoji,
56
+ onFocus = props.onFocus;
57
+ if (onFocus) {
58
+ onFocus(toEmojiId(emoji), emoji, event);
59
+ }
60
+ };
51
61
  var handleDelete = function handleDelete(props, event) {
52
62
  var emoji = props.emoji,
53
63
  onDelete = props.onDelete;
@@ -79,7 +89,19 @@ export var SpriteEmoji = function SpriteEmoji(props) {
79
89
  selectOnHover = props.selectOnHover,
80
90
  className = props.className,
81
91
  showTooltip = props.showTooltip,
82
- shouldBeInteractive = props.shouldBeInteractive;
92
+ _props$shouldBeIntera = props.shouldBeInteractive,
93
+ shouldBeInteractive = _props$shouldBeIntera === void 0 ? false : _props$shouldBeIntera,
94
+ tabIndex = props.tabIndex,
95
+ onSelected = props.onSelected,
96
+ onMouseMove = props.onMouseMove,
97
+ onFocus = props.onFocus,
98
+ onDelete = props.onDelete,
99
+ onLoadError = props.onLoadError,
100
+ onLoadSuccess = props.onLoadSuccess,
101
+ showDelete = props.showDelete,
102
+ disableLazyLoad = props.disableLazyLoad,
103
+ autoWidth = props.autoWidth,
104
+ other = _objectWithoutProperties(props, _excluded);
83
105
  var representation = emoji.representation;
84
106
  var sprite = representation.sprite;
85
107
  var classes = "".concat(emojiNodeStyles, " ").concat(selected ? commonSelectedStyles : '', " ").concat(selectOnHover ? selectOnHoverStyles : '', " ").concat(className ? className : '');
@@ -99,11 +121,11 @@ export var SpriteEmoji = function SpriteEmoji(props) {
99
121
  backgroundPosition: "".concat(xPositionInPercent, "% ").concat(yPositionInPercent, "%"),
100
122
  backgroundSize: "".concat(sprite.column * 100, "% ").concat(sprite.row * 100, "%")
101
123
  }, sizing);
102
- return jsx("span", {
124
+ return jsx("span", _extends({
103
125
  "data-testid": "sprite-emoji-".concat(emoji.shortName),
104
126
  "data-emoji-type": "sprite",
105
- tabIndex: shouldBeInteractive ? 0 : undefined,
106
- role: shouldBeInteractive ? 'button' : undefined,
127
+ tabIndex: shouldBeInteractive ? tabIndex || 0 : undefined,
128
+ role: shouldBeInteractive ? 'button' : 'img',
107
129
  css: emojiContainer,
108
130
  className: classes,
109
131
  onKeyPress: function onKeyPress(event) {
@@ -115,9 +137,12 @@ export var SpriteEmoji = function SpriteEmoji(props) {
115
137
  onMouseEnter: function onMouseEnter(event) {
116
138
  handleMouseMove(props, event);
117
139
  },
140
+ onFocus: function onFocus(event) {
141
+ handleFocus(props, event);
142
+ },
118
143
  "aria-label": emoji.shortName,
119
144
  title: showTooltip ? emoji.shortName : ''
120
- }, jsx("span", {
145
+ }, other), jsx("span", {
121
146
  className: emojiSprite,
122
147
  style: style
123
148
  }, "\xA0"));
@@ -132,10 +157,18 @@ export var ImageEmoji = function ImageEmoji(props) {
132
157
  className = props.className,
133
158
  showTooltip = props.showTooltip,
134
159
  showDelete = props.showDelete,
135
- shouldBeInteractive = props.shouldBeInteractive,
160
+ _props$shouldBeIntera2 = props.shouldBeInteractive,
161
+ shouldBeInteractive = _props$shouldBeIntera2 === void 0 ? false : _props$shouldBeIntera2,
162
+ tabIndex = props.tabIndex,
163
+ onSelected = props.onSelected,
164
+ onMouseMove = props.onMouseMove,
165
+ onFocus = props.onFocus,
166
+ onDelete = props.onDelete,
167
+ onLoadError = props.onLoadError,
136
168
  onLoadSuccess = props.onLoadSuccess,
137
169
  disableLazyLoad = props.disableLazyLoad,
138
- autoWidth = props.autoWidth;
170
+ autoWidth = props.autoWidth,
171
+ other = _objectWithoutProperties(props, _excluded2);
139
172
  var _useInView = useInView({
140
173
  triggerOnce: true
141
174
  }),
@@ -233,12 +266,12 @@ export var ImageEmoji = function ImageEmoji(props) {
233
266
  onError: onError,
234
267
  onLoad: onLoad
235
268
  }, sizing));
236
- return jsx("span", {
269
+ return jsx("span", _extends({
237
270
  "data-testid": "image-emoji-".concat(emoji.shortName),
238
271
  "data-emoji-type": "image",
239
272
  css: emojiStyles,
240
- tabIndex: shouldBeInteractive ? 0 : undefined,
241
- role: shouldBeInteractive ? 'button' : undefined,
273
+ tabIndex: shouldBeInteractive ? tabIndex || 0 : undefined,
274
+ role: shouldBeInteractive ? 'button' : 'img',
242
275
  className: classes,
243
276
  onKeyPress: function onKeyPress(event) {
244
277
  return handleKeyPress(props, event);
@@ -249,10 +282,13 @@ export var ImageEmoji = function ImageEmoji(props) {
249
282
  onMouseEnter: function onMouseEnter(event) {
250
283
  handleMouseMove(props, event);
251
284
  },
285
+ onFocus: function onFocus(event) {
286
+ handleFocus(props, event);
287
+ },
252
288
  "aria-label": emoji.shortName,
253
289
  title: showTooltip ? emoji.shortName : '',
254
290
  ref: ref
255
- }, deleteButton, emojiNode);
291
+ }, other), deleteButton, emojiNode);
256
292
  };
257
293
  export var Emoji = function Emoji(props) {
258
294
  var emoji = props.emoji;
@@ -1,20 +1,21 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  /** @jsx jsx */
4
- import { Fragment, useState } from 'react';
4
+ import { Fragment, useState, useRef, useEffect, memo } from 'react';
5
5
  import { jsx } from '@emotion/react';
6
6
  import { FormattedMessage, injectIntl } from 'react-intl-next';
7
7
  import EmojiDeletePreview from '../common/EmojiDeletePreview';
8
8
  import EmojiUploadPicker from '../common/EmojiUploadPicker';
9
9
  import { EmojiPickerListSearch } from '../picker/EmojiPickerListSearch';
10
10
  import ToneSelector from './ToneSelector';
11
- import EmojiButton from './EmojiButton';
11
+ import TonePreviewButton from './TonePreviewButton';
12
12
  import { messages } from '../i18n';
13
13
  import AkButton from '@atlaskit/button/standard-button';
14
14
  import AddIcon from '@atlaskit/icon/glyph/add';
15
15
  import { setSkinToneAriaLabelText } from './setSkinToneAriaLabelText';
16
16
  import { addCustomEmoji, addCustomEmojiButton, emojiActionsWrapper, emojiPickerAddEmoji, emojiToneSelectorContainer } from './styles';
17
17
  import { emojiActionsContainerWithBottomShadow, emojiPickerFooter } from '../picker/styles';
18
+ import { DEFAULT_TONE } from '../../util/constants';
18
19
  export var emojiActionsTestId = 'emoji-actions';
19
20
  export var uploadEmojiTestId = 'upload-emoji';
20
21
 
@@ -22,8 +23,7 @@ export var uploadEmojiTestId = 'upload-emoji';
22
23
 
23
24
  var AddOwnEmoji = function AddOwnEmoji(props) {
24
25
  var onOpenUpload = props.onOpenUpload,
25
- uploadEnabled = props.uploadEnabled,
26
- formatMessage = props.intl.formatMessage;
26
+ uploadEnabled = props.uploadEnabled;
27
27
  return jsx(Fragment, null, uploadEnabled && jsx("div", {
28
28
  css: addCustomEmoji,
29
29
  "data-testid": uploadEmojiTestId
@@ -31,44 +31,73 @@ var AddOwnEmoji = function AddOwnEmoji(props) {
31
31
  return jsx(AkButton, {
32
32
  onClick: onOpenUpload,
33
33
  iconBefore: jsx(AddIcon, {
34
- label: formatMessage(messages.addCustomEmojiLabel),
34
+ label: "",
35
35
  size: "small"
36
36
  }),
37
37
  appearance: "subtle",
38
38
  css: addCustomEmojiButton,
39
- className: emojiPickerAddEmoji
39
+ className: emojiPickerAddEmoji,
40
+ tabIndex: 0,
41
+ id: "add-custom-emoji"
40
42
  }, label);
41
43
  })));
42
44
  };
43
45
  var TonesWrapper = function TonesWrapper(props) {
44
46
  var toneEmoji = props.toneEmoji,
45
- selectedTone = props.selectedTone,
47
+ _props$selectedTone = props.selectedTone,
48
+ selectedTone = _props$selectedTone === void 0 ? DEFAULT_TONE : _props$selectedTone,
46
49
  intl = props.intl,
47
- onToneSelected = props.onToneSelected,
48
50
  onToneOpen = props.onToneOpen,
49
51
  showToneSelector = props.showToneSelector;
50
52
  var formatMessage = intl.formatMessage;
53
+ var tonePreviewButtonRef = useRef(null);
54
+ var _useState = useState(false),
55
+ _useState2 = _slicedToArray(_useState, 2),
56
+ focusTonePreviewButton = _useState2[0],
57
+ setFocusTonePreviewButton = _useState2[1];
58
+ useEffect(function () {
59
+ if (focusTonePreviewButton && tonePreviewButtonRef.current) {
60
+ tonePreviewButtonRef.current.focus();
61
+ }
62
+ return function () {
63
+ setFocusTonePreviewButton(false);
64
+ };
65
+ });
66
+ var onToneCloseHandler = function onToneCloseHandler() {
67
+ var onToneClose = props.onToneClose;
68
+ onToneClose();
69
+ setFocusTonePreviewButton(true);
70
+ };
71
+ var onToneSelectedHandler = function onToneSelectedHandler(toneValue) {
72
+ var onToneSelected = props.onToneSelected;
73
+ onToneSelected(toneValue);
74
+ setFocusTonePreviewButton(true);
75
+ };
51
76
  if (!toneEmoji) {
52
77
  return null;
53
78
  }
54
- var previewEmoji = toneEmoji;
55
- if (selectedTone && previewEmoji.skinVariations) {
56
- previewEmoji = previewEmoji.skinVariations[(selectedTone || 1) - 1];
79
+ var previewToneEmoji = toneEmoji;
80
+ if (selectedTone !== DEFAULT_TONE && previewToneEmoji.skinVariations) {
81
+ previewToneEmoji = previewToneEmoji.skinVariations[selectedTone - 1];
57
82
  }
58
83
  return jsx("div", {
59
84
  css: emojiToneSelectorContainer
60
- }, showToneSelector && jsx(ToneSelector, {
85
+ }, jsx(ToneSelector, {
61
86
  emoji: toneEmoji,
62
- onToneSelected: onToneSelected,
63
- previewEmojiId: previewEmoji.id
64
- }), jsx(EmojiButton, {
87
+ onToneSelected: onToneSelectedHandler,
88
+ onToneClose: onToneCloseHandler,
89
+ selectedTone: selectedTone,
90
+ isVisible: showToneSelector
91
+ }), jsx(TonePreviewButton, {
92
+ ref: tonePreviewButtonRef,
65
93
  ariaExpanded: showToneSelector,
66
- emoji: previewEmoji,
94
+ emoji: previewToneEmoji,
67
95
  selectOnHover: true,
68
96
  onSelected: onToneOpen,
69
97
  ariaLabelText: formatMessage(messages.emojiSelectSkinToneButtonAriaLabelText, {
70
- selectedTone: "".concat(setSkinToneAriaLabelText(previewEmoji.name), " selected")
71
- })
98
+ selectedTone: "".concat(setSkinToneAriaLabelText(previewToneEmoji.name))
99
+ }),
100
+ isVisible: !showToneSelector
72
101
  }));
73
102
  };
74
103
  export var EmojiActions = function EmojiActions(props) {
@@ -84,15 +113,20 @@ export var EmojiActions = function EmojiActions(props) {
84
113
  onFileChooserClicked = props.onFileChooserClicked,
85
114
  emojiToDelete = props.emojiToDelete,
86
115
  onChange = props.onChange,
87
- query = props.query;
88
- var _useState = useState(false),
89
- _useState2 = _slicedToArray(_useState, 2),
90
- showToneSelector = _useState2[0],
91
- setShowToneSelector = _useState2[1];
116
+ query = props.query,
117
+ _props$resultsCount = props.resultsCount,
118
+ resultsCount = _props$resultsCount === void 0 ? 0 : _props$resultsCount;
119
+ var _useState3 = useState(false),
120
+ _useState4 = _slicedToArray(_useState3, 2),
121
+ showToneSelector = _useState4[0],
122
+ setShowToneSelector = _useState4[1];
92
123
  var previewFooterClassnames = [emojiPickerFooter, emojiActionsContainerWithBottomShadow];
93
124
  var onToneOpenHandler = function onToneOpenHandler() {
94
125
  return setShowToneSelector(true);
95
126
  };
127
+ var onToneCloseHandler = function onToneCloseHandler() {
128
+ return setShowToneSelector(false);
129
+ };
96
130
  var onToneSelectedHandler = function onToneSelectedHandler(toneValue) {
97
131
  setShowToneSelector(false);
98
132
  if (onToneSelected) {
@@ -133,11 +167,13 @@ export var EmojiActions = function EmojiActions(props) {
133
167
  css: emojiActionsWrapper
134
168
  }, !showToneSelector && jsx(EmojiPickerListSearch, {
135
169
  onChange: onChange,
136
- query: query
170
+ query: query,
171
+ resultsCount: resultsCount
137
172
  }), jsx(TonesWrapper, _extends({}, props, {
138
173
  onToneOpen: onToneOpenHandler,
174
+ onToneClose: onToneCloseHandler,
139
175
  onToneSelected: onToneSelectedHandler,
140
176
  showToneSelector: showToneSelector
141
177
  }))), jsx(AddOwnEmoji, props));
142
178
  };
143
- export default injectIntl(EmojiActions);
179
+ export default injectIntl( /*#__PURE__*/memo(EmojiActions));
@@ -1,8 +1,9 @@
1
1
  /** @jsx jsx */
2
-
2
+ import { Fragment } from 'react';
3
3
  import { jsx } from '@emotion/react';
4
4
  import Tooltip from '@atlaskit/tooltip';
5
5
  import ErrorIcon from '@atlaskit/icon/glyph/error';
6
+ import VisuallyHidden from '@atlaskit/visually-hidden';
6
7
  export var emojiErrorMessageTestId = 'emoji-error-message';
7
8
  export var emojiErrorMessageTooltipTestId = 'emoji-error-message-tooltip';
8
9
  export var emojiErrorIconTestId = 'emoji-error-icon';
@@ -10,7 +11,7 @@ var EmojiErrorMessage = function EmojiErrorMessage(props) {
10
11
  var messageStyles = props.messageStyles,
11
12
  message = props.message,
12
13
  tooltip = props.tooltip;
13
- return tooltip ? jsx("div", {
14
+ var visualContent = tooltip ? jsx("div", {
14
15
  css: messageStyles,
15
16
  "data-testid": emojiErrorMessageTestId
16
17
  }, jsx(Tooltip, {
@@ -27,6 +28,9 @@ var EmojiErrorMessage = function EmojiErrorMessage(props) {
27
28
  }, jsx(ErrorIcon, {
28
29
  label: "Error",
29
30
  size: "small"
30
- }), " ", message);
31
+ }), message);
32
+ return jsx(Fragment, null, jsx(VisuallyHidden, {
33
+ role: "alert"
34
+ }, message), visualContent);
31
35
  };
32
36
  export default EmojiErrorMessage;
@@ -34,6 +34,7 @@ var EmojiPlaceholder = function EmojiPlaceholder(props) {
34
34
  return jsx("span", {
35
35
  "data-testid": emojiPlaceholderTestId(shortName),
36
36
  "aria-busy": loading,
37
+ role: "status",
37
38
  "aria-label": shortName,
38
39
  className: placeholder,
39
40
  css: loading ? [placeholderContainer, placeholderContainerAnimated] : placeholderContainer,
@@ -0,0 +1,52 @@
1
+ /** @jsx jsx */
2
+ import React, { memo, forwardRef } from 'react';
3
+ import { jsx } from '@emotion/react';
4
+ import { leftClick } from '../../util/mouse';
5
+ import { emojiButton, emojiRadio } from './styles';
6
+ import Emoji from './Emoji';
7
+ import { TONESELECTOR_KEYBOARD_KEYS_SUPPORTED } from '../../util/constants';
8
+ import VisuallyHidden from '@atlaskit/visually-hidden';
9
+ var handleMouseDown = function handleMouseDown(props, event) {
10
+ var onSelected = props.onSelected;
11
+ event.preventDefault();
12
+ if (onSelected && leftClick(event)) {
13
+ onSelected();
14
+ }
15
+ };
16
+ var handleKeyPress = function handleKeyPress(props, event) {
17
+ if (TONESELECTOR_KEYBOARD_KEYS_SUPPORTED.includes(event.key)) {
18
+ var onSelected = props.onSelected;
19
+ event.preventDefault();
20
+ if (onSelected) {
21
+ onSelected();
22
+ }
23
+ }
24
+ };
25
+ export var EmojiRadioButton = /*#__PURE__*/forwardRef(function (props, ref) {
26
+ var emoji = props.emoji,
27
+ selectOnHover = props.selectOnHover,
28
+ ariaLabelText = props.ariaLabelText,
29
+ defaultChecked = props.defaultChecked;
30
+ return jsx("label", {
31
+ css: emojiButton,
32
+ onMouseDown: function onMouseDown(event) {
33
+ return handleMouseDown(props, event);
34
+ },
35
+ onKeyDown: function onKeyDown(event) {
36
+ return handleKeyPress(props, event);
37
+ }
38
+ }, jsx(VisuallyHidden, null, ariaLabelText), jsx("input", {
39
+ ref: ref,
40
+ "data-testid": ariaLabelText,
41
+ type: "radio",
42
+ name: "skin-tone",
43
+ css: emojiRadio,
44
+ defaultChecked: defaultChecked
45
+ }), jsx(Emoji, {
46
+ emoji: emoji,
47
+ selectOnHover: selectOnHover,
48
+ shouldBeInteractive: false,
49
+ "aria-hidden": true
50
+ }));
51
+ });
52
+ export default /*#__PURE__*/memo(EmojiRadioButton);