Skip to content

Commit 5f24b4f

Browse files
author
Abraham Lara Granados
committed
feat(examples): updated web chat custom element animated examples to use the new closePanelButtonConfig property
1 parent 028bd04 commit 5f24b4f

5 files changed

Lines changed: 185 additions & 89 deletions

File tree

integrations/webchat/examples/custom-element/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
This code is for extending the IBM watsonx Assistant web chat. If you are new to developing with web chat, please start with the [web chat development overview](https://cloud.ibm.com/docs/watson-assistant?topic=watson-assistant-web-chat-develop). The code in this folder is commented with links and references to the web chat APIs used.
66

7+
78
## Custom elements
89

910
This example demonstrates how to use a custom element to change the size and position of the main web chat window.
@@ -12,6 +13,7 @@ It demonstrates:
1213

1314
- How to use a [**view:change**](https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-events#viewchange) event handler to show or hide the main web chat window when it is opened or closed.
1415
- How to use the [**element**](https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-configuration#configurationobject) configuration property to specify which custom element to use.
16+
- How to use [**closePanelButtonConfig**](https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-configuration#closePanelButtonConfig) configuration property for implementing a custom element as a side panel.
1517
- How to apply custom animation to the entrance and exit of web chat.
1618

1719
## Running the Code
@@ -22,7 +24,7 @@ It demonstrates:
2224

2325
### Running the React Examples
2426

25-
1. `cd client/react` or `cd client/react-animation`
27+
1. `cd client/react` or `cd client/react-animation`
2628
2. `npm install`
2729
3. `npm run start`
2830
4. Open a web browser to `localhost:3000`

integrations/webchat/examples/custom-element/client/javascript-animation/index.html

Lines changed: 118 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818

1919
.WebChatContainer {
2020
position: absolute;
21-
width: 500px;
21+
width: 380px;
2222
right: 0;
23-
top: 16px;
24-
bottom: 16px;
23+
top: 0;
24+
bottom: 0;
2525
}
2626

2727
#WACContainer.WACContainer .WebChatStyles {
@@ -35,95 +35,141 @@
3535

3636
#WACContainer.WACContainer .StartOpenAnimation {
3737
transition: none;
38-
right: -500px;
38+
right: -380px;
3939
}
4040

4141
#WACContainer.WACContainer .OpenAnimation {
42-
right: 16px;
42+
right: 0;
4343
}
4444

4545
#WACContainer.WACContainer .CloseAnimation {
46-
right: -500px;
46+
right: -380px;
47+
}
48+
49+
/* The selectors below are for handling the opening/closing animations in the left direction. */
50+
51+
.WebChatContainer--left {
52+
left: 0;
53+
right: unset;
54+
}
55+
56+
.WebChatContainer--left #WACContainer.WACContainer .WebChatStyles {
57+
position: relative;
58+
transition: left 500ms ease-in-out;
59+
}
60+
61+
.WebChatContainer--left #WACContainer.WACContainer .StartOpenAnimation {
62+
transition: none;
63+
left: -380px;
64+
right: unset;
65+
}
66+
67+
.WebChatContainer--left #WACContainer.WACContainer .OpenAnimation {
68+
left: 0;
69+
right: unset;
70+
}
71+
72+
.WebChatContainer--left #WACContainer.WACContainer .CloseAnimation {
73+
left: -380px;
74+
right: unset;
4775
}
4876
</style>
4977
</head>
5078
<body>
79+
<!-- Add the class WebChatContainer--left so the panel opens/closes from the left side of the page. -->
80+
<div class="WebChatContainer"></div>
5181

52-
<div class="WebChatContainer"></div>
53-
54-
<script>
55-
const customElement = document.querySelector('.WebChatContainer');
56-
let stylesInitialized = false;
57-
58-
/**
59-
* This function is called after a view change has occurred. It will trigger the animation for the main window and
60-
* then make the main window hidden or visible after the animation as needed.
61-
*/
62-
function viewChangeHandler(event, instance) {
63-
if (!stylesInitialized) {
64-
// The first time we get this, set the styles to their initial, default state.
65-
instance.elements.getMainWindow().addClassName('HideWebChat');
66-
instance.elements.getMainWindow().addClassName('WebChatStyles');
67-
stylesInitialized = true;
68-
}
82+
<script>
83+
const customElement = document.querySelector('.WebChatContainer');
84+
const closeIconDirection = customElement.classList.contains('WebChatContainer--left') ? 'left' : 'right';
85+
let stylesInitialized = false;
86+
87+
/**
88+
* This function is called after a view change has occurred. It will trigger the animation for the main window and
89+
* then make the main window hidden or visible after the animation as needed.
90+
*/
91+
function viewChangeHandler(event, instance) {
92+
if (!stylesInitialized) {
93+
// The first time we get this, set the styles to their initial, default state.
94+
instance.elements.getMainWindow().addClassName('HideWebChat');
95+
instance.elements.getMainWindow().addClassName('WebChatStyles');
96+
stylesInitialized = true;
97+
}
6998

70-
const mainWindowChanged = event.oldViewState.mainWindow !== event.newViewState.mainWindow;
71-
if (mainWindowChanged) {
72-
if (event.reason === 'sessionHistory') {
73-
// If we're re-opening web chat from session history, skip the animation by leaving out "StartOpenAnimation".
74-
if (event.newViewState.mainWindow) {
75-
instance.elements.getMainWindow().addClassName('OpenAnimation');
76-
instance.elements.getMainWindow().removeClassName('HideWebChat');
77-
} else {
78-
instance.elements.getMainWindow().addClassName('HideWebChat');
79-
}
80-
} else if (event.newViewState.mainWindow) {
81-
// Move the main window to the off-screen position and then un-hide it.
82-
instance.elements.getMainWindow().addClassName('StartOpenAnimation');
99+
const mainWindowChanged = event.oldViewState.mainWindow !== event.newViewState.mainWindow;
100+
if (mainWindowChanged) {
101+
if (event.reason === 'sessionHistory') {
102+
// If we're re-opening web chat from session history, skip the animation by leaving out "StartOpenAnimation".
103+
if (event.newViewState.mainWindow) {
104+
instance.elements.getMainWindow().addClassName('OpenAnimation');
83105
instance.elements.getMainWindow().removeClassName('HideWebChat');
84-
setTimeout(() => {
85-
// Give the browser a chance to render the off-screen state and then trigger the open animation.
86-
instance.elements.getMainWindow().addClassName('OpenAnimation');
87-
instance.elements.getMainWindow().removeClassName('StartOpenAnimation');
88-
});
89106
} else {
90-
// Trigger the animation to slide the main window to the hidden position.
91-
instance.elements.getMainWindow().addClassName('CloseAnimation');
92-
instance.elements.getMainWindow().removeClassName('OpenAnimation');
93-
setTimeout(() => {
94-
// After the animation is complete, hide the main window.
95-
instance.elements.getMainWindow().addClassName('HideWebChat');
96-
instance.elements.getMainWindow().removeClassName('CloseAnimation');
97-
}, 500);
107+
instance.elements.getMainWindow().addClassName('HideWebChat');
98108
}
109+
} else if (event.newViewState.mainWindow) {
110+
// Move the main window to the off-screen position and then un-hide it.
111+
instance.elements.getMainWindow().addClassName('StartOpenAnimation');
112+
instance.elements.getMainWindow().removeClassName('HideWebChat');
113+
setTimeout(() => {
114+
// Give the browser a chance to render the off-screen state and then trigger the open animation.
115+
instance.elements.getMainWindow().addClassName('OpenAnimation');
116+
instance.elements.getMainWindow().removeClassName('StartOpenAnimation');
117+
});
99118
}
100119
}
120+
}
101121

102-
/**
103-
* This is the function that is called when the web chat code has been loaded and it is ready to be rendered.
104-
*/
105-
async function onLoad(instance) {
106-
// Add listeners so we know when web chat has been opened or closed.
107-
// See https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-events#summary for more about our
108-
// events.
109-
instance.on({ type: 'view:change', handler: viewChangeHandler });
122+
/**
123+
* This function is called when the "close panel" button is clicked. It will add a class that will kick off the
124+
* closing animation of the side panel.
125+
*/
126+
function closePanelButtonToggledHandler(event, instance) {
127+
// Trigger the animation to slide the main window to the hidden position.
128+
instance.elements.getMainWindow().addClassName('CloseAnimation');
129+
instance.elements.getMainWindow().removeClassName('OpenAnimation');
130+
setTimeout(() => {
131+
// After the animation is complete, hide the main window.
132+
instance.elements.getMainWindow().addClassName('HideWebChat');
133+
instance.elements.getMainWindow().removeClassName('CloseAnimation');
110134

111-
await instance.render();
112-
}
135+
// Close web chat.
136+
instance.changeView('launcher');
137+
}, 500);
138+
}
139+
140+
/**
141+
* This is the function that is called when the web chat code has been loaded and it is ready to be rendered.
142+
*/
143+
async function onLoad(instance) {
144+
// Add listeners so we know when web chat has been opened or closed.
145+
// See https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-events#summary for more about our
146+
// events.
147+
instance.on({ type: 'view:change', handler: viewChangeHandler });
148+
// Add closePanelButton:toggled event listener to handle closing the side panel.
149+
// See https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-events#closePanelButton:toggled
150+
instance.on({ type: 'closePanelButton:toggled', handler: closePanelButtonToggledHandler });
151+
152+
await instance.render();
153+
}
154+
155+
// This is the standard web chat configuration object. You can modify these values with the embed code for your
156+
// own assistant if you wish to try this example with your assistant. You can find the documentation for this at
157+
// https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-configuration#configurationobject.
158+
window.watsonAssistantChatOptions = {
159+
integrationID: "07b05ae0-7e2e-47d1-a309-d0f5b9915ac5",
160+
region: "us-south",
161+
serviceInstanceID: "9a3613d2-3ce6-4928-8eb6-4d659d87ae68",
162+
// This is where we provide the custom element to web chat so it knows where it is supposed to be placed.
163+
element: customElement,
164+
closePanelButtonConfig: {
165+
is_on: true,
166+
closeIconDirection,
167+
},
168+
onLoad: onLoad,
169+
};
113170

114-
// This is the standard web chat configuration object. You can modify these values with the embed code for your
115-
// own assistant if you wish to try this example with your assistant. You can find the documentation for this at
116-
// https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-configuration#configurationobject.
117-
window.watsonAssistantChatOptions = {
118-
integrationID: "07b05ae0-7e2e-47d1-a309-d0f5b9915ac5",
119-
region: "us-south",
120-
serviceInstanceID: "9a3613d2-3ce6-4928-8eb6-4d659d87ae68",
121-
// This is where we provide the custom element to web chat so it knows where it is supposed to be placed.
122-
element: customElement,
123-
onLoad: onLoad,
124-
};
125-
setTimeout(function(){const t=document.createElement('script');t.src="https://web-chat.global.assistant.watson.appdomain.cloud/versions/" + (window.watsonAssistantChatOptions.clientVersion || 'latest') + "/WatsonAssistantChatEntry.js";document.head.appendChild(t);});
126-
</script>
171+
setTimeout(function(){const t=document.createElement('script');t.src="https://web-chat.global.assistant.watson.appdomain.cloud/versions/" + (window.watsonAssistantChatOptions.clientVersion || 'latest') + "/WatsonAssistantChatEntry.js";document.head.appendChild(t);});
172+
</script>
127173

128174
</body>
129175
</html>

integrations/webchat/examples/custom-element/client/react-animation/src/App.css

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ body {
1111

1212
.WebChatContainer {
1313
position: absolute;
14-
width: 500px;
14+
width: 380px;
1515
right: 0;
16-
top: 16px;
17-
bottom: 16px;
16+
top: 0;
17+
bottom: 0;
1818
}
1919

2020
#WACContainer.WACContainer .WebChatStyles {
@@ -28,13 +28,41 @@ body {
2828

2929
#WACContainer.WACContainer .StartOpenAnimation {
3030
transition: none;
31-
right: -500px;
31+
right: -380px;
3232
}
3333

3434
#WACContainer.WACContainer .OpenAnimation {
35-
right: 16px;
35+
right: 0;
3636
}
3737

3838
#WACContainer.WACContainer .CloseAnimation {
39-
right: -500px;
39+
right: -380px;
40+
}
41+
42+
/* The selectors below are for handling the opening/closing animations in the left direction. */
43+
44+
.WebChatContainer--left {
45+
left: 0;
46+
right: unset;
47+
}
48+
49+
.WebChatContainer--left #WACContainer.WACContainer .WebChatStyles {
50+
position: relative;
51+
transition: left 500ms ease-in-out;
4052
}
53+
54+
.WebChatContainer--left #WACContainer.WACContainer .StartOpenAnimation {
55+
transition: none;
56+
left: -380px;
57+
right: unset;
58+
}
59+
60+
.WebChatContainer--left #WACContainer.WACContainer .OpenAnimation {
61+
left: 0;
62+
right: unset;
63+
}
64+
65+
.WebChatContainer--left #WACContainer.WACContainer .CloseAnimation {
66+
left: -380px;
67+
right: unset;
68+
}

integrations/webchat/examples/custom-element/client/react-animation/src/App.js

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,43 @@ import { config } from './config';
99
* See https://www.npmjs.com/package/@ibm-watson/assistant-web-chat-react.
1010
*/
1111

12+
const IS_CLOSE_ICON_DIRECTION_LEFT = config.closePanelButtonConfig.closeIconDirection === 'left';
13+
1214
function App() {
1315
const stylesInitializedRef = useRef(false);
1416

1517
return (
1618
<WebChatCustomElement
17-
className="WebChatContainer"
19+
className={`WebChatContainer${IS_CLOSE_ICON_DIRECTION_LEFT ? ' WebChatContainer--left' : ''}`}
1820
config={config}
21+
onBeforeRender={onBeforeRenderHandler}
1922
onViewChange={(event, instance) => viewChangeHandler(event, instance, stylesInitializedRef)}
2023
/>
2124
);
2225
}
2326

27+
/**
28+
* This function is called before web chat is rendered.
29+
*/
30+
function onBeforeRenderHandler(instance) {
31+
// Listen for the "close panel" button being clicked. Add a class that will kick off the closing animation of the
32+
// side panel.
33+
// See https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-events#closePanelButton:toggled
34+
instance.on({ type: 'closePanelButton:toggled', handler: () => {
35+
// Trigger the animation to slide the main window to the hidden position.
36+
instance.elements.getMainWindow().addClassName('CloseAnimation');
37+
instance.elements.getMainWindow().removeClassName('OpenAnimation');
38+
setTimeout(() => {
39+
// After the animation is complete, hide the main window.
40+
instance.elements.getMainWindow().addClassName('HideWebChat');
41+
instance.elements.getMainWindow().removeClassName('CloseAnimation');
42+
43+
// Close web chat.
44+
instance.changeView('launcher');
45+
}, 500);
46+
}});
47+
}
48+
2449
/**
2550
* This function is called after a view change has occurred. It will trigger the animation for the main window and
2651
* then make the main window hidden or visible after the animation as needed.
@@ -52,15 +77,6 @@ function viewChangeHandler(event, instance, stylesInitializedRef) {
5277
instance.elements.getMainWindow().addClassName('OpenAnimation');
5378
instance.elements.getMainWindow().removeClassName('StartOpenAnimation');
5479
});
55-
} else {
56-
// Trigger the animation to slide the main window to the hidden position.
57-
instance.elements.getMainWindow().addClassName('CloseAnimation');
58-
instance.elements.getMainWindow().removeClassName('OpenAnimation');
59-
setTimeout(() => {
60-
// After the animation is complete, hide the main window.
61-
instance.elements.getMainWindow().addClassName('HideWebChat');
62-
instance.elements.getMainWindow().removeClassName('CloseAnimation');
63-
}, 500);
6480
}
6581
}
6682
}

integrations/webchat/examples/custom-element/client/react-animation/src/config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ const config = {
66
region: 'us-south',
77
serviceInstanceID: '9a3613d2-3ce6-4928-8eb6-4d659d87ae68',
88
subscriptionID: null,
9+
closePanelButtonConfig: {
10+
is_on: true,
11+
closeIconDirection: 'right', // The application will animate the side panel to the 'left' or 'right' based on this value.
12+
}
913
};
1014

1115
export { config };

0 commit comments

Comments
 (0)