@telia-ace/widget-conversation 1.0.17 → 1.0.18

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 (35) hide show
  1. package/dist/{ui → components}/conversation/conversation.d.ts +0 -0
  2. package/dist/{ui/conversation/conversation-component.d.ts → components/conversation/plugin.d.ts} +8 -2
  3. package/dist/components/conversation/ui/content.d.ts +2 -0
  4. package/dist/{ui/conversation/conversation-input.d.ts → components/conversation/ui/input.d.ts} +0 -0
  5. package/dist/{ui/conversation/conversation-loader.d.ts → components/conversation/ui/loader.d.ts} +1 -1
  6. package/dist/{ui/conversation → components/conversation/ui}/message-list-items/button-list.d.ts +1 -1
  7. package/dist/{ui/conversation → components/conversation/ui}/message-list-items/custom.d.ts +0 -0
  8. package/dist/{ui/conversation → components/conversation/ui}/message-list-items/html.d.ts +1 -1
  9. package/dist/{ui/conversation → components/conversation/ui}/message-list-items/link-list.d.ts +1 -1
  10. package/dist/{ui/conversation → components/conversation/ui}/message-list-items/separator.d.ts +0 -0
  11. package/dist/{ui/conversation → components/conversation/ui}/message-list-items/text.d.ts +0 -0
  12. package/dist/{ui/conversation → components/conversation/ui}/message-types/agent.d.ts +1 -1
  13. package/dist/{ui/conversation → components/conversation/ui}/message-types/index.d.ts +0 -0
  14. package/dist/{ui/conversation → components/conversation/ui}/message-types/message-list.d.ts +1 -1
  15. package/dist/{ui/conversation → components/conversation/ui}/message-types/system.d.ts +0 -0
  16. package/dist/{ui/conversation → components/conversation/ui}/message-types/timestamp.d.ts +0 -0
  17. package/dist/{ui/conversation → components/conversation/ui}/message-types/user.d.ts +0 -0
  18. package/dist/components/conversation/ui/message.d.ts +7 -0
  19. package/dist/components/conversation/ui/overlay-outlets.d.ts +13 -0
  20. package/dist/components/conversation/ui/styles.d.ts +27 -0
  21. package/dist/{ui/return-button/return-button-component.d.ts → components/return-button/plugin.d.ts} +1 -2
  22. package/dist/{ui → components}/return-button/return-button.d.ts +0 -0
  23. package/dist/conversation.js +418 -312
  24. package/dist/conversation.js.map +1 -1
  25. package/dist/index.d.ts +2 -1
  26. package/dist/index.js +30 -8
  27. package/dist/index.js.map +1 -1
  28. package/dist/return-button.js.map +1 -1
  29. package/package.json +4 -4
  30. package/dist/ui/conversation/conversation-content.d.ts +0 -11
  31. package/dist/ui/conversation/conversation-message.d.ts +0 -7
  32. package/dist/ui/conversation/conversation-styles.d.ts +0 -12
  33. package/dist/ui/conversation/index.d.ts +0 -2
  34. package/dist/ui/index.d.ts +0 -2
  35. package/dist/ui/return-button/index.d.ts +0 -2
@@ -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, Html as Html$1, genericHtml, Lightbox, ItemList, itemList, buttonCss, useComponent, List, list, invertedHoverButton, usePrevious, useTransitionEnd, headingElement } from "@telia-ace/widget-ui";
32
+ import { Input, Button, borderTabStyle, SymbolBadge, useDispatch, useProperties, useScroll, Typography, invertedHoverButton, List, buttonCss, Html as Html$1, genericHtml, Lightbox, ItemList, itemList, useComponent, list, headingElement, usePrevious, useTransitionEnd, WidgetOverlayOutlet } from "@telia-ace/widget-ui";
33
33
  import { appendClassNames, uuid } from "@telia-ace/widget-utilities";
34
- import React, { useState, useEffect, Suspense, useRef, useCallback } from "react";
34
+ import React, { useState, useEffect, Suspense, useCallback, useRef } from "react";
35
35
  import styled, { css, keyframes } from "styled-components";
36
- import { ConversationMessageListItemType, ConversationMessageType } from "./index.js";
37
36
  import { FormComponent } from "@telia-ace/widget-forms";
37
+ import { ConversationMessageListItemType, ConversationMessageType } from "./index.js";
38
38
  import "@telia-ace/widget-core";
39
39
  import "@telia-ace/widget-services";
40
40
  import "@telia-ace/widget-plugins";
@@ -82,7 +82,9 @@ const ConversationInput = ({ className }) => {
82
82
  return;
83
83
  }
84
84
  e.preventDefault();
85
- dispatch("action", secondaryAction);
85
+ dispatch("action", __spreadValues({
86
+ actionKey: secondaryAction.action
87
+ }, secondaryAction));
86
88
  };
87
89
  const calculateHeight = (value) => {
88
90
  if (multiline && inputRef.current) {
@@ -364,10 +366,11 @@ const MessageTitle = styled(Typography)`
364
366
  `;
365
367
  const MessageContainer = styled.div`
366
368
  display: flex;
369
+ justify-content: ${(p) => p.user ? "end" : "start"};
367
370
  `;
368
371
  const MessageContent = styled.div`
369
- ${(p) => !p.user && nonUserMessageStyling(p.stacked, p.theme)}
370
- ${(p) => p.user && userMessageStyling(p.stacked, p.theme)}
372
+ ${(p) => !p.user && p.stacked && nonUserMessageStyling(p.stacked, p.theme)}
373
+ ${(p) => p.user && p.stacked && userMessageStyling(p.stacked, p.theme)}
371
374
 
372
375
  display: inline-block;
373
376
  margin-top: ${(p) => {
@@ -434,18 +437,6 @@ const userMessageStyling = (stacked, theme) => {
434
437
  `;
435
438
  };
436
439
  const MessageContentPart = styled.div`
437
- padding: ${(p) => {
438
- var _a;
439
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
440
- }} ${(p) => {
441
- var _a;
442
- return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
443
- }};
444
-
445
- ${(p) => p.noPadding && css`
446
- padding: 0;
447
- `}
448
-
449
440
  margin-bottom: ${(p) => {
450
441
  var _a;
451
442
  return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
@@ -464,21 +455,110 @@ const messageContentPadding = css`
464
455
  return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
465
456
  }};
466
457
  `;
458
+ const StyledForm = styled(FormComponent)`
459
+ margin: ${(p) => {
460
+ var _a;
461
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
462
+ }} 0;
463
+ padding: 0 ${(p) => {
464
+ var _a;
465
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
466
+ }};
467
+ & button.humany-form-component-button {
468
+ ${(p) => {
469
+ var _a, _b;
470
+ return invertedHoverButton({
471
+ active: false,
472
+ primaryColor: (_a = p.theme.colors) == null ? void 0 : _a.primary,
473
+ secondaryColor: (_b = p.theme.colors) == null ? void 0 : _b.accent
474
+ });
475
+ }};
476
+ display: block;
477
+ width: 100%;
478
+ margin-bottom: ${(p) => {
479
+ var _a;
480
+ return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
481
+ }};
482
+ }
483
+ & button.humany-form-component-submit {
484
+ width: 100%;
485
+ margin: 0;
486
+ :not(:last-child) {
487
+ margin-bottom: ${(p) => {
488
+ var _a;
489
+ return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
490
+ }};
491
+ }
492
+ }
493
+ `;
494
+ const StyledActionList = styled(List)`
495
+ padding: 0;
496
+ list-style: none;
497
+ button {
498
+ font-size: inherit;
499
+ }
500
+ margin: ${(p) => {
501
+ var _a;
502
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
503
+ }} 0;
504
+ padding: 0 ${(p) => {
505
+ var _a;
506
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
507
+ }};
508
+ display: flex;
509
+ gap: ${(p) => {
510
+ var _a;
511
+ return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
512
+ }};
513
+ `;
514
+ const StyledActionButton = styled.button`
515
+ ${buttonCss};
516
+ display: block;
517
+ background-color: ${(p) => {
518
+ var _a;
519
+ return (_a = p.theme.colors) == null ? void 0 : _a.primary;
520
+ }};
521
+ width: 100%;
522
+ color: #fff;
523
+ margin: ${(p) => {
524
+ var _a;
525
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
526
+ }} 0;
527
+ padding: 0 ${(p) => {
528
+ var _a;
529
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
530
+ }};
531
+ font-family: Lato;
532
+ font-size: ${(p) => {
533
+ var _a;
534
+ return (_a = p.theme.fonts) == null ? void 0 : _a.huge;
535
+ }};
536
+ font-weight: 300;
537
+ &:focus {
538
+ ${(p) => {
539
+ var _a;
540
+ return ((_a = p.theme.accessibility) == null ? void 0 : _a.isTabbing) && css`
541
+ ${borderTabStyle}
542
+ background-color: transparent;
543
+ `;
544
+ }}
545
+ }
546
+ `;
467
547
  const ConversationLoader = ({ className, agentData }) => {
468
548
  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)))));
469
549
  };
470
- const imageLightboxRenderer$1 = (attrs) => /* @__PURE__ */ React.createElement(Lightbox, {
550
+ const imageLightboxRenderer = (attrs) => /* @__PURE__ */ React.createElement(Lightbox, {
471
551
  attrs
472
552
  });
473
- const htmlParseInstructions$1 = {
553
+ const htmlParseInstructions = {
474
554
  transform: {
475
- img: imageLightboxRenderer$1
555
+ img: imageLightboxRenderer
476
556
  }
477
557
  };
478
558
  const Html = ({ body }) => {
479
559
  return /* @__PURE__ */ React.createElement(StyledHtml, {
480
560
  html: body,
481
- htmlParseInstruction: htmlParseInstructions$1
561
+ htmlParseInstruction: htmlParseInstructions
482
562
  });
483
563
  };
484
564
  const StyledHtml = styled(Html$1)`
@@ -496,6 +576,137 @@ const StyledHtml = styled(Html$1)`
496
576
  }
497
577
  }
498
578
  `;
579
+ const StyledTimestamp = styled.p`
580
+ && {
581
+ font-size: ${(p) => {
582
+ var _a;
583
+ return (_a = p.theme.fonts) == null ? void 0 : _a.small;
584
+ }};
585
+ font-weight: 300;
586
+ }
587
+ padding-top: ${(p) => {
588
+ var _a;
589
+ return (_a = p.theme.sizes) == null ? void 0 : _a.small;
590
+ }};
591
+ margin: 0;
592
+ line-height: 1.5em;
593
+ grid-area: info;
594
+ color: ${(p) => {
595
+ var _a;
596
+ return (_a = p.theme.colors) == null ? void 0 : _a.text;
597
+ }};
598
+ `;
599
+ const getTimestamp = (raw) => {
600
+ return new Date(raw).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
601
+ };
602
+ const Timestamp = ({ className, name, timestamp }) => {
603
+ if (!name && !timestamp) {
604
+ return null;
605
+ }
606
+ let output = "";
607
+ if (name) {
608
+ if (timestamp) {
609
+ output = `${name}: ${getTimestamp(timestamp)}`;
610
+ } else {
611
+ output = name;
612
+ }
613
+ } else if (timestamp) {
614
+ output = getTimestamp(timestamp);
615
+ }
616
+ return /* @__PURE__ */ React.createElement(StyledTimestamp, null, output);
617
+ };
618
+ const AgentMessage = ({ className, children, sender, timestamp }) => {
619
+ const { avatar, name } = sender;
620
+ const { avatarSize } = useProperties();
621
+ return /* @__PURE__ */ React.createElement(StyledAgentMessage, {
622
+ hasAvatar: !!avatar,
623
+ className: appendClassNames(className, "humany-conversation-agent-message")
624
+ }, avatar && /* @__PURE__ */ React.createElement(Avatar, {
625
+ avatarSize
626
+ }, typeof avatar === "string" ? /* @__PURE__ */ React.createElement("img", {
627
+ src: avatar
628
+ }) : /* @__PURE__ */ React.createElement(SymbolBadge, {
629
+ symbol: avatar
630
+ })), children, /* @__PURE__ */ React.createElement(Timestamp, {
631
+ name,
632
+ timestamp
633
+ }));
634
+ };
635
+ const StyledAgentMessage = styled.div`
636
+ display: grid;
637
+ margin-right: 10%;
638
+ width: 90%;
639
+ ${(p) => p.hasAvatar ? css`
640
+ grid-template-columns: auto 1fr;
641
+ grid-template-rows: 1fr auto;
642
+ grid-template-areas:
643
+ 'avatar content'
644
+ '. info';
645
+ ` : css`
646
+ grid-template-columns: 1fr;
647
+ grid-template-rows: 1fr auto;
648
+ grid-template-areas:
649
+ 'content'
650
+ 'info';
651
+ `};
652
+ `;
653
+ const SystemMessage = ({
654
+ className,
655
+ children,
656
+ timestamp,
657
+ discrete,
658
+ fullWidth
659
+ }) => {
660
+ return /* @__PURE__ */ React.createElement(StyledSystemMessage, {
661
+ className: appendClassNames(className, "humany-conversation-system-message"),
662
+ fullWidth
663
+ }, discrete ? /* @__PURE__ */ React.createElement(Discrete, {
664
+ className: "humany-conversation-discrete-message"
665
+ }, children, /* @__PURE__ */ React.createElement(Timestamp, {
666
+ timestamp
667
+ })) : /* @__PURE__ */ React.createElement(React.Fragment, null, children, /* @__PURE__ */ React.createElement(Timestamp, {
668
+ timestamp
669
+ })));
670
+ };
671
+ const StyledSystemMessage = styled.div`
672
+ ${(p) => p.fullWidth && "width: 100%"};
673
+ padding: 0 ${(p) => {
674
+ var _a;
675
+ return (_a = p.theme.sizes) == null ? void 0 : _a.large;
676
+ }};
677
+ overflow: auto;
678
+ `;
679
+ const Discrete = styled.div`
680
+ text-align: center;
681
+ word-wrap: break-word;
682
+ font-size: ${(p) => {
683
+ var _a;
684
+ return (_a = p.theme.fonts) == null ? void 0 : _a.normal;
685
+ }};
686
+ color: ${(p) => {
687
+ var _a;
688
+ return (_a = p.theme.colors) == null ? void 0 : _a.text;
689
+ }};
690
+ > p {
691
+ margin: 0;
692
+ }
693
+ `;
694
+ const UserMessage = ({ className, children, timestamp }) => {
695
+ const { userLabel = "" } = useProperties();
696
+ return /* @__PURE__ */ React.createElement(StyledUserMessage, {
697
+ className: appendClassNames(className, "humany-conversation-user-message")
698
+ }, children, /* @__PURE__ */ React.createElement(Timestamp, {
699
+ name: userLabel,
700
+ timestamp
701
+ }));
702
+ };
703
+ const StyledUserMessage = styled.div`
704
+ margin-left: 10%;
705
+ width: 90%;
706
+ display: flex;
707
+ flex-direction: column;
708
+ align-items: flex-end;
709
+ `;
499
710
  const mapActions = (actions) => Array.isArray(actions) ? actions : Object.keys(actions).map((i) => {
500
711
  return {
501
712
  label: actions[i],
@@ -713,286 +924,20 @@ const StyledList = styled(List)`
713
924
  margin: 0;
714
925
  }
715
926
  `;
716
- const ConversationContent = ({ content, isUser, stacked }) => {
717
- const dispatch = useDispatch();
718
- const { title, body, actions, form, items } = content;
719
- return /* @__PURE__ */ React.createElement(MessageContent, {
720
- user: isUser,
721
- stacked: !!stacked && stacked,
722
- fullWidth: !!form || !!actions
723
- }, title && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(MessageTitle, {
724
- variant: "h2"
725
- }, title)), body && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(Html, {
726
- body
727
- })), form && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(StyledForm, __spreadProps(__spreadValues({}, form), {
728
- onChange: (key, data) => {
729
- dispatch("form", {
730
- data,
731
- formKey: form.schema.id,
732
- actionKey: key
733
- });
734
- }
735
- }))), actions && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(StyledActionList, {
736
- items: Object.keys(actions).map((i) => {
737
- return { label: actions[i], actionKey: i };
738
- }),
739
- renderItem: (item) => {
740
- return /* @__PURE__ */ React.createElement("li", {
741
- key: item.actionKey
742
- }, /* @__PURE__ */ React.createElement(StyledActionButton, {
743
- onClick: () => {
744
- dispatch("action", item.actionKey);
745
- }
746
- }, item.label));
747
- }
748
- })), items && /* @__PURE__ */ React.createElement(MessageList, {
749
- key: uuid(),
750
- items,
751
- dispatch
752
- }));
753
- };
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
- }};
763
- & button.humany-form-component-button {
764
- ${(p) => {
765
- var _a, _b;
766
- return invertedHoverButton({
767
- active: false,
768
- primaryColor: (_a = p.theme.colors) == null ? void 0 : _a.primary,
769
- secondaryColor: (_b = p.theme.colors) == null ? void 0 : _b.accent
770
- });
771
- }};
772
- display: block;
773
- width: 100%;
774
- margin-bottom: ${(p) => {
775
- var _a;
776
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
777
- }};
778
- }
779
- & button.humany-form-component-submit {
780
- width: 100%;
781
- margin: 0;
782
- :not(:last-child) {
783
- margin-bottom: ${(p) => {
784
- var _a;
785
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
786
- }};
787
- }
788
- }
789
- `;
790
- const StyledActionList = styled(List)`
791
- padding: 0;
792
- list-style: none;
793
- button {
794
- font-size: inherit;
795
- }
796
- margin: ${(p) => {
797
- var _a;
798
- return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
799
- }} 0;
800
- padding: 0 ${(p) => {
801
- var _a;
802
- return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
803
- }};
804
- display: flex;
805
- gap: ${(p) => {
806
- var _a;
807
- return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
808
- }};
809
- `;
810
- const StyledActionButton = styled.button`
811
- ${buttonCss};
812
- display: block;
813
- background-color: ${(p) => {
814
- var _a;
815
- return (_a = p.theme.colors) == null ? void 0 : _a.primary;
816
- }};
817
- width: 100%;
818
- color: #fff;
819
- margin: ${(p) => {
820
- var _a;
821
- return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
822
- }} 0;
823
- padding: 0 ${(p) => {
824
- var _a;
825
- return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
826
- }};
827
- font-family: Lato;
828
- font-size: ${(p) => {
829
- var _a;
830
- return (_a = p.theme.fonts) == null ? void 0 : _a.huge;
831
- }};
832
- font-weight: 300;
833
- &:focus {
834
- ${(p) => {
835
- var _a;
836
- return ((_a = p.theme.accessibility) == null ? void 0 : _a.isTabbing) && css`
837
- ${borderTabStyle}
838
- background-color: transparent;
839
- `;
840
- }}
841
- }
842
- `;
843
- const StyledTimestamp = styled.p`
844
- && {
845
- font-size: ${(p) => {
846
- var _a;
847
- return (_a = p.theme.fonts) == null ? void 0 : _a.small;
848
- }};
849
- font-weight: 300;
850
- }
851
- padding-top: ${(p) => {
852
- var _a;
853
- return (_a = p.theme.sizes) == null ? void 0 : _a.small;
854
- }};
855
- margin: 0;
856
- line-height: 1.5em;
857
- grid-area: info;
858
- color: ${(p) => {
859
- var _a;
860
- return (_a = p.theme.colors) == null ? void 0 : _a.text;
861
- }};
862
- `;
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;
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
- `};
916
- `;
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;
946
- font-size: ${(p) => {
947
- var _a;
948
- return (_a = p.theme.fonts) == null ? void 0 : _a.normal;
949
- }};
950
- color: ${(p) => {
951
- var _a;
952
- return (_a = p.theme.colors) == null ? void 0 : _a.text;
953
- }};
954
- > p {
955
- margin: 0;
956
- }
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;
973
- `;
974
- const imageLightboxRenderer = (attrs) => /* @__PURE__ */ React.createElement(Lightbox, {
975
- attrs
976
- });
977
- const htmlParseInstructions = {
978
- transform: {
979
- img: imageLightboxRenderer
980
- }
981
- };
982
- const ConversationMessageComponent = ({
927
+ const ConversationMessage = ({
983
928
  className,
984
929
  timestamp,
985
930
  sender,
986
931
  type,
987
932
  content
988
933
  }) => {
989
- const getMessageStackPosition = (index) => {
934
+ const getMessageStackPosition = useCallback((index) => {
990
935
  let messageOrder = "first";
991
936
  if (content.length > 1) {
992
937
  messageOrder = index === 0 ? "first" : index + 1 === content.length ? "last" : "middle";
993
938
  }
994
939
  return messageOrder;
995
- };
940
+ }, [content]);
996
941
  const createSystemMessage = () => {
997
942
  return /* @__PURE__ */ React.createElement(React.Fragment, null, content.map((item) => {
998
943
  const { key, body, title, form, actions } = item;
@@ -1003,10 +948,9 @@ const ConversationMessageComponent = ({
1003
948
  discrete,
1004
949
  timestamp,
1005
950
  fullWidth: !!form || !!actions
1006
- }, discrete && body ? /* @__PURE__ */ React.createElement(Html$1, {
1007
- html: body,
1008
- htmlParseInstruction: htmlParseInstructions
1009
- }) : /* @__PURE__ */ React.createElement(ConversationContent, {
951
+ }, discrete && body ? /* @__PURE__ */ React.createElement(Html, {
952
+ body
953
+ }) : /* @__PURE__ */ React.createElement(Message, {
1010
954
  content: item,
1011
955
  isUser: false
1012
956
  }));
@@ -1020,7 +964,7 @@ const ConversationMessageComponent = ({
1020
964
  }, /* @__PURE__ */ React.createElement(ContentBundle, null, content.map((item, index) => {
1021
965
  return /* @__PURE__ */ React.createElement(MessageContainer, {
1022
966
  key: item.key
1023
- }, /* @__PURE__ */ React.createElement(ConversationContent, {
967
+ }, /* @__PURE__ */ React.createElement(Message, {
1024
968
  content: item,
1025
969
  isUser: false,
1026
970
  stacked: getMessageStackPosition(index)
@@ -1033,8 +977,9 @@ const ConversationMessageComponent = ({
1033
977
  className
1034
978
  }, /* @__PURE__ */ React.createElement(ContentBundle, null, content.map((item, index) => {
1035
979
  return /* @__PURE__ */ React.createElement(MessageContainer, {
980
+ user: true,
1036
981
  key: item.key
1037
- }, /* @__PURE__ */ React.createElement(ConversationContent, {
982
+ }, /* @__PURE__ */ React.createElement(Message, {
1038
983
  content: item,
1039
984
  isUser: true,
1040
985
  stacked: getMessageStackPosition(index)
@@ -1052,7 +997,45 @@ const ConversationMessageComponent = ({
1052
997
  return null;
1053
998
  }
1054
999
  };
1055
- const Conversation = ({ className }) => {
1000
+ const Message = ({ content, isUser, stacked }) => {
1001
+ const dispatch = useDispatch();
1002
+ const { title, body, actions, form, items } = content;
1003
+ return /* @__PURE__ */ React.createElement(MessageContent, {
1004
+ user: isUser,
1005
+ stacked,
1006
+ fullWidth: !!form || !!actions
1007
+ }, title && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(MessageTitle, {
1008
+ variant: "h2"
1009
+ }, title)), body && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(Html, {
1010
+ body
1011
+ })), form && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(StyledForm, __spreadProps(__spreadValues({}, form), {
1012
+ onChange: (key, data) => {
1013
+ dispatch("form", {
1014
+ data,
1015
+ formKey: form.schema.id,
1016
+ actionKey: key
1017
+ });
1018
+ }
1019
+ }))), actions && /* @__PURE__ */ React.createElement(MessageContentPart, null, /* @__PURE__ */ React.createElement(StyledActionList, {
1020
+ items: Object.keys(actions).map((i) => {
1021
+ return { label: actions[i], actionKey: i };
1022
+ }),
1023
+ renderItem: (item) => {
1024
+ return /* @__PURE__ */ React.createElement("li", {
1025
+ key: item.actionKey
1026
+ }, /* @__PURE__ */ React.createElement(StyledActionButton, {
1027
+ onClick: () => {
1028
+ dispatch("action", item.actionKey);
1029
+ }
1030
+ }, item.label));
1031
+ }
1032
+ })), items && /* @__PURE__ */ React.createElement(MessageList, {
1033
+ key: uuid(),
1034
+ items,
1035
+ dispatch
1036
+ }));
1037
+ };
1038
+ const ConversationContent = () => {
1056
1039
  const lastEntry = useRef(document.createElement("div"));
1057
1040
  const [scrollableCss, viewElem] = useScroll(true);
1058
1041
  const { messages, loading, typingActors } = useProperties();
@@ -1112,9 +1095,7 @@ const Conversation = ({ className }) => {
1112
1095
  }
1113
1096
  return null;
1114
1097
  };
1115
- return /* @__PURE__ */ React.createElement(Wrapper, {
1116
- className: appendClassNames(className, "humany-conversation-component")
1117
- }, /* @__PURE__ */ React.createElement(Scrollable, {
1098
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Scrollable, {
1118
1099
  tabIndex: 0,
1119
1100
  scrollableCss,
1120
1101
  ref: viewElem
@@ -1125,19 +1106,9 @@ const Conversation = ({ className }) => {
1125
1106
  tabIndex: -1,
1126
1107
  key: `${type}_${sender == null ? void 0 : sender.name}_${timestamp}_${content[0].key}`,
1127
1108
  ref: index + 1 < messages.length ? null : typingActors.length ? null : lastEntry
1128
- }, /* @__PURE__ */ React.createElement(ConversationMessageComponent, __spreadValues({}, message)));
1109
+ }, /* @__PURE__ */ React.createElement(ConversationMessage, __spreadValues({}, message)));
1129
1110
  }) : null, renderTypingActors(), loading && /* @__PURE__ */ React.createElement(MessageEntry, null, /* @__PURE__ */ React.createElement(ConversationLoader, null))), /* @__PURE__ */ React.createElement(ConversationInput, null));
1130
1111
  };
1131
- const Wrapper = styled.div`
1132
- position: absolute;
1133
- right: 0;
1134
- left: 0;
1135
- bottom: 0;
1136
- top: 0;
1137
- overflow: hidden;
1138
- display: flex;
1139
- flex-direction: column;
1140
- `;
1141
1112
  const Scrollable = styled.div`
1142
1113
  display: flex;
1143
1114
  flex-direction: column;
@@ -1192,5 +1163,140 @@ const MessageEntry = styled.div`
1192
1163
  font-weight: normal;
1193
1164
  `)}
1194
1165
  `;
1166
+ const OverlayOutlet = ({ dispatch }) => {
1167
+ const wrapperRef = useRef(null);
1168
+ useEffect(() => {
1169
+ if (wrapperRef.current && wrapperRef.current.parentNode) {
1170
+ dispatch("overlay-outlet-mounted", wrapperRef.current);
1171
+ }
1172
+ }, [wrapperRef]);
1173
+ return /* @__PURE__ */ React.createElement(WidgetOverlayOutlet, {
1174
+ portalId: "humany-conversation-overlay-portal",
1175
+ className: "humany-conversation-overlay-outlet",
1176
+ ref: wrapperRef
1177
+ });
1178
+ };
1179
+ const ConversationOverlayOutlet = ({
1180
+ dispatch,
1181
+ header,
1182
+ buttonLabel
1183
+ }) => {
1184
+ return /* @__PURE__ */ React.createElement(StyledWidgetOverlayOutlet, {
1185
+ portalId: "humany-conversation-portal",
1186
+ className: "humany-conversation-outlet"
1187
+ }, /* @__PURE__ */ React.createElement(ConversationOverlayHead, {
1188
+ className: "humany-conversation-outlet-head"
1189
+ }, /* @__PURE__ */ React.createElement(ConversationOverlayHeadButton, {
1190
+ className: "humany-conversation-outlet-head-button",
1191
+ "aria-label": buttonLabel,
1192
+ title: buttonLabel,
1193
+ onClick: () => dispatch("hide-overlay-conversation")
1194
+ }, /* @__PURE__ */ React.createElement(SymbolBadge, {
1195
+ symbol: {
1196
+ type: "Svg",
1197
+ content: "caret-down"
1198
+ },
1199
+ size: 20
1200
+ })), header && /* @__PURE__ */ React.createElement(ConversationOverlayHeader, {
1201
+ className: "humany-conversation-outlet-header",
1202
+ variant: "h1"
1203
+ }, header)), /* @__PURE__ */ React.createElement(ConversationContent, null));
1204
+ };
1205
+ const StyledWidgetOverlayOutlet = styled(WidgetOverlayOutlet)`
1206
+ z-index: 11;
1207
+ top: auto;
1208
+ height: 65%;
1209
+ background-color: #ffffff;
1210
+ display: flex;
1211
+ flex-direction: column;
1212
+ border-top-right-radius: ${(p) => {
1213
+ var _a;
1214
+ return (_a = p.theme.sizes) == null ? void 0 : _a.large;
1215
+ }};
1216
+ border-top-left-radius: ${(p) => {
1217
+ var _a;
1218
+ return (_a = p.theme.sizes) == null ? void 0 : _a.large;
1219
+ }};
1220
+ `;
1221
+ const ConversationOverlayHead = styled.div`
1222
+ display: flex;
1223
+ flex-direction: column;
1224
+ justify-content: center;
1225
+ align-items: center;
1226
+ gap: ${(p) => {
1227
+ var _a;
1228
+ return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
1229
+ }};
1230
+ padding: ${(p) => {
1231
+ var _a;
1232
+ return (_a = p.theme.sizes) == null ? void 0 : _a.normal;
1233
+ }};
1234
+ ${(p) => p.theme.border && `border-bottom: ${p.theme.border};`}
1235
+ `;
1236
+ const ConversationOverlayHeader = styled(Typography)`
1237
+ font-size: ${(p) => {
1238
+ var _a;
1239
+ return (_a = p.theme.fonts) == null ? void 0 : _a.medium;
1240
+ }};
1241
+ color: ${(p) => {
1242
+ var _a;
1243
+ return (_a = p.theme.colors) == null ? void 0 : _a.text;
1244
+ }};
1245
+ margin: 0;
1246
+ `;
1247
+ const ConversationOverlayHeadButton = styled(Button)`
1248
+ display: flex;
1249
+ align-items: center;
1250
+ justify-content: center;
1251
+ padding: ${(p) => {
1252
+ var _a;
1253
+ return (_a = p.theme.sizes) == null ? void 0 : _a.small;
1254
+ }} ${(p) => {
1255
+ var _a;
1256
+ return (_a = p.theme.sizes) == null ? void 0 : _a.medium;
1257
+ }};
1258
+ ${(p) => p.theme.borderRadius && `border-radius: ${p.theme.borderRadius};`}
1259
+
1260
+ &:focus {
1261
+ ${(p) => {
1262
+ var _a;
1263
+ return ((_a = p.theme.accessibility) == null ? void 0 : _a.isTabbing) && borderTabStyle;
1264
+ }};
1265
+ }
1266
+
1267
+ svg line {
1268
+ stroke: ${(p) => {
1269
+ var _a;
1270
+ return (_a = p.theme.colors) == null ? void 0 : _a.text;
1271
+ }};
1272
+ }
1273
+ `;
1274
+ const Conversation = ({ className }) => {
1275
+ const {
1276
+ overlay,
1277
+ overlayConversationHeader,
1278
+ overlayConversationCloseLabel
1279
+ } = useProperties();
1280
+ const dispatch = useDispatch();
1281
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Wrapper, {
1282
+ className: appendClassNames(className, "humany-conversation-component")
1283
+ }, /* @__PURE__ */ React.createElement(ConversationContent, null)), overlay && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(OverlayOutlet, {
1284
+ dispatch
1285
+ }), overlay.conversation && /* @__PURE__ */ React.createElement(ConversationOverlayOutlet, {
1286
+ dispatch,
1287
+ header: overlayConversationHeader,
1288
+ buttonLabel: overlayConversationCloseLabel
1289
+ })));
1290
+ };
1291
+ const Wrapper = styled.div`
1292
+ position: absolute;
1293
+ right: 0;
1294
+ left: 0;
1295
+ bottom: 0;
1296
+ top: 0;
1297
+ overflow: hidden;
1298
+ display: flex;
1299
+ flex-direction: column;
1300
+ `;
1195
1301
  export { Conversation as default };
1196
1302
  //# sourceMappingURL=conversation.js.map