botframework-webchat-fluent-theme 4.18.1-main.20250325.438c779 → 4.18.1-main.20250423.6c68093

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botframework-webchat-fluent-theme",
3
- "version": "4.18.1-main.20250325.438c779",
3
+ "version": "4.18.1-main.20250423.6c68093",
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",
@@ -72,15 +72,15 @@
72
72
  "@types/math-random": "^1.0.2",
73
73
  "@types/node": "^22.13.4",
74
74
  "@types/react": "^16.14.62",
75
- "botframework-webchat-base": "4.18.1-main.20250325.438c779",
76
- "botframework-webchat-styles": "4.18.1-main.20250325.438c779",
75
+ "botframework-webchat-base": "4.18.1-main.20250423.6c68093",
76
+ "botframework-webchat-styles": "4.18.1-main.20250423.6c68093",
77
77
  "tsup": "^8.3.6",
78
78
  "typescript": "^5.7.3"
79
79
  },
80
80
  "dependencies": {
81
- "botframework-webchat-api": "4.18.1-main.20250325.438c779",
82
- "botframework-webchat-component": "4.18.1-main.20250325.438c779",
83
- "botframework-webchat-core": "4.18.1-main.20250325.438c779",
81
+ "botframework-webchat-api": "4.18.1-main.20250423.6c68093",
82
+ "botframework-webchat-component": "4.18.1-main.20250423.6c68093",
83
+ "botframework-webchat-core": "4.18.1-main.20250423.6c68093",
84
84
  "classnames": "2.5.1",
85
85
  "inject-meta-tag": "0.0.1",
86
86
  "math-random": "2.0.1",
package/src/bundle.ts CHANGED
@@ -1,8 +1,10 @@
1
+ import { SendBox as FluentSendBox } from './components/sendBox/index';
1
2
  import { FluentThemeProvider, testIds } from './index';
2
3
 
3
4
  (globalThis as any).WebChat = {
4
5
  ...(globalThis as any).WebChat,
5
6
  FluentThemeProvider,
7
+ FluentSendBox,
6
8
  testIds: {
7
9
  ...(globalThis as any).WebChat?.testIds,
8
10
  ...testIds
@@ -85,7 +85,7 @@
85
85
  font-size: 14px;
86
86
  line-height: 20px;
87
87
  outline: none;
88
- padding: 4px 4px 0;
88
+ margin: var(--webchat-spacingVerticalXS) var(--webchat-spacingHorizontalXS) var(--webchat-spacingVerticalNone);
89
89
  resize: none;
90
90
 
91
91
  /* Prevent zoom on focus on iOS */
@@ -1,6 +1,14 @@
1
1
  import { hooks, type SendBoxFocusOptions } from 'botframework-webchat-component';
2
2
  import cx from 'classnames';
3
- import React, { memo, useCallback, useRef, useState, type FormEventHandler, type MouseEventHandler } from 'react';
3
+ import React, {
4
+ memo,
5
+ ReactNode,
6
+ useCallback,
7
+ useRef,
8
+ useState,
9
+ type FormEventHandler,
10
+ type MouseEventHandler
11
+ } from 'react';
4
12
  import { useRefFrom } from 'use-ref-from';
5
13
  import { SendIcon } from '../../icons';
6
14
  import { useStyles, useVariantClassName } from '../../styles';
@@ -33,6 +41,7 @@ const {
33
41
 
34
42
  type Props = Readonly<{
35
43
  className?: string | undefined;
44
+ completion?: ReactNode | undefined;
36
45
  isPrimary?: boolean | undefined;
37
46
  placeholder?: string | undefined;
38
47
  }>;
@@ -198,6 +207,7 @@ function SendBox(props: Props) {
198
207
  <TextArea
199
208
  aria-label={isMessageLengthExceeded ? localize('TEXT_INPUT_LENGTH_EXCEEDED_ALT') : localize('TEXT_INPUT_ALT')}
200
209
  className={cx(classNames['sendbox__sendbox-text'], classNames['sendbox__text-area--in-grid'])}
210
+ completion={props.completion}
201
211
  data-testid={testIds.sendBoxTextBox}
202
212
  hidden={shouldShowTelephoneKeypad}
203
213
  onInput={handleMessageChange}
@@ -2,7 +2,8 @@
2
2
  display: grid;
3
3
  grid-template-areas: 'main';
4
4
  max-height: 200px;
5
- overflow: hidden;
5
+ overflow: auto;
6
+ scrollbar-gutter: stable;
6
7
  }
7
8
 
8
9
  :global(.webchat-fluent) .sendbox__text-area--hidden {
@@ -11,6 +12,22 @@
11
12
  visibility: collapse;
12
13
  }
13
14
 
15
+ :global(.webchat-fluent) .sendbox__text-area--in-completion {
16
+ .sendbox__text-area-doppelganger {
17
+ visibility: visible;
18
+ }
19
+
20
+ .sendbox__text-area-input {
21
+ background-color: transparent;
22
+ caret-color: var(--webchat-colorNeutralForeground1);
23
+ color: transparent;
24
+ }
25
+
26
+ textarea::placeholder {
27
+ color: transparent;
28
+ }
29
+ }
30
+
14
31
  :global(.webchat-fluent) .sendbox__text-area-shared {
15
32
  border: none;
16
33
  font: inherit;
@@ -18,11 +35,12 @@
18
35
  outline: inherit;
19
36
  overflow-wrap: anywhere;
20
37
  resize: inherit;
21
- scrollbar-gutter: stable;
22
38
  }
23
39
 
24
40
  :global(.webchat-fluent) .sendbox__text-area-doppelganger {
25
- overflow: hidden;
41
+ overflow: visible;
42
+ pointer-events: none;
43
+ user-select: none;
26
44
  visibility: hidden;
27
45
  white-space: pre-wrap;
28
46
  }
@@ -30,11 +48,12 @@
30
48
  :global(.webchat-fluent) .sendbox__text-area-input {
31
49
  background-color: inherit;
32
50
  color: currentColor;
33
- height: 100%;
51
+ contain: size;
52
+ overflow: hidden;
34
53
  padding: 0;
35
54
  }
36
55
 
37
- :global(.webchat-fluent) .sendbox__text-area-input--scroll {
56
+ :global(.webchat-fluent) .sendbox__text-area--scroll {
38
57
  /* Edge uses -webkit-scrollbar if scrollbar-* is not set */
39
58
  scrollbar-color: unset;
40
59
  scrollbar-width: unset;
@@ -1,6 +1,14 @@
1
1
  import { hooks } from 'botframework-webchat-api';
2
2
  import cx from 'classnames';
3
- import React, { forwardRef, Fragment, useCallback, type FormEventHandler, type KeyboardEventHandler } from 'react';
3
+ import React, {
4
+ forwardRef,
5
+ Fragment,
6
+ useCallback,
7
+ useRef,
8
+ type FormEventHandler,
9
+ type KeyboardEventHandler,
10
+ type ReactNode
11
+ } from 'react';
4
12
  import { useStyles } from '../../styles';
5
13
  import styles from './TextArea.module.css';
6
14
 
@@ -11,6 +19,7 @@ const TextArea = forwardRef<
11
19
  Readonly<{
12
20
  'aria-label'?: string | undefined;
13
21
  className?: string | undefined;
22
+ completion?: ReactNode | undefined;
14
23
  'data-testid'?: string | undefined;
15
24
 
16
25
  /**
@@ -30,13 +39,22 @@ const TextArea = forwardRef<
30
39
  >((props, ref) => {
31
40
  const [uiState] = useUIState();
32
41
  const classNames = useStyles(styles);
42
+ const isInCompositionRef = useRef<boolean>(false);
33
43
 
34
44
  const disabled = uiState === 'disabled';
35
45
 
46
+ const handleCompositionEnd = useCallback(() => {
47
+ isInCompositionRef.current = false;
48
+ }, [isInCompositionRef]);
49
+
50
+ const handleCompositionStart = useCallback(() => {
51
+ isInCompositionRef.current = true;
52
+ }, [isInCompositionRef]);
53
+
36
54
  const handleKeyDown = useCallback<KeyboardEventHandler<HTMLTextAreaElement>>(event => {
37
55
  // Shift+Enter adds a new line
38
56
  // Enter requests related form submission
39
- if (!event.shiftKey && event.key === 'Enter') {
57
+ if (!event.shiftKey && event.key === 'Enter' && !isInCompositionRef.current) {
40
58
  event.preventDefault();
41
59
 
42
60
  if ('form' in event.target && event.target.form instanceof HTMLFormElement) {
@@ -49,41 +67,29 @@ const TextArea = forwardRef<
49
67
  <div
50
68
  className={cx(
51
69
  classNames['sendbox__text-area'],
70
+ classNames['sendbox__text-area--scroll'],
52
71
  { [classNames['sendbox__text-area--hidden']]: props.hidden },
72
+ { [classNames['sendbox__text-area--in-completion']]: props.completion },
53
73
  props.className
54
74
  )}
55
75
  role={props.hidden ? 'hidden' : undefined}
56
76
  >
57
77
  {uiState === 'blueprint' ? (
58
- <div
59
- className={cx(
60
- classNames['sendbox__text-area-doppelganger'],
61
- classNames['sendbox__text-area-input--scroll'],
62
- classNames['sendbox__text-area-shared']
63
- )}
64
- >
78
+ <div className={cx(classNames['sendbox__text-area-doppelganger'], classNames['sendbox__text-area-shared'])}>
65
79
  {' '}
66
80
  </div>
67
81
  ) : (
68
82
  <Fragment>
69
- <div
70
- className={cx(
71
- classNames['sendbox__text-area-doppelganger'],
72
- classNames['sendbox__text-area-input--scroll'],
73
- classNames['sendbox__text-area-shared']
74
- )}
75
- >
76
- {props.value || props.placeholder}{' '}
83
+ <div className={cx(classNames['sendbox__text-area-doppelganger'], classNames['sendbox__text-area-shared'])}>
84
+ {props.completion ? props.completion : props.value || props.placeholder}{' '}
77
85
  </div>
78
86
  <textarea
79
87
  aria-disabled={disabled}
80
88
  aria-label={props['aria-label']}
81
- className={cx(
82
- classNames['sendbox__text-area-input'],
83
- classNames['sendbox__text-area-input--scroll'],
84
- classNames['sendbox__text-area-shared']
85
- )}
89
+ className={cx(classNames['sendbox__text-area-input'], classNames['sendbox__text-area-shared'])}
86
90
  data-testid={props['data-testid']}
91
+ onCompositionEnd={handleCompositionEnd}
92
+ onCompositionStart={handleCompositionStart}
87
93
  onInput={props.onInput}
88
94
  onKeyDown={handleKeyDown}
89
95
  placeholder={props.placeholder}
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { injectMetaTag } from 'inject-meta-tag';
2
2
 
3
+ import { SendBox as FluentSendBox } from './components/sendBox/index';
3
4
  import FluentThemeProvider from './private/FluentThemeProvider';
4
5
  import testIds from './testIds';
5
6
 
@@ -14,4 +15,4 @@ injectMetaTag(
14
15
  `version=${process.env['npm_package_version']}; build-tool=${process.env['build_tool']}; module-format=${process.env['module_format']}`
15
16
  );
16
17
 
17
- export { FluentThemeProvider, buildInfo, testIds };
18
+ export { FluentThemeProvider, FluentSendBox, buildInfo, testIds };