Skip to content

Commit 6c68093

Browse files
authored
Fluent: implement initial completion (#5466)
* WIP: completion * more conditions * Fix scroll in Chrome * Changelog * sort
1 parent 7c4e5a8 commit 6c68093

14 files changed

+153
-30
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ Notes: web developers are advised to use [`~` (tilde range)](https://github.com/
8484
- Set `styleOptions.speechRecognitionContinuous` to `true` with a Web Speech API provider with continuous mode support
8585
- Added support of [contentless activity in livestream](https://github.com/microsoft/BotFramework-WebChat/blob/main/docs/LIVESTREAMING.md#scenario-3-interim-activities-with-no-content), in PR [#5430](https://github.com/microsoft/BotFramework-WebChat/pull/5430), by [@compulim](https://github.com/compulim)
8686
- Added sliding dots typing indicator in Fluent theme, in PR [#5447](https://github.com/microsoft/BotFramework-WebChat/pull/5447) and PR [#5448](https://github.com/microsoft/BotFramework-WebChat/pull/5448), by [@compulim](https://github.com/compulim)
87+
- (Experimental) Add an ability to pass `completion` prop into Fluent send box and expose the component, in PR [#5466](https://github.com/microsoft/BotFramework-WebChat/pull/5466), by [@OEvgeny](https://github.com/OEvgeny)
8788

8889
### Changed
8990

-16.7 KB
Loading

__tests__/html/fluentTheme/transcript.navigation.pageUpDown.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
await pageConditions.scrollStabilized();
7070
await host.snapshot();
7171

72-
// Should page up because the send box is no longer empty
72+
// Should page up because the send box is now empty
7373
await host.sendKeys('BACK_SPACE', 'PAGE_UP');
7474
await pageConditions.scrollStabilized();
7575
await host.snapshot();
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<!doctype html>
2+
<html lang="en-US">
3+
4+
<head>
5+
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
6+
<script crossorigin="anonymous" src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script>
7+
<script crossorigin="anonymous" src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
8+
<script crossorigin="anonymous" src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
9+
<script crossorigin="anonymous" src="/test-harness.js"></script>
10+
<script crossorigin="anonymous" src="/test-page-object.js"></script>
11+
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
12+
<script crossorigin="anonymous" src="/__dist__/botframework-webchat-fluent-theme.production.min.js"></script>
13+
<style>
14+
.completion {
15+
opacity: 0.75;
16+
}
17+
</style>
18+
</head>
19+
20+
<body>
21+
<main id="webchat"></main>
22+
<script type="text/babel">
23+
run(async function () {
24+
const {
25+
React,
26+
ReactDOM: { render },
27+
WebChat: {
28+
FluentThemeProvider, FluentSendBox, testIds,
29+
Components: { BasicWebChat, Composer },
30+
hooks: { useSendBoxValue }
31+
}
32+
} = window; // Imports in UMD fashion.
33+
34+
const { directLine, store } = testHelpers.createDirectLineEmulator();
35+
36+
const PrimarySendBox = (props) => {
37+
const [globalMessage, setGlobalMessage] = useSendBoxValue();
38+
const [completion, setCompletion] = React.useState('Aloha');
39+
40+
41+
const handleKeyDown = (event) => {
42+
if (event.key === 'Tab' && !event.shiftKey && event.target.localName === 'textarea' && globalMessage && completion) {
43+
event.preventDefault();
44+
setGlobalMessage([globalMessage, completion].join(' '))
45+
setCompletion('');
46+
}
47+
}
48+
49+
const completionNode = globalMessage && completion
50+
? <>{globalMessage} <span className="completion">{completion} (press <kbd>Tab</kbd> to complete)</span></>
51+
: undefined;
52+
53+
return (
54+
<div onKeyDown={handleKeyDown}>
55+
<FluentSendBox {...props} completion={completionNode} isPrimary={true} />
56+
</div>
57+
);
58+
};
59+
60+
const sendBoxMiddleware = [() => () => () => PrimarySendBox];
61+
62+
const App = () => (
63+
<Composer directLine={directLine} store={store} sendBoxMiddleware={sendBoxMiddleware}>
64+
<BasicWebChat />
65+
</Composer>
66+
);
67+
68+
render(
69+
<FluentThemeProvider>
70+
<App />
71+
</FluentThemeProvider>,
72+
document.getElementById('webchat')
73+
);
74+
75+
await pageConditions.uiConnected();
76+
77+
document.querySelector(`[data-testid="${testIds.sendBoxTextBox}"]`).focus();
78+
79+
await host.snapshot('local');
80+
81+
// WHEN: The text typed in.
82+
await host.sendKeys('Hello');
83+
84+
// THEN: Send box should have completion.
85+
await host.snapshot('local');
86+
87+
// WHEN: The tab is pressed.
88+
await host.sendTab();
89+
90+
// THEN: Text should be completed and completion should be gone.
91+
await host.snapshot('local');
92+
93+
// WHEN: The tab is pressed 2nd time.
94+
await host.sendTab();
95+
96+
// THEN: The focus moves out of the Sendbox.
97+
await host.snapshot('local');
98+
});
99+
</script>
100+
</body>
101+
102+
</html>
6.34 KB
Loading
8.12 KB
Loading
5.36 KB
Loading
5.63 KB
Loading

packages/fluent-theme/src/bundle.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { SendBox as FluentSendBox } from './components/sendBox/index';
12
import { FluentThemeProvider, testIds } from './index';
23

34
(globalThis as any).WebChat = {
45
...(globalThis as any).WebChat,
56
FluentThemeProvider,
7+
FluentSendBox,
68
testIds: {
79
...(globalThis as any).WebChat?.testIds,
810
...testIds

packages/fluent-theme/src/components/sendBox/SendBox.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
font-size: 14px;
8686
line-height: 20px;
8787
outline: none;
88-
padding: 4px 4px 0;
88+
margin: var(--webchat-spacingVerticalXS) var(--webchat-spacingHorizontalXS) var(--webchat-spacingVerticalNone);
8989
resize: none;
9090

9191
/* Prevent zoom on focus on iOS */

0 commit comments

Comments
 (0)