Add ability to customize Web Chat by extending UI without re-implementing existing controls by dawolff-ms · Pull Request #4539 · microsoft/BotFramework-WebChat · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 69 additions & 0 deletions __tests__/html/customization.basicWebChat.restructure.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<script crossorigin="anonymous" src="https://unpkg.com/@babel/standalone@7.8.7/babel.min.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/react@16.8.6/umd/react.development.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/react-dom@16.8.6/umd/react-dom.development.js"></script>
<script crossorigin="anonymous" src="/test-harness.js"></script>
<script crossorigin="anonymous" src="/test-page-object.js"></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
</head>
<body>
<div id="webchat"></div>
<script type="text/babel" data-presets="env,stage-3,react">
const {
ReactDOM: { render },
WebChat: {
Components: { AccessKeySinkSurface, BasicToaster, BasicTranscript, BasicConnectivityStatus, BasicSendBox, Composer },
createDirectLine
}
} = window;

run(async function () {
const directLine = await createDirectLine({ token: await testHelpers.token.fetchDirectLineToken() });
const store = testHelpers.createStore();

const classes = {
surface: "surface-class-name",
sendBox: "send-box-class-name",
transcript: "transcript-class-name",
customComponent: "custom-component-class-name"
}
const role = "main";

render(
<Composer directLine={directLine} store={store}>
<AccessKeySinkSurface className={classes.surface} role={role}>
<BasicToaster />
<BasicSendBox className={classes.sendBox} />
<BasicConnectivityStatus />
<div className={classes.customComponent}>This is a custom component.</div>
<BasicTranscript className={classes.transcript} />
</AccessKeySinkSurface>
</Composer>,
document.getElementById('webchat')
);

await pageConditions.uiConnected();

const container = document.getElementById('webchat');
expect(container?.firstChild).not.toBeUndefined();

const surface = container.firstChild;
expect(surface.className).toContain(classes.surface);
expect(surface.role).toEqual(role);

const components = surface.childNodes;
expect(components[0].className).toContain("toaster");
expect(components[1].className).toContain(classes.sendBox);
expect(components[2].textContent).toContain("Connectivity Status");
expect(components[3].className).toContain(classes.customComponent);
expect(components[4].className).toContain("keyboard-help");
expect(components[5].className).toContain(classes.transcript);

await host.snapshot();
});
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions __tests__/html/customization.basicWebChat.restructure.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('customization', () => {
test('should render BasicWebChat components in a different structure', () => runHTML('customization.basicWebChat.restructure.html'));
});
13 changes: 13 additions & 0 deletions packages/component/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import ReactWebChat, { ReactWebChatProps } from './ReactWebChat';

import Composer, { ComposerProps } from './Composer';

import AccessKeySinkSurface from './Utils/AccessKeySink/Surface';

import BasicWebChat, { BasicWebChatProps } from './BasicWebChat';
import BasicConnectivityStatus from './BasicConnectivityStatus';
import BasicSendBox from './BasicSendBox';
import BasicToaster from './BasicToaster';
import BasicTranscript from './BasicTranscript';

import Avatar from './Activity/Avatar';
import Bubble from './Activity/Bubble';
Expand Down Expand Up @@ -51,6 +57,13 @@ const Components = {
Composer,
Localize,

// Components for restructuring BasicWebChat
AccessKeySinkSurface,
BasicConnectivityStatus,
BasicSendBox,
BasicToaster,
BasicTranscript,

// Components for recomposing activities and attachments
AudioContent,
FileContent,
Expand Down
5 changes: 5 additions & 0 deletions samples/06.recomposing-ui/e.extending-ui/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# We are hitting an issue around react-scripts preflight check, and it is by design.
# When react-scripts start supporting newer babel-jest@24, we could remove this check skip.
# https://github.com/facebook/create-react-app/issues/4167

SKIP_PREFLIGHT_CHECK=true
23 changes: 23 additions & 0 deletions samples/06.recomposing-ui/e.extending-ui/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
219 changes: 219 additions & 0 deletions samples/06.recomposing-ui/e.extending-ui/README.md
Loading