@atlaskit/reactions 31.4.0 → 31.5.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @atlaskit/reactions
2
2
 
3
+ ## 31.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#145160](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/145160)
8
+ [`cab4c531afd63`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cab4c531afd63) -
9
+ [ux] Modifies the clicking behavior for the hoverable summary view feature
10
+
3
11
  ## 31.4.0
4
12
 
5
13
  ### Minor Changes
@@ -11,7 +11,7 @@ var _analyticsGasTypes = require("@atlaskit/analytics-gas-types");
11
11
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
12
12
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
13
13
  var packageName = "@atlaskit/reactions";
14
- var packageVersion = "31.4.0";
14
+ var packageVersion = "31.5.0";
15
15
  /**
16
16
  * TODO: move to utility package?
17
17
  * A random sampling function
@@ -277,6 +277,8 @@ var PopperWrapper = exports.PopperWrapper = function PopperWrapper(props) {
277
277
  _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
278
278
  popupRef = _useState6[0],
279
279
  setPopupRef = _useState6[1];
280
+ var _useIntl = (0, _reactIntlNext.useIntl)(),
281
+ formatMessage = _useIntl.formatMessage;
280
282
  /**
281
283
  * add focus lock to popup
282
284
  */
@@ -293,6 +295,8 @@ var PopperWrapper = exports.PopperWrapper = function PopperWrapper(props) {
293
295
  style = _ref3.style,
294
296
  update = _ref3.update;
295
297
  return /*#__PURE__*/_react.default.createElement("div", {
298
+ role: "group",
299
+ "aria-label": formatMessage(_i18n.messages.popperWrapperLabel),
296
300
  id: PICKER_CONTROL_ID,
297
301
  "data-testid": RENDER_REACTIONPICKERPANEL_TESTID
298
302
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
@@ -14,10 +14,12 @@ var _runtime = require("@compiled/react/runtime");
14
14
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
15
15
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
16
16
  var _popup = _interopRequireDefault(require("@atlaskit/popup"));
17
+ var _picker = require("@atlaskit/emoji/picker");
17
18
  var _useDelayedState3 = require("../hooks/useDelayedState");
18
19
  var _Reaction = require("./Reaction");
19
20
  var _ReactionSummaryViewEmojiPicker = require("./ReactionSummaryViewEmojiPicker");
20
21
  var _ReactionSummaryButton = require("./ReactionSummaryButton");
22
+ var _ufo = require("../ufo");
21
23
  var _compiled = require("@atlaskit/primitives/compiled");
22
24
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
23
25
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -75,36 +77,83 @@ var ReactionSummaryView = exports.ReactionSummaryView = function ReactionSummary
75
77
  _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
76
78
  isSummaryViewButtonHovered = _useState4[0],
77
79
  setIsSummaryViewButtonHovered = _useState4[1];
80
+ var _useState5 = (0, _react.useState)(false),
81
+ _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
82
+ isSummaryButtonEmojiPickerOpen = _useState6[0],
83
+ setIsSummaryButtonEmojiPickerOpen = _useState6[1];
84
+ var _useState7 = (0, _react.useState)(false),
85
+ _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
86
+ isSummaryViewTrayEmojiPickerOpen = _useState8[0],
87
+ setIsSummaryViewTrayEmojiPickerOpen = _useState8[1];
88
+
89
+ /**
90
+ * Event callback when the picker is closed
91
+ * @param _id Optional id if an emoji button was selected or undefined if was clicked outside the picker
92
+ */
93
+ var close = (0, _react.useCallback)(function (_id) {
94
+ setIsSummaryButtonEmojiPickerOpen(false);
95
+ // ufo abort reaction experience
96
+ _ufo.PickerRender.abort({
97
+ metadata: {
98
+ emojiId: _id,
99
+ source: 'ReactionPicker',
100
+ reason: 'close dialog'
101
+ }
102
+ });
103
+ }, [setIsSummaryButtonEmojiPickerOpen]);
104
+ /**
105
+ * Event callback when an emoji icon is selected
106
+ * @param item selected item
107
+ */
108
+ var onEmojiSelected = (0, _react.useCallback)(function (item) {
109
+ // no emoji was selected
110
+ if (!item.id) {
111
+ return;
112
+ }
113
+ onSelection(item.id, 'emojiPicker');
114
+ close(item.id);
115
+ }, [onSelection, close]);
78
116
  var handlePopupClose = (0, _react.useCallback)(function () {
79
- return setSummaryPopupOpen(false);
80
- }, [setSummaryPopupOpen]);
117
+ setSummaryPopupOpen(false);
118
+ setIsSummaryButtonEmojiPickerOpen(false);
119
+ }, [setSummaryPopupOpen, setIsSummaryButtonEmojiPickerOpen]);
81
120
  var handleSummaryClick = (0, _react.useCallback)(function () {
82
- return setSummaryPopupOpen(!isSummaryPopupOpen);
83
- }, [isSummaryPopupOpen, setSummaryPopupOpen]);
121
+ if (hoverableSummaryView) {
122
+ // ufo start reactions picker open experience
123
+ _ufo.PickerRender.start();
124
+ onOpen && onOpen();
125
+ setSummaryPopupOpen(false);
126
+ // ufo reactions picker opened success
127
+ _ufo.PickerRender.success();
128
+ } else {
129
+ setSummaryPopupOpen(!isSummaryPopupOpen);
130
+ }
131
+ setIsSummaryButtonEmojiPickerOpen(!isSummaryButtonEmojiPickerOpen);
132
+ }, [isSummaryPopupOpen, onOpen, isSummaryButtonEmojiPickerOpen, hoverableSummaryView, setSummaryPopupOpen, setIsSummaryButtonEmojiPickerOpen]);
84
133
  var handleButtonMouseEnter = (0, _react.useCallback)(function () {
85
134
  setIsSummaryViewButtonHovered(true);
86
- if (hoverableSummaryView) {
135
+ if (hoverableSummaryView && !isSummaryButtonEmojiPickerOpen) {
87
136
  setSummaryPopupOpen(true);
88
137
  }
89
- }, [hoverableSummaryView, setSummaryPopupOpen]);
138
+ }, [hoverableSummaryView, setSummaryPopupOpen, setIsSummaryViewButtonHovered, isSummaryButtonEmojiPickerOpen]);
90
139
  var handleButtonMouseLeave = (0, _react.useCallback)(function () {
91
140
  setIsSummaryViewButtonHovered(false);
92
- if (hoverableSummaryView && !isHoveringSummaryView) {
141
+ if (hoverableSummaryView && !isHoveringSummaryView && !isSummaryViewTrayEmojiPickerOpen) {
93
142
  setSummaryPopupOpen(false);
94
143
  }
95
- }, [hoverableSummaryView, isHoveringSummaryView, setSummaryPopupOpen]);
144
+ }, [hoverableSummaryView, isHoveringSummaryView, setSummaryPopupOpen, setIsSummaryViewButtonHovered, isSummaryViewTrayEmojiPickerOpen]);
96
145
  var handleSummaryViewTrayMouseEnter = (0, _react.useCallback)(function () {
97
146
  setIsHoveringSummaryView(true);
98
- if (hoverableSummaryView) {
147
+ if (hoverableSummaryView && !isSummaryButtonEmojiPickerOpen) {
99
148
  setSummaryPopupOpen(true);
100
149
  }
101
- }, [hoverableSummaryView, setSummaryPopupOpen]);
150
+ }, [hoverableSummaryView, setSummaryPopupOpen, setIsHoveringSummaryView, isSummaryButtonEmojiPickerOpen]);
102
151
  var handleSummaryViewTrayMouseLeave = (0, _react.useCallback)(function () {
103
152
  setIsHoveringSummaryView(false);
104
- if (hoverableSummaryView && !isSummaryViewButtonHovered) {
153
+ if (hoverableSummaryView && !isSummaryViewButtonHovered && !isSummaryViewTrayEmojiPickerOpen) {
105
154
  setSummaryPopupOpen(false);
106
155
  }
107
- }, [hoverableSummaryView, isSummaryViewButtonHovered, setSummaryPopupOpen]);
156
+ }, [hoverableSummaryView, isSummaryViewButtonHovered, setIsHoveringSummaryView, setSummaryPopupOpen, isSummaryViewTrayEmojiPickerOpen]);
108
157
  var handleEmojiSelection = (0, _react.useCallback)(function (emojiId, source) {
109
158
  onSelection(emojiId, source);
110
159
  if (hoverableSummaryView) {
@@ -114,12 +163,17 @@ var ReactionSummaryView = exports.ReactionSummaryView = function ReactionSummary
114
163
  return /*#__PURE__*/React.createElement(_popup.default, {
115
164
  placement: placement,
116
165
  content: function content() {
117
- return /*#__PURE__*/React.createElement(_compiled.Box, {
166
+ return isSummaryButtonEmojiPickerOpen && hoverableSummaryView ? /*#__PURE__*/React.createElement(_picker.EmojiPicker, {
167
+ emojiProvider: emojiProvider,
168
+ onSelection: onEmojiSelected,
169
+ size: emojiPickerSize
170
+ }) : /*#__PURE__*/React.createElement(_compiled.Box, {
118
171
  testId: RENDER_SUMMARY_VIEW_POPUP_TESTID,
119
172
  onMouseEnter: handleSummaryViewTrayMouseEnter,
120
173
  onMouseLeave: handleSummaryViewTrayMouseLeave
121
174
  }, allowSelectFromSummaryView && /*#__PURE__*/React.createElement(_compiled.Flex, {
122
- justifyContent: "center"
175
+ justifyContent: "center",
176
+ testId: "reaction-summary-view-emoji-picker-container"
123
177
  }, /*#__PURE__*/React.createElement(_ReactionSummaryViewEmojiPicker.ReactionSummaryViewEmojiPicker, {
124
178
  emojiProvider: emojiProvider,
125
179
  disabled: disabled,
@@ -128,7 +182,8 @@ var ReactionSummaryView = exports.ReactionSummaryView = function ReactionSummary
128
182
  tooltipContent: tooltipContent,
129
183
  reactionPickerTriggerIcon: reactionPickerTriggerIcon,
130
184
  reactionPickerTriggerText: reactionPickerTriggerText,
131
- onOpen: onOpen
185
+ onOpen: onOpen,
186
+ setIsSummaryViewTrayEmojiPickerOpen: setIsSummaryViewTrayEmojiPickerOpen
132
187
  })), /*#__PURE__*/React.createElement(_compiled.Inline, {
133
188
  xcss: styles.summaryPopup,
134
189
  space: "space.025",
@@ -150,7 +205,7 @@ var ReactionSummaryView = exports.ReactionSummaryView = function ReactionSummary
150
205
  });
151
206
  })));
152
207
  },
153
- isOpen: isSummaryPopupOpen,
208
+ isOpen: isSummaryPopupOpen || isSummaryButtonEmojiPickerOpen,
154
209
  onClose: handlePopupClose,
155
210
  trigger: function trigger(triggerProps) {
156
211
  return /*#__PURE__*/React.createElement(_ReactionSummaryButton.ReactionSummaryButton, (0, _extends2.default)({}, triggerProps, {
@@ -23,7 +23,8 @@ var ReactionSummaryViewEmojiPicker = exports.ReactionSummaryViewEmojiPicker = fu
23
23
  reactionPickerTriggerIcon = _ref.reactionPickerTriggerIcon,
24
24
  tooltipContent = _ref.tooltipContent,
25
25
  onOpen = _ref.onOpen,
26
- reactionPickerTriggerText = _ref.reactionPickerTriggerText;
26
+ reactionPickerTriggerText = _ref.reactionPickerTriggerText,
27
+ setIsSummaryViewTrayEmojiPickerOpen = _ref.setIsSummaryViewTrayEmojiPickerOpen;
27
28
  var _useState = (0, _react.useState)(false),
28
29
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
29
30
  isOpen = _useState2[0],
@@ -31,9 +32,9 @@ var ReactionSummaryViewEmojiPicker = exports.ReactionSummaryViewEmojiPicker = fu
31
32
  var handleClick = function handleClick() {
32
33
  // ufo start reactions picker open experience
33
34
  _ufo.PickerRender.start();
34
- setIsOpen(function (prevIsOpen) {
35
- return !prevIsOpen;
36
- });
35
+ var newIsOpen = !isOpen;
36
+ setIsOpen(newIsOpen);
37
+ setIsSummaryViewTrayEmojiPickerOpen && setIsSummaryViewTrayEmojiPickerOpen(newIsOpen);
37
38
  onOpen && onOpen();
38
39
 
39
40
  // ufo reactions picker opened success
@@ -46,6 +47,7 @@ var ReactionSummaryViewEmojiPicker = exports.ReactionSummaryViewEmojiPicker = fu
46
47
  */
47
48
  var close = (0, _react.useCallback)(function (_id) {
48
49
  setIsOpen(false);
50
+ setIsSummaryViewTrayEmojiPickerOpen && setIsSummaryViewTrayEmojiPickerOpen(false);
49
51
  // ufo abort reaction experience
50
52
  _ufo.PickerRender.abort({
51
53
  metadata: {
@@ -54,7 +56,7 @@ var ReactionSummaryViewEmojiPicker = exports.ReactionSummaryViewEmojiPicker = fu
54
56
  reason: 'close dialog'
55
57
  }
56
58
  });
57
- }, [setIsOpen]);
59
+ }, [setIsOpen, setIsSummaryViewTrayEmojiPickerOpen]);
58
60
 
59
61
  /**
60
62
  * Event callback when an emoji icon is selected
@@ -72,7 +74,7 @@ var ReactionSummaryViewEmojiPicker = exports.ReactionSummaryViewEmojiPicker = fu
72
74
  testId: "reaction-summary-view-emoji-picker",
73
75
  isOpen: isOpen,
74
76
  placement: "bottom-start",
75
- offset: [-10, -66],
77
+ offset: [-10, -34],
76
78
  onClose: function onClose() {
77
79
  return close();
78
80
  },
@@ -75,5 +75,10 @@ var messages = exports.messages = (0, _reactIntlNext.defineMessages)({
75
75
  id: 'reactions.dialog.viewall.tooltip',
76
76
  defaultMessage: 'View all user reactions',
77
77
  description: 'Tooltip content of see who reacted link'
78
+ },
79
+ popperWrapperLabel: {
80
+ id: 'reactions-reaction.picker-label',
81
+ defaultMessage: 'Add reactions',
82
+ description: 'A label to the reaction picker group'
78
83
  }
79
84
  });
@@ -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.4.0";
4
+ const packageVersion = "31.5.0";
5
5
  /**
6
6
  * TODO: move to utility package?
7
7
  * A random sampling function
@@ -2,7 +2,7 @@
2
2
  import "./ReactionPicker.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
5
- import { FormattedMessage } from 'react-intl-next';
5
+ 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';
@@ -249,6 +249,9 @@ export const PopperWrapper = props => {
249
249
  popperModifiers
250
250
  } = props;
251
251
  const [popupRef, setPopupRef] = useState(null);
252
+ const {
253
+ formatMessage
254
+ } = useIntl();
252
255
  /**
253
256
  * add focus lock to popup
254
257
  */
@@ -266,6 +269,8 @@ export const PopperWrapper = props => {
266
269
  update
267
270
  }) => {
268
271
  return /*#__PURE__*/React.createElement("div", {
272
+ role: "group",
273
+ "aria-label": formatMessage(messages.popperWrapperLabel),
269
274
  id: PICKER_CONTROL_ID,
270
275
  "data-testid": RENDER_REACTIONPICKERPANEL_TESTID
271
276
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
@@ -5,10 +5,12 @@ import * as React from 'react';
5
5
  import { ax, ix } from "@compiled/react/runtime";
6
6
  import { useCallback, useState } from 'react';
7
7
  import Popup from '@atlaskit/popup';
8
+ import { EmojiPicker } from '@atlaskit/emoji/picker';
8
9
  import { useDelayedState } from '../hooks/useDelayedState';
9
10
  import { Reaction } from './Reaction';
10
11
  import { ReactionSummaryViewEmojiPicker } from './ReactionSummaryViewEmojiPicker';
11
12
  import { ReactionSummaryButton } from './ReactionSummaryButton';
13
+ import { PickerRender } from '../ufo';
12
14
  import { Box, Flex, Inline } from '@atlaskit/primitives/compiled';
13
15
  const styles = {
14
16
  summaryPopup: "_ca0q1b66 _u5f3u2gc _n3tdu2gc _19bvu2gc _p12foiq5"
@@ -47,32 +49,77 @@ export const ReactionSummaryView = ({
47
49
  const [isSummaryPopupOpen, setSummaryPopupOpen] = useDelayedState(false, hoverableSummaryViewDelay);
48
50
  const [isHoveringSummaryView, setIsHoveringSummaryView] = useState(false);
49
51
  const [isSummaryViewButtonHovered, setIsSummaryViewButtonHovered] = useState(false);
50
- const handlePopupClose = useCallback(() => setSummaryPopupOpen(false), [setSummaryPopupOpen]);
51
- const handleSummaryClick = useCallback(() => setSummaryPopupOpen(!isSummaryPopupOpen), [isSummaryPopupOpen, setSummaryPopupOpen]);
52
+ const [isSummaryButtonEmojiPickerOpen, setIsSummaryButtonEmojiPickerOpen] = useState(false);
53
+ const [isSummaryViewTrayEmojiPickerOpen, setIsSummaryViewTrayEmojiPickerOpen] = useState(false);
54
+
55
+ /**
56
+ * Event callback when the picker is closed
57
+ * @param _id Optional id if an emoji button was selected or undefined if was clicked outside the picker
58
+ */
59
+ const close = useCallback(_id => {
60
+ setIsSummaryButtonEmojiPickerOpen(false);
61
+ // ufo abort reaction experience
62
+ PickerRender.abort({
63
+ metadata: {
64
+ emojiId: _id,
65
+ source: 'ReactionPicker',
66
+ reason: 'close dialog'
67
+ }
68
+ });
69
+ }, [setIsSummaryButtonEmojiPickerOpen]);
70
+ /**
71
+ * Event callback when an emoji icon is selected
72
+ * @param item selected item
73
+ */
74
+ const onEmojiSelected = useCallback(item => {
75
+ // no emoji was selected
76
+ if (!item.id) {
77
+ return;
78
+ }
79
+ onSelection(item.id, 'emojiPicker');
80
+ close(item.id);
81
+ }, [onSelection, close]);
82
+ const handlePopupClose = useCallback(() => {
83
+ setSummaryPopupOpen(false);
84
+ setIsSummaryButtonEmojiPickerOpen(false);
85
+ }, [setSummaryPopupOpen, setIsSummaryButtonEmojiPickerOpen]);
86
+ const handleSummaryClick = useCallback(() => {
87
+ if (hoverableSummaryView) {
88
+ // ufo start reactions picker open experience
89
+ PickerRender.start();
90
+ onOpen && onOpen();
91
+ setSummaryPopupOpen(false);
92
+ // ufo reactions picker opened success
93
+ PickerRender.success();
94
+ } else {
95
+ setSummaryPopupOpen(!isSummaryPopupOpen);
96
+ }
97
+ setIsSummaryButtonEmojiPickerOpen(!isSummaryButtonEmojiPickerOpen);
98
+ }, [isSummaryPopupOpen, onOpen, isSummaryButtonEmojiPickerOpen, hoverableSummaryView, setSummaryPopupOpen, setIsSummaryButtonEmojiPickerOpen]);
52
99
  const handleButtonMouseEnter = useCallback(() => {
53
100
  setIsSummaryViewButtonHovered(true);
54
- if (hoverableSummaryView) {
101
+ if (hoverableSummaryView && !isSummaryButtonEmojiPickerOpen) {
55
102
  setSummaryPopupOpen(true);
56
103
  }
57
- }, [hoverableSummaryView, setSummaryPopupOpen]);
104
+ }, [hoverableSummaryView, setSummaryPopupOpen, setIsSummaryViewButtonHovered, isSummaryButtonEmojiPickerOpen]);
58
105
  const handleButtonMouseLeave = useCallback(() => {
59
106
  setIsSummaryViewButtonHovered(false);
60
- if (hoverableSummaryView && !isHoveringSummaryView) {
107
+ if (hoverableSummaryView && !isHoveringSummaryView && !isSummaryViewTrayEmojiPickerOpen) {
61
108
  setSummaryPopupOpen(false);
62
109
  }
63
- }, [hoverableSummaryView, isHoveringSummaryView, setSummaryPopupOpen]);
110
+ }, [hoverableSummaryView, isHoveringSummaryView, setSummaryPopupOpen, setIsSummaryViewButtonHovered, isSummaryViewTrayEmojiPickerOpen]);
64
111
  const handleSummaryViewTrayMouseEnter = useCallback(() => {
65
112
  setIsHoveringSummaryView(true);
66
- if (hoverableSummaryView) {
113
+ if (hoverableSummaryView && !isSummaryButtonEmojiPickerOpen) {
67
114
  setSummaryPopupOpen(true);
68
115
  }
69
- }, [hoverableSummaryView, setSummaryPopupOpen]);
116
+ }, [hoverableSummaryView, setSummaryPopupOpen, setIsHoveringSummaryView, isSummaryButtonEmojiPickerOpen]);
70
117
  const handleSummaryViewTrayMouseLeave = useCallback(() => {
71
118
  setIsHoveringSummaryView(false);
72
- if (hoverableSummaryView && !isSummaryViewButtonHovered) {
119
+ if (hoverableSummaryView && !isSummaryViewButtonHovered && !isSummaryViewTrayEmojiPickerOpen) {
73
120
  setSummaryPopupOpen(false);
74
121
  }
75
- }, [hoverableSummaryView, isSummaryViewButtonHovered, setSummaryPopupOpen]);
122
+ }, [hoverableSummaryView, isSummaryViewButtonHovered, setIsHoveringSummaryView, setSummaryPopupOpen, isSummaryViewTrayEmojiPickerOpen]);
76
123
  const handleEmojiSelection = useCallback((emojiId, source) => {
77
124
  onSelection(emojiId, source);
78
125
  if (hoverableSummaryView) {
@@ -81,12 +128,17 @@ export const ReactionSummaryView = ({
81
128
  }, [onSelection, hoverableSummaryView, setSummaryPopupOpen]);
82
129
  return /*#__PURE__*/React.createElement(Popup, {
83
130
  placement: placement,
84
- content: () => /*#__PURE__*/React.createElement(Box, {
131
+ content: () => isSummaryButtonEmojiPickerOpen && hoverableSummaryView ? /*#__PURE__*/React.createElement(EmojiPicker, {
132
+ emojiProvider: emojiProvider,
133
+ onSelection: onEmojiSelected,
134
+ size: emojiPickerSize
135
+ }) : /*#__PURE__*/React.createElement(Box, {
85
136
  testId: RENDER_SUMMARY_VIEW_POPUP_TESTID,
86
137
  onMouseEnter: handleSummaryViewTrayMouseEnter,
87
138
  onMouseLeave: handleSummaryViewTrayMouseLeave
88
139
  }, allowSelectFromSummaryView && /*#__PURE__*/React.createElement(Flex, {
89
- justifyContent: "center"
140
+ justifyContent: "center",
141
+ testId: "reaction-summary-view-emoji-picker-container"
90
142
  }, /*#__PURE__*/React.createElement(ReactionSummaryViewEmojiPicker, {
91
143
  emojiProvider: emojiProvider,
92
144
  disabled: disabled,
@@ -95,7 +147,8 @@ export const ReactionSummaryView = ({
95
147
  tooltipContent: tooltipContent,
96
148
  reactionPickerTriggerIcon: reactionPickerTriggerIcon,
97
149
  reactionPickerTriggerText: reactionPickerTriggerText,
98
- onOpen: onOpen
150
+ onOpen: onOpen,
151
+ setIsSummaryViewTrayEmojiPickerOpen: setIsSummaryViewTrayEmojiPickerOpen
99
152
  })), /*#__PURE__*/React.createElement(Inline, {
100
153
  xcss: styles.summaryPopup,
101
154
  space: "space.025",
@@ -114,7 +167,7 @@ export const ReactionSummaryView = ({
114
167
  handleOpenReactionsDialog: handleOpenReactionsDialog,
115
168
  isViewOnly: isViewOnly
116
169
  })))),
117
- isOpen: isSummaryPopupOpen,
170
+ isOpen: isSummaryPopupOpen || isSummaryButtonEmojiPickerOpen,
118
171
  onClose: handlePopupClose,
119
172
  trigger: triggerProps => /*#__PURE__*/React.createElement(ReactionSummaryButton, _extends({}, triggerProps, {
120
173
  emojiProvider: emojiProvider,
@@ -12,13 +12,16 @@ export const ReactionSummaryViewEmojiPicker = ({
12
12
  reactionPickerTriggerIcon,
13
13
  tooltipContent,
14
14
  onOpen,
15
- reactionPickerTriggerText
15
+ reactionPickerTriggerText,
16
+ setIsSummaryViewTrayEmojiPickerOpen
16
17
  }) => {
17
18
  const [isOpen, setIsOpen] = useState(false);
18
19
  const handleClick = () => {
19
20
  // ufo start reactions picker open experience
20
21
  PickerRender.start();
21
- setIsOpen(prevIsOpen => !prevIsOpen);
22
+ const newIsOpen = !isOpen;
23
+ setIsOpen(newIsOpen);
24
+ setIsSummaryViewTrayEmojiPickerOpen && setIsSummaryViewTrayEmojiPickerOpen(newIsOpen);
22
25
  onOpen && onOpen();
23
26
 
24
27
  // ufo reactions picker opened success
@@ -31,6 +34,7 @@ export const ReactionSummaryViewEmojiPicker = ({
31
34
  */
32
35
  const close = useCallback(_id => {
33
36
  setIsOpen(false);
37
+ setIsSummaryViewTrayEmojiPickerOpen && setIsSummaryViewTrayEmojiPickerOpen(false);
34
38
  // ufo abort reaction experience
35
39
  PickerRender.abort({
36
40
  metadata: {
@@ -39,7 +43,7 @@ export const ReactionSummaryViewEmojiPicker = ({
39
43
  reason: 'close dialog'
40
44
  }
41
45
  });
42
- }, [setIsOpen]);
46
+ }, [setIsOpen, setIsSummaryViewTrayEmojiPickerOpen]);
43
47
 
44
48
  /**
45
49
  * Event callback when an emoji icon is selected
@@ -57,7 +61,7 @@ export const ReactionSummaryViewEmojiPicker = ({
57
61
  testId: "reaction-summary-view-emoji-picker",
58
62
  isOpen: isOpen,
59
63
  placement: "bottom-start",
60
- offset: [-10, -66],
64
+ offset: [-10, -34],
61
65
  onClose: () => close(),
62
66
  content: () => /*#__PURE__*/React.createElement(EmojiPicker, {
63
67
  emojiProvider: emojiProvider,
@@ -72,5 +72,10 @@ export const messages = defineMessages({
72
72
  id: 'reactions.dialog.viewall.tooltip',
73
73
  defaultMessage: 'View all user reactions',
74
74
  description: 'Tooltip content of see who reacted link'
75
+ },
76
+ popperWrapperLabel: {
77
+ id: 'reactions-reaction.picker-label',
78
+ defaultMessage: 'Add reactions',
79
+ description: 'A label to the reaction picker group'
75
80
  }
76
81
  });
@@ -4,7 +4,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
4
4
  import { createAndFireEvent } from '@atlaskit/analytics-next';
5
5
  import { UI_EVENT_TYPE, OPERATIONAL_EVENT_TYPE } from '@atlaskit/analytics-gas-types';
6
6
  var packageName = "@atlaskit/reactions";
7
- var packageVersion = "31.4.0";
7
+ var packageVersion = "31.5.0";
8
8
  /**
9
9
  * TODO: move to utility package?
10
10
  * A random sampling function
@@ -6,7 +6,7 @@ import { ax, ix } from "@compiled/react/runtime";
6
6
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
7
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
8
  import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
9
- import { FormattedMessage } from 'react-intl-next';
9
+ import { FormattedMessage, useIntl } from 'react-intl-next';
10
10
  import { EmojiPicker } from '@atlaskit/emoji/picker';
11
11
  import { Manager, Popper, Reference } from '@atlaskit/popper';
12
12
  import { layers } from '@atlaskit/theme/constants';
@@ -268,6 +268,8 @@ export var PopperWrapper = function PopperWrapper(props) {
268
268
  _useState6 = _slicedToArray(_useState5, 2),
269
269
  popupRef = _useState6[0],
270
270
  setPopupRef = _useState6[1];
271
+ var _useIntl = useIntl(),
272
+ formatMessage = _useIntl.formatMessage;
271
273
  /**
272
274
  * add focus lock to popup
273
275
  */
@@ -284,6 +286,8 @@ export var PopperWrapper = function PopperWrapper(props) {
284
286
  style = _ref3.style,
285
287
  update = _ref3.update;
286
288
  return /*#__PURE__*/React.createElement("div", {
289
+ role: "group",
290
+ "aria-label": formatMessage(messages.popperWrapperLabel),
287
291
  id: PICKER_CONTROL_ID,
288
292
  "data-testid": RENDER_REACTIONPICKERPANEL_TESTID
289
293
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
@@ -6,10 +6,12 @@ import * as React from 'react';
6
6
  import { ax, ix } from "@compiled/react/runtime";
7
7
  import { useCallback, useState } from 'react';
8
8
  import Popup from '@atlaskit/popup';
9
+ import { EmojiPicker } from '@atlaskit/emoji/picker';
9
10
  import { useDelayedState } from '../hooks/useDelayedState';
10
11
  import { Reaction } from './Reaction';
11
12
  import { ReactionSummaryViewEmojiPicker } from './ReactionSummaryViewEmojiPicker';
12
13
  import { ReactionSummaryButton } from './ReactionSummaryButton';
14
+ import { PickerRender } from '../ufo';
13
15
  import { Box, Flex, Inline } from '@atlaskit/primitives/compiled';
14
16
  var styles = {
15
17
  summaryPopup: "_ca0q1b66 _u5f3u2gc _n3tdu2gc _19bvu2gc _p12foiq5"
@@ -65,36 +67,83 @@ export var ReactionSummaryView = function ReactionSummaryView(_ref) {
65
67
  _useState4 = _slicedToArray(_useState3, 2),
66
68
  isSummaryViewButtonHovered = _useState4[0],
67
69
  setIsSummaryViewButtonHovered = _useState4[1];
70
+ var _useState5 = useState(false),
71
+ _useState6 = _slicedToArray(_useState5, 2),
72
+ isSummaryButtonEmojiPickerOpen = _useState6[0],
73
+ setIsSummaryButtonEmojiPickerOpen = _useState6[1];
74
+ var _useState7 = useState(false),
75
+ _useState8 = _slicedToArray(_useState7, 2),
76
+ isSummaryViewTrayEmojiPickerOpen = _useState8[0],
77
+ setIsSummaryViewTrayEmojiPickerOpen = _useState8[1];
78
+
79
+ /**
80
+ * Event callback when the picker is closed
81
+ * @param _id Optional id if an emoji button was selected or undefined if was clicked outside the picker
82
+ */
83
+ var close = useCallback(function (_id) {
84
+ setIsSummaryButtonEmojiPickerOpen(false);
85
+ // ufo abort reaction experience
86
+ PickerRender.abort({
87
+ metadata: {
88
+ emojiId: _id,
89
+ source: 'ReactionPicker',
90
+ reason: 'close dialog'
91
+ }
92
+ });
93
+ }, [setIsSummaryButtonEmojiPickerOpen]);
94
+ /**
95
+ * Event callback when an emoji icon is selected
96
+ * @param item selected item
97
+ */
98
+ var onEmojiSelected = useCallback(function (item) {
99
+ // no emoji was selected
100
+ if (!item.id) {
101
+ return;
102
+ }
103
+ onSelection(item.id, 'emojiPicker');
104
+ close(item.id);
105
+ }, [onSelection, close]);
68
106
  var handlePopupClose = useCallback(function () {
69
- return setSummaryPopupOpen(false);
70
- }, [setSummaryPopupOpen]);
107
+ setSummaryPopupOpen(false);
108
+ setIsSummaryButtonEmojiPickerOpen(false);
109
+ }, [setSummaryPopupOpen, setIsSummaryButtonEmojiPickerOpen]);
71
110
  var handleSummaryClick = useCallback(function () {
72
- return setSummaryPopupOpen(!isSummaryPopupOpen);
73
- }, [isSummaryPopupOpen, setSummaryPopupOpen]);
111
+ if (hoverableSummaryView) {
112
+ // ufo start reactions picker open experience
113
+ PickerRender.start();
114
+ onOpen && onOpen();
115
+ setSummaryPopupOpen(false);
116
+ // ufo reactions picker opened success
117
+ PickerRender.success();
118
+ } else {
119
+ setSummaryPopupOpen(!isSummaryPopupOpen);
120
+ }
121
+ setIsSummaryButtonEmojiPickerOpen(!isSummaryButtonEmojiPickerOpen);
122
+ }, [isSummaryPopupOpen, onOpen, isSummaryButtonEmojiPickerOpen, hoverableSummaryView, setSummaryPopupOpen, setIsSummaryButtonEmojiPickerOpen]);
74
123
  var handleButtonMouseEnter = useCallback(function () {
75
124
  setIsSummaryViewButtonHovered(true);
76
- if (hoverableSummaryView) {
125
+ if (hoverableSummaryView && !isSummaryButtonEmojiPickerOpen) {
77
126
  setSummaryPopupOpen(true);
78
127
  }
79
- }, [hoverableSummaryView, setSummaryPopupOpen]);
128
+ }, [hoverableSummaryView, setSummaryPopupOpen, setIsSummaryViewButtonHovered, isSummaryButtonEmojiPickerOpen]);
80
129
  var handleButtonMouseLeave = useCallback(function () {
81
130
  setIsSummaryViewButtonHovered(false);
82
- if (hoverableSummaryView && !isHoveringSummaryView) {
131
+ if (hoverableSummaryView && !isHoveringSummaryView && !isSummaryViewTrayEmojiPickerOpen) {
83
132
  setSummaryPopupOpen(false);
84
133
  }
85
- }, [hoverableSummaryView, isHoveringSummaryView, setSummaryPopupOpen]);
134
+ }, [hoverableSummaryView, isHoveringSummaryView, setSummaryPopupOpen, setIsSummaryViewButtonHovered, isSummaryViewTrayEmojiPickerOpen]);
86
135
  var handleSummaryViewTrayMouseEnter = useCallback(function () {
87
136
  setIsHoveringSummaryView(true);
88
- if (hoverableSummaryView) {
137
+ if (hoverableSummaryView && !isSummaryButtonEmojiPickerOpen) {
89
138
  setSummaryPopupOpen(true);
90
139
  }
91
- }, [hoverableSummaryView, setSummaryPopupOpen]);
140
+ }, [hoverableSummaryView, setSummaryPopupOpen, setIsHoveringSummaryView, isSummaryButtonEmojiPickerOpen]);
92
141
  var handleSummaryViewTrayMouseLeave = useCallback(function () {
93
142
  setIsHoveringSummaryView(false);
94
- if (hoverableSummaryView && !isSummaryViewButtonHovered) {
143
+ if (hoverableSummaryView && !isSummaryViewButtonHovered && !isSummaryViewTrayEmojiPickerOpen) {
95
144
  setSummaryPopupOpen(false);
96
145
  }
97
- }, [hoverableSummaryView, isSummaryViewButtonHovered, setSummaryPopupOpen]);
146
+ }, [hoverableSummaryView, isSummaryViewButtonHovered, setIsHoveringSummaryView, setSummaryPopupOpen, isSummaryViewTrayEmojiPickerOpen]);
98
147
  var handleEmojiSelection = useCallback(function (emojiId, source) {
99
148
  onSelection(emojiId, source);
100
149
  if (hoverableSummaryView) {
@@ -104,12 +153,17 @@ export var ReactionSummaryView = function ReactionSummaryView(_ref) {
104
153
  return /*#__PURE__*/React.createElement(Popup, {
105
154
  placement: placement,
106
155
  content: function content() {
107
- return /*#__PURE__*/React.createElement(Box, {
156
+ return isSummaryButtonEmojiPickerOpen && hoverableSummaryView ? /*#__PURE__*/React.createElement(EmojiPicker, {
157
+ emojiProvider: emojiProvider,
158
+ onSelection: onEmojiSelected,
159
+ size: emojiPickerSize
160
+ }) : /*#__PURE__*/React.createElement(Box, {
108
161
  testId: RENDER_SUMMARY_VIEW_POPUP_TESTID,
109
162
  onMouseEnter: handleSummaryViewTrayMouseEnter,
110
163
  onMouseLeave: handleSummaryViewTrayMouseLeave
111
164
  }, allowSelectFromSummaryView && /*#__PURE__*/React.createElement(Flex, {
112
- justifyContent: "center"
165
+ justifyContent: "center",
166
+ testId: "reaction-summary-view-emoji-picker-container"
113
167
  }, /*#__PURE__*/React.createElement(ReactionSummaryViewEmojiPicker, {
114
168
  emojiProvider: emojiProvider,
115
169
  disabled: disabled,
@@ -118,7 +172,8 @@ export var ReactionSummaryView = function ReactionSummaryView(_ref) {
118
172
  tooltipContent: tooltipContent,
119
173
  reactionPickerTriggerIcon: reactionPickerTriggerIcon,
120
174
  reactionPickerTriggerText: reactionPickerTriggerText,
121
- onOpen: onOpen
175
+ onOpen: onOpen,
176
+ setIsSummaryViewTrayEmojiPickerOpen: setIsSummaryViewTrayEmojiPickerOpen
122
177
  })), /*#__PURE__*/React.createElement(Inline, {
123
178
  xcss: styles.summaryPopup,
124
179
  space: "space.025",
@@ -140,7 +195,7 @@ export var ReactionSummaryView = function ReactionSummaryView(_ref) {
140
195
  });
141
196
  })));
142
197
  },
143
- isOpen: isSummaryPopupOpen,
198
+ isOpen: isSummaryPopupOpen || isSummaryButtonEmojiPickerOpen,
144
199
  onClose: handlePopupClose,
145
200
  trigger: function trigger(triggerProps) {
146
201
  return /*#__PURE__*/React.createElement(ReactionSummaryButton, _extends({}, triggerProps, {
@@ -13,7 +13,8 @@ export var ReactionSummaryViewEmojiPicker = function ReactionSummaryViewEmojiPic
13
13
  reactionPickerTriggerIcon = _ref.reactionPickerTriggerIcon,
14
14
  tooltipContent = _ref.tooltipContent,
15
15
  onOpen = _ref.onOpen,
16
- reactionPickerTriggerText = _ref.reactionPickerTriggerText;
16
+ reactionPickerTriggerText = _ref.reactionPickerTriggerText,
17
+ setIsSummaryViewTrayEmojiPickerOpen = _ref.setIsSummaryViewTrayEmojiPickerOpen;
17
18
  var _useState = useState(false),
18
19
  _useState2 = _slicedToArray(_useState, 2),
19
20
  isOpen = _useState2[0],
@@ -21,9 +22,9 @@ export var ReactionSummaryViewEmojiPicker = function ReactionSummaryViewEmojiPic
21
22
  var handleClick = function handleClick() {
22
23
  // ufo start reactions picker open experience
23
24
  PickerRender.start();
24
- setIsOpen(function (prevIsOpen) {
25
- return !prevIsOpen;
26
- });
25
+ var newIsOpen = !isOpen;
26
+ setIsOpen(newIsOpen);
27
+ setIsSummaryViewTrayEmojiPickerOpen && setIsSummaryViewTrayEmojiPickerOpen(newIsOpen);
27
28
  onOpen && onOpen();
28
29
 
29
30
  // ufo reactions picker opened success
@@ -36,6 +37,7 @@ export var ReactionSummaryViewEmojiPicker = function ReactionSummaryViewEmojiPic
36
37
  */
37
38
  var close = useCallback(function (_id) {
38
39
  setIsOpen(false);
40
+ setIsSummaryViewTrayEmojiPickerOpen && setIsSummaryViewTrayEmojiPickerOpen(false);
39
41
  // ufo abort reaction experience
40
42
  PickerRender.abort({
41
43
  metadata: {
@@ -44,7 +46,7 @@ export var ReactionSummaryViewEmojiPicker = function ReactionSummaryViewEmojiPic
44
46
  reason: 'close dialog'
45
47
  }
46
48
  });
47
- }, [setIsOpen]);
49
+ }, [setIsOpen, setIsSummaryViewTrayEmojiPickerOpen]);
48
50
 
49
51
  /**
50
52
  * Event callback when an emoji icon is selected
@@ -62,7 +64,7 @@ export var ReactionSummaryViewEmojiPicker = function ReactionSummaryViewEmojiPic
62
64
  testId: "reaction-summary-view-emoji-picker",
63
65
  isOpen: isOpen,
64
66
  placement: "bottom-start",
65
- offset: [-10, -66],
67
+ offset: [-10, -34],
66
68
  onClose: function onClose() {
67
69
  return close();
68
70
  },
@@ -69,5 +69,10 @@ export var messages = defineMessages({
69
69
  id: 'reactions.dialog.viewall.tooltip',
70
70
  defaultMessage: 'View all user reactions',
71
71
  description: 'Tooltip content of see who reacted link'
72
+ },
73
+ popperWrapperLabel: {
74
+ id: 'reactions-reaction.picker-label',
75
+ defaultMessage: 'Add reactions',
76
+ description: 'A label to the reaction picker group'
72
77
  }
73
78
  });
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { type ReactionPickerProps } from './ReactionPicker';
3
3
  interface ReactionSummaryViewEmojiPickerProps extends ReactionPickerProps {
4
+ setIsSummaryViewTrayEmojiPickerOpen?: (isOpen: boolean) => void;
4
5
  }
5
- export declare const ReactionSummaryViewEmojiPicker: ({ emojiProvider, onSelection, emojiPickerSize, disabled, reactionPickerTriggerIcon, tooltipContent, onOpen, reactionPickerTriggerText, }: ReactionSummaryViewEmojiPickerProps) => React.JSX.Element;
6
+ export declare const ReactionSummaryViewEmojiPicker: ({ emojiProvider, onSelection, emojiPickerSize, disabled, reactionPickerTriggerIcon, tooltipContent, onOpen, reactionPickerTriggerText, setIsSummaryViewTrayEmojiPickerOpen, }: ReactionSummaryViewEmojiPickerProps) => React.JSX.Element;
6
7
  export {};
@@ -69,4 +69,9 @@ export declare const messages: {
69
69
  defaultMessage: string;
70
70
  description: string;
71
71
  };
72
+ popperWrapperLabel: {
73
+ id: string;
74
+ defaultMessage: string;
75
+ description: string;
76
+ };
72
77
  };
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { type ReactionPickerProps } from './ReactionPicker';
3
3
  interface ReactionSummaryViewEmojiPickerProps extends ReactionPickerProps {
4
+ setIsSummaryViewTrayEmojiPickerOpen?: (isOpen: boolean) => void;
4
5
  }
5
- export declare const ReactionSummaryViewEmojiPicker: ({ emojiProvider, onSelection, emojiPickerSize, disabled, reactionPickerTriggerIcon, tooltipContent, onOpen, reactionPickerTriggerText, }: ReactionSummaryViewEmojiPickerProps) => React.JSX.Element;
6
+ export declare const ReactionSummaryViewEmojiPicker: ({ emojiProvider, onSelection, emojiPickerSize, disabled, reactionPickerTriggerIcon, tooltipContent, onOpen, reactionPickerTriggerText, setIsSummaryViewTrayEmojiPickerOpen, }: ReactionSummaryViewEmojiPickerProps) => React.JSX.Element;
6
7
  export {};
@@ -69,4 +69,9 @@ export declare const messages: {
69
69
  defaultMessage: string;
70
70
  description: string;
71
71
  };
72
+ popperWrapperLabel: {
73
+ id: string;
74
+ defaultMessage: string;
75
+ description: string;
76
+ };
72
77
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/reactions",
3
- "version": "31.4.0",
3
+ "version": "31.5.0",
4
4
  "description": "Reactions component",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"