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.
- package/dist/botframework-webchat-fluent-theme.css.map +1 -1
- package/dist/botframework-webchat-fluent-theme.development.css.map +1 -1
- package/dist/botframework-webchat-fluent-theme.development.js +8 -8
- package/dist/botframework-webchat-fluent-theme.development.js.map +1 -1
- package/dist/botframework-webchat-fluent-theme.js +1 -1
- package/dist/botframework-webchat-fluent-theme.js.map +1 -1
- package/dist/botframework-webchat-fluent-theme.mjs +1 -1
- package/dist/botframework-webchat-fluent-theme.mjs.map +1 -1
- package/dist/botframework-webchat-fluent-theme.production.min.css.map +1 -1
- package/dist/botframework-webchat-fluent-theme.production.min.js +8 -8
- package/dist/botframework-webchat-fluent-theme.production.min.js.map +1 -1
- package/package.json +6 -6
- package/src/components/activity/ActivityDecorator.module.css +12 -2
- package/src/components/dropZone/DropZone.tsx +2 -2
- package/src/components/icon/FluentIcon.module.css +53 -0
- package/src/components/icon/FluentIcon.tsx +51 -0
- package/src/components/icon/index.ts +1 -0
- package/src/components/preChatActivity/PreChatMessageActivity.module.css +1 -0
- package/src/components/preChatActivity/StarterPromptsCardAction.module.css +1 -1
- package/src/components/preChatActivity/StarterPromptsCardAction.tsx +7 -4
- package/src/components/sendBox/AddAttachmentButton.tsx +3 -2
- package/src/components/sendBox/SendBox.module.css +69 -5
- package/src/components/sendBox/SendBox.tsx +18 -14
- package/src/components/sendBox/TelephoneKeypadToolbarButton.tsx +2 -2
- package/src/components/sendBox/Toolbar.module.css +2 -0
- package/src/components/suggestedActions/SuggestedAction.tsx +2 -2
- package/src/components/suggestedActions/SuggestedActions.tsx +2 -2
- package/src/components/telephoneKeypad/private/TelephoneKeypad.tsx +4 -4
- package/src/components/theme/Theme.module.css +45 -45
- package/src/components/typingIndicator/SlidingDotsTypingIndicator.module.css +1 -1
- package/src/private/FluentThemeProvider.tsx +6 -10
- package/src/components/sendBox/Attachments.module.css +0 -7
- package/src/components/sendBox/Attachments.tsx +0 -35
- package/src/components/sendBox/TextArea.module.css +0 -82
- package/src/components/sendBox/TextArea.tsx +0 -111
- package/src/icons/AddDocumentIcon.tsx +0 -13
- package/src/icons/AttachmentIcon.tsx +0 -13
- package/src/icons/InfoSmallIcon.tsx +0 -13
- package/src/icons/SendIcon.tsx +0 -13
- package/src/icons/TelephoneKeypadIcon.tsx +0 -13
- 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.
|
|
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.
|
|
72
|
-
"botframework-webchat-styles": "4.18.1-main.
|
|
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.
|
|
78
|
-
"botframework-webchat-component": "4.18.1-main.
|
|
79
|
-
"botframework-webchat-core": "4.18.1-main.
|
|
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:
|
|
280
|
+
min-height: 12.4px;
|
|
275
281
|
justify-content: center;
|
|
276
|
-
line-height:
|
|
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 {
|
|
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
|
-
<
|
|
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';
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import {
|
|
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
|
-
<
|
|
61
|
+
<FluentIcon
|
|
62
|
+
appearance="text"
|
|
60
63
|
className={classNames['pre-chat-message-activity__card-action-image']}
|
|
61
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
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) .
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
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 {
|
|
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
|
-
<
|
|
24
|
+
<FluentIcon appearance="text" icon="keypad" />
|
|
25
25
|
</ToolbarButton>
|
|
26
26
|
);
|
|
27
27
|
});
|
|
@@ -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,
|
|
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,
|
|
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
|
-
<
|
|
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"
|