botframework-webchat-fluent-theme 4.18.1-main.20240808.851825d → 4.18.1-main.20240820.2dbeed3

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 (34) 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 +11 -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 +11 -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 +306 -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 +20 -15
  22. package/src/components/preChatActivity/StarterPromptsCardAction.tsx +2 -2
  23. package/src/components/preChatActivity/isPreChatMessageActivity.ts +2 -21
  24. package/src/components/sendBox/SendBox.module.css +3 -1
  25. package/src/components/theme/Theme.module.css +293 -17
  26. package/src/components/theme/Theme.tsx +3 -2
  27. package/src/private/FluentThemeProvider.tsx +22 -13
  28. package/src/private/VariantComposer.ts +29 -0
  29. package/src/private/createComposer.tsx +16 -0
  30. package/src/private/useVariants.ts +7 -0
  31. package/src/styles/index.ts +2 -1
  32. package/src/styles/useVariantClassName.ts +16 -0
  33. package/src/components/preChatActivity/private/MonochromeImageMasker.module.css +0 -5
  34. package/src/components/preChatActivity/private/MonochromeImageMasker.tsx +0 -19
@@ -1,33 +1,43 @@
1
1
  :global(.webchat-fluent).theme {
2
2
  display: contents;
3
3
 
4
+ --webchat-colorNeutralForegroundDisabled: var(--colorNeutralForegroundDisabled, #bdbdbd);
4
5
  --webchat-colorNeutralForeground1: var(--colorNeutralForeground1, #242424);
6
+ --webchat-colorNeutralForeground1Hover: var(--colorNeutralForeground1Hover, #242424);
7
+ --webchat-colorNeutralForeground1Pressed: var(--colorNeutralForeground1Pressed, #242424);
5
8
  --webchat-colorNeutralForeground2: var(--colorNeutralForeground2, #424242);
6
- --webchat-colorNeutralForeground4: var(--colorNeutralForeground4, #707070);
7
-
8
9
  --webchat-colorNeutralForeground2BrandHover: var(--colorNeutralForeground2BrandHover, #02729c);
9
10
  --webchat-colorNeutralForeground2BrandPressed: var(--colorNeutralForeground2BrandPressed, #01678c);
10
11
  --webchat-colorNeutralForeground2BrandSelected: var(--colorNeutralForeground2BrandSelected, #067191);
12
+ --webchat-colorNeutralForeground3: var(--colorNeutralForeground3, #616161);
13
+ --webchat-colorNeutralForeground4: var(--colorNeutralForeground4, #707070);
14
+ --webchat-colorNeutralForeground5: var(--colorNeutralForeground5, #7e7e7e);
11
15
 
12
- --webchat-colorNeutralForegroundDisabled: var(--colorNeutralForegroundDisabled, #bdbdbd);
13
-
16
+ --webchat-colorNeutralBackgroundDisabled: var(--colorNeutralBackgroundDisabled, #f0f0f0);
14
17
  --webchat-colorNeutralBackground1: var(--colorNeutralBackground1, #ffffff);
18
+ --webchat-colorNeutralBackground1Hover: var(--colorNeutralBackground1Hover, #f5f5f5);
19
+ --webchat-colorNeutralBackground1Pressed: var(--colorNeutralBackground1Pressed, #e0e0e0);
20
+ --webchat-colorNeutralBackground3: var(--colorNeutralBackground3, #f5f5f5);
15
21
  --webchat-colorNeutralBackground4: var(--colorNeutralBackground4, #f0f0f0);
16
22
  --webchat-colorNeutralBackground5: var(--colorNeutralBackground5, #ebebeb);
17
23
 
18
- --webchat-colorNeutralBackground1Disabled: var(--colorNeutralBackground1Disabled, #f0f0f0);
19
- --webchat-colorNeutralBackground1Pressed: var(--colorNeutralBackground1Pressed, #e0e0e0);
20
-
21
- --webchat-colorNeutralGrey94: var(--colorNeutralGrey94, #f0f0f0);
24
+ --webchat-colorTransparentBackground: var(--colorTransparentBackground, rgba(0, 0, 0, 0.4));
22
25
 
26
+ --webchat-colorNeutralStrokeDisabled: var(--colorNeutralStrokeDisabled, #e0e0e0);
23
27
  --webchat-colorNeutralStroke1: var(--colorNeutralStroke1, #d1d1d1);
24
- --webchat-colorNeutralStroke2: var(--colorNeutralStroke2, #e0e0e0);
28
+ --webchat-colorNeutralStroke1Hover: var(--colorNeutralStroke1Hover, #c7c7c7);
29
+ --webchat-colorNeutralStroke1Pressed: var(--colorNeutralStroke1Pressed, #b3b3b3);
25
30
  --webchat-colorNeutralStroke1Selected: var(--colorNeutralStroke1Selected, #bdbdbd);
31
+ --webchat-colorNeutralStroke2: var(--colorNeutralStroke2, #e0e0e0);
26
32
 
27
33
  --webchat-colorStrokeFocus2: var(--colorStrokeFocus2, #000000);
28
34
 
29
35
  --webchat-colorBrandStroke2: var(--colorBrandStroke2, #9edcf7);
36
+ --webchat-colorBrandStroke2Pressed: var(--colorBrandStroke2Pressed, #01384d);
37
+
38
+ --webchat-colorTransparentStroke: var(--colorTransparentStroke, transparent);
30
39
 
40
+ --webchat-colorBrandForeground1: var(--colorBrandForeground1, #01678c);
31
41
  --webchat-colorBrandForeground2Hover: var(--colorBrandForeground2Hover, #015a7a);
32
42
  --webchat-colorBrandForeground2Pressed: var(--colorBrandForeground2Pressed, #01384d);
33
43
 
@@ -36,6 +46,7 @@
36
46
  --webchat-colorBrandForegroundLinkPressed: var(--colorBrandForegroundLinkPressed, #014259);
37
47
  --webchat-colorBrandForegroundLinkSelected: var(--colorBrandForegroundLinkSelected, #01678c);
38
48
 
49
+ --webchat-colorBrandBackground2: var(--colorBrandBackground2, #def2fc);
39
50
  --webchat-colorBrandBackground2Hover: var(--colorBrandBackground2Hover, #bee7fa);
40
51
  --webchat-colorBrandBackground2Pressed: var(--colorBrandBackground2Pressed, #7fd2f5);
41
52
 
@@ -49,19 +60,37 @@
49
60
  --webchat-colorGray190: var(--colorGray190, #201f1e);
50
61
  --webchat-colorGray200: var(--colorGray200, #1b1a19);
51
62
 
52
- /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/borderRadius.ts */
53
- --webchat-borderRadiusSmall: var(--borderRadiusSmall, 2px);
54
- --webchat-borderRadiusLarge: var(--borderRadiusLarge, 6px);
55
- --webchat-borderRadiusXLarge: var(--borderRadiusXLarge, 8px);
56
-
57
63
  /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/utils/shadows.ts */
64
+ --webchat-shadow2: var(--shadow2, 0 0 2px rgba(0, 0, 0, 12%), 0 1px 2px rgba(0, 0, 0, 14%));
65
+ --webchat-shadow4: var(--shadow4, 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.14));
58
66
  --webchat-shadow16: var(--shadow16, 0 6.4px 14.4px 0 rgba(0, 0, 0, 0.132), 0 1.2px 3.6px 0 rgba(0, 0, 0, 0.108));
67
+ --webchat-shadow64: var(--shadow64, 0 0 8px rgba(0, 0, 0, 0.12), 0 32px 64px rgba(0, 0, 0, 0.14));
59
68
 
60
69
  /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/spacings.ts */
70
+ --webchat-spacingHorizontalNone: var(--spacingHorizontalNone, 0);
71
+ --webchat-spacingHorizontalXXS: var(--spacingHorizontalXXS, 2px);
72
+ --webchat-spacingHorizontalXS: var(--spacingHorizontalXS, 4px);
73
+ --webchat-spacingHorizontalSNudge: var(--spacingHorizontalSNudge, 6px);
74
+ --webchat-spacingHorizontalS: var(--spacingHorizontalS, 8px);
61
75
  --webchat-spacingHorizontalMNudge: var(--spacingHorizontalMNudge, 10px);
62
76
  --webchat-spacingHorizontalM: var(--spacingHorizontalM, 12px);
77
+ --webchat-spacingHorizontalL: var(--spacingHorizontalL, 16px);
78
+ --webchat-spacingHorizontalXL: var(--spacingHorizontalXL, 20px);
79
+ --webchat-spacingHorizontalXXL: var(--spacingHorizontalXXL, 24px);
63
80
  --webchat-spacingHorizontalXXXL: var(--spacingHorizontalXXXL, 32px);
81
+
82
+ /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/spacings.ts */
83
+ --webchat-spacingVerticalNone: var(--spacingVerticalNone, 0);
84
+ --webchat-spacingVerticalXXS: var(--spacingVerticalXXS, 2px);
85
+ --webchat-spacingVerticalXS: var(--spacingVerticalXS, 4px);
86
+ --webchat-spacingVerticalSNudge: var(--spacingVerticalSNudge, 6px);
87
+ --webchat-spacingVerticalS: var(--spacingVerticalS, 8px);
88
+ --webchat-spacingVerticalMNudge: var(--spacingVerticalMNudge, 10px);
89
+ --webchat-spacingVerticalM: var(--spacingVerticalM, 12px);
64
90
  --webchat-spacingVerticalL: var(--spacingVerticalL, 16px);
91
+ --webchat-spacingVerticalXL: var(--spacingVerticalXL, 20px);
92
+ --webchat-spacingVerticalXXL: var(--spacingVerticalXXL, 24px);
93
+ --webchat-spacingVerticalXXXL: var(--spacingVerticalXXXL, 32px);
65
94
 
66
95
  /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/fonts.ts */
67
96
  --webchat-fontFamilyBase: var(--fontFamilyBase, 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif);
@@ -72,22 +101,46 @@
72
101
  --webchat-fontWeightSemibold: var(--fontWeightSemibold, 600);
73
102
 
74
103
  /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/fonts.ts */
104
+ --webchat-fontSizeBase100: var(--fontSizeBase100, 10px);
105
+ --webchat-fontSizeBase200: var(--fontSizeBase200, 12px);
75
106
  --webchat-fontSizeBase300: var(--fontSizeBase300, 14px);
107
+ --webchat-fontSizeBase400: var(--fontSizeBase400, 16px);
108
+ --webchat-fontSizeBase500: var(--fontSizeBase500, 20px);
109
+ --webchat-fontSizeBase600: var(--fontSizeBase600, 24px);
76
110
  --webchat-fontSizeHero700: var(--fontSizeHero700, 28px);
111
+ --webchat-fontSizeHero800: var(--fontSizeHero800, 32px);
112
+ --webchat-fontSizeHero900: var(--fontSizeHero900, 40px);
77
113
 
114
+ --webchat-lineHeightBase100: var(--lineHeightBase100, 14px);
115
+ --webchat-lineHeightBase200: var(--lineHeightBase200, 16px);
78
116
  --webchat-lineHeightBase300: var(--lineHeightBase300, 20px);
117
+ --webchat-lineHeightBase400: var(--lineHeightBase400, 22px);
118
+ --webchat-lineHeightBase500: var(--lineHeightBase500, 28px);
119
+ --webchat-lineHeightBase600: var(--lineHeightBase600, 32px);
79
120
  --webchat-lineHeightHero700: var(--lineHeightHero700, 36px);
121
+ --webchat-lineHeightHero800: var(--lineHeightHero800, 40px);
122
+ --webchat-lineHeightHero900: var(--lineHeightHero900, 52px);
123
+ --webchat-lineHeightHero1000: var(--lineHeightHero1000, 92px);
80
124
 
125
+ /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/borderRadius.ts */
126
+ --webchat-borderRadiusSmall: var(--borderRadiusSmall, 2px);
127
+ --webchat-borderRadiusMedium: var(--borderRadiusMedium, 4px);
128
+ --webchat-borderRadiusLarge: var(--borderRadiusLarge, 6px);
129
+ --webchat-borderRadiusXLarge: var(--borderRadiusXLarge, 8px);
130
+
131
+ /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/strokeWidths.ts */
132
+ --webchat-strokeWidthThin: var(--strokeWidthThin, 1px);
133
+ --webchat-strokeWidthThick: var(--strokeWidthThicker, 2px);
81
134
  --webchat-strokeWidthThicker: var(--strokeWidthThicker, 3px);
82
135
 
136
+ /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/durations.ts */
83
137
  --webchat-durationUltraFast: var(--durationUltraFast, 0);
84
138
  --webchat-durationNormal: var(--durationNormal, 200ms);
139
+ --webchat-durationUltraSlow: var(--durationUltraSlow, 500ms);
85
140
 
141
+ /* https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/curves.ts */
86
142
  --webchat-curveAccelerateMid: var(--curveAccelerateMid, cubic-bezier(1,0,1,1));
87
143
  --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%);
91
144
  }
92
145
 
93
146
  @media (prefers-reduced-motion) {
@@ -96,3 +149,226 @@
96
149
  --webchat-durationNormal: 0.01ms;
97
150
  }
98
151
  }
152
+
153
+ /* Style Options override */
154
+ :global(.webchat-fluent).theme :global(.webchat__css-custom-properties) {
155
+ --webchat__color--accent: var(--webchat-colorBrandForeground1);
156
+ --webchat__color--subtle: var(--webchat-colorNeutralForeground2);
157
+ --webchat__color--timestamp: var(--webchat-colorNeutralForeground3);
158
+ --webchat__font--primary: var(--webchat-fontFamilyBase);
159
+ --webchat__font-size--small: var(--webchat-fontSizeBase200);
160
+ --webchat__font-size--medium: var(--webchat-fontSizeBase300);
161
+ --webchat__line-height--small: var(--webchat-lineHeightBase200);
162
+ --webchat__line-height--medium: var(--webchat-lineHeightBase300);
163
+ --webchat__max-width--bubble: var(--webchat-bubble-maxWidth);
164
+ --webchat__min-height--bubble: var(--webchat-bubble-minHeight);
165
+ --webchat__padding--regular: var(--webchat-spacingVerticalS);
166
+ --webchat__padding--sendbox:
167
+ var(--webchat-spacingVerticalNone)
168
+ var(--webchat-spacingHorizontalMNudge)
169
+ var(--webchat-spacingHorizontalMNudge);
170
+ }
171
+
172
+ :global(.webchat-fluent).theme.variant-copilot :global(.webchat__css-custom-properties) {
173
+ --webchat__padding--sendbox:
174
+ var(--webchat-spacingVerticalNone)
175
+ var(--webchat-spacingHorizontalXL)
176
+ var(--webchat-spacingVerticalMNudge)
177
+ var(--webchat-spacingHorizontalMNudge);
178
+ }
179
+
180
+ /* Transcript surface */
181
+ :global(.webchat-fluent).theme :global(.webchat__surface) {
182
+ background-color: var(--webchat__color--surface);
183
+ }
184
+
185
+ :global(.webchat-fluent).theme.variant-copilot :global(.webchat__surface) {
186
+ box-sizing: border-box;
187
+ padding-inline-start: var(--webchat-spacingHorizontalMNudge);
188
+ }
189
+
190
+ /* Transcript scrollable */
191
+ :global(.webchat-fluent).theme :global(.webchat__basic-transcript .webchat__basic-transcript__scrollable) {
192
+ /* Edge uses -webkit-scrollbar if scrollbar-* is not set */
193
+ scrollbar-color: unset;
194
+ scrollbar-width: unset;
195
+ /* Firefox */
196
+ -moz-scrollbar-color: var(--webchat-colorNeutralForeground5) transparent;
197
+ -moz-scrollbar-width: thin;
198
+
199
+ &::-webkit-scrollbar {
200
+ width: var(--webchat-spacingVerticalMNudge);
201
+ visibility: hidden;
202
+ }
203
+
204
+ &:hover::-webkit-scrollbar {
205
+ width: var(--webchat-spacingVerticalMNudge);
206
+ }
207
+
208
+ &:hover::-webkit-scrollbar-thumb {
209
+ background-clip: padding-box;
210
+ background-color: var(--webchat-colorNeutralForeground5);
211
+ border-radius: 10px;
212
+ border-right: 4px solid transparent;
213
+ border: 3px solid transparent;
214
+ }
215
+
216
+ &:hover::-webkit-scrollbar-thumb:hover {
217
+ background-clip: padding-box;
218
+ background-color: var(--webchat-colorNeutralForeground5);
219
+ border-radius: 10px;
220
+ border-right: 2px solid transparent;
221
+ border: 1px solid transparent;
222
+ }
223
+ }
224
+
225
+ :global(.webchat-fluent).theme.variant-copilot :global(.webchat__basic-transcript .webchat__basic-transcript__scrollable) {
226
+ scrollbar-gutter: stable;
227
+ }
228
+
229
+ /* Transcript focus indicator color when in focus-visible state */
230
+ :global(.webchat-fluent).theme :global(.webchat__basic-transcript .webchat__basic-transcript__terminator:focus-visible + .webchat__basic-transcript__focus-indicator) {
231
+ border-color: var(--webchat-colorStrokeFocus2);
232
+ }
233
+
234
+ /* Transcript Activity indicator without focus-visible state */
235
+ :global(.webchat-fluent).theme :global(.webchat__basic-transcript:not(:focus-visible) .webchat__basic-transcript__activity-indicator--focus) {
236
+ /* Hide activity focus when no focus-visible state */
237
+ display: none;
238
+ }
239
+
240
+ /* Transcript Focus indicator when activity focused */
241
+ :global(.webchat-fluent).theme :global(.webchat__basic-transcript:focus-visible:has(.webchat__basic-transcript__activity-indicator--focus)) {
242
+ :global(.webchat__basic-transcript__focus-indicator) {
243
+ /* Hide transcript focus when an activity is focused */
244
+ display: none;
245
+ }
246
+ }
247
+
248
+ /* Transcript focused activity */
249
+ :global(.webchat-fluent).theme :global(.webchat__basic-transcript:focus-visible .webchat__basic-transcript__activity:has(.webchat__basic-transcript__activity-indicator--focus)) {
250
+ :global(.webchat__basic-transcript__activity-indicator--focus) {
251
+ /* Hide transcript activity focus when the activity is focused */
252
+ display: none;
253
+ }
254
+
255
+ :global(.webchat__bubble)::after, :global(.pre-chat-message-activity)::after {
256
+ content: '';
257
+ position: absolute;
258
+ inset: -2px;
259
+ border: var(--webchat-strokeWidthThick) solid var(--webchat-colorStrokeFocus2);
260
+ border-radius: var(--webchat__bubble--border-radius);
261
+ pointer-events: none;
262
+ }
263
+
264
+ :global(.pre-chat-message-activity)::after {
265
+ inset: 0;
266
+ border-radius: var(--webchat-borderRadiusSmall);
267
+ }
268
+ }
269
+
270
+ /* Transcript with a single pre-chat activity */
271
+ :global(.webchat-fluent).theme :global(.webchat__basic-transcript:has(.webchat__basic-transcript__activity:only-child):has(.pre-chat-message-activity) .webchat__basic-transcript__filler) {
272
+ /* limit grow to half of the size to center the activity */
273
+ flex-grow: 0.5;
274
+ }
275
+
276
+ /* Modal */
277
+ :global(.webchat-fluent).theme :global(.webchat__modal-dialog) {
278
+ height: 100%;
279
+ display: grid;
280
+ place-items: center;
281
+
282
+ &::backdrop {
283
+ background-color: var(--webchat-colorTransparentBackground);
284
+ }
285
+
286
+ :global(.webchat__modal-dialog__box) {
287
+ background-color: var(--webchat-colorNeutralBackground1);
288
+ border-radius: var(--webchat-borderRadiusXLarge);
289
+ position: relative;
290
+ color: var(--webchat-colorNeutralForeground1);
291
+ box-shadow: var(--webchat-shadow64);
292
+ }
293
+
294
+ :global(.webchat__modal-dialog__close-button) {
295
+ color: var(--webchat-colorNeutralForeground1);
296
+ transition: background-color var(--webchat-durationNormal) var(--webchat-curveDecelerateMid);
297
+ }
298
+
299
+ /* TODO: align with original fluent modal styles in WebChat as they don't match v9 anymore */
300
+ :global(.webchat__modal-dialog__close-button):focus:not(:active):hover {
301
+ background-color: var(--webchat-colorNeutralBackground3);
302
+ }
303
+
304
+ :global(.webchat__modal-dialog__close-button):focus:active {
305
+ background-color: var(--webchat-colorNeutralBackground4);
306
+ }
307
+
308
+ :global(.webchat__modal-dialog__close-button):not(:focus-visible) {
309
+ border: none;
310
+ }
311
+
312
+ :global(.webchat__modal-dialog__close-button):focus {
313
+ border-color: var(--webchat-colorStrokeFocus2);
314
+ }
315
+
316
+ :global(.webchat__modal-dialog__close-button-image) {
317
+ fill: currentColor;
318
+ }
319
+ }
320
+
321
+ /* Activity button */
322
+ :global(.webchat-fluent).theme :global(.webchat__activity-button) {
323
+ background: var(--webchat-colorNeutralBackground1);
324
+ border-radius: var(--webchat-borderRadiusMedium);
325
+ border: var(--webchat-strokeWidthThin) solid var(--webchat-colorNeutralStroke1);
326
+ color: var(--webchat-colorNeutralForeground1);
327
+ gap: var(--webchat-spacingHorizontalXS);
328
+ padding: 5px var(--webchat-spacingHorizontalM);
329
+
330
+ &:hover {
331
+ background: var(--webchat-colorNeutralBackground1Hover);
332
+ border: var(--webchat-strokeWidthThin) solid var(--webchat-colorNeutralStroke1Hover);
333
+ color: var(--webchat-colorNeutralForeground1Hover);
334
+ }
335
+
336
+ &:active {
337
+ background: var(--webchat-colorNeutralBackground1Pressed);
338
+ border: var(--webchat-strokeWidthThin) solid var(--webchat-colorNeutralStroke1Pressed);
339
+ color: var(--webchat-colorNeutralForeground1Pressed);
340
+ }
341
+
342
+ &:focus-visible {
343
+ background: var(--webchat-colorNeutralBackground1);
344
+ outline: var(--webchat-strokeWidthThick) solid var(--webchat-colorStrokeFocus2);
345
+ outline-offset: calc(var(--webchat-strokeWidthThick) * -1);
346
+ }
347
+
348
+ &:disabled {
349
+ background: var(--webchat-colorNeutralBackgroundDisabled);
350
+ border: var(--webchat-strokeWidthThin) solid var(--webchat-colorNeutralStrokeDisabled);
351
+ color: var(--webchat-colorNeutralForegroundDisabled);
352
+ }
353
+
354
+ :global(.webchat__activity-button__icon) {
355
+ height: 20px;
356
+ width: 20px;
357
+ }
358
+ }
359
+
360
+ /* Copy button */
361
+ :global(.webchat-fluent).theme :global(.webchat__activity-copy-button) {
362
+ :global(.webchat__activity-copy-button__copied-text) {
363
+ background-color: var(--webchat-colorNeutralBackground1);
364
+ }
365
+
366
+ &:global(.webchat__activity-copy-button--copied) :global(.webchat__activity-copy-button__copied-text) {
367
+ animation-duration: var(--webchat-durationUltraSlow);
368
+ }
369
+ }
370
+
371
+ /* Monochrome image masker */
372
+ :global(.webchat-fluent).theme :global(.webchat__monochrome-image-masker) {
373
+ background-color: var(--webchat-colorNeutralForeground4);
374
+ }
@@ -1,11 +1,12 @@
1
1
  import React, { type ReactNode } from 'react';
2
2
  import cx from 'classnames';
3
3
  import styles from './Theme.module.css';
4
- import { useStyles } from '../../styles';
4
+ import { useStyles, useVariantClassName } from '../../styles';
5
5
 
6
6
  export const rootClassName = 'webchat-fluent';
7
7
 
8
8
  export default function Theme(props: Readonly<{ readonly children: ReactNode | undefined }>) {
9
9
  const classNames = useStyles(styles);
10
- return <div className={cx(rootClassName, classNames['theme'])}>{props.children}</div>;
10
+ const variantClassName = useVariantClassName(styles);
11
+ return <div className={cx(rootClassName, classNames['theme'], variantClassName)}>{props.children}</div>;
11
12
  }
@@ -1,17 +1,19 @@
1
+ import type { ActivityMiddleware } from 'botframework-webchat-api';
1
2
  import { Components } from 'botframework-webchat-component';
2
3
  import React, { memo, type ReactNode } from 'react';
3
4
 
4
- import type { ActivityMiddleware } from 'botframework-webchat-api';
5
+ import { ActivityDecorator } from '../components/activity';
5
6
  import { isPreChatMessageActivity, PreChatMessageActivity } from '../components/preChatActivity';
6
7
  import { PrimarySendBox } from '../components/sendBox';
7
8
  import { TelephoneKeypadProvider } from '../components/telephoneKeypad';
8
9
  import { WebChatTheme } from '../components/theme';
10
+ import VariantComposer, { VariantList } from './VariantComposer';
9
11
 
10
12
  const { ThemeProvider } = Components;
11
13
 
12
- type Props = Readonly<{ children?: ReactNode | undefined }>;
14
+ type Props = Readonly<{ children?: ReactNode | undefined; variant?: VariantList | undefined }>;
13
15
 
14
- const activityMiddleware: ActivityMiddleware[] = [
16
+ const activityMiddleware: readonly ActivityMiddleware[] = Object.freeze([
15
17
  () =>
16
18
  next =>
17
19
  (...args) => {
@@ -21,19 +23,26 @@ const activityMiddleware: ActivityMiddleware[] = [
21
23
  return () => <PreChatMessageActivity activity={activity} />;
22
24
  }
23
25
 
24
- return next(...args);
26
+ const renderActivity = next(...args);
27
+
28
+ return renderActivity
29
+ ? (...args) => <ActivityDecorator activity={activity}>{renderActivity(...args)}</ActivityDecorator>
30
+ : renderActivity;
25
31
  }
26
- ];
32
+ ]);
33
+
27
34
  const sendBoxMiddleware = [() => () => () => PrimarySendBox];
28
35
 
29
- const FluentThemeProvider = ({ children }: Props) => (
30
- <WebChatTheme>
31
- <TelephoneKeypadProvider>
32
- <ThemeProvider activityMiddleware={activityMiddleware} sendBoxMiddleware={sendBoxMiddleware}>
33
- {children}
34
- </ThemeProvider>
35
- </TelephoneKeypadProvider>
36
- </WebChatTheme>
36
+ const FluentThemeProvider = ({ children, variant = 'fluent' }: Props) => (
37
+ <VariantComposer variant={variant}>
38
+ <WebChatTheme>
39
+ <TelephoneKeypadProvider>
40
+ <ThemeProvider activityMiddleware={activityMiddleware} sendBoxMiddleware={sendBoxMiddleware}>
41
+ {children}
42
+ </ThemeProvider>
43
+ </TelephoneKeypadProvider>
44
+ </WebChatTheme>
45
+ </VariantComposer>
37
46
  );
38
47
 
39
48
  export default memo(FluentThemeProvider);
@@ -0,0 +1,29 @@
1
+ import { createContext } from 'react';
2
+
3
+ import createComposer from './createComposer';
4
+
5
+ type VariantName = 'fluent' | 'copilot' | '';
6
+
7
+ export type VariantList = `${VariantName}`;
8
+
9
+ export type VariantContextType = {
10
+ variant: VariantList;
11
+ };
12
+
13
+ export const VariantContext = createContext<VariantContextType>(
14
+ new Proxy(
15
+ {},
16
+ {
17
+ get() {
18
+ throw new Error('Unable to use VariantContext without VariantComposer');
19
+ }
20
+ }
21
+ ) as unknown as VariantContextType
22
+ );
23
+
24
+ const VariantComposer = createComposer<VariantContextType>(VariantContext, {
25
+ defaults: { variant: '' },
26
+ displayName: 'VariantComposer'
27
+ });
28
+
29
+ export default VariantComposer;
@@ -0,0 +1,16 @@
1
+ import React, { type Context, memo, type ReactNode, useMemo } from 'react';
2
+
3
+ export default function createComposer<
4
+ C,
5
+ P extends { children?: ReactNode | undefined } = Partial<C> & { children?: ReactNode | undefined }
6
+ >({ Provider }: Context<C>, { defaults, displayName }: Readonly<{ defaults: Readonly<C>; displayName: string }>) {
7
+ const Composer = ({ children, ...props }: Readonly<P>) => {
8
+ const value = useMemo(() => Object.freeze({ ...defaults, ...props }), [props]);
9
+
10
+ return <Provider value={value}>{children}</Provider>;
11
+ };
12
+
13
+ Composer.displayName = displayName;
14
+
15
+ return memo(Composer);
16
+ }
@@ -0,0 +1,7 @@
1
+ import { useContext, useMemo } from 'react';
2
+ import { VariantContext } from './VariantComposer';
3
+
4
+ export default function useVariants() {
5
+ const { variant } = useContext(VariantContext);
6
+ return useMemo(() => variant.split(' '), [variant]);
7
+ }
@@ -1,4 +1,5 @@
1
1
  import injectStyle from './injectStyle';
2
2
  import useStyles from './useStyles';
3
+ import useVariantClassName from './useVariantClassName';
3
4
 
4
- export { injectStyle, useStyles };
5
+ export { injectStyle, useStyles, useVariantClassName };
@@ -0,0 +1,16 @@
1
+ import { useMemo } from 'react';
2
+ import useVariants from '../private/useVariants';
3
+ import useStyles from './useStyles';
4
+
5
+ export default function useVariantClassName<T extends CSSModuleClasses>(styles: T): string {
6
+ const classNames = useStyles(styles);
7
+ const variants = useVariants();
8
+ return useMemo(
9
+ () =>
10
+ variants
11
+ .map(variant => classNames[`variant-${variant}`])
12
+ .filter(value => value)
13
+ .join(' '),
14
+ [classNames, variants]
15
+ );
16
+ }
@@ -1,5 +0,0 @@
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
- }
@@ -1,19 +0,0 @@
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);