@atlaskit/reactions 21.5.1 → 21.6.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.
Files changed (310) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/MockReactionsClient/package.json +7 -0
  3. package/dist/cjs/{client/MockReactionsClient.js → MockReactionsClient.js} +4 -6
  4. package/dist/cjs/analytics/analytics.js +141 -0
  5. package/dist/cjs/analytics/index.js +4 -134
  6. package/dist/cjs/client/ReactionServiceClient.js +29 -6
  7. package/dist/cjs/client/index.js +1 -33
  8. package/dist/cjs/components/{Counter.js → Counter/Counter.js} +32 -39
  9. package/dist/cjs/components/Counter/index.js +36 -0
  10. package/dist/cjs/components/Counter/styles.js +33 -0
  11. package/dist/cjs/components/EmojiButton/EmojiButton.js +58 -0
  12. package/dist/cjs/components/EmojiButton/index.js +19 -0
  13. package/dist/cjs/components/EmojiButton/styles.js +25 -0
  14. package/dist/cjs/components/FlashAnimation/FlashAnimation.js +42 -0
  15. package/dist/cjs/components/FlashAnimation/index.js +19 -0
  16. package/dist/cjs/components/{FlashAnimation.js → FlashAnimation/styles.js} +7 -26
  17. package/dist/cjs/components/Reaction/Reaction.js +163 -0
  18. package/dist/cjs/components/Reaction/index.js +19 -0
  19. package/dist/cjs/components/Reaction/styles.js +70 -0
  20. package/dist/cjs/components/ReactionPicker/ReactionPicker.js +272 -0
  21. package/dist/cjs/components/ReactionPicker/index.js +19 -0
  22. package/dist/cjs/components/ReactionPicker/styles.js +37 -0
  23. package/dist/cjs/components/ReactionTooltip/ReactionTooltip.js +71 -0
  24. package/dist/cjs/components/ReactionTooltip/index.js +19 -0
  25. package/dist/cjs/components/ReactionTooltip/styles.js +46 -0
  26. package/dist/cjs/components/Reactions/Reactions.js +200 -0
  27. package/dist/cjs/components/Reactions/index.js +25 -0
  28. package/dist/cjs/components/Reactions/styles.js +29 -0
  29. package/dist/cjs/components/Selector/Selector.js +132 -0
  30. package/dist/cjs/components/Selector/index.js +30 -0
  31. package/dist/cjs/components/Selector/styles.js +56 -0
  32. package/dist/cjs/components/ShowMore/ShowMore.js +71 -0
  33. package/dist/cjs/components/ShowMore/index.js +19 -0
  34. package/dist/cjs/components/ShowMore/styles.js +44 -0
  35. package/dist/cjs/components/Trigger/Trigger.js +59 -0
  36. package/dist/cjs/components/Trigger/index.js +13 -0
  37. package/dist/cjs/components/Trigger/styles.js +46 -0
  38. package/dist/cjs/components/{UfoErrorBoundary.js → UfoErrorBoundary/UfoErrorBoundary.js} +3 -0
  39. package/dist/cjs/components/UfoErrorBoundary/index.js +13 -0
  40. package/dist/cjs/containers/ConnectedReactionPicker/ConnectedReactionPicker.js +62 -0
  41. package/dist/cjs/containers/ConnectedReactionPicker/index.js +13 -0
  42. package/dist/cjs/containers/ConnectedReactionsView/ConnectedReactionsView.js +258 -0
  43. package/dist/cjs/containers/ConnectedReactionsView/index.js +13 -0
  44. package/dist/cjs/containers/index.js +23 -13
  45. package/dist/cjs/hooks/index.js +13 -0
  46. package/dist/cjs/hooks/useClickAway.js +35 -0
  47. package/dist/cjs/index.js +8 -0
  48. package/dist/cjs/shared/constants.js +39 -8
  49. package/dist/cjs/{components → shared}/i18n.js +1 -1
  50. package/dist/cjs/shared/index.js +11 -3
  51. package/dist/cjs/shared/utils.js +54 -0
  52. package/dist/cjs/store/{ReactionsStore.js → MemoryReactionsStore.js} +37 -18
  53. package/dist/cjs/store/ReactionConsumer.js +43 -15
  54. package/dist/cjs/store/index.js +8 -2
  55. package/dist/cjs/store/utils.js +4 -10
  56. package/dist/cjs/{client/ReactionClient.js → types/client.js} +0 -0
  57. package/dist/cjs/types/index.js +2 -2
  58. package/dist/cjs/types/reaction.js +43 -0
  59. package/dist/cjs/types/{DetailedReaction.js → store.js} +0 -0
  60. package/dist/cjs/version.json +1 -1
  61. package/dist/es2019/{client/MockReactionsClient.js → MockReactionsClient.js} +4 -5
  62. package/dist/es2019/analytics/analytics.js +64 -0
  63. package/dist/es2019/analytics/index.js +3 -65
  64. package/dist/es2019/analytics/ufo.js +0 -1
  65. package/dist/es2019/client/ReactionServiceClient.js +31 -6
  66. package/dist/es2019/client/index.js +1 -2
  67. package/dist/es2019/components/{Counter.js → Counter/Counter.js} +26 -31
  68. package/dist/es2019/components/Counter/index.js +3 -0
  69. package/dist/es2019/components/Counter/styles.js +20 -0
  70. package/dist/es2019/components/EmojiButton/EmojiButton.js +35 -0
  71. package/dist/es2019/components/EmojiButton/index.js +1 -0
  72. package/dist/es2019/components/EmojiButton/styles.js +16 -0
  73. package/dist/es2019/components/FlashAnimation/FlashAnimation.js +18 -0
  74. package/dist/es2019/components/FlashAnimation/index.js +1 -0
  75. package/dist/es2019/components/{FlashAnimation.js → FlashAnimation/styles.js} +6 -17
  76. package/dist/es2019/components/Reaction/Reaction.js +104 -0
  77. package/dist/es2019/components/Reaction/index.js +1 -0
  78. package/dist/es2019/components/Reaction/styles.js +55 -0
  79. package/dist/es2019/components/ReactionPicker/ReactionPicker.js +208 -0
  80. package/dist/es2019/components/ReactionPicker/index.js +1 -0
  81. package/dist/es2019/components/ReactionPicker/styles.js +23 -0
  82. package/dist/es2019/components/ReactionTooltip/ReactionTooltip.js +46 -0
  83. package/dist/es2019/components/ReactionTooltip/index.js +1 -0
  84. package/dist/es2019/components/ReactionTooltip/styles.js +32 -0
  85. package/dist/es2019/components/Reactions/Reactions.js +156 -0
  86. package/dist/es2019/components/Reactions/index.js +1 -0
  87. package/dist/es2019/components/Reactions/styles.js +19 -0
  88. package/dist/es2019/components/Selector/Selector.js +98 -0
  89. package/dist/es2019/components/Selector/index.js +3 -0
  90. package/dist/es2019/components/Selector/styles.js +39 -0
  91. package/dist/es2019/components/ShowMore/ShowMore.js +43 -0
  92. package/dist/es2019/components/ShowMore/index.js +1 -0
  93. package/dist/es2019/components/ShowMore/styles.js +30 -0
  94. package/dist/es2019/components/{Trigger.js → Trigger/Trigger.js} +15 -20
  95. package/dist/es2019/components/Trigger/index.js +1 -0
  96. package/dist/es2019/components/Trigger/styles.js +24 -0
  97. package/dist/es2019/components/{UfoErrorBoundary.js → UfoErrorBoundary/UfoErrorBoundary.js} +4 -0
  98. package/dist/es2019/components/UfoErrorBoundary/index.js +1 -0
  99. package/dist/es2019/containers/ConnectedReactionPicker/ConnectedReactionPicker.js +27 -0
  100. package/dist/es2019/containers/ConnectedReactionPicker/index.js +1 -0
  101. package/dist/es2019/containers/ConnectedReactionsView/ConnectedReactionsView.js +166 -0
  102. package/dist/es2019/containers/ConnectedReactionsView/index.js +1 -0
  103. package/dist/es2019/containers/index.js +2 -2
  104. package/dist/es2019/hooks/index.js +1 -0
  105. package/dist/es2019/hooks/useClickAway.js +27 -0
  106. package/dist/es2019/index.js +3 -1
  107. package/dist/es2019/shared/constants.js +32 -4
  108. package/dist/es2019/{components → shared}/i18n.js +1 -1
  109. package/dist/es2019/shared/index.js +6 -2
  110. package/dist/es2019/shared/utils.js +35 -0
  111. package/dist/es2019/store/{ReactionsStore.js → MemoryReactionsStore.js} +36 -17
  112. package/dist/es2019/store/ReactionConsumer.js +18 -12
  113. package/dist/es2019/store/index.js +1 -1
  114. package/dist/es2019/store/utils.js +8 -4
  115. package/dist/es2019/{client/ReactionClient.js → types/client.js} +0 -0
  116. package/dist/es2019/types/index.js +1 -1
  117. package/dist/es2019/types/reaction.js +34 -0
  118. package/dist/es2019/types/{DetailedReaction.js → store.js} +0 -0
  119. package/dist/es2019/version.json +1 -1
  120. package/dist/esm/{client/MockReactionsClient.js → MockReactionsClient.js} +4 -5
  121. package/dist/esm/analytics/analytics.js +99 -0
  122. package/dist/esm/analytics/index.js +3 -99
  123. package/dist/esm/analytics/ufo.js +0 -1
  124. package/dist/esm/client/ReactionServiceClient.js +30 -6
  125. package/dist/esm/client/index.js +1 -2
  126. package/dist/esm/components/{Counter.js → Counter/Counter.js} +26 -31
  127. package/dist/esm/components/Counter/index.js +3 -0
  128. package/dist/esm/components/Counter/styles.js +20 -0
  129. package/dist/esm/components/EmojiButton/EmojiButton.js +35 -0
  130. package/dist/esm/components/EmojiButton/index.js +1 -0
  131. package/dist/esm/components/EmojiButton/styles.js +16 -0
  132. package/dist/esm/components/FlashAnimation/FlashAnimation.js +20 -0
  133. package/dist/esm/components/FlashAnimation/index.js +1 -0
  134. package/dist/esm/components/{FlashAnimation.js → FlashAnimation/styles.js} +6 -19
  135. package/dist/esm/components/Reaction/Reaction.js +131 -0
  136. package/dist/esm/components/Reaction/index.js +1 -0
  137. package/dist/esm/components/Reaction/styles.js +55 -0
  138. package/dist/esm/components/ReactionPicker/ReactionPicker.js +243 -0
  139. package/dist/esm/components/ReactionPicker/index.js +1 -0
  140. package/dist/esm/components/ReactionPicker/styles.js +23 -0
  141. package/dist/esm/components/ReactionTooltip/ReactionTooltip.js +46 -0
  142. package/dist/esm/components/ReactionTooltip/index.js +1 -0
  143. package/dist/esm/components/ReactionTooltip/styles.js +32 -0
  144. package/dist/esm/components/Reactions/Reactions.js +166 -0
  145. package/dist/esm/components/Reactions/index.js +1 -0
  146. package/dist/esm/components/Reactions/styles.js +19 -0
  147. package/dist/esm/components/Selector/Selector.js +107 -0
  148. package/dist/esm/components/Selector/index.js +3 -0
  149. package/dist/esm/components/Selector/styles.js +41 -0
  150. package/dist/esm/components/ShowMore/ShowMore.js +46 -0
  151. package/dist/esm/components/ShowMore/index.js +1 -0
  152. package/dist/esm/components/ShowMore/styles.js +30 -0
  153. package/dist/esm/components/{Trigger.js → Trigger/Trigger.js} +15 -20
  154. package/dist/esm/components/Trigger/index.js +1 -0
  155. package/dist/esm/components/Trigger/styles.js +31 -0
  156. package/dist/esm/components/{UfoErrorBoundary.js → UfoErrorBoundary/UfoErrorBoundary.js} +4 -0
  157. package/dist/esm/components/UfoErrorBoundary/index.js +1 -0
  158. package/dist/esm/containers/ConnectedReactionPicker/ConnectedReactionPicker.js +46 -0
  159. package/dist/esm/containers/ConnectedReactionPicker/index.js +1 -0
  160. package/dist/esm/containers/ConnectedReactionsView/ConnectedReactionsView.js +227 -0
  161. package/dist/esm/containers/ConnectedReactionsView/index.js +1 -0
  162. package/dist/esm/containers/index.js +2 -2
  163. package/dist/esm/hooks/index.js +1 -0
  164. package/dist/esm/hooks/useClickAway.js +28 -0
  165. package/dist/esm/index.js +3 -1
  166. package/dist/esm/shared/constants.js +34 -4
  167. package/dist/esm/{components → shared}/i18n.js +1 -1
  168. package/dist/esm/shared/index.js +6 -2
  169. package/dist/esm/shared/utils.js +41 -0
  170. package/dist/esm/store/{ReactionsStore.js → MemoryReactionsStore.js} +36 -20
  171. package/dist/esm/store/ReactionConsumer.js +42 -15
  172. package/dist/esm/store/index.js +1 -1
  173. package/dist/esm/store/utils.js +8 -4
  174. package/dist/{es2019/types/ReactionSource.js → esm/types/client.js} +0 -0
  175. package/dist/esm/types/index.js +1 -1
  176. package/dist/esm/types/reaction.js +34 -0
  177. package/dist/{es2019/types/ReactionSummary.js → esm/types/store.js} +0 -0
  178. package/dist/esm/version.json +1 -1
  179. package/dist/types/{client/MockReactionsClient.d.ts → MockReactionsClient.d.ts} +4 -5
  180. package/dist/types/analytics/analytics.d.ts +96 -0
  181. package/dist/types/analytics/index.d.ts +1 -96
  182. package/dist/types/client/ReactionServiceClient.d.ts +27 -10
  183. package/dist/types/client/index.d.ts +0 -2
  184. package/dist/types/components/{Counter.d.ts → Counter/Counter.d.ts} +15 -7
  185. package/dist/types/components/Counter/index.d.ts +3 -0
  186. package/dist/types/components/Counter/styles.d.ts +3 -0
  187. package/dist/types/components/EmojiButton/EmojiButton.d.ts +22 -0
  188. package/dist/types/components/EmojiButton/index.d.ts +2 -0
  189. package/dist/types/components/EmojiButton/styles.d.ts +1 -0
  190. package/dist/types/components/FlashAnimation/FlashAnimation.d.ts +20 -0
  191. package/dist/types/components/FlashAnimation/index.d.ts +2 -0
  192. package/dist/types/components/FlashAnimation/styles.d.ts +3 -0
  193. package/dist/types/components/Reaction/Reaction.d.ts +38 -0
  194. package/dist/types/components/Reaction/index.d.ts +2 -0
  195. package/dist/types/components/Reaction/styles.d.ts +10 -0
  196. package/dist/types/components/{ReactionPicker.d.ts → ReactionPicker/ReactionPicker.d.ts} +12 -33
  197. package/dist/types/components/ReactionPicker/index.d.ts +2 -0
  198. package/dist/types/components/ReactionPicker/styles.d.ts +3 -0
  199. package/dist/types/components/ReactionTooltip/ReactionTooltip.d.ts +22 -0
  200. package/dist/types/components/ReactionTooltip/index.d.ts +2 -0
  201. package/dist/types/components/ReactionTooltip/styles.d.ts +4 -0
  202. package/dist/types/components/Reactions/Reactions.d.ts +64 -0
  203. package/dist/types/components/Reactions/index.d.ts +2 -0
  204. package/dist/types/components/Reactions/styles.d.ts +2 -0
  205. package/dist/types/components/Selector/Selector.d.ts +34 -0
  206. package/dist/types/components/Selector/index.d.ts +3 -0
  207. package/dist/types/components/Selector/styles.d.ts +10 -0
  208. package/dist/types/components/{ShowMore.d.ts → ShowMore/ShowMore.d.ts} +14 -13
  209. package/dist/types/components/ShowMore/index.d.ts +2 -0
  210. package/dist/types/components/ShowMore/styles.d.ts +3 -0
  211. package/dist/types/components/Trigger/Trigger.d.ts +23 -0
  212. package/dist/types/components/Trigger/index.d.ts +2 -0
  213. package/dist/types/components/Trigger/styles.d.ts +5 -0
  214. package/dist/types/components/UfoErrorBoundary/UfoErrorBoundary.d.ts +16 -0
  215. package/dist/types/components/UfoErrorBoundary/index.d.ts +2 -0
  216. package/dist/types/components/index.d.ts +4 -1
  217. package/dist/types/containers/ConnectedReactionPicker/ConnectedReactionPicker.d.ts +27 -0
  218. package/dist/types/containers/ConnectedReactionPicker/index.d.ts +2 -0
  219. package/dist/types/containers/ConnectedReactionsView/ConnectedReactionsView.d.ts +52 -0
  220. package/dist/types/containers/ConnectedReactionsView/index.d.ts +2 -0
  221. package/dist/types/containers/index.d.ts +2 -2
  222. package/dist/types/hooks/index.d.ts +1 -0
  223. package/dist/types/hooks/useClickAway.d.ts +8 -0
  224. package/dist/types/index.d.ts +2 -2
  225. package/dist/types/shared/constants.d.ts +13 -3
  226. package/dist/types/{components → shared}/i18n.d.ts +0 -0
  227. package/dist/types/shared/index.d.ts +3 -1
  228. package/dist/types/shared/utils.d.ts +11 -0
  229. package/dist/types/store/{ReactionsStore.d.ts → MemoryReactionsStore.d.ts} +21 -61
  230. package/dist/types/store/ReactionConsumer.d.ts +47 -19
  231. package/dist/types/store/index.d.ts +2 -2
  232. package/dist/types/store/utils.d.ts +3 -7
  233. package/dist/types/types/Actions.d.ts +3 -0
  234. package/dist/types/types/User.d.ts +6 -0
  235. package/dist/types/types/client.d.ts +38 -0
  236. package/dist/types/types/index.d.ts +4 -6
  237. package/dist/types/types/reaction.d.ts +82 -0
  238. package/dist/types/types/store.d.ts +63 -0
  239. package/extract-react-type/ConnectedReactionPicker.ts +2 -4
  240. package/extract-react-type/ConnectedReactionsView.ts +3 -5
  241. package/extract-react-type/Reaction.ts +2 -4
  242. package/extract-react-type/Reactions.ts +2 -4
  243. package/extract-react-type/actions.ts +1 -3
  244. package/extract-react-type/reactionClient.ts +3 -5
  245. package/extract-react-type/reactionsStore.ts +3 -5
  246. package/package.json +21 -5
  247. package/dist/cjs/components/EmojiButton.js +0 -100
  248. package/dist/cjs/components/Reaction.js +0 -229
  249. package/dist/cjs/components/ReactionPicker.js +0 -297
  250. package/dist/cjs/components/ReactionTooltip.js +0 -82
  251. package/dist/cjs/components/Reactions.js +0 -194
  252. package/dist/cjs/components/Selector.js +0 -189
  253. package/dist/cjs/components/ShowMore.js +0 -119
  254. package/dist/cjs/components/Trigger.js +0 -58
  255. package/dist/cjs/components/utils.js +0 -28
  256. package/dist/cjs/containers/ConnectedReactionPicker.js +0 -53
  257. package/dist/cjs/containers/ConnectedReactionsView.js +0 -139
  258. package/dist/cjs/types/ReactionSource.js +0 -5
  259. package/dist/cjs/types/ReactionStatus.js +0 -19
  260. package/dist/cjs/types/ReactionSummary.js +0 -5
  261. package/dist/cjs/types/Reactions.js +0 -5
  262. package/dist/cjs/types/ReactionsState.js +0 -5
  263. package/dist/es2019/components/EmojiButton.js +0 -50
  264. package/dist/es2019/components/Reaction.js +0 -183
  265. package/dist/es2019/components/ReactionPicker.js +0 -247
  266. package/dist/es2019/components/ReactionTooltip.js +0 -66
  267. package/dist/es2019/components/Reactions.js +0 -150
  268. package/dist/es2019/components/Selector.js +0 -127
  269. package/dist/es2019/components/ShowMore.js +0 -71
  270. package/dist/es2019/components/utils.js +0 -13
  271. package/dist/es2019/containers/ConnectedReactionPicker.js +0 -36
  272. package/dist/es2019/containers/ConnectedReactionsView.js +0 -118
  273. package/dist/es2019/types/ReactionStatus.js +0 -11
  274. package/dist/es2019/types/Reactions.js +0 -1
  275. package/dist/es2019/types/ReactionsState.js +0 -1
  276. package/dist/esm/client/ReactionClient.js +0 -1
  277. package/dist/esm/components/EmojiButton.js +0 -77
  278. package/dist/esm/components/Reaction.js +0 -207
  279. package/dist/esm/components/ReactionPicker.js +0 -274
  280. package/dist/esm/components/ReactionTooltip.js +0 -63
  281. package/dist/esm/components/Reactions.js +0 -180
  282. package/dist/esm/components/Selector.js +0 -160
  283. package/dist/esm/components/ShowMore.js +0 -95
  284. package/dist/esm/components/utils.js +0 -15
  285. package/dist/esm/containers/ConnectedReactionPicker.js +0 -38
  286. package/dist/esm/containers/ConnectedReactionsView.js +0 -116
  287. package/dist/esm/types/DetailedReaction.js +0 -1
  288. package/dist/esm/types/ReactionSource.js +0 -1
  289. package/dist/esm/types/ReactionStatus.js +0 -11
  290. package/dist/esm/types/ReactionSummary.js +0 -1
  291. package/dist/esm/types/Reactions.js +0 -1
  292. package/dist/esm/types/ReactionsState.js +0 -1
  293. package/dist/types/client/ReactionClient.d.ts +0 -28
  294. package/dist/types/components/EmojiButton.d.ts +0 -21
  295. package/dist/types/components/FlashAnimation.d.ts +0 -18
  296. package/dist/types/components/Reaction.d.ts +0 -44
  297. package/dist/types/components/ReactionTooltip.d.ts +0 -14
  298. package/dist/types/components/Reactions.d.ts +0 -83
  299. package/dist/types/components/Selector.d.ts +0 -39
  300. package/dist/types/components/Trigger.d.ts +0 -16
  301. package/dist/types/components/UfoErrorBoundary.d.ts +0 -9
  302. package/dist/types/components/utils.d.ts +0 -4
  303. package/dist/types/containers/ConnectedReactionPicker.d.ts +0 -16
  304. package/dist/types/containers/ConnectedReactionsView.d.ts +0 -31
  305. package/dist/types/types/DetailedReaction.d.ts +0 -7
  306. package/dist/types/types/ReactionSource.d.ts +0 -4
  307. package/dist/types/types/ReactionStatus.d.ts +0 -9
  308. package/dist/types/types/ReactionSummary.d.ts +0 -10
  309. package/dist/types/types/Reactions.d.ts +0 -4
  310. package/dist/types/types/ReactionsState.d.ts +0 -20
@@ -1,13 +1,7 @@
1
1
  /** @jsx jsx */
2
- import { jsx, css, keyframes } from '@emotion/core';
2
+ import { css, keyframes } from '@emotion/core';
3
3
  import { B75, B300 } from '@atlaskit/theme/colors';
4
4
  import { token } from '@atlaskit/tokens';
5
- import React from 'react';
6
- export const flashAnimationTestId = 'flash-animation';
7
- const containerStyle = css({
8
- width: '100%',
9
- height: '100%'
10
- });
11
5
  const flashTime = 700;
12
6
  export const flashAnimation = keyframes({
13
7
  '0%': {
@@ -26,15 +20,10 @@ export const flashAnimation = keyframes({
26
20
  borderColor: token('color.border.selected', B300)
27
21
  }
28
22
  });
23
+ export const containerStyle = css({
24
+ width: '100%',
25
+ height: '100%'
26
+ });
29
27
  export const flashStyle = css({
30
28
  animation: `${flashAnimation} ${flashTime}ms ease-in-out`
31
- });
32
- /**
33
- * Flash animation background component. See Reaction component for usage.
34
- */
35
-
36
- export const FlashAnimation = props => jsx("div", {
37
- className: props.className,
38
- css: [containerStyle, props.flash && flashStyle],
39
- "data-testid": flashAnimationTestId
40
- }, props.children);
29
+ });
@@ -0,0 +1,104 @@
1
+ /** @jsx jsx */
2
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
3
+ import { jsx } from '@emotion/core';
4
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
5
+ import { ResourcedEmoji } from '@atlaskit/emoji';
6
+ import { Analytics } from '../../analytics';
7
+ import { Counter } from '../Counter';
8
+ import { FlashAnimation } from '../FlashAnimation';
9
+ import { ReactionTooltip } from '../ReactionTooltip';
10
+ import { utils } from '../../shared';
11
+ import * as styles from './styles';
12
+ /**
13
+ * Test id for Reaction item wrapper div
14
+ */
15
+
16
+ export const RENDER_REACTION_TESTID = 'render_reaction_wrapper';
17
+
18
+ /**
19
+ * Render an emoji reaction button
20
+ */
21
+ export const Reaction = ({
22
+ emojiProvider,
23
+ onClick,
24
+ reaction,
25
+ onMouseEnter,
26
+ className,
27
+ flash = false
28
+ }) => {
29
+ const emojiId = {
30
+ id: reaction.emojiId,
31
+ shortName: ''
32
+ };
33
+ const hoverStart = useRef();
34
+ const {
35
+ createAnalyticsEvent
36
+ } = useAnalyticsEvents();
37
+ const [emojiName, setEmojiName] = useState(); // TODO: Extract the flow to a custom hook to retrieve emoji detailed description from an id using a custom hook. This will benefit a better optimization instead of the emojiProvider resolving everytime.
38
+ // Also optimize in future version to fetch in batch several emojiIds
39
+
40
+ useEffect(() => {
41
+ (async () => {
42
+ const emojiResource = await Promise.resolve(emojiProvider);
43
+ const foundEmoji = await emojiResource.findByEmojiId({
44
+ shortName: '',
45
+ id: reaction.emojiId
46
+ });
47
+
48
+ if (foundEmoji) {
49
+ setEmojiName(foundEmoji.name);
50
+ }
51
+ })();
52
+ }, [emojiProvider, reaction.emojiId]);
53
+ const handleMouseUp = useCallback(event => {
54
+ event.preventDefault();
55
+
56
+ if (utils.isLeftClick(event)) {
57
+ const {
58
+ reacted,
59
+ emojiId
60
+ } = reaction;
61
+ Analytics.createAndFireSafe(createAnalyticsEvent, Analytics.createReactionClickedEvent, !reacted, emojiId);
62
+ onClick(reaction.emojiId, event);
63
+ }
64
+ }, [createAnalyticsEvent, reaction, onClick]);
65
+ const handleMouseEnter = useCallback(event => {
66
+ event.preventDefault();
67
+
68
+ if (!reaction.users || !reaction.users.length) {
69
+ hoverStart.current = Date.now();
70
+ }
71
+
72
+ Analytics.createAndFireSafe(createAnalyticsEvent, Analytics.createReactionHoveredEvent, hoverStart.current);
73
+
74
+ if (onMouseEnter) {
75
+ onMouseEnter(reaction, event);
76
+ }
77
+ }, [createAnalyticsEvent, reaction, onMouseEnter]);
78
+ return jsx(ReactionTooltip, {
79
+ emojiName: emojiName,
80
+ reaction: reaction
81
+ }, jsx("button", {
82
+ className: className,
83
+ css: [styles.reactionStyle, reaction.reacted && styles.reactedStyle],
84
+ title: reaction.emojiId,
85
+ type: "button",
86
+ "data-testid": RENDER_REACTION_TESTID,
87
+ onMouseUp: handleMouseUp,
88
+ onMouseEnter: handleMouseEnter
89
+ }, jsx(FlashAnimation, {
90
+ flash: flash,
91
+ css: styles.flashStyle
92
+ }, jsx("div", {
93
+ css: [styles.emojiStyle, reaction.count === 0 && {
94
+ padding: '4px 2px 4px 10px'
95
+ }]
96
+ }, jsx(ResourcedEmoji, {
97
+ emojiProvider: emojiProvider,
98
+ emojiId: emojiId,
99
+ fitToHeight: 16
100
+ })), jsx(Counter, {
101
+ value: reaction.count,
102
+ highlight: reaction.reacted
103
+ }))));
104
+ };
@@ -0,0 +1 @@
1
+ export { Reaction, RENDER_REACTION_TESTID } from './Reaction';
@@ -0,0 +1,55 @@
1
+ /** @jsx jsx */
2
+ import { css } from '@emotion/core';
3
+ import { B50, B75, B300, N20, N40, N400 } from '@atlaskit/theme/colors';
4
+ import { token } from '@atlaskit/tokens';
5
+ /**
6
+ * Default styling px height for an emoji reaction
7
+ */
8
+
9
+ const akHeight = 24;
10
+ /**
11
+ * Styling Note:
12
+ * Padding and line height are set within the child components
13
+ * of FlashAnimation b/c it otherwise throws off the flash styling
14
+ */
15
+
16
+ export const emojiStyle = css({
17
+ transformOrigin: 'center center 0',
18
+ lineHeight: '12px',
19
+ padding: '4px 4px 4px 8px'
20
+ });
21
+ export const reactionStyle = css({
22
+ outline: 'none',
23
+ display: 'flex',
24
+ flexDirection: 'row',
25
+ alignItems: 'flex-start',
26
+ minWidth: '36px',
27
+ height: `${akHeight}px`,
28
+ background: 'transparent',
29
+ border: `1px solid ${token('color.border', N40)}`,
30
+ boxSizing: 'border-box',
31
+ borderRadius: '20px',
32
+ color: `${token('color.text.subtle', N400)}`,
33
+ cursor: 'pointer',
34
+ margin: 0,
35
+ padding: 0,
36
+ transition: '200ms ease-in-out',
37
+ '&:hover': {
38
+ background: `${token('color.background.neutral.subtle.hovered', N20)}`
39
+ }
40
+ });
41
+ export const reactedStyle = css({
42
+ backgroundColor: token('color.background.selected', B50),
43
+ borderColor: token('color.border.selected', B300),
44
+ '&:hover': {
45
+ background: `${token('color.background.selected.hovered', B75)}`
46
+ }
47
+ });
48
+ export const flashHeight = akHeight - 2; // height without the 1px border
49
+
50
+ export const flashStyle = css({
51
+ display: 'flex',
52
+ flexDirection: 'row',
53
+ borderRadius: '10px',
54
+ height: `${flashHeight}px`
55
+ });
@@ -0,0 +1,208 @@
1
+ /** @jsx jsx */
2
+ import React, { Fragment, useCallback, useRef, useState } from 'react';
3
+ import { jsx } from '@emotion/core';
4
+ import { EmojiPicker } from '@atlaskit/emoji/picker';
5
+ import { Manager, Popper, Reference } from '@atlaskit/popper';
6
+ import { layers } from '@atlaskit/theme/constants';
7
+ import { Selector } from '../Selector';
8
+ import { Trigger } from '../Trigger';
9
+ import { UFO } from '../../analytics';
10
+ import { useClickAway } from '../../hooks';
11
+ import * as styles from './styles';
12
+ /**
13
+ * Test id for wrapper ReactionPicker div
14
+ */
15
+
16
+ export const RENDER_REACTIONPICKER_TESTID = 'reactionPicker-testid';
17
+ const popperModifiers = [
18
+ /**
19
+ Removing this applyStyle modifier as it throws client errors ref:
20
+ https://popper.js.org/docs/v1/#modifiers
21
+ https://popper.js.org/docs/v1/#modifiers..applyStyle
22
+ { name: 'applyStyle', enabled: false },
23
+ */
24
+ {
25
+ name: 'hide',
26
+ enabled: false
27
+ }, {
28
+ name: 'offset',
29
+ enabled: true,
30
+ options: {
31
+ offset: [0, 0]
32
+ }
33
+ }, {
34
+ name: 'flip',
35
+ enabled: true,
36
+ options: {
37
+ flipVariations: true,
38
+ boundariesElement: 'scrollParent'
39
+ }
40
+ }, {
41
+ name: 'preventOverflow',
42
+ enabled: true
43
+ }];
44
+
45
+ /**
46
+ * Picker component for adding reactions
47
+ */
48
+ export const ReactionPicker = /*#__PURE__*/React.memo(props => {
49
+ const {
50
+ miniMode,
51
+ className,
52
+ emojiProvider,
53
+ onSelection,
54
+ allowAllEmojis,
55
+ disabled,
56
+ pickerQuickReactionEmojiIds,
57
+ onShowMore,
58
+ onOpen,
59
+ onCancel
60
+ } = props;
61
+ /**
62
+ * Container <div /> reference (used by custom hook to detect click outside)
63
+ */
64
+
65
+ const wrapperRef = useRef(null);
66
+ /**
67
+ * a function you can ask Popper to recompute your tooltip's position. It will directly call the Popper#update method
68
+ */
69
+
70
+ const updatePopper = useRef(() => Promise.resolve());
71
+ const [settings, setSettings] = useState({
72
+ /**
73
+ * Show the picker floating panel
74
+ */
75
+ isOpen: false,
76
+
77
+ /**
78
+ * Show the full custom emoji list picker or the default list of emojis
79
+ */
80
+ showFullPicker: !!allowAllEmojis && Array.isArray(pickerQuickReactionEmojiIds) && pickerQuickReactionEmojiIds.length === 0
81
+ });
82
+ /**
83
+ * Custom hook triggers when user clicks outside the reactions picker
84
+ */
85
+
86
+ useClickAway(wrapperRef, () => {
87
+ if (onCancel) {
88
+ onCancel();
89
+ }
90
+
91
+ close();
92
+ });
93
+ /**
94
+ * Event callback when the picker is closed
95
+ * @param _id Optional id if an emoji button was selected or undefineed if was clicked outside the picker
96
+ */
97
+
98
+ const close = useCallback(_id => {
99
+ setSettings({
100
+ isOpen: false,
101
+ showFullPicker: !!allowAllEmojis && Array.isArray(pickerQuickReactionEmojiIds) && pickerQuickReactionEmojiIds.length === 0
102
+ }); // ufo abort reaction experience
103
+
104
+ UFO.PickerRender.abort({
105
+ metadata: {
106
+ emojiId: _id,
107
+ source: 'Reaction-Picker',
108
+ reason: 'close dialog'
109
+ }
110
+ });
111
+ }, [allowAllEmojis, pickerQuickReactionEmojiIds]);
112
+ /**
113
+ * Event handle rwhen selecting to show the custom emoji icons picker
114
+ * @param e event param
115
+ */
116
+
117
+ const onSelectMoreClick = useCallback(async e => {
118
+ e.preventDefault();
119
+ await updatePopper.current(); // Update popper position
120
+
121
+ setSettings({
122
+ isOpen: true,
123
+ showFullPicker: true
124
+ });
125
+
126
+ if (onShowMore) {
127
+ onShowMore();
128
+ }
129
+ }, [onShowMore]);
130
+ /**
131
+ * Event callback when an emoji icon is selected
132
+ * @param item selected item
133
+ */
134
+
135
+ const onEmojiSelected = useCallback(item => {
136
+ // no emoji was selected
137
+ if (!item.id) {
138
+ return;
139
+ }
140
+
141
+ onSelection(item.id, settings.showFullPicker ? 'emojiPicker' : 'quickSelector');
142
+ close(item.id);
143
+ }, [close, onSelection, settings.showFullPicker]);
144
+ /**
145
+ * Event handler when the emoji icon to open the custom picker is selected
146
+ */
147
+
148
+ const onTriggerClick = () => {
149
+ // ufo start reactions picker open experience
150
+ UFO.PickerRender.start();
151
+ setSettings({
152
+ isOpen: !settings.isOpen,
153
+ showFullPicker: !!allowAllEmojis && Array.isArray(pickerQuickReactionEmojiIds) && pickerQuickReactionEmojiIds.length === 0
154
+ });
155
+
156
+ if (onOpen) {
157
+ onOpen();
158
+ } // ufo reactions picker opened success
159
+
160
+
161
+ UFO.PickerRender.success();
162
+ };
163
+
164
+ const wrapperClassName = ` ${settings.isOpen ? 'isOpen' : ''} ${miniMode ? 'miniMode' : ''} ${className}`;
165
+ return jsx("div", {
166
+ className: wrapperClassName,
167
+ css: styles.pickerStyle,
168
+ ref: wrapperRef,
169
+ "data-testid": RENDER_REACTIONPICKER_TESTID
170
+ }, jsx(Manager, null, jsx(Reference, null, ({
171
+ ref: popperRef
172
+ }) => // Render a button to open the <Selector /> panel
173
+ jsx(Trigger, {
174
+ ref: popperRef,
175
+ onClick: onTriggerClick,
176
+ miniMode: miniMode,
177
+ disabled: disabled
178
+ })), jsx(Popper, {
179
+ placement: "bottom-start",
180
+ modifiers: popperModifiers
181
+ }, ({
182
+ ref,
183
+ style,
184
+ update
185
+ }) => {
186
+ updatePopper.current = update;
187
+ return jsx(Fragment, null, settings.isOpen && jsx("div", {
188
+ style: {
189
+ zIndex: layers.layer(),
190
+ ...style
191
+ },
192
+ ref: ref
193
+ }, jsx("div", {
194
+ css: styles.popupStyle
195
+ }, settings.showFullPicker ? jsx(EmojiPicker, {
196
+ emojiProvider: emojiProvider,
197
+ onSelection: onEmojiSelected
198
+ }) : jsx("div", {
199
+ css: styles.contentStyle
200
+ }, jsx(Selector, {
201
+ emojiProvider: emojiProvider,
202
+ onSelection: onEmojiSelected,
203
+ showMore: allowAllEmojis,
204
+ onMoreClick: onSelectMoreClick,
205
+ pickerQuickReactionEmojiIds: pickerQuickReactionEmojiIds
206
+ })))));
207
+ })));
208
+ });
@@ -0,0 +1 @@
1
+ export { ReactionPicker, RENDER_REACTIONPICKER_TESTID } from './ReactionPicker';
@@ -0,0 +1,23 @@
1
+ /** @jsx jsx */
2
+ import { css } from '@emotion/core';
3
+ import { borderRadius } from '@atlaskit/theme/constants';
4
+ import { N0, N50A, N60A } from '@atlaskit/theme/colors';
5
+ import { token } from '@atlaskit/tokens';
6
+ export const pickerStyle = css({
7
+ verticalAlign: 'middle',
8
+ '&.miniMode': {
9
+ display: 'inline-block',
10
+ marginRight: '4px'
11
+ }
12
+ });
13
+ export const contentStyle = css({
14
+ display: 'flex'
15
+ });
16
+ export const popupStyle = css({
17
+ background: token('elevation.surface.overlay', N0),
18
+ borderRadius: `${borderRadius()}px`,
19
+ boxShadow: token('elevation.shadow.overlay', `0 4px 8px -2px ${N50A}, 0 0 1px ${N60A}`),
20
+ '&> div': {
21
+ boxShadow: undefined
22
+ }
23
+ });
@@ -0,0 +1,46 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+
3
+ /** @jsx jsx */
4
+ import React from 'react';
5
+ import { jsx } from '@emotion/core';
6
+ import Tooltip from '@atlaskit/tooltip';
7
+ import { FormattedMessage } from 'react-intl-next';
8
+ import { constants, i18n } from '../../shared';
9
+ import * as styles from './styles';
10
+ /**
11
+ * Test id for wrapper ReactionTooltip div
12
+ */
13
+
14
+ export const RENDER_REACTIONTOOLTIP_TESTID = 'render-reactionTooltip';
15
+ export const ReactionTooltip = ({
16
+ emojiName,
17
+ children,
18
+ maxReactions = constants.TOOLTIP_USERS_LIMIT,
19
+ reaction: {
20
+ users = []
21
+ }
22
+ }) => {
23
+ /**
24
+ * Render list of users in the tooltip box
25
+ */
26
+ const content = !users || users.length === 0 ? null : jsx("div", {
27
+ css: styles.tooltipStyle
28
+ }, jsx("ul", null, emojiName ? jsx("li", {
29
+ css: styles.emojiNameStyle
30
+ }, emojiName) : null, users.slice(0, maxReactions).map((user, index) => {
31
+ return jsx("li", {
32
+ key: index
33
+ }, user.displayName);
34
+ }), users.length > maxReactions ? jsx("li", {
35
+ css: styles.footerStyle
36
+ }, jsx(FormattedMessage, _extends({}, i18n.messages.otherUsers, {
37
+ values: {
38
+ count: users.length - maxReactions
39
+ }
40
+ }))) : null));
41
+ return jsx(Tooltip, {
42
+ content: content,
43
+ position: "bottom",
44
+ "data-testid": RENDER_REACTIONTOOLTIP_TESTID
45
+ }, React.Children.only(children));
46
+ };
@@ -0,0 +1 @@
1
+ export { ReactionTooltip, RENDER_REACTIONTOOLTIP_TESTID } from './ReactionTooltip';
@@ -0,0 +1,32 @@
1
+ /** @jsx jsx */
2
+ import { css } from '@emotion/core';
3
+ import { token } from '@atlaskit/tokens';
4
+ import { N90 } from '@atlaskit/theme/colors';
5
+ export const verticalMargin = 5;
6
+ export const tooltipStyle = css({
7
+ maxWidth: '150px',
8
+ textOverflow: 'ellipsis',
9
+ whiteSpace: 'nowrap',
10
+ overflow: 'hidden',
11
+ marginBottom: verticalMargin,
12
+ ul: {
13
+ listStyle: 'none',
14
+ margin: 0,
15
+ padding: 0,
16
+ textAlign: 'left'
17
+ },
18
+ li: {
19
+ overflow: 'hidden',
20
+ textOverflow: 'ellipsis',
21
+ marginTop: verticalMargin
22
+ }
23
+ });
24
+ export const emojiNameStyle = css({
25
+ textTransform: 'capitalize',
26
+ color: token('color.text.inverse', N90),
27
+ fontWeight: 600
28
+ });
29
+ export const footerStyle = css({
30
+ color: token('color.text.inverse', N90),
31
+ fontWeight: 300
32
+ });
@@ -0,0 +1,156 @@
1
+ /** @jsx jsx */
2
+ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
3
+ import { jsx } from '@emotion/core';
4
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
5
+ import Tooltip from '@atlaskit/tooltip';
6
+ import { FormattedMessage } from 'react-intl-next';
7
+ import { Analytics } from '../../analytics';
8
+ import { ReactionStatus } from '../../types';
9
+ import { i18n } from '../../shared';
10
+ import { Reaction } from '../Reaction';
11
+ import { ReactionPicker } from '../ReactionPicker';
12
+ import * as styles from './styles';
13
+
14
+ /**
15
+ * Test id for wrapper Reactions div
16
+ */
17
+ export const RENDER_REACTIONS_TESTID = 'render-reactions';
18
+ /**
19
+ * Test id for the tooltip
20
+ */
21
+
22
+ export const RENDER_TOOLTIP_TESTID = 'render-tooltip';
23
+
24
+ /**
25
+ * Renders list of reactions
26
+ */
27
+ export const Reactions = /*#__PURE__*/React.memo(({
28
+ flash = {},
29
+ status,
30
+ errorMessage,
31
+ loadReaction,
32
+ quickReactionEmojiIds,
33
+ containerAri,
34
+ ari,
35
+ pickerQuickReactionEmojiIds,
36
+ onReactionHover,
37
+ onSelection,
38
+ reactions = [],
39
+ emojiProvider,
40
+ allowAllEmojis,
41
+ onReactionClick
42
+ }) => {
43
+ const {
44
+ createAnalyticsEvent
45
+ } = useAnalyticsEvents();
46
+ let openTime = useRef();
47
+ let renderTime = useRef();
48
+
49
+ if (status !== ReactionStatus.ready) {
50
+ renderTime.current = Date.now();
51
+ }
52
+
53
+ useEffect(() => {
54
+ if (status === ReactionStatus.notLoaded) {
55
+ loadReaction();
56
+ }
57
+ }, [status, loadReaction]);
58
+ useEffect(() => {
59
+ if (status === ReactionStatus.ready && renderTime.current) {
60
+ Analytics.createAndFireSafe(createAnalyticsEvent, Analytics.createReactionsRenderedEvent, renderTime.current);
61
+ renderTime.current = undefined;
62
+ }
63
+ }, [createAnalyticsEvent, status]);
64
+ /**
65
+ * Get content of the tooltip
66
+ */
67
+
68
+ const getTooltip = () => {
69
+ switch (status) {
70
+ case ReactionStatus.error:
71
+ return errorMessage || jsx(FormattedMessage, i18n.messages.unexpectedError);
72
+
73
+ case ReactionStatus.loading:
74
+ case ReactionStatus.notLoaded:
75
+ return jsx(FormattedMessage, i18n.messages.loadingReactions);
76
+
77
+ default:
78
+ return undefined;
79
+ }
80
+ };
81
+
82
+ const handleReactionMouseEnter = summary => {
83
+ if (onReactionHover) {
84
+ onReactionHover(summary.emojiId);
85
+ }
86
+ };
87
+
88
+ const handlePickerOpen = useCallback(() => {
89
+ openTime.current = Date.now();
90
+ Analytics.createAndFireSafe(createAnalyticsEvent, Analytics.createPickerButtonClickedEvent, reactions.length);
91
+ }, [createAnalyticsEvent, reactions]);
92
+ const handleOnCancel = useCallback(() => {
93
+ Analytics.createAndFireSafe(createAnalyticsEvent, Analytics.createPickerCancelledEvent, openTime.current);
94
+ openTime.current = undefined;
95
+ }, [createAnalyticsEvent]);
96
+ const handleOnMore = useCallback(() => {
97
+ Analytics.createAndFireSafe(createAnalyticsEvent, Analytics.createPickerMoreClickedEvent, openTime.current);
98
+ }, [createAnalyticsEvent]);
99
+ const handleOnSelection = useCallback((emojiId, source) => {
100
+ Analytics.createAndFireSafe(createAnalyticsEvent, Analytics.createReactionSelectionEvent, source, emojiId, reactions.find(reaction => reaction.emojiId === emojiId), openTime.current);
101
+ openTime.current = undefined;
102
+ onSelection(emojiId);
103
+ }, [createAnalyticsEvent, onSelection, reactions]);
104
+ /**
105
+ * 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
106
+ */
107
+
108
+ const memorizedReactions = useMemo(() => {
109
+ //
110
+
111
+ /**
112
+ * If reactions not empty, don't show quick reactions Pre defined emoji or if its empty => return the current list of reactions
113
+ */
114
+ if (reactions.length > 0 || !quickReactionEmojiIds) {
115
+ return reactions;
116
+ } // add any missing default reactions
117
+
118
+
119
+ const items = quickReactionEmojiIds.filter(emojiId => !reactions.some(reaction => reaction.emojiId === emojiId)).map(emojiId => {
120
+ return {
121
+ ari,
122
+ containerAri,
123
+ emojiId,
124
+ count: 0,
125
+ reacted: false
126
+ };
127
+ });
128
+ return reactions.concat(items);
129
+ }, [ari, containerAri, quickReactionEmojiIds, reactions]);
130
+ return jsx("div", {
131
+ css: styles.wrapperStyle,
132
+ "data-testid": RENDER_REACTIONS_TESTID
133
+ }, memorizedReactions.map(reaction => jsx(Reaction, {
134
+ key: reaction.emojiId,
135
+ css: styles.reactionStyle,
136
+ reaction: reaction,
137
+ emojiProvider: emojiProvider,
138
+ onClick: onReactionClick,
139
+ onMouseEnter: handleReactionMouseEnter,
140
+ flash: flash[reaction.emojiId]
141
+ })), jsx(Tooltip, {
142
+ testId: RENDER_TOOLTIP_TESTID,
143
+ content: getTooltip()
144
+ }, jsx(ReactionPicker, {
145
+ css: styles.reactionStyle,
146
+ emojiProvider: emojiProvider,
147
+ miniMode: true,
148
+ allowAllEmojis: allowAllEmojis,
149
+ pickerQuickReactionEmojiIds: pickerQuickReactionEmojiIds,
150
+ disabled: status !== ReactionStatus.ready,
151
+ onSelection: handleOnSelection,
152
+ onOpen: handlePickerOpen,
153
+ onCancel: handleOnCancel,
154
+ onShowMore: handleOnMore
155
+ })));
156
+ });
@@ -0,0 +1 @@
1
+ export { Reactions, RENDER_REACTIONS_TESTID, RENDER_TOOLTIP_TESTID } from './Reactions';
@@ -0,0 +1,19 @@
1
+ /** @jsx jsx */
2
+ import { css } from '@emotion/core';
3
+ export const reactionStyle = css({
4
+ display: 'inline-block',
5
+ // top margin of 2px to allow spacing between rows when wrapped (paired with top margin in reactionsStyle)
6
+ margin: '2px 4px 0 4px'
7
+ });
8
+ export const wrapperStyle = css({
9
+ display: 'flex',
10
+ flexWrap: 'wrap',
11
+ position: 'relative',
12
+ alignItems: 'center',
13
+ borderRadius: '15px',
14
+ // To allow to row spacing of 2px on wrap, and 0px on first row
15
+ marginTop: '-2px',
16
+ '> :first-of-type > :first-child': {
17
+ marginLeft: 0
18
+ }
19
+ });