@telia-ace/widget-conversation 1.0.16 → 1.0.17

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.
@@ -29,12 +29,12 @@ var __objRest = (source, exclude) => {
29
29
  }
30
30
  return target;
31
31
  };
32
- import { Input, Button, borderTabStyle, SymbolBadge, useDispatch, useProperties, useScroll, Typography, useComponent, invertedHoverButton, Html, List, buttonCss, Lightbox, useTransitionEnd, headingElement } from "@telia-ace/widget-ui";
32
+ import { Input, Button, borderTabStyle, SymbolBadge, useDispatch, useProperties, useScroll, Typography, Html as Html$1, genericHtml, Lightbox, ItemList, itemList, buttonCss, useComponent, List, list, invertedHoverButton, usePrevious, useTransitionEnd, headingElement } from "@telia-ace/widget-ui";
33
33
  import { appendClassNames, uuid } from "@telia-ace/widget-utilities";
34
- import React, { useState, useEffect, Suspense, Fragment, useRef, useCallback } from "react";
34
+ import React, { useState, useEffect, Suspense, useRef, useCallback } from "react";
35
35
  import styled, { css, keyframes } from "styled-components";
36
- import { FormComponent } from "@telia-ace/widget-forms";
37
36
  import { ConversationMessageListItemType, ConversationMessageType } from "./index.js";
37
+ import { FormComponent } from "@telia-ace/widget-forms";
38
38
  import "@telia-ace/widget-core";
39
39
  import "@telia-ace/widget-services";
40
40
  import "@telia-ace/widget-plugins";
@@ -82,7 +82,7 @@ const ConversationInput = ({ className }) => {
82
82
  return;
83
83
  }
84
84
  e.preventDefault();
85
- dispatch("action", secondaryAction.action);
85
+ dispatch("action", secondaryAction);
86
86
  };
87
87
  const calculateHeight = (value) => {
88
88
  if (multiline && inputRef.current) {
@@ -117,7 +117,7 @@ const ConversationInput = ({ className }) => {
117
117
  className: appendClassNames("humany-conversation-input", className),
118
118
  "data-has-focus": inputFocus,
119
119
  scrollableCss
120
- }, secondaryAction && /* @__PURE__ */ React.createElement(StyledButton, {
120
+ }, secondaryAction && /* @__PURE__ */ React.createElement(SecondaryActionButton, {
121
121
  disabled: inputDisabled,
122
122
  onClick: onSecondaryActionButtonClick,
123
123
  title: secondaryAction.label,
@@ -164,13 +164,10 @@ const StyledTextArea = styled(Input)`
164
164
  line-height: 1.2em;
165
165
  height: 1.2em;
166
166
  padding: 0;
167
- margin: ${(p) => {
167
+ margin: calc(${(p) => {
168
168
  var _a;
169
169
  return (_a = p.theme.sizes) == null ? void 0 : _a.small;
170
- }} ${(p) => {
171
- var _a;
172
- return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
173
- }};
170
+ }} * 2);
174
171
  font-size: ${(p) => {
175
172
  var _a;
176
173
  return (_a = p.theme.fonts) == null ? void 0 : _a.normal;
@@ -222,6 +219,13 @@ const StyledButton = styled(Button)`
222
219
  }};
223
220
  }
224
221
  `;
222
+ const SecondaryActionButton = styled(StyledButton)`
223
+ border-right: ${(p) => p.theme.border};
224
+ margin: ${(p) => {
225
+ var _a;
226
+ return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
227
+ }} 0;
228
+ `;
225
229
  const Wrapper$1 = styled.div`
226
230
  ${(p) => p.grow ? css`
227
231
  min-height: 50px;
@@ -349,7 +353,6 @@ const Loader = styled.div`
349
353
  const ContentBundle = styled.div`
350
354
  grid-area: content;
351
355
  max-width: 100%;
352
- overflow: hidden;
353
356
  `;
354
357
  const MessageTitle = styled(Typography)`
355
358
  font-size: ${(p) => {
@@ -363,35 +366,14 @@ const MessageContainer = styled.div`
363
366
  display: flex;
364
367
  `;
365
368
  const MessageContent = styled.div`
366
- background-color: ${(p) => {
367
- var _a, _b;
368
- return p.user ? (_a = p.theme.colors) == null ? void 0 : _a.primary : (_b = p.theme.colors) == null ? void 0 : _b.accent;
369
- }};
370
- color: ${(p) => {
371
- var _a, _b;
372
- return p.user ? (_a = p.theme.colors) == null ? void 0 : _a.accent : (_b = p.theme.colors) == null ? void 0 : _b.text;
373
- }};
374
- border-radius: 5px; // TODO: prop?
375
- border: 1px solid rgb(231, 231, 231);
376
- padding-top: calc(${(p) => {
377
- var _a;
378
- return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
379
- }} - ${(p) => {
380
- var _a;
381
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
382
- }});
383
- padding-bottom: calc(${(p) => {
384
- var _a;
385
- return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
386
- }} - ${(p) => {
387
- var _a;
388
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
389
- }});
369
+ ${(p) => !p.user && nonUserMessageStyling(p.stacked, p.theme)}
370
+ ${(p) => p.user && userMessageStyling(p.stacked, p.theme)}
371
+
372
+ display: inline-block;
390
373
  margin-top: ${(p) => {
391
374
  var _a;
392
375
  return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
393
376
  }};
394
- display: inline-block;
395
377
  && > * {
396
378
  overflow-wrap: break-word;
397
379
  word-wrap: break-word;
@@ -401,39 +383,56 @@ const MessageContent = styled.div`
401
383
  }
402
384
  max-width: 100%;
403
385
  ${(p) => p.fullWidth && "width: 100%;"}
386
+ `;
387
+ const nonUserMessageStyling = (stacked, theme) => {
388
+ var _a, _b;
389
+ const colors = css`
390
+ background-color: ${(_a = theme.colors) == null ? void 0 : _a.accent};
391
+ color: ${(_b = theme.colors) == null ? void 0 : _b.text};
392
+ ${theme.border && `border: ${theme.border};`};
393
+ `;
394
+ if (!theme.borderRadius) {
395
+ return colors;
396
+ }
397
+ return css`
398
+ ${colors}
404
399
 
405
- ${(p) => !p.user && css`
406
- border: ${p.theme.border};
407
- `}
408
- ${(p) => p.user && "margin-left: auto"};
400
+ border-top-right-radius: ${theme.borderRadius};
401
+ border-bottom-right-radius: ${theme.borderRadius};
409
402
 
410
- ${(p) => p.stacked === "first" && p.user && css`
411
- border-bottom-right-radius: 1px; // TODO: Prop?
412
- `}
413
- ${(p) => p.stacked === "middle" && p.user && css`
414
- border-bottom-right-radius: 1px;
415
- border-top-right-radius: 1px;
416
- `}
417
- ${(p) => p.stacked === "last" && p.user && css`
418
- border-top-right-radius: 1px;
419
- `}
420
- ${(p) => p.stacked === "first" && !p.user && css`
421
- border-bottom-left-radius: 1px;
403
+ ${stacked === "first" && `
404
+ border-top-left-radius: ${theme.borderRadius};
422
405
  `}
423
- ${(p) => p.stacked === "middle" && !p.user && css`
424
- border-bottom-left-radius: 1px;
425
- border-top-left-radius: 1px;
406
+
407
+ ${stacked === "last" && `
408
+ border-bottom-left-radius: ${theme.borderRadius};
426
409
  `}
427
- ${(p) => p.stacked === "last" && !p.user && css`
428
- border-top-left-radius: 1px;
429
- `};
410
+ `;
411
+ };
412
+ const userMessageStyling = (stacked, theme) => {
413
+ var _a, _b;
414
+ const colors = css`
415
+ background-color: ${(_a = theme.colors) == null ? void 0 : _a.primary};
416
+ color: ${(_b = theme.colors) == null ? void 0 : _b.accent};
417
+ `;
418
+ if (!theme.borderRadius) {
419
+ return colors;
420
+ }
421
+ return css`
422
+ ${colors}
430
423
 
431
- ${(p) => !p.stacked && css`
432
- ${p.user ? "border-bottom-right-radius: 1px;" : "border-bottom-left-radius: 1px;"}
433
- `};
424
+ border-top-left-radius: ${theme.borderRadius};
425
+ border-bottom-left-radius: ${theme.borderRadius};
434
426
 
435
- transition: border-radius 500ms linear;
436
- `;
427
+ ${stacked === "first" && `
428
+ border-top-right-radius: ${theme.borderRadius};
429
+ `}
430
+
431
+ ${stacked === "last" && `
432
+ border-bottom-right-radius: ${theme.borderRadius};
433
+ `}
434
+ `;
435
+ };
437
436
  const MessageContentPart = styled.div`
438
437
  padding: ${(p) => {
439
438
  var _a;
@@ -455,190 +454,276 @@ const MessageContentPart = styled.div`
455
454
  margin-bottom: 0;
456
455
  }
457
456
  `;
457
+ const messageContentPadding = css`
458
+ margin: ${(p) => {
459
+ var _a;
460
+ return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
461
+ }} 0;
462
+ padding: 0 ${(p) => {
463
+ var _a;
464
+ return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
465
+ }};
466
+ `;
458
467
  const ConversationLoader = ({ className, agentData }) => {
459
468
  return /* @__PURE__ */ React.createElement(ContentBundle, null, /* @__PURE__ */ React.createElement(MessageContainer, null, /* @__PURE__ */ React.createElement(MessageContent, null, /* @__PURE__ */ React.createElement(Loader, null, /* @__PURE__ */ React.createElement("div", null), /* @__PURE__ */ React.createElement("div", null), /* @__PURE__ */ React.createElement("div", null)))));
460
469
  };
461
- const StyledTimestamp = styled.p`
462
- && {
463
- font-size: ${(p) => {
470
+ const imageLightboxRenderer$1 = (attrs) => /* @__PURE__ */ React.createElement(Lightbox, {
471
+ attrs
472
+ });
473
+ const htmlParseInstructions$1 = {
474
+ transform: {
475
+ img: imageLightboxRenderer$1
476
+ }
477
+ };
478
+ const Html = ({ body }) => {
479
+ return /* @__PURE__ */ React.createElement(StyledHtml, {
480
+ html: body,
481
+ htmlParseInstruction: htmlParseInstructions$1
482
+ });
483
+ };
484
+ const StyledHtml = styled(Html$1)`
485
+ ${genericHtml}
486
+ color: inherit;
487
+ white-space: pre-wrap;
488
+ ${messageContentPadding}
489
+ a {
490
+ color: ${(p) => p.theme.colors.link};
491
+ &:focus {
492
+ ${(p) => {
464
493
  var _a;
465
- return (_a = p.theme.fonts) == null ? void 0 : _a.small;
494
+ return ((_a = p.theme.accessibility) == null ? void 0 : _a.isTabbing) && borderTabStyle;
466
495
  }};
467
- font-weight: 300;
496
+ }
468
497
  }
469
- padding-top: ${(p) => {
498
+ `;
499
+ const mapActions = (actions) => Array.isArray(actions) ? actions : Object.keys(actions).map((i) => {
500
+ return {
501
+ label: actions[i],
502
+ actionKey: i
503
+ };
504
+ });
505
+ const ButtonList = ({ header, actions, dispatch }) => {
506
+ return /* @__PURE__ */ React.createElement(StyledButtonList, {
507
+ header,
508
+ items: mapActions(actions),
509
+ renderItem: (item) => {
510
+ return /* @__PURE__ */ React.createElement("li", {
511
+ key: item.actionKey
512
+ }, /* @__PURE__ */ React.createElement(StyledButtonListButton, {
513
+ onClick: () => {
514
+ dispatch("action", item);
515
+ },
516
+ "aria-label": item.label,
517
+ title: item.label
518
+ }, /* @__PURE__ */ React.createElement(SymbolBadge, {
519
+ symbol: item.symbol
520
+ }), item.label));
521
+ }
522
+ });
523
+ };
524
+ const StyledButtonList = styled(ItemList)`
525
+ ${itemList}
526
+ > ul {
527
+ display: flex;
528
+ flex-wrap: wrap;
529
+ gap: ${(p) => {
470
530
  var _a;
471
- return (_a = p.theme.sizes) == null ? void 0 : _a.small;
531
+ return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
472
532
  }};
473
- margin: 0;
474
- line-height: 1.5em;
475
- grid-area: info;
476
- color: ${(p) => {
533
+ > li {
534
+ margin: 0;
535
+ }
536
+ }
537
+ ${messageContentPadding}
538
+ `;
539
+ const StyledButtonListButton = styled(Button)`
540
+ ${buttonCss};
541
+
542
+ display: block;
543
+ padding: ${(p) => {
477
544
  var _a;
478
- return (_a = p.theme.colors) == null ? void 0 : _a.text;
545
+ return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
546
+ }};
547
+ background-color: ${(p) => {
548
+ var _a;
549
+ return (_a = p.theme.colors) == null ? void 0 : _a.primary;
550
+ }};
551
+ width: 100%;
552
+ color: #ffffff;
553
+ &:focus {
554
+ ${(p) => {
555
+ var _a;
556
+ return ((_a = p.theme.accessibility) == null ? void 0 : _a.isTabbing) && css`
557
+ ${borderTabStyle}
558
+ background-color: transparent;
559
+ `;
560
+ }}
561
+ }
562
+
563
+ i,
564
+ svg {
565
+ margin-right: ${(p) => {
566
+ var _a;
567
+ return (_a = p.theme.sizes) == null ? void 0 : _a.small;
479
568
  }};
480
- `;
481
- const getTimestamp = (raw) => {
482
- return new Date(raw).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
483
- };
484
- const Timestamp = ({ className, name, timestamp }) => {
485
- if (!name && !timestamp) {
486
- return null;
487
- }
488
- let output = "";
489
- if (name) {
490
- if (timestamp) {
491
- output = `${name}: ${getTimestamp(timestamp)}`;
492
- } else {
493
- output = name;
494
569
  }
495
- } else if (timestamp) {
496
- output = getTimestamp(timestamp);
497
- }
498
- return /* @__PURE__ */ React.createElement(StyledTimestamp, null, output);
499
- };
500
- const AgentMessage = ({ className, children, sender, timestamp }) => {
501
- const { avatar, name } = sender;
502
- const { avatarSize } = useProperties();
503
- return /* @__PURE__ */ React.createElement(StyledAgentMessage, {
504
- hasAvatar: !!avatar,
505
- className: appendClassNames(className, "humany-conversation-agent-message")
506
- }, avatar && /* @__PURE__ */ React.createElement(Avatar, {
507
- avatarSize
508
- }, typeof avatar === "string" ? /* @__PURE__ */ React.createElement("img", {
509
- src: avatar
510
- }) : /* @__PURE__ */ React.createElement(SymbolBadge, {
511
- symbol: avatar
512
- })), children, /* @__PURE__ */ React.createElement(Timestamp, {
513
- name,
514
- timestamp
515
- }));
516
- };
517
- const StyledAgentMessage = styled.div`
518
- display: grid;
519
- margin-right: 10%;
520
- width: 90%;
521
- ${(p) => p.hasAvatar ? css`
522
- grid-template-columns: auto 1fr;
523
- grid-template-rows: 1fr auto;
524
- grid-template-areas:
525
- 'avatar content'
526
- '. info';
527
- ` : css`
528
- grid-template-columns: 1fr;
529
- grid-template-rows: 1fr auto;
530
- grid-template-areas:
531
- 'content'
532
- 'info';
533
- `};
534
570
  `;
535
- const CustomMessage = (props) => {
536
- const CustomComponent = useComponent(props.type);
537
- if (!CustomComponent) {
571
+ const Custom = ({ type, content = {} }) => {
572
+ const Component = useComponent(type);
573
+ if (!Component || !type) {
538
574
  return null;
539
575
  }
540
576
  return /* @__PURE__ */ React.createElement(Suspense, {
541
577
  fallback: null
542
- }, /* @__PURE__ */ React.createElement(MessageContent, {
543
- user: props.isUser,
544
- stacked: !!props.stacked && props.stacked,
545
- fullWidth: !!props.content.form || !!props.content.actions
546
- }, /* @__PURE__ */ React.createElement(MessageContentPart, {
547
- noPadding: !!props.content.noPadding && props.content.noPadding
548
- }, /* @__PURE__ */ React.createElement(CustomComponent, __spreadValues({}, props.content)))));
578
+ }, /* @__PURE__ */ React.createElement(Component, __spreadValues({}, content)));
549
579
  };
550
- const SystemMessage = ({
551
- className,
552
- children,
553
- timestamp,
554
- discrete,
555
- fullWidth
556
- }) => {
557
- return /* @__PURE__ */ React.createElement(StyledSystemMessage, {
558
- className: appendClassNames(className, "humany-conversation-system-message"),
559
- fullWidth
560
- }, discrete ? /* @__PURE__ */ React.createElement(Discrete, {
561
- className: "humany-conversation-discrete-message"
562
- }, children, /* @__PURE__ */ React.createElement(Timestamp, {
563
- timestamp
564
- })) : /* @__PURE__ */ React.createElement(React.Fragment, null, children, /* @__PURE__ */ React.createElement(Timestamp, {
565
- timestamp
566
- })));
580
+ const LinkList = ({ header, actions, dispatch }) => {
581
+ return /* @__PURE__ */ React.createElement(StyledLinkList, {
582
+ header,
583
+ items: mapActions(actions),
584
+ renderItem: (item) => {
585
+ return /* @__PURE__ */ React.createElement("li", {
586
+ key: item.actionKey
587
+ }, /* @__PURE__ */ React.createElement(StyledLinkButton, {
588
+ help: item.actionKey === "help",
589
+ onClick: () => {
590
+ dispatch("action", item);
591
+ },
592
+ "aria-label": item.label,
593
+ title: item.label
594
+ }, item.label, item.actionKey === "help" && /* @__PURE__ */ React.createElement(SymbolBadge, {
595
+ size: 14,
596
+ symbol: {
597
+ type: "Svg",
598
+ content: "caret-down"
599
+ }
600
+ })));
601
+ }
602
+ });
567
603
  };
568
- const StyledSystemMessage = styled.div`
569
- ${(p) => p.fullWidth && "width: 100%"};
570
- padding: 0 ${(p) => {
604
+ const StyledLinkList = styled(ItemList)`
605
+ ${itemList}
606
+ ${messageContentPadding}
607
+ > ul {
608
+ display: flex;
609
+ flex-direction: column;
610
+ gap: ${(p) => {
571
611
  var _a;
572
- return (_a = p.theme.sizes) == null ? void 0 : _a.large;
612
+ return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
573
613
  }};
574
- overflow: auto;
614
+ > li {
615
+ margin: 0;
616
+ }
617
+ }
575
618
  `;
576
- const Discrete = styled.div`
577
- text-align: center;
578
- word-wrap: break-word;
579
- font-size: ${(p) => {
580
- var _a;
581
- return (_a = p.theme.fonts) == null ? void 0 : _a.normal;
582
- }};
619
+ const StyledLinkButton = styled(Button)`
620
+ display: block;
621
+ text-align: left;
622
+ font-weight: 300;
583
623
  color: ${(p) => {
584
624
  var _a;
585
- return (_a = p.theme.colors) == null ? void 0 : _a.text;
625
+ return (_a = p.theme.colors) == null ? void 0 : _a.primary;
626
+ }};
627
+
628
+ ${(p) => {
629
+ var _a, _b;
630
+ return p.help && css`
631
+ color: ${(_a = p.theme.colors) == null ? void 0 : _a.text};
632
+ text-decoration: underline;
633
+
634
+ i,
635
+ svg {
636
+ margin-left: ${(_b = p.theme.sizes) == null ? void 0 : _b.small};
637
+ }
638
+ `;
639
+ }}
640
+
641
+ &:focus {
642
+ ${(p) => {
643
+ var _a, _b;
644
+ return ((_a = p.theme.accessibility) == null ? void 0 : _a.isTabbing) && css`
645
+ ${borderTabStyle}
646
+ span {
647
+ color: ${(_b = p.theme.colors) == null ? void 0 : _b.primary};
648
+ text-decoration: underline;
649
+ }
650
+ `;
586
651
  }};
587
- > p {
588
- margin: 0;
589
652
  }
590
653
  `;
591
- const UserMessage = ({ className, children, timestamp }) => {
592
- const { userLabel = "" } = useProperties();
593
- return /* @__PURE__ */ React.createElement(StyledUserMessage, {
594
- className: appendClassNames(className, "humany-conversation-user-message")
595
- }, children, /* @__PURE__ */ React.createElement(Timestamp, {
596
- name: userLabel,
597
- timestamp
598
- }));
654
+ const Separator = () => {
655
+ return /* @__PURE__ */ React.createElement(StyledSeparator, null);
599
656
  };
600
- const StyledUserMessage = styled.div`
601
- margin-left: 10%;
602
- width: 90%;
603
- display: flex;
604
- flex-direction: column;
605
- align-items: flex-end;
657
+ const StyledSeparator = styled.div`
658
+ ${(p) => p.theme.border && `border-bottom: ${p.theme.border};`}
659
+ width: 100%;
606
660
  `;
607
- const CustomMessageListItem = ({ type, content = {} }) => {
608
- const Component = useComponent(type);
609
- if (!Component || !type) {
610
- return null;
611
- }
612
- return /* @__PURE__ */ React.createElement(Component, __spreadValues({}, content));
661
+ const Text = ({ text }) => {
662
+ return /* @__PURE__ */ React.createElement(StyledTypography, {
663
+ variant: "span"
664
+ }, text);
613
665
  };
614
- const imageLightboxRenderer$1 = (attrs) => /* @__PURE__ */ React.createElement(Lightbox, {
615
- attrs
616
- });
617
- const htmlParseInstructions$1 = {
618
- transform: {
619
- img: imageLightboxRenderer$1
620
- }
666
+ const StyledTypography = styled(Typography)`
667
+ ${messageContentPadding}
668
+ `;
669
+ const mapItem = ([type, content]) => {
670
+ return { type, content, id: uuid() };
671
+ };
672
+ const MessageList = ({ items, dispatch }) => {
673
+ return /* @__PURE__ */ React.createElement(StyledList, {
674
+ items: items.map(mapItem),
675
+ renderLi: true,
676
+ renderItem: (item) => {
677
+ switch (item.type) {
678
+ case ConversationMessageListItemType.Text: {
679
+ return /* @__PURE__ */ React.createElement(Text, {
680
+ text: item.content
681
+ });
682
+ }
683
+ case ConversationMessageListItemType.HTML: {
684
+ return /* @__PURE__ */ React.createElement(Html, __spreadValues({}, item.content));
685
+ }
686
+ case ConversationMessageListItemType.Separator: {
687
+ return /* @__PURE__ */ React.createElement(Separator, __spreadValues({}, item.content));
688
+ }
689
+ case ConversationMessageListItemType.LinkList: {
690
+ return /* @__PURE__ */ React.createElement(LinkList, __spreadProps(__spreadValues({}, item.content), {
691
+ dispatch
692
+ }));
693
+ }
694
+ case ConversationMessageListItemType.ButtonList: {
695
+ return /* @__PURE__ */ React.createElement(ButtonList, __spreadProps(__spreadValues({}, item.content), {
696
+ dispatch
697
+ }));
698
+ }
699
+ default: {
700
+ return /* @__PURE__ */ React.createElement(Custom, {
701
+ type: item.type,
702
+ content: item.content
703
+ });
704
+ }
705
+ }
706
+ }
707
+ });
621
708
  };
709
+ const StyledList = styled(List)`
710
+ ${list}
711
+
712
+ > li {
713
+ margin: 0;
714
+ }
715
+ `;
622
716
  const ConversationContent = ({ content, isUser, stacked }) => {
623
717
  const dispatch = useDispatch();
624
- const { title, body, actions, form, type, items } = content;
625
- if (type)
626
- return /* @__PURE__ */ React.createElement(CustomMessage, {
627
- type,
628
- content,
629
- isUser,
630
- stacked
631
- });
718
+ const { title, body, actions, form, items } = content;
632
719
  return /* @__PURE__ */ React.createElement(MessageContent, {
633
- noPadding: true,
634
720
  user: isUser,
635
721
  stacked: !!stacked && stacked,
636
722
  fullWidth: !!form || !!actions
637
723
  }, title && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(MessageTitle, {
638
724
  variant: "h2"
639
- }, title)), body && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(StyledHtml, {
640
- html: body,
641
- htmlParseInstruction: htmlParseInstructions$1
725
+ }, title)), body && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(Html, {
726
+ body
642
727
  })), form && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(StyledForm, __spreadProps(__spreadValues({}, form), {
643
728
  onChange: (key, data) => {
644
729
  dispatch("form", {
@@ -660,107 +745,21 @@ const ConversationContent = ({ content, isUser, stacked }) => {
660
745
  }
661
746
  }, item.label));
662
747
  }
663
- })), items && /* @__PURE__ */ React.createElement(Fragment, null, /* @__PURE__ */ React.createElement(MessageContentPart, {
748
+ })), items && /* @__PURE__ */ React.createElement(MessageList, {
664
749
  key: uuid(),
665
- noPadding: true
666
- }, /* @__PURE__ */ React.createElement(StyledActionList, {
667
- items: items.map(([type2, content2]) => {
668
- return { type: type2, content: content2 };
669
- }),
670
- renderItem: (item) => {
671
- const itemKey = uuid();
672
- switch (item.type) {
673
- case ConversationMessageListItemType.Header: {
674
- return /* @__PURE__ */ React.createElement(ConversationListItem, {
675
- key: itemKey
676
- }, /* @__PURE__ */ React.createElement(HeaderText, null, item.content));
677
- }
678
- case ConversationMessageListItemType.Text: {
679
- return /* @__PURE__ */ React.createElement(ConversationListItem, {
680
- key: itemKey
681
- }, /* @__PURE__ */ React.createElement("span", null, item.content));
682
- }
683
- case ConversationMessageListItemType.HTML: {
684
- return /* @__PURE__ */ React.createElement(ConversationListItem, {
685
- key: itemKey
686
- }, /* @__PURE__ */ React.createElement(StyledHtml, {
687
- html: item.content.body,
688
- htmlParseInstruction: htmlParseInstructions$1
689
- }));
690
- }
691
- case ConversationMessageListItemType.Separator: {
692
- return /* @__PURE__ */ React.createElement(ConversationListItem, {
693
- key: itemKey,
694
- noPadding: true
695
- }, /* @__PURE__ */ React.createElement(SeparatorPadding, null, /* @__PURE__ */ React.createElement(Separator, null)));
696
- }
697
- case ConversationMessageListItemType.LinkList: {
698
- const items2 = Array.isArray(item.content.actions) ? item.content.actions : Object.keys(item.content.actions).map((i) => {
699
- return {
700
- label: item.content.actions[i],
701
- actionKey: i
702
- };
703
- });
704
- return /* @__PURE__ */ React.createElement(ConversationListItem, {
705
- key: itemKey
706
- }, /* @__PURE__ */ React.createElement(StyledLinkList, {
707
- items: items2,
708
- renderItem: (item2) => {
709
- return /* @__PURE__ */ React.createElement("li", {
710
- key: item2.actionKey
711
- }, /* @__PURE__ */ React.createElement(StyledLinkButton, {
712
- help: item2.actionKey === "help",
713
- onClick: () => {
714
- dispatch("action", item2.actionKey);
715
- }
716
- }, item2.label, item2.actionKey === "help" && /* @__PURE__ */ React.createElement(SymbolBadge, {
717
- size: 14,
718
- symbol: {
719
- type: "Svg",
720
- content: "caret-down"
721
- }
722
- })));
723
- }
724
- }));
725
- }
726
- case ConversationMessageListItemType.ButtonList: {
727
- const items2 = Array.isArray(item.content.actions) ? item.content.actions : Object.keys(item.content.actions).map((i) => {
728
- return {
729
- label: item.content.actions[i],
730
- actionKey: i
731
- };
732
- });
733
- return /* @__PURE__ */ React.createElement(ConversationListItem, {
734
- key: itemKey
735
- }, /* @__PURE__ */ React.createElement(StyledButtonList, {
736
- items: items2,
737
- renderItem: (item2) => {
738
- return /* @__PURE__ */ React.createElement("li", {
739
- key: item2.actionKey
740
- }, /* @__PURE__ */ React.createElement(StyledButtonListButton, {
741
- onClick: () => {
742
- dispatch("action", item2.actionKey);
743
- }
744
- }, /* @__PURE__ */ React.createElement(SymbolBadge, {
745
- symbol: item2.symbol
746
- }), item2.label));
747
- }
748
- }));
749
- }
750
- default: {
751
- return /* @__PURE__ */ React.createElement(ConversationListItem, {
752
- key: itemKey,
753
- noPadding: true
754
- }, /* @__PURE__ */ React.createElement(CustomMessageListItem, {
755
- type: item.type,
756
- content: item.content
757
- }));
758
- }
759
- }
760
- }
761
- }))));
750
+ items,
751
+ dispatch
752
+ }));
762
753
  };
763
754
  const StyledForm = styled(FormComponent)`
755
+ margin: ${(p) => {
756
+ var _a;
757
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
758
+ }} 0;
759
+ padding: 0 ${(p) => {
760
+ var _a;
761
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
762
+ }};
764
763
  & button.humany-form-component-button {
765
764
  ${(p) => {
766
765
  var _a, _b;
@@ -788,141 +787,43 @@ const StyledForm = styled(FormComponent)`
788
787
  }
789
788
  }
790
789
  `;
791
- const StyledHtml = styled(Html)`
792
- white-space: pre-wrap;
793
- a {
794
- color: ${(p) => p.theme.colors.link};
795
- &:focus {
796
- ${(p) => {
797
- var _a;
798
- return ((_a = p.theme.accessibility) == null ? void 0 : _a.isTabbing) && borderTabStyle;
799
- }};
800
- }
801
- }
802
- `;
803
790
  const StyledActionList = styled(List)`
804
791
  padding: 0;
805
792
  list-style: none;
806
- margin: 0 -${(p) => {
793
+ button {
794
+ font-size: inherit;
795
+ }
796
+ margin: ${(p) => {
807
797
  var _a;
808
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
809
- }};
810
- > li {
811
- margin: ${(p) => {
798
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
799
+ }} 0;
800
+ padding: 0 ${(p) => {
812
801
  var _a;
813
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
802
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
814
803
  }};
815
- }
816
- `;
817
- const StyledButtonList = styled(List)`
818
- padding: 0;
819
- list-style: none;
820
- > li {
821
- margin: ${(p) => {
822
- var _a;
823
- return (_a = p.theme.sizes) == null ? void 0 : _a.small;
824
- }} ${(p) => {
804
+ display: flex;
805
+ gap: ${(p) => {
825
806
  var _a;
826
807
  return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
827
808
  }};
828
- margin-left: 0;
829
- display: inline-block;
830
- }
831
809
  `;
832
- const StyledButtonListButton = styled.button`
810
+ const StyledActionButton = styled.button`
833
811
  ${buttonCss};
834
812
  display: block;
835
- text-align: left;
836
813
  background-color: ${(p) => {
837
814
  var _a;
838
815
  return (_a = p.theme.colors) == null ? void 0 : _a.primary;
839
816
  }};
840
817
  width: 100%;
841
818
  color: #fff;
842
- &:focus {
843
- ${(p) => {
844
- var _a;
845
- return ((_a = p.theme.accessibility) == null ? void 0 : _a.isTabbing) && css`
846
- ${borderTabStyle}
847
- background-color: transparent;
848
- `;
849
- }}
850
- }
851
-
852
- i,
853
- svg {
854
- margin-right: ${(p) => {
855
- var _a;
856
- return (_a = p.theme.sizes) == null ? void 0 : _a.small;
857
- }};
858
- }
859
- `;
860
- const StyledLinkList = styled(List)`
861
- padding: 0;
862
- list-style: none;
863
- > li {
864
- margin-bottom: ${(p) => {
865
- var _a;
866
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
867
- }};
868
-
869
- &:last-child {
870
- margin-bottom: 0;
871
- }
872
- }
873
- `;
874
- const HeaderText = styled.strong`
875
- font-size: ${(p) => {
876
- var _a;
877
- return (_a = p.theme.fonts) == null ? void 0 : _a.huge;
878
- }};
879
- `;
880
- const StyledLinkButton = styled.button`
881
- display: block;
882
- background-color: transparent;
883
- text-align: left;
884
- border: none;
885
- padding: 0;
886
- font-weight: 300;
887
- font-family: inherit;
888
- cursor: pointer;
889
- color: ${(p) => {
890
- var _a;
891
- return (_a = p.theme.colors) == null ? void 0 : _a.primary;
892
- }};
893
-
894
- ${(p) => {
895
- var _a, _b;
896
- return p.help && css`
897
- color: ${(_a = p.theme.colors) == null ? void 0 : _a.text};
898
- text-decoration: underline;
899
-
900
- i,
901
- svg {
902
- margin-left: ${(_b = p.theme.sizes) == null ? void 0 : _b.small};
903
- }
904
- `;
905
- }}
906
- `;
907
- styled(SymbolBadge)`
908
- font-size: ${(p) => {
909
- var _a;
910
- return (_a = p.theme.fonts) == null ? void 0 : _a.large;
911
- }} !important;
912
- margin-right: ${(p) => {
819
+ margin: ${(p) => {
913
820
  var _a;
914
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
915
- }};
916
- `;
917
- const StyledActionButton = styled.button`
918
- ${buttonCss};
919
- display: block;
920
- background-color: ${(p) => {
821
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
822
+ }} 0;
823
+ padding: 0 ${(p) => {
921
824
  var _a;
922
- return (_a = p.theme.colors) == null ? void 0 : _a.primary;
825
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
923
826
  }};
924
- width: 100%;
925
- color: #fff;
926
827
  font-family: Lato;
927
828
  font-size: ${(p) => {
928
829
  var _a;
@@ -939,107 +840,136 @@ const StyledActionButton = styled.button`
939
840
  }}
940
841
  }
941
842
  `;
942
- const SeparatorPadding = styled.div`
943
- padding-top: calc(${(p) => {
944
- var _a;
945
- return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
946
- }} - ${(p) => {
947
- var _a;
948
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
949
- }});
950
- padding-bottom: calc(${(p) => {
951
- var _a;
952
- return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
953
- }} - ${(p) => {
954
- var _a;
955
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
956
- }});
957
- `;
958
- const Separator = styled.div`
959
- background-color: #efefef;
960
- height: 1px;
961
- width: 100%;
962
- `;
963
- styled.div`
964
- display: flex;
965
- align-items: center;
966
- justify-content: center;
967
- cursor: pointer;
968
-
969
- > i,
970
- svg {
971
- margin-right: ${(p) => {
843
+ const StyledTimestamp = styled.p`
844
+ && {
845
+ font-size: ${(p) => {
972
846
  var _a;
973
- return (_a = p.theme.sizes) == null ? void 0 : _a.small;
847
+ return (_a = p.theme.fonts) == null ? void 0 : _a.small;
974
848
  }};
849
+ font-weight: 300;
975
850
  }
976
- `;
977
- const ConversationListItem = styled.li`
978
- padding-left: ${(p) => {
851
+ padding-top: ${(p) => {
979
852
  var _a;
980
- return p.noPadding ? 0 : (_a = p.theme.sizes) == null ? void 0 : _a.medium;
853
+ return (_a = p.theme.sizes) == null ? void 0 : _a.small;
981
854
  }};
982
- padding-right: ${(p) => {
855
+ margin: 0;
856
+ line-height: 1.5em;
857
+ grid-area: info;
858
+ color: ${(p) => {
983
859
  var _a;
984
- return p.noPadding ? 0 : (_a = p.theme.sizes) == null ? void 0 : _a.medium;
860
+ return (_a = p.theme.colors) == null ? void 0 : _a.text;
985
861
  }};
986
862
  `;
987
- styled.li`
988
- @media (min-width: 768px) {
989
- display: list-item !important;
990
- margin-right: 0 !important;
991
- margin-top: ${(p) => {
992
- var _a;
993
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
994
- }} !important;
863
+ const getTimestamp = (raw) => {
864
+ return new Date(raw).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
865
+ };
866
+ const Timestamp = ({ className, name, timestamp }) => {
867
+ if (!name && !timestamp) {
868
+ return null;
869
+ }
870
+ let output = "";
871
+ if (name) {
872
+ if (timestamp) {
873
+ output = `${name}: ${getTimestamp(timestamp)}`;
874
+ } else {
875
+ output = name;
995
876
  }
877
+ } else if (timestamp) {
878
+ output = getTimestamp(timestamp);
879
+ }
880
+ return /* @__PURE__ */ React.createElement(StyledTimestamp, null, output);
881
+ };
882
+ const AgentMessage = ({ className, children, sender, timestamp }) => {
883
+ const { avatar, name } = sender;
884
+ const { avatarSize } = useProperties();
885
+ return /* @__PURE__ */ React.createElement(StyledAgentMessage, {
886
+ hasAvatar: !!avatar,
887
+ className: appendClassNames(className, "humany-conversation-agent-message")
888
+ }, avatar && /* @__PURE__ */ React.createElement(Avatar, {
889
+ avatarSize
890
+ }, typeof avatar === "string" ? /* @__PURE__ */ React.createElement("img", {
891
+ src: avatar
892
+ }) : /* @__PURE__ */ React.createElement(SymbolBadge, {
893
+ symbol: avatar
894
+ })), children, /* @__PURE__ */ React.createElement(Timestamp, {
895
+ name,
896
+ timestamp
897
+ }));
898
+ };
899
+ const StyledAgentMessage = styled.div`
900
+ display: grid;
901
+ margin-right: 10%;
902
+ width: 90%;
903
+ ${(p) => p.hasAvatar ? css`
904
+ grid-template-columns: auto 1fr;
905
+ grid-template-rows: 1fr auto;
906
+ grid-template-areas:
907
+ 'avatar content'
908
+ '. info';
909
+ ` : css`
910
+ grid-template-columns: 1fr;
911
+ grid-template-rows: 1fr auto;
912
+ grid-template-areas:
913
+ 'content'
914
+ 'info';
915
+ `};
996
916
  `;
997
- styled.button`
998
- @media (min-width: 768px) {
999
- min-width: 100%;
1000
- margin-right: 0;
1001
- }
1002
- display: inline-block;
917
+ const SystemMessage = ({
918
+ className,
919
+ children,
920
+ timestamp,
921
+ discrete,
922
+ fullWidth
923
+ }) => {
924
+ return /* @__PURE__ */ React.createElement(StyledSystemMessage, {
925
+ className: appendClassNames(className, "humany-conversation-system-message"),
926
+ fullWidth
927
+ }, discrete ? /* @__PURE__ */ React.createElement(Discrete, {
928
+ className: "humany-conversation-discrete-message"
929
+ }, children, /* @__PURE__ */ React.createElement(Timestamp, {
930
+ timestamp
931
+ })) : /* @__PURE__ */ React.createElement(React.Fragment, null, children, /* @__PURE__ */ React.createElement(Timestamp, {
932
+ timestamp
933
+ })));
934
+ };
935
+ const StyledSystemMessage = styled.div`
936
+ ${(p) => p.fullWidth && "width: 100%"};
937
+ padding: 0 ${(p) => {
938
+ var _a;
939
+ return (_a = p.theme.sizes) == null ? void 0 : _a.large;
940
+ }};
941
+ overflow: auto;
942
+ `;
943
+ const Discrete = styled.div`
944
+ text-align: center;
945
+ word-wrap: break-word;
1003
946
  font-size: ${(p) => {
1004
947
  var _a;
1005
948
  return (_a = p.theme.fonts) == null ? void 0 : _a.normal;
1006
949
  }};
1007
- border-color: ${(p) => {
1008
- var _a;
1009
- return (_a = p.theme.colors) == null ? void 0 : _a.primary;
1010
- }} !important;
1011
- font-weight: 300;
1012
- && {
1013
- margin-right: ${(p) => {
950
+ color: ${(p) => {
1014
951
  var _a;
1015
- return (_a = p.theme.sizes) == null ? void 0 : _a.small;
952
+ return (_a = p.theme.colors) == null ? void 0 : _a.text;
1016
953
  }};
954
+ > p {
955
+ margin: 0;
1017
956
  }
1018
- ${(p) => {
1019
- var _a, _b;
1020
- return p["data-direction"] === "horizontal" && css`
1021
- width: 225px;
1022
- max-width: calc(50% - ${(_a = p.theme.sizes) == null ? void 0 : _a.large} - ${(_b = p.theme.sizes) == null ? void 0 : _b.small});
1023
- `;
1024
- }}
1025
- ${(p) => p["data-direction"] === "vertical" && css`
1026
- min-width: 150px;
1027
- `}
1028
- ${(p) => {
1029
- var _a;
1030
- return invertedHoverButton({
1031
- primaryColor: `${(_a = p.theme.colors) == null ? void 0 : _a.primary}`,
1032
- secondaryColor: "#FFFFFF"
1033
- });
1034
- }}
1035
- i {
1036
- margin: 0 ${(p) => {
1037
- var _a;
1038
- return (_a = p.theme.sizes) == null ? void 0 : _a.small;
1039
- }} 0 0;
1040
- }
1041
- span {
1042
- }
957
+ `;
958
+ const UserMessage = ({ className, children, timestamp }) => {
959
+ const { userLabel = "" } = useProperties();
960
+ return /* @__PURE__ */ React.createElement(StyledUserMessage, {
961
+ className: appendClassNames(className, "humany-conversation-user-message")
962
+ }, children, /* @__PURE__ */ React.createElement(Timestamp, {
963
+ name: userLabel,
964
+ timestamp
965
+ }));
966
+ };
967
+ const StyledUserMessage = styled.div`
968
+ margin-left: 10%;
969
+ width: 90%;
970
+ display: flex;
971
+ flex-direction: column;
972
+ align-items: flex-end;
1043
973
  `;
1044
974
  const imageLightboxRenderer = (attrs) => /* @__PURE__ */ React.createElement(Lightbox, {
1045
975
  attrs
@@ -1056,9 +986,8 @@ const ConversationMessageComponent = ({
1056
986
  type,
1057
987
  content
1058
988
  }) => {
1059
- useDispatch();
1060
989
  const getMessageStackPosition = (index) => {
1061
- let messageOrder = void 0;
990
+ let messageOrder = "first";
1062
991
  if (content.length > 1) {
1063
992
  messageOrder = index === 0 ? "first" : index + 1 === content.length ? "last" : "middle";
1064
993
  }
@@ -1074,7 +1003,7 @@ const ConversationMessageComponent = ({
1074
1003
  discrete,
1075
1004
  timestamp,
1076
1005
  fullWidth: !!form || !!actions
1077
- }, discrete && body ? /* @__PURE__ */ React.createElement(Html, {
1006
+ }, discrete && body ? /* @__PURE__ */ React.createElement(Html$1, {
1078
1007
  html: body,
1079
1008
  htmlParseInstruction: htmlParseInstructions
1080
1009
  }) : /* @__PURE__ */ React.createElement(ConversationContent, {
@@ -1123,86 +1052,13 @@ const ConversationMessageComponent = ({
1123
1052
  return null;
1124
1053
  }
1125
1054
  };
1126
- styled(FormComponent)`
1127
- & button.humany-form-component-button {
1128
- ${(p) => {
1129
- var _a, _b;
1130
- return invertedHoverButton({
1131
- active: false,
1132
- primaryColor: (_a = p.theme.colors) == null ? void 0 : _a.primary,
1133
- secondaryColor: (_b = p.theme.colors) == null ? void 0 : _b.accent
1134
- });
1135
- }};
1136
- display: block;
1137
- width: 100%;
1138
- margin-bottom: ${(p) => {
1139
- var _a;
1140
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
1141
- }};
1142
- }
1143
-
1144
- & button.humany-form-component-submit {
1145
- width: 100%;
1146
- margin: 0;
1147
- :not(:last-child) {
1148
- margin-bottom: ${(p) => {
1149
- var _a;
1150
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
1151
- }};
1152
- }
1153
- }
1154
- `;
1155
- styled(Html)`
1156
- white-space: pre-wrap;
1157
-
1158
- a {
1159
- color: ${(p) => p.theme.colors.link};
1160
- &:focus {
1161
- ${(p) => {
1162
- var _a;
1163
- return ((_a = p.theme.accessibility) == null ? void 0 : _a.isTabbing) && borderTabStyle;
1164
- }};
1165
- }
1166
- }
1167
- `;
1168
- styled(List)`
1169
- padding: 0;
1170
- list-style: none;
1171
- margin: 0 -${(p) => {
1172
- var _a;
1173
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
1174
- }};
1175
- > li {
1176
- margin: ${(p) => {
1177
- var _a;
1178
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
1179
- }};
1180
- }
1181
- `;
1182
- styled.button`
1183
- ${buttonCss};
1184
- display: block;
1185
- background-color: ${(p) => {
1186
- var _a;
1187
- return (_a = p.theme.colors) == null ? void 0 : _a.primary;
1188
- }};
1189
- width: 100%;
1190
- color: #fff;
1191
- &:focus {
1192
- ${(p) => {
1193
- var _a;
1194
- return ((_a = p.theme.accessibility) == null ? void 0 : _a.isTabbing) && css`
1195
- ${borderTabStyle}
1196
- background-color: transparent;
1197
- `;
1198
- }}
1199
- }
1200
- `;
1201
1055
  const Conversation = ({ className }) => {
1202
1056
  const lastEntry = useRef(document.createElement("div"));
1203
1057
  const [scrollableCss, viewElem] = useScroll(true);
1204
1058
  const { messages, loading, typingActors } = useProperties();
1205
1059
  const [canSmooth, setCanSmooth] = useState(false);
1060
+ const previousMessages = usePrevious(messages);
1061
+ const previousTypingActors = usePrevious(typingActors);
1206
1062
  const scrollView = useCallback((lastEntry2, smooth = true) => {
1207
1063
  if (lastEntry2 !== null && lastEntry2.current !== null) {
1208
1064
  if (messages && messages.length === 1) {
@@ -1218,12 +1074,23 @@ const Conversation = ({ className }) => {
1218
1074
  behavior: smooth ? "smooth" : "auto"
1219
1075
  });
1220
1076
  }
1221
- }, 0);
1077
+ }, 150);
1222
1078
  }
1223
1079
  }, [lastEntry]);
1224
1080
  useEffect(() => {
1225
1081
  if (canSmooth) {
1226
- scrollView(lastEntry);
1082
+ const messageCountChanged = messages.length !== (previousMessages == null ? void 0 : previousMessages.length);
1083
+ const typingActorCountChanged = typingActors.length !== (previousTypingActors == null ? void 0 : previousTypingActors.length);
1084
+ const messageContentCountChanged = messages.reduce((changed, message, index) => {
1085
+ var _a;
1086
+ if (((_a = previousMessages == null ? void 0 : previousMessages[index]) == null ? void 0 : _a.content.length) !== message.content.length) {
1087
+ return true;
1088
+ }
1089
+ return changed;
1090
+ }, false);
1091
+ if (messageCountChanged || messageContentCountChanged || typingActorCountChanged) {
1092
+ scrollView(lastEntry);
1093
+ }
1227
1094
  }
1228
1095
  }, [messages, typingActors]);
1229
1096
  useTransitionEnd(() => {
@@ -1309,13 +1176,6 @@ const MessageEntry = styled.div`
1309
1176
  }};
1310
1177
  }
1311
1178
 
1312
- * {
1313
- font-size: ${(p) => {
1314
- var _a;
1315
- return (_a = p.theme.fonts) == null ? void 0 : _a.normal;
1316
- }};
1317
- }
1318
-
1319
1179
  & span,
1320
1180
  p,
1321
1181
  a,