botframework-webchat-fluent-theme 4.18.1-main.20240808.851825d → 4.18.1-main.20240813.c50aac5

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 (31) hide show
  1. package/dist/botframework-webchat-fluent-theme.css.map +1 -1
  2. package/dist/botframework-webchat-fluent-theme.d.mts +2 -1
  3. package/dist/botframework-webchat-fluent-theme.d.ts +2 -1
  4. package/dist/botframework-webchat-fluent-theme.development.css.map +1 -1
  5. package/dist/botframework-webchat-fluent-theme.development.js +1 -1
  6. package/dist/botframework-webchat-fluent-theme.development.js.map +1 -1
  7. package/dist/botframework-webchat-fluent-theme.js +1 -1
  8. package/dist/botframework-webchat-fluent-theme.js.map +1 -1
  9. package/dist/botframework-webchat-fluent-theme.mjs +1 -1
  10. package/dist/botframework-webchat-fluent-theme.mjs.map +1 -1
  11. package/dist/botframework-webchat-fluent-theme.production.min.css.map +1 -1
  12. package/dist/botframework-webchat-fluent-theme.production.min.js +1 -1
  13. package/dist/botframework-webchat-fluent-theme.production.min.js.map +1 -1
  14. package/package.json +4 -4
  15. package/src/components/activity/ActivityDecorator.module.css +305 -0
  16. package/src/components/activity/ActivityDecorator.tsx +26 -0
  17. package/src/components/activity/CopilotMessageHeader.module.css +42 -0
  18. package/src/components/activity/CopilotMessageHeader.tsx +41 -0
  19. package/src/components/activity/index.ts +1 -0
  20. package/src/components/preChatActivity/PreChatMessageActivity.module.css +4 -2
  21. package/src/components/preChatActivity/StarterPromptsCardAction.module.css +1 -1
  22. package/src/components/preChatActivity/private/MonochromeImageMasker.module.css +3 -1
  23. package/src/components/sendBox/SendBox.module.css +3 -1
  24. package/src/components/theme/Theme.module.css +223 -10
  25. package/src/components/theme/Theme.tsx +3 -2
  26. package/src/private/FluentThemeProvider.tsx +20 -11
  27. package/src/private/VariantComposer.ts +29 -0
  28. package/src/private/createComposer.tsx +16 -0
  29. package/src/private/useVariants.ts +7 -0
  30. package/src/styles/index.ts +2 -1
  31. package/src/styles/useVariantClassName.ts +16 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botframework-webchat-fluent-theme",
3
- "version": "4.18.1-main.20240808.851825d",
3
+ "version": "4.18.1-main.20240813.c50aac5",
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,9 +69,9 @@
69
69
  "typescript": "^5.4.5"
70
70
  },
71
71
  "dependencies": {
72
- "botframework-webchat-api": "4.18.1-main.20240808.851825d",
73
- "botframework-webchat-component": "4.18.1-main.20240808.851825d",
74
- "botframework-webchat-core": "4.18.1-main.20240808.851825d",
72
+ "botframework-webchat-api": "4.18.1-main.20240813.c50aac5",
73
+ "botframework-webchat-component": "4.18.1-main.20240813.c50aac5",
74
+ "botframework-webchat-core": "4.18.1-main.20240813.c50aac5",
75
75
  "classnames": "2.5.1",
76
76
  "inject-meta-tag": "0.0.1",
77
77
  "math-random": "2.0.1",
@@ -0,0 +1,305 @@
1
+
2
+ :global(.webchat-fluent) .activity-decorator {
3
+ display: contents;
4
+
5
+ --webchat__bubble--inline-padding: var(--webchat-spacingHorizontalL);
6
+ --webchat__bubble--block-padding: var(--webchat-spacingVerticalM);
7
+ --webchat__bubble--min-height: var(--webchat-bubble-minHeight);
8
+ --webchat__bubble--max-width: var(--webchat-bubble-maxWidth);
9
+
10
+ --webchat-bubble-maxWidth: var(--bubble-maxWidth, 450px);
11
+ --webchat-bubble-minHeight: var(--bubble-minHeight, 36px);
12
+ --webchat-externalLink-mask: var(--externalLink-mask, var(--webchat__icon-url--external-link) center center / 10px 10px);
13
+ --webchat-externalLink-maxWidth: var(--externalLink-maxWidth, 204px);
14
+
15
+ /* Override for stacked layout message which has user message bubble props */
16
+ &:has(:global(.webchat__stacked-layout .webchat__bubble--from-user)) {
17
+ --webchat__bubble--background-color: var(--webchat-colorBrandBackground2);
18
+ --webchat__bubble--block-padding: var(--webchat-spacingVerticalS);
19
+ }
20
+ }
21
+
22
+ /* Decorator fluent variant */
23
+ :global(.webchat-fluent) .activity-decorator.variant-fluent {
24
+ --webchat__bubble--background-color: var(--webchat-colorNeutralBackground1);
25
+ --webchat__bubble--border-radius: var(--webchat-borderRadiusXLarge);
26
+ --webchat__bubble--box-shadow: var(--webchat-shadow4);
27
+ }
28
+
29
+ /* Decorator copilot variant */
30
+ :global(.webchat-fluent) .activity-decorator.variant-copilot {
31
+ --webchat__bubble--border-radius: var(--webchat-borderRadiusXLarge);
32
+
33
+ &:not(:has(:global(.webchat__bubble--from-user))) {
34
+ --webchat__bubble--block-padding: var(--webchat-spacingVerticalS) var(--webchat-spacingVerticalXXS);
35
+ --webchat__bubble--border-radius: var(--webchat-borderRadiusSmall);
36
+ --webchat__bubble--inline-padding: 32px var(--webchat-spacingHorizontalNone);
37
+ }
38
+
39
+ &:not(:has(:global(.webchat__bubble--from-user))) :global(.webchat__stacked-layout__status) {
40
+ display: none;
41
+ }
42
+
43
+ :global(.webchat__activity-status) {
44
+ margin: 0 0 var(--webchat-spacingHorizontalXXS);
45
+ }
46
+
47
+ :global(.webchat__stacked-layout__status) {
48
+ order: -1;
49
+ }
50
+
51
+ /* TODO: remove when we get decorators in and can place header directly to the bubble */
52
+ &:not(:has(:global(.webchat__bubble--from-user))) :global(.webchat__stacked-layout .webchat__bubble .webchat__text-content) {
53
+ padding-block: calc(var(--webchat-spacingVerticalS) + 20px) var(--webchat-spacingVerticalXXS);
54
+ }
55
+
56
+ &:not(:has(:global(.webchat__bubble--from-user))) :global(.webchat__stacked-layout .webchat__bubble) {
57
+ margin-block-start: -24px;
58
+ margin-inline-start: -4px;
59
+ }
60
+ }
61
+
62
+ /* Transcript activity non-empty */
63
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__basic-transcript__activity-body:not(:empty)) {
64
+ padding-block-end: var(--webchat-spacingVerticalXL);
65
+ }
66
+
67
+ /* Stacked layout */
68
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__stacked-layout) {
69
+ display: flex;
70
+ flex-flow: column nowrap;
71
+ }
72
+
73
+ /* Stacked layout which has message bubble */
74
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__stacked-layout .webchat__stacked-layout__content:has(.webchat__bubble)) {
75
+ overflow: visible;
76
+ }
77
+
78
+ /* Message status */
79
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__stacked-layout .webchat__stacked-layout__status) {
80
+ font-size: var(--webchat__font-size--small);
81
+ line-height: var(--webchat__line-height--small);
82
+ }
83
+
84
+ /* Message bubble */
85
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__stacked-layout .webchat__bubble) {
86
+ max-width: var(--webchat__bubble--max-width);
87
+ overflow: visible;
88
+ }
89
+
90
+ /* Message bubble content */
91
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__stacked-layout .webchat__bubble .webchat__bubble__content) {
92
+ background-color: var(--webchat__bubble--background-color);
93
+ border-radius: var(--webchat__bubble--border-radius);
94
+ border-width: 0;
95
+ box-sizing: border-box;
96
+ color: var(--webchat-colorNeutralForeground1);
97
+ min-height: var(--webchat__bubble--min-height);
98
+ }
99
+
100
+ /* Message bubble text content */
101
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__stacked-layout .webchat__bubble .webchat__text-content) {
102
+ font-size: var(--webchat__font-size--medium);
103
+ line-height: var(--webchat__line-height--medium);
104
+ min-height: auto;
105
+ padding-block: var(--webchat__bubble--block-padding);
106
+ padding-inline: var(--webchat__bubble--inline-padding);
107
+ }
108
+
109
+ /* Message bubble content pseudo */
110
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__stacked-layout .webchat__bubble .webchat__bubble__content)::before {
111
+ border-radius: inherit;
112
+ box-shadow: var(--webchat__bubble--box-shadow);
113
+ content: '';
114
+ inset: 0;
115
+ isolation: isolate;
116
+ pointer-events: none;
117
+ position: absolute;
118
+ }
119
+
120
+ /* Markdown links and citation links */
121
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__render-markdown) a[href]:not(:global(.webchat__render-markdown__pure-identifier)) {
122
+ color: var(--webchat-colorBrandForegroundLink);
123
+ text-decoration-color: transparent;
124
+
125
+ &:target {
126
+ color: var(--webchat-colorBrandForegroundLinkSelected);
127
+ }
128
+
129
+ &:hover {
130
+ color: var(--webchat-colorBrandForegroundLinkHover);
131
+ text-decoration: underline 1px currentColor;
132
+ }
133
+
134
+ &:active {
135
+ color: var(--webchat-colorBrandForegroundLinkPressed);
136
+ }
137
+
138
+ &:focus-visible {
139
+ outline: none;
140
+ text-decoration: underline 1px double var(--webchat-colorStrokeFocus2);
141
+ }
142
+
143
+ :global(.webchat__render-markdown__external-link-icon) {
144
+ background: currentColor;
145
+ -webkit-mask: var(--webchat__icon-url--external-link) no-repeat;
146
+ mask: var(--webchat__icon-url--external-link) no-repeat;
147
+ }
148
+ }
149
+
150
+ /* Citation inline references */
151
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__render-markdown) :global(.webchat__render-markdown__citation),
152
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__render-markdown) :global(.webchat__render-markdown__pure-identifier) {
153
+ align-items: center;
154
+ background-color: var(--webchat-colorNeutralBackground3);
155
+ border-radius: var(--webchat-borderRadiusMedium);
156
+ border: var(--webchat-strokeWidthThin) solid var(--webchat-colorNeutralStroke2);
157
+ box-sizing: border-box;
158
+ color: var(--webchat-colorNeutralForeground2);
159
+ display: inline-flex;
160
+ font-size: var(--webchat-fontSizeBase100);
161
+ font-weight: var(--webchat-fontWeightSemibold);
162
+ height: 14px;
163
+ justify-content: center;
164
+ line-height: var(--webchat-lineHeightBase100);
165
+ margin-left: var(--webchat-spacingHorizontalXXS);
166
+ margin-right: var(--webchat-spacingHorizontalXXS);
167
+ min-width: 14px;
168
+ text-decoration: none;
169
+ transition: all var(--webchat-durationNormal) var(--webchat-curveDecelerateMid);
170
+ vertical-align: calc((var(--webchat-lineHeightBase100) - var(--webchat-fontSizeBase100)) / 2);
171
+
172
+ &:hover {
173
+ background-color: var(--webchat-colorBrandBackground2Hover);
174
+ border-color: var(--webchat-colorBrandStroke2Hover);
175
+ color: var(--webchat-colorBrandForeground2Hover);
176
+ cursor: pointer;
177
+ }
178
+
179
+ &:hover:active {
180
+ background-color: var(--webchat-colorBrandBackground2Pressed);
181
+ border-color: var(--webchat-colorBrandStroke2Pressed);
182
+ color: var(--webchat-colorBrandForeground2Pressed);
183
+ }
184
+
185
+ &::before, &::after {
186
+ all: unset;
187
+ }
188
+
189
+ &:has(:global(.webchat__render-markdown__external-link-icon)) {
190
+ padding-inline: 3px;
191
+ }
192
+
193
+ :global(.webchat__render-markdown__external-link-icon) {
194
+ background: currentColor;
195
+ height: 0.7em;
196
+ -webkit-mask: var(--webchat__icon-url--external-link) no-repeat;
197
+ mask: var(--webchat__icon-url--external-link) no-repeat;
198
+ }
199
+ }
200
+
201
+ /* Citation summary chevron */
202
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__link-definitions__header) {
203
+ :global(.webchat__link-definitions__header-text) {
204
+ color: var(--webchat-colorNeutralForeground3);
205
+ }
206
+
207
+ :global(.webchat__link-definitions__header-chevron) {
208
+ fill: var(--webchat-colorNeutralForeground3);
209
+ font-size: var(--webchat__font-size--small);
210
+ width: 1em;
211
+ }
212
+ }
213
+
214
+ /* Citation link definitions */
215
+ :global(.webchat-fluent) .activity-decorator :global(.webchat__link-definitions) {
216
+ --webchat__citation__external-link--mask: var(--webchat-externalLink-mask);
217
+ --webchat__citation__link--max-width: var(--webchat-externalLink-maxWidth);
218
+
219
+ :global(.webchat__link-definitions__list) {
220
+ color: var(--webchat__color--subtle);
221
+ display: flex;
222
+ flex-flow: row wrap;
223
+ gap: var(--webchat-spacingHorizontalS);
224
+ }
225
+
226
+ :global(.webchat__link-definitions__list-item) {
227
+ border-radius: var(--webchat-borderRadiusMedium);
228
+ max-width: var(--webchat__citation__link--max-width);
229
+ }
230
+
231
+ :global(.webchat__link-definitions__list-item-box) {
232
+ background-color: var(--webchat-colorNeutralBackground3);
233
+ border-radius: var(--webchat-borderRadiusMedium);
234
+ border: var(--webchat-strokeWidthThin) solid var(--webchat-colorNeutralStroke2);
235
+ box-sizing: border-box;
236
+ color: currentColor;
237
+ display: inline-flex;
238
+ font-size: var(--webchat__font-size--small);
239
+ height: 24px;
240
+ padding-inline-end: var(--webchat-spacingHorizontalS);
241
+ }
242
+
243
+ :global(.webchat__link-definitions__list-item-body) {
244
+ font-family: inherit;
245
+ gap: var(--webchat-spacingHorizontalSNudge);
246
+ min-width: 0;
247
+ padding: 0;
248
+ }
249
+
250
+ :global(.webchat__link-definitions__badge) {
251
+ align-self: center;
252
+ background-color: transparent;
253
+ border-radius: 0;
254
+ border: none;
255
+ color: currentColor;
256
+ font-size: var(--webchat-fontSizeBase100);
257
+ font-weight: var(--webchat-fontWeightSemibold);
258
+ line-height: var(--webchat-lineHeightBase100);
259
+ margin: 0;
260
+ min-width: 20px;
261
+ padding: 0;
262
+ position: relative;
263
+ text-align: center;
264
+ }
265
+
266
+ :global(.webchat__link-definitions__badge)::after {
267
+ border-right: var(--webchat-strokeWidthThin) solid var(--webchat-colorNeutralStroke2);
268
+ bottom: 0;
269
+ content: '';
270
+ display: block;
271
+ height: 16px;
272
+ position: absolute;
273
+ right: 0;
274
+ top: 0;
275
+ width: 0;
276
+ }
277
+
278
+ :global(.webchat__link-definitions__list-item-main-text) {
279
+ gap: var(--webchat-spacingHorizontalXS);
280
+ }
281
+
282
+ :global(.webchat__link-definitions__list-item-text) {
283
+ color: currentColor;
284
+ text-decoration: none;
285
+ text-overflow: ellipsis;
286
+ }
287
+
288
+ :global(.webchat__link-definitions__list-item-main-text):has(:global(.webchat__link-definitions__open-in-new-window-icon))::before {
289
+ align-self: center;
290
+ background: currentColor;
291
+ color: currentColor;
292
+ content: '';
293
+ flex: none;
294
+ font-size: var(--webchat-fontSizeBase400);
295
+ height: 1em;
296
+ -webkit-mask: var(--webchat__citation__external-link--mask) no-repeat;
297
+ mask: var(--webchat__citation__external-link--mask) no-repeat;
298
+ padding: 0;
299
+ width: 1em;
300
+ }
301
+
302
+ :global(.webchat__link-definitions__open-in-new-window-icon) {
303
+ display: none;
304
+ }
305
+ }
@@ -0,0 +1,26 @@
1
+ import { WebChatActivity } from 'botframework-webchat-component';
2
+ import cx from 'classnames';
3
+ import React, { ReactNode, memo } from 'react';
4
+ import useVariants from '../../private/useVariants';
5
+ import { useStyles, useVariantClassName } from '../../styles';
6
+ import styles from './ActivityDecorator.module.css';
7
+ import CopilotMessageHeader from './CopilotMessageHeader';
8
+
9
+ function ActivityDecorator({ activity, children }: Readonly<{ activity: WebChatActivity; children: ReactNode }>) {
10
+ const classNames = useStyles(styles);
11
+ const variants = useVariants();
12
+ const variantClassName = useVariantClassName(styles);
13
+
14
+ const shouldRenderHeader = variants.includes('copilot') && activity?.from?.role !== 'user' && !!children;
15
+
16
+ return (
17
+ <div className={cx(classNames['activity-decorator'], variantClassName)}>
18
+ {shouldRenderHeader && <CopilotMessageHeader activity={activity} />}
19
+ {children}
20
+ </div>
21
+ );
22
+ }
23
+
24
+ ActivityDecorator.displayName = 'ActivityDecorator';
25
+
26
+ export default memo(ActivityDecorator);
@@ -0,0 +1,42 @@
1
+
2
+ :global(.webchat-fluent) .copilot-message-header {
3
+ align-items: center;
4
+ cursor: default;
5
+ display: flex;
6
+ flex-wrap: nowrap;
7
+ gap: var(--webchat-spacingHorizontalS);
8
+ margin-inline-start: var(--webchat-spacingVerticalMNudge);
9
+ padding-block-start: var(--webchat-spacingVerticalXS);
10
+ /* TODO: remove when moved to the bubble */
11
+ position: relative;
12
+ z-index: 1;
13
+ }
14
+
15
+ :global(.webchat-fluent) .copilot-message-header__avatar {
16
+ aspect-ratio: 1;
17
+ background-color: var(--background-color);
18
+ border-radius: var(--webchat-borderRadiusSmall);
19
+ width: 20px;
20
+ }
21
+
22
+ :global(.webchat-fluent) .copilot-message-header__title {
23
+ font-size: var(--webchat-fontSizeBase300);
24
+ font-weight: var(--webchat-fontWeightSemibold);
25
+ line-height: var(--webchat-lineHeightBase300);
26
+ max-width: 240px;
27
+ overflow: hidden;
28
+ text-overflow: ellipsis;
29
+ text-wrap: nowrap;
30
+ }
31
+
32
+ :global(.webchat-fluent) .copilot-message-header__ai-generated-content {
33
+ align-items: center;
34
+ background-color: var(--webchat-colorNeutralBackground5);
35
+ border-radius: var(--webchat-borderRadiusMedium);
36
+ color: var(--webchat-colorNeutralForeground3);
37
+ display: flex;
38
+ font-size: var(--webchat-fontSizeBase100);
39
+ height: 20px;
40
+ line-height: var(--webchat-lineHeightBase100);
41
+ padding-inline: 4px;
42
+ }
@@ -0,0 +1,41 @@
1
+ import { WebChatActivity, hooks } from 'botframework-webchat-component';
2
+ import React, { memo, useMemo, type CSSProperties } from 'react';
3
+ import { useStyles } from '../../styles';
4
+ import styles from './CopilotMessageHeader.module.css';
5
+
6
+ const { useStyleOptions, useLocalizer } = hooks;
7
+
8
+ function CopilotMessageHeader({ activity }: Readonly<{ activity?: WebChatActivity | undefined }>) {
9
+ const [{ botAvatarImage, botAvatarBackgroundColor }] = useStyleOptions();
10
+ const classNames = useStyles(styles);
11
+ const localize = useLocalizer();
12
+ // TODO: how we determine the activity has ai-generated content
13
+ const isAIGenerated = useMemo(() => !!activity, [activity]);
14
+ const botTitle = activity?.from?.name;
15
+
16
+ const avatarStyle = useMemo(
17
+ () => ({ '--background-color': botAvatarBackgroundColor }) as CSSProperties,
18
+ [botAvatarBackgroundColor]
19
+ );
20
+
21
+ return (
22
+ <div className={classNames['copilot-message-header']}>
23
+ <img
24
+ alt={localize('AVATAR_ALT', botTitle)}
25
+ className={classNames['copilot-message-header__avatar']}
26
+ src={botAvatarImage}
27
+ style={avatarStyle}
28
+ />
29
+ <span className={classNames['copilot-message-header__title']} title={botTitle}>
30
+ {botTitle}
31
+ </span>
32
+ {isAIGenerated && (
33
+ <span className={classNames['copilot-message-header__ai-generated-content']}>
34
+ {localize('ACTIVITY_CONTENT_CAUTION')}
35
+ </span>
36
+ )}
37
+ </div>
38
+ );
39
+ }
40
+
41
+ export default memo(CopilotMessageHeader);
@@ -0,0 +1 @@
1
+ export { default as ActivityDecorator } from './ActivityDecorator';
@@ -1,9 +1,11 @@
1
1
  :global(.webchat-fluent) .pre-chat-message-activity {
2
+ box-sizing: border-box;
2
3
  display: grid;
4
+ gap: var(--webchat-spacingHorizontalXXXL);
3
5
  grid-template-areas: 'body' 'toolbar';
4
6
  grid-template-rows: auto auto;
5
- gap: var(--webchat-spacingHorizontalXXXL);
6
- padding: var(--webchat-spacingHorizontalXXXL);
7
+ padding: var(--webchat-spacingHorizontalXXXL) var(--webchat-spacingHorizontalM);
8
+ position: relative;
7
9
  }
8
10
 
9
11
  :global(.webchat-fluent) .pre-chat-message-activity__body {
@@ -22,7 +22,7 @@
22
22
  }
23
23
 
24
24
  :global(.webchat-fluent) .pre-chat-message-activity__card-action-box:hover {
25
- background-color: var(--webchat-colorNeutralGrey94);
25
+ background-color: var(--webchat-colorNeutralBackground1Hover);
26
26
  }
27
27
 
28
28
  :global(.webchat-fluent) .pre-chat-message-activity__card-action-box:active {
@@ -1,5 +1,7 @@
1
1
  :global(.webchat-fluent) .pre-chat-message-activity__monochrome-image-masker {
2
2
  background-color: var(--webchat-colorNeutralForeground4);
3
+ -webkit-mask-image: var(--mask-image);
3
4
  mask-image: var(--mask-image);
4
- --webkit-mask-image: var(--mask-image);
5
+ -webkit-mask-repeat: no-repeat;
6
+ mask-repeat: no-repeat;
5
7
  }
@@ -1,7 +1,9 @@
1
1
  :global(.webchat-fluent) .sendbox {
2
+ --webchat__sendbox--padding: var(--webchat__padding--sendbox);
3
+
2
4
  color: var(--webchat-colorNeutralForeground1);
3
5
  font-family: var(--webchat-fontFamilyBase);
4
- padding: 0 10px 10px;
6
+ padding: var(--webchat__sendbox--padding);
5
7
  text-rendering: optimizeLegibility;
6
8
 
7
9
  --webchat-sendbox-attachment-area-active: ;