botframework-webchat-fluent-theme 4.17.1-main.20240708.c9247bf → 4.18.1-main.20240807.dfe788c

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 (27) hide show
  1. package/dist/botframework-webchat-fluent-theme.css.map +1 -1
  2. package/dist/botframework-webchat-fluent-theme.development.css.map +1 -1
  3. package/dist/botframework-webchat-fluent-theme.development.js +1 -1
  4. package/dist/botframework-webchat-fluent-theme.development.js.map +1 -1
  5. package/dist/botframework-webchat-fluent-theme.js +1 -1
  6. package/dist/botframework-webchat-fluent-theme.js.map +1 -1
  7. package/dist/botframework-webchat-fluent-theme.mjs +1 -1
  8. package/dist/botframework-webchat-fluent-theme.mjs.map +1 -1
  9. package/dist/botframework-webchat-fluent-theme.production.min.css.map +1 -1
  10. package/dist/botframework-webchat-fluent-theme.production.min.js +1 -1
  11. package/dist/botframework-webchat-fluent-theme.production.min.js.map +1 -1
  12. package/package.json +6 -5
  13. package/src/components/preChatActivity/PreChatMessageActivity.module.css +34 -0
  14. package/src/components/preChatActivity/PreChatMessageActivity.tsx +35 -0
  15. package/src/components/preChatActivity/StarterPromptsCardAction.module.css +58 -0
  16. package/src/components/preChatActivity/StarterPromptsCardAction.tsx +62 -0
  17. package/src/components/preChatActivity/StarterPromptsToolbar.module.css +18 -0
  18. package/src/components/preChatActivity/StarterPromptsToolbar.tsx +35 -0
  19. package/src/components/preChatActivity/index.tsx +2 -0
  20. package/src/components/preChatActivity/isPreChatMessageActivity.ts +26 -0
  21. package/src/components/preChatActivity/private/MonochromeImageMasker.module.css +5 -0
  22. package/src/components/preChatActivity/private/MonochromeImageMasker.tsx +19 -0
  23. package/src/components/sendBox/SendBox.tsx +1 -1
  24. package/src/components/suggestedActions/SuggestedActions.tsx +46 -43
  25. package/src/components/theme/Theme.module.css +23 -5
  26. package/src/components/theme/Theme.tsx +1 -1
  27. package/src/private/FluentThemeProvider.tsx +19 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botframework-webchat-fluent-theme",
3
- "version": "4.17.1-main.20240708.c9247bf",
3
+ "version": "4.18.1-main.20240807.dfe788c",
4
4
  "description": "Fluent theme for Bot Framework Web Chat",
5
5
  "main": "./dist/botframework-webchat-fluent-theme.js",
6
6
  "types": "./dist/botframework-webchat-fluent-theme.d.ts",
@@ -69,13 +69,14 @@
69
69
  "typescript": "^5.4.5"
70
70
  },
71
71
  "dependencies": {
72
- "botframework-webchat-api": "4.17.1-main.20240708.c9247bf",
73
- "botframework-webchat-component": "4.17.1-main.20240708.c9247bf",
74
- "botframework-webchat-core": "4.17.1-main.20240708.c9247bf",
72
+ "botframework-webchat-api": "4.18.1-main.20240807.dfe788c",
73
+ "botframework-webchat-component": "4.18.1-main.20240807.dfe788c",
74
+ "botframework-webchat-core": "4.18.1-main.20240807.dfe788c",
75
75
  "classnames": "2.5.1",
76
76
  "inject-meta-tag": "0.0.1",
77
77
  "math-random": "2.0.1",
78
- "use-ref-from": "0.1.0"
78
+ "use-ref-from": "0.1.0",
79
+ "valibot": "^0.37.0"
79
80
  },
80
81
  "peerDependencies": {
81
82
  "react": ">= 16.8.6"
@@ -0,0 +1,34 @@
1
+ :global(.webchat-fluent) .pre-chat-message-activity {
2
+ display: grid;
3
+ grid-template-areas: 'body' 'toolbar';
4
+ grid-template-rows: auto auto;
5
+ gap: var(--webchat-spacingHorizontalXXXL);
6
+ padding: var(--webchat-spacingHorizontalXXXL);
7
+ }
8
+
9
+ :global(.webchat-fluent) .pre-chat-message-activity__body {
10
+ font-family: var(--webchat-fontFamilyBase);
11
+ font-size: var(--webchat-fontSizeBase300);
12
+ font-weight: var(--webchat-fontWeightRegular);
13
+ grid-area: body;
14
+ line-height: var(--webchat-lineHeightBase300);
15
+ text-align: center;
16
+ }
17
+
18
+ :global(.webchat-fluent) .pre-chat-message-activity__body h2 {
19
+ color: var(--webchat-colorNeutralForeground1);
20
+ font-family: inherit;
21
+ font-weight: var(--webchat-fontWeightSemibold);
22
+ font-size: var(--webchat-fontSizeHero700);
23
+ line-height: var(--webchat-lineHeightHero700);
24
+ margin: var(--webchat-spacingVerticalL) 0 0;
25
+ }
26
+
27
+ :global(.webchat-fluent) .pre-chat-message-activity__body img {
28
+ border-radius: 4px;
29
+ height: 64px;
30
+ }
31
+
32
+ :global(.webchat-fluent) .pre-chat-message-activity__toolbar {
33
+ grid-area: toolbar;
34
+ }
@@ -0,0 +1,35 @@
1
+ import { hooks } from 'botframework-webchat-component';
2
+ import { type WebChatActivity } from 'botframework-webchat-core';
3
+ import React, { memo, useMemo } from 'react';
4
+ import { useStyles } from '../../styles/index.js';
5
+ import styles from './PreChatMessageActivity.module.css';
6
+ import StarterPromptsToolbar from './StarterPromptsToolbar.js';
7
+
8
+ type Props = Readonly<{ activity: WebChatActivity & { type: 'message' } }>;
9
+
10
+ const { useRenderMarkdownAsHTML } = hooks;
11
+
12
+ const PreChatMessageActivity = ({ activity }: Props) => {
13
+ const classNames = useStyles(styles);
14
+ const renderMarkdownAsHTML = useRenderMarkdownAsHTML();
15
+
16
+ const html = useMemo(
17
+ () => (renderMarkdownAsHTML ? { __html: renderMarkdownAsHTML(activity.text || '') } : { __html: '' }),
18
+ [activity.text, renderMarkdownAsHTML]
19
+ );
20
+
21
+ return (
22
+ <div className={classNames['pre-chat-message-activity']}>
23
+ {/* eslint-disable-next-line react/no-danger */}
24
+ <div className={classNames['pre-chat-message-activity__body']} dangerouslySetInnerHTML={html} />
25
+ <StarterPromptsToolbar
26
+ cardActions={activity.suggestedActions?.actions || []}
27
+ className={classNames['pre-chat-message-activity__toolbar']}
28
+ />
29
+ </div>
30
+ );
31
+ };
32
+
33
+ PreChatMessageActivity.displayName = 'PreChatMessageActivity';
34
+
35
+ export default memo(PreChatMessageActivity);
@@ -0,0 +1,58 @@
1
+ :global(.webchat-fluent) .pre-chat-message-activity__card-action-box {
2
+ appearance: none;
3
+ background-color: var(--webchat-colorNeutralBackground1);
4
+ border: 0;
5
+ border-radius: 16px;
6
+ box-shadow: var(--webchat-shadow2);
7
+ color: var(--webchat-colorNeutralForeground1);
8
+ cursor: pointer;
9
+ display: grid;
10
+ gap: 8px;
11
+ grid-template-areas: 'image title' 'image subtitle';
12
+ grid-template-columns: 20px 1fr;
13
+ grid-template-rows: auto 1fr;
14
+ overflow: hidden;
15
+ padding: 16px 20px;
16
+ text-align: left;
17
+ user-select: none;
18
+ }
19
+
20
+ :global(.webchat-fluent) .pre-chat-message-activity__card-action-box:disabled {
21
+ background-color: var(--webchat-colorNeutralBackground1Disabled);
22
+ }
23
+
24
+ :global(.webchat-fluent) .pre-chat-message-activity__card-action-box:hover {
25
+ background-color: var(--webchat-colorNeutralGrey94);
26
+ }
27
+
28
+ :global(.webchat-fluent) .pre-chat-message-activity__card-action-box:active {
29
+ background-color: var(--webchat-colorNeutralBackground1Pressed);
30
+ }
31
+
32
+ :global(.webchat-fluent) .pre-chat-message-activity__card-action-box:focus-visible {
33
+ outline: solid 2px var(--webchat-colorStrokeFocus2);
34
+ outline-offset: -2px;
35
+ }
36
+
37
+ :global(.webchat-fluent) .pre-chat-message-activity__card-action-image {
38
+ grid-area: image;
39
+ height: 20px;
40
+ width: 20px;
41
+ }
42
+
43
+ :global(.webchat-fluent) .pre-chat-message-activity__card-action-subtitle {
44
+ font-family: var(--webchat-fontFamilyBase);
45
+ font-size: 14px;
46
+ font-weight: var(--webchat-fontWeightRegular);
47
+ grid-area: subtitle;
48
+ line-height: 20px;
49
+ pointer-events: none; /* Links in subtitle are not clickable. */
50
+ }
51
+
52
+ :global(.webchat-fluent) .pre-chat-message-activity__card-action-title {
53
+ font-family: var(--webchat-fontFamilyBase);
54
+ font-size: 14px;
55
+ font-weight: var(--webchat-fontWeightSemibold);
56
+ grid-area: title;
57
+ line-height: 20px;
58
+ }
@@ -0,0 +1,62 @@
1
+ import { hooks } from 'botframework-webchat-component';
2
+ import { type DirectLineCardAction } from 'botframework-webchat-core';
3
+ import cx from 'classnames';
4
+ import React, { memo, useCallback, useMemo } from 'react';
5
+ import { useRefFrom } from 'use-ref-from';
6
+ import { useStyles } from '../../styles/index.js';
7
+ import MonochromeImageMasker from './private/MonochromeImageMasker.js';
8
+ import styles from './StarterPromptsCardAction.module.css';
9
+
10
+ const { useFocus, useRenderMarkdownAsHTML, useSendBoxValue } = hooks;
11
+
12
+ type Props = Readonly<{
13
+ className?: string | undefined;
14
+ messageBackAction: DirectLineCardAction & { type: 'messageBack' };
15
+ }>;
16
+
17
+ const StarterPromptAction = ({ className, messageBackAction }: Props) => {
18
+ const [_, setSendBoxValue] = useSendBoxValue();
19
+ const classNames = useStyles(styles);
20
+ const focus = useFocus();
21
+ const inputTextRef = useRefFrom(messageBackAction.displayText || messageBackAction.text || '');
22
+ const renderMarkdownAsHTML = useRenderMarkdownAsHTML('message activity');
23
+ const subtitleHTML = useMemo(
24
+ () => (renderMarkdownAsHTML ? { __html: renderMarkdownAsHTML(messageBackAction.text || '') } : { __html: '' }),
25
+ [messageBackAction.text, renderMarkdownAsHTML]
26
+ );
27
+
28
+ const handleClick = useCallback(() => {
29
+ setSendBoxValue(inputTextRef.current);
30
+
31
+ // Focus on the send box after the value is "pasted."
32
+ focus('sendBox');
33
+ }, [focus, inputTextRef, setSendBoxValue]);
34
+
35
+ return (
36
+ <button
37
+ className={cx(className, classNames['pre-chat-message-activity__card-action-box'])}
38
+ onClick={handleClick}
39
+ type="button"
40
+ >
41
+ <div className={classNames['pre-chat-message-activity__card-action-title']}>
42
+ {'title' in messageBackAction && messageBackAction.title}
43
+ </div>
44
+ {'image' in messageBackAction && messageBackAction.image && (
45
+ <MonochromeImageMasker
46
+ className={classNames['pre-chat-message-activity__card-action-image']}
47
+ src={messageBackAction.image}
48
+ />
49
+ // <img className="pre-chat-message-activity__card-action-image" src={messageBackAction.image} />
50
+ )}
51
+ <div
52
+ className={classNames['pre-chat-message-activity__card-action-subtitle']}
53
+ // eslint-disable-next-line react/no-danger
54
+ dangerouslySetInnerHTML={subtitleHTML}
55
+ />
56
+ </button>
57
+ );
58
+ };
59
+
60
+ StarterPromptAction.displayName = 'StarterPromptAction';
61
+
62
+ export default memo(StarterPromptAction);
@@ -0,0 +1,18 @@
1
+ :global(.webchat-fluent) .pre-chat-message-activity__card-action-toolbar {
2
+ container-name: webchat-container;
3
+ container-type: inline-size;
4
+ }
5
+
6
+ :global(.webchat-fluent) .pre-chat-message-activity__card-action-toolbar-grid {
7
+ display: grid;
8
+ gap: var(--webchat-spacingHorizontalM);
9
+ grid-template-columns: 1fr 1fr 1fr;
10
+ padding: 0;
11
+ }
12
+
13
+ /* TODO: What is the good width to show as 3 columns? Web Chat, by default, has a bubble max width of 480px. */
14
+ @container webchat-container (width <= 480px) {
15
+ :global(.webchat-fluent) .pre-chat-message-activity__card-action-toolbar-grid {
16
+ grid-template-columns: 1fr;
17
+ }
18
+ }
@@ -0,0 +1,35 @@
1
+ import { type DirectLineCardAction } from 'botframework-webchat-core';
2
+ import cx from 'classnames';
3
+ import React, { memo } from 'react';
4
+ import { useStyles } from '../../styles/index.js';
5
+ import StarterPromptsCardAction from './StarterPromptsCardAction.js';
6
+ import styles from './StarterPromptsToolbar.module.css';
7
+
8
+ type Props = Readonly<{
9
+ cardActions: readonly DirectLineCardAction[];
10
+ className?: string | undefined;
11
+ }>;
12
+
13
+ const StarterPrompts = ({ cardActions, className }: Props) => {
14
+ const classNames = useStyles(styles);
15
+
16
+ return (
17
+ // TODO: Accessibility-wise, this should be role="toolbar" with keyboard navigation.
18
+ <div className={cx(className, classNames['pre-chat-message-activity__card-action-toolbar'])}>
19
+ <div className={classNames['pre-chat-message-activity__card-action-toolbar-grid']}>
20
+ {cardActions
21
+ .filter<DirectLineCardAction & { type: 'messageBack' }>(
22
+ (card: DirectLineCardAction): card is DirectLineCardAction & { type: 'messageBack' } =>
23
+ card.type === 'messageBack'
24
+ )
25
+ .map(cardAction => (
26
+ <StarterPromptsCardAction key={cardAction.text} messageBackAction={cardAction} />
27
+ ))}
28
+ </div>
29
+ </div>
30
+ );
31
+ };
32
+
33
+ StarterPrompts.displayName = 'StarterPrompts';
34
+
35
+ export default memo(StarterPrompts);
@@ -0,0 +1,2 @@
1
+ export { default as isPreChatMessageActivity } from './isPreChatMessageActivity.js';
2
+ export { default as PreChatMessageActivity } from './PreChatMessageActivity.js';
@@ -0,0 +1,26 @@
1
+ import type { WebChatActivity } from 'botframework-webchat-core';
2
+ import { array, literal, object, safeParse, string, type InferOutput } from 'valibot';
3
+
4
+ const messageEntity = object({
5
+ '@context': literal('https://schema.org'),
6
+ '@id': literal(''), // Must be empty string.
7
+ '@type': literal('Message'),
8
+ keywords: array(string()),
9
+ type: literal('https://schema.org/Message')
10
+ });
11
+
12
+ type MessageEntity = InferOutput<typeof messageEntity>;
13
+
14
+ export default function isPreChatMessageActivity(
15
+ activity: undefined | WebChatActivity
16
+ ): activity is WebChatActivity & { type: 'message' } {
17
+ if (activity?.type !== 'message') {
18
+ return false;
19
+ }
20
+
21
+ const message = activity.entities?.find(
22
+ (entity): entity is MessageEntity => safeParse(messageEntity, entity).success
23
+ );
24
+
25
+ return !!message?.keywords.includes('PreChatMessage');
26
+ }
@@ -0,0 +1,5 @@
1
+ :global(.webchat-fluent) .pre-chat-message-activity__monochrome-image-masker {
2
+ background-color: var(--webchat-colorNeutralForeground4);
3
+ mask-image: var(--mask-image);
4
+ --webkit-mask-image: var(--mask-image);
5
+ }
@@ -0,0 +1,19 @@
1
+ import cx from 'classnames';
2
+ import React, { memo, useMemo, type CSSProperties } from 'react';
3
+ import { useStyles } from '../../../styles/index.js';
4
+ import styles from './MonochromeImageMasker.module.css';
5
+
6
+ type Props = Readonly<{ className?: string | undefined; src: string }>;
7
+
8
+ const MonochromeImageMasker = ({ className, src }: Props) => {
9
+ const classNames = useStyles(styles);
10
+ const style = useMemo(() => ({ '--mask-image': `url(${src})` }) as CSSProperties, [src]);
11
+
12
+ return (
13
+ <div className={cx(className, classNames['pre-chat-message-activity__monochrome-image-masker'])} style={style} />
14
+ );
15
+ };
16
+
17
+ MonochromeImageMasker.displayName = 'MonochromeImageMasker';
18
+
19
+ export default memo(MonochromeImageMasker);
@@ -183,7 +183,7 @@ function SendBox(
183
183
  />
184
184
  <Attachments attachments={attachments} className={classNames['sendbox__attachment--in-grid']} />
185
185
  <div className={cx(classNames['sendbox__sendbox-controls'], classNames['sendbox__sendbox-controls--in-grid'])}>
186
- {!telephoneKeypadShown && maxMessageLength && (
186
+ {!telephoneKeypadShown && maxMessageLength && isFinite(maxMessageLength) && (
187
187
  <div
188
188
  className={cx(classNames['sendbox__text-counter'], {
189
189
  [classNames['sendbox__text-counter--error']]: isMessageLengthExceeded
@@ -1,11 +1,12 @@
1
1
  import { hooks } from 'botframework-webchat-component';
2
2
  import cx from 'classnames';
3
3
  import React, { memo, useCallback, type ReactNode } from 'react';
4
- import SuggestedAction from './SuggestedAction';
5
- import computeSuggestedActionText from './private/computeSuggestedActionText';
6
- import styles from './SuggestedActions.module.css';
7
4
  import { useStyles } from '../../styles';
5
+ import { isPreChatMessageActivity } from '../preChatActivity';
6
+ import computeSuggestedActionText from './private/computeSuggestedActionText';
8
7
  import RovingFocusProvider from './private/rovingFocus';
8
+ import SuggestedAction from './SuggestedAction';
9
+ import styles from './SuggestedActions.module.css';
9
10
 
10
11
  const { useFocus, useLocalizer, useStyleOptions, useStyleSet, useSuggestedActions } = hooks;
11
12
 
@@ -44,54 +45,56 @@ function SuggestedActionStackedOrFlowContainer(
44
45
  function SuggestedActions() {
45
46
  const classNames = useStyles(styles);
46
47
  const localize = useLocalizer();
47
- const [suggestedActions] = useSuggestedActions();
48
+ const [suggestedActions, _, { activity }] = useSuggestedActions();
48
49
  const focus = useFocus();
49
50
 
50
51
  const handleEscapeKey = useCallback(() => {
51
52
  focus('sendBox');
52
53
  }, [focus]);
53
54
 
54
- const children = suggestedActions.map((cardAction, index) => {
55
- const { displayText, image, imageAltText, text, type, value } = cardAction as {
56
- displayText?: string;
57
- image?: string;
58
- imageAltText?: string;
59
- text?: string;
60
- type:
61
- | 'call'
62
- | 'downloadFile'
63
- | 'imBack'
64
- | 'messageBack'
65
- | 'openUrl'
66
- | 'playAudio'
67
- | 'playVideo'
68
- | 'postBack'
69
- | 'showImage'
70
- | 'signin';
71
- value?: { [key: string]: any } | string;
72
- };
55
+ const children = isPreChatMessageActivity(activity)
56
+ ? [] // Do not show suggested actions for pre-chat message, suggested actions has already shown inlined.
57
+ : suggestedActions.map((cardAction, index) => {
58
+ const { displayText, image, imageAltText, text, type, value } = cardAction as {
59
+ displayText?: string;
60
+ image?: string;
61
+ imageAltText?: string;
62
+ text?: string;
63
+ type:
64
+ | 'call'
65
+ | 'downloadFile'
66
+ | 'imBack'
67
+ | 'messageBack'
68
+ | 'openUrl'
69
+ | 'playAudio'
70
+ | 'playVideo'
71
+ | 'postBack'
72
+ | 'showImage'
73
+ | 'signin';
74
+ value?: { [key: string]: any } | string;
75
+ };
73
76
 
74
- if (!suggestedActions?.length) {
75
- return null;
76
- }
77
+ if (!suggestedActions?.length) {
78
+ return null;
79
+ }
77
80
 
78
- return (
79
- <SuggestedAction
80
- buttonText={computeSuggestedActionText(cardAction)}
81
- displayText={displayText}
82
- image={image}
83
- // Image alt text should use `imageAltText` field and fallback to `text` field.
84
- // https://github.com/microsoft/botframework-sdk/blob/main/specs/botframework-activity/botframework-activity.md#image-alt-text
85
- imageAlt={image && (imageAltText || text)}
86
- itemIndex={index}
87
- // eslint-disable-next-line react/no-array-index-key
88
- key={index}
89
- text={text}
90
- type={type}
91
- value={value}
92
- />
93
- );
94
- });
81
+ return (
82
+ <SuggestedAction
83
+ buttonText={computeSuggestedActionText(cardAction)}
84
+ displayText={displayText}
85
+ image={image}
86
+ // Image alt text should use `imageAltText` field and fallback to `text` field.
87
+ // https://github.com/microsoft/botframework-sdk/blob/main/specs/botframework-activity/botframework-activity.md#image-alt-text
88
+ imageAlt={image && (imageAltText || text)}
89
+ itemIndex={index}
90
+ // eslint-disable-next-line react/no-array-index-key
91
+ key={index}
92
+ text={text}
93
+ type={type}
94
+ value={value}
95
+ />
96
+ );
97
+ });
95
98
 
96
99
  return (
97
100
  <RovingFocusProvider onEscapeKey={handleEscapeKey}>
@@ -1,4 +1,3 @@
1
-
2
1
  :global(.webchat-fluent).theme {
3
2
  display: contents;
4
3
 
@@ -16,10 +15,15 @@
16
15
  --webchat-colorNeutralBackground4: var(--colorNeutralBackground4, #f0f0f0);
17
16
  --webchat-colorNeutralBackground5: var(--colorNeutralBackground5, #ebebeb);
18
17
 
18
+ --webchat-colorNeutralBackground1Disabled: var(--colorNeutralBackground1Disabled, #f0f0f0);
19
+ --webchat-colorNeutralBackground1Pressed: var(--colorNeutralBackground1Pressed, #e0e0e0);
20
+
21
+ --webchat-colorNeutralGrey94: var(--colorNeutralGrey94, #f0f0f0);
22
+
19
23
  --webchat-colorNeutralStroke1: var(--colorNeutralStroke1, #d1d1d1);
20
24
  --webchat-colorNeutralStroke2: var(--colorNeutralStroke2, #e0e0e0);
21
25
  --webchat-colorNeutralStroke1Selected: var(--colorNeutralStroke1Selected, #bdbdbd);
22
-
26
+
23
27
  --webchat-colorStrokeFocus2: var(--colorStrokeFocus2, #000000);
24
28
 
25
29
  --webchat-colorBrandStroke2: var(--colorBrandStroke2, #9edcf7);
@@ -30,7 +34,7 @@
30
34
  --webchat-colorBrandForegroundLink: var(--colorBrandForegroundLink, #01678c);
31
35
  --webchat-colorBrandForegroundLinkHover: var(--colorBrandForegroundLinkHover, #015a7a);
32
36
  --webchat-colorBrandForegroundLinkPressed: var(--colorBrandForegroundLinkPressed, #014259);
33
- --webchat-colorBrandForegroundLinkSelected: var(--colorBrandForegroundLinkSelected, #01678c);
37
+ --webchat-colorBrandForegroundLinkSelected: var(--colorBrandForegroundLinkSelected, #01678c);
34
38
 
35
39
  --webchat-colorBrandBackground2Hover: var(--colorBrandBackground2Hover, #bee7fa);
36
40
  --webchat-colorBrandBackground2Pressed: var(--colorBrandBackground2Pressed, #7fd2f5);
@@ -55,14 +59,25 @@
55
59
 
56
60
  /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/spacings.ts */
57
61
  --webchat-spacingHorizontalMNudge: var(--spacingHorizontalMNudge, 10px);
62
+ --webchat-spacingHorizontalM: var(--spacingHorizontalM, 12px);
63
+ --webchat-spacingHorizontalXXXL: var(--spacingHorizontalXXXL, 32px);
64
+ --webchat-spacingVerticalL: var(--spacingVerticalL, 16px);
58
65
 
59
66
  /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/fonts.ts */
60
67
  --webchat-fontFamilyBase: var(--fontFamilyBase, 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif);
61
68
  --webchat-fontFamilyNumeric: var(--fontFamilyNumeric, Bahnschrift, 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif);
62
69
 
63
70
  /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/fonts.ts */
71
+ --webchat-fontWeightRegular: var(--fontWeightRegular, 400);
64
72
  --webchat-fontWeightSemibold: var(--fontWeightSemibold, 600);
65
-
73
+
74
+ /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/fonts.ts */
75
+ --webchat-fontSizeBase300: var(--fontSizeBase300, 14px);
76
+ --webchat-fontSizeHero700: var(--fontSizeHero700, 28px);
77
+
78
+ --webchat-lineHeightBase300: var(--lineHeightBase300, 20px);
79
+ --webchat-lineHeightHero700: var(--lineHeightHero700, 36px);
80
+
66
81
  --webchat-strokeWidthThicker: var(--strokeWidthThicker, 3px);
67
82
 
68
83
  --webchat-durationUltraFast: var(--durationUltraFast, 0);
@@ -70,6 +85,9 @@
70
85
 
71
86
  --webchat-curveAccelerateMid: var(--curveAccelerateMid, cubic-bezier(1,0,1,1));
72
87
  --webchat-curveDecelerateMid: var(--curveDecelerateMid, cubic-bezier(0,0,0,1));
88
+
89
+ /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/utils/shadows.ts */
90
+ --webchat-shadow2: 0 0 2px rgba(0, 0, 0, 12%), 0 1px 2px rgba(0, 0, 0, 14%);
73
91
  }
74
92
 
75
93
  @media (prefers-reduced-motion) {
@@ -77,4 +95,4 @@
77
95
  --webchat-durationUltraFast: 0.01ms;
78
96
  --webchat-durationNormal: 0.01ms;
79
97
  }
80
- }
98
+ }
@@ -5,7 +5,7 @@ import { useStyles } from '../../styles';
5
5
 
6
6
  export const rootClassName = 'webchat-fluent';
7
7
 
8
- export default function WebchatTheme(props: Readonly<{ readonly children: ReactNode | undefined }>) {
8
+ export default function Theme(props: Readonly<{ readonly children: ReactNode | undefined }>) {
9
9
  const classNames = useStyles(styles);
10
10
  return <div className={cx(rootClassName, classNames['theme'])}>{props.children}</div>;
11
11
  }
@@ -1,20 +1,37 @@
1
1
  import { Components } from 'botframework-webchat-component';
2
2
  import React, { memo, type ReactNode } from 'react';
3
3
 
4
+ import type { ActivityMiddleware } from 'botframework-webchat-api';
5
+ import { isPreChatMessageActivity, PreChatMessageActivity } from '../components/preChatActivity';
6
+ import { SendBox } from '../components/sendBox';
4
7
  import { TelephoneKeypadProvider } from '../components/telephoneKeypad';
5
8
  import { WebChatTheme } from '../components/theme';
6
- import { SendBox } from '../components/sendBox';
7
9
 
8
10
  const { ThemeProvider } = Components;
9
11
 
10
12
  type Props = Readonly<{ children?: ReactNode | undefined }>;
11
13
 
14
+ const activityMiddleware: ActivityMiddleware[] = [
15
+ () =>
16
+ next =>
17
+ (...args) => {
18
+ const activity = args[0]?.activity;
19
+
20
+ if (activity && isPreChatMessageActivity(activity)) {
21
+ return () => <PreChatMessageActivity activity={activity} />;
22
+ }
23
+
24
+ return next(...args);
25
+ }
26
+ ];
12
27
  const sendBoxMiddleware = [() => () => () => SendBox];
13
28
 
14
29
  const FluentThemeProvider = ({ children }: Props) => (
15
30
  <WebChatTheme>
16
31
  <TelephoneKeypadProvider>
17
- <ThemeProvider sendBoxMiddleware={sendBoxMiddleware}>{children}</ThemeProvider>
32
+ <ThemeProvider activityMiddleware={activityMiddleware} sendBoxMiddleware={sendBoxMiddleware}>
33
+ {children}
34
+ </ThemeProvider>
18
35
  </TelephoneKeypadProvider>
19
36
  </WebChatTheme>
20
37
  );