Skip to content

Commit c30e4e2

Browse files
authored
Fluent: suggested actions roving focus (#5154)
* Fluent: suggested actions roving focus * Changelog * Update packages/fluent-theme/src/components/suggestedActions/private/rovingFocus.tsx * fix nit
1 parent 71714d3 commit c30e4e2

16 files changed

+469
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
5555
- Added an information message to the telephone keypad, in PR [#5140](https://github.com/microsoft/BotFramework-WebChat/pull/5140)
5656
- Added animation to focus indicator and pixel-perfected, in PR [#5143](https://github.com/microsoft/BotFramework-WebChat/pull/5143)
5757
- Integrated focus management for send box, in PR [#5150](https://github.com/microsoft/BotFramework-WebChat/pull/5150), by [@OEvgeny](https://github.com/OEvgeny)
58+
- Added keyboard navigation support into suggested actions, in PR [#5154](https://github.com/microsoft/BotFramework-WebChat/pull/5154), by [@OEvgeny](https://github.com/OEvgeny)
5859
- (Experimental) Added `<LocalizeString />` component which can be used to localize strings, by [@OEvgeny](https://github.com/OEvgeny) in PR [#5140](https://github.com/microsoft/BotFramework-WebChat/pull/5140)
5960
- Added `<ThemeProvider>` component to apply theme pack to Web Chat, by [@compulim](https://github.com/compulim), in PR [#5120](https://github.com/microsoft/BotFramework-WebChat/pull/5120)
6061
- Added `useMakeThumbnail` hook option to create a thumbnail from the file given, by [@compulim](https://github.com/compulim), in PR [#5123](https://github.com/microsoft/BotFramework-WebChat/pull/5123) and [#5122](https://github.com/microsoft/BotFramework-WebChat/pull/5122)
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
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/standalone/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+
</head>
14+
15+
<body>
16+
<main id="webchat"></main>
17+
<script type="text/babel">
18+
run(async function () {
19+
const {
20+
React,
21+
ReactDOM: { render },
22+
WebChat: { FluentThemeProvider, ReactWebChat }
23+
} = window; // Imports in UMD fashion.
24+
25+
const { directLine, store } = testHelpers.createDirectLineEmulator();
26+
27+
const App = () => <ReactWebChat directLine={directLine} store={store} />;
28+
29+
render(
30+
<FluentThemeProvider>
31+
<App />
32+
</FluentThemeProvider>,
33+
document.getElementById('webchat')
34+
);
35+
36+
await pageConditions.uiConnected();
37+
38+
await directLine.emulateIncomingActivity({
39+
type: 'message',
40+
textFormat: 'plain',
41+
text: 'Please select one of the actions below',
42+
suggestedActions: {
43+
actions: [
44+
{
45+
image: `https://raw.githubusercontent.com/compulim/BotFramework-MockBot/master/public/assets/square-icon.png`,
46+
imageAltText: 'a blue square',
47+
title: 'IM back as string',
48+
type: 'imBack',
49+
value: 'postback imback-string'
50+
},
51+
{
52+
image: `https://raw.githubusercontent.com/compulim/BotFramework-MockBot/master/public/assets/square-icon-red.png`,
53+
imageAltText: 'a red square',
54+
title: 'Post back as string',
55+
type: 'postBack',
56+
value: 'postback postback-string'
57+
},
58+
{
59+
image: `https://raw.githubusercontent.com/compulim/BotFramework-MockBot/master/public/assets/square-icon-green.png`,
60+
imageAltText: 'a green square',
61+
title: 'Post back as JSON',
62+
text: 'Some text',
63+
type: 'postBack',
64+
value: {
65+
hello: 'World!'
66+
}
67+
},
68+
{
69+
image: `https://raw.githubusercontent.com/compulim/BotFramework-MockBot/master/public/assets/square-icon-purple.png`,
70+
imageAltText: 'a purple square',
71+
displayText: 'say Hello World!',
72+
title: 'Message back as JSON with display text',
73+
text: 'Some text',
74+
type: 'messageBack',
75+
value: {
76+
hello: 'World!'
77+
}
78+
},
79+
{
80+
image: `https://raw.githubusercontent.com/compulim/BotFramework-MockBot/master/public/assets/square-icon-purple.png`,
81+
imageAltText: 'a purple square',
82+
title: 'Message back as JSON without display text',
83+
type: 'messageBack',
84+
value: {
85+
hello: 'World!'
86+
}
87+
},
88+
{
89+
displayText: 'Aloha',
90+
image: `https://raw.githubusercontent.com/compulim/BotFramework-MockBot/master/public/assets/square-icon-purple.png`,
91+
imageAltText: 'a purple square',
92+
text: 'echo Hello',
93+
title: 'Aloha',
94+
type: 'messageBack'
95+
}
96+
],
97+
to: []
98+
}
99+
});
100+
101+
document.querySelector(`[data-testid="${WebChat.testIds.sendBoxTextBox}"]`).focus();
102+
103+
// WHEN: Focus suggested actions
104+
await host.sendShiftTab();
105+
106+
// THEN: Should focus first suggested action
107+
await host.snapshot();
108+
const firstAction = document.activeElement;
109+
110+
// WHEN: Press arrow right key four times:
111+
await host.sendKeys('ARROW_RIGHT'); // 2nd
112+
await host.sendKeys('ARROW_RIGHT'); // 3rd
113+
await host.sendKeys('ARROW_RIGHT'); // 4th
114+
await host.sendKeys('ARROW_RIGHT'); // 5th
115+
await host.sendKeys('ARROW_RIGHT'); // 6th
116+
117+
// THEN: Should focus the last suggested action
118+
expect(document.activeElement?.innerText).toContain('Aloha');
119+
const lastAction = document.activeElement;
120+
await host.snapshot();
121+
122+
// WHEN: escape key is pressed
123+
await host.sendKeys('ESCAPE');
124+
125+
// THEN: Should focus sendbox
126+
expect(document.activeElement).toBe(
127+
document.querySelector(`[data-testid="${WebChat.testIds.sendBoxTextBox}"]`)
128+
);
129+
await host.snapshot();
130+
131+
// WHEN: Focus suggested actions
132+
await host.sendShiftTab();
133+
134+
// THEN: Should focus the last suggested action
135+
expect(document.activeElement).toBe(lastAction);
136+
137+
// WHEN: Press arrow right again
138+
await host.sendKeys('ARROW_RIGHT');
139+
140+
// THEN: Should wrap around to the first action
141+
expect(document.activeElement).toBe(firstAction);
142+
143+
// WHEN: Press arrow left and space keys
144+
await host.sendKeys('ARROW_LEFT');
145+
await (await directLine.actPostActivity(() => host.sendKeys(' '))).resolveAll();
146+
147+
// THEN: Should wrap around, send last action and focus sendbox
148+
expect(document.activeElement).toBe(
149+
document.querySelector(`[data-testid="${WebChat.testIds.sendBoxTextBox}"]`)
150+
);
151+
await host.snapshot();
152+
});
153+
</script>
154+
</body>
155+
156+
</html>

0 commit comments

Comments
 (0)