@pega/cosmos-react-social 4.0.0-dev.2.0 → 4.0.0-dev.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/Chat/Chat.d.ts +11 -13
- package/lib/components/Chat/Chat.d.ts.map +1 -1
- package/lib/components/Chat/Chat.js +9 -12
- package/lib/components/Chat/Chat.js.map +1 -1
- package/lib/components/Chat/Chat.types.d.ts +115 -2
- package/lib/components/Chat/Chat.types.d.ts.map +1 -1
- package/lib/components/Chat/Chat.types.js +9 -1
- package/lib/components/Chat/Chat.types.js.map +1 -1
- package/lib/components/Chat/ChatBody.d.ts +3 -8
- package/lib/components/Chat/ChatBody.d.ts.map +1 -1
- package/lib/components/Chat/ChatBody.js +288 -14
- package/lib/components/Chat/ChatBody.js.map +1 -1
- package/lib/components/Chat/ChatComposer.d.ts +3 -4
- package/lib/components/Chat/ChatComposer.d.ts.map +1 -1
- package/lib/components/Chat/ChatComposer.js +39 -29
- package/lib/components/Chat/ChatComposer.js.map +1 -1
- package/lib/components/Chat/ChatHeader.d.ts +17 -5
- package/lib/components/Chat/ChatHeader.d.ts.map +1 -1
- package/lib/components/Chat/ChatHeader.js +30 -14
- package/lib/components/Chat/ChatHeader.js.map +1 -1
- package/lib/components/Chat/ChatSettingsPanel.d.ts +7 -0
- package/lib/components/Chat/ChatSettingsPanel.d.ts.map +1 -0
- package/lib/components/Chat/ChatSettingsPanel.js +15 -0
- package/lib/components/Chat/ChatSettingsPanel.js.map +1 -0
- package/lib/components/Chat/ChatSettingsPanel.styles.d.ts +16 -0
- package/lib/components/Chat/ChatSettingsPanel.styles.d.ts.map +1 -0
- package/lib/components/Chat/ChatSettingsPanel.styles.js +47 -0
- package/lib/components/Chat/ChatSettingsPanel.styles.js.map +1 -0
- package/lib/components/Chat/Message.d.ts +3 -43
- package/lib/components/Chat/Message.d.ts.map +1 -1
- package/lib/components/Chat/Message.js +67 -27
- package/lib/components/Chat/Message.js.map +1 -1
- package/lib/components/Chat/Message.styles.d.ts +32 -21
- package/lib/components/Chat/Message.styles.d.ts.map +1 -1
- package/lib/components/Chat/Message.styles.js +92 -20
- package/lib/components/Chat/Message.styles.js.map +1 -1
- package/lib/components/Chat/SuggestedReplyPicker.d.ts +12 -3
- package/lib/components/Chat/SuggestedReplyPicker.d.ts.map +1 -1
- package/lib/components/Chat/SuggestedReplyPicker.js +92 -51
- package/lib/components/Chat/SuggestedReplyPicker.js.map +1 -1
- package/lib/components/Chat/SystemMessage.d.ts +4 -15
- package/lib/components/Chat/SystemMessage.d.ts.map +1 -1
- package/lib/components/Chat/SystemMessage.js +32 -22
- package/lib/components/Chat/SystemMessage.js.map +1 -1
- package/lib/components/Chat/TypeIndicator.d.ts +3 -10
- package/lib/components/Chat/TypeIndicator.d.ts.map +1 -1
- package/lib/components/Chat/TypeIndicator.js +5 -2
- package/lib/components/Chat/TypeIndicator.js.map +1 -1
- package/lib/components/Chat/index.d.ts +6 -9
- package/lib/components/Chat/index.d.ts.map +1 -1
- package/lib/components/Chat/index.js +2 -5
- package/lib/components/Chat/index.js.map +1 -1
- package/lib/components/Email/Email.styles.d.ts +15 -4
- package/lib/components/Email/Email.styles.d.ts.map +1 -1
- package/lib/components/Email/Email.styles.js +51 -4
- package/lib/components/Email/Email.styles.js.map +1 -1
- package/lib/components/Email/Email.types.d.ts +32 -14
- package/lib/components/Email/Email.types.d.ts.map +1 -1
- package/lib/components/Email/Email.types.js.map +1 -1
- package/lib/components/Email/EmailCaseView.d.ts.map +1 -1
- package/lib/components/Email/EmailCaseView.js +2 -2
- package/lib/components/Email/EmailCaseView.js.map +1 -1
- package/lib/components/Email/EmailComposer.d.ts.map +1 -1
- package/lib/components/Email/EmailComposer.js +91 -44
- package/lib/components/Email/EmailComposer.js.map +1 -1
- package/lib/components/Email/EmailConversation.d.ts.map +1 -1
- package/lib/components/Email/EmailConversation.js +76 -81
- package/lib/components/Email/EmailConversation.js.map +1 -1
- package/lib/components/Email/EmailManager.js +2 -2
- package/lib/components/Email/EmailManager.js.map +1 -1
- package/lib/components/Email/EmailNotificationPanel.d.ts +7 -0
- package/lib/components/Email/EmailNotificationPanel.d.ts.map +1 -0
- package/lib/components/Email/EmailNotificationPanel.js +15 -0
- package/lib/components/Email/EmailNotificationPanel.js.map +1 -0
- package/lib/components/Email/EmailSelector.d.ts +1 -0
- package/lib/components/Email/EmailSelector.d.ts.map +1 -1
- package/lib/components/Email/EmailSelector.js +16 -4
- package/lib/components/Email/EmailSelector.js.map +1 -1
- package/lib/components/Email/EmailSummaryItem.d.ts +2 -1
- package/lib/components/Email/EmailSummaryItem.d.ts.map +1 -1
- package/lib/components/Email/EmailSummaryItem.js +35 -26
- package/lib/components/Email/EmailSummaryItem.js.map +1 -1
- package/lib/components/Email/EmailSummaryList.d.ts.map +1 -1
- package/lib/components/Email/EmailSummaryList.js +17 -33
- package/lib/components/Email/EmailSummaryList.js.map +1 -1
- package/lib/components/Email/EntityList.js +1 -1
- package/lib/components/Email/EntityList.js.map +1 -1
- package/lib/components/Email/index.d.ts +3 -1
- package/lib/components/Email/index.d.ts.map +1 -1
- package/lib/components/Email/index.js +2 -0
- package/lib/components/Email/index.js.map +1 -1
- package/lib/components/Email/utils/EntityHighlighter.d.ts.map +1 -1
- package/lib/components/Email/utils/EntityHighlighter.js +4 -10
- package/lib/components/Email/utils/EntityHighlighter.js.map +1 -1
- package/lib/components/Feed/Feed.context.d.ts +3 -0
- package/lib/components/Feed/Feed.context.d.ts.map +1 -1
- package/lib/components/Feed/Feed.context.js.map +1 -1
- package/lib/components/Feed/Feed.d.ts.map +1 -1
- package/lib/components/Feed/Feed.js +18 -5
- package/lib/components/Feed/Feed.js.map +1 -1
- package/lib/components/Feed/FeedAttachments.d.ts +1 -1
- package/lib/components/Feed/FeedAttachments.d.ts.map +1 -1
- package/lib/components/Feed/FeedAttachments.js +5 -10
- package/lib/components/Feed/FeedAttachments.js.map +1 -1
- package/lib/components/Feed/FeedLikeButton.d.ts +1 -1
- package/lib/components/Feed/FeedLikeButton.d.ts.map +1 -1
- package/lib/components/Feed/FeedLikeButton.js +32 -34
- package/lib/components/Feed/FeedLikeButton.js.map +1 -1
- package/lib/components/Feed/FeedModalList.js +1 -1
- package/lib/components/Feed/FeedModalList.js.map +1 -1
- package/lib/components/Feed/FeedNewPost.d.ts.map +1 -1
- package/lib/components/Feed/FeedNewPost.js +3 -3
- package/lib/components/Feed/FeedNewPost.js.map +1 -1
- package/lib/components/Feed/FeedNewPostTypeMenu.d.ts +4 -7
- package/lib/components/Feed/FeedNewPostTypeMenu.d.ts.map +1 -1
- package/lib/components/Feed/FeedNewPostTypeMenu.js +37 -49
- package/lib/components/Feed/FeedNewPostTypeMenu.js.map +1 -1
- package/lib/components/Feed/FeedPost.d.ts.map +1 -1
- package/lib/components/Feed/FeedPost.js +16 -26
- package/lib/components/Feed/FeedPost.js.map +1 -1
- package/lib/components/Feed/FeedPost.types.d.ts +1 -3
- package/lib/components/Feed/FeedPost.types.d.ts.map +1 -1
- package/lib/components/Feed/FeedPost.types.js.map +1 -1
- package/lib/components/Feed/FeedReply.types.d.ts +1 -3
- package/lib/components/Feed/FeedReply.types.d.ts.map +1 -1
- package/lib/components/Feed/FeedReply.types.js.map +1 -1
- package/lib/components/Feed/FeedReplyInput.d.ts +1 -1
- package/lib/components/Feed/FeedReplyInput.d.ts.map +1 -1
- package/lib/components/Feed/FeedReplyInput.js +4 -0
- package/lib/components/Feed/FeedReplyInput.js.map +1 -1
- package/lib/components/HashtagButton/HashtagButton.d.ts.map +1 -1
- package/lib/components/HashtagButton/HashtagButton.js +2 -2
- package/lib/components/HashtagButton/HashtagButton.js.map +1 -1
- package/lib/components/MentionButton/MentionButton.d.ts +1 -1
- package/lib/components/MentionButton/MentionButton.d.ts.map +1 -1
- package/lib/components/MentionButton/MentionButton.js +11 -13
- package/lib/components/MentionButton/MentionButton.js.map +1 -1
- package/package.json +11 -11
- package/lib/components/Chat/ChatTranscript.d.ts +0 -23
- package/lib/components/Chat/ChatTranscript.d.ts.map +0 -1
- package/lib/components/Chat/ChatTranscript.js +0 -45
- package/lib/components/Chat/ChatTranscript.js.map +0 -1
- package/lib/components/Chat/MessageList.d.ts +0 -35
- package/lib/components/Chat/MessageList.d.ts.map +0 -1
- package/lib/components/Chat/MessageList.js +0 -134
- package/lib/components/Chat/MessageList.js.map +0 -1
- package/lib/components/Chat/RepeatingView.d.ts +0 -31
- package/lib/components/Chat/RepeatingView.d.ts.map +0 -1
- package/lib/components/Chat/RepeatingView.js +0 -47
- package/lib/components/Chat/RepeatingView.js.map +0 -1
- package/lib/components/Chat/TranscriptMessage.d.ts +0 -25
- package/lib/components/Chat/TranscriptMessage.d.ts.map +0 -1
- package/lib/components/Chat/TranscriptMessage.js +0 -48
- package/lib/components/Chat/TranscriptMessage.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FunctionComponent, Ref } from 'react';
|
|
2
2
|
import { BannerProps, ForwardProps, NoChildrenProp } from '@pega/cosmos-react-core';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
export
|
|
3
|
+
import { ChatComposerProps } from './ChatComposer';
|
|
4
|
+
import { ChatHeaderProps } from './ChatHeader';
|
|
5
|
+
import { SuggestedReplyPickerProps } from './SuggestedReplyPicker';
|
|
6
|
+
import { ChatBodyProps } from './Chat.types';
|
|
7
|
+
export type ChatBannerProps = {
|
|
8
8
|
/** Content */
|
|
9
9
|
content: string;
|
|
10
10
|
/** Name of the icon */
|
|
@@ -14,17 +14,15 @@ export interface ChatProps extends NoChildrenProp {
|
|
|
14
14
|
/** ref to the element */
|
|
15
15
|
ref?: Ref<HTMLElement>;
|
|
16
16
|
/** Header of conversation pane */
|
|
17
|
-
header:
|
|
18
|
-
/** Utility - This is used by utility container internally. It has predefined styles and visible conditionally based on utility prop is */
|
|
19
|
-
utility?: ReactNode;
|
|
17
|
+
header: ChatHeaderProps;
|
|
20
18
|
/** Wrapper of message groups, system messages, type ahead */
|
|
21
|
-
body:
|
|
19
|
+
body: ChatBodyProps;
|
|
22
20
|
/** Wrapper of suggested replies */
|
|
23
|
-
suggestedReplyPicker?:
|
|
21
|
+
suggestedReplyPicker?: SuggestedReplyPickerProps;
|
|
24
22
|
/** chat banner */
|
|
25
|
-
banner?: BannerProps
|
|
23
|
+
banner?: Pick<BannerProps, 'variant' | 'messages'>;
|
|
26
24
|
/** Wrapper of conversation input, emojis, attachments */
|
|
27
|
-
|
|
25
|
+
composer: ChatComposerProps;
|
|
28
26
|
}
|
|
29
27
|
declare const Chat: FunctionComponent<ChatProps & ForwardProps>;
|
|
30
28
|
export default Chat;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/Chat.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/Chat.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA+B,GAAG,EAAE,MAAM,OAAO,CAAC;AAG5E,OAAO,EAGL,WAAW,EAEX,YAAY,EACZ,cAAc,EACf,MAAM,yBAAyB,CAAC;AAIjC,OAAqB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC3D,OAA6B,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,WAAW,SAAU,SAAQ,cAAc;IAC/C,yBAAyB;IACzB,GAAG,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;IACvB,kCAAkC;IAClC,MAAM,EAAE,eAAe,CAAC;IACxB,6DAA6D;IAC7D,IAAI,EAAE,aAAa,CAAC;IACpB,mCAAmC;IACnC,oBAAoB,CAAC,EAAE,yBAAyB,CAAC;IACjD,kBAAkB;IAClB,MAAM,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,UAAU,CAAC,CAAC;IACnD,yDAAyD;IACzD,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAgED,QAAA,MAAM,IAAI,EAAE,iBAAiB,CAAC,SAAS,GAAG,YAAY,CAqBrD,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
3
|
import styled, { css } from 'styled-components';
|
|
4
4
|
import { Flex, Banner, defaultThemeProp } from '@pega/cosmos-react-core';
|
|
5
5
|
import { StyledBanner } from '@pega/cosmos-react-core/lib/components/Banner/Banner';
|
|
6
|
+
import ChatBody from './ChatBody';
|
|
7
|
+
import ChatComposer from './ChatComposer';
|
|
8
|
+
import ChatHeader from './ChatHeader';
|
|
9
|
+
import SuggestedReplyPicker from './SuggestedReplyPicker';
|
|
6
10
|
const StyledUtilityContainer = styled.div ``;
|
|
7
11
|
const StyledUtilityMerger = styled.div ``;
|
|
8
12
|
const StyledUtilityContent = styled.div ``;
|
|
9
13
|
const StyledChatContainer = styled.section(props => {
|
|
10
|
-
const { theme: { base: { spacing, shadow: { high: shadowHigh }, palette: { 'primary-background': primaryBackground, 'secondary-background': secondaryBackground } } } } = props;
|
|
14
|
+
const { theme: { base: { spacing, shadow: { high: shadowHigh }, palette: { 'primary-background': primaryBackground, 'secondary-background': secondaryBackground }, 'border-radius': borderRadius } } } = props;
|
|
11
15
|
return css `
|
|
12
16
|
height: 100%;
|
|
13
17
|
background: ${primaryBackground};
|
|
14
18
|
width: 100%;
|
|
19
|
+
border-radius: ${borderRadius};
|
|
15
20
|
${StyledUtilityMerger} {
|
|
16
21
|
min-height: 15rem;
|
|
17
22
|
position: relative;
|
|
@@ -50,18 +55,10 @@ const StyledChatContainer = styled.section(props => {
|
|
|
50
55
|
});
|
|
51
56
|
StyledChatContainer.defaultProps = defaultThemeProp;
|
|
52
57
|
const Chat = forwardRef((props, ref) => {
|
|
53
|
-
const { header, body,
|
|
54
|
-
const utilityContentRef = useRef(null);
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
utilityContentRef.current?.focus();
|
|
57
|
-
}, [utility]);
|
|
58
|
+
const { header, body, composer, banner, suggestedReplyPicker, ...restProps } = props;
|
|
58
59
|
return (_jsxs(Flex, { ref: ref, as: StyledChatContainer, container: {
|
|
59
60
|
direction: 'column'
|
|
60
|
-
}, ...restProps, children: [header,
|
|
61
|
-
direction: 'column'
|
|
62
|
-
}, as: StyledUtilityMerger, children: [utility && (_jsx(Flex, { tabIndex: 0, as: StyledUtilityContainer, container: {
|
|
63
|
-
direction: 'column'
|
|
64
|
-
}, children: _jsx(StyledUtilityContent, { ref: utilityContentRef, children: utility }) })), banner && (_jsx(Banner, { id: banner.id, variant: banner.variant, heading: banner.heading, messages: banner.messages })), body] }), suggestedReplyPicker, footer] }));
|
|
61
|
+
}, ...restProps, children: [_jsx(ChatHeader, { ...header }), banner && _jsx(Banner, { variant: banner.variant, messages: banner.messages }), _jsx(ChatBody, { ...body }), suggestedReplyPicker && _jsx(SuggestedReplyPicker, { ...suggestedReplyPicker }), _jsx(ChatComposer, { ...composer })] }));
|
|
65
62
|
});
|
|
66
63
|
export default Chat;
|
|
67
64
|
//# sourceMappingURL=Chat.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.js","sourceRoot":"","sources":["../../../src/components/Chat/Chat.tsx"],"names":[],"mappings":";AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Chat.js","sourceRoot":"","sources":["../../../src/components/Chat/Chat.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAqB,UAAU,EAAwB,MAAM,OAAO,CAAC;AAC5E,OAAO,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EACL,IAAI,EACJ,MAAM,EAEN,gBAAgB,EAGjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,sDAAsD,CAAC;AAEpF,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,YAAmC,MAAM,gBAAgB,CAAC;AACjE,OAAO,UAA+B,MAAM,cAAc,CAAC;AAC3D,OAAO,oBAAmD,MAAM,wBAAwB,CAAC;AAyBzF,MAAM,sBAAsB,GAAG,MAAM,CAAC,GAAG,CAAA,EAAE,CAAC;AAC5C,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAA,EAAE,CAAC;AACzC,MAAM,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAA,EAAE,CAAC;AAE1C,MAAM,mBAAmB,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;IACjD,MAAM,EACJ,KAAK,EAAE,EACL,IAAI,EAAE,EACJ,OAAO,EACP,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAC5B,OAAO,EAAE,EACP,oBAAoB,EAAE,iBAAiB,EACvC,sBAAsB,EAAE,mBAAmB,EAC5C,EACD,eAAe,EAAE,YAAY,EAC9B,EACF,EACF,GAAG,KAAK,CAAC;IACV,OAAO,GAAG,CAAA;;kBAEM,iBAAiB;;qBAEd,YAAY;MAC3B,mBAAmB;;;;;;MAMnB,sBAAsB;;;;;;;0BAOF,mBAAmB;UACnC,oBAAoB;mBACX,OAAO;sBACJ,UAAU;;;;sCAIM,mBAAmB;oDACL,mBAAmB;;;;;;;;MAQjE,YAAY;0BACQ,OAAO;;;;GAI9B,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,mBAAmB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAEpD,MAAM,IAAI,GAAgD,UAAU,CAClE,CAAC,KAAiC,EAAE,GAAqB,EAAE,EAAE;IAC3D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,oBAAoB,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IAErF,OAAO,CACL,MAAC,IAAI,IACH,GAAG,EAAE,GAAG,EACR,EAAE,EAAE,mBAAmB,EACvB,SAAS,EAAE;YACT,SAAS,EAAE,QAAQ;SACpB,KACG,SAAS,aAEb,KAAC,UAAU,OAAK,MAAM,GAAI,EACzB,MAAM,IAAI,KAAC,MAAM,IAAC,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAI,EACzE,KAAC,QAAQ,OAAK,IAAI,GAAI,EACrB,oBAAoB,IAAI,KAAC,oBAAoB,OAAK,oBAAoB,GAAI,EAC3E,KAAC,YAAY,OAAK,QAAQ,GAAI,IACzB,CACR,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import { FunctionComponent, forwardRef, PropsWithoutRef, Ref } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport {\n Flex,\n Banner,\n BannerProps,\n defaultThemeProp,\n ForwardProps,\n NoChildrenProp\n} from '@pega/cosmos-react-core';\nimport { StyledBanner } from '@pega/cosmos-react-core/lib/components/Banner/Banner';\n\nimport ChatBody from './ChatBody';\nimport ChatComposer, { ChatComposerProps } from './ChatComposer';\nimport ChatHeader, { ChatHeaderProps } from './ChatHeader';\nimport SuggestedReplyPicker, { SuggestedReplyPickerProps } from './SuggestedReplyPicker';\nimport { ChatBodyProps } from './Chat.types';\n\nexport type ChatBannerProps = {\n /** Content */\n content: string;\n /** Name of the icon */\n icon: string;\n};\n\nexport interface ChatProps extends NoChildrenProp {\n /** ref to the element */\n ref?: Ref<HTMLElement>;\n /** Header of conversation pane */\n header: ChatHeaderProps;\n /** Wrapper of message groups, system messages, type ahead */\n body: ChatBodyProps;\n /** Wrapper of suggested replies */\n suggestedReplyPicker?: SuggestedReplyPickerProps;\n /** chat banner */\n banner?: Pick<BannerProps, 'variant' | 'messages'>;\n /** Wrapper of conversation input, emojis, attachments */\n composer: ChatComposerProps;\n}\n\nconst StyledUtilityContainer = styled.div``;\nconst StyledUtilityMerger = styled.div``;\nconst StyledUtilityContent = styled.div``;\n\nconst StyledChatContainer = styled.section(props => {\n const {\n theme: {\n base: {\n spacing,\n shadow: { high: shadowHigh },\n palette: {\n 'primary-background': primaryBackground,\n 'secondary-background': secondaryBackground\n },\n 'border-radius': borderRadius\n }\n }\n } = props;\n return css`\n height: 100%;\n background: ${primaryBackground};\n width: 100%;\n border-radius: ${borderRadius};\n ${StyledUtilityMerger} {\n min-height: 15rem;\n position: relative;\n height: 100%;\n overflow-y: hidden;\n }\n ${StyledUtilityContainer} {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n max-height: 60%;\n width: 100%;\n background-color: ${secondaryBackground};\n > ${StyledUtilityContent} {\n padding: ${spacing} 0;\n box-shadow: ${shadowHigh};\n height: auto;\n width: 100%;\n overflow-y: auto;\n background: linear-gradient(${secondaryBackground} 10%, rgba(255, 255, 255, 0)),\n linear-gradient(rgba(255, 255, 255, 0), ${secondaryBackground} 10%) 0 100%,\n radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)),\n radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)) 0 100%;\n background-repeat: no-repeat;\n background-size: 100% 1rem, 100% 1rem, 100% 0.25rem, 100% 0.25rem;\n background-attachment: local, local, scroll, scroll;\n }\n }\n ${StyledBanner} {\n padding: calc(2 * ${spacing});\n margin-bottom: 0;\n flex-shrink: 0;\n }\n `;\n});\n\nStyledChatContainer.defaultProps = defaultThemeProp;\n\nconst Chat: FunctionComponent<ChatProps & ForwardProps> = forwardRef(\n (props: PropsWithoutRef<ChatProps>, ref: ChatProps['ref']) => {\n const { header, body, composer, banner, suggestedReplyPicker, ...restProps } = props;\n\n return (\n <Flex\n ref={ref}\n as={StyledChatContainer}\n container={{\n direction: 'column'\n }}\n {...restProps}\n >\n <ChatHeader {...header} />\n {banner && <Banner variant={banner.variant} messages={banner.messages} />}\n <ChatBody {...body} />\n {suggestedReplyPicker && <SuggestedReplyPicker {...suggestedReplyPicker} />}\n <ChatComposer {...composer} />\n </Flex>\n );\n }\n);\n\nexport default Chat;\n"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactNode, Ref } from 'react';
|
|
2
|
+
import { DefaultTheme } from 'styled-components';
|
|
3
|
+
import { BaseProps, Action, NoChildrenProp, OmitStrict, LinkProps, AvatarProps } from '@pega/cosmos-react-core';
|
|
2
4
|
export interface AttachmentItemProps extends BaseProps {
|
|
3
5
|
/** Unique Id for this attachment */
|
|
4
6
|
id: string;
|
|
@@ -6,7 +8,7 @@ export interface AttachmentItemProps extends BaseProps {
|
|
|
6
8
|
name: string;
|
|
7
9
|
/**
|
|
8
10
|
* A Cosmos icon name identifier to use for a attachment. Will serve as a fallback to a broken thumbnail.
|
|
9
|
-
* @default
|
|
11
|
+
* @default 'document-doc'
|
|
10
12
|
*/
|
|
11
13
|
icon?: string;
|
|
12
14
|
/** A string to be used as an image src for a attachment thumbnail. Falls back to a provided icon or the default attachment icon. */
|
|
@@ -20,4 +22,115 @@ export interface AttachmentItemProps extends BaseProps {
|
|
|
20
22
|
/** When passed, this will render a single icon button or within a MenuButton if onDelete is defined. */
|
|
21
23
|
onDelete?: (id: string) => void;
|
|
22
24
|
}
|
|
25
|
+
export type UserAvailability = 'available' | 'unavailable' | 'temporarilyUnavailable';
|
|
26
|
+
export interface ChatSettingsPanelProps extends NoChildrenProp {
|
|
27
|
+
status?: UserAvailability;
|
|
28
|
+
label: string;
|
|
29
|
+
onClick: () => void;
|
|
30
|
+
}
|
|
31
|
+
export type ColorTheme = [
|
|
32
|
+
keyof OmitStrict<DefaultTheme['base']['colors'], 'white' | 'black'>,
|
|
33
|
+
'extra-light' | 'light' | 'medium' | 'dark' | 'extra-dark'
|
|
34
|
+
];
|
|
35
|
+
export interface MediaPageLinks extends Pick<LinkProps, 'href'> {
|
|
36
|
+
/** Unique id for this push link */
|
|
37
|
+
id: string;
|
|
38
|
+
/** A string to be used as an image src for a thumbnail. */
|
|
39
|
+
thumbnail?: AttachmentItemProps['thumbnail'];
|
|
40
|
+
/** Additional information about the linked resource. */
|
|
41
|
+
title?: string;
|
|
42
|
+
}
|
|
43
|
+
export type MessageHeaderProps = {
|
|
44
|
+
/** message header content */
|
|
45
|
+
content?: ReactNode;
|
|
46
|
+
/** meta data */
|
|
47
|
+
meta?: ReactNode;
|
|
48
|
+
};
|
|
49
|
+
export interface MessageProps {
|
|
50
|
+
/** Message to be displayed */
|
|
51
|
+
message?: string;
|
|
52
|
+
/** Attachment list */
|
|
53
|
+
attachments?: AttachmentItemProps[];
|
|
54
|
+
/** Message page push links list */
|
|
55
|
+
mediaPageLinks?: MediaPageLinks[];
|
|
56
|
+
/** timestamp of the message(Formatted) */
|
|
57
|
+
timestamp?: string;
|
|
58
|
+
/** Incoming message/ outgoing message */
|
|
59
|
+
direction: 'in' | 'out';
|
|
60
|
+
/** Avatar information, can be image and name */
|
|
61
|
+
avatarInfo?: Pick<AvatarProps, 'name' | 'imageSrc'>;
|
|
62
|
+
/** Message status */
|
|
63
|
+
status?: 'delivered' | 'opened' | 'undeliverable' | 'sent';
|
|
64
|
+
/** Indicates if this message is being currently typed */
|
|
65
|
+
typing?: boolean;
|
|
66
|
+
/** Message header */
|
|
67
|
+
messageHeader?: MessageHeaderProps;
|
|
68
|
+
/** Sender type */
|
|
69
|
+
senderType: 'customer' | 'agent' | 'bot';
|
|
70
|
+
/** Sender ID, will be helpful in deciding the colour */
|
|
71
|
+
senderId: string;
|
|
72
|
+
/** Number used to determine the color of agent's message */
|
|
73
|
+
agentVariant?: number;
|
|
74
|
+
/** ref to the message wrapper */
|
|
75
|
+
ref?: Ref<HTMLLIElement>;
|
|
76
|
+
}
|
|
77
|
+
export interface TypeIndicatorProps extends Pick<MessageProps, 'ref' | 'message' | 'senderId' | 'senderType' | 'agentVariant'> {
|
|
78
|
+
/** Avatar information, can be image and name */
|
|
79
|
+
avatarInfo: Pick<AvatarProps, 'name' | 'imageSrc'>;
|
|
80
|
+
}
|
|
81
|
+
export interface SystemMessageProps extends Pick<MessageProps, 'ref' | 'timestamp'> {
|
|
82
|
+
/** System message to be displayed */
|
|
83
|
+
message: string;
|
|
84
|
+
/** variant of this system message
|
|
85
|
+
* @default 'secondary'
|
|
86
|
+
*/
|
|
87
|
+
variant?: 'primary' | 'secondary';
|
|
88
|
+
}
|
|
89
|
+
export interface ChatBodyHandleValue {
|
|
90
|
+
isScrolledToLatest: () => boolean;
|
|
91
|
+
scrollToLatestMessage: () => void;
|
|
92
|
+
scrollToNewMessage: () => void;
|
|
93
|
+
}
|
|
94
|
+
export interface ChatBodyProps {
|
|
95
|
+
/** Transcripts */
|
|
96
|
+
transcripts: {
|
|
97
|
+
/** Unique id of a chat session */
|
|
98
|
+
id: string;
|
|
99
|
+
/** Messages in a chat session */
|
|
100
|
+
messages: ChatBodyListItemProps[];
|
|
101
|
+
}[];
|
|
102
|
+
/** Live chat messages */
|
|
103
|
+
liveChat: ChatBodyListItemProps[];
|
|
104
|
+
/** Total unread messages */
|
|
105
|
+
unreadMessageCount?: number;
|
|
106
|
+
/** on scroll to button */
|
|
107
|
+
onScrollToButtonClick?: () => void;
|
|
108
|
+
/** Indicates if the data is being currently loading */
|
|
109
|
+
loading?: boolean;
|
|
110
|
+
/** Offset of the row item that need to trigger the load more callback */
|
|
111
|
+
offset?: number;
|
|
112
|
+
/** Callback to fetch more rows */
|
|
113
|
+
loadMore?: () => void;
|
|
114
|
+
/** Imperative handle */
|
|
115
|
+
handle?: Ref<ChatBodyHandleValue>;
|
|
116
|
+
/** ref to the element */
|
|
117
|
+
ref?: Ref<HTMLDivElement>;
|
|
118
|
+
}
|
|
119
|
+
type MessageListItemProps = OmitStrict<MessageProps, 'agentVariant' | 'typing'> & {
|
|
120
|
+
type: 'message';
|
|
121
|
+
id: string;
|
|
122
|
+
};
|
|
123
|
+
type SystemMessageListItemProps = SystemMessageProps & {
|
|
124
|
+
type: 'system';
|
|
125
|
+
id: string;
|
|
126
|
+
};
|
|
127
|
+
type TypeIndicatorListItemPops = OmitStrict<TypeIndicatorProps, 'agentVariant'> & {
|
|
128
|
+
type: 'typing';
|
|
129
|
+
id: string;
|
|
130
|
+
};
|
|
131
|
+
export type ChatBodyListItemProps = MessageListItemProps | SystemMessageListItemProps | TypeIndicatorListItemPops;
|
|
132
|
+
export declare const isMessageListItem: (message: ChatBodyListItemProps) => message is MessageListItemProps;
|
|
133
|
+
export declare const isSystemMessageListItem: (message: ChatBodyListItemProps) => message is SystemMessageListItemProps;
|
|
134
|
+
export declare const isTypeIndicatorListItem: (message: ChatBodyListItemProps) => message is TypeIndicatorListItemPops;
|
|
135
|
+
export {};
|
|
23
136
|
//# sourceMappingURL=Chat.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.types.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/Chat.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"Chat.types.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/Chat.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export const isMessageListItem = (message) => {
|
|
2
|
+
return message.type === 'message';
|
|
3
|
+
};
|
|
4
|
+
export const isSystemMessageListItem = (message) => {
|
|
5
|
+
return message.type === 'system';
|
|
6
|
+
};
|
|
7
|
+
export const isTypeIndicatorListItem = (message) => {
|
|
8
|
+
return message.type === 'typing';
|
|
9
|
+
};
|
|
2
10
|
//# sourceMappingURL=Chat.types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.types.js","sourceRoot":"","sources":["../../../src/components/Chat/Chat.types.ts"],"names":[],"mappings":"","sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"Chat.types.js","sourceRoot":"","sources":["../../../src/components/Chat/Chat.types.ts"],"names":[],"mappings":"AA4JA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,OAA8B,EACG,EAAE;IACnC,OAAO,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC;AACpC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,OAA8B,EACS,EAAE;IACzC,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC;AACnC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,OAA8B,EACQ,EAAE;IACxC,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC;AACnC,CAAC,CAAC","sourcesContent":["import { ReactNode, Ref } from 'react';\nimport { DefaultTheme } from 'styled-components';\n\nimport {\n BaseProps,\n Action,\n NoChildrenProp,\n OmitStrict,\n LinkProps,\n AvatarProps\n} from '@pega/cosmos-react-core';\n\nexport interface AttachmentItemProps extends BaseProps {\n /** Unique Id for this attachment */\n id: string;\n /** Name of the attachment. */\n name: string;\n /**\n * A Cosmos icon name identifier to use for a attachment. Will serve as a fallback to a broken thumbnail.\n * @default 'document-doc'\n */\n icon?: string;\n /** A string to be used as an image src for a attachment thumbnail. Falls back to a provided icon or the default attachment icon. */\n thumbnail?: string;\n /** Additional information about the attachment. If progress prop is passed and its value is less than 100, this region is instead used for the upload progress indicator. */\n meta?: string;\n /** When passed, previews the attachment on click */\n onPreview?: (id: string) => void;\n /** Actions list for the attachment */\n actions?: Action[];\n /** When passed, this will render a single icon button or within a MenuButton if onDelete is defined. */\n onDelete?: (id: string) => void;\n}\n\nexport type UserAvailability = 'available' | 'unavailable' | 'temporarilyUnavailable';\n\nexport interface ChatSettingsPanelProps extends NoChildrenProp {\n status?: UserAvailability;\n label: string;\n onClick: () => void;\n}\n\nexport type ColorTheme = [\n keyof OmitStrict<DefaultTheme['base']['colors'], 'white' | 'black'>,\n 'extra-light' | 'light' | 'medium' | 'dark' | 'extra-dark'\n];\n\nexport interface MediaPageLinks extends Pick<LinkProps, 'href'> {\n /** Unique id for this push link */\n id: string;\n /** A string to be used as an image src for a thumbnail. */\n thumbnail?: AttachmentItemProps['thumbnail'];\n /** Additional information about the linked resource. */\n title?: string;\n}\n\nexport type MessageHeaderProps = {\n /** message header content */\n content?: ReactNode;\n /** meta data */\n meta?: ReactNode;\n};\n\nexport interface MessageProps {\n /** Message to be displayed */\n message?: string;\n /** Attachment list */\n attachments?: AttachmentItemProps[];\n /** Message page push links list */\n mediaPageLinks?: MediaPageLinks[];\n /** timestamp of the message(Formatted) */\n timestamp?: string;\n /** Incoming message/ outgoing message */\n direction: 'in' | 'out';\n /** Avatar information, can be image and name */\n avatarInfo?: Pick<AvatarProps, 'name' | 'imageSrc'>;\n /** Message status */\n status?: 'delivered' | 'opened' | 'undeliverable' | 'sent';\n /** Indicates if this message is being currently typed */\n typing?: boolean;\n /** Message header */\n messageHeader?: MessageHeaderProps;\n /** Sender type */\n senderType: 'customer' | 'agent' | 'bot';\n /** Sender ID, will be helpful in deciding the colour */\n senderId: string;\n /** Number used to determine the color of agent's message */\n agentVariant?: number;\n /** ref to the message wrapper */\n ref?: Ref<HTMLLIElement>;\n}\n\nexport interface TypeIndicatorProps\n extends Pick<MessageProps, 'ref' | 'message' | 'senderId' | 'senderType' | 'agentVariant'> {\n /** Avatar information, can be image and name */\n avatarInfo: Pick<AvatarProps, 'name' | 'imageSrc'>;\n}\n\nexport interface SystemMessageProps extends Pick<MessageProps, 'ref' | 'timestamp'> {\n /** System message to be displayed */\n message: string;\n /** variant of this system message\n * @default 'secondary'\n */\n variant?: 'primary' | 'secondary';\n}\n\nexport interface ChatBodyHandleValue {\n isScrolledToLatest: () => boolean;\n scrollToLatestMessage: () => void;\n scrollToNewMessage: () => void;\n}\n\nexport interface ChatBodyProps {\n /** Transcripts */\n transcripts: {\n /** Unique id of a chat session */\n id: string;\n /** Messages in a chat session */\n messages: ChatBodyListItemProps[];\n }[];\n /** Live chat messages */\n liveChat: ChatBodyListItemProps[];\n /** Total unread messages */\n unreadMessageCount?: number;\n /** on scroll to button */\n onScrollToButtonClick?: () => void;\n /** Indicates if the data is being currently loading */\n loading?: boolean;\n /** Offset of the row item that need to trigger the load more callback */\n offset?: number;\n /** Callback to fetch more rows */\n loadMore?: () => void;\n /** Imperative handle */\n handle?: Ref<ChatBodyHandleValue>;\n /** ref to the element */\n ref?: Ref<HTMLDivElement>;\n}\n\ntype MessageListItemProps = OmitStrict<MessageProps, 'agentVariant' | 'typing'> & {\n type: 'message';\n id: string;\n};\n\ntype SystemMessageListItemProps = SystemMessageProps & { type: 'system'; id: string };\n\ntype TypeIndicatorListItemPops = OmitStrict<TypeIndicatorProps, 'agentVariant'> & {\n type: 'typing';\n id: string;\n};\n\nexport type ChatBodyListItemProps =\n | MessageListItemProps\n | SystemMessageListItemProps\n | TypeIndicatorListItemPops;\n\nexport const isMessageListItem = (\n message: ChatBodyListItemProps\n): message is MessageListItemProps => {\n return message.type === 'message';\n};\n\nexport const isSystemMessageListItem = (\n message: ChatBodyListItemProps\n): message is SystemMessageListItemProps => {\n return message.type === 'system';\n};\n\nexport const isTypeIndicatorListItem = (\n message: ChatBodyListItemProps\n): message is TypeIndicatorListItemPops => {\n return message.type === 'typing';\n};\n"]}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import { FunctionComponent
|
|
1
|
+
import { FunctionComponent } from 'react';
|
|
2
2
|
import { ForwardProps } from '@pega/cosmos-react-core';
|
|
3
|
-
import
|
|
4
|
-
export
|
|
5
|
-
/** ref to the element */
|
|
6
|
-
ref?: Ref<HTMLDivElement>;
|
|
7
|
-
/** Message data Array */
|
|
8
|
-
children: ReactElement<typeof MessageList>;
|
|
9
|
-
}
|
|
3
|
+
import { ChatBodyProps } from './Chat.types';
|
|
4
|
+
export declare const NewMessageSeparatorId = "new-message-separator";
|
|
10
5
|
declare const ChatBody: FunctionComponent<ChatBodyProps & ForwardProps>;
|
|
11
6
|
export default ChatBody;
|
|
12
7
|
//# sourceMappingURL=ChatBody.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatBody.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ChatBody.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ChatBody.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ChatBody.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAUlB,MAAM,OAAO,CAAC;AAGf,OAAO,EAKL,YAAY,EAYb,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAGL,aAAa,EAKd,MAAM,cAAc,CAAC;AAQtB,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAuH7D,QAAA,MAAM,QAAQ,EAAE,iBAAiB,CAAC,aAAa,GAAG,YAAY,CA2R7D,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -1,18 +1,292 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { createElement as _createElement } from "react";
|
|
3
|
+
import { forwardRef, useCallback, useImperativeHandle, useLayoutEffect, useRef, useState, useEffect } from 'react';
|
|
4
|
+
import styled, { css } from 'styled-components';
|
|
5
|
+
import { Button, debounce, defaultThemeProp, Flex, getFocusables, Icon, Progress, registerIcon, StyledButton, useAfterInitialEffect, useArrows, useI18n, useItemIntersection, useLiveLog, useOuterEvent } from '@pega/cosmos-react-core';
|
|
6
|
+
import * as caretDownIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/caret-down.icon';
|
|
7
|
+
import { isMessageListItem, isSystemMessageListItem, isTypeIndicatorListItem } from './Chat.types';
|
|
8
|
+
import Message from './Message';
|
|
9
|
+
import SystemMessage, { StyledSystemMessage } from './SystemMessage';
|
|
10
|
+
import TypeIndicator from './TypeIndicator';
|
|
11
|
+
import { StyledMessageContainer } from './Message.styles';
|
|
12
|
+
registerIcon(caretDownIcon);
|
|
13
|
+
export const NewMessageSeparatorId = 'new-message-separator';
|
|
14
|
+
const StyledMessageList = styled.ul ``;
|
|
15
|
+
const StyledSession = styled.div ``;
|
|
16
|
+
const StyledChatBody = styled.div(props => {
|
|
17
|
+
const { theme: { base: { shadow: { high: shadowHigh, focus }, colors: { white }, spacing, palette } } } = props;
|
|
18
|
+
return css `
|
|
19
|
+
position: relative;
|
|
20
|
+
overflow-y: hidden;
|
|
21
|
+
|
|
22
|
+
> ${StyledButton} {
|
|
23
|
+
position: absolute;
|
|
24
|
+
bottom: 0;
|
|
25
|
+
left: 50%;
|
|
26
|
+
transform: translate(-50%, -50%);
|
|
27
|
+
box-shadow: ${shadowHigh};
|
|
28
|
+
z-index: 1;
|
|
29
|
+
background-color: ${white};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
> ${StyledMessageList} {
|
|
33
|
+
overflow-y: auto;
|
|
34
|
+
list-style-type: none;
|
|
35
|
+
height: 100%;
|
|
36
|
+
|
|
37
|
+
> ${StyledSession} {
|
|
38
|
+
padding-inline: 1rem;
|
|
39
|
+
:not(:last-child) {
|
|
40
|
+
border-block-end: 0.0625rem solid ${palette['border-line']};
|
|
41
|
+
margin-block-end: ${spacing};
|
|
42
|
+
padding-block-end: ${spacing};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
${StyledMessageContainer}, ${StyledSystemMessage} {
|
|
46
|
+
&:focus-visible {
|
|
47
|
+
box-shadow: ${focus};
|
|
48
|
+
outline: none;
|
|
49
|
+
}
|
|
50
|
+
margin-block-end: ${spacing};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
`;
|
|
54
|
+
});
|
|
55
|
+
StyledChatBody.defaultProps = defaultThemeProp;
|
|
56
|
+
const ScrollToLatest = props => {
|
|
57
|
+
const { scrollContainerRef } = props;
|
|
58
|
+
useLayoutEffect(() => {
|
|
59
|
+
if (scrollContainerRef.current) {
|
|
60
|
+
scrollContainerRef.current.scrollTop =
|
|
61
|
+
scrollContainerRef.current.scrollHeight - scrollContainerRef.current.offsetHeight;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return null;
|
|
65
|
+
};
|
|
66
|
+
const ChatMessage = ({ agentSerial, message }) => {
|
|
67
|
+
const getAgentVariant = (senderId, senderType, direction = 'in') => {
|
|
68
|
+
if (agentSerial.current === null)
|
|
69
|
+
return undefined;
|
|
70
|
+
if (senderType === 'agent' && direction === 'in') {
|
|
71
|
+
if (agentSerial.current[senderId] !== undefined) {
|
|
72
|
+
return agentSerial.current[senderId];
|
|
73
|
+
}
|
|
74
|
+
const nextIndex = Object.entries(agentSerial.current).length;
|
|
75
|
+
agentSerial.current[senderId] = nextIndex;
|
|
76
|
+
return nextIndex;
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
};
|
|
80
|
+
if (isMessageListItem(message)) {
|
|
81
|
+
const { id, senderType, direction, senderId } = message;
|
|
82
|
+
const agentVariant = getAgentVariant(senderId, senderType, direction);
|
|
83
|
+
return _createElement(Message, { ...message, key: id, agentVariant: agentVariant });
|
|
84
|
+
}
|
|
85
|
+
if (isSystemMessageListItem(message)) {
|
|
86
|
+
const extraProps = {};
|
|
87
|
+
const { id } = message;
|
|
88
|
+
if (id === NewMessageSeparatorId) {
|
|
89
|
+
extraProps['data-new-message-separator'] = NewMessageSeparatorId;
|
|
90
|
+
}
|
|
91
|
+
return _createElement(SystemMessage, { ...message, key: id, ...extraProps });
|
|
92
|
+
}
|
|
93
|
+
if (isTypeIndicatorListItem(message)) {
|
|
94
|
+
const { id, senderId, senderType } = message;
|
|
95
|
+
const agentVariant = getAgentVariant(senderId, senderType);
|
|
96
|
+
return _createElement(TypeIndicator, { ...message, key: id, agentVariant: agentVariant });
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
};
|
|
9
100
|
const ChatBody = forwardRef((props, ref) => {
|
|
10
|
-
const {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
101
|
+
const { transcripts, liveChat, unreadMessageCount = 0, onScrollToButtonClick, handle, loading, offset = -1, loadMore, ...restProps } = props;
|
|
102
|
+
const t = useI18n();
|
|
103
|
+
const conversationRef = useRef(null);
|
|
104
|
+
const scrollRef = useRef(false);
|
|
105
|
+
const buttonRef = useRef(null);
|
|
106
|
+
const focusInMessageList = useRef(false);
|
|
107
|
+
const initialMessageListFocused = useRef(false);
|
|
108
|
+
const elementRef = useRef(null);
|
|
109
|
+
const activeElementIndex = useRef(-1);
|
|
110
|
+
const agentSerial = useRef({});
|
|
111
|
+
const [messageList, setMessageList] = useState([]);
|
|
112
|
+
const [verticalNav, setVerticalNav] = useState(true);
|
|
113
|
+
const { announcePolite } = useLiveLog();
|
|
114
|
+
const isScrolledToLatest = useCallback(() => {
|
|
115
|
+
return conversationRef.current
|
|
116
|
+
? conversationRef.current.scrollHeight -
|
|
117
|
+
conversationRef.current.scrollTop -
|
|
118
|
+
conversationRef.current.offsetHeight <=
|
|
119
|
+
30
|
|
120
|
+
: true;
|
|
121
|
+
}, [conversationRef.current]);
|
|
122
|
+
const scrollToLatestMessage = useCallback(() => {
|
|
123
|
+
if (conversationRef.current) {
|
|
124
|
+
conversationRef.current.scrollTop = conversationRef.current.scrollHeight;
|
|
125
|
+
focusInMessageList.current = true;
|
|
126
|
+
messageList[messageList.length - 1]?.focus();
|
|
127
|
+
activeElementIndex.current = messageList.length - 1;
|
|
128
|
+
}
|
|
129
|
+
}, [conversationRef.current, messageList]);
|
|
130
|
+
const [displayScrollLatest, setDisplayScrollToLatest] = useState(false);
|
|
131
|
+
const onMessageListScroll = useCallback(() => {
|
|
132
|
+
const isScrolled = isScrolledToLatest();
|
|
133
|
+
if (scrollRef.current && isScrolled) {
|
|
134
|
+
scrollRef.current = false;
|
|
135
|
+
if (unreadMessageCount) {
|
|
136
|
+
onScrollToButtonClick?.();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (!scrollRef.current && !isScrolled) {
|
|
140
|
+
scrollRef.current = true;
|
|
141
|
+
}
|
|
142
|
+
setDisplayScrollToLatest(!isScrolled);
|
|
143
|
+
}, [isScrolledToLatest(), unreadMessageCount]);
|
|
144
|
+
const scrollToNewMessage = useCallback(() => {
|
|
145
|
+
if (conversationRef.current) {
|
|
146
|
+
setDisplayScrollToLatest(false);
|
|
147
|
+
const newMessageIndicatorEle = conversationRef.current.querySelector('[data-new-message-separator]');
|
|
148
|
+
if (newMessageIndicatorEle &&
|
|
149
|
+
newMessageIndicatorEle.nextElementSibling instanceof HTMLElement) {
|
|
150
|
+
conversationRef.current.scrollTop = newMessageIndicatorEle.offsetTop;
|
|
151
|
+
focusInMessageList.current = true;
|
|
152
|
+
newMessageIndicatorEle.nextElementSibling.focus();
|
|
153
|
+
activeElementIndex.current =
|
|
154
|
+
messageList.findIndex(item => item?.hasAttribute('data-new-message-separator')) + 1;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
scrollToLatestMessage();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}, [conversationRef.current, messageList]);
|
|
161
|
+
useImperativeHandle(handle, () => ({
|
|
162
|
+
isScrolledToLatest,
|
|
163
|
+
scrollToLatestMessage,
|
|
164
|
+
scrollToNewMessage
|
|
165
|
+
}), [isScrolledToLatest, scrollToLatestMessage, scrollToNewMessage]);
|
|
166
|
+
useItemIntersection(conversationRef, offset, () => {
|
|
167
|
+
loadMore?.();
|
|
168
|
+
}, ':scope > div > li');
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
const focusableElements = conversationRef.current?.querySelectorAll('li[type="system"],li[type="message"],li[type="typing"]');
|
|
171
|
+
if (focusableElements)
|
|
172
|
+
setMessageList(Array.from(focusableElements));
|
|
173
|
+
if (focusableElements && initialMessageListFocused.current === false) {
|
|
174
|
+
activeElementIndex.current = focusableElements.length - 1;
|
|
175
|
+
}
|
|
176
|
+
}, [transcripts, liveChat]);
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
elementRef.current = messageList[activeElementIndex.current];
|
|
179
|
+
if (verticalNav) {
|
|
180
|
+
elementRef.current?.focus();
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
getFocusables(elementRef)[0]?.focus();
|
|
184
|
+
}
|
|
185
|
+
}, [verticalNav]);
|
|
186
|
+
useArrows(conversationRef, {
|
|
187
|
+
cycle: true,
|
|
188
|
+
selector: ':scope > div > li',
|
|
189
|
+
dir: 'up-down',
|
|
190
|
+
allowTabFocus: true
|
|
191
|
+
}, [transcripts, liveChat]);
|
|
192
|
+
useArrows(elementRef, {
|
|
193
|
+
cycle: true,
|
|
194
|
+
selector: 'a, button, input, textarea, select, details',
|
|
195
|
+
dir: 'left-right',
|
|
196
|
+
allowTabFocus: true
|
|
197
|
+
}, [transcripts, liveChat, verticalNav]);
|
|
198
|
+
const focusSiblingElement = (currentElement, isShiftKey = false) => {
|
|
199
|
+
elementRef.current = currentElement;
|
|
200
|
+
const focusableElements = getFocusables(elementRef);
|
|
201
|
+
if (focusableElements?.length > 0) {
|
|
202
|
+
focusableElements?.[isShiftKey ? focusableElements.length - 1 : 0].focus();
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
const element = isShiftKey
|
|
206
|
+
? elementRef.current?.previousElementSibling
|
|
207
|
+
: elementRef.current?.nextElementSibling;
|
|
208
|
+
if (element)
|
|
209
|
+
focusSiblingElement(element, isShiftKey);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
useOuterEvent('mousedown', [conversationRef], () => {
|
|
213
|
+
focusInMessageList.current = false;
|
|
214
|
+
});
|
|
215
|
+
useAfterInitialEffect(() => {
|
|
216
|
+
if (liveChat?.length > 0) {
|
|
217
|
+
const unreadMessage = liveChat[liveChat.length - 1];
|
|
218
|
+
if (isSystemMessageListItem(unreadMessage) ||
|
|
219
|
+
(isMessageListItem(unreadMessage) && unreadMessage.direction === 'in')) {
|
|
220
|
+
announcePolite({
|
|
221
|
+
message: t('new_message'),
|
|
222
|
+
type: 'alert'
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}, [liveChat]);
|
|
227
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Flex, { ...restProps, as: StyledChatBody, item: {
|
|
228
|
+
grow: 1
|
|
229
|
+
}, container: {
|
|
230
|
+
direction: 'column'
|
|
231
|
+
}, ref: ref, children: [_jsxs(StyledMessageList, { ref: conversationRef, onScroll: debounce(onMessageListScroll, 100), onFocus: () => {
|
|
232
|
+
if (!focusInMessageList.current) {
|
|
233
|
+
initialMessageListFocused.current = true;
|
|
234
|
+
elementRef.current = messageList[activeElementIndex.current];
|
|
235
|
+
elementRef.current?.focus();
|
|
236
|
+
focusInMessageList.current = true;
|
|
237
|
+
}
|
|
238
|
+
}, onKeyDown: e => {
|
|
239
|
+
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
|
|
240
|
+
elementRef.current = messageList[activeElementIndex.current];
|
|
241
|
+
if (getFocusables(elementRef).length > 0) {
|
|
242
|
+
setVerticalNav(false);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
|
|
246
|
+
if (e.key === 'ArrowUp') {
|
|
247
|
+
activeElementIndex.current =
|
|
248
|
+
activeElementIndex.current === 0
|
|
249
|
+
? messageList.length - 1
|
|
250
|
+
: activeElementIndex.current - 1;
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
activeElementIndex.current =
|
|
254
|
+
activeElementIndex.current === messageList.length - 1
|
|
255
|
+
? 0
|
|
256
|
+
: activeElementIndex.current + 1;
|
|
257
|
+
}
|
|
258
|
+
setVerticalNav(true);
|
|
259
|
+
}
|
|
260
|
+
else if (e.key === 'Tab') {
|
|
261
|
+
e.preventDefault();
|
|
262
|
+
focusInMessageList.current = false;
|
|
263
|
+
if (e.shiftKey) {
|
|
264
|
+
const prevElement = conversationRef?.current?.parentElement?.previousElementSibling;
|
|
265
|
+
if (prevElement)
|
|
266
|
+
focusSiblingElement(prevElement, true);
|
|
267
|
+
}
|
|
268
|
+
else if (unreadMessageCount > 0 || displayScrollLatest) {
|
|
269
|
+
buttonRef?.current?.focus();
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
const nextElement = conversationRef.current?.parentElement?.nextElementSibling;
|
|
273
|
+
if (nextElement)
|
|
274
|
+
focusSiblingElement(nextElement);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}, children: [loading && _jsx(Progress, { as: 'li', placement: 'block' }), transcripts.map(session => {
|
|
278
|
+
return (_jsx(StyledSession, { children: session.messages.map(message => (_jsx(ChatMessage, { message: message, agentSerial: agentSerial }, message.id))) }, session.id));
|
|
279
|
+
}), _jsx(StyledSession, { children: liveChat.map(message => (_jsx(ChatMessage, { message: message, agentSerial: agentSerial }, message.id))) })] }), (unreadMessageCount > 0 || displayScrollLatest) && (_jsxs(Button, { "aria-label": unreadMessageCount > 0
|
|
280
|
+
? t('scroll_to_unread_messages')
|
|
281
|
+
: t('scroll_to_latest_message'), onClick: () => {
|
|
282
|
+
if (unreadMessageCount > 0) {
|
|
283
|
+
scrollToNewMessage();
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
scrollToLatestMessage();
|
|
287
|
+
}
|
|
288
|
+
onScrollToButtonClick?.();
|
|
289
|
+
}, icon: unreadMessageCount === 0, ref: buttonRef, children: [_jsx(Icon, { name: 'caret-down' }), unreadMessageCount > 0 && _jsxs(_Fragment, { children: ["\u00A0 ", t('new_messages')] })] }))] }), isScrolledToLatest() && _jsx(ScrollToLatest, { scrollContainerRef: conversationRef })] }));
|
|
16
290
|
});
|
|
17
291
|
export default ChatBody;
|
|
18
292
|
//# sourceMappingURL=ChatBody.js.map
|