@atlaskit/reactions 22.2.5 → 22.2.6
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 +10 -0
- package/dist/cjs/analytics/analytics.js +20 -1
- package/dist/cjs/components/ReactionPicker/ReactionPicker.js +66 -35
- package/dist/cjs/components/ReactionPicker/styles.js +7 -1
- package/dist/cjs/components/Reactions/Reactions.js +7 -3
- package/dist/cjs/components/Trigger/Trigger.js +4 -1
- package/dist/cjs/components/Trigger/styles.js +5 -0
- package/dist/cjs/hooks/useCloseManager.js +2 -2
- package/dist/cjs/hooks/useFocusTrap.js +46 -0
- package/dist/cjs/shared/constants.js +6 -2
- package/dist/cjs/store/MemoryReactionsStore.js +1 -1
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/analytics/analytics.js +18 -0
- package/dist/es2019/components/ReactionPicker/ReactionPicker.js +50 -26
- package/dist/es2019/components/ReactionPicker/styles.js +5 -0
- package/dist/es2019/components/Reactions/Reactions.js +7 -3
- package/dist/es2019/components/Trigger/Trigger.js +2 -0
- package/dist/es2019/components/Trigger/styles.js +6 -1
- package/dist/es2019/hooks/useCloseManager.js +2 -3
- package/dist/es2019/hooks/useFocusTrap.js +38 -0
- package/dist/es2019/shared/constants.js +4 -1
- package/dist/es2019/store/MemoryReactionsStore.js +1 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/analytics/analytics.js +18 -0
- package/dist/esm/components/ReactionPicker/ReactionPicker.js +67 -36
- package/dist/esm/components/ReactionPicker/styles.js +5 -0
- package/dist/esm/components/Reactions/Reactions.js +7 -3
- package/dist/esm/components/Trigger/Trigger.js +2 -0
- package/dist/esm/components/Trigger/styles.js +6 -1
- package/dist/esm/hooks/useCloseManager.js +2 -3
- package/dist/esm/hooks/useFocusTrap.js +37 -0
- package/dist/esm/shared/constants.js +4 -1
- package/dist/esm/store/MemoryReactionsStore.js +1 -1
- package/dist/esm/version.json +1 -1
- package/dist/types/analytics/analytics.d.ts +9 -0
- package/dist/types/components/ReactionPicker/styles.d.ts +1 -0
- package/dist/types/components/Trigger/Trigger.d.ts +1 -0
- package/dist/types/hooks/useCloseManager.d.ts +3 -1
- package/dist/types/hooks/useFocusTrap.d.ts +5 -0
- package/dist/types/shared/constants.d.ts +1 -0
- package/package.json +9 -7
- package/README.md +0 -3
- package/dist/cjs/analytics/constants.js +0 -9
- package/dist/es2019/analytics/constants.js +0 -2
- package/dist/esm/analytics/constants.js +0 -2
- package/dist/types/analytics/constants.d.ts +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @atlaskit/reactions
|
|
2
2
|
|
|
3
|
+
## 22.2.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`6b5bf5505b6`](https://bitbucket.org/atlassian/atlassian-frontend/commits/6b5bf5505b6) - revert atlaskit popup refactor in reaction picker
|
|
8
|
+
- [`db658265a45`](https://bitbucket.org/atlassian/atlassian-frontend/commits/db658265a45) - add sampling for reaction view analytics
|
|
9
|
+
- [`c84afc8fbd8`](https://bitbucket.org/atlassian/atlassian-frontend/commits/c84afc8fbd8) - [ux] add focus trap to reaction picker
|
|
10
|
+
- [`ed219dee1bd`](https://bitbucket.org/atlassian/atlassian-frontend/commits/ed219dee1bd) - refactor reactions picker with @atlaskit/popup
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
|
|
3
13
|
## 22.2.5
|
|
4
14
|
|
|
5
15
|
### 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,7 @@ 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");
|
|
23
24
|
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
25
|
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
26
|
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 +88,20 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
|
|
|
87
88
|
_props$tooltipContent = props.tooltipContent,
|
|
88
89
|
tooltipContent = _props$tooltipContent === void 0 ? (0, _react2.jsx)(_reactIntlNext.FormattedMessage, _shared.i18n.messages.addReaction) : _props$tooltipContent,
|
|
89
90
|
emojiPickerSize = props.emojiPickerSize;
|
|
91
|
+
var _useState = (0, _react.useState)(null),
|
|
92
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
93
|
+
triggerRef = _useState2[0],
|
|
94
|
+
setTriggerRef = _useState2[1];
|
|
95
|
+
var _useState3 = (0, _react.useState)(null),
|
|
96
|
+
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
|
|
97
|
+
popupRef = _useState4[0],
|
|
98
|
+
setPopupRef = _useState4[1];
|
|
90
99
|
/**
|
|
91
100
|
* Container <div /> reference (used by custom hook to detect click outside)
|
|
92
101
|
*/
|
|
93
102
|
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
103
|
var updatePopper = (0, _react.useRef)();
|
|
98
|
-
var
|
|
104
|
+
var _useState5 = (0, _react.useState)({
|
|
99
105
|
/**
|
|
100
106
|
* Show the picker floating panel
|
|
101
107
|
*/
|
|
@@ -105,27 +111,39 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
|
|
|
105
111
|
*/
|
|
106
112
|
showFullPicker: !!allowAllEmojis && Array.isArray(pickerQuickReactionEmojiIds) && pickerQuickReactionEmojiIds.length === 0
|
|
107
113
|
}),
|
|
108
|
-
|
|
109
|
-
settings =
|
|
110
|
-
setSettings =
|
|
114
|
+
_useState6 = (0, _slicedToArray2.default)(_useState5, 2),
|
|
115
|
+
settings = _useState6[0],
|
|
116
|
+
setSettings = _useState6[1];
|
|
111
117
|
|
|
112
118
|
/**
|
|
113
119
|
* Custom hook triggers when user clicks outside the reactions picker
|
|
114
120
|
*/
|
|
115
|
-
(0, _hooks.useCloseManager)(wrapperRef, function () {
|
|
116
|
-
onCancel();
|
|
121
|
+
(0, _hooks.useCloseManager)(wrapperRef, function (callbackType) {
|
|
117
122
|
close();
|
|
123
|
+
onCancel();
|
|
124
|
+
if (triggerRef && callbackType === 'ESCAPE') {
|
|
125
|
+
requestAnimationFrame(function () {
|
|
126
|
+
return triggerRef.focus();
|
|
127
|
+
});
|
|
128
|
+
}
|
|
118
129
|
}, true, settings.isOpen);
|
|
119
130
|
|
|
131
|
+
/**
|
|
132
|
+
* add focus lock to popup
|
|
133
|
+
*/
|
|
134
|
+
(0, _useFocusTrap.useFocusTrap)({
|
|
135
|
+
initialFocusRef: null,
|
|
136
|
+
targetRef: popupRef
|
|
137
|
+
});
|
|
138
|
+
|
|
120
139
|
/**
|
|
121
140
|
* Event callback when the picker is closed
|
|
122
141
|
* @param _id Optional id if an emoji button was selected or undefineed if was clicked outside the picker
|
|
123
142
|
*/
|
|
124
143
|
var close = (0, _react.useCallback)(function (_id) {
|
|
125
|
-
setSettings({
|
|
126
|
-
isOpen: false
|
|
127
|
-
|
|
128
|
-
});
|
|
144
|
+
setSettings(_objectSpread(_objectSpread({}, settings), {}, {
|
|
145
|
+
isOpen: false
|
|
146
|
+
}));
|
|
129
147
|
// ufo abort reaction experience
|
|
130
148
|
_analytics.UFO.PickerRender.abort({
|
|
131
149
|
metadata: {
|
|
@@ -134,7 +152,7 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
|
|
|
134
152
|
reason: 'close dialog'
|
|
135
153
|
}
|
|
136
154
|
});
|
|
137
|
-
}, [
|
|
155
|
+
}, [settings]);
|
|
138
156
|
|
|
139
157
|
/**
|
|
140
158
|
* Event handle rwhen selecting to show the custom emoji icons picker
|
|
@@ -176,25 +194,18 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
|
|
|
176
194
|
// ufo reactions picker opened success
|
|
177
195
|
_analytics.UFO.PickerRender.success();
|
|
178
196
|
};
|
|
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
197
|
var wrapperClassName = " ".concat(settings.isOpen ? 'isOpen' : '', " ").concat(miniMode ? 'miniMode' : '', " ").concat(className);
|
|
198
|
+
(0, _react.useLayoutEffect)(function () {
|
|
199
|
+
var _updatePopper$current;
|
|
200
|
+
(_updatePopper$current = updatePopper.current) === null || _updatePopper$current === void 0 ? void 0 : _updatePopper$current.call(updatePopper);
|
|
201
|
+
}, [settings]);
|
|
191
202
|
return (0, _react2.jsx)("div", {
|
|
192
203
|
className: wrapperClassName,
|
|
193
204
|
css: styles.pickerStyle,
|
|
194
205
|
"data-testid": RENDER_REACTIONPICKER_TESTID,
|
|
195
206
|
ref: wrapperRef
|
|
196
207
|
}, (0, _react2.jsx)(_popper.Manager, null, (0, _react2.jsx)(_popper.Reference, null, function (_ref) {
|
|
197
|
-
var
|
|
208
|
+
var _ref2 = _ref.ref;
|
|
198
209
|
return (
|
|
199
210
|
// Render a button to open the <Selector /> panel
|
|
200
211
|
(0, _react2.jsx)(_Trigger.Trigger, {
|
|
@@ -202,28 +213,48 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
|
|
|
202
213
|
'aria-expanded': settings.isOpen,
|
|
203
214
|
'aria-controls': PICKER_CONTROL_ID
|
|
204
215
|
},
|
|
205
|
-
ref:
|
|
216
|
+
ref: function ref(node) {
|
|
217
|
+
if (node && settings.isOpen) {
|
|
218
|
+
if (typeof _ref2 === 'function') {
|
|
219
|
+
_ref2(node);
|
|
220
|
+
} else {
|
|
221
|
+
_ref2.current = node;
|
|
222
|
+
}
|
|
223
|
+
setTriggerRef(node);
|
|
224
|
+
}
|
|
225
|
+
},
|
|
206
226
|
onClick: onTriggerClick,
|
|
207
227
|
miniMode: miniMode,
|
|
208
228
|
disabled: disabled,
|
|
209
229
|
tooltipContent: settings.isOpen ? null : tooltipContent
|
|
210
230
|
})
|
|
211
231
|
);
|
|
212
|
-
}), (0, _react2.jsx)(_popper.Popper, {
|
|
232
|
+
}), settings.isOpen && (0, _react2.jsx)(_popper.Popper, {
|
|
213
233
|
placement: "bottom-start",
|
|
214
234
|
modifiers: popperModifiers
|
|
215
|
-
}, function (
|
|
216
|
-
var
|
|
217
|
-
style =
|
|
218
|
-
update =
|
|
235
|
+
}, function (_ref3) {
|
|
236
|
+
var _ref4 = _ref3.ref,
|
|
237
|
+
style = _ref3.style,
|
|
238
|
+
update = _ref3.update;
|
|
219
239
|
updatePopper.current = update;
|
|
220
|
-
return (0, _react2.jsx)(
|
|
240
|
+
return (0, _react2.jsx)("div", {
|
|
221
241
|
id: PICKER_CONTROL_ID,
|
|
222
242
|
"data-testid": RENDER_REACTIONPICKERPANEL_TESTID,
|
|
223
243
|
style: _objectSpread({
|
|
224
244
|
zIndex: _constants.layers.layer()
|
|
225
245
|
}, style),
|
|
226
|
-
ref: ref
|
|
246
|
+
ref: function ref(node) {
|
|
247
|
+
if (node) {
|
|
248
|
+
if (typeof _ref4 === 'function') {
|
|
249
|
+
_ref4(node);
|
|
250
|
+
} else {
|
|
251
|
+
_ref4.current = node;
|
|
252
|
+
}
|
|
253
|
+
setPopupRef(node);
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
css: styles.popupWrapperStyle,
|
|
257
|
+
tabIndex: 0
|
|
227
258
|
}, (0, _react2.jsx)("div", {
|
|
228
259
|
css: styles.popupStyle
|
|
229
260
|
}, settings.showFullPicker ? (0, _react2.jsx)(_picker.EmojiPicker, {
|
|
@@ -238,7 +269,7 @@ var ReactionPicker = /*#__PURE__*/_react.default.memo(function (props) {
|
|
|
238
269
|
showMore: allowAllEmojis,
|
|
239
270
|
onMoreClick: onSelectMoreClick,
|
|
240
271
|
pickerQuickReactionEmojiIds: pickerQuickReactionEmojiIds
|
|
241
|
-
}))))
|
|
272
|
+
}))));
|
|
242
273
|
})));
|
|
243
274
|
});
|
|
244
275
|
exports.ReactionPicker = ReactionPicker;
|
|
@@ -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
|
-
|
|
127
|
-
|
|
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
|
-
|
|
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("../
|
|
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); }
|
package/dist/cjs/version.json
CHANGED
|
@@ -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) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
|
-
import React, {
|
|
2
|
+
import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
|
3
3
|
import { jsx } from '@emotion/react';
|
|
4
4
|
import { FormattedMessage } from 'react-intl-next';
|
|
5
5
|
import { EmojiPicker } from '@atlaskit/emoji/picker';
|
|
@@ -11,6 +11,7 @@ import { UFO } from '../../analytics';
|
|
|
11
11
|
import { i18n } from '../../shared';
|
|
12
12
|
import { useCloseManager } from '../../hooks';
|
|
13
13
|
import * as styles from './styles';
|
|
14
|
+
import { useFocusTrap } from '../../hooks/useFocusTrap';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Test id for wrapper ReactionPicker div
|
|
@@ -71,13 +72,12 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
71
72
|
tooltipContent = jsx(FormattedMessage, i18n.messages.addReaction),
|
|
72
73
|
emojiPickerSize
|
|
73
74
|
} = props;
|
|
75
|
+
const [triggerRef, setTriggerRef] = useState(null);
|
|
76
|
+
const [popupRef, setPopupRef] = useState(null);
|
|
74
77
|
/**
|
|
75
78
|
* Container <div /> reference (used by custom hook to detect click outside)
|
|
76
79
|
*/
|
|
77
80
|
const wrapperRef = useRef(null);
|
|
78
|
-
/**
|
|
79
|
-
* a function you can ask Popper to recompute your tooltip's position. It will directly call the Popper#update method
|
|
80
|
-
*/
|
|
81
81
|
const updatePopper = useRef();
|
|
82
82
|
const [settings, setSettings] = useState({
|
|
83
83
|
/**
|
|
@@ -93,19 +93,30 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
93
93
|
/**
|
|
94
94
|
* Custom hook triggers when user clicks outside the reactions picker
|
|
95
95
|
*/
|
|
96
|
-
useCloseManager(wrapperRef,
|
|
97
|
-
onCancel();
|
|
96
|
+
useCloseManager(wrapperRef, callbackType => {
|
|
98
97
|
close();
|
|
98
|
+
onCancel();
|
|
99
|
+
if (triggerRef && callbackType === 'ESCAPE') {
|
|
100
|
+
requestAnimationFrame(() => triggerRef.focus());
|
|
101
|
+
}
|
|
99
102
|
}, true, settings.isOpen);
|
|
100
103
|
|
|
104
|
+
/**
|
|
105
|
+
* add focus lock to popup
|
|
106
|
+
*/
|
|
107
|
+
useFocusTrap({
|
|
108
|
+
initialFocusRef: null,
|
|
109
|
+
targetRef: popupRef
|
|
110
|
+
});
|
|
111
|
+
|
|
101
112
|
/**
|
|
102
113
|
* Event callback when the picker is closed
|
|
103
114
|
* @param _id Optional id if an emoji button was selected or undefineed if was clicked outside the picker
|
|
104
115
|
*/
|
|
105
116
|
const close = useCallback(_id => {
|
|
106
117
|
setSettings({
|
|
107
|
-
|
|
108
|
-
|
|
118
|
+
...settings,
|
|
119
|
+
isOpen: false
|
|
109
120
|
});
|
|
110
121
|
// ufo abort reaction experience
|
|
111
122
|
UFO.PickerRender.abort({
|
|
@@ -115,7 +126,7 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
115
126
|
reason: 'close dialog'
|
|
116
127
|
}
|
|
117
128
|
});
|
|
118
|
-
}, [
|
|
129
|
+
}, [settings]);
|
|
119
130
|
|
|
120
131
|
/**
|
|
121
132
|
* Event handle rwhen selecting to show the custom emoji icons picker
|
|
@@ -157,25 +168,18 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
157
168
|
// ufo reactions picker opened success
|
|
158
169
|
UFO.PickerRender.success();
|
|
159
170
|
};
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* When picker is opened, re-calculate the picker position
|
|
163
|
-
*/
|
|
164
|
-
useEffect(() => {
|
|
165
|
-
if (settings.isOpen) {
|
|
166
|
-
if (updatePopper.current) {
|
|
167
|
-
updatePopper.current();
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}, [settings]);
|
|
171
171
|
const wrapperClassName = ` ${settings.isOpen ? 'isOpen' : ''} ${miniMode ? 'miniMode' : ''} ${className}`;
|
|
172
|
+
useLayoutEffect(() => {
|
|
173
|
+
var _updatePopper$current;
|
|
174
|
+
(_updatePopper$current = updatePopper.current) === null || _updatePopper$current === void 0 ? void 0 : _updatePopper$current.call(updatePopper);
|
|
175
|
+
}, [settings]);
|
|
172
176
|
return jsx("div", {
|
|
173
177
|
className: wrapperClassName,
|
|
174
178
|
css: styles.pickerStyle,
|
|
175
179
|
"data-testid": RENDER_REACTIONPICKER_TESTID,
|
|
176
180
|
ref: wrapperRef
|
|
177
181
|
}, jsx(Manager, null, jsx(Reference, null, ({
|
|
178
|
-
ref
|
|
182
|
+
ref
|
|
179
183
|
}) =>
|
|
180
184
|
// Render a button to open the <Selector /> panel
|
|
181
185
|
jsx(Trigger, {
|
|
@@ -183,12 +187,21 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
183
187
|
'aria-expanded': settings.isOpen,
|
|
184
188
|
'aria-controls': PICKER_CONTROL_ID
|
|
185
189
|
},
|
|
186
|
-
ref:
|
|
190
|
+
ref: node => {
|
|
191
|
+
if (node && settings.isOpen) {
|
|
192
|
+
if (typeof ref === 'function') {
|
|
193
|
+
ref(node);
|
|
194
|
+
} else {
|
|
195
|
+
ref.current = node;
|
|
196
|
+
}
|
|
197
|
+
setTriggerRef(node);
|
|
198
|
+
}
|
|
199
|
+
},
|
|
187
200
|
onClick: onTriggerClick,
|
|
188
201
|
miniMode: miniMode,
|
|
189
202
|
disabled: disabled,
|
|
190
203
|
tooltipContent: settings.isOpen ? null : tooltipContent
|
|
191
|
-
})), jsx(Popper, {
|
|
204
|
+
})), settings.isOpen && jsx(Popper, {
|
|
192
205
|
placement: "bottom-start",
|
|
193
206
|
modifiers: popperModifiers
|
|
194
207
|
}, ({
|
|
@@ -197,14 +210,25 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
197
210
|
update
|
|
198
211
|
}) => {
|
|
199
212
|
updatePopper.current = update;
|
|
200
|
-
return jsx(
|
|
213
|
+
return jsx("div", {
|
|
201
214
|
id: PICKER_CONTROL_ID,
|
|
202
215
|
"data-testid": RENDER_REACTIONPICKERPANEL_TESTID,
|
|
203
216
|
style: {
|
|
204
217
|
zIndex: layers.layer(),
|
|
205
218
|
...style
|
|
206
219
|
},
|
|
207
|
-
ref:
|
|
220
|
+
ref: node => {
|
|
221
|
+
if (node) {
|
|
222
|
+
if (typeof ref === 'function') {
|
|
223
|
+
ref(node);
|
|
224
|
+
} else {
|
|
225
|
+
ref.current = node;
|
|
226
|
+
}
|
|
227
|
+
setPopupRef(node);
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
css: styles.popupWrapperStyle,
|
|
231
|
+
tabIndex: 0
|
|
208
232
|
}, jsx("div", {
|
|
209
233
|
css: styles.popupStyle
|
|
210
234
|
}, settings.showFullPicker ? jsx(EmojiPicker, {
|
|
@@ -219,6 +243,6 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
219
243
|
showMore: allowAllEmojis,
|
|
220
244
|
onMoreClick: onSelectMoreClick,
|
|
221
245
|
pickerQuickReactionEmojiIds: pickerQuickReactionEmojiIds
|
|
222
|
-
}))))
|
|
246
|
+
}))));
|
|
223
247
|
})));
|
|
224
248
|
});
|
|
@@ -11,6 +11,11 @@ export const pickerStyle = css({
|
|
|
11
11
|
export const contentStyle = css({
|
|
12
12
|
display: 'flex'
|
|
13
13
|
});
|
|
14
|
+
export const popupWrapperStyle = css({
|
|
15
|
+
':focus': {
|
|
16
|
+
outline: 'none'
|
|
17
|
+
}
|
|
18
|
+
});
|
|
14
19
|
export const popupStyle = css({
|
|
15
20
|
background: `var(--ds-surface-overlay, ${N0})`,
|
|
16
21
|
borderRadius: `${borderRadius()}px`,
|
|
@@ -13,6 +13,8 @@ import { Reaction } from '../Reaction';
|
|
|
13
13
|
import { ReactionsDialog } from '../ReactionDialog';
|
|
14
14
|
import { ReactionPicker } from '../ReactionPicker';
|
|
15
15
|
import * as styles from './styles';
|
|
16
|
+
import { isSampled } from '../../analytics/analytics';
|
|
17
|
+
import { SAMPLING_RATE_REACTIONS_RENDERED_EXP } from '../../shared/constants';
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Set of all available UFO experiences relating to reactions dialog
|
|
@@ -97,9 +99,11 @@ export const Reactions = /*#__PURE__*/React.memo(({
|
|
|
97
99
|
if (status !== ReactionStatus.ready) {
|
|
98
100
|
renderTime.current = Date.now();
|
|
99
101
|
} else {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
if (isSampled(SAMPLING_RATE_REACTIONS_RENDERED_EXP)) {
|
|
103
|
+
var _renderTime$current;
|
|
104
|
+
Analytics.createAndFireSafe(createAnalyticsEvent, Analytics.createReactionsRenderedEvent, (_renderTime$current = renderTime.current) !== null && _renderTime$current !== void 0 ? _renderTime$current : Date.now() //renderTime.current can be null during unit test cases
|
|
105
|
+
);
|
|
106
|
+
}
|
|
103
107
|
renderTime.current = undefined;
|
|
104
108
|
}
|
|
105
109
|
}, [createAnalyticsEvent, status]);
|