@atlaskit/reactions 31.5.2 → 31.6.1

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 (67) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/analytics/index.js +1 -1
  3. package/dist/cjs/components/EmojiButton.compiled.css +14 -2
  4. package/dist/cjs/components/EmojiButton.js +8 -4
  5. package/dist/cjs/components/Reaction.js +2 -1
  6. package/dist/cjs/components/ReactionParticleEffect.compiled.css +3 -1
  7. package/dist/cjs/components/ReactionParticleEffect.js +3 -7
  8. package/dist/cjs/components/ReactionPicker.js +115 -45
  9. package/dist/cjs/components/ReactionSummaryButton.js +2 -1
  10. package/dist/cjs/components/Reactions.js +3 -1
  11. package/dist/cjs/components/ReactionsDialogHeader.js +2 -1
  12. package/dist/cjs/components/RepositionOnUpdate.js +3 -2
  13. package/dist/cjs/components/Selector.compiled.css +2 -1
  14. package/dist/cjs/components/Selector.js +30 -9
  15. package/dist/cjs/components/Trigger.js +6 -3
  16. package/dist/cjs/hooks/useDelayedState.js +1 -1
  17. package/dist/cjs/shared/constants.js +5 -2
  18. package/dist/cjs/shared/i18n.js +5 -0
  19. package/dist/es2019/analytics/index.js +1 -1
  20. package/dist/es2019/components/EmojiButton.compiled.css +14 -2
  21. package/dist/es2019/components/EmojiButton.js +8 -4
  22. package/dist/es2019/components/Reaction.js +2 -1
  23. package/dist/es2019/components/ReactionParticleEffect.compiled.css +3 -3
  24. package/dist/es2019/components/ReactionParticleEffect.js +3 -4
  25. package/dist/es2019/components/ReactionPicker.js +90 -35
  26. package/dist/es2019/components/ReactionSummaryButton.js +2 -1
  27. package/dist/es2019/components/Reactions.js +3 -1
  28. package/dist/es2019/components/ReactionsDialogHeader.js +2 -1
  29. package/dist/es2019/components/RepositionOnUpdate.js +3 -2
  30. package/dist/es2019/components/Selector.compiled.css +2 -1
  31. package/dist/es2019/components/Selector.js +29 -9
  32. package/dist/es2019/components/Trigger.js +5 -3
  33. package/dist/es2019/hooks/useDelayedState.js +1 -1
  34. package/dist/es2019/shared/constants.js +4 -1
  35. package/dist/es2019/shared/i18n.js +5 -0
  36. package/dist/esm/analytics/index.js +1 -1
  37. package/dist/esm/components/EmojiButton.compiled.css +14 -2
  38. package/dist/esm/components/EmojiButton.js +8 -4
  39. package/dist/esm/components/Reaction.js +2 -1
  40. package/dist/esm/components/ReactionParticleEffect.compiled.css +3 -1
  41. package/dist/esm/components/ReactionParticleEffect.js +3 -7
  42. package/dist/esm/components/ReactionPicker.js +114 -45
  43. package/dist/esm/components/ReactionSummaryButton.js +2 -1
  44. package/dist/esm/components/Reactions.js +3 -1
  45. package/dist/esm/components/ReactionsDialogHeader.js +2 -1
  46. package/dist/esm/components/RepositionOnUpdate.js +3 -2
  47. package/dist/esm/components/Selector.compiled.css +2 -1
  48. package/dist/esm/components/Selector.js +30 -9
  49. package/dist/esm/components/Trigger.js +6 -3
  50. package/dist/esm/hooks/useDelayedState.js +1 -1
  51. package/dist/esm/shared/constants.js +4 -1
  52. package/dist/esm/shared/i18n.js +5 -0
  53. package/dist/types/components/EmojiButton.d.ts +5 -1
  54. package/dist/types/components/ReactionPicker.d.ts +9 -1
  55. package/dist/types/components/RepositionOnUpdate.d.ts +2 -2
  56. package/dist/types/components/Selector.d.ts +5 -1
  57. package/dist/types/components/Trigger.d.ts +1 -0
  58. package/dist/types/shared/constants.d.ts +1 -0
  59. package/dist/types/shared/i18n.d.ts +5 -0
  60. package/dist/types-ts4.5/components/EmojiButton.d.ts +5 -1
  61. package/dist/types-ts4.5/components/ReactionPicker.d.ts +9 -1
  62. package/dist/types-ts4.5/components/RepositionOnUpdate.d.ts +2 -2
  63. package/dist/types-ts4.5/components/Selector.d.ts +5 -1
  64. package/dist/types-ts4.5/components/Trigger.d.ts +1 -0
  65. package/dist/types-ts4.5/shared/constants.d.ts +1 -0
  66. package/dist/types-ts4.5/shared/i18n.d.ts +5 -0
  67. package/package.json +2 -2
@@ -27,6 +27,7 @@ var styles = {
27
27
  disabledTrigger: "_1h6d13gt _bfhksyzs",
28
28
  miniMode: "_2rkoglpi _1dqoglyw _1ul91tcg _ca0q1b66 _u5f31b66 _n3td1b66 _19bv1b66",
29
29
  fullWidthSummaryViewReactionPickerTrigger: "_1bsb1osq _ca0qu2gc _19bvu2gc _u5f3u2gc",
30
+ fullWidthSelectorTrayReactionPickerTrigger: "_1bsb1osq _ca0q1b66 _19bv1b66 _u5f31b66",
30
31
  fullWidth: "_1bsb1osq _p12f3xl8"
31
32
  };
32
33
 
@@ -76,7 +77,9 @@ var Trigger = exports.Trigger = /*#__PURE__*/_react2.default.forwardRef(function
76
77
  _props$fullWidthSumma = props.fullWidthSummaryViewReactionPickerTrigger,
77
78
  fullWidthSummaryViewReactionPickerTrigger = _props$fullWidthSumma === void 0 ? false : _props$fullWidthSumma,
78
79
  _props$isListItem = props.isListItem,
79
- isListItem = _props$isListItem === void 0 ? false : _props$isListItem;
80
+ isListItem = _props$isListItem === void 0 ? false : _props$isListItem,
81
+ _props$fullWidthSelec = props.fullWidthSelectorTrayReactionPickerTrigger,
82
+ fullWidthSelectorTrayReactionPickerTrigger = _props$fullWidthSelec === void 0 ? false : _props$fullWidthSelec;
80
83
  var handleMouseDown = function handleMouseDown(e, analyticsEvent) {
81
84
  if (onClick && !disabled) {
82
85
  onClick(e, analyticsEvent);
@@ -85,7 +88,7 @@ var Trigger = exports.Trigger = /*#__PURE__*/_react2.default.forwardRef(function
85
88
  var renderPressableButton = function renderPressableButton() {
86
89
  return /*#__PURE__*/_react2.default.createElement(_compiled.Pressable, (0, _extends2.default)({
87
90
  testId: RENDER_TRIGGER_BUTTON_TESTID,
88
- xcss: (0, _react.cx)(styles.trigger, fullWidthSummaryViewReactionPickerTrigger && styles.fullWidth, subtleReactionsSummaryAndPicker && styles.subtleTrigger, showAddReactionText && styles.expandedTrigger, disabled ? styles.disabledTrigger : showOpaqueBackground ? styles.opaqueEnabledTrigger : styles.transparentEnabledTrigger, miniMode && styles.miniMode,
91
+ xcss: (0, _react.cx)(styles.trigger, (fullWidthSummaryViewReactionPickerTrigger || fullWidthSelectorTrayReactionPickerTrigger) && styles.fullWidth, subtleReactionsSummaryAndPicker && styles.subtleTrigger, showAddReactionText && styles.expandedTrigger, disabled ? styles.disabledTrigger : showOpaqueBackground ? styles.opaqueEnabledTrigger : styles.transparentEnabledTrigger, miniMode && styles.miniMode,
89
92
  // eslint-disable-next-line @atlaskit/platform/ensure-feature-flag-prefix
90
93
  (0, _platformFeatureFlags.fg)('platform-component-visual-refresh') && styles.triggerStylesRefresh, showRoundTrigger && styles.roundTrigger),
91
94
  style: {
@@ -110,7 +113,7 @@ var Trigger = exports.Trigger = /*#__PURE__*/_react2.default.forwardRef(function
110
113
  }, reactionPickerTriggerText));
111
114
  };
112
115
  return /*#__PURE__*/_react2.default.createElement(_compiled.Box, {
113
- xcss: (0, _react.cx)(fullWidthSummaryViewReactionPickerTrigger && styles.fullWidthSummaryViewReactionPickerTrigger),
116
+ xcss: (0, _react.cx)(fullWidthSummaryViewReactionPickerTrigger && styles.fullWidthSummaryViewReactionPickerTrigger, fullWidthSelectorTrayReactionPickerTrigger && styles.fullWidthSelectorTrayReactionPickerTrigger),
114
117
  testId: RENDER_TRIGGER_CONTAINER_TESTID
115
118
  }, /*#__PURE__*/_react2.default.createElement(_tooltip.default, {
116
119
  testId: RENDER_TOOLTIP_TRIGGER_TESTID,
@@ -25,7 +25,7 @@ var useDelayedState = exports.useDelayedState = function useDelayedState(initial
25
25
  if (timeoutRef.current) {
26
26
  clearTimeout(timeoutRef.current);
27
27
  }
28
- if (immediate) {
28
+ if (immediate || delay === 0) {
29
29
  setState(newState);
30
30
  } else {
31
31
  timeoutRef.current = setTimeout(function () {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.TOOLTIP_USERS_LIMIT = exports.SAMPLING_RATE_REACTIONS_RENDERED_EXP = exports.NUMBER_OF_REACTIONS_TO_DISPLAY = exports.ExtendedReactionsByShortName = exports.ExtendedReactions = exports.DefaultReactionsByShortName = exports.DefaultReactions = void 0;
6
+ exports.TOOLTIP_USERS_LIMIT = exports.SAMPLING_RATE_REACTIONS_RENDERED_EXP = exports.RESOURCED_EMOJI_COMPACT_HEIGHT = exports.NUMBER_OF_REACTIONS_TO_DISPLAY = exports.ExtendedReactionsByShortName = exports.ExtendedReactions = exports.DefaultReactionsByShortName = exports.DefaultReactions = void 0;
7
7
  /**
8
8
  * Initial list of emoji to pick from
9
9
  */
@@ -101,4 +101,7 @@ var TOOLTIP_USERS_LIMIT = exports.TOOLTIP_USERS_LIMIT = 5;
101
101
  var NUMBER_OF_REACTIONS_TO_DISPLAY = exports.NUMBER_OF_REACTIONS_TO_DISPLAY = 8;
102
102
 
103
103
  // This rate is used in fetching emoji resource
104
- var SAMPLING_RATE_REACTIONS_RENDERED_EXP = exports.SAMPLING_RATE_REACTIONS_RENDERED_EXP = 50;
104
+ var SAMPLING_RATE_REACTIONS_RENDERED_EXP = exports.SAMPLING_RATE_REACTIONS_RENDERED_EXP = 50;
105
+
106
+ // Reactions compact height value
107
+ var RESOURCED_EMOJI_COMPACT_HEIGHT = exports.RESOURCED_EMOJI_COMPACT_HEIGHT = 16;
@@ -11,6 +11,11 @@ var messages = exports.messages = (0, _reactIntlNext.defineMessages)({
11
11
  defaultMessage: 'Add reaction',
12
12
  description: 'Message for add reaction button'
13
13
  },
14
+ addNewReaction: {
15
+ id: 'fabric.reactions.add.new',
16
+ defaultMessage: 'Add new',
17
+ description: 'Message for add new reaction button in hoverable reaction picker'
18
+ },
14
19
  loadingReactions: {
15
20
  id: 'fabric.reactions.loading',
16
21
  defaultMessage: 'Loading...',
@@ -1,7 +1,7 @@
1
1
  import { createAndFireEvent } from '@atlaskit/analytics-next';
2
2
  import { UI_EVENT_TYPE, OPERATIONAL_EVENT_TYPE } from '@atlaskit/analytics-gas-types';
3
3
  const packageName = "@atlaskit/reactions";
4
- const packageVersion = "31.5.2";
4
+ const packageVersion = "31.6.1";
5
5
  /**
6
6
  * TODO: move to utility package?
7
7
  * A random sampling function
@@ -1,17 +1,29 @@
1
1
 
2
2
  ._2rkoglpi{border-radius:var(--ds-border-radius,4px)}
3
- ._189eidpf{border-width:0}._12ji1r31{outline-color:currentColor}
3
+ ._2rkoiti9{border-radius:var(--ds-border-radius-100,4px)}
4
+ ._189ee4h9{border-width:var(--ds-border-width,1px)}
5
+ ._189eidpf{border-width:0}
6
+ ._1dqonqa1{border-style:solid}
7
+ ._1h6dmuej{border-color:var(--ds-border,#091e4224)}._12ji1r31{outline-color:currentColor}
4
8
  ._12y31o36{outline-width:medium}
5
9
  ._18u0ze3t{margin-left:var(--ds-space-0,0)}
10
+ ._19bv1b66{padding-left:var(--ds-space-050,4px)}
6
11
  ._19bvu2gc{padding-left:var(--ds-space-100,8px)}
7
12
  ._19pkze3t{margin-top:var(--ds-space-0,0)}
8
13
  ._1e0c1txw{display:flex}
9
14
  ._1qu2glyw{outline-style:none}
10
15
  ._2hwxze3t{margin-right:var(--ds-space-0,0)}
16
+ ._8hrz1nam{transform-origin:center center 0}
11
17
  ._bfhksm61{background-color:var(--ds-background-neutral-subtle,#00000000)}
12
18
  ._ca0qu2gc{padding-top:var(--ds-space-100,8px)}
19
+ ._ca0qv77o{padding-top:var(--ds-space-025,2px)}
20
+ ._n3td1b66{padding-bottom:var(--ds-space-050,4px)}
13
21
  ._n3tdu2gc{padding-bottom:var(--ds-space-100,8px)}
14
22
  ._otyrze3t{margin-bottom:var(--ds-space-0,0)}
23
+ ._syaz1gjq{color:var(--ds-text-subtle,#44546f)}
24
+ ._u5f31b66{padding-right:var(--ds-space-050,4px)}
15
25
  ._u5f3u2gc{padding-right:var(--ds-space-100,8px)}
16
26
  ._o7ksrkh3:hover{transition:transform .2s cubic-bezier(.23,1,.32,1)}
17
- ._1llw1q5f:hover{transform:scale(1.33)}
27
+ ._1llw1q5f:hover{transform:scale(1.33)}
28
+ ._irr3166n:hover{background-color:var(--ds-background-neutral-subtle-hovered,#091e420f)}
29
+ ._1di61dty:active{background-color:var(--ds-background-neutral-subtle-pressed,#091e4224)}
@@ -6,9 +6,11 @@ import { useIntl } from 'react-intl-next';
6
6
  import { ResourcedEmoji } from '@atlaskit/emoji';
7
7
  import { messages } from '../shared/i18n';
8
8
  import { isLeftClick } from '../shared/utils';
9
+ import { RESOURCED_EMOJI_COMPACT_HEIGHT } from '../shared/constants';
9
10
  import { Pressable } from '@atlaskit/primitives/compiled';
10
11
  const styles = {
11
- emojiButton: "_12ji1r31 _1qu2glyw _12y31o36 _2rkoglpi _189eidpf _1e0c1txw _bfhksm61 _19pkze3t _2hwxze3t _otyrze3t _18u0ze3t _ca0qu2gc _u5f3u2gc _n3tdu2gc _19bvu2gc _o7ksrkh3 _1llw1q5f"
12
+ emojiButton: "_12ji1r31 _1qu2glyw _12y31o36 _2rkoglpi _189eidpf _1e0c1txw _bfhksm61 _19pkze3t _2hwxze3t _otyrze3t _18u0ze3t _ca0qu2gc _u5f3u2gc _n3tdu2gc _19bvu2gc _o7ksrkh3 _1llw1q5f",
13
+ hoverableReactionPickerSelectorEmojiButton: "_12ji1r31 _1qu2glyw _12y31o36 _2rkoiti9 _189ee4h9 _1dqonqa1 _1h6dmuej _1e0c1txw _8hrz1nam _ca0qv77o _u5f31b66 _n3td1b66 _19bv1b66 _bfhksm61 _syaz1gjq _19pkze3t _2hwxze3t _otyrze3t _18u0ze3t _irr3166n _1di61dty"
12
14
  };
13
15
  export const RENDER_BUTTON_TESTID = 'button-emoji-id';
14
16
  /**
@@ -17,7 +19,8 @@ export const RENDER_BUTTON_TESTID = 'button-emoji-id';
17
19
  export const EmojiButton = ({
18
20
  emojiId,
19
21
  onClick,
20
- emojiProvider
22
+ emojiProvider,
23
+ hoverableReactionPickerSelectorEmoji
21
24
  }) => {
22
25
  const onButtonClick = event => {
23
26
  event.preventDefault();
@@ -32,9 +35,10 @@ export const EmojiButton = ({
32
35
  "aria-label": intl.formatMessage(messages.reactWithEmoji, {
33
36
  emoji: emojiId.shortName
34
37
  }),
35
- xcss: styles.emojiButton
38
+ xcss: hoverableReactionPickerSelectorEmoji ? styles.hoverableReactionPickerSelectorEmojiButton : styles.emojiButton
36
39
  }, /*#__PURE__*/React.createElement(ResourcedEmoji, {
37
40
  emojiProvider: emojiProvider,
38
- emojiId: emojiId
41
+ emojiId: emojiId,
42
+ fitToHeight: hoverableReactionPickerSelectorEmoji ? RESOURCED_EMOJI_COMPACT_HEIGHT : undefined
39
43
  }));
40
44
  };
@@ -12,6 +12,7 @@ import { ReactionParticleEffect } from './ReactionParticleEffect';
12
12
  import { ReactionTooltip } from './ReactionTooltip';
13
13
  import { messages } from '../shared/i18n';
14
14
  import { isLeftClick } from '../shared/utils';
15
+ import { RESOURCED_EMOJI_COMPACT_HEIGHT } from '../shared/constants';
15
16
  import { ReactionButton } from './ReactionButton';
16
17
  import { StaticReaction } from './StaticReaction';
17
18
  import { Box, Inline } from '@atlaskit/primitives/compiled';
@@ -106,7 +107,7 @@ export const Reaction = ({
106
107
  }, /*#__PURE__*/React.createElement(ResourcedEmoji, {
107
108
  emojiProvider: emojiProvider,
108
109
  emojiId: emojiId,
109
- fitToHeight: 16
110
+ fitToHeight: RESOURCED_EMOJI_COMPACT_HEIGHT
110
111
  })), /*#__PURE__*/React.createElement(Counter, {
111
112
  value: reaction.count,
112
113
  highlight: !isViewOnly && reaction.reacted
@@ -1,5 +1,5 @@
1
1
 
2
- ._y44vik89{animation:k102rpwx ease-in-out,k4txmy4 ease}._154iidpf{top:0}
2
+ ._y44v7u0o{animation:reaction-particle-fade ease-in-out,reaction-particle-float ease}._154iidpf{top:0}
3
3
  ._1lac188d:nth-child(3){animation-delay:.3s}
4
4
  ._1ltvftgi{left:8px}
5
5
  ._1ltvidpf{left:0}
@@ -14,6 +14,6 @@
14
14
  ._lcxvglyw{pointer-events:none}
15
15
  ._tzy4idpf{opacity:0}
16
16
  ._xg4k6ebc:nth-child(2){animation-delay:.15s}
17
- @keyframes k102rpwx{0%{opacity:0}20%{opacity:1}60%{opacity:1}to{opacity:0}}
18
- @keyframes k4txmy4{0%{transform:translateY(0) scale(1)}to{transform:translateY(-90pt) scale(1.7)}}
17
+ @keyframes reaction-particle-fade{0%{opacity:0}20%{opacity:1}60%{opacity:1}to{opacity:0}}
18
+ @keyframes reaction-particle-float{0%{transform:translateY(0) scale(1)}to{transform:translateY(-90pt) scale(1.7)}}
19
19
  @media (prefers-reduced-motion:reduce){._m602idpf{opacity:0}}
@@ -4,8 +4,7 @@ import * as React from 'react';
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
5
  import { ResourcedEmoji } from '@atlaskit/emoji';
6
6
  import { layers } from '@atlaskit/theme/constants';
7
- const fade = null;
8
- const float = null;
7
+ import { RESOURCED_EMOJI_COMPACT_HEIGHT } from '../shared/constants';
9
8
  const containerStyle = null;
10
9
  const reactionParticleStyle = null;
11
10
  export const PARTICLE_COUNT = 4;
@@ -17,10 +16,10 @@ export const ReactionParticleEffect = ({
17
16
  }, [...Array(PARTICLE_COUNT)].map((_, index) => {
18
17
  return /*#__PURE__*/React.createElement("div", {
19
18
  key: index,
20
- className: ax(["_y44vik89 _kqswstnw _154iidpf _1ltvidpf _lcxvglyw _tzy4idpf _5sagpwmj _1qen1lpd _xg4k6ebc _91vyftgi _1lac188d _jsy51n1a _7vm81dfm"])
19
+ className: ax(["_y44v7u0o _kqswstnw _154iidpf _1ltvidpf _lcxvglyw _tzy4idpf _5sagpwmj _1qen1lpd _xg4k6ebc _91vyftgi _1lac188d _jsy51n1a _7vm81dfm"])
21
20
  }, /*#__PURE__*/React.createElement(ResourcedEmoji, {
22
21
  emojiProvider: emojiProvider,
23
22
  emojiId: emojiId,
24
- fitToHeight: 16
23
+ fitToHeight: RESOURCED_EMOJI_COMPACT_HEIGHT
25
24
  }));
26
25
  }));
@@ -6,18 +6,22 @@ import { FormattedMessage, useIntl } from 'react-intl-next';
6
6
  import { EmojiPicker } from '@atlaskit/emoji/picker';
7
7
  import { Manager, Popper, Reference } from '@atlaskit/popper';
8
8
  import { layers } from '@atlaskit/theme/constants';
9
+ import { Box } from '@atlaskit/primitives/compiled';
9
10
  import { useCloseManager } from '../hooks/useCloseManager';
11
+ import { useDelayedState } from '../hooks/useDelayedState';
10
12
  import { useFocusTrap } from '../hooks/useFocusTrap';
11
13
  import { messages } from '../shared/i18n';
12
14
  import { PickerRender } from '../ufo';
13
15
  import { Selector } from './Selector';
14
16
  import { Trigger } from './Trigger';
17
+ import { RepositionOnUpdate } from './RepositionOnUpdate';
15
18
  import { N0, N50A, N60A } from '@atlaskit/theme/colors';
16
19
  const pickerStyle = null;
17
- const contentStyle = null;
18
20
  const popupWrapperStyle = null;
19
21
  const popupStyle = null;
20
- import { RepositionOnUpdate } from './RepositionOnUpdate';
22
+ const additionalStyles = {
23
+ selectorContainer: "_1e0c1txw"
24
+ };
21
25
 
22
26
  /**
23
27
  * Test id for wrapper ReactionPicker div
@@ -58,9 +62,15 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
58
62
  reactionPickerTriggerText,
59
63
  reactionPickerPlacement,
60
64
  reactionsPickerPreventOverflowOptions,
61
- isListItem = false
65
+ isListItem = false,
66
+ hoverableReactionPicker = false,
67
+ hoverableReactionPickerDelay = 0
62
68
  } = props;
63
69
  const [triggerRef, setTriggerRef] = useState(null);
70
+ const [isHoverableReactionPickerEmojiPickerOpen, setIsHoverableReactionPickerEmojiPickerOpen] = useState(false);
71
+ const [isHoveringTrigger, setIsHoveringTrigger] = useState(false);
72
+ const [isHoveringPopup, setIsHoveringPopup] = useState(false);
73
+ const [isPopupTrayOpen, setIsPopupTrayOpen] = useDelayedState(false, hoverableReactionPickerDelay);
64
74
 
65
75
  /**
66
76
  * Container <div /> reference (used by custom hook to detect click outside)
@@ -99,10 +109,6 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
99
109
  })
100
110
  }];
101
111
  const [settings, setSettings] = useState({
102
- /**
103
- * Show the picker floating panel
104
- */
105
- isOpen: false,
106
112
  /**
107
113
  * Show the full custom emoji list picker or the default list of emojis
108
114
  */
@@ -122,17 +128,14 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
122
128
  if (triggerRef && callbackType === 'ESCAPE') {
123
129
  requestAnimationFrame(() => triggerRef.focus());
124
130
  }
125
- }, true, settings.isOpen);
131
+ }, true, isPopupTrayOpen);
126
132
 
127
133
  /**
128
134
  * Event callback when the picker is closed
129
135
  * @param _id Optional id if an emoji button was selected or undefineed if was clicked outside the picker
130
136
  */
131
137
  const close = useCallback(_id => {
132
- setSettings({
133
- ...settings,
134
- isOpen: false
135
- });
138
+ setIsPopupTrayOpen(false);
136
139
  // ufo abort reaction experience
137
140
  PickerRender.abort({
138
141
  metadata: {
@@ -141,7 +144,10 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
141
144
  reason: 'close dialog'
142
145
  }
143
146
  });
144
- }, [settings]);
147
+ if (hoverableReactionPicker) {
148
+ setIsHoverableReactionPickerEmojiPickerOpen(false);
149
+ }
150
+ }, [setIsPopupTrayOpen, setIsHoverableReactionPickerEmojiPickerOpen, hoverableReactionPicker]);
145
151
 
146
152
  /**
147
153
  * Event handle rwhen selecting to show the custom emoji icons picker
@@ -150,12 +156,15 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
150
156
  const onSelectMoreClick = useCallback(e => {
151
157
  e.preventDefault();
152
158
  setSettings({
153
- isOpen: true,
154
- showFullPicker: true,
159
+ showFullPicker: hoverableReactionPicker ? settings.showFullPicker : true,
155
160
  popperPlacement
156
161
  });
162
+ setIsPopupTrayOpen(true);
163
+ if (hoverableReactionPicker) {
164
+ setIsHoverableReactionPickerEmojiPickerOpen(!isHoverableReactionPickerEmojiPickerOpen);
165
+ }
157
166
  onShowMore();
158
- }, [onShowMore, popperPlacement]);
167
+ }, [settings.showFullPicker, setIsPopupTrayOpen, onShowMore, popperPlacement, hoverableReactionPicker, setIsHoverableReactionPickerEmojiPickerOpen, isHoverableReactionPickerEmojiPickerOpen]);
159
168
 
160
169
  /**
161
170
  * Event callback when an emoji icon is selected
@@ -166,26 +175,63 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
166
175
  if (!item.id) {
167
176
  return;
168
177
  }
169
- onSelection(item.id, settings.showFullPicker ? 'emojiPicker' : 'quickSelector');
178
+ onSelection(item.id, settings.showFullPicker || hoverableReactionPicker && isHoverableReactionPickerEmojiPickerOpen ? 'emojiPicker' : 'quickSelector');
170
179
  close(item.id);
171
- }, [close, onSelection, settings.showFullPicker]);
180
+ }, [close, onSelection, settings.showFullPicker, hoverableReactionPicker, isHoverableReactionPickerEmojiPickerOpen]);
172
181
 
173
182
  /**
174
183
  * Event handler when the emoji icon to open the custom picker is selected
175
184
  */
176
- const onTriggerClick = () => {
185
+ const onTriggerClick = useCallback(() => {
177
186
  // ufo start reactions picker open experience
178
187
  PickerRender.start();
179
188
  setSettings({
180
- isOpen: !settings.isOpen,
181
- showFullPicker: !!allowAllEmojis && Array.isArray(pickerQuickReactionEmojiIds) && pickerQuickReactionEmojiIds.length === 0,
189
+ ...settings,
182
190
  popperPlacement
183
191
  });
192
+ if (hoverableReactionPicker) {
193
+ setIsHoverableReactionPickerEmojiPickerOpen(!isHoverableReactionPickerEmojiPickerOpen);
194
+ setIsPopupTrayOpen(!isHoverableReactionPickerEmojiPickerOpen || !isPopupTrayOpen);
195
+ } else {
196
+ setIsPopupTrayOpen(!isPopupTrayOpen);
197
+ }
184
198
  onOpen();
185
199
  // ufo reactions picker opened success
186
200
  PickerRender.success();
187
- };
188
- const wrapperClassName = ` ${settings.isOpen ? 'isOpen' : ''} ${miniMode ? 'miniMode' : ''} ${className}`;
201
+ }, [hoverableReactionPicker, isPopupTrayOpen, setIsPopupTrayOpen, isHoverableReactionPickerEmojiPickerOpen, onOpen, settings, popperPlacement]);
202
+ const handleTriggerMouseEnter = useCallback(() => {
203
+ if (hoverableReactionPicker) {
204
+ setIsHoveringTrigger(true);
205
+ if (!isHoverableReactionPickerEmojiPickerOpen) {
206
+ setIsPopupTrayOpen(true);
207
+ }
208
+ }
209
+ }, [hoverableReactionPicker, isHoverableReactionPickerEmojiPickerOpen, setIsPopupTrayOpen]);
210
+ const handleTriggerMouseLeave = useCallback(() => {
211
+ if (hoverableReactionPicker) {
212
+ setIsHoveringTrigger(false);
213
+ if (!isHoveringPopup && !isHoverableReactionPickerEmojiPickerOpen) {
214
+ setIsPopupTrayOpen(false);
215
+ }
216
+ }
217
+ }, [hoverableReactionPicker, isHoveringPopup, isHoverableReactionPickerEmojiPickerOpen, setIsPopupTrayOpen]);
218
+ const handlePopupMouseEnter = useCallback(() => {
219
+ if (hoverableReactionPicker) {
220
+ setIsHoveringPopup(true);
221
+ if (!isHoverableReactionPickerEmojiPickerOpen) {
222
+ setIsPopupTrayOpen(true);
223
+ }
224
+ }
225
+ }, [hoverableReactionPicker, isHoverableReactionPickerEmojiPickerOpen, setIsPopupTrayOpen]);
226
+ const handlePopupMouseLeave = useCallback(() => {
227
+ if (hoverableReactionPicker) {
228
+ setIsHoveringPopup(false);
229
+ if (!isHoveringTrigger && !isHoverableReactionPickerEmojiPickerOpen) {
230
+ setIsPopupTrayOpen(false);
231
+ }
232
+ }
233
+ }, [hoverableReactionPicker, isHoveringTrigger, isHoverableReactionPickerEmojiPickerOpen, setIsPopupTrayOpen]);
234
+ const wrapperClassName = ` ${isPopupTrayOpen ? 'isOpen' : ''} ${miniMode ? 'miniMode' : ''} ${className}`;
189
235
  useLayoutEffect(() => {
190
236
  var _updatePopper$current;
191
237
  (_updatePopper$current = updatePopper.current) === null || _updatePopper$current === void 0 ? void 0 : _updatePopper$current.call(updatePopper);
@@ -200,13 +246,16 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
200
246
  }) =>
201
247
  /*#__PURE__*/
202
248
  // Render a button to open the <Selector /> panel
203
- React.createElement(Trigger, {
249
+ React.createElement(Box, {
250
+ onMouseEnter: handleTriggerMouseEnter,
251
+ onMouseLeave: handleTriggerMouseLeave
252
+ }, /*#__PURE__*/React.createElement(Trigger, {
204
253
  ariaAttributes: {
205
- 'aria-expanded': settings.isOpen,
254
+ 'aria-expanded': isPopupTrayOpen,
206
255
  'aria-controls': PICKER_CONTROL_ID
207
256
  },
208
257
  ref: node => {
209
- if (node && settings.isOpen) {
258
+ if (node && isPopupTrayOpen) {
210
259
  if (typeof ref === 'function') {
211
260
  ref(node);
212
261
  } else {
@@ -215,11 +264,11 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
215
264
  setTriggerRef(node);
216
265
  }
217
266
  },
218
- isSelected: settings.isOpen,
267
+ isSelected: isPopupTrayOpen,
219
268
  onClick: onTriggerClick,
220
269
  miniMode: miniMode,
221
270
  disabled: disabled,
222
- tooltipContent: settings.isOpen ? null : tooltipContent,
271
+ tooltipContent: isPopupTrayOpen ? null : tooltipContent,
223
272
  showOpaqueBackground: showOpaqueBackground,
224
273
  showAddReactionText: showAddReactionText,
225
274
  subtleReactionsSummaryAndPicker: subtleReactionsSummaryAndPicker,
@@ -227,26 +276,31 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
227
276
  reactionPickerTriggerIcon: reactionPickerTriggerIcon,
228
277
  reactionPickerTriggerText: reactionPickerTriggerText,
229
278
  isListItem: isListItem
230
- })), settings.isOpen && /*#__PURE__*/React.createElement(PopperWrapper, {
279
+ }))), isPopupTrayOpen && /*#__PURE__*/React.createElement(PopperWrapper, {
231
280
  settings: settings,
232
- popperModifiers: popperModifiers
233
- }, settings.showFullPicker ? /*#__PURE__*/React.createElement(EmojiPicker, {
281
+ popperModifiers: popperModifiers,
282
+ isOpen: isPopupTrayOpen
283
+ }, settings.showFullPicker || hoverableReactionPicker && isHoverableReactionPickerEmojiPickerOpen ? /*#__PURE__*/React.createElement(EmojiPicker, {
234
284
  emojiProvider: emojiProvider,
235
285
  onSelection: onEmojiSelected,
236
286
  size: emojiPickerSize
237
- }) : /*#__PURE__*/React.createElement("div", {
238
- className: ax(["_1e0c1txw"])
287
+ }) : /*#__PURE__*/React.createElement(Box, {
288
+ xcss: additionalStyles.selectorContainer,
289
+ onMouseEnter: handlePopupMouseEnter,
290
+ onMouseLeave: handlePopupMouseLeave
239
291
  }, /*#__PURE__*/React.createElement(Selector, {
240
292
  emojiProvider: emojiProvider,
241
293
  onSelection: onEmojiSelected,
242
294
  showMore: allowAllEmojis,
243
295
  onMoreClick: onSelectMoreClick,
244
- pickerQuickReactionEmojiIds: pickerQuickReactionEmojiIds
296
+ pickerQuickReactionEmojiIds: pickerQuickReactionEmojiIds,
297
+ hoverableReactionPickerSelector: hoverableReactionPicker
245
298
  })))));
246
299
  });
247
300
  export const PopperWrapper = props => {
248
301
  const {
249
302
  settings,
303
+ isOpen,
250
304
  children,
251
305
  popperModifiers
252
306
  } = props;
@@ -296,7 +350,8 @@ export const PopperWrapper = props => {
296
350
  className: ax(["_nt751r31 _49pcglyw _1hvw1o36"])
297
351
  }, /*#__PURE__*/React.createElement(RepositionOnUpdate, {
298
352
  update: update,
299
- settings: settings
353
+ settings: settings,
354
+ isOpen: isOpen
300
355
  }, /*#__PURE__*/React.createElement("div", {
301
356
  className: ax(["_2rko1sit _bfhk1bhr _16qs1kf5 _1bch1b66 _79pa1b66"])
302
357
  }, children)));
@@ -6,6 +6,7 @@ import { forwardRef, useMemo } from 'react';
6
6
  import { useIntl } from 'react-intl-next';
7
7
  import { ResourcedEmoji } from '@atlaskit/emoji';
8
8
  import { messages } from '../shared/i18n';
9
+ import { RESOURCED_EMOJI_COMPACT_HEIGHT } from '../shared/constants';
9
10
  import { Counter } from './Counter';
10
11
  import { ReactionButton } from './ReactionButton';
11
12
  import { Box, Flex, Inline } from '@atlaskit/primitives/compiled';
@@ -80,7 +81,7 @@ export const ReactionSummaryButton = /*#__PURE__*/forwardRef(({
80
81
  id: reaction.emojiId,
81
82
  shortName: ''
82
83
  },
83
- fitToHeight: 16
84
+ fitToHeight: RESOURCED_EMOJI_COMPACT_HEIGHT
84
85
  })))), /*#__PURE__*/React.createElement(Counter, {
85
86
  value: totalReactionsCount,
86
87
  useDarkerFont: useButtonAlignmentStyling,
@@ -302,7 +302,7 @@ export const Reactions = /*#__PURE__*/React.memo(({
302
302
  onOpen: handlePickerOpen,
303
303
  onCancel: handleOnCancel,
304
304
  onShowMore: handleOnMore,
305
- tooltipContent: getTooltip(status, errorMessage, reactionPickerTriggerTooltipContent),
305
+ tooltipContent: hoverableSummaryView ? null : getTooltip(status, errorMessage, reactionPickerTriggerTooltipContent),
306
306
  emojiPickerSize: emojiPickerSize,
307
307
  miniMode: miniMode,
308
308
  showOpaqueBackground: showOpaqueBackground,
@@ -311,6 +311,8 @@ export const Reactions = /*#__PURE__*/React.memo(({
311
311
  reactionPickerTriggerIcon: reactionPickerTriggerIcon,
312
312
  reactionPickerTriggerText: reactionPickerTriggerText,
313
313
  isListItem: isListItem,
314
+ hoverableReactionPicker: hoverableSummaryView,
315
+ hoverableReactionPickerDelay: hoverableSummaryView ? 300 : 0,
314
316
  className: ax(["_1e0c1o8l _19pk1b66"])
315
317
  }), /*#__PURE__*/React.createElement(ModalTransition, null, !!selectedEmojiId && /*#__PURE__*/React.createElement(UFOSegment, {
316
318
  name: "reactions-dialog"
@@ -19,6 +19,7 @@ import { ResourcedEmoji } from '@atlaskit/emoji/element';
19
19
  import { fg } from '@atlaskit/platform-feature-flags';
20
20
  import { messages } from '../shared/i18n';
21
21
  import { Counter } from './Counter';
22
+ import { RESOURCED_EMOJI_COMPACT_HEIGHT } from '../shared/constants';
22
23
  const styles = {
23
24
  leftNavigationStyle: "_19pk1b66 _1wpzynz6 _19bvpxbi _n3tdutpp",
24
25
  rightNavigationStyle: "_19pk1b66 _1wpzynz6 _18u01wug _2hwxu2gc",
@@ -163,7 +164,7 @@ export const ReactionsDialogHeader = ({
163
164
  }, /*#__PURE__*/React.createElement(ResourcedEmoji, {
164
165
  emojiProvider: emojiProvider,
165
166
  emojiId: emojiId,
166
- fitToHeight: 16,
167
+ fitToHeight: RESOURCED_EMOJI_COMPACT_HEIGHT,
167
168
  showTooltip: true
168
169
  })), /*#__PURE__*/React.createElement(Box, {
169
170
  xcss: styles.counterStyle
@@ -6,7 +6,8 @@ import React, { Fragment, useLayoutEffect, useRef } from 'react';
6
6
  export const RepositionOnUpdate = ({
7
7
  children,
8
8
  update,
9
- settings
9
+ settings,
10
+ isOpen
10
11
  }) => {
11
12
  // Ref used here to skip update on first render (when refs haven't been set)
12
13
  const isFirstRenderRef = useRef(true);
@@ -17,7 +18,7 @@ export const RepositionOnUpdate = ({
17
18
  }
18
19
  // callback function from popper that repositions pop-up on content Update
19
20
  update();
20
- }, [update, settings]);
21
+ }, [update, settings, isOpen]);
21
22
 
22
23
  // wrapping in fragment to make TS happy (known issue with FC returning children)
23
24
  return /*#__PURE__*/React.createElement(Fragment, null, children);
@@ -1,4 +1,5 @@
1
- ._12l2u2gc{margin-inline-end:var(--ds-space-100,8px)}
1
+
2
+ ._zulp1b66{gap:var(--ds-space-050,4px)}._12l2u2gc{margin-inline-end:var(--ds-space-100,8px)}
2
3
  ._19bv1b66{padding-left:var(--ds-space-050,4px)}
3
4
  ._1e0c1o8l{display:inline-block}
4
5
  ._1o51q7pw{animation-fill-mode:forwards}
@@ -4,13 +4,16 @@ import * as React from 'react';
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
5
  import { Fragment } from 'react';
6
6
  import Tooltip from '@atlaskit/tooltip';
7
+ import { Box, Inline } from '@atlaskit/primitives/compiled';
8
+ import { messages } from '../shared/i18n';
7
9
  import { DefaultReactions } from '../shared/constants';
8
10
  import { EmojiButton } from './EmojiButton';
9
11
  import { ShowMore } from './ShowMore';
10
- import { Box, Inline } from '@atlaskit/primitives/compiled';
12
+ import { Trigger } from './Trigger';
11
13
  const styles = {
12
14
  container: "_ca0q1b66 _u5f31b66 _n3td1b66 _19bv1b66",
13
- separator: "_t6vde4h9 _5wramuej _1p3lnqa1 _ahbq1b66 _12l2u2gc _4t3i1tcg _1e0c1o8l"
15
+ separator: "_t6vde4h9 _5wramuej _1p3lnqa1 _ahbq1b66 _12l2u2gc _4t3i1tcg _1e0c1o8l",
16
+ hoverableReactionPickerSelectorContainer: "_zulp1b66 _ca0q1b66 _u5f31b66 _n3td1b66 _19bv1b66"
14
17
  };
15
18
  const revealAnimation = null;
16
19
  const revealStyle = null;
@@ -37,7 +40,8 @@ export const Selector = ({
37
40
  onMoreClick,
38
41
  onSelection,
39
42
  showMore,
40
- pickerQuickReactionEmojiIds = DefaultReactions
43
+ pickerQuickReactionEmojiIds = DefaultReactions,
44
+ hoverableReactionPickerSelector = false
41
45
  }) => {
42
46
  /**
43
47
  * Render the default emoji icon
@@ -46,17 +50,33 @@ export const Selector = ({
46
50
  */
47
51
  const renderEmoji = (emoji, index) => {
48
52
  var _emoji$id;
49
- return /*#__PURE__*/React.createElement(Reveal, {
50
- key: (_emoji$id = emoji.id) !== null && _emoji$id !== void 0 ? _emoji$id : emoji.shortName,
51
- testId: RENDER_SELECTOR_TESTID
52
- }, /*#__PURE__*/React.createElement(Tooltip, {
53
+ const emojiButtonAndTooltip = /*#__PURE__*/React.createElement(Tooltip, {
53
54
  content: emoji.shortName
54
55
  }, /*#__PURE__*/React.createElement(EmojiButton, {
55
56
  emojiId: emoji,
56
57
  emojiProvider: emojiProvider,
57
- onClick: onSelection
58
- })));
58
+ onClick: onSelection,
59
+ hoverableReactionPickerSelectorEmoji: hoverableReactionPickerSelector
60
+ }));
61
+ return hoverableReactionPickerSelector ? emojiButtonAndTooltip : /*#__PURE__*/React.createElement(Reveal, {
62
+ key: (_emoji$id = emoji.id) !== null && _emoji$id !== void 0 ? _emoji$id : emoji.shortName,
63
+ testId: RENDER_SELECTOR_TESTID
64
+ }, emojiButtonAndTooltip);
59
65
  };
66
+ if (hoverableReactionPickerSelector) {
67
+ return /*#__PURE__*/React.createElement(Box, {
68
+ xcss: styles.hoverableReactionPickerSelectorContainer
69
+ }, /*#__PURE__*/React.createElement(Trigger, {
70
+ tooltipContent: messages.addReaction.defaultMessage,
71
+ onClick: onMoreClick,
72
+ showAddReactionText: true,
73
+ reactionPickerTriggerText: messages.addNewReaction.defaultMessage,
74
+ fullWidthSelectorTrayReactionPickerTrigger: true
75
+ }), /*#__PURE__*/React.createElement(Inline, {
76
+ alignBlock: "center",
77
+ xcss: hoverableReactionPickerSelector ? styles.hoverableReactionPickerSelectorContainer : styles.container
78
+ }, pickerQuickReactionEmojiIds ? pickerQuickReactionEmojiIds.map(renderEmoji) : null));
79
+ }
60
80
  return /*#__PURE__*/React.createElement(Inline, {
61
81
  alignBlock: "center",
62
82
  xcss: styles.container