botframework-webchat-fluent-theme 4.17.0-main.20240416.e3f5401 → 4.17.0-main.20240419.2240f2a
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.development.css.map +1 -0
- package/dist/botframework-webchat-fluent-theme.development.js +418 -2085
- package/dist/botframework-webchat-fluent-theme.development.js.map +1 -1
- package/dist/botframework-webchat-fluent-theme.production.min.css.map +1 -0
- package/dist/botframework-webchat-fluent-theme.production.min.js +1 -3
- package/dist/botframework-webchat-fluent-theme.production.min.js.map +1 -1
- package/dist/index.css.map +1 -0
- package/dist/index.js +285 -545
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +335 -595
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -5
- package/src/components/Theme.module.css +65 -0
- package/src/components/Theme.tsx +4 -65
- package/src/components/dropZone/index.module.css +23 -0
- package/src/components/dropZone/index.tsx +6 -31
- package/src/components/sendbox/AddAttachmentButton.module.css +10 -0
- package/src/components/sendbox/AddAttachmentButton.tsx +5 -17
- package/src/components/sendbox/Attachments.module.css +7 -0
- package/src/components/sendbox/Attachments.tsx +7 -13
- package/src/components/sendbox/ErrorMessage.module.css +9 -0
- package/src/components/sendbox/ErrorMessage.tsx +2 -13
- package/src/components/sendbox/TelephoneKeypadToolbarButton.tsx +3 -2
- package/src/components/sendbox/TextArea.module.css +63 -0
- package/src/components/sendbox/TextArea.tsx +9 -70
- package/src/components/sendbox/Toolbar.module.css +51 -0
- package/src/components/sendbox/Toolbar.tsx +7 -55
- package/src/components/sendbox/index.module.css +86 -0
- package/src/components/sendbox/index.tsx +18 -77
- package/src/components/suggestedActions/SuggestedAction.module.css +35 -0
- package/src/components/suggestedActions/SuggestedAction.tsx +3 -43
- package/src/components/suggestedActions/index.module.css +23 -0
- package/src/components/suggestedActions/index.tsx +6 -29
- package/src/components/telephoneKeypad/private/Button.module.css +62 -0
- package/src/components/telephoneKeypad/private/Button.tsx +5 -67
- package/src/components/telephoneKeypad/private/TelephoneKeypad.module.css +59 -0
- package/src/components/telephoneKeypad/private/TelephoneKeypad.tsx +17 -35
- package/src/env.d.ts +7 -0
- package/src/icons/AddDocumentIcon.tsx +0 -1
- package/src/icons/AttachmentIcon.tsx +0 -1
- package/src/icons/InfoSmallIcon.tsx +17 -0
- package/src/icons/SendIcon.tsx +0 -1
- package/src/icons/TelephoneKeypad.tsx +0 -1
- package/src/index.ts +3 -0
- package/src/styles/injectStyle.ts +9 -0
- package/src/styles/useStyles.ts +19 -0
- package/src/styles.ts +4 -0
- package/src/tsconfig.json +2 -1
- package/src/private/useStyleToEmotionObject.ts +0 -32
- package/src/styles/index.ts +0 -15
package/src/components/Theme.tsx
CHANGED
|
@@ -1,72 +1,11 @@
|
|
|
1
1
|
import React, { type ReactNode } from 'react';
|
|
2
|
+
import cx from 'classnames';
|
|
3
|
+
import styles from './Theme.module.css';
|
|
2
4
|
import { useStyles } from '../styles';
|
|
3
5
|
|
|
4
|
-
const
|
|
5
|
-
'webchat-fluent__theme': {
|
|
6
|
-
display: 'contents',
|
|
7
|
-
|
|
8
|
-
'--webchat-colorNeutralForeground1': 'var(--colorNeutralForeground1, #242424)',
|
|
9
|
-
'--webchat-colorNeutralForeground2': 'var(--colorNeutralForeground2, #424242)',
|
|
10
|
-
'--webchat-colorNeutralForeground4': 'var(--colorNeutralForeground4, #707070)',
|
|
11
|
-
|
|
12
|
-
'--webchat-colorNeutralForegroundDisabled': 'var(--colorNeutralForegroundDisabled, #bdbdbd)',
|
|
13
|
-
|
|
14
|
-
'--webchat-colorNeutralBackground1': 'var(--colorNeutralBackground1, #ffffff)',
|
|
15
|
-
'--webchat-colorNeutralBackground4': 'var(--colorNeutralBackground4, #f0f0f0)',
|
|
16
|
-
'--webchat-colorNeutralBackground5': 'var(--colorNeutralBackground5, #ebebeb)',
|
|
17
|
-
|
|
18
|
-
'--webchat-colorSubtleBackgroundHover': 'var(--colorSubtleBackgroundHover, #f5f5f5)',
|
|
19
|
-
'--webchat-colorSubtleBackgroundPressed': 'var(--colorSubtleBackgroundPressed, #e0e0e0)',
|
|
20
|
-
|
|
21
|
-
'--webchat-colorNeutralStroke1': 'var(--colorNeutralStroke1, #d1d1d1)',
|
|
22
|
-
'--webchat-colorNeutralStroke2': 'var(--colorNeutralStroke2, #e0e0e0)',
|
|
23
|
-
'--webchat-colorNeutralStroke1Selected': 'var(--colorNeutralStroke1Selected, #bdbdbd)',
|
|
24
|
-
|
|
25
|
-
'--webchat-colorBrandStroke2': 'var(--colorBrandStroke2, #9edcf7)',
|
|
26
|
-
|
|
27
|
-
'--webchat-colorBrandForeground2Hover': 'var(--colorBrandForeground2Hover, #015a7a)',
|
|
28
|
-
'--webchat-colorBrandForeground2Pressed': 'var(--colorBrandForeground2Pressed, #01384d)',
|
|
29
|
-
|
|
30
|
-
'--webchat-colorBrandBackground2Hover': 'var(--colorBrandBackground2Hover, #bee7fa)',
|
|
31
|
-
'--webchat-colorBrandBackground2Pressed': 'var(--colorBrandBackground2Pressed, #7fd2f5)',
|
|
32
|
-
|
|
33
|
-
'--webchat-colorCompoundBrandForeground1': 'var(--colorCompoundBrandForeground1, #077fab)',
|
|
34
|
-
|
|
35
|
-
'--webchat-colorCompoundBrandForeground1Hover': 'var(--colorCompoundBrandForeground1Hover, #02729c)',
|
|
36
|
-
'--webchat-colorCompoundBrandForeground1Pressed': 'var(--colorCompoundBrandForeground1Pressed, #01678c)',
|
|
37
|
-
|
|
38
|
-
'--webchat-colorStatusDangerForeground1': 'var(--colorStatusDangerForeground1, #b10e1c)',
|
|
39
|
-
|
|
40
|
-
// https://github.com/microsoft/fluentui/blob/master/packages/theme/src/colors/FluentColors.ts
|
|
41
|
-
'--webchat-colorGray30': 'var(--colorGray30, #edebe9)',
|
|
42
|
-
'--webchat-colorGray160': 'var(--colorGray160, #323130)',
|
|
43
|
-
'--webchat-colorGray190': 'var(--colorGray190, #201f1e)',
|
|
44
|
-
'--webchat-colorGray200': 'var(--colorGray200, #1b1a19)',
|
|
45
|
-
|
|
46
|
-
// https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/borderRadius.ts
|
|
47
|
-
'--webchat-borderRadiusSmall': 'var(--borderRadiusSmall, 2px)',
|
|
48
|
-
'--webchat-borderRadiusLarge': 'var(--borderRadiusLarge, 6px)',
|
|
49
|
-
'--webchat-borderRadiusXLarge': 'var(--borderRadiusXLarge, 8px)',
|
|
50
|
-
|
|
51
|
-
// https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/utils/shadows.ts
|
|
52
|
-
'--webchat-shadow16':
|
|
53
|
-
'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))',
|
|
54
|
-
|
|
55
|
-
// https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/spacings.ts
|
|
56
|
-
'--webchat-spacingHorizontalMNudge': 'var(--spacingHorizontalMNudge, 10px)',
|
|
57
|
-
|
|
58
|
-
// https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/fonts.ts
|
|
59
|
-
'--webchat-fontFamilyBase': `var(--fontFamilyBase, 'Segoe UI)', 'Segoe UI Web (West European))', -apple-system,
|
|
60
|
-
BlinkMacSystemFont, Roboto, 'Helvetica Neue)', sans-serif)`,
|
|
61
|
-
'--webchat-fontFamilyNumeric': `var(--fontFamilyNumeric, Bahnschrift, 'Segoe UI)', 'Segoe UI Web (West European))',
|
|
62
|
-
-apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue)', sans-serif)`,
|
|
63
|
-
|
|
64
|
-
// https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/fonts.ts
|
|
65
|
-
'--webchat-fontWeightSemibold': 'var(--fontWeightSemibold, 600)'
|
|
66
|
-
}
|
|
67
|
-
};
|
|
6
|
+
export const rootClassName = 'webchat-fluent';
|
|
68
7
|
|
|
69
8
|
export default function WebchatTheme(props: Readonly<{ readonly children: ReactNode | undefined }>) {
|
|
70
9
|
const classNames = useStyles(styles);
|
|
71
|
-
return <div className={classNames['
|
|
10
|
+
return <div className={cx(rootClassName, classNames['theme'])}>{props.children}</div>;
|
|
72
11
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
:global(.webchat-fluent) .sendbox__attachment-drop-zone {
|
|
2
|
+
background-color: var(--webchat-colorNeutralBackground4);
|
|
3
|
+
border-radius: inherit;
|
|
4
|
+
cursor: copy;
|
|
5
|
+
display: grid;
|
|
6
|
+
gap: 8px;
|
|
7
|
+
inset: 0;
|
|
8
|
+
place-content: center;
|
|
9
|
+
place-items: center;
|
|
10
|
+
position: absolute;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
:global(.webchat-fluent) .sendbox__attachment-drop-zone--droppable {
|
|
14
|
+
background-color: #e00;
|
|
15
|
+
color: White
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
:global(.webchat-fluent) .sendbox__attachment-drop-zone-icon {
|
|
19
|
+
height: 36px;
|
|
20
|
+
/* Set "pointer-events: none" to ignore dragging over the icon. Otherwise, when dragging over the icon; it would disable the "--droppable" modifier.*/
|
|
21
|
+
pointer-events: none;
|
|
22
|
+
width: 36px
|
|
23
|
+
}
|
|
@@ -1,40 +1,15 @@
|
|
|
1
|
-
import { hooks } from 'botframework-webchat-
|
|
1
|
+
import { hooks } from 'botframework-webchat-component';
|
|
2
2
|
import cx from 'classnames';
|
|
3
3
|
import React, { memo, useCallback, useEffect, useRef, useState, type DragEventHandler } from 'react';
|
|
4
4
|
import { useRefFrom } from 'use-ref-from';
|
|
5
5
|
|
|
6
6
|
import { AddDocumentIcon } from '../../icons/AddDocumentIcon';
|
|
7
|
-
import { useStyles } from '../../styles';
|
|
8
7
|
import testIds from '../../testIds';
|
|
8
|
+
import styles from './index.module.css';
|
|
9
|
+
import { useStyles } from '../../styles';
|
|
9
10
|
|
|
10
11
|
const { useLocalizer } = hooks;
|
|
11
12
|
|
|
12
|
-
const styles = {
|
|
13
|
-
'webchat-fluent__sendbox__attachment-drop-zone': {
|
|
14
|
-
backgroundColor: 'var(--webchat-colorNeutralBackground4)',
|
|
15
|
-
borderRadius: 'inherit',
|
|
16
|
-
cursor: 'copy',
|
|
17
|
-
display: 'grid',
|
|
18
|
-
gap: '8px',
|
|
19
|
-
inset: '0',
|
|
20
|
-
placeContent: 'center',
|
|
21
|
-
placeItems: 'center',
|
|
22
|
-
position: 'absolute'
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
'webchat-fluent__sendbox__attachment-drop-zone--droppable': {
|
|
26
|
-
backgroundColor: '#e00',
|
|
27
|
-
color: 'White'
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
'webchat-fluent__sendbox__attachment-drop-zone-icon': {
|
|
31
|
-
height: '36px',
|
|
32
|
-
// Set "pointer-events: none" to ignore dragging over the icon. Otherwise, when dragging over the icon, it would disable the "--droppable" modifier.
|
|
33
|
-
pointerEvents: 'none',
|
|
34
|
-
width: '36px'
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
|
|
38
13
|
const handleDragOver: DragEventHandler<HTMLDivElement> = event => {
|
|
39
14
|
// This is for preventing the browser from opening the dropped file in a new tab.
|
|
40
15
|
event.preventDefault();
|
|
@@ -113,15 +88,15 @@ const DropZone = (props: { readonly onFilesAdded: (files: File[]) => void }) =>
|
|
|
113
88
|
|
|
114
89
|
return dropZoneState ? (
|
|
115
90
|
<div
|
|
116
|
-
className={cx(classNames['
|
|
117
|
-
[classNames['
|
|
91
|
+
className={cx(classNames['sendbox__attachment-drop-zone'], {
|
|
92
|
+
[classNames['sendbox__attachment-drop-zone--droppable']]: dropZoneState === 'droppable'
|
|
118
93
|
})}
|
|
119
94
|
data-testid={testIds.sendBoxDropZone}
|
|
120
95
|
onDragOver={handleDragOver}
|
|
121
96
|
onDrop={handleDrop}
|
|
122
97
|
ref={dropZoneRef}
|
|
123
98
|
>
|
|
124
|
-
<AddDocumentIcon className={classNames['
|
|
99
|
+
<AddDocumentIcon className={classNames['sendbox__attachment-drop-zone-icon']} />
|
|
125
100
|
{localize('TEXT_INPUT_DROP_ZONE')}
|
|
126
101
|
</div>
|
|
127
102
|
) : null;
|
|
@@ -1,26 +1,14 @@
|
|
|
1
|
-
import { hooks } from 'botframework-webchat-
|
|
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
|
import { AttachmentIcon } from '../../icons/AttachmentIcon';
|
|
5
|
-
import { useStyles } from '../../styles';
|
|
6
5
|
import testIds from '../../testIds';
|
|
7
6
|
import { ToolbarButton } from './Toolbar';
|
|
7
|
+
import styles from './AddAttachmentButton.module.css';
|
|
8
|
+
import { useStyles } from '../../styles';
|
|
8
9
|
|
|
9
10
|
const { useLocalizer, useStyleOptions } = hooks;
|
|
10
11
|
|
|
11
|
-
const styles = {
|
|
12
|
-
'webchat-fluent__sendbox__add-attachment': {
|
|
13
|
-
display: 'grid'
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
'webchat-fluent__sendbox__add-attachment-input': {
|
|
17
|
-
fontSize: 0,
|
|
18
|
-
height: 0,
|
|
19
|
-
opacity: 0,
|
|
20
|
-
width: 0
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
12
|
function AddAttachmentButton(
|
|
25
13
|
props: Readonly<{
|
|
26
14
|
disabled?: boolean | undefined;
|
|
@@ -49,12 +37,12 @@ function AddAttachmentButton(
|
|
|
49
37
|
);
|
|
50
38
|
|
|
51
39
|
return (
|
|
52
|
-
<div className={classNames['
|
|
40
|
+
<div className={classNames['sendbox__add-attachment']}>
|
|
53
41
|
<input
|
|
54
42
|
accept={uploadAccept}
|
|
55
43
|
aria-disabled={props.disabled}
|
|
56
44
|
aria-hidden="true"
|
|
57
|
-
className={classNames['
|
|
45
|
+
className={classNames['sendbox__add-attachment-input']}
|
|
58
46
|
multiple={uploadMultiple}
|
|
59
47
|
onInput={props.disabled ? undefined : handleFileChange}
|
|
60
48
|
readOnly={props.disabled}
|
|
@@ -1,19 +1,11 @@
|
|
|
1
|
-
import { hooks } from 'botframework-webchat-
|
|
1
|
+
import { hooks } from 'botframework-webchat-component';
|
|
2
2
|
import React, { memo } from 'react';
|
|
3
|
+
import cx from 'classnames';
|
|
4
|
+
import styles from './Attachments.module.css';
|
|
3
5
|
import { useStyles } from '../../styles';
|
|
4
6
|
|
|
5
7
|
const { useLocalizer } = hooks;
|
|
6
8
|
|
|
7
|
-
const styles = {
|
|
8
|
-
'webchat-fluent__sendbox__attachment': {
|
|
9
|
-
border: '1px solid var(--webchat-colorNeutralStroke1)',
|
|
10
|
-
borderRadius: 'var(--webchat-borderRadiusLarge)',
|
|
11
|
-
cursor: 'default',
|
|
12
|
-
padding: '6px 8px',
|
|
13
|
-
width: 'fit-content'
|
|
14
|
-
}
|
|
15
|
-
};
|
|
16
|
-
|
|
17
9
|
const attachmentsPluralStringIds = {
|
|
18
10
|
one: 'TEXT_INPUT_ATTACHMENTS_ONE',
|
|
19
11
|
two: 'TEXT_INPUT_ATTACHMENTS_TWO',
|
|
@@ -23,15 +15,17 @@ const attachmentsPluralStringIds = {
|
|
|
23
15
|
};
|
|
24
16
|
|
|
25
17
|
function Attachments({
|
|
26
|
-
attachments
|
|
18
|
+
attachments,
|
|
19
|
+
className
|
|
27
20
|
}: Readonly<{
|
|
28
21
|
readonly attachments: readonly Readonly<{ blob: Blob | File; thumbnailURL?: URL | undefined }>[];
|
|
22
|
+
readonly className?: string | undefined;
|
|
29
23
|
}>) {
|
|
30
24
|
const classNames = useStyles(styles);
|
|
31
25
|
const localizeWithPlural = useLocalizer({ plural: true });
|
|
32
26
|
|
|
33
27
|
return attachments.length ? (
|
|
34
|
-
<div className={classNames['
|
|
28
|
+
<div className={cx(classNames['sendbox__attachment'], className)}>
|
|
35
29
|
{localizeWithPlural(attachmentsPluralStringIds, attachments.length)}
|
|
36
30
|
</div>
|
|
37
31
|
) : null;
|
|
@@ -1,23 +1,12 @@
|
|
|
1
1
|
import React, { memo } from 'react';
|
|
2
|
+
import styles from './ErrorMessage.module.css';
|
|
2
3
|
import { useStyles } from '../../styles';
|
|
3
4
|
|
|
4
|
-
const styles = {
|
|
5
|
-
'webchat-fluent___sendbox__error-message': {
|
|
6
|
-
fontSize: 0,
|
|
7
|
-
height: 0,
|
|
8
|
-
width: 0,
|
|
9
|
-
position: 'absolute',
|
|
10
|
-
top: 0,
|
|
11
|
-
left: 0,
|
|
12
|
-
color: 'transparent'
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
|
|
16
5
|
function ErrorMessage(props: Readonly<{ id: string; error?: string | undefined }>) {
|
|
17
6
|
const classNames = useStyles(styles);
|
|
18
7
|
return (
|
|
19
8
|
// eslint-disable-next-line react/forbid-dom-props
|
|
20
|
-
<span className={classNames['
|
|
9
|
+
<span className={classNames['sendbox__error-message']} id={props.id} role="alert">
|
|
21
10
|
{props.error}
|
|
22
11
|
</span>
|
|
23
12
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { memo, useCallback } from 'react';
|
|
2
2
|
|
|
3
|
-
import { hooks } from 'botframework-webchat-
|
|
3
|
+
import { hooks } from 'botframework-webchat-component';
|
|
4
4
|
import { TelephoneKeypadIcon } from '../../icons/TelephoneKeypad';
|
|
5
5
|
import testIds from '../../testIds';
|
|
6
6
|
import { useTelephoneKeypadShown } from '../TelephoneKeypad';
|
|
@@ -9,7 +9,7 @@ import { ToolbarButton } from './Toolbar';
|
|
|
9
9
|
const { useLocalizer } = hooks;
|
|
10
10
|
|
|
11
11
|
const TelephoneKeypadToolbarButton = memo(() => {
|
|
12
|
-
const [, setTelephoneKeypadShown] = useTelephoneKeypadShown();
|
|
12
|
+
const [telephoneKeypadShown, setTelephoneKeypadShown] = useTelephoneKeypadShown();
|
|
13
13
|
const localize = useLocalizer();
|
|
14
14
|
|
|
15
15
|
const handleClick = useCallback(() => setTelephoneKeypadShown(shown => !shown), [setTelephoneKeypadShown]);
|
|
@@ -19,6 +19,7 @@ const TelephoneKeypadToolbarButton = memo(() => {
|
|
|
19
19
|
aria-label={localize('TEXT_INPUT_TELEPHONE_KEYPAD_BUTTON_ALT')}
|
|
20
20
|
data-testid={testIds.sendBoxTelephoneKeypadToolbarButton}
|
|
21
21
|
onClick={handleClick}
|
|
22
|
+
selected={telephoneKeypadShown}
|
|
22
23
|
>
|
|
23
24
|
<TelephoneKeypadIcon />
|
|
24
25
|
</ToolbarButton>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
:global(.webchat-fluent) .sendbox__text-area {
|
|
2
|
+
display: grid;
|
|
3
|
+
grid-template-areas: 'main';
|
|
4
|
+
max-height: 200px;
|
|
5
|
+
overflow: hidden;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
:global(.webchat-fluent) .sendbox__text-area--hidden {
|
|
9
|
+
/* TODO: Not perfect way of hiding the text box. */
|
|
10
|
+
height: 0;
|
|
11
|
+
visibility: collapse;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:global(.webchat-fluent) .sendbox__text-area-shared {
|
|
15
|
+
border: none;
|
|
16
|
+
font: inherit;
|
|
17
|
+
grid-area: main;
|
|
18
|
+
outline: inherit;
|
|
19
|
+
overflow-wrap: anywhere;
|
|
20
|
+
resize: inherit;
|
|
21
|
+
scrollbar-gutter: stable;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
:global(.webchat-fluent) .sendbox__text-area-doppelganger {
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
visibility: hidden;
|
|
27
|
+
white-space: pre-wrap;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
:global(.webchat-fluent) .sendbox__text-area-input {
|
|
31
|
+
background-color: inherit;
|
|
32
|
+
color: currentColor;
|
|
33
|
+
height: 100%;
|
|
34
|
+
padding: 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
:global(.webchat-fluent) .sendbox__text-area-input--scroll {
|
|
38
|
+
/* Edge uses -webkit-scrollbar if scrollbar-* is not set */
|
|
39
|
+
scrollbar-color: unset;
|
|
40
|
+
scrollbar-width: unset;
|
|
41
|
+
/* Firefox */
|
|
42
|
+
-moz-scrollbar-color: var(--webchat-colorNeutralBackground5) var(--webchat-colorNeutralForeground2);
|
|
43
|
+
-moz-scrollbar-width: thin;
|
|
44
|
+
|
|
45
|
+
/* Chrome, Edge, and Safari */
|
|
46
|
+
&::-webkit-scrollbar {
|
|
47
|
+
width: 8px
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&::-webkit-scrollbar-track {
|
|
51
|
+
background-color: var(--webchat-colorNeutralBackground5);
|
|
52
|
+
border-radius: 16px
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&::-webkit-scrollbar-thumb {
|
|
56
|
+
background-color: var(--webchat-colorNeutralForeground2);
|
|
57
|
+
border-radius: 16px
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
&::-webkit-scrollbar-corner {
|
|
61
|
+
background-color: var(--webchat-colorNeutralBackground5);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -1,68 +1,7 @@
|
|
|
1
1
|
import cx from 'classnames';
|
|
2
2
|
import React, { forwardRef, useCallback, type FormEventHandler, type KeyboardEventHandler } from 'react';
|
|
3
|
-
|
|
4
3
|
import { useStyles } from '../../styles';
|
|
5
|
-
|
|
6
|
-
const styles = {
|
|
7
|
-
'webchat-fluent__sendbox__text-area': {
|
|
8
|
-
display: 'grid',
|
|
9
|
-
gridTemplateAreas: `'main'`,
|
|
10
|
-
maxHeight: '200px',
|
|
11
|
-
overflow: 'hidden'
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
'webchat-fluent__sendbox__text-area--hidden': {
|
|
15
|
-
// TODO: Not perfect way of hiding the text box.
|
|
16
|
-
height: 0,
|
|
17
|
-
visibility: 'collapse'
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
'webchat-fluent__sendbox__text-area-shared': {
|
|
21
|
-
border: 'none',
|
|
22
|
-
font: 'inherit',
|
|
23
|
-
gridArea: 'main',
|
|
24
|
-
outline: 'inherit',
|
|
25
|
-
overflowWrap: 'anywhere',
|
|
26
|
-
resize: 'inherit',
|
|
27
|
-
scrollbarGutter: 'stable'
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
'webchat-fluent__sendbox__text-area-doppelganger': {
|
|
31
|
-
overflow: 'hidden',
|
|
32
|
-
visibility: 'hidden',
|
|
33
|
-
whiteSpace: 'pre-wrap'
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
'webchat-fluent__sendbox__text-area-input': {
|
|
37
|
-
height: '100%',
|
|
38
|
-
padding: 0
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
'webchat-fluent__sendbox__text-area-input--scroll': {
|
|
42
|
-
/* Firefox */
|
|
43
|
-
MozScrollbarColor: 'var(--webchat-colorNeutralBackground5) var(--webchat-colorNeutralForeground2)',
|
|
44
|
-
MozScrollbarWidth: 'thin',
|
|
45
|
-
|
|
46
|
-
/* Chrome, Edge, and Safari */
|
|
47
|
-
'&::-webkit-scrollbar': {
|
|
48
|
-
width: '8px'
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
'&::-webkit-scrollbar-track': {
|
|
52
|
-
backgroundColor: 'var(--webchat-colorNeutralBackground5)',
|
|
53
|
-
borderRadius: '16px'
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
'&::-webkit-scrollbar-thumb': {
|
|
57
|
-
backgroundColor: 'var(--webchat-colorNeutralForeground2)',
|
|
58
|
-
borderRadius: '16px'
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
'&::-webkit-scrollbar-corner': {
|
|
62
|
-
backgroundColor: 'var(--webchat-colorNeutralBackground5)'
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
};
|
|
4
|
+
import styles from './TextArea.module.css';
|
|
66
5
|
|
|
67
6
|
const TextArea = forwardRef<
|
|
68
7
|
HTMLTextAreaElement,
|
|
@@ -103,9 +42,9 @@ const TextArea = forwardRef<
|
|
|
103
42
|
return (
|
|
104
43
|
<div
|
|
105
44
|
className={cx(
|
|
106
|
-
classNames['
|
|
45
|
+
classNames['sendbox__text-area'],
|
|
107
46
|
{
|
|
108
|
-
[classNames['
|
|
47
|
+
[classNames['sendbox__text-area--hidden']]: props.hidden
|
|
109
48
|
},
|
|
110
49
|
props.className
|
|
111
50
|
)}
|
|
@@ -113,9 +52,9 @@ const TextArea = forwardRef<
|
|
|
113
52
|
>
|
|
114
53
|
<div
|
|
115
54
|
className={cx(
|
|
116
|
-
classNames['
|
|
117
|
-
classNames['
|
|
118
|
-
classNames['
|
|
55
|
+
classNames['sendbox__text-area-doppelganger'],
|
|
56
|
+
classNames['sendbox__text-area-shared'],
|
|
57
|
+
classNames['sendbox__text-area-input--scroll']
|
|
119
58
|
)}
|
|
120
59
|
>
|
|
121
60
|
{props.value || props.placeholder}{' '}
|
|
@@ -123,9 +62,9 @@ const TextArea = forwardRef<
|
|
|
123
62
|
<textarea
|
|
124
63
|
aria-label={props['aria-label']}
|
|
125
64
|
className={cx(
|
|
126
|
-
classNames['
|
|
127
|
-
classNames['
|
|
128
|
-
classNames['
|
|
65
|
+
classNames['sendbox__text-area-input'],
|
|
66
|
+
classNames['sendbox__text-area-shared'],
|
|
67
|
+
classNames['sendbox__text-area-input--scroll']
|
|
129
68
|
)}
|
|
130
69
|
data-testid={props['data-testid']}
|
|
131
70
|
onInput={props.onInput}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
:global(.webchat-fluent) .sendbox__toolbar {
|
|
2
|
+
display: flex;
|
|
3
|
+
gap: 4px;
|
|
4
|
+
margin-inline-start: auto;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
:global(.webchat-fluent) .sendbox__toolbar-button {
|
|
8
|
+
align-items: center;
|
|
9
|
+
appearance: none;
|
|
10
|
+
aspect-ratio: 1;
|
|
11
|
+
background: transparent;
|
|
12
|
+
border-radius: var(--webchat-borderRadiusSmall);
|
|
13
|
+
border: none;
|
|
14
|
+
color: currentColor;
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
display: flex;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
padding: 3px;
|
|
19
|
+
width: 32px;
|
|
20
|
+
|
|
21
|
+
> svg {
|
|
22
|
+
font-size: 20px;
|
|
23
|
+
pointer-events: none;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&.sendbox__toolbar-button--selected {
|
|
27
|
+
color: var(--webchat-colorNeutralForeground2BrandSelected);
|
|
28
|
+
}
|
|
29
|
+
@media (hover: hover) {
|
|
30
|
+
&:not([aria-disabled="true"]):hover {
|
|
31
|
+
color: var(--webchat-colorNeutralForeground2BrandHover);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
&:not([aria-disabled="true"]):active {
|
|
35
|
+
color: var(--webchat-colorNeutralForeground2BrandPressed);
|
|
36
|
+
}
|
|
37
|
+
&[aria-disabled="true"] {
|
|
38
|
+
color: var(--webchat-colorNeutralForegroundDisabled);
|
|
39
|
+
cursor: not-allowed;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:global(.webchat-fluent) .sendbox__toolbar-separator {
|
|
44
|
+
align-self: center;
|
|
45
|
+
border-inline-end: 1px solid var(--webchat-colorNeutralStroke2);
|
|
46
|
+
height: 28px;
|
|
47
|
+
|
|
48
|
+
&:first-child, &:last-child, &:only-child {
|
|
49
|
+
display: none
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -1,59 +1,8 @@
|
|
|
1
1
|
import cx from 'classnames';
|
|
2
2
|
import React, { memo, type MouseEventHandler, type ReactNode } from 'react';
|
|
3
|
+
import styles from './Toolbar.module.css';
|
|
3
4
|
import { useStyles } from '../../styles';
|
|
4
5
|
|
|
5
|
-
const styles = {
|
|
6
|
-
'webchat-fluent__sendbox__toolbar': {
|
|
7
|
-
display: 'flex',
|
|
8
|
-
gap: '4px',
|
|
9
|
-
marginInlineStart: 'auto'
|
|
10
|
-
},
|
|
11
|
-
|
|
12
|
-
'webchat-fluent__sendbox__toolbar-button': {
|
|
13
|
-
alignItems: 'center',
|
|
14
|
-
appearance: 'none',
|
|
15
|
-
aspectRatio: '1',
|
|
16
|
-
background: 'transparent',
|
|
17
|
-
border: 'none',
|
|
18
|
-
borderRadius: 'var(--webchat-borderRadiusSmall)',
|
|
19
|
-
cursor: 'pointer',
|
|
20
|
-
display: 'flex',
|
|
21
|
-
justifyContent: 'center',
|
|
22
|
-
padding: '3px',
|
|
23
|
-
width: '32px',
|
|
24
|
-
|
|
25
|
-
'> svg': {
|
|
26
|
-
fontSize: '20px',
|
|
27
|
-
pointerEvents: 'none'
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
'@media (hover: hover)': {
|
|
31
|
-
'&:not([aria-disabled="true"]):hover': {
|
|
32
|
-
backgroundColor: 'var(--webchat-colorSubtleBackgroundHover)',
|
|
33
|
-
color: 'var(--webchat-colorCompoundBrandForeground1Hover)'
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
'&:not([aria-disabled="true"]):active': {
|
|
37
|
-
backgroundColor: 'var(--webchat-colorSubtleBackgroundPressed)',
|
|
38
|
-
color: 'var(--webchat-colorCompoundBrandForeground1Pressed)'
|
|
39
|
-
},
|
|
40
|
-
'&[aria-disabled="true"]': {
|
|
41
|
-
color: 'var(--webchat-colorNeutralForegroundDisabled)',
|
|
42
|
-
cursor: 'not-allowed'
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
'webchat-fluent__sendbox__toolbar-separator': {
|
|
47
|
-
alignSelf: 'center',
|
|
48
|
-
borderInlineEnd: '1px solid var(--webchat-colorNeutralStroke2)',
|
|
49
|
-
height: '28px',
|
|
50
|
-
|
|
51
|
-
'&:first-child, &:last-child, &:only-child': {
|
|
52
|
-
display: 'none'
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
6
|
const preventDefaultHandler: MouseEventHandler<HTMLButtonElement> = event => event.preventDefault();
|
|
58
7
|
|
|
59
8
|
export const ToolbarButton = memo(
|
|
@@ -65,6 +14,7 @@ export const ToolbarButton = memo(
|
|
|
65
14
|
'data-testid'?: string | undefined;
|
|
66
15
|
disabled?: boolean | undefined;
|
|
67
16
|
onClick?: MouseEventHandler<HTMLButtonElement> | undefined;
|
|
17
|
+
selected?: boolean | undefined;
|
|
68
18
|
type?: 'button' | 'submit' | undefined;
|
|
69
19
|
}>
|
|
70
20
|
) => {
|
|
@@ -73,7 +23,9 @@ export const ToolbarButton = memo(
|
|
|
73
23
|
return (
|
|
74
24
|
<button
|
|
75
25
|
aria-label={props['aria-label']}
|
|
76
|
-
className={cx(classNames['
|
|
26
|
+
className={cx(classNames['sendbox__toolbar-button'], props.className, {
|
|
27
|
+
[classNames['sendbox__toolbar-button--selected']]: props.selected
|
|
28
|
+
})}
|
|
77
29
|
data-testid={props['data-testid']}
|
|
78
30
|
onClick={props.disabled ? preventDefaultHandler : props.onClick}
|
|
79
31
|
type={props.type === 'submit' ? 'submit' : 'button'}
|
|
@@ -93,7 +45,7 @@ ToolbarButton.displayName = 'ToolbarButton';
|
|
|
93
45
|
export const Toolbar = memo((props: Readonly<{ children?: ReactNode | undefined; className?: string | undefined }>) => {
|
|
94
46
|
const classNames = useStyles(styles);
|
|
95
47
|
|
|
96
|
-
return <div className={cx(classNames['
|
|
48
|
+
return <div className={cx(classNames['sendbox__toolbar'], props.className)}>{props.children}</div>;
|
|
97
49
|
});
|
|
98
50
|
|
|
99
51
|
Toolbar.displayName = 'Toolbar';
|
|
@@ -105,7 +57,7 @@ export const ToolbarSeparator = memo(
|
|
|
105
57
|
return (
|
|
106
58
|
<div
|
|
107
59
|
aria-orientation="vertical"
|
|
108
|
-
className={cx(classNames['
|
|
60
|
+
className={cx(classNames['sendbox__toolbar-separator'], props.className)}
|
|
109
61
|
role="separator"
|
|
110
62
|
/>
|
|
111
63
|
);
|