@atlaskit/reactions 22.2.5 → 22.2.7

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 (50) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/analytics/analytics.js +20 -1
  3. package/dist/cjs/components/ReactionPicker/ReactionPicker.js +92 -51
  4. package/dist/cjs/components/ReactionPicker/RepositionOnUpdate.js +34 -0
  5. package/dist/cjs/components/ReactionPicker/styles.js +7 -1
  6. package/dist/cjs/components/Reactions/Reactions.js +7 -3
  7. package/dist/cjs/components/Trigger/Trigger.js +4 -1
  8. package/dist/cjs/components/Trigger/styles.js +5 -0
  9. package/dist/cjs/hooks/useCloseManager.js +2 -2
  10. package/dist/cjs/hooks/useFocusTrap.js +46 -0
  11. package/dist/cjs/shared/constants.js +6 -2
  12. package/dist/cjs/store/MemoryReactionsStore.js +1 -1
  13. package/dist/cjs/version.json +1 -1
  14. package/dist/es2019/analytics/analytics.js +18 -0
  15. package/dist/es2019/components/ReactionPicker/ReactionPicker.js +77 -41
  16. package/dist/es2019/components/ReactionPicker/RepositionOnUpdate.js +24 -0
  17. package/dist/es2019/components/ReactionPicker/styles.js +5 -0
  18. package/dist/es2019/components/Reactions/Reactions.js +7 -3
  19. package/dist/es2019/components/Trigger/Trigger.js +2 -0
  20. package/dist/es2019/components/Trigger/styles.js +6 -1
  21. package/dist/es2019/hooks/useCloseManager.js +2 -3
  22. package/dist/es2019/hooks/useFocusTrap.js +38 -0
  23. package/dist/es2019/shared/constants.js +4 -1
  24. package/dist/es2019/store/MemoryReactionsStore.js +1 -1
  25. package/dist/es2019/version.json +1 -1
  26. package/dist/esm/analytics/analytics.js +18 -0
  27. package/dist/esm/components/ReactionPicker/ReactionPicker.js +92 -51
  28. package/dist/esm/components/ReactionPicker/RepositionOnUpdate.js +23 -0
  29. package/dist/esm/components/ReactionPicker/styles.js +5 -0
  30. package/dist/esm/components/Reactions/Reactions.js +7 -3
  31. package/dist/esm/components/Trigger/Trigger.js +2 -0
  32. package/dist/esm/components/Trigger/styles.js +6 -1
  33. package/dist/esm/hooks/useCloseManager.js +2 -3
  34. package/dist/esm/hooks/useFocusTrap.js +37 -0
  35. package/dist/esm/shared/constants.js +4 -1
  36. package/dist/esm/store/MemoryReactionsStore.js +1 -1
  37. package/dist/esm/version.json +1 -1
  38. package/dist/types/analytics/analytics.d.ts +9 -0
  39. package/dist/types/components/ReactionPicker/RepositionOnUpdate.d.ts +13 -0
  40. package/dist/types/components/ReactionPicker/styles.d.ts +1 -0
  41. package/dist/types/components/Trigger/Trigger.d.ts +1 -0
  42. package/dist/types/hooks/useCloseManager.d.ts +3 -1
  43. package/dist/types/hooks/useFocusTrap.d.ts +5 -0
  44. package/dist/types/shared/constants.d.ts +1 -0
  45. package/package.json +9 -7
  46. package/README.md +0 -3
  47. package/dist/cjs/analytics/constants.js +0 -9
  48. package/dist/es2019/analytics/constants.js +0 -2
  49. package/dist/esm/analytics/constants.js +0 -2
  50. package/dist/types/analytics/constants.d.ts +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/reactions
2
2
 
3
+ ## 22.2.7
4
+
5
+ ### Patch Changes
6
+
7
+ - [`419eaff2c03`](https://bitbucket.org/atlassian/atlassian-frontend/commits/419eaff2c03) - fix focus trap not deactivated issue in reaction picker
8
+ - Updated dependencies
9
+
10
+ ## 22.2.6
11
+
12
+ ### Patch Changes
13
+
14
+ - [`6b5bf5505b6`](https://bitbucket.org/atlassian/atlassian-frontend/commits/6b5bf5505b6) - revert atlaskit popup refactor in reaction picker
15
+ - [`db658265a45`](https://bitbucket.org/atlassian/atlassian-frontend/commits/db658265a45) - add sampling for reaction view analytics
16
+ - [`c84afc8fbd8`](https://bitbucket.org/atlassian/atlassian-frontend/commits/c84afc8fbd8) - [ux] add focus trap to reaction picker
17
+ - [`ed219dee1bd`](https://bitbucket.org/atlassian/atlassian-frontend/commits/ed219dee1bd) - refactor reactions picker with @atlaskit/popup
18
+ - Updated dependencies
19
+
3
20
  ## 22.2.5
4
21
 
5
22
  ### Patch Changes
@@ -4,13 +4,32 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.extractErrorInfo = exports.createRestSucceededEvent = exports.createRestFailedEvent = exports.createReactionsRenderedEvent = exports.createReactionSelectionEvent = exports.createReactionHoveredEvent = exports.createReactionFocusedEvent = exports.createReactionClickedEvent = exports.createPickerMoreClickedEvent = exports.createPickerCancelledEvent = exports.createPickerButtonClickedEvent = exports.createAndFireSafe = exports.createAndFireEventInElementsChannel = void 0;
7
+ exports.isSampled = exports.extractErrorInfo = exports.createRestSucceededEvent = exports.createRestFailedEvent = exports.createReactionsRenderedEvent = exports.createReactionSelectionEvent = exports.createReactionHoveredEvent = exports.createReactionFocusedEvent = exports.createReactionClickedEvent = exports.createPickerMoreClickedEvent = exports.createPickerCancelledEvent = exports.createPickerButtonClickedEvent = exports.createAndFireSafe = exports.createAndFireEventInElementsChannel = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _analyticsNext = require("@atlaskit/analytics-next");
10
10
  var _analyticsGasTypes = require("@atlaskit/analytics-gas-types");
11
11
  var _version = require("../version.json");
12
12
  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; }
13
13
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
14
+ /**
15
+ * TODO: move to utility package?
16
+ * A random sampling function
17
+ * sampling algorithm is from @atlassian/jira-coinflip at https://stash.atlassian.com/projects/JIRACLOUD/repos/jira-frontend/browse/src/packages/platform/app-framework/coinflip/src/index.tsx
18
+ * E.g. isSampled(2) will pass 50% of the time
19
+ * @param rate The chance that it will pass (1 in <rate> times)
20
+ * @returns bool, if it passes or not
21
+ */
22
+ // default sampling function to determine which one to be sampled
23
+ var isSampled = function isSampled(rate) {
24
+ if (rate === 1) {
25
+ return true;
26
+ }
27
+ if (rate === 0) {
28
+ return false;
29
+ }
30
+ return Math.random() * rate <= 1;
31
+ };
32
+ exports.isSampled = isSampled;
14
33
  var createAndFireEventInElementsChannel = (0, _analyticsNext.createAndFireEvent)('fabric-elements');
15
34
  exports.createAndFireEventInElementsChannel = createAndFireEventInElementsChannel;
16
35
  var createAndFireSafe = function createAndFireSafe(createAnalyticsEvent, creator) {
@@ -20,6 +20,8 @@ var _analytics = require("../../analytics");
20
20
  var _shared = require("../../shared");
21
21
  var _hooks = require("../../hooks");
22
22
  var styles = _interopRequireWildcard(require("./styles"));
23
+ var _useFocusTrap = require("../../hooks/useFocusTrap");
24
+ var _RepositionOnUpdate = require("./RepositionOnUpdate");
23
25
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
24
26
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
25
27
  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; }
@@ -87,15 +89,17 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
87
89
  _props$tooltipContent = props.tooltipContent,
88
90
  tooltipContent = _props$tooltipContent === void 0 ? (0, _react2.jsx)(_reactIntlNext.FormattedMessage, _shared.i18n.messages.addReaction) : _props$tooltipContent,
89
91
  emojiPickerSize = props.emojiPickerSize;
92
+ var _useState = (0, _react.useState)(null),
93
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
94
+ triggerRef = _useState2[0],
95
+ setTriggerRef = _useState2[1];
96
+
90
97
  /**
91
98
  * Container <div /> reference (used by custom hook to detect click outside)
92
99
  */
93
100
  var wrapperRef = (0, _react.useRef)(null);
94
- /**
95
- * a function you can ask Popper to recompute your tooltip's position. It will directly call the Popper#update method
96
- */
97
101
  var updatePopper = (0, _react.useRef)();
98
- var _useState = (0, _react.useState)({
102
+ var _useState3 = (0, _react.useState)({
99
103
  /**
100
104
  * Show the picker floating panel
101
105
  */
@@ -105,16 +109,21 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
105
109
  */
106
110
  showFullPicker: !!allowAllEmojis && Array.isArray(pickerQuickReactionEmojiIds) && pickerQuickReactionEmojiIds.length === 0
107
111
  }),
108
- _useState2 = (0, _slicedToArray2.default)(_useState, 2),
109
- settings = _useState2[0],
110
- setSettings = _useState2[1];
112
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
113
+ settings = _useState4[0],
114
+ setSettings = _useState4[1];
111
115
 
112
116
  /**
113
117
  * Custom hook triggers when user clicks outside the reactions picker
114
118
  */
115
- (0, _hooks.useCloseManager)(wrapperRef, function () {
116
- onCancel();
119
+ (0, _hooks.useCloseManager)(wrapperRef, function (callbackType) {
117
120
  close();
121
+ onCancel();
122
+ if (triggerRef && callbackType === 'ESCAPE') {
123
+ requestAnimationFrame(function () {
124
+ return triggerRef.focus();
125
+ });
126
+ }
118
127
  }, true, settings.isOpen);
119
128
 
120
129
  /**
@@ -122,10 +131,9 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
122
131
  * @param _id Optional id if an emoji button was selected or undefineed if was clicked outside the picker
123
132
  */
124
133
  var close = (0, _react.useCallback)(function (_id) {
125
- setSettings({
126
- isOpen: false,
127
- showFullPicker: !!allowAllEmojis && Array.isArray(pickerQuickReactionEmojiIds) && pickerQuickReactionEmojiIds.length === 0
128
- });
134
+ setSettings(_objectSpread(_objectSpread({}, settings), {}, {
135
+ isOpen: false
136
+ }));
129
137
  // ufo abort reaction experience
130
138
  _analytics.UFO.PickerRender.abort({
131
139
  metadata: {
@@ -134,7 +142,7 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
134
142
  reason: 'close dialog'
135
143
  }
136
144
  });
137
- }, [allowAllEmojis, pickerQuickReactionEmojiIds]);
145
+ }, [settings]);
138
146
 
139
147
  /**
140
148
  * Event handle rwhen selecting to show the custom emoji icons picker
@@ -176,25 +184,18 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
176
184
  // ufo reactions picker opened success
177
185
  _analytics.UFO.PickerRender.success();
178
186
  };
179
-
180
- /**
181
- * When picker is opened, re-calculate the picker position
182
- */
183
- (0, _react.useEffect)(function () {
184
- if (settings.isOpen) {
185
- if (updatePopper.current) {
186
- updatePopper.current();
187
- }
188
- }
189
- }, [settings]);
190
187
  var wrapperClassName = " ".concat(settings.isOpen ? 'isOpen' : '', " ").concat(miniMode ? 'miniMode' : '', " ").concat(className);
188
+ (0, _react.useLayoutEffect)(function () {
189
+ var _updatePopper$current;
190
+ (_updatePopper$current = updatePopper.current) === null || _updatePopper$current === void 0 ? void 0 : _updatePopper$current.call(updatePopper);
191
+ }, [settings]);
191
192
  return (0, _react2.jsx)("div", {
192
193
  className: wrapperClassName,
193
194
  css: styles.pickerStyle,
194
195
  "data-testid": RENDER_REACTIONPICKER_TESTID,
195
196
  ref: wrapperRef
196
197
  }, (0, _react2.jsx)(_popper.Manager, null, (0, _react2.jsx)(_popper.Reference, null, function (_ref) {
197
- var popperRef = _ref.ref;
198
+ var _ref2 = _ref.ref;
198
199
  return (
199
200
  // Render a button to open the <Selector /> panel
200
201
  (0, _react2.jsx)(_Trigger.Trigger, {
@@ -202,43 +203,83 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
202
203
  'aria-expanded': settings.isOpen,
203
204
  'aria-controls': PICKER_CONTROL_ID
204
205
  },
205
- ref: popperRef,
206
+ ref: function ref(node) {
207
+ if (node && settings.isOpen) {
208
+ if (typeof _ref2 === 'function') {
209
+ _ref2(node);
210
+ } else {
211
+ _ref2.current = node;
212
+ }
213
+ setTriggerRef(node);
214
+ }
215
+ },
206
216
  onClick: onTriggerClick,
207
217
  miniMode: miniMode,
208
218
  disabled: disabled,
209
219
  tooltipContent: settings.isOpen ? null : tooltipContent
210
220
  })
211
221
  );
212
- }), (0, _react2.jsx)(_popper.Popper, {
222
+ }), settings.isOpen && (0, _react2.jsx)(PopperWrapper, {
223
+ settings: settings
224
+ }, settings.showFullPicker ? (0, _react2.jsx)(_picker.EmojiPicker, {
225
+ emojiProvider: emojiProvider,
226
+ onSelection: onEmojiSelected,
227
+ size: emojiPickerSize
228
+ }) : (0, _react2.jsx)("div", {
229
+ css: styles.contentStyle
230
+ }, (0, _react2.jsx)(_Selector.Selector, {
231
+ emojiProvider: emojiProvider,
232
+ onSelection: onEmojiSelected,
233
+ showMore: allowAllEmojis,
234
+ onMoreClick: onSelectMoreClick,
235
+ pickerQuickReactionEmojiIds: pickerQuickReactionEmojiIds
236
+ })))));
237
+ });
238
+ exports.ReactionPicker = ReactionPicker;
239
+ var PopperWrapper = function PopperWrapper(props) {
240
+ var settings = props.settings,
241
+ children = props.children;
242
+ var _useState5 = (0, _react.useState)(null),
243
+ _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
244
+ popupRef = _useState6[0],
245
+ setPopupRef = _useState6[1];
246
+ /**
247
+ * add focus lock to popup
248
+ */
249
+ (0, _useFocusTrap.useFocusTrap)({
250
+ initialFocusRef: null,
251
+ targetRef: popupRef
252
+ });
253
+ return (0, _react2.jsx)(_popper.Popper, {
213
254
  placement: "bottom-start",
214
255
  modifiers: popperModifiers
215
- }, function (_ref2) {
216
- var ref = _ref2.ref,
217
- style = _ref2.style,
218
- update = _ref2.update;
219
- updatePopper.current = update;
220
- return (0, _react2.jsx)(_react.Fragment, null, settings.isOpen && (0, _react2.jsx)("div", {
256
+ }, function (_ref3) {
257
+ var _ref4 = _ref3.ref,
258
+ style = _ref3.style,
259
+ update = _ref3.update;
260
+ return (0, _react2.jsx)("div", {
221
261
  id: PICKER_CONTROL_ID,
222
262
  "data-testid": RENDER_REACTIONPICKERPANEL_TESTID,
223
263
  style: _objectSpread({
224
264
  zIndex: _constants.layers.layer()
225
265
  }, style),
226
- ref: ref
266
+ ref: function ref(node) {
267
+ if (node) {
268
+ if (typeof _ref4 === 'function') {
269
+ _ref4(node);
270
+ } else {
271
+ _ref4.current = node;
272
+ }
273
+ setPopupRef(node);
274
+ }
275
+ },
276
+ css: styles.popupWrapperStyle,
277
+ tabIndex: 0
278
+ }, (0, _react2.jsx)(_RepositionOnUpdate.RepositionOnUpdate, {
279
+ update: update,
280
+ settings: settings
227
281
  }, (0, _react2.jsx)("div", {
228
282
  css: styles.popupStyle
229
- }, settings.showFullPicker ? (0, _react2.jsx)(_picker.EmojiPicker, {
230
- emojiProvider: emojiProvider,
231
- onSelection: onEmojiSelected,
232
- size: emojiPickerSize
233
- }) : (0, _react2.jsx)("div", {
234
- css: styles.contentStyle
235
- }, (0, _react2.jsx)(_Selector.Selector, {
236
- emojiProvider: emojiProvider,
237
- onSelection: onEmojiSelected,
238
- showMore: allowAllEmojis,
239
- onMoreClick: onSelectMoreClick,
240
- pickerQuickReactionEmojiIds: pickerQuickReactionEmojiIds
241
- })))));
242
- })));
243
- });
244
- exports.ReactionPicker = ReactionPicker;
283
+ }, children)));
284
+ });
285
+ };
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.RepositionOnUpdate = void 0;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
10
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
11
+ /**
12
+ * Copied from ADS popup component with some tweeks for our use
13
+ */
14
+
15
+ // eslint-disable-next-line @repo/internal/react/require-jsdoc
16
+ var RepositionOnUpdate = function RepositionOnUpdate(_ref) {
17
+ var children = _ref.children,
18
+ update = _ref.update,
19
+ settings = _ref.settings;
20
+ // Ref used here to skip update on first render (when refs haven't been set)
21
+ var isFirstRenderRef = (0, _react.useRef)(true);
22
+ (0, _react.useLayoutEffect)(function () {
23
+ if (isFirstRenderRef.current) {
24
+ isFirstRenderRef.current = false;
25
+ return;
26
+ }
27
+ // callback function from popper that repositions pop-up on content Update
28
+ update();
29
+ }, [update, settings]);
30
+
31
+ // wrapping in fragment to make TS happy (known issue with FC returning children)
32
+ return /*#__PURE__*/_react.default.createElement(_react.Fragment, null, children);
33
+ };
34
+ exports.RepositionOnUpdate = RepositionOnUpdate;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.popupStyle = exports.pickerStyle = exports.contentStyle = void 0;
6
+ exports.popupWrapperStyle = exports.popupStyle = exports.pickerStyle = exports.contentStyle = void 0;
7
7
  var _react = require("@emotion/react");
8
8
  var _constants = require("@atlaskit/theme/constants");
9
9
  var _colors = require("@atlaskit/theme/colors");
@@ -20,6 +20,12 @@ var contentStyle = (0, _react.css)({
20
20
  display: 'flex'
21
21
  });
22
22
  exports.contentStyle = contentStyle;
23
+ var popupWrapperStyle = (0, _react.css)({
24
+ ':focus': {
25
+ outline: 'none'
26
+ }
27
+ });
28
+ exports.popupWrapperStyle = popupWrapperStyle;
23
29
  var popupStyle = (0, _react.css)({
24
30
  background: "var(--ds-surface-overlay, ".concat(_colors.N0, ")"),
25
31
  borderRadius: "".concat((0, _constants.borderRadius)(), "px"),
@@ -23,6 +23,8 @@ var _Reaction = require("../Reaction");
23
23
  var _ReactionDialog = require("../ReactionDialog");
24
24
  var _ReactionPicker = require("../ReactionPicker");
25
25
  var styles = _interopRequireWildcard(require("./styles"));
26
+ var _analytics2 = require("../../analytics/analytics");
27
+ var _constants = require("../../shared/constants");
26
28
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
27
29
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
28
30
  /** @jsx jsx */
@@ -123,9 +125,11 @@ var Reactions = /*#__PURE__*/_react.default.memo(function (_ref) {
123
125
  if (status !== _types.ReactionStatus.ready) {
124
126
  renderTime.current = Date.now();
125
127
  } else {
126
- var _renderTime$current;
127
- _analytics.Analytics.createAndFireSafe(createAnalyticsEvent, _analytics.Analytics.createReactionsRenderedEvent, (_renderTime$current = renderTime.current) !== null && _renderTime$current !== void 0 ? _renderTime$current : Date.now() //renderTime.current can be null during unit test cases
128
- );
128
+ if ((0, _analytics2.isSampled)(_constants.SAMPLING_RATE_REACTIONS_RENDERED_EXP)) {
129
+ var _renderTime$current;
130
+ _analytics.Analytics.createAndFireSafe(createAnalyticsEvent, _analytics.Analytics.createReactionsRenderedEvent, (_renderTime$current = renderTime.current) !== null && _renderTime$current !== void 0 ? _renderTime$current : Date.now() //renderTime.current can be null during unit test cases
131
+ );
132
+ }
129
133
  renderTime.current = undefined;
130
134
  }
131
135
  }, [createAnalyticsEvent, status]);
@@ -5,7 +5,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.Trigger = exports.RENDER_TOOLTIP_TRIGGER_TESTID = void 0;
8
+ exports.Trigger = exports.RENDER_TRIGGER_BUTTON_TESTID = exports.RENDER_TOOLTIP_TRIGGER_TESTID = void 0;
9
9
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
10
  var _react = _interopRequireDefault(require("react"));
11
11
  var _react2 = require("@emotion/react");
@@ -22,6 +22,8 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
22
22
  */
23
23
  var RENDER_TOOLTIP_TRIGGER_TESTID = 'render-tooltip-trigger';
24
24
  exports.RENDER_TOOLTIP_TRIGGER_TESTID = RENDER_TOOLTIP_TRIGGER_TESTID;
25
+ var RENDER_TRIGGER_BUTTON_TESTID = 'render-trigger-button';
26
+ exports.RENDER_TRIGGER_BUTTON_TESTID = RENDER_TRIGGER_BUTTON_TESTID;
25
27
  /**
26
28
  * Render an emoji button to open the reactions select picker
27
29
  */
@@ -42,6 +44,7 @@ var Trigger = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
42
44
  testId: RENDER_TOOLTIP_TRIGGER_TESTID,
43
45
  content: tooltipContent
44
46
  }, (0, _react2.jsx)(_standardButton.default, (0, _extends2.default)({
47
+ testId: RENDER_TRIGGER_BUTTON_TESTID,
45
48
  css: styles.triggerStyle({
46
49
  miniMode: miniMode,
47
50
  disabled: disabled
@@ -39,6 +39,11 @@ var triggerStyle = function triggerStyle(_ref) {
39
39
  }), {}, {
40
40
  '&:hover': {
41
41
  background: "".concat("var(--ds-background-neutral-subtle-hovered, ".concat(_colors.N20, ")"))
42
+ },
43
+ '&:focus': {
44
+ boxShadow: "0 0 0 2px ".concat("var(--ds-border-focused, ".concat(_colors.B100, ")")),
45
+ transitionDuration: '0s, 0.2s',
46
+ outline: 'none'
42
47
  }
43
48
  }));
44
49
  };
@@ -25,13 +25,13 @@ function useCloseManager(ref, callback) {
25
25
  */
26
26
  function handleClickOutside(event) {
27
27
  if (ref.current && event.target instanceof Node && !ref.current.contains(event.target)) {
28
- callback();
28
+ callback('CLICK_OUTSIDE');
29
29
  }
30
30
  }
31
31
  function handleKeydown(event) {
32
32
  var key = event.key;
33
33
  if (key === 'Escape' || key === 'Esc') {
34
- callback();
34
+ callback('ESCAPE');
35
35
  }
36
36
  }
37
37
 
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.useFocusTrap = void 0;
8
+ var _react = require("react");
9
+ var _focusTrap = _interopRequireDefault(require("focus-trap"));
10
+ /**
11
+ * Custom hook to add focus trap
12
+ * used for focus trap in ReactionPicker
13
+ * copied from useFocusManager in @atlaskit/popup
14
+ */
15
+
16
+ var useFocusTrap = function useFocusTrap(_ref) {
17
+ var targetRef = _ref.targetRef,
18
+ initialFocusRef = _ref.initialFocusRef;
19
+ (0, _react.useEffect)(function () {
20
+ if (!targetRef) {
21
+ return;
22
+ }
23
+ var trapConfig = {
24
+ clickOutsideDeactivates: true,
25
+ escapeDeactivates: true,
26
+ initialFocus: initialFocusRef || targetRef,
27
+ fallbackFocus: targetRef,
28
+ returnFocusOnDeactivate: false
29
+ };
30
+ var focusTrap = (0, _focusTrap.default)(targetRef, trapConfig);
31
+
32
+ // wait for the popup to reposition itself before we focus
33
+ var frameId = requestAnimationFrame(function () {
34
+ frameId = null;
35
+ focusTrap.activate();
36
+ });
37
+ return function () {
38
+ if (frameId != null) {
39
+ cancelAnimationFrame(frameId);
40
+ frameId = null;
41
+ }
42
+ focusTrap.deactivate();
43
+ };
44
+ }, [targetRef, initialFocusRef]);
45
+ };
46
+ exports.useFocusTrap = useFocusTrap;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.TOOLTIP_USERS_LIMIT = 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.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
  */
@@ -104,4 +104,8 @@ var TOOLTIP_USERS_LIMIT = 5;
104
104
  */
105
105
  exports.TOOLTIP_USERS_LIMIT = TOOLTIP_USERS_LIMIT;
106
106
  var NUMBER_OF_REACTIONS_TO_DISPLAY = 9;
107
- exports.NUMBER_OF_REACTIONS_TO_DISPLAY = NUMBER_OF_REACTIONS_TO_DISPLAY;
107
+
108
+ // This rate is used in fetching emoji resource
109
+ exports.NUMBER_OF_REACTIONS_TO_DISPLAY = NUMBER_OF_REACTIONS_TO_DISPLAY;
110
+ var SAMPLING_RATE_REACTIONS_RENDERED_EXP = 50;
111
+ exports.SAMPLING_RATE_REACTIONS_RENDERED_EXP = SAMPLING_RATE_REACTIONS_RENDERED_EXP;
@@ -13,7 +13,7 @@ var _analytics = require("../analytics");
13
13
  var Types = _interopRequireWildcard(require("../types"));
14
14
  var _batched = require("./batched");
15
15
  var utils = _interopRequireWildcard(require("./utils"));
16
- var _constants = require("../analytics/constants");
16
+ var _constants = require("../shared/constants");
17
17
  var _ufo = require("../analytics/ufo");
18
18
  var _analytics2 = require("../analytics/analytics");
19
19
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "name": "@atlaskit/reactions",
3
- "version": "22.2.5"
3
+ "version": "22.2.7"
4
4
  }
@@ -1,6 +1,24 @@
1
1
  import { createAndFireEvent } from '@atlaskit/analytics-next';
2
2
  import { UI_EVENT_TYPE, OPERATIONAL_EVENT_TYPE } from '@atlaskit/analytics-gas-types';
3
3
  import { name as packageName, version as packageVersion } from '../version.json';
4
+ /**
5
+ * TODO: move to utility package?
6
+ * A random sampling function
7
+ * sampling algorithm is from @atlassian/jira-coinflip at https://stash.atlassian.com/projects/JIRACLOUD/repos/jira-frontend/browse/src/packages/platform/app-framework/coinflip/src/index.tsx
8
+ * E.g. isSampled(2) will pass 50% of the time
9
+ * @param rate The chance that it will pass (1 in <rate> times)
10
+ * @returns bool, if it passes or not
11
+ */
12
+ // default sampling function to determine which one to be sampled
13
+ export const isSampled = rate => {
14
+ if (rate === 1) {
15
+ return true;
16
+ }
17
+ if (rate === 0) {
18
+ return false;
19
+ }
20
+ return Math.random() * rate <= 1;
21
+ };
4
22
  export const createAndFireEventInElementsChannel = createAndFireEvent('fabric-elements');
5
23
  export const createAndFireSafe = (createAnalyticsEvent, creator, ...args) => {
6
24
  if (createAnalyticsEvent) {