Skip to content

Commit 7a493cd

Browse files
author
Abraham Lara Granados
committed
feat(examples): updated web chat custom element animated examples to use new close button icons for side-panels
1 parent 028bd04 commit 7a493cd

File tree

5 files changed

+149
-80
lines changed

5 files changed

+149
-80
lines changed

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: 105 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,128 @@
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') ? 'side-panel-left' : 'side-panel-right';
85+
let stylesInitialized = false;
6986

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');
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+
}
98+
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+
});
118+
} else {
119+
// Trigger the animation to slide the main window to the hidden position.
120+
instance.elements.getMainWindow().addClassName('CloseAnimation');
121+
instance.elements.getMainWindow().removeClassName('OpenAnimation');
122+
setTimeout(() => {
123+
// After the animation is complete, hide the main window.
124+
instance.elements.getMainWindow().addClassName('HideWebChat');
125+
instance.elements.getMainWindow().removeClassName('CloseAnimation');
126+
}, 500);
99127
}
100128
}
129+
}
101130

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 });
131+
/**
132+
* This is the function that is called when the web chat code has been loaded and it is ready to be rendered.
133+
*/
134+
async function onLoad(instance) {
135+
// Add listeners so we know when web chat has been opened or closed.
136+
// See https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-events#summary for more about our
137+
// events.
138+
instance.on({ type: 'view:change', handler: viewChangeHandler });
110139

111-
await instance.render();
112-
}
140+
await instance.render();
141+
}
142+
143+
// This is the standard web chat configuration object. You can modify these values with the embed code for your
144+
// own assistant if you wish to try this example with your assistant. You can find the documentation for this at
145+
// https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-configuration#configurationobject.
146+
window.watsonAssistantChatOptions = {
147+
integrationID: "07b05ae0-7e2e-47d1-a309-d0f5b9915ac5",
148+
region: "us-south",
149+
serviceInstanceID: "9a3613d2-3ce6-4928-8eb6-4d659d87ae68",
150+
// This is where we provide the custom element to web chat so it knows where it is supposed to be placed.
151+
element: customElement,
152+
headerConfig: {
153+
closeButtonIconType: closeIconDirection,
154+
},
155+
onLoad: onLoad,
156+
};
113157

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>
158+
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);});
159+
</script>
127160

128161
</body>
129162
</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: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ 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.headerConfig.closeButtonIconType === 'side-panel-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}
1921
onViewChange={(event, instance) => viewChangeHandler(event, instance, stylesInitializedRef)}
2022
/>

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+
headerConfig: {
10+
// The application will animate the side panel to the left or right based on this value.
11+
closeButtonIconType: 'side-panel-right', // side-panel-left or side-panel-right
12+
},
913
};
1014

1115
export { config };

0 commit comments

Comments
 (0)