@atlaskit/reactions 21.8.1 → 22.0.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 +26 -0
- package/dist/cjs/MockReactionsClient.js +24 -16
- package/dist/cjs/analytics/analytics.js +9 -1
- package/dist/cjs/analytics/ufo.js +24 -2
- package/dist/cjs/components/Counter/Counter.js +16 -20
- package/dist/cjs/components/Reaction/Reaction.js +52 -18
- package/dist/cjs/components/Reaction/styles.js +8 -1
- package/dist/cjs/components/ReactionDialog/ReactionView.js +121 -0
- package/dist/cjs/components/ReactionDialog/ReactionsDialog.js +187 -0
- package/dist/cjs/components/ReactionDialog/ReactionsList.js +104 -0
- package/dist/cjs/components/ReactionDialog/index.js +13 -0
- package/dist/cjs/components/ReactionDialog/styles.js +202 -0
- package/dist/cjs/components/ReactionPicker/ReactionPicker.js +15 -20
- package/dist/cjs/components/ReactionTooltip/ReactionTooltip.js +26 -12
- package/dist/cjs/components/ReactionTooltip/styles.js +11 -2
- package/dist/cjs/components/Reactions/Reactions.js +166 -21
- package/dist/cjs/components/Reactions/styles.js +11 -6
- package/dist/cjs/components/Trigger/Trigger.js +1 -2
- package/dist/cjs/components/index.js +9 -1
- package/dist/cjs/containers/ConnectedReactionPicker/ConnectedReactionPicker.js +6 -2
- package/dist/cjs/containers/ConnectedReactionsView/ConnectedReactionsView.js +9 -4
- package/dist/cjs/shared/constants.js +62 -10
- package/dist/cjs/shared/i18n.js +40 -0
- package/dist/cjs/shared/utils.js +60 -2
- package/dist/cjs/types/reaction.js +13 -1
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/MockReactionsClient.js +22 -14
- package/dist/es2019/analytics/analytics.js +3 -0
- package/dist/es2019/analytics/ufo.js +19 -0
- package/dist/es2019/components/Counter/Counter.js +16 -15
- package/dist/es2019/components/Reaction/Reaction.js +43 -18
- package/dist/es2019/components/Reaction/styles.js +9 -2
- package/dist/es2019/components/ReactionDialog/ReactionView.js +69 -0
- package/dist/es2019/components/ReactionDialog/ReactionsDialog.js +145 -0
- package/dist/es2019/components/ReactionDialog/ReactionsList.js +69 -0
- package/dist/es2019/components/ReactionDialog/index.js +1 -0
- package/dist/es2019/components/ReactionDialog/styles.js +169 -0
- package/dist/es2019/components/ReactionPicker/ReactionPicker.js +12 -20
- package/dist/es2019/components/ReactionTooltip/ReactionTooltip.js +22 -12
- package/dist/es2019/components/ReactionTooltip/styles.js +9 -1
- package/dist/es2019/components/Reactions/Reactions.js +146 -22
- package/dist/es2019/components/Reactions/styles.js +9 -5
- package/dist/es2019/components/Trigger/Trigger.js +1 -2
- package/dist/es2019/components/index.js +2 -1
- package/dist/es2019/containers/ConnectedReactionPicker/ConnectedReactionPicker.js +8 -2
- package/dist/es2019/containers/ConnectedReactionsView/ConnectedReactionsView.js +5 -4
- package/dist/es2019/shared/constants.js +55 -6
- package/dist/es2019/shared/i18n.js +43 -0
- package/dist/es2019/shared/utils.js +51 -0
- package/dist/es2019/types/reaction.js +13 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/MockReactionsClient.js +24 -13
- package/dist/esm/analytics/analytics.js +5 -0
- package/dist/esm/analytics/ufo.js +19 -0
- package/dist/esm/components/Counter/Counter.js +17 -17
- package/dist/esm/components/Reaction/Reaction.js +51 -19
- package/dist/esm/components/Reaction/styles.js +9 -2
- package/dist/esm/components/ReactionDialog/ReactionView.js +98 -0
- package/dist/esm/components/ReactionDialog/ReactionsDialog.js +161 -0
- package/dist/esm/components/ReactionDialog/ReactionsList.js +79 -0
- package/dist/esm/components/ReactionDialog/index.js +1 -0
- package/dist/esm/components/ReactionDialog/styles.js +177 -0
- package/dist/esm/components/ReactionPicker/ReactionPicker.js +15 -20
- package/dist/esm/components/ReactionTooltip/ReactionTooltip.js +26 -12
- package/dist/esm/components/ReactionTooltip/styles.js +9 -1
- package/dist/esm/components/Reactions/Reactions.js +158 -22
- package/dist/esm/components/Reactions/styles.js +9 -5
- package/dist/esm/components/Trigger/Trigger.js +1 -2
- package/dist/esm/components/index.js +2 -1
- package/dist/esm/containers/ConnectedReactionPicker/ConnectedReactionPicker.js +6 -2
- package/dist/esm/containers/ConnectedReactionsView/ConnectedReactionsView.js +8 -4
- package/dist/esm/shared/constants.js +57 -6
- package/dist/esm/shared/i18n.js +40 -0
- package/dist/esm/shared/utils.js +53 -0
- package/dist/esm/types/reaction.js +13 -1
- package/dist/esm/version.json +1 -1
- package/dist/types/MockReactionsClient.d.ts +7 -3
- package/dist/types/analytics/analytics.d.ts +10 -0
- package/dist/types/analytics/ufo.d.ts +18 -2
- package/dist/types/components/Counter/Counter.d.ts +0 -1
- package/dist/types/components/Reaction/Reaction.d.ts +11 -1
- package/dist/types/components/ReactionDialog/ReactionView.d.ts +19 -0
- package/dist/types/components/ReactionDialog/ReactionsDialog.d.ts +32 -0
- package/dist/types/components/ReactionDialog/ReactionsList.d.ts +23 -0
- package/dist/types/components/ReactionDialog/index.d.ts +1 -0
- package/dist/types/components/ReactionDialog/styles.d.ts +11 -0
- package/dist/types/components/ReactionPicker/ReactionPicker.d.ts +5 -0
- package/dist/types/components/ReactionTooltip/ReactionTooltip.d.ts +12 -0
- package/dist/types/components/ReactionTooltip/styles.d.ts +1 -0
- package/dist/types/components/Reactions/Reactions.d.ts +45 -6
- package/dist/types/components/Reactions/styles.d.ts +1 -0
- package/dist/types/components/index.d.ts +1 -0
- package/dist/types/containers/ConnectedReactionPicker/ConnectedReactionPicker.d.ts +0 -4
- package/dist/types/containers/ConnectedReactionsView/ConnectedReactionsView.d.ts +2 -11
- package/dist/types/index.d.ts +1 -1
- package/dist/types/shared/constants.d.ts +11 -5
- package/dist/types/shared/i18n.d.ts +40 -0
- package/dist/types/shared/utils.d.ts +7 -0
- package/dist/types/types/User.d.ts +10 -0
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/reaction.d.ts +15 -2
- package/docs/0-intro.tsx +3 -0
- package/docs/5-graphql-support.tsx +153 -0
- package/package.json +8 -6
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { css } from '@emotion/react';
|
|
3
|
+
import { B400, N500, N800 } from '@atlaskit/theme/colors';
|
|
4
|
+
import { token } from '@atlaskit/tokens';
|
|
5
|
+
import { constants } from '../../shared';
|
|
6
|
+
const REACTIONS_CONTAINER_WIDTH = 48;
|
|
7
|
+
const REACTION_RIGHT_MARGIN = 8;
|
|
8
|
+
/* we want to display around 9 reactions and show 10th one as faded so removing 2px from REACTIONS_CONTAINER_WIDTH*/
|
|
9
|
+
|
|
10
|
+
const CONTAINER_WIDTH = constants.NUMBER_OF_REACTIONS_TO_DISPLAY * (REACTIONS_CONTAINER_WIDTH + REACTION_RIGHT_MARGIN) + REACTIONS_CONTAINER_WIDTH - 2;
|
|
11
|
+
const REACTION_CONTAINER_HEIGHT = 48;
|
|
12
|
+
/*Reactions Container. Using pseudo Element :after to set border since with onClick of Reaction to higlight the
|
|
13
|
+
border blue below the reaction. Setting Border Width based on number of reactions to make sure it shows up
|
|
14
|
+
in case the container overflows */
|
|
15
|
+
|
|
16
|
+
export const containerStyle = reactionsBorderWidth => css({
|
|
17
|
+
overflow: 'hidden',
|
|
18
|
+
maxWidth: `${CONTAINER_WIDTH}px`,
|
|
19
|
+
height: '100%',
|
|
20
|
+
display: 'flex',
|
|
21
|
+
justifyContent: 'start',
|
|
22
|
+
position: 'relative',
|
|
23
|
+
scrollBehavior: 'smooth',
|
|
24
|
+
'&:after': {
|
|
25
|
+
content: '""',
|
|
26
|
+
zIndex: 0,
|
|
27
|
+
display: 'block',
|
|
28
|
+
minWidth: `${reactionsBorderWidth}%`,
|
|
29
|
+
bottom: '0px',
|
|
30
|
+
position: 'absolute'
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
export const titleStyle = css({
|
|
34
|
+
'& > h1': {
|
|
35
|
+
fontSize: '24px!important',
|
|
36
|
+
color: `${token('color.text', N800)}`
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
const containerEdgeAngle = {
|
|
40
|
+
rightEdge: 270,
|
|
41
|
+
leftEdge: 90
|
|
42
|
+
};
|
|
43
|
+
export const counterStyle = isSelected => css({
|
|
44
|
+
display: 'flex',
|
|
45
|
+
alignSelf: 'center',
|
|
46
|
+
lineHeight: '14px',
|
|
47
|
+
fontSize: '11px',
|
|
48
|
+
fontWeight: isSelected ? 700 : 400,
|
|
49
|
+
paddingRight: '0px',
|
|
50
|
+
marginTop: '5px',
|
|
51
|
+
'> div': {
|
|
52
|
+
width: '100%',
|
|
53
|
+
padding: '0px!important',
|
|
54
|
+
//Counter component has its own styles overriding them to match designs
|
|
55
|
+
color: isSelected ? `${token('color.text', B400)}!important` : `2px solid ${token('color.text', N500)}!important`
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const fadedCss = (edge, theme) => css({
|
|
60
|
+
content: '""',
|
|
61
|
+
position: 'absolute',
|
|
62
|
+
left: '0px',
|
|
63
|
+
top: '0px',
|
|
64
|
+
width: `${REACTIONS_CONTAINER_WIDTH}px`,
|
|
65
|
+
height: `${REACTION_CONTAINER_HEIGHT}px`,
|
|
66
|
+
zIndex: 0,
|
|
67
|
+
background: theme === 'dark' || theme === 'legacy-dark' ? `linear-gradient(${containerEdgeAngle[edge]}deg, rgba(34, 39, 43, 0.95) 40.23%, rgba(34, 39, 43, 0.55) 58.33%, rgba(34, 39, 43, 0) 77.49%)` : `linear-gradient(${containerEdgeAngle[edge]}deg, rgba(255, 255, 255, 0.95) 40.23%, rgba(255, 255, 255, 0.55) 58.33%, rgba(255, 255, 255, 0) 77.49%)`
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export const customTabWrapper = (isSelected, selectedEmojiId, theme) => css({
|
|
71
|
+
flexShrink: 0,
|
|
72
|
+
display: 'flex',
|
|
73
|
+
flexDirection: 'column',
|
|
74
|
+
textAlign: 'center',
|
|
75
|
+
alignItems: 'center',
|
|
76
|
+
justifyContent: 'center',
|
|
77
|
+
minWidth: `${REACTIONS_CONTAINER_WIDTH}px`,
|
|
78
|
+
minHeight: `${REACTION_CONTAINER_HEIGHT}px`,
|
|
79
|
+
marginRight: `${REACTION_RIGHT_MARGIN}px`,
|
|
80
|
+
boxSizing: 'border-box',
|
|
81
|
+
position: 'relative',
|
|
82
|
+
'> div': {
|
|
83
|
+
minWidth: `${REACTIONS_CONTAINER_WIDTH}px`,
|
|
84
|
+
minHeight: `${REACTION_CONTAINER_HEIGHT}px`,
|
|
85
|
+
padding: '0px !important',
|
|
86
|
+
alignItems: 'center',
|
|
87
|
+
justifyContent: 'center'
|
|
88
|
+
},
|
|
89
|
+
'& > span': {
|
|
90
|
+
minHeight: '16px',
|
|
91
|
+
minWidth: '16px'
|
|
92
|
+
},
|
|
93
|
+
'&.disabled:after': fadedCss('rightEdge', theme),
|
|
94
|
+
'&.disabled + &.disabled:after': fadedCss('leftEdge', theme),
|
|
95
|
+
'&:after': isSelected ? {
|
|
96
|
+
content: '""',
|
|
97
|
+
borderBottom: `2px solid ${token('color.text', B400)}`,
|
|
98
|
+
width: `${REACTIONS_CONTAINER_WIDTH}px`,
|
|
99
|
+
bottom: '0px',
|
|
100
|
+
display: 'block',
|
|
101
|
+
position: 'absolute',
|
|
102
|
+
zIndex: 2
|
|
103
|
+
} : {
|
|
104
|
+
content: '""',
|
|
105
|
+
borderBottom: `2px solid transparent`,
|
|
106
|
+
width: `${REACTIONS_CONTAINER_WIDTH}px`,
|
|
107
|
+
bottom: '0px',
|
|
108
|
+
display: 'block',
|
|
109
|
+
position: 'absolute',
|
|
110
|
+
zIndex: 1
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
export const navigationContainerStyle = css({
|
|
114
|
+
'> button': {
|
|
115
|
+
cursor: 'pointer'
|
|
116
|
+
},
|
|
117
|
+
'button:last-child': {
|
|
118
|
+
marginLeft: '16px'
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
export const reactionViewStyle = css({
|
|
122
|
+
marginTop: '24px',
|
|
123
|
+
display: 'flex',
|
|
124
|
+
flexDirection: 'column',
|
|
125
|
+
p: {
|
|
126
|
+
margin: 0,
|
|
127
|
+
color: `${token('color.text', N800)}`,
|
|
128
|
+
textTransform: 'capitalize',
|
|
129
|
+
fontWeight: 600,
|
|
130
|
+
fontSize: 16,
|
|
131
|
+
lineHeight: '20px',
|
|
132
|
+
'> span': {
|
|
133
|
+
marginRight: 8
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
export const userListStyle = css({
|
|
138
|
+
listStyle: 'none',
|
|
139
|
+
marginTop: 16,
|
|
140
|
+
padding: 0,
|
|
141
|
+
textAlign: 'left',
|
|
142
|
+
li: {
|
|
143
|
+
color: `${token('color.text', N500)}`,
|
|
144
|
+
fontSize: 14
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
export const userStyle = css({
|
|
148
|
+
display: 'flex',
|
|
149
|
+
alignItems: 'center',
|
|
150
|
+
padding: '8px 0px 8px 0px',
|
|
151
|
+
'> span': {
|
|
152
|
+
marginLeft: 16
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
export const customTabListStyles = css({
|
|
156
|
+
overflow: 'auto',
|
|
157
|
+
scrollBehavior: 'smooth',
|
|
158
|
+
display: 'flex',
|
|
159
|
+
paddingBottom: 4,
|
|
160
|
+
'div[role=tablist]': {
|
|
161
|
+
flexGrow: 1
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
export const centerSpinner = css({
|
|
165
|
+
display: 'flex',
|
|
166
|
+
justifyContent: 'center',
|
|
167
|
+
alignItems: 'center',
|
|
168
|
+
height: '100%'
|
|
169
|
+
});
|
|
@@ -61,10 +61,11 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
61
61
|
allowAllEmojis,
|
|
62
62
|
disabled,
|
|
63
63
|
pickerQuickReactionEmojiIds,
|
|
64
|
-
onShowMore,
|
|
65
|
-
onOpen,
|
|
66
|
-
onCancel,
|
|
67
|
-
tooltipContent = jsx(FormattedMessage, i18n.messages.addReaction)
|
|
64
|
+
onShowMore = () => {},
|
|
65
|
+
onOpen = () => {},
|
|
66
|
+
onCancel = () => {},
|
|
67
|
+
tooltipContent = jsx(FormattedMessage, i18n.messages.addReaction),
|
|
68
|
+
emojiPickerSize
|
|
68
69
|
} = props;
|
|
69
70
|
/**
|
|
70
71
|
* Container <div /> reference (used by custom hook to detect click outside)
|
|
@@ -92,10 +93,7 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
92
93
|
*/
|
|
93
94
|
|
|
94
95
|
useClickAway(wrapperRef, () => {
|
|
95
|
-
|
|
96
|
-
onCancel();
|
|
97
|
-
}
|
|
98
|
-
|
|
96
|
+
onCancel();
|
|
99
97
|
close();
|
|
100
98
|
}, 'click', true);
|
|
101
99
|
/**
|
|
@@ -128,10 +126,7 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
128
126
|
isOpen: true,
|
|
129
127
|
showFullPicker: true
|
|
130
128
|
});
|
|
131
|
-
|
|
132
|
-
if (onShowMore) {
|
|
133
|
-
onShowMore();
|
|
134
|
-
}
|
|
129
|
+
onShowMore();
|
|
135
130
|
}, [onShowMore]);
|
|
136
131
|
/**
|
|
137
132
|
* Event callback when an emoji icon is selected
|
|
@@ -158,11 +153,7 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
158
153
|
isOpen: !settings.isOpen,
|
|
159
154
|
showFullPicker: !!allowAllEmojis && Array.isArray(pickerQuickReactionEmojiIds) && pickerQuickReactionEmojiIds.length === 0
|
|
160
155
|
});
|
|
161
|
-
|
|
162
|
-
if (onOpen) {
|
|
163
|
-
onOpen();
|
|
164
|
-
} // ufo reactions picker opened success
|
|
165
|
-
|
|
156
|
+
onOpen(); // ufo reactions picker opened success
|
|
166
157
|
|
|
167
158
|
UFO.PickerRender.success();
|
|
168
159
|
};
|
|
@@ -182,7 +173,6 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
182
173
|
return jsx("div", {
|
|
183
174
|
className: wrapperClassName,
|
|
184
175
|
css: styles.pickerStyle,
|
|
185
|
-
ref: wrapperRef,
|
|
186
176
|
"data-testid": RENDER_REACTIONPICKER_TESTID
|
|
187
177
|
}, jsx(Manager, null, jsx(Reference, null, ({
|
|
188
178
|
ref: popperRef
|
|
@@ -214,10 +204,12 @@ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
|
|
|
214
204
|
},
|
|
215
205
|
ref: ref
|
|
216
206
|
}, jsx("div", {
|
|
217
|
-
css: styles.popupStyle
|
|
207
|
+
css: styles.popupStyle,
|
|
208
|
+
ref: wrapperRef
|
|
218
209
|
}, settings.showFullPicker ? jsx(EmojiPicker, {
|
|
219
210
|
emojiProvider: emojiProvider,
|
|
220
|
-
onSelection: onEmojiSelected
|
|
211
|
+
onSelection: onEmojiSelected,
|
|
212
|
+
size: emojiPickerSize
|
|
221
213
|
}) : jsx("div", {
|
|
222
214
|
css: styles.contentStyle
|
|
223
215
|
}, jsx(Selector, {
|
|
@@ -13,31 +13,41 @@ import * as styles from './styles';
|
|
|
13
13
|
|
|
14
14
|
export const RENDER_REACTIONTOOLTIP_TESTID = 'render-reactionTooltip';
|
|
15
15
|
export const ReactionTooltip = ({
|
|
16
|
-
emojiName,
|
|
17
16
|
children,
|
|
18
|
-
|
|
17
|
+
emojiName,
|
|
19
18
|
reaction: {
|
|
20
|
-
users = []
|
|
21
|
-
|
|
19
|
+
users = [],
|
|
20
|
+
emojiId = ''
|
|
21
|
+
},
|
|
22
|
+
maxReactions = constants.TOOLTIP_USERS_LIMIT,
|
|
23
|
+
handleUserListClick,
|
|
24
|
+
allowUserDialog = false,
|
|
25
|
+
isEnabled = true
|
|
22
26
|
}) => {
|
|
23
27
|
/**
|
|
24
28
|
* Render list of users in the tooltip box
|
|
25
29
|
*/
|
|
26
|
-
const content = !users || users.length === 0 ? null : jsx("div", {
|
|
27
|
-
css: styles.tooltipStyle
|
|
30
|
+
const content = !users || users.length === 0 || !isEnabled ? null : jsx("div", {
|
|
31
|
+
css: styles.tooltipStyle,
|
|
32
|
+
tabIndex: 0
|
|
28
33
|
}, jsx("ul", null, emojiName ? jsx("li", {
|
|
29
34
|
css: styles.emojiNameStyle
|
|
30
|
-
}, emojiName) : null, users.slice(0, maxReactions).map(
|
|
35
|
+
}, emojiName) : null, users.slice(0, maxReactions).map(user => {
|
|
31
36
|
return jsx("li", {
|
|
32
|
-
key:
|
|
37
|
+
key: user.id
|
|
33
38
|
}, user.displayName);
|
|
34
|
-
}),
|
|
35
|
-
css: styles.footerStyle
|
|
36
|
-
|
|
39
|
+
}), jsx("li", {
|
|
40
|
+
css: allowUserDialog ? [styles.footerStyle, styles.underlineStyle] : styles.footerStyle,
|
|
41
|
+
onClick: () => {
|
|
42
|
+
if (allowUserDialog && handleUserListClick) {
|
|
43
|
+
handleUserListClick(emojiId);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}, users.length > maxReactions ? jsx(FormattedMessage, _extends({}, i18n.messages.otherUsers, {
|
|
37
47
|
values: {
|
|
38
48
|
count: users.length - maxReactions
|
|
39
49
|
}
|
|
40
|
-
}))
|
|
50
|
+
})) : allowUserDialog && jsx(FormattedMessage, i18n.messages.moreInfo))));
|
|
41
51
|
return jsx(Tooltip, {
|
|
42
52
|
content: content,
|
|
43
53
|
position: "bottom",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
2
|
import { css } from '@emotion/react';
|
|
3
3
|
import { token } from '@atlaskit/tokens';
|
|
4
|
-
import { N90 } from '@atlaskit/theme/colors';
|
|
4
|
+
import { N90, N800, N0 } from '@atlaskit/theme/colors';
|
|
5
5
|
export const verticalMargin = 5;
|
|
6
6
|
export const tooltipStyle = css({
|
|
7
7
|
maxWidth: '150px',
|
|
@@ -29,4 +29,12 @@ export const emojiNameStyle = css({
|
|
|
29
29
|
export const footerStyle = css({
|
|
30
30
|
color: token('color.text.inverse', N90),
|
|
31
31
|
fontWeight: 300
|
|
32
|
+
});
|
|
33
|
+
export const underlineStyle = css({
|
|
34
|
+
cursor: 'pointer',
|
|
35
|
+
textDecoration: 'underline',
|
|
36
|
+
':hover': {
|
|
37
|
+
backgroundColor: token('color.background.neutral.bold', N800),
|
|
38
|
+
color: token('color.text.inverse', N0)
|
|
39
|
+
}
|
|
32
40
|
});
|
|
@@ -1,19 +1,48 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
|
-
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { jsx } from '@emotion/react';
|
|
4
|
-
import { useAnalyticsEvents } from '@atlaskit/analytics-next';
|
|
5
4
|
import { FormattedMessage } from 'react-intl-next';
|
|
6
|
-
import {
|
|
5
|
+
import { useAnalyticsEvents } from '@atlaskit/analytics-next';
|
|
6
|
+
import { ModalTransition } from '@atlaskit/modal-dialog';
|
|
7
|
+
import Button from '@atlaskit/button';
|
|
8
|
+
import Tooltip from '@atlaskit/tooltip';
|
|
9
|
+
import { Analytics, UFO } from '../../analytics';
|
|
7
10
|
import { ReactionStatus } from '../../types';
|
|
8
11
|
import { i18n } from '../../shared';
|
|
9
12
|
import { Reaction } from '../Reaction';
|
|
13
|
+
import { ReactionsDialog } from '../ReactionDialog';
|
|
10
14
|
import { ReactionPicker } from '../ReactionPicker';
|
|
11
15
|
import * as styles from './styles';
|
|
16
|
+
/**
|
|
17
|
+
* Set of all available UFO experiences relating to reactions dialog
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export const ufoExperiences = {
|
|
21
|
+
/**
|
|
22
|
+
* Expeirence when a reaction dialog is opened
|
|
23
|
+
*/
|
|
24
|
+
openDialog: UFO.ReactionDialogOpened,
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Experience when a reaction dialog is closed
|
|
28
|
+
*/
|
|
29
|
+
closeDialog: UFO.ReactionDialogClosed,
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Experience when a reaction changed/fetched from inside the modal dialog
|
|
33
|
+
*/
|
|
34
|
+
selectedReactionChangeInsideDialog: UFO.ReactionDialogSelectedReactionChanged
|
|
35
|
+
};
|
|
12
36
|
/**
|
|
13
37
|
* Test id for wrapper Reactions div
|
|
14
38
|
*/
|
|
15
39
|
|
|
16
40
|
export const RENDER_REACTIONS_TESTID = 'render-reactions';
|
|
41
|
+
/**
|
|
42
|
+
* Test id for the view all reacted user to trigger the dialog
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
export const RENDER_VIEWALL_REACTED_USERS_DIALOG = 'viewall-reacted-users-dialog';
|
|
17
46
|
|
|
18
47
|
/**
|
|
19
48
|
* Get content of the tooltip
|
|
@@ -46,41 +75,48 @@ export const Reactions = /*#__PURE__*/React.memo(({
|
|
|
46
75
|
loadReaction,
|
|
47
76
|
quickReactionEmojis,
|
|
48
77
|
pickerQuickReactionEmojiIds,
|
|
49
|
-
|
|
78
|
+
getReactionDetails = () => {},
|
|
79
|
+
onReactionHover = () => {},
|
|
50
80
|
onSelection,
|
|
51
81
|
reactions = [],
|
|
52
82
|
emojiProvider,
|
|
53
83
|
allowAllEmojis,
|
|
54
|
-
onReactionClick
|
|
84
|
+
onReactionClick,
|
|
85
|
+
allowUserDialog,
|
|
86
|
+
onDialogOpenCallback = () => {},
|
|
87
|
+
onDialogCloseCallback = () => {},
|
|
88
|
+
onDialogSelectReactionCallback = () => {},
|
|
89
|
+
emojiPickerSize = 'medium'
|
|
55
90
|
}) => {
|
|
91
|
+
const [selectedEmojiId, setSelectedEmojiId] = useState();
|
|
56
92
|
const {
|
|
57
93
|
createAnalyticsEvent
|
|
58
94
|
} = useAnalyticsEvents();
|
|
59
95
|
let openTime = useRef();
|
|
60
96
|
let renderTime = useRef();
|
|
61
|
-
|
|
62
|
-
if (status !== ReactionStatus.ready) {
|
|
63
|
-
renderTime.current = Date.now();
|
|
64
|
-
}
|
|
65
|
-
|
|
66
97
|
useEffect(() => {
|
|
67
98
|
if (status === ReactionStatus.notLoaded) {
|
|
68
99
|
loadReaction();
|
|
69
100
|
}
|
|
70
101
|
}, [status, loadReaction]);
|
|
71
102
|
useEffect(() => {
|
|
72
|
-
if (status
|
|
73
|
-
|
|
103
|
+
if (status !== ReactionStatus.ready) {
|
|
104
|
+
renderTime.current = Date.now();
|
|
105
|
+
} else {
|
|
106
|
+
var _renderTime$current;
|
|
107
|
+
|
|
108
|
+
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
|
|
109
|
+
);
|
|
74
110
|
renderTime.current = undefined;
|
|
75
111
|
}
|
|
76
112
|
}, [createAnalyticsEvent, status]);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
113
|
+
const handleReactionMouseEnter = useCallback(emojiId => {
|
|
114
|
+
getReactionDetails(emojiId);
|
|
115
|
+
onReactionHover(emojiId);
|
|
116
|
+
}, [getReactionDetails, onReactionHover]);
|
|
117
|
+
const handleReactionFocused = useCallback(emojiId => {
|
|
118
|
+
getReactionDetails(emojiId);
|
|
119
|
+
}, [getReactionDetails]);
|
|
84
120
|
const handlePickerOpen = useCallback(() => {
|
|
85
121
|
openTime.current = Date.now();
|
|
86
122
|
Analytics.createAndFireSafe(createAnalyticsEvent, Analytics.createPickerButtonClickedEvent, reactions.length);
|
|
@@ -97,10 +133,80 @@ export const Reactions = /*#__PURE__*/React.memo(({
|
|
|
97
133
|
openTime.current = undefined;
|
|
98
134
|
onSelection(emojiId);
|
|
99
135
|
}, [createAnalyticsEvent, onSelection, reactions]);
|
|
136
|
+
/**
|
|
137
|
+
* event handler to open selected reaction from tooltip
|
|
138
|
+
* @param emojiId selected emoji id
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
const handleOpenReactionsDialog = emojiId => {
|
|
142
|
+
// ufo start opening reaction dialog
|
|
143
|
+
ufoExperiences.openDialog.start();
|
|
144
|
+
setSelectedEmojiId(emojiId);
|
|
145
|
+
onDialogOpenCallback(emojiId, 'tooltip'); // ufo opening reaction dialog success
|
|
146
|
+
|
|
147
|
+
ufoExperiences.openDialog.success({
|
|
148
|
+
metadata: {
|
|
149
|
+
emojiId: emojiId,
|
|
150
|
+
source: 'Reactions',
|
|
151
|
+
reason: 'Opening dialog from emoji tooltip link successfully'
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Event handler to oepn all reactions link button
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
const handleOpenAllReactionsDialog = () => {
|
|
161
|
+
// ufo start opening reaction dialog
|
|
162
|
+
ufoExperiences.openDialog.start();
|
|
163
|
+
const emojiId = reactions[0].emojiId;
|
|
164
|
+
getReactionDetails(emojiId);
|
|
165
|
+
setSelectedEmojiId(emojiId);
|
|
166
|
+
onDialogOpenCallback(emojiId, 'button'); // ufo opening reaction dialog success
|
|
167
|
+
|
|
168
|
+
ufoExperiences.openDialog.success({
|
|
169
|
+
metadata: {
|
|
170
|
+
emojiId: emojiId,
|
|
171
|
+
source: 'Reactions',
|
|
172
|
+
reason: 'Opening all reactions dialog link successfully'
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const handleCloseReactionsDialog = (e, analyticsEvent) => {
|
|
178
|
+
// ufo closing opening reaction dialog
|
|
179
|
+
ufoExperiences.closeDialog.start();
|
|
180
|
+
setSelectedEmojiId('');
|
|
181
|
+
onDialogCloseCallback(e, analyticsEvent); // ufo closing reaction dialog success
|
|
182
|
+
|
|
183
|
+
ufoExperiences.closeDialog.success({
|
|
184
|
+
metadata: {
|
|
185
|
+
source: 'Reactions',
|
|
186
|
+
reason: 'Closing reactions dialog successfully'
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const handleSelectReactionInDialog = (emojiId, analyticsEvent) => {
|
|
192
|
+
// ufo selected reaction inside the modal dialog
|
|
193
|
+
ufoExperiences.selectedReactionChangeInsideDialog.start();
|
|
194
|
+
handleReactionMouseEnter(emojiId);
|
|
195
|
+
onDialogSelectReactionCallback(emojiId, analyticsEvent); // ufo selected reaction inside the modal dialog success
|
|
196
|
+
|
|
197
|
+
ufoExperiences.selectedReactionChangeInsideDialog.success({
|
|
198
|
+
metadata: {
|
|
199
|
+
emojiId: emojiId,
|
|
200
|
+
source: 'Reactions',
|
|
201
|
+
reason: 'Selected Emoji changed'
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
};
|
|
100
205
|
/**
|
|
101
206
|
* Get the reactions that we want to render are any reactions with a count greater than zero as well as any default emoji not already shown
|
|
102
207
|
*/
|
|
103
208
|
|
|
209
|
+
|
|
104
210
|
const memorizedReactions = useMemo(() => {
|
|
105
211
|
//
|
|
106
212
|
|
|
@@ -138,7 +244,10 @@ export const Reactions = /*#__PURE__*/React.memo(({
|
|
|
138
244
|
emojiProvider: emojiProvider,
|
|
139
245
|
onClick: onReactionClick,
|
|
140
246
|
onMouseEnter: handleReactionMouseEnter,
|
|
141
|
-
|
|
247
|
+
onFocused: handleReactionFocused,
|
|
248
|
+
flash: flash[reaction.emojiId],
|
|
249
|
+
handleUserListClick: handleOpenReactionsDialog,
|
|
250
|
+
allowUserDialog: allowUserDialog
|
|
142
251
|
})), jsx(ReactionPicker, {
|
|
143
252
|
css: styles.reactionStyle,
|
|
144
253
|
emojiProvider: emojiProvider,
|
|
@@ -150,6 +259,21 @@ export const Reactions = /*#__PURE__*/React.memo(({
|
|
|
150
259
|
onOpen: handlePickerOpen,
|
|
151
260
|
onCancel: handleOnCancel,
|
|
152
261
|
onShowMore: handleOnMore,
|
|
153
|
-
tooltipContent: getTooltip(status, errorMessage)
|
|
154
|
-
|
|
262
|
+
tooltipContent: getTooltip(status, errorMessage),
|
|
263
|
+
emojiPickerSize: emojiPickerSize
|
|
264
|
+
}), allowUserDialog && reactions.length > 0 && jsx(Tooltip, {
|
|
265
|
+
content: jsx(FormattedMessage, i18n.messages.seeWhoReactedTooltip),
|
|
266
|
+
hideTooltipOnClick: true
|
|
267
|
+
}, jsx(Button, {
|
|
268
|
+
appearance: "subtle-link",
|
|
269
|
+
onClick: handleOpenAllReactionsDialog,
|
|
270
|
+
css: styles.seeWhoReacted,
|
|
271
|
+
testId: RENDER_VIEWALL_REACTED_USERS_DIALOG
|
|
272
|
+
}, jsx(FormattedMessage, i18n.messages.seeWhoReacted))), jsx(ModalTransition, null, !!selectedEmojiId && jsx(ReactionsDialog, {
|
|
273
|
+
selectedEmojiId: selectedEmojiId,
|
|
274
|
+
reactions: memorizedReactions,
|
|
275
|
+
emojiProvider: emojiProvider,
|
|
276
|
+
handleCloseReactionsDialog: handleCloseReactionsDialog,
|
|
277
|
+
handleSelectReaction: handleSelectReactionInDialog
|
|
278
|
+
})));
|
|
155
279
|
});
|
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
import { css } from '@emotion/react';
|
|
3
3
|
export const reactionStyle = css({
|
|
4
4
|
display: 'inline-block',
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
margin: '4px'
|
|
6
|
+
});
|
|
7
|
+
export const seeWhoReacted = css({
|
|
8
|
+
height: '24px',
|
|
9
|
+
lineHeight: '24px',
|
|
10
|
+
paddingLeft: '4px',
|
|
11
|
+
paddingRight: '4px',
|
|
12
|
+
margin: '4px'
|
|
7
13
|
});
|
|
8
14
|
export const wrapperStyle = css({
|
|
9
15
|
display: 'flex',
|
|
@@ -11,9 +17,7 @@ export const wrapperStyle = css({
|
|
|
11
17
|
position: 'relative',
|
|
12
18
|
alignItems: 'center',
|
|
13
19
|
borderRadius: '15px',
|
|
14
|
-
|
|
15
|
-
marginTop: '-2px',
|
|
16
|
-
'> :first-of-type > :first-child': {
|
|
20
|
+
'> :first-of-type > :first-of-type': {
|
|
17
21
|
marginLeft: 0
|
|
18
22
|
}
|
|
19
23
|
});
|
|
@@ -33,8 +33,7 @@ export const Trigger = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
33
33
|
|
|
34
34
|
return jsx(Tooltip, {
|
|
35
35
|
testId: RENDER_TOOLTIP_TRIGGER_TESTID,
|
|
36
|
-
content: tooltipContent
|
|
37
|
-
position: "top"
|
|
36
|
+
content: tooltipContent
|
|
38
37
|
}, jsx(Button, _extends({
|
|
39
38
|
css: styles.triggerStyle({
|
|
40
39
|
miniMode,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { Reaction } from './Reaction';
|
|
2
2
|
export { ReactionPicker } from './ReactionPicker';
|
|
3
3
|
export { Reactions } from './Reactions';
|
|
4
|
-
export { UfoErrorBoundary } from './UfoErrorBoundary';
|
|
4
|
+
export { UfoErrorBoundary } from './UfoErrorBoundary';
|
|
5
|
+
export { ReactionsDialog } from './ReactionDialog/ReactionsDialog';
|
|
@@ -7,15 +7,21 @@ import { UFO } from '../../analytics';
|
|
|
7
7
|
* Reaction Picker component
|
|
8
8
|
*/
|
|
9
9
|
export const ConnectedReactionPicker = props => {
|
|
10
|
+
const {
|
|
11
|
+
store,
|
|
12
|
+
containerAri,
|
|
13
|
+
ari
|
|
14
|
+
} = props;
|
|
10
15
|
/**
|
|
11
16
|
* callback event when an emoji item is selected
|
|
12
17
|
* @param emojiId unique id for the reaction emoji
|
|
13
18
|
*/
|
|
19
|
+
|
|
14
20
|
const onSelection = emojiId => {
|
|
15
21
|
(async () => {
|
|
16
|
-
const _store = await Promise.resolve(
|
|
22
|
+
const _store = await Promise.resolve(store);
|
|
17
23
|
|
|
18
|
-
_store.addReaction(
|
|
24
|
+
_store.addReaction(containerAri, ari, emojiId);
|
|
19
25
|
})();
|
|
20
26
|
};
|
|
21
27
|
|
|
@@ -52,7 +52,7 @@ export const mapDispatchToPropsHelper = (actions, containerAri, ari) => {
|
|
|
52
52
|
onReactionClick: emojiId => {
|
|
53
53
|
actions.toggleReaction(containerAri, ari, emojiId);
|
|
54
54
|
},
|
|
55
|
-
|
|
55
|
+
getReactionDetails: emojiId => {
|
|
56
56
|
actions.getDetailedReaction(containerAri, ari, emojiId);
|
|
57
57
|
},
|
|
58
58
|
onSelection: emojiId => {
|
|
@@ -64,7 +64,8 @@ export const ConnectedReactionsView = props => {
|
|
|
64
64
|
const {
|
|
65
65
|
ari,
|
|
66
66
|
containerAri,
|
|
67
|
-
store
|
|
67
|
+
store,
|
|
68
|
+
...rest
|
|
68
69
|
} = props;
|
|
69
70
|
/**
|
|
70
71
|
* Reference to the <Reactions /> component instance mandatory props
|
|
@@ -159,6 +160,6 @@ export const ConnectedReactionsView = props => {
|
|
|
159
160
|
}, /*#__PURE__*/React.createElement(UfoErrorBoundary, {
|
|
160
161
|
experiences: experienceInstance.current ? [experienceInstance.current] : []
|
|
161
162
|
}, stateData && dispatchData ? /*#__PURE__*/React.createElement(Reactions, _extends({
|
|
162
|
-
key: `${
|
|
163
|
-
},
|
|
163
|
+
key: `${containerAri}|${ari}`
|
|
164
|
+
}, rest, dispatchData, stateData)) : null));
|
|
164
165
|
};
|