@orioro/react-reactions 0.0.1

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/dist/index.mjs ADDED
@@ -0,0 +1,961 @@
1
+ import React, { useState, useEffect, useMemo, useCallback, forwardRef, useImperativeHandle, createContext, useContext } from 'react';
2
+ import { Popover, IconButton, Tooltip, Avatar, Text, Spinner, Tabs } from '@radix-ui/themes';
3
+ import EmojiMartPicker from '@emoji-mart/react';
4
+ import PT_BR from '@emoji-mart/data/i18n/pt.json';
5
+ import { Icon } from '@mdi/react';
6
+ import { mdiEmoticonHappyOutline, mdiClose } from '@mdi/js';
7
+ import { Flex, DotDotDot, Box, Button } from '@orioro/react-ui-core';
8
+ import styled from 'styled-components';
9
+ import { AnimatePresence, motion } from 'framer-motion';
10
+ import { usePrevious, usePreviousDistinct } from 'react-use';
11
+
12
+ var DEFAULT_SIZE = 18;
13
+
14
+ function EmojiPicker(_a) {
15
+ var _b = _a.i18n,
16
+ i18n = _b === void 0 ? PT_BR : _b,
17
+ data = _a.data,
18
+ open = _a.open,
19
+ onSetOpen = _a.onSetOpen,
20
+ _onEmojiSelect = _a.onEmojiSelect,
21
+ trigger = _a.trigger,
22
+ _c = _a.size,
23
+ size = _c === void 0 ? DEFAULT_SIZE : _c;
24
+ var _d = useState(open),
25
+ localOpen = _d[0],
26
+ setLocalOpen = _d[1];
27
+ useEffect(function () {
28
+ if (localOpen !== open && typeof onSetOpen === 'function') {
29
+ onSetOpen(localOpen);
30
+ }
31
+ }, [localOpen, onSetOpen]);
32
+ return /*#__PURE__*/React.createElement(Popover.Root, {
33
+ open: localOpen,
34
+ onOpenChange: setLocalOpen
35
+ }, /*#__PURE__*/React.createElement(Popover.Trigger, null, trigger ? trigger : ( /*#__PURE__*/React.createElement(IconButton, {
36
+ radius: "full",
37
+ variant: "ghost",
38
+ size: "1",
39
+ onClick: function onClick() {
40
+ return setLocalOpen(true);
41
+ }
42
+ }, /*#__PURE__*/React.createElement(Tooltip, {
43
+ content: "Adicionar rea\xE7\xE3o",
44
+ delayDuration: 1000
45
+ }, /*#__PURE__*/React.createElement(Icon, {
46
+ path: mdiEmoticonHappyOutline,
47
+ size: "".concat(1.15 * size, "px")
48
+ }))))), /*#__PURE__*/React.createElement(Popover.Content, {
49
+ style: {
50
+ padding: 0,
51
+ minWidth: 350
52
+ },
53
+ sideOffset: -24 - 4
54
+ }, /*#__PURE__*/React.createElement(EmojiMartPicker, {
55
+ data: data,
56
+ onEmojiSelect: function onEmojiSelect(emoji) {
57
+ setLocalOpen(false);
58
+ _onEmojiSelect(emoji);
59
+ },
60
+ i18n: i18n,
61
+ autofocus: true,
62
+ skinTonePosition: "none",
63
+ previewPosition: "none"
64
+ })));
65
+ }
66
+
67
+ function _typeof(o) {
68
+ "@babel/helpers - typeof";
69
+
70
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
71
+ return typeof o;
72
+ } : function (o) {
73
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
74
+ }, _typeof(o);
75
+ }
76
+
77
+ var _assign = function __assign() {
78
+ _assign = Object.assign || function __assign(t) {
79
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
80
+ s = arguments[i];
81
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
82
+ }
83
+ return t;
84
+ };
85
+ return _assign.apply(this, arguments);
86
+ };
87
+ function __awaiter(thisArg, _arguments, P, generator) {
88
+ function adopt(value) {
89
+ return value instanceof P ? value : new P(function (resolve) {
90
+ resolve(value);
91
+ });
92
+ }
93
+ return new (P || (P = Promise))(function (resolve, reject) {
94
+ function fulfilled(value) {
95
+ try {
96
+ step(generator.next(value));
97
+ } catch (e) {
98
+ reject(e);
99
+ }
100
+ }
101
+ function rejected(value) {
102
+ try {
103
+ step(generator["throw"](value));
104
+ } catch (e) {
105
+ reject(e);
106
+ }
107
+ }
108
+ function step(result) {
109
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
110
+ }
111
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
112
+ });
113
+ }
114
+ function __generator(thisArg, body) {
115
+ var _ = {
116
+ label: 0,
117
+ sent: function sent() {
118
+ if (t[0] & 1) throw t[1];
119
+ return t[1];
120
+ },
121
+ trys: [],
122
+ ops: []
123
+ },
124
+ f,
125
+ y,
126
+ t,
127
+ g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
128
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function () {
129
+ return this;
130
+ }), g;
131
+ function verb(n) {
132
+ return function (v) {
133
+ return step([n, v]);
134
+ };
135
+ }
136
+ function step(op) {
137
+ if (f) throw new TypeError("Generator is already executing.");
138
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
139
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
140
+ if (y = 0, t) op = [op[0] & 2, t.value];
141
+ switch (op[0]) {
142
+ case 0:
143
+ case 1:
144
+ t = op;
145
+ break;
146
+ case 4:
147
+ _.label++;
148
+ return {
149
+ value: op[1],
150
+ done: false
151
+ };
152
+ case 5:
153
+ _.label++;
154
+ y = op[1];
155
+ op = [0];
156
+ continue;
157
+ case 7:
158
+ op = _.ops.pop();
159
+ _.trys.pop();
160
+ continue;
161
+ default:
162
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
163
+ _ = 0;
164
+ continue;
165
+ }
166
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
167
+ _.label = op[1];
168
+ break;
169
+ }
170
+ if (op[0] === 6 && _.label < t[1]) {
171
+ _.label = t[1];
172
+ t = op;
173
+ break;
174
+ }
175
+ if (t && _.label < t[2]) {
176
+ _.label = t[2];
177
+ _.ops.push(op);
178
+ break;
179
+ }
180
+ if (t[2]) _.ops.pop();
181
+ _.trys.pop();
182
+ continue;
183
+ }
184
+ op = body.call(thisArg, _);
185
+ } catch (e) {
186
+ op = [6, e];
187
+ y = 0;
188
+ } finally {
189
+ f = t = 0;
190
+ }
191
+ if (op[0] & 5) throw op[1];
192
+ return {
193
+ value: op[0] ? op[1] : void 0,
194
+ done: true
195
+ };
196
+ }
197
+ }
198
+ function __spreadArray(to, from, pack) {
199
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
200
+ if (ar || !(i in from)) {
201
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
202
+ ar[i] = from[i];
203
+ }
204
+ }
205
+ return to.concat(ar || Array.prototype.slice.call(from));
206
+ }
207
+ function __makeTemplateObject(cooked, raw) {
208
+ if (Object.defineProperty) {
209
+ Object.defineProperty(cooked, "raw", {
210
+ value: raw
211
+ });
212
+ } else {
213
+ cooked.raw = raw;
214
+ }
215
+ return cooked;
216
+ }
217
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
218
+ var e = new Error(message);
219
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
220
+ };
221
+
222
+ var Btn = styled.button(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0;\n text-align: left;\n"], ["\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0;\n text-align: left;\n"])));
223
+ function ReactionCard(_a) {
224
+ var reaction = _a.reaction,
225
+ onRemoveReaction = _a.onRemoveReaction,
226
+ onViewReaction = _a.onViewReaction,
227
+ authedUserId = _a.authedUserId;
228
+ var isAuthedUserReaction = useMemo(function () {
229
+ return reaction.user.id === authedUserId;
230
+ }, [reaction, authedUserId]);
231
+ var onClick = useMemo(function () {
232
+ return reaction.isPersisting ? undefined : isAuthedUserReaction ? typeof onRemoveReaction === 'function' ? function () {
233
+ return onRemoveReaction(reaction.id);
234
+ } : typeof onViewReaction === 'function' ? function () {
235
+ return onViewReaction(reaction.id);
236
+ } : undefined : typeof onViewReaction === 'function' ? function () {
237
+ return onViewReaction(reaction.id);
238
+ } : undefined;
239
+ }, [isAuthedUserReaction, onRemoveReaction, onViewReaction, reaction]);
240
+ return /*#__PURE__*/React.createElement(Btn, {
241
+ type: "button",
242
+ onClick: onClick
243
+ }, /*#__PURE__*/React.createElement(Flex, {
244
+ direction: "row",
245
+ gap: "3",
246
+ alignItems: "center"
247
+ }, /*#__PURE__*/React.createElement(Avatar, {
248
+ src: reaction.user.pictureUrl,
249
+ fallback: reaction.user.name ? reaction.user.name.split(/\s+/).slice(0, 2).map(function (part) {
250
+ return part.substring(0, 1);
251
+ }).join('').toUpperCase() : '',
252
+ radius: "full"
253
+ }), /*#__PURE__*/React.createElement(Flex, {
254
+ direction: "column",
255
+ gap: "0",
256
+ flexGrow: "1"
257
+ }, isAuthedUserReaction && typeof onRemoveReaction === 'function' ? ( /*#__PURE__*/React.createElement(Flex, {
258
+ direction: "row",
259
+ gap: "3",
260
+ alignItems: "center"
261
+ }, /*#__PURE__*/React.createElement(Flex, {
262
+ direction: "column",
263
+ gap: "0",
264
+ flexGrow: "1"
265
+ }, /*#__PURE__*/React.createElement(Text, {
266
+ weight: "bold",
267
+ size: "2"
268
+ }, reaction.user.name ? "".concat(reaction.user.name, " (voc\xEA)") : 'Você'), reaction.isPersisting ? ( /*#__PURE__*/React.createElement(Text, {
269
+ size: "1",
270
+ color: "gray"
271
+ }, /*#__PURE__*/React.createElement(DotDotDot, null, "Salvando"))) : ( /*#__PURE__*/React.createElement(Text, {
272
+ size: "1",
273
+ color: "gray"
274
+ }, "Clique para remover"))), reaction.isPersisting ? ( /*#__PURE__*/React.createElement(Spinner, null)) : ( /*#__PURE__*/React.createElement(Icon, {
275
+ path: mdiClose,
276
+ size: "1rem"
277
+ })))) : ( /*#__PURE__*/React.createElement(React.Fragment, null, reaction.user.name && ( /*#__PURE__*/React.createElement(Text, {
278
+ weight: "bold",
279
+ size: "2",
280
+ style: {
281
+ display: '-webkit-box',
282
+ lineClamp: 1,
283
+ WebkitLineClamp: 1,
284
+ WebkitBoxOrient: 'vertical',
285
+ overflow: 'hidden',
286
+ textOverflow: 'ellipsis'
287
+ }
288
+ }, reaction.user.name)), reaction.user.description && ( /*#__PURE__*/React.createElement(Text, {
289
+ size: "1",
290
+ color: "gray",
291
+ style: {
292
+ display: '-webkit-box',
293
+ lineClamp: 2,
294
+ WebkitLineClamp: 2,
295
+ WebkitBoxOrient: 'vertical',
296
+ overflow: 'hidden',
297
+ textOverflow: 'ellipsis'
298
+ }
299
+ }, reaction.user.description))))), /*#__PURE__*/React.createElement(Flex, {
300
+ style: {
301
+ marginLeft: 20
302
+ },
303
+ flexShrink: "0",
304
+ direction: "row",
305
+ gap: "1"
306
+ }, /*#__PURE__*/React.createElement("em-emoji", {
307
+ size: "1.5em",
308
+ key: reaction.emoji.id,
309
+ id: reaction.emoji.id
310
+ }))));
311
+ }
312
+ var templateObject_1;
313
+
314
+ function arrayGroupBy(array, iteratee) {
315
+ return array.reduce(function (result, item) {
316
+ var key = iteratee(item);
317
+ if (!result[key]) {
318
+ result[key] = [];
319
+ }
320
+ result[key].push(item);
321
+ return result;
322
+ }, {});
323
+ }
324
+
325
+ function hashReactionSet(reactions) {
326
+ return reactions.sort(function (rA, rB) {
327
+ return rA.user.id < rB.user.id ? -1 : 1;
328
+ }).reduce(function (acc, reaction) {
329
+ return "".concat(acc, "|").concat(reaction.user.id).concat(reaction.emoji.id);
330
+ }, '');
331
+ }
332
+ function areReactionSetsEqual(setA, setB) {
333
+ return hashReactionSet(setA) === hashReactionSet(setB);
334
+ }
335
+
336
+ function ReactionGroupTabs(_a) {
337
+ var reactions = _a.reactions,
338
+ _b = _a.authedUserId,
339
+ authedUserId = _b === void 0 ? null : _b,
340
+ onViewReaction = _a.onViewReaction,
341
+ onRemoveReaction = _a.onRemoveReaction;
342
+ var sortedReactions = useMemo(function () {
343
+ return authedUserId ? reactions.reduce(function (acc, reaction) {
344
+ return reaction.user.id === authedUserId ? __spreadArray([reaction], acc, true) : __spreadArray(__spreadArray([], acc, true), [reaction], false);
345
+ }, []) : reactions;
346
+ }, [reactions, authedUserId]);
347
+ var groups = useMemo(function () {
348
+ return Object.entries(arrayGroupBy(sortedReactions, function (reaction) {
349
+ return reaction.emoji.id;
350
+ })).map(function (_a) {
351
+ var emojiId = _a[0],
352
+ reactions = _a[1];
353
+ return {
354
+ emojiId: emojiId,
355
+ reactions: reactions
356
+ };
357
+ }).sort(function (gA, gB) {
358
+ return gB.reactions.length - gA.reactions.length;
359
+ });
360
+ }, [sortedReactions]);
361
+ return /*#__PURE__*/React.createElement(Tabs.Root, {
362
+ defaultValue: "_all"
363
+ }, /*#__PURE__*/React.createElement(Tabs.List, {
364
+ size: groups.length > 8 ? '1' : '2',
365
+ //
366
+ // Prevent clicking on tabs from propagating (closing popover)
367
+ //
368
+ onClick: function onClick(e) {
369
+ return e.stopPropagation();
370
+ }
371
+ }, /*#__PURE__*/React.createElement(Tabs.Trigger, {
372
+ value: "_all"
373
+ }, "Todas ", reactions.length), groups.map(function (group) {
374
+ return /*#__PURE__*/React.createElement(Tabs.Trigger, {
375
+ key: group.emojiId,
376
+ value: "emoji_".concat(group.emojiId)
377
+ }, /*#__PURE__*/React.createElement(Flex, {
378
+ direction: "row",
379
+ alignItems: "center",
380
+ gap: "2"
381
+ }, /*#__PURE__*/React.createElement("em-emoji", {
382
+ size: "1.25em",
383
+ id: group.emojiId
384
+ }), /*#__PURE__*/React.createElement("span", null, group.reactions.length)));
385
+ })), /*#__PURE__*/React.createElement(Box, {
386
+ p: "3"
387
+ }, /*#__PURE__*/React.createElement(Tabs.Content, {
388
+ value: "_all"
389
+ }, /*#__PURE__*/React.createElement(Flex, {
390
+ direction: "column",
391
+ gap: "3"
392
+ }, sortedReactions.map(function (reaction, index) {
393
+ return /*#__PURE__*/React.createElement(ReactionCard, {
394
+ key: reaction.id || index,
395
+ reaction: reaction,
396
+ onViewReaction: onViewReaction,
397
+ onRemoveReaction: onRemoveReaction,
398
+ authedUserId: authedUserId
399
+ });
400
+ }))), groups.map(function (group) {
401
+ return /*#__PURE__*/React.createElement(Tabs.Content, {
402
+ key: group.emojiId,
403
+ value: "emoji_".concat(group.emojiId)
404
+ }, /*#__PURE__*/React.createElement(Flex, {
405
+ direction: "column",
406
+ gap: "3"
407
+ }, group.reactions.map(function (reaction, index) {
408
+ return /*#__PURE__*/React.createElement(ReactionCard, {
409
+ key: reaction.id || index,
410
+ reaction: reaction,
411
+ onViewReaction: onViewReaction,
412
+ onRemoveReaction: onRemoveReaction,
413
+ authedUserId: authedUserId
414
+ });
415
+ })));
416
+ })));
417
+ }
418
+
419
+ var variants = {
420
+ enter: function enter(direction) {
421
+ return {
422
+ y: direction > 0 ? 20 : -20,
423
+ opacity: 0,
424
+ scale: 0
425
+ };
426
+ },
427
+ center: {
428
+ zIndex: 1,
429
+ y: 0,
430
+ opacity: 1,
431
+ scale: 1
432
+ },
433
+ exit: function exit(direction) {
434
+ return {
435
+ zIndex: 0,
436
+ y: direction < 0 ? 20 : -20,
437
+ opacity: 0,
438
+ scale: 0
439
+ };
440
+ }
441
+ };
442
+ function AnimatedCounter(_a) {
443
+ var _b = _a.value,
444
+ value = _b === void 0 ? 0 : _b,
445
+ _c = _a.style,
446
+ style = _c === void 0 ? {} : _c;
447
+ var previous = usePrevious(value);
448
+ var direction = value - (previous || 0);
449
+ return /*#__PURE__*/React.createElement("div", {
450
+ style: _assign({
451
+ position: 'relative'
452
+ }, style)
453
+ }, /*#__PURE__*/React.createElement("div", {
454
+ // Placeholder element
455
+ style: {
456
+ opacity: 0,
457
+ pointerEvents: 'none'
458
+ }
459
+ }, value), /*#__PURE__*/React.createElement(AnimatePresence, {
460
+ custom: direction
461
+ }, /*#__PURE__*/React.createElement(motion.div, {
462
+ style: {
463
+ position: 'absolute',
464
+ top: 0
465
+ // fontSize: '1em',
466
+ },
467
+ key: value,
468
+ variants: variants,
469
+ initial: "enter",
470
+ exit: "exit",
471
+ custom: direction,
472
+ animate: "center",
473
+ transition: {
474
+ duration: 0.2
475
+ }
476
+ }, value)));
477
+ }
478
+
479
+ var MOTION_VARIANTS = {
480
+ enter: {
481
+ opacity: 0,
482
+ scale: 1.5,
483
+ width: 0
484
+ },
485
+ // Set width relative to font size
486
+ display: function display(_a) {
487
+ var size = _a.size;
488
+ var targetWidth = size + 4;
489
+ return {
490
+ opacity: 1,
491
+ scale: 1,
492
+ width: targetWidth,
493
+ height: targetWidth
494
+ };
495
+ },
496
+ exit: {
497
+ opacity: 0,
498
+ scale: 0,
499
+ width: 0
500
+ }
501
+ };
502
+ function _hashGroupedReactions(groups) {
503
+ return Object.entries(groups).sort(function (_a, _b) {
504
+ var idA = _a[0];
505
+ var idB = _b[0];
506
+ return idA < idB ? -1 : 1;
507
+ }).reduce(function (acc, _a) {
508
+ var id = _a[0],
509
+ reactions = _a[1];
510
+ return "".concat(acc, "|").concat(id, "-").concat(reactions.length);
511
+ }, '');
512
+ }
513
+ function _areGroupedReactionsEqual(groupA, groupB) {
514
+ return _hashGroupedReactions(groupA) === _hashGroupedReactions(groupB);
515
+ }
516
+ function ReactionsBar(_a) {
517
+ var reactions = _a.reactions,
518
+ _b = _a.authedUserId,
519
+ authedUserId = _b === void 0 ? null : _b,
520
+ _c = _a.maxLength,
521
+ maxLength = _c === void 0 ? 10 : _c,
522
+ _d = _a.counter,
523
+ counter = _d === void 0 ? true : _d,
524
+ _e = _a.size,
525
+ size = _e === void 0 ? DEFAULT_SIZE : _e;
526
+ var authedUserReaction = useMemo(function () {
527
+ return authedUserId && reactions.find(function (reaction) {
528
+ var _a;
529
+ return ((_a = reaction.user) === null || _a === void 0 ? void 0 : _a.id) === authedUserId;
530
+ });
531
+ }, [reactions, authedUserId]);
532
+ var groupedReactions = useMemo(function () {
533
+ return arrayGroupBy(reactions, function (reaction) {
534
+ return reaction.emoji.id;
535
+ });
536
+ }, [reactions]);
537
+ var prevGroupedReactions = usePreviousDistinct(groupedReactions, function (prev, next) {
538
+ return Boolean(prev) && _areGroupedReactionsEqual(prev, next);
539
+ });
540
+ var reactionUpdates = useMemo(function () {
541
+ if (prevGroupedReactions && groupedReactions !== prevGroupedReactions) {
542
+ return Object.fromEntries(Object.entries(groupedReactions).map(function (_a) {
543
+ var emojiId = _a[0],
544
+ reactions = _a[1];
545
+ var prevCount = prevGroupedReactions[emojiId] ? prevGroupedReactions[emojiId].length : 0;
546
+ return [emojiId, reactions.length - prevCount];
547
+ }).filter(function (_a) {
548
+ var diff = _a[1];
549
+ return diff !== 0;
550
+ }));
551
+ } else {
552
+ return null;
553
+ }
554
+ }, [groupedReactions]);
555
+ var _f = useMemo(function () {
556
+ var all = Object.entries(groupedReactions).map(function (_a) {
557
+ var emojiId = _a[0],
558
+ reactions = _a[1];
559
+ return {
560
+ emojiId: emojiId,
561
+ reactions: reactions
562
+ };
563
+ }).sort(function (gA, gB) {
564
+ return authedUserReaction && gA.emojiId === authedUserReaction.emoji.id ? -1 : authedUserReaction && gB.emojiId === authedUserReaction.emoji.id ? 1 : gB.reactions.length - gA.reactions.length;
565
+ });
566
+ var display = all.slice(0, maxLength);
567
+ return {
568
+ all: all,
569
+ display: display
570
+ };
571
+ }, [groupedReactions, authedUserReaction]),
572
+ display = _f.display,
573
+ all = _f.all;
574
+ return /*#__PURE__*/React.createElement(Flex, {
575
+ direction: "row",
576
+ gap: "3",
577
+ alignItems: "center"
578
+ }, /*#__PURE__*/React.createElement("div", {
579
+ style: {
580
+ display: 'flex',
581
+ alignItems: 'center',
582
+ flexWrap: 'wrap'
583
+ }
584
+ }, /*#__PURE__*/React.createElement(AnimatePresence, null, display.map(function (_a, index) {
585
+ var emojiId = _a.emojiId,
586
+ reactions = _a.reactions;
587
+ var animationClassName = Boolean(reactionUpdates && reactionUpdates[emojiId]) ? reactionUpdates[emojiId] > 0 ? 'react-reactions--bounce' : 'react-reactions--shake' : undefined;
588
+ var namedReactions = reactions.filter(function (reaction) {
589
+ return Boolean(reaction.user.name);
590
+ });
591
+ var displayReactions = namedReactions.slice(0, 5);
592
+ var remainingReactions = namedReactions.slice(5);
593
+ return /*#__PURE__*/React.createElement(motion.div, {
594
+ key: "".concat(emojiId),
595
+ custom: {
596
+ size: size
597
+ },
598
+ variants: MOTION_VARIANTS,
599
+ initial: "enter",
600
+ animate: "display",
601
+ exit: "exit",
602
+ style: {
603
+ display: 'flex',
604
+ alignItems: 'center'
605
+ }
606
+ }, /*#__PURE__*/React.createElement("div", {
607
+ className: animationClassName
608
+ }, /*#__PURE__*/React.createElement(Tooltip, {
609
+ content: displayReactions.length === 0 ? reactions.length : ( /*#__PURE__*/React.createElement(React.Fragment, null, displayReactions.map(function (reaction) {
610
+ return /*#__PURE__*/React.createElement(React.Fragment, {
611
+ key: reaction.id
612
+ }, reaction.user.name, /*#__PURE__*/React.createElement("br", null));
613
+ }), remainingReactions.length === 0 ? null : remainingReactions.length === 1 ? remainingReactions[0].user.name : "+ ".concat(remainingReactions.length, " pessoas")))
614
+ }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("em-emoji", {
615
+ id: emojiId,
616
+ size: size
617
+ })))));
618
+ })), all.length > display.length ? /*#__PURE__*/React.createElement("div", null, "\u2026") : null), counter && reactions.length > 0 && ( /*#__PURE__*/React.createElement(AnimatedCounter, {
619
+ style: {
620
+ fontWeight: 'bold',
621
+ fontSize: Math.max(10, 0.75 * size)
622
+ },
623
+ value: reactions.length
624
+ })));
625
+ }
626
+
627
+ function ReactionsDisplay(_a) {
628
+ var reactions = _a.reactions,
629
+ _b = _a.authedUserId,
630
+ authedUserId = _b === void 0 ? null : _b,
631
+ onViewReaction = _a.onViewReaction,
632
+ onRemoveReaction = _a.onRemoveReaction,
633
+ _c = _a.size,
634
+ size = _c === void 0 ? DEFAULT_SIZE : _c,
635
+ maxLength = _a.maxLength,
636
+ counter = _a.counter;
637
+ var _d = useState(false),
638
+ popoverOpen = _d[0],
639
+ setPopoverOpen = _d[1];
640
+ var onClosePopover = useCallback(function () {
641
+ return setPopoverOpen(false);
642
+ }, [setPopoverOpen]);
643
+ return /*#__PURE__*/React.createElement(Popover.Root, {
644
+ open: popoverOpen,
645
+ onOpenChange: setPopoverOpen
646
+ }, reactions.length > 0 && ( /*#__PURE__*/React.createElement(Popover.Trigger, null, /*#__PURE__*/React.createElement(Button, {
647
+ variant: "ghost",
648
+ style: {
649
+ lineHeight: 1,
650
+ maxWidth: '100%'
651
+ },
652
+ radius: "full"
653
+ }, /*#__PURE__*/React.createElement(ReactionsBar, {
654
+ reactions: reactions,
655
+ authedUserId: authedUserId,
656
+ size: size,
657
+ maxLength: maxLength,
658
+ counter: counter
659
+ })))), /*#__PURE__*/React.createElement(Popover.Content, {
660
+ size: "1",
661
+ style: {
662
+ padding: 0
663
+ },
664
+ maxHeight: "50vh"
665
+ }, /*#__PURE__*/React.createElement(Box, {
666
+ style: {
667
+ maxWidth: {
668
+ xs: '90vw',
669
+ sm: '480px'
670
+ }
671
+ },
672
+ onClick: onClosePopover
673
+ }, /*#__PURE__*/React.createElement(ReactionGroupTabs, {
674
+ reactions: reactions,
675
+ authedUserId: authedUserId,
676
+ onViewReaction: onViewReaction,
677
+ onRemoveReaction: onRemoveReaction
678
+ }))));
679
+ }
680
+
681
+ var LOCAL_TARGET = Symbol();
682
+ var LOCAL_ID_PREFIX = '$$LOCAL_ID_';
683
+ function _localId() {
684
+ return "".concat(LOCAL_ID_PREFIX).concat(Math.random().toString(36).substring(2, 9));
685
+ }
686
+ function _isLocalId(reactionId) {
687
+ return typeof reactionId === 'string' && reactionId.startsWith(LOCAL_ID_PREFIX);
688
+ }
689
+ var ReactionsControl = /*#__PURE__*/forwardRef(function ReactionsControlInner(_a, ref) {
690
+ var _this = this;
691
+ var externalReactions = _a.reactions,
692
+ authedUser = _a.authedUser,
693
+ onAuthenticate = _a.onAuthenticate,
694
+ onViewReaction = _a.onViewReaction,
695
+ onRemoveReaction = _a.onRemoveReaction,
696
+ onSetReaction = _a.onSetReaction,
697
+ _b = _a.picker,
698
+ picker = _b === void 0 ? true : _b,
699
+ _c = _a.alwaysShowPicker,
700
+ alwaysShowPicker = _c === void 0 ? false : _c,
701
+ _d = _a.counter,
702
+ counter = _d === void 0 ? true : _d,
703
+ maxLength = _a.maxLength,
704
+ _e = _a.style,
705
+ style = _e === void 0 ? {} : _e,
706
+ _f = _a.size,
707
+ size = _f === void 0 ? DEFAULT_SIZE : _f;
708
+ var _g = useState(false),
709
+ isPersisting = _g[0],
710
+ setIsPersisting = _g[1];
711
+ //
712
+ // Locally track reaction state in order to provide instantaneous
713
+ // ui feedback
714
+ //
715
+ var _h = useState(externalReactions),
716
+ localReactions = _h[0],
717
+ setLocalReactions = _h[1];
718
+ var _j = useState(false),
719
+ pickerOpen = _j[0],
720
+ setPickerOpen = _j[1];
721
+ var authedUserReaction = useMemo(function () {
722
+ return authedUser && localReactions.find(function (reaction) {
723
+ return reaction.user.id === authedUser.id;
724
+ });
725
+ }, [authedUser, localReactions]);
726
+ var onRemoveReaction_ = useMemo(function () {
727
+ return typeof onRemoveReaction !== 'function' ? null : function (reactionId) {
728
+ return __awaiter(_this, void 0, void 0, function () {
729
+ var err_1;
730
+ return __generator(this, function (_a) {
731
+ switch (_a.label) {
732
+ case 0:
733
+ //
734
+ // Immediately update local reactions
735
+ //
736
+ setLocalReactions(function (localReactions) {
737
+ return localReactions.filter(function (localReaction) {
738
+ return localReaction.id !== reactionId;
739
+ });
740
+ });
741
+ if (!!_isLocalId(reactionId)) return [3 /*break*/, 5];
742
+ setIsPersisting(true);
743
+ _a.label = 1;
744
+ case 1:
745
+ _a.trys.push([1, 3,, 4]);
746
+ return [4 /*yield*/, onRemoveReaction(reactionId)];
747
+ case 2:
748
+ _a.sent();
749
+ return [3 /*break*/, 4];
750
+ case 3:
751
+ err_1 = _a.sent();
752
+ console.error(err_1);
753
+ return [3 /*break*/, 4];
754
+ case 4:
755
+ setIsPersisting(false);
756
+ _a.label = 5;
757
+ case 5:
758
+ return [2 /*return*/];
759
+ }
760
+ });
761
+ });
762
+ };
763
+ }, [onRemoveReaction, isPersisting]);
764
+ var setReaction = useMemo(function () {
765
+ return typeof onSetReaction !== 'function' ? null : function (emoji) {
766
+ return __awaiter(_this, void 0, void 0, function () {
767
+ var authedUser_, _a, _b, mockLocalReaction_1, persistedReaction_1, err_2;
768
+ return __generator(this, function (_c) {
769
+ switch (_c.label) {
770
+ case 0:
771
+ _a = authedUser;
772
+ if (_a) return [3 /*break*/, 3];
773
+ _b = typeof onAuthenticate === 'function';
774
+ if (!_b) return [3 /*break*/, 2];
775
+ return [4 /*yield*/, onAuthenticate()];
776
+ case 1:
777
+ _b = _c.sent();
778
+ _c.label = 2;
779
+ case 2:
780
+ _a = _b;
781
+ _c.label = 3;
782
+ case 3:
783
+ authedUser_ = _a || null;
784
+ if (!authedUser_) return [3 /*break*/, 8];
785
+ mockLocalReaction_1 = {
786
+ isPersisting: true,
787
+ targetId: LOCAL_TARGET,
788
+ id: _localId(),
789
+ emoji: emoji,
790
+ user: authedUser_
791
+ };
792
+ //
793
+ // Mock a local reaction for immediate user feedback
794
+ //
795
+ setLocalReactions(__spreadArray([mockLocalReaction_1], localReactions.filter(function (localR) {
796
+ return localR.user.id !== authedUser_.id;
797
+ }), true));
798
+ //
799
+ // Request reaction to be set
800
+ //
801
+ setIsPersisting(true);
802
+ _c.label = 4;
803
+ case 4:
804
+ _c.trys.push([4, 6,, 7]);
805
+ return [4 /*yield*/, onSetReaction(emoji)];
806
+ case 5:
807
+ persistedReaction_1 = _c.sent();
808
+ if (_typeof(persistedReaction_1) !== 'object') {
809
+ console.error(persistedReaction_1);
810
+ throw new Error('Invalid persisted reaction: ' + persistedReaction_1);
811
+ }
812
+ //
813
+ // Replace local reaction with persited version and
814
+ // unset isPersisting flag
815
+ //
816
+ setLocalReactions(function (currentReactions) {
817
+ return currentReactions.map(function (localR) {
818
+ return localR === mockLocalReaction_1 ? persistedReaction_1 : localR;
819
+ });
820
+ });
821
+ return [3 /*break*/, 7];
822
+ case 6:
823
+ err_2 = _c.sent();
824
+ console.error(err_2);
825
+ return [3 /*break*/, 7];
826
+ case 7:
827
+ setIsPersisting(false);
828
+ _c.label = 8;
829
+ case 8:
830
+ return [2 /*return*/];
831
+ }
832
+ });
833
+ });
834
+ };
835
+ }, [localReactions, onSetReaction, authedUser]);
836
+ //
837
+ // Expose local setReaction method so that
838
+ // external components may use it to provide instant
839
+ // reaction feedback
840
+ //
841
+ useImperativeHandle(ref, function () {
842
+ return {
843
+ setReaction: setReaction
844
+ };
845
+ }, [setReaction]);
846
+ //
847
+ // Sync external reactions with localReactions
848
+ //
849
+ useEffect(function () {
850
+ //
851
+ // Use a hashing comparison that takes into account
852
+ // only user id and reaction (ignoring reaction.id),
853
+ //
854
+ if (!areReactionSetsEqual(externalReactions, localReactions) && !isPersisting) {
855
+ setLocalReactions(externalReactions);
856
+ }
857
+ }, [externalReactions]);
858
+ return /*#__PURE__*/React.createElement("div", {
859
+ style: _assign({
860
+ display: 'flex',
861
+ alignItems: 'center'
862
+ }, style)
863
+ }, /*#__PURE__*/React.createElement(AnimatePresence, null, localReactions.length > 0 && ( /*#__PURE__*/React.createElement(motion.div, {
864
+ style: {
865
+ display: 'flex',
866
+ alignItems: 'center',
867
+ fontSize: size
868
+ },
869
+ initial: {
870
+ opacity: 0
871
+ },
872
+ animate: {
873
+ opacity: 1
874
+ },
875
+ exit: {
876
+ opacity: 0,
877
+ scale: 0,
878
+ width: 0
879
+ }
880
+ }, /*#__PURE__*/React.createElement(ReactionsDisplay, {
881
+ reactions: localReactions,
882
+ authedUserId: authedUser === null || authedUser === void 0 ? void 0 : authedUser.id,
883
+ onViewReaction: onViewReaction,
884
+ onRemoveReaction: onRemoveReaction_,
885
+ counter: counter,
886
+ maxLength: maxLength,
887
+ size: size
888
+ })))), picker && setReaction && ( /*#__PURE__*/React.createElement(AnimatePresence, null, (!authedUserReaction || alwaysShowPicker) && ( /*#__PURE__*/React.createElement(motion.div, {
889
+ style: {
890
+ display: 'flex',
891
+ alignItems: 'center',
892
+ fontSize: size
893
+ },
894
+ initial: {
895
+ opacity: 0,
896
+ marginLeft: 0
897
+ },
898
+ animate: {
899
+ opacity: 1,
900
+ marginLeft: localReactions.length > 0 ? '1em' : 0
901
+ },
902
+ exit: {
903
+ opacity: 0,
904
+ marginLeft: 0
905
+ }
906
+ }, /*#__PURE__*/React.createElement(EmojiPicker, {
907
+ open: pickerOpen,
908
+ onSetOpen: setPickerOpen,
909
+ onEmojiSelect: setReaction,
910
+ size: size
911
+ }))))));
912
+ });
913
+
914
+ var ReactionsContext = /*#__PURE__*/createContext({
915
+ authedUser: null,
916
+ reactions: [],
917
+ setReaction: function setReaction() {
918
+ throw new Error('ReactionsContext#setReaction undefined');
919
+ },
920
+ removeReaction: function removeReaction() {
921
+ throw new Error('ReactionsContext#removeReaction undefined');
922
+ }
923
+ });
924
+ function ReactionsProvider(_a) {
925
+ var authedUser = _a.authedUser,
926
+ reactions = _a.reactions,
927
+ children = _a.children,
928
+ onSetReaction = _a.onSetReaction,
929
+ onRemoveReaction = _a.onRemoveReaction;
930
+ var ctxValue = useMemo(function () {
931
+ return {
932
+ authedUser: authedUser,
933
+ reactions: reactions,
934
+ setReaction: function setReaction(emoji) {
935
+ if (!authedUser) {
936
+ throw new Error('Unable to set reaction without authedUser');
937
+ }
938
+ return Promise.resolve(onSetReaction(_assign(_assign({}, emoji), {
939
+ userId: authedUser === null || authedUser === void 0 ? void 0 : authedUser.id
940
+ })));
941
+ },
942
+ removeReaction: function removeReaction(reactionId) {
943
+ return Promise.resolve(onRemoveReaction(reactionId));
944
+ }
945
+ };
946
+ }, [onSetReaction, onRemoveReaction, reactions, authedUser]);
947
+ return /*#__PURE__*/React.createElement(ReactionsContext.Provider, {
948
+ value: ctxValue
949
+ }, children);
950
+ }
951
+ function useReactions(_a) {
952
+ var targetId = _a.targetId;
953
+ var ctxValue = useContext(ReactionsContext);
954
+ return targetId ? _assign(_assign({}, ctxValue), {
955
+ reactions: ctxValue.reactions.filter(function (reaction) {
956
+ return reaction.targetId === targetId;
957
+ })
958
+ }) : ctxValue;
959
+ }
960
+
961
+ export { EmojiPicker, ReactionCard, ReactionGroupTabs, ReactionsBar, ReactionsContext, ReactionsControl, ReactionsDisplay, ReactionsProvider, useReactions };