botframework-webchat-fluent-theme 4.18.1-main.20250515.4c7400a → 4.18.1-main.20250701.b63791f

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 (41) 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 +8 -8
  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 +8 -8
  11. package/dist/botframework-webchat-fluent-theme.production.min.js.map +1 -1
  12. package/package.json +6 -6
  13. package/src/components/activity/ActivityDecorator.module.css +12 -2
  14. package/src/components/dropZone/DropZone.tsx +2 -2
  15. package/src/components/icon/FluentIcon.module.css +53 -0
  16. package/src/components/icon/FluentIcon.tsx +51 -0
  17. package/src/components/icon/index.ts +1 -0
  18. package/src/components/preChatActivity/PreChatMessageActivity.module.css +1 -0
  19. package/src/components/preChatActivity/StarterPromptsCardAction.module.css +1 -1
  20. package/src/components/preChatActivity/StarterPromptsCardAction.tsx +7 -4
  21. package/src/components/sendBox/AddAttachmentButton.tsx +3 -2
  22. package/src/components/sendBox/SendBox.module.css +69 -5
  23. package/src/components/sendBox/SendBox.tsx +18 -14
  24. package/src/components/sendBox/TelephoneKeypadToolbarButton.tsx +2 -2
  25. package/src/components/sendBox/Toolbar.module.css +2 -0
  26. package/src/components/suggestedActions/SuggestedAction.tsx +2 -2
  27. package/src/components/suggestedActions/SuggestedActions.tsx +2 -2
  28. package/src/components/telephoneKeypad/private/TelephoneKeypad.tsx +4 -4
  29. package/src/components/theme/Theme.module.css +45 -45
  30. package/src/components/typingIndicator/SlidingDotsTypingIndicator.module.css +1 -1
  31. package/src/private/FluentThemeProvider.tsx +6 -10
  32. package/src/components/sendBox/Attachments.module.css +0 -7
  33. package/src/components/sendBox/Attachments.tsx +0 -35
  34. package/src/components/sendBox/TextArea.module.css +0 -82
  35. package/src/components/sendBox/TextArea.tsx +0 -111
  36. package/src/icons/AddDocumentIcon.tsx +0 -13
  37. package/src/icons/AttachmentIcon.tsx +0 -13
  38. package/src/icons/InfoSmallIcon.tsx +0 -13
  39. package/src/icons/SendIcon.tsx +0 -13
  40. package/src/icons/TelephoneKeypadIcon.tsx +0 -13
  41. package/src/icons/index.ts +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botframework-webchat-fluent-theme",
3
- "version": "4.18.1-main.20250515.4c7400a",
3
+ "version": "4.18.1-main.20250701.b63791f",
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",
@@ -68,15 +68,15 @@
68
68
  "@types/math-random": "^1.0.2",
69
69
  "@types/node": "^22.13.4",
70
70
  "@types/react": "^16.14.62",
71
- "botframework-webchat-base": "4.18.1-main.20250515.4c7400a",
72
- "botframework-webchat-styles": "4.18.1-main.20250515.4c7400a",
71
+ "botframework-webchat-base": "4.18.1-main.20250701.b63791f",
72
+ "botframework-webchat-styles": "4.18.1-main.20250701.b63791f",
73
73
  "tsup": "^8.3.6",
74
74
  "typescript": "^5.7.3"
75
75
  },
76
76
  "dependencies": {
77
- "botframework-webchat-api": "4.18.1-main.20250515.4c7400a",
78
- "botframework-webchat-component": "4.18.1-main.20250515.4c7400a",
79
- "botframework-webchat-core": "4.18.1-main.20250515.4c7400a",
77
+ "botframework-webchat-api": "4.18.1-main.20250701.b63791f",
78
+ "botframework-webchat-component": "4.18.1-main.20250701.b63791f",
79
+ "botframework-webchat-core": "4.18.1-main.20250701.b63791f",
80
80
  "classnames": "2.5.1",
81
81
  "inject-meta-tag": "0.0.1",
82
82
  "math-random": "2.0.1",
@@ -220,6 +220,12 @@
220
220
  }
221
221
  }
222
222
 
223
+ :global(.webchat-fluent)
224
+ .activity-decorator
225
+ :global(.webchat__stacked-layout .webchat__bubble .webchat__fileContent__downloadIcon) {
226
+ color: var(--webchat-colorBrandForegroundLink);
227
+ }
228
+
223
229
  /* Markdown links and citation links */
224
230
  :global(.webchat-fluent)
225
231
  .activity-decorator
@@ -271,9 +277,9 @@
271
277
  display: inline-flex;
272
278
  font-size: var(--webchat-fontSizeBase100);
273
279
  font-weight: var(--webchat-fontWeightSemibold);
274
- height: 14px;
280
+ min-height: 12.4px;
275
281
  justify-content: center;
276
- line-height: var(--webchat-lineHeightBase100);
282
+ line-height: 12.4px;
277
283
  margin-left: var(--webchat-spacingHorizontalXXS);
278
284
  margin-right: var(--webchat-spacingHorizontalXXS);
279
285
  min-width: 14px;
@@ -319,6 +325,10 @@
319
325
  color: var(--webchat-colorNeutralForeground3);
320
326
  }
321
327
 
328
+ :global(.webchat__link-definitions__message-sensitivity-label-text) {
329
+ color: var(--webchat-colorNeutralForeground4);
330
+ }
331
+
322
332
  :global(.webchat__link-definitions__header-chevron) {
323
333
  fill: var(--webchat-colorNeutralForeground3);
324
334
  font-size: var(--webchat__font-size--small);
@@ -11,7 +11,7 @@ import React, {
11
11
  } from 'react';
12
12
  import { useRefFrom } from 'use-ref-from';
13
13
 
14
- import { AddDocumentIcon } from '../../icons';
14
+ import { FluentIcon } from '../icon';
15
15
  import testIds from '../../testIds';
16
16
  import styles from './DropZone.module.css';
17
17
  import { useStyles } from '../../styles';
@@ -131,7 +131,7 @@ const DropZone = (props: { readonly onFilesAdded: (files: File[]) => void }) =>
131
131
  onDrop={handleDrop}
132
132
  ref={dropZoneRef}
133
133
  >
134
- <AddDocumentIcon className={classNames['sendbox__attachment-drop-zone-icon']} />
134
+ <FluentIcon appearance="text" className={classNames['sendbox__attachment-drop-zone-icon']} icon="add-document" />
135
135
  {localize('TEXT_INPUT_DROP_ZONE')}
136
136
  </div>
137
137
  ) : null;
@@ -0,0 +1,53 @@
1
+ :global(.webchat-fluent) .fluent-icon {
2
+ min-width: var(--webchat__fluent-icon--size, 1em);
3
+ min-height: var(--webchat__fluent-icon--size, 1em);
4
+ place-self: center;
5
+
6
+ /* Use the image as texture. */
7
+ background-image: var(--webchat__fluent-icon--image, none);
8
+ background-position: center;
9
+ background-repeat: no-repeat;
10
+ background-size: var(--webchat__fluent-icon--size, 1em);
11
+
12
+ /* If image is not set, fallback to solid color. */
13
+ background-color: var(--webchat__fluent-icon--color, transparent);
14
+
15
+ /* 3. Set the mask if any. */
16
+ -webkit-mask-image: var(--webchat__fluent-icon--mask);
17
+ -webkit-mask-position: center;
18
+ -webkit-mask-repeat: no-repeat;
19
+ -webkit-mask-size: var(--webchat__fluent-icon--size, 1em);
20
+ mask-image: var(--webchat__fluent-icon--mask);
21
+ mask-position: center;
22
+ mask-repeat: no-repeat;
23
+ mask-size: var(--webchat__fluent-icon--size, 1em);
24
+ }
25
+
26
+ /* #region: Appearance */
27
+ :global(.webchat) .appearance--text {
28
+ --webchat__fluent-icon--color: currentColor;
29
+ }
30
+ /* #endregion */
31
+
32
+ /* #region: Icons */
33
+ :global(.webchat) .icon--add-document {
34
+ --webchat__fluent-icon--mask: url('data:image/svg+xml;utf8,<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M6 2a2 2 0 0 0-2 2v5.2c.32-.08.66-.15 1-.18V4a1 1 0 0 1 1-1h4v3.5c0 .83.67 1.5 1.5 1.5H15v8a1 1 0 0 1-1 1h-3.6c-.18.36-.4.7-.66 1H14a2 2 0 0 0 2-2V7.41c0-.4-.16-.78-.44-1.06l-3.91-3.91A1.5 1.5 0 0 0 10.59 2H6Zm8.8 5h-3.3a.5.5 0 0 1-.5-.5V3.2L14.8 7ZM10 14.5a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Zm-4-2a.5.5 0 0 0-1 0V14H3.5a.5.5 0 0 0 0 1H5v1.5a.5.5 0 0 0 1 0V15h1.5a.5.5 0 0 0 0-1H6v-1.5Z"/></svg>');
35
+ }
36
+
37
+ :global(.webchat) .icon--attachment {
38
+ --webchat__fluent-icon--mask: url('data:image/svg+xml;utf8,<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="m4.83 10.48 5.65-5.65a3 3 0 0 1 4.25 4.24L8 15.8a1.5 1.5 0 0 1-2.12-2.12l6-6.01a.5.5 0 1 0-.7-.71l-6 6.01a2.5 2.5 0 0 0 3.53 3.54l6.71-6.72a4 4 0 1 0-5.65-5.66L4.12 9.78a.5.5 0 0 0 .7.7Z"/></svg>');
39
+ }
40
+
41
+ :global(.webchat) .icon--info-16 {
42
+ --webchat__fluent-icon--mask: url('data:image/svg+xml;utf8,<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8.5 7.5a.5.5 0 1 0-1 0v3a.5.5 0 0 0 1 0v-3Zm.25-2a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1ZM2 8a6 6 0 1 1 12 0A6 6 0 0 1 2 8Z"/></svg>');
43
+ }
44
+
45
+ :global(.webchat) .icon--send {
46
+ --webchat__fluent-icon--mask: url('data:image/svg+xml;utf8,<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M2.18 2.11a.5.5 0 0 1 .54-.06l15 7.5a.5.5 0 0 1 0 .9l-15 7.5a.5.5 0 0 1-.7-.58L3.98 10 2.02 2.63a.5.5 0 0 1 .16-.52Zm2.7 8.39-1.61 6.06L16.38 10 3.27 3.44 4.88 9.5h6.62a.5.5 0 1 1 0 1H4.88Z"/></svg>');
47
+ }
48
+
49
+ :global(.webchat) .icon--keypad {
50
+ --webchat__fluent-icon--mask: url('data:image/svg+xml;utf8,<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M6 5.25a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Zm0 4a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5ZM7.25 12a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0ZM10 5.25a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5ZM11.25 8a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0ZM10 13.25a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5ZM11.25 16a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0ZM14 5.25a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5ZM15.25 8a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0ZM14 13.25a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z"/></svg>');
51
+ }
52
+
53
+ /* #endregion */
@@ -0,0 +1,51 @@
1
+ import { createIconComponent } from 'botframework-webchat-component/internal';
2
+ import { validateProps } from 'botframework-webchat-react-valibot';
3
+ import { useStyles } from 'botframework-webchat-styles/react';
4
+ import cx from 'classnames';
5
+ import React, { memo, useMemo, type CSSProperties } from 'react';
6
+ import { object, optional, pipe, readonly, string, type InferInput } from 'valibot';
7
+
8
+ import styles from './FluentIcon.module.css';
9
+
10
+ const baseFluentIconPropsSchema = pipe(
11
+ object({
12
+ className: optional(string()),
13
+ mask: optional(string())
14
+ }),
15
+ readonly()
16
+ );
17
+
18
+ function BaseFluentIcon(props: InferInput<typeof baseFluentIconPropsSchema>) {
19
+ const { className } = validateProps(baseFluentIconPropsSchema, props);
20
+
21
+ const classNames = useStyles(styles);
22
+
23
+ const maskStyle = useMemo(
24
+ () =>
25
+ props.mask ? ({ '--webchat__fluent-icon--mask': `url(${JSON.stringify(props.mask)})` } as CSSProperties) : {},
26
+ [props.mask]
27
+ );
28
+
29
+ return <div className={cx(classNames['fluent-icon'], className)} style={maskStyle} />;
30
+ }
31
+
32
+ const { component: FluentIcon, modifierPropsSchema } = createIconComponent(
33
+ styles,
34
+ ['appearance', 'icon'],
35
+ BaseFluentIcon
36
+ );
37
+
38
+ FluentIcon.displayName = 'FluentIcon';
39
+
40
+ const fluentIconPropsSchema = pipe(
41
+ object({
42
+ ...baseFluentIconPropsSchema.entries,
43
+ ...modifierPropsSchema.entries
44
+ }),
45
+ readonly()
46
+ );
47
+
48
+ type FluentIconProps = InferInput<typeof fluentIconPropsSchema>;
49
+
50
+ export default memo(FluentIcon);
51
+ export { fluentIconPropsSchema, type FluentIconProps };
@@ -0,0 +1 @@
1
+ export { default as FluentIcon } from './FluentIcon';
@@ -46,6 +46,7 @@
46
46
  }
47
47
 
48
48
  :global(.webchat-fluent) .pre-chat-message-activity__body-subtitle {
49
+ color: var(--webchat-colorNeutralForeground1);
49
50
  font-size: var(--webchat-fontSizeBase300);
50
51
  line-height: var(--webchat-lineHeightBase300);
51
52
  overflow-wrap: anywhere;
@@ -18,7 +18,7 @@
18
18
  user-select: none;
19
19
 
20
20
  &:has(.pre-chat-message-activity__card-action-image) {
21
- grid-template-areas: 'image title' 'image subtitle';
21
+ grid-template-areas: 'image title' 'empty subtitle';
22
22
  grid-template-columns: 20px 1fr;
23
23
  }
24
24
 
@@ -1,14 +1,16 @@
1
- import { Components, hooks } from 'botframework-webchat-component';
1
+ import { hooks } from 'botframework-webchat-component';
2
2
  import { type DirectLineCardAction } from 'botframework-webchat-core';
3
3
  import cx from 'classnames';
4
4
  import React, { memo, useCallback, useMemo } from 'react';
5
5
  import { useRefFrom } from 'use-ref-from';
6
+
6
7
  import { useStyles } from '../../styles/index.js';
7
8
  import testIds from '../../testIds.js';
9
+ import { FluentIcon } from '../icon';
10
+
8
11
  import styles from './StarterPromptsCardAction.module.css';
9
12
 
10
13
  const { useFocus, useRenderMarkdownAsHTML, useSendBoxValue, useUIState } = hooks;
11
- const { MonochromeImageMasker } = Components;
12
14
 
13
15
  type Props = Readonly<{
14
16
  className?: string | undefined;
@@ -56,9 +58,10 @@ const StarterPromptsCardAction = ({ className, messageBackAction }: Props) => {
56
58
  >
57
59
  <div className={classNames['pre-chat-message-activity__card-action-title']}>{title}</div>
58
60
  {'image' in messageBackAction && messageBackAction.image && (
59
- <MonochromeImageMasker
61
+ <FluentIcon
62
+ appearance="text"
60
63
  className={classNames['pre-chat-message-activity__card-action-image']}
61
- src={messageBackAction.image}
64
+ mask={messageBackAction.image}
62
65
  />
63
66
  )}
64
67
  <div
@@ -1,7 +1,8 @@
1
1
  import { hooks } from 'botframework-webchat-component';
2
2
  import React, { useCallback, useRef, type ChangeEventHandler, memo } from 'react';
3
3
  import { useRefFrom } from 'use-ref-from';
4
- import { AttachmentIcon } from '../../icons';
4
+
5
+ import { FluentIcon } from '../icon';
5
6
  import testIds from '../../testIds';
6
7
  import { ToolbarButton } from './Toolbar';
7
8
  import styles from './AddAttachmentButton.module.css';
@@ -56,7 +57,7 @@ function AddAttachmentButton(
56
57
  data-testid={testIds.sendBoxUploadButton}
57
58
  onClick={handleClick}
58
59
  >
59
- <AttachmentIcon />
60
+ <FluentIcon appearance="text" icon="attachment" />
60
61
  </ToolbarButton>
61
62
  </div>
62
63
  );
@@ -33,8 +33,8 @@
33
33
  padding: 8px;
34
34
  position: relative;
35
35
 
36
- &:has(.sendbox__attachment--in-grid) {
37
- --webchat-sendbox-attachment-area-active: 'attachment';
36
+ &:has(.sendbox__attachment-bar--in-grid) {
37
+ --webchat-sendbox-attachment-area-active: 'attachment-bar';
38
38
  }
39
39
 
40
40
  &:focus-within {
@@ -64,8 +64,8 @@
64
64
  grid-area: text-area;
65
65
  }
66
66
 
67
- > .sendbox__attachment--in-grid {
68
- grid-area: attachment;
67
+ > .sendbox__attachment-bar--in-grid {
68
+ grid-area: attachment-bar;
69
69
  }
70
70
 
71
71
  > .sendbox__sendbox-controls--in-grid {
@@ -77,7 +77,69 @@
77
77
  }
78
78
  }
79
79
 
80
- :global(.webchat-fluent) .sendbox__sendbox-text {
80
+ :global(.webchat-fluent) .sendbox__attachment-bar:global(.send-box-attachment-bar) {
81
+ :global(.send-box-attachment-bar__box) {
82
+ gap: var(--webchat-spacingVerticalXS) var(--webchat-spacingHorizontalXS);
83
+ }
84
+
85
+ &:global(.send-box-attachment-bar--as-list-item) {
86
+ margin-inline-end: calc(-1 * var(--webchat-spacingHorizontalS));
87
+ }
88
+
89
+ &:global(.send-box-attachment-bar--as-list-item .send-box-attachment-bar__box:not(:empty)) {
90
+ padding: var(--webchat-spacingVerticalXS) var(--webchat-spacingHorizontalXS);
91
+ }
92
+
93
+ :global(.send-box-attachment-bar-item.send-box-attachment-bar-item--as-list-item) {
94
+ box-shadow: var(--webchat-shadow2);
95
+ border-radius: var(--webchat-borderRadiusMedium);
96
+ padding: var(--webchat-spacingVerticalXXS) var(--webchat-spacingHorizontalXXS);
97
+ }
98
+
99
+ :global(.send-box-attachment-bar-item.send-box-attachment-bar-item--as-thumbnail) {
100
+ border: var(--webchat-strokeWidthThin) solid var(--webchat-colorNeutralStroke1Selected);
101
+ border-radius: var(--webchat-borderRadiusXLarge);
102
+ }
103
+
104
+ :global(.send-box-attachment-bar-item .send-box-attachment-bar-item__delete-button) {
105
+ background-color: var(--webchat-colorNeutralBackground1);
106
+ border-radius: var(--webchat-borderRadiusMedium);
107
+ color: var(--webchat-colorNeutralForeground1);
108
+ transition: background-color var(--webchat-durationNormal) var(--webchat-curveAccelerateMid), color
109
+ var(--webchat-durationNormal) var(--webchat-curveAccelerateMid), opacity var(--webchat-durationUltraFast)
110
+ var(--webchat-curveAccelerateMid);
111
+
112
+ &:hover {
113
+ background-color: var(--webchat-colorNeutralBackground1Hover);
114
+ color: var(--webchat-colorNeutralForeground1Hover);
115
+ }
116
+
117
+ &:active {
118
+ background-color: var(--webchat-colorNeutralBackground1Pressed);
119
+ color: var(--webchat-colorNeutralForeground1Pressed);
120
+ }
121
+
122
+ &:disabled,
123
+ &[aria-disabled='true'] {
124
+ background-color: var(--webchat-colorNeutralBackgroundDisabled);
125
+ border-color: var(--webchat-colorNeutralStrokeDisabled);
126
+ color: var(--webchat-colorNeutralForegroundDisabled);
127
+ }
128
+ }
129
+
130
+ :global(
131
+ .send-box-attachment-bar-item.send-box-attachment-bar-item.send-box-attachment-bar-item.send-box-attachment-bar-item--as-list-item
132
+ .send-box-attachment-bar-item__preview
133
+ ) {
134
+ padding-inline: var(--webchat-spacingHorizontalS);
135
+ }
136
+
137
+ :global(.send-box-attachment-bar-item-file-preview.send-box-attachment-bar-item-file-preview--as-list-item) {
138
+ gap: var(--webchat-spacingVerticalS) var(--webchat-spacingHorizontalS);
139
+ }
140
+ }
141
+
142
+ :global(.webchat-fluent) .sendbox__sendbox-text-area {
81
143
  background-color: transparent;
82
144
  border: none;
83
145
  flex: auto;
@@ -88,6 +150,8 @@
88
150
  margin: var(--webchat-spacingVerticalXS) var(--webchat-spacingHorizontalXS) var(--webchat-spacingVerticalNone);
89
151
  resize: none;
90
152
 
153
+ --webchat__text-area--carret-color: var(--webchat-colorNeutralForeground1);
154
+
91
155
  /* Prevent zoom on focus on iOS */
92
156
  @media only screen and (hover: none) and (pointer: coarse) {
93
157
  &:focus-within {
@@ -1,4 +1,4 @@
1
- import { hooks, type SendBoxFocusOptions } from 'botframework-webchat-component';
1
+ import { hooks, Components, type SendBoxFocusOptions } from 'botframework-webchat-component';
2
2
  import cx from 'classnames';
3
3
  import React, {
4
4
  memo,
@@ -10,21 +10,20 @@ import React, {
10
10
  type MouseEventHandler
11
11
  } from 'react';
12
12
  import { useRefFrom } from 'use-ref-from';
13
- import { SendIcon } from '../../icons';
13
+
14
+ import { FluentIcon } from '../icon';
14
15
  import { useStyles, useVariantClassName } from '../../styles';
15
16
  import testIds from '../../testIds';
16
17
  import { DropZone } from '../dropZone';
17
18
  import { SuggestedActions } from '../suggestedActions';
18
19
  import { TelephoneKeypadSurrogate, useTelephoneKeypadShown, type DTMF } from '../telephoneKeypad';
19
20
  import AddAttachmentButton from './AddAttachmentButton';
20
- import Attachments from './Attachments';
21
21
  import ErrorMessage from './ErrorMessage';
22
22
  import useSubmitError from './private/useSubmitError';
23
23
  import useTranscriptNavigation from './private/useTranscriptNavigation';
24
24
  import useUniqueId from './private/useUniqueId';
25
25
  import styles from './SendBox.module.css';
26
26
  import TelephoneKeypadToolbarButton from './TelephoneKeypadToolbarButton';
27
- import TextArea from './TextArea';
28
27
  import { Toolbar, ToolbarButton, ToolbarSeparator } from './Toolbar';
29
28
 
30
29
  const {
@@ -39,6 +38,8 @@ const {
39
38
  useUIState
40
39
  } = hooks;
41
40
 
41
+ const { AttachmentBar, TextArea } = Components;
42
+
42
43
  type Props = Readonly<{
43
44
  className?: string | undefined;
44
45
  completion?: ReactNode | undefined;
@@ -138,14 +139,9 @@ function SendBox(props: Props) {
138
139
  )
139
140
  );
140
141
 
141
- setAttachments(newAttachments);
142
-
143
- // TODO: Currently in the UX, we have no way to remove attachments.
144
- // Keep concatenating doesn't make sense in current UX.
145
- // When end-user can remove attachment, we should enable the code again.
146
- // setAttachments(attachments => attachments.concat(newAttachments));
142
+ setAttachments(attachmentsRef.current.concat(newAttachments));
147
143
  },
148
- [makeThumbnail, setAttachments]
144
+ [attachmentsRef, makeThumbnail, setAttachments]
149
145
  );
150
146
 
151
147
  const handleFormSubmit: FormEventHandler<HTMLFormElement> = useCallback(
@@ -206,7 +202,7 @@ function SendBox(props: Props) {
206
202
  >
207
203
  <TextArea
208
204
  aria-label={isMessageLengthExceeded ? localize('TEXT_INPUT_LENGTH_EXCEEDED_ALT') : localize('TEXT_INPUT_ALT')}
209
- className={cx(classNames['sendbox__sendbox-text'], classNames['sendbox__text-area--in-grid'])}
205
+ className={cx(classNames['sendbox__sendbox-text-area'], classNames['sendbox__text-area--in-grid'])}
210
206
  completion={props.completion}
211
207
  data-testid={testIds.sendBoxTextBox}
212
208
  hidden={shouldShowTelephoneKeypad}
@@ -221,7 +217,15 @@ function SendBox(props: Props) {
221
217
  isHorizontal={false}
222
218
  onButtonClick={handleTelephoneKeypadButtonClick}
223
219
  />
224
- <Attachments attachments={attachments} className={classNames['sendbox__attachment--in-grid']} />
220
+ {!isBlueprint && (
221
+ <AttachmentBar
222
+ className={cx(
223
+ 'webchat__send-box__attachment-bar',
224
+ classNames['sendbox__attachment-bar'],
225
+ classNames['sendbox__attachment-bar--in-grid']
226
+ )}
227
+ />
228
+ )}
225
229
  <div className={cx(classNames['sendbox__sendbox-controls'], classNames['sendbox__sendbox-controls--in-grid'])}>
226
230
  {shouldShowMessageLength && (
227
231
  <div
@@ -242,7 +246,7 @@ function SendBox(props: Props) {
242
246
  disabled={isMessageLengthExceeded || shouldShowTelephoneKeypad}
243
247
  type="submit"
244
248
  >
245
- <SendIcon />
249
+ <FluentIcon appearance="text" icon="send" />
246
250
  </ToolbarButton>
247
251
  </Toolbar>
248
252
  </div>
@@ -1,7 +1,7 @@
1
1
  import React, { memo, useCallback } from 'react';
2
2
 
3
3
  import { hooks } from 'botframework-webchat-component';
4
- import { TelephoneKeypadIcon } from '../../icons';
4
+ import { FluentIcon } from '../icon';
5
5
  import testIds from '../../testIds';
6
6
  import { useTelephoneKeypadShown } from '../telephoneKeypad';
7
7
  import { ToolbarButton } from './Toolbar';
@@ -21,7 +21,7 @@ const TelephoneKeypadToolbarButton = memo(() => {
21
21
  onClick={handleClick}
22
22
  selected={telephoneKeypadShown}
23
23
  >
24
- <TelephoneKeypadIcon />
24
+ <FluentIcon appearance="text" icon="keypad" />
25
25
  </ToolbarButton>
26
26
  );
27
27
  });
@@ -21,6 +21,8 @@
21
21
  justify-content: center;
22
22
  padding: 3px;
23
23
 
24
+ --webchat__fluent-icon--size: 20px;
25
+
24
26
  > :global(.webchat__monochrome-image-masker) {
25
27
  font-size: 20px;
26
28
  pointer-events: none;
@@ -9,7 +9,7 @@ import AccessibleButton from './AccessibleButton';
9
9
  import { useRovingFocusItemRef } from './private/rovingFocus';
10
10
  import styles from './SuggestedAction.module.css';
11
11
 
12
- const { useFocus, usePerformCardAction, useScrollToEnd, useStyleSet, useSuggestedActions, useUIState } = hooks;
12
+ const { useFocus, usePerformCardAction, useScrollToEnd, useStyleSet, useSuggestedActionsHooks, useUIState } = hooks;
13
13
 
14
14
  type SuggestedActionProps = Readonly<{
15
15
  buttonText: string | undefined;
@@ -44,7 +44,7 @@ function SuggestedAction({
44
44
  type,
45
45
  value
46
46
  }: SuggestedActionProps) {
47
- const [_, setSuggestedActions] = useSuggestedActions();
47
+ const [_, setSuggestedActions] = useSuggestedActionsHooks().useSuggestedActions();
48
48
  const [{ suggestedAction: suggestedActionStyleSet }] = useStyleSet();
49
49
  const [uiState] = useUIState();
50
50
  const focus = useFocus();
@@ -8,7 +8,7 @@ import RovingFocusProvider from './private/rovingFocus';
8
8
  import SuggestedAction from './SuggestedAction';
9
9
  import styles from './SuggestedActions.module.css';
10
10
 
11
- const { useFocus, useLocalizer, useStyleOptions, useStyleSet, useSuggestedActions, useUIState } = hooks;
11
+ const { useFocus, useLocalizer, useStyleOptions, useStyleSet, useSuggestedActionsHooks, useUIState } = hooks;
12
12
 
13
13
  function SuggestedActionStackedOrFlowContainer(
14
14
  props: Readonly<{
@@ -45,7 +45,7 @@ function SuggestedActionStackedOrFlowContainer(
45
45
  function SuggestedActions() {
46
46
  const classNames = useStyles(styles);
47
47
  const localize = useLocalizer();
48
- const [suggestedActions, _, { activity }] = useSuggestedActions();
48
+ const [suggestedActions, _, { activity }] = useSuggestedActionsHooks().useSuggestedActions();
49
49
  const focus = useFocus();
50
50
 
51
51
  const handleEscapeKey = useCallback(() => {
@@ -3,14 +3,14 @@ import cx from 'classnames';
3
3
  import React, { memo, useCallback, useEffect, useRef, type KeyboardEventHandler, type ReactNode } from 'react';
4
4
  import { useRefFrom } from 'use-ref-from';
5
5
 
6
- import Button from './Button';
7
6
  // import HorizontalDialPadController from './HorizontalDialPadController';
7
+ import { useStyles } from '../../../styles';
8
8
  import testIds from '../../../testIds';
9
+ import { FluentIcon } from '../../icon';
9
10
  import { type DTMF } from '../types';
10
11
  import useShown from '../useShown';
12
+ import Button from './Button';
11
13
  import styles from './TelephoneKeypad.module.css';
12
- import { useStyles } from '../../../styles';
13
- import { InfoSmallIcon } from '../../../icons';
14
14
 
15
15
  const { LocalizedString } = Components;
16
16
 
@@ -128,7 +128,7 @@ const TelephoneKeypad = memo(({ autoFocus, className, onButtonClick, isHorizonta
128
128
  <Button button="#" data-testid={testIds.sendBoxTelephoneKeypadButtonPound} onClick={handleButtonPoundClick} />
129
129
  </Orientation>
130
130
  <div className={classNames['telephone-keypad__info-message']}>
131
- <InfoSmallIcon />
131
+ <FluentIcon appearance="text" icon="info-16" />
132
132
  <LocalizedString
133
133
  linkClassName={classNames['telephone-keypad__info-message-link']}
134
134
  stringIds="TELEPHONE_KEYPAD_INPUT_MESSAGE"