@telia-ace/widget-conversation 1.0.22 → 1.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +110 -210
  2. package/dist/conversation.3981560b.js +1100 -0
  3. package/dist/conversation.3981560b.js.map +1 -0
  4. package/dist/index.d.ts +1 -2
  5. package/dist/index.js +432 -760
  6. package/dist/index.js.map +1 -1
  7. package/dist/return-button.8773c0de.js +159 -0
  8. package/dist/return-button.8773c0de.js.map +1 -0
  9. package/dist/types.d.ts +41 -34
  10. package/dist/{components/conversation/plugin.d.ts → ui/conversation/conversation-component.d.ts} +2 -13
  11. package/dist/ui/conversation/conversation-content.d.ts +11 -0
  12. package/dist/{components/conversation/ui/input.d.ts → ui/conversation/conversation-input.d.ts} +0 -0
  13. package/dist/ui/conversation/conversation-loader.d.ts +8 -0
  14. package/dist/ui/conversation/conversation-message.d.ts +7 -0
  15. package/dist/ui/conversation/conversation-styles.d.ts +11 -0
  16. package/dist/{components → ui}/conversation/conversation.d.ts +0 -0
  17. package/dist/ui/conversation/index.d.ts +2 -0
  18. package/dist/{components/conversation/ui → ui/conversation}/message-types/agent.d.ts +1 -1
  19. package/dist/ui/conversation/message-types/custom.d.ts +9 -0
  20. package/dist/{components/conversation/ui → ui/conversation}/message-types/index.d.ts +1 -0
  21. package/dist/{components/conversation/ui → ui/conversation}/message-types/system.d.ts +0 -0
  22. package/dist/{components/conversation/ui → ui/conversation}/message-types/timestamp.d.ts +0 -0
  23. package/dist/{components/conversation/ui → ui/conversation}/message-types/user.d.ts +0 -0
  24. package/dist/ui/index.d.ts +2 -0
  25. package/dist/ui/return-button/index.d.ts +2 -0
  26. package/dist/{components/return-button/plugin.d.ts → ui/return-button/return-button-component.d.ts} +2 -1
  27. package/dist/{components → ui}/return-button/return-button.d.ts +0 -0
  28. package/package.json +13 -10
  29. package/dist/components/conversation/ui/content.d.ts +0 -2
  30. package/dist/components/conversation/ui/loader.d.ts +0 -8
  31. package/dist/components/conversation/ui/message-list-items/button-list.d.ts +0 -8
  32. package/dist/components/conversation/ui/message-list-items/custom.d.ts +0 -9
  33. package/dist/components/conversation/ui/message-list-items/html.d.ts +0 -5
  34. package/dist/components/conversation/ui/message-list-items/link-list.d.ts +0 -8
  35. package/dist/components/conversation/ui/message-list-items/separator.d.ts +0 -2
  36. package/dist/components/conversation/ui/message-list-items/text.d.ts +0 -6
  37. package/dist/components/conversation/ui/message-list-items/video-request.d.ts +0 -8
  38. package/dist/components/conversation/ui/message-types/message-list.d.ts +0 -9
  39. package/dist/components/conversation/ui/message.d.ts +0 -7
  40. package/dist/components/conversation/ui/overlay-outlets.d.ts +0 -13
  41. package/dist/components/conversation/ui/styles.d.ts +0 -27
  42. package/dist/conversation.js +0 -1394
  43. package/dist/conversation.js.map +0 -1
  44. package/dist/return-button.js +0 -174
  45. package/dist/return-button.js.map +0 -1
  46. package/dist/utils/map-actions.d.ts +0 -1
package/README.md CHANGED
@@ -2,24 +2,22 @@
2
2
 
3
3
  The Widget Conversation API provides support for reading and writing to a conversational component inside a widget.
4
4
 
5
- ## Sandbox
5
+ ## Explore the API
6
6
 
7
- For demonstration purposes, we've set up a sandbox for the Widget Conversational API so that you can see it in action. Keep in mind that this is for demonstration purposes only and may not reflect best practice.
8
-
9
- > We do not recommend binding functions to the `window` object.
7
+ You can try out and watch the Conversation API in action by clicking the button below.
8
+ Keep in mind that this is for demonstration purposes only and may not be best practice.
9
+ We do not recommend binding functions to the `Window` object.
10
10
 
11
11
  [![Edit elegant-jones-rnyrd](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/elegant-jones-rnyrd?fontsize=14&hidenavigation=1&theme=dark)
12
12
 
13
13
  ## Accessing the API
14
14
 
15
- In order to access the API you need to have a widget with a conversational component.
16
-
17
- ### Creating the plugin
18
-
19
- You need to register the conversational provider in the `providers`-property in the component. To access the global instance of `ConversationPlatform`, you pass in the current `Container` to the `getInstance()` method. It will return a `Promise` that is resolved to the `ConversationPlatform` instance. In the instance, register a provider and pass in name and handler by calling the `registerProvider()` function as shown below.
15
+ Inside a plugin, access the global instance of `ConversationPlatform` by passing in the current `Container` to the `getInstance()` method. It will return a `Promise` that is resolved to the `ConversationPlatform` instance. On the instance, register a provider and pass in a name and handler by calling the `registerProvider()` function as shown below.
20
16
 
21
17
  The handler function will be called once a conversational component for the specified provider is activated in the widget. Use the provider to interact with the conversation.
22
18
 
19
+ ##### Example
20
+
23
21
  ```ts
24
22
  import { ConversationPlatform } from '@telia-ace/widget-conversation';
25
23
 
@@ -32,122 +30,71 @@ const MyPlugin = async (container) => {
32
30
  };
33
31
  ```
34
32
 
35
- You also need to register the provider inside the widget configuration:
33
+ ## Writing to the conversation
34
+
35
+ When writing content to the conversation you will first need to create an `Agent` object and then use its `print()` function. Specify the type of entry to print and pass in the content.
36
36
 
37
- ```JSON
38
- "my-conversation-component": {
39
- "type": "conversation",
40
- "properties": {
41
- "providers": ["my-chat"],
42
- // ...
43
- },
44
- "context": {}
45
- },
46
- ```
37
+ ### `print(content: object)`
47
38
 
48
- ### Creating an agent in the conversation
39
+ Returns a `ConversationEntry` message that can be used to update and/or remove the content from the conversation at a later stage.
49
40
 
50
- When using `createAgent` you can specify both a name and an avatar. These will then be displayed in the conversation alongside that agent's entries.
41
+ ##### Example
51
42
 
52
43
  ```ts
53
- const agent = conversation.createAgent({
54
- name: 'Agent Smith',
55
- avatar: 'https://www.site.com/avatar.jpg',
56
- });
57
- ```
44
+ const agent = conversation.createAgent();
45
+ const entry = agent.print('Lorem ipsum');
58
46
 
59
- ## Writing to the conversation
47
+ entry.update({
48
+ // ...
49
+ });
60
50
 
61
- ***`print()` accepts an array, which is considered best practice when writing to the conversation. The previous way of posting an object is still currently be supported, but is considered to be deprecated.**
51
+ entry.remove();
52
+ ```
62
53
 
63
- ### Posting, updating and removing content
54
+ ### Messages
64
55
 
65
- When managing content in the conversation you'll first need to create an `Agent`-object and then use its `print()` function. There are serveral types of entries in order to accommodate different types of content.
56
+ #### Simple text message
66
57
 
67
- The `print(items: ConversationMessageItem[])` function let's you return a `ConversationEntry` message that can be used to update and/or remove the content from the conversation.
58
+ Used to render plain text without HTML-formatting.
68
59
 
69
- ##### Example of simple text message
60
+ ##### Example
70
61
 
71
62
  ```ts
72
63
  // print user message
73
- conversation.user.print([['text', 'Lorem ipsum']]);
64
+ conversation.user.print('Lorem ipsum');
74
65
 
75
66
  // print agent message
76
67
  const agent = conversation.createAgent();
77
- agent.print([['text', 'Lorem ipsum']]);
68
+ agent.print('Lorem ipsum');
78
69
  ```
79
70
 
80
- ##### Example of updating or removing content
71
+ #### Message with list of actions
81
72
 
82
- ```ts
83
- const agent = conversation.createAgent();
84
- const entry = agent.print([['text', 'Hello world!']]);
73
+ Example of how to render a list with actions. Is only supported on `Agent` and as system message.
85
74
 
86
- entry.update([
87
- // ...
88
- ]);
89
-
90
- entry.remove();
91
- ```
92
-
93
- ### Entry with list of actions
75
+ | Name | Type | Description |
76
+ | --------- | -------- | ------------------------------------------------------------- |
77
+ | `title` | `string` | Title for the entry. |
78
+ | `body` | `string` | Body content for the entry. Supports HTML. |
79
+ | `actions` | `object` | Key-value-pairs representing available actions for the entry. |
94
80
 
95
- You can post an entry into the conversation with actions. You can specify a title, body and available actions. This is only supported for the `Agent` and will be displayed as a system message.
96
-
97
- This can be either in the form of a "ButtonList" or an "LinkList" as demostrated below.
98
-
99
- | Name | Type | Description |
100
- | --------- | -------- | -------------------------------------------- |
101
- | `header` | `string` | Header for the entry. |
102
- | `actions` | `array` | Array of of available actions for the entry. |
103
-
104
- ##### Example of a list of actions
81
+ ##### Example
105
82
 
106
83
  ```ts
107
- // example of button list
108
- agent.print([
109
- [
110
- 'button-list',
111
- {
112
- header: 'Download invoices',
113
- actions: [
114
- {
115
- actionKey: 'invoice_190201',
116
- label: 'Invoice 190201',
117
- },
118
- {
119
- actionKey: 'invoice_190301',
120
- label: 'Invoice 190301',
121
- },
122
- ],
123
- },
124
- ],
125
- ]);
126
-
127
- // here we use a link list instead, but with the same actions
128
- agent.print([
129
- [
130
- 'link-list',
131
- {
132
- header: 'Download invoices',
133
- actions: [
134
- {
135
- actionKey: 'invoice_190201',
136
- label: 'Invoice 190201',
137
- },
138
- {
139
- actionKey: 'invoice_190301',
140
- label: 'Invoice 190301',
141
- },
142
- ],
143
- },
144
- ],
145
- ]);
84
+ agent.print({
85
+ title: 'Download invoices',
86
+ body: 'Click an invoice below to download a copy.',
87
+ actions: {
88
+ invoice_190201: 'Invoice 190201',
89
+ invoice_190301: 'Invoice 190301',
90
+ invoice_190401: 'Invoice 190401',
91
+ },
92
+ });
146
93
  ```
147
94
 
148
- ### Entry with a form
95
+ #### Message with a form
149
96
 
150
- You can also post a message with a form attached. This uses the `FormBuilder`-method. This is handled by the `conversation.form` event. It is only supported for `Agent` and will be displayed as a system message.
97
+ Example of how to render a form that can be handled by the `conversation.form` event. Is only supported on `Agent` and as system message.
151
98
 
152
99
  | Name | Type | Description |
153
100
  | ------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -156,7 +103,7 @@ You can also post a message with a form attached. This uses the `FormBuilder`-me
156
103
  | `form` | `(FormBuilder) => void` | A callback function for building the form. Refer to the [`@telia-ace/widget-forms`](https://www.npmjs.com/package/@telia-ace/widget-forms) package for more information about `FormBuilder`. |
157
104
  | `key` | `string` | The key used to refer to the form when validating and submitting the form. |
158
105
 
159
- ##### Example of an entry with a form
106
+ ##### Example
160
107
 
161
108
  ```ts
162
109
  agent.print({
@@ -185,63 +132,47 @@ agent.print({
185
132
  });
186
133
  ```
187
134
 
188
- ### Entry with a video call
189
-
190
- Use the `video-request` item type to create an entry representing an incoming video call. This entry can also have a form attached, which uses the `FormBuilder`-method and is handled by the `conversation.form` event. It is only supported for an `Agent` and will be displayed as a system message.
135
+ ### Specify a sender name and/or avatar
191
136
 
192
- | Name | Type | Description |
193
- | -------------- | -------- | ----------------------------------------------- |
194
- | `header` | `string` | Header for the entry. |
195
- | `acceptLabel` | `string` | Label to be shown for the "accept call button" |
196
- | `declineLabel` | `string` | Label to be shown for the "decline call button" |
137
+ To create an agent with a name and avatar use the `createAgent` method on the conversation.
197
138
 
198
- ##### Example of an entry for an incoming video call
139
+ ##### Example
199
140
 
200
141
  ```ts
201
- agent.print([
202
- [
203
- 'video-request',
204
- {
205
- header: 'Video call',
206
- accept: 'Accept',
207
- decline: 'Decline',
208
- },
209
- ],
210
- ]);
211
- ```
212
-
213
- When the user presses one of these buttons to accept or decline the call, an action will be dispatched with actionKey `accept-video-call` or `decline-video-call`, depending on which button was clicked.
214
-
215
- Listening to these actions can be done as following:
142
+ const agent = conversation.createAgent({
143
+ name: 'Mr. Agent',
144
+ avatar: 'https://www.site.com/avatar.jpg',
145
+ });
216
146
 
217
- ```ts
218
- component.actions.watch('conversation.action', (input, next) => {
219
- if (input.actionKey === 'accept-video-call') {
220
- // this will render an overlay over the widget,
221
- // and prepare the widget for displaying the actual call
222
- component.actions.dispatch('show-overlay', {});
223
- } else if (input.actionKey === 'decline-video-call') {
224
- // ...
225
- }
226
- return next(input);
147
+ agent.print({
148
+ title: 'I found the following invoices associated to your account:',
149
+ actions: {
150
+ action1: 'Action 1',
151
+ action2: 'Action 2',
152
+ action3: 'Action 3',
153
+ },
227
154
  });
228
155
  ```
229
156
 
230
- Use an overlay over the conversation to render your video call. The `show-overlay`-action, as described above, accomplishes this. After the overlay is rendered and ready it will dispatch another event: `overlay-mounted`. Use the HTML element this generates to render your video call.
157
+ ### Writing system messages
158
+
159
+ In order to print a system message to the conversation you invoke the `print` method on the `conversation`. The `print` method accepts the same arguments as on the `Agent`.
160
+
161
+ #### Example
231
162
 
232
163
  ```ts
233
- component.actions.watch('overlay-mounted', (overlayElem, next) => {
234
- // the overlayElem here may be used to render the ongoing call
235
- });
164
+ conversation.print('Lorem ipsum');
236
165
  ```
237
166
 
238
- ### The loading and typing indicators
167
+ ### Loading/typing indicator
239
168
 
240
- When you need to fetch data from external resource you should use the `loading()` function on the `ConversationProvider` to inform the user that something is about to happen. Even in cases when the response is available immediately it gives a better user experience to present a loading indicator for a short while.
169
+ In many cases you will likely fetch data from an external resource before the content is written to the conversation. In this case you should use the `loading()` function on the `ConversationProvider` to inform the user that something is about to happen. Even in cases when the response is available immediately it gives a better user experience to present a loading indicator for a short while.
241
170
 
242
- When you need to make the user aware that your agent is currently typing, you should use the `typing` function on `Agent`.
171
+ In cases where you want to notify the user that the agent is currently typing, you should use the `typing` function on `Agent`.
172
+
173
+ #### Example
243
174
 
244
- #### Example of `loading`
175
+ ##### Loading
245
176
 
246
177
  ```ts
247
178
  const done = conversation.loading();
@@ -249,7 +180,7 @@ const done = conversation.loading();
249
180
  done(); // remove loader
250
181
  ```
251
182
 
252
- #### Example of `typing`
183
+ ##### Typing indicator
253
184
 
254
185
  ```ts
255
186
  const done = agent.typing();
@@ -257,34 +188,51 @@ const done = agent.typing();
257
188
  done(); // remove loader
258
189
  ```
259
190
 
260
- ## Writing system messages
191
+ ## Reading from the conversation
261
192
 
262
- System message in the conversation are sent by using the `print` method on the `conversation`. The `print` method accepts the same arguments as on the `Agent`.
193
+ The second parameter to your provider handler is a `ComponentNode` instance representing the conversational component. On it you can read the component's properties and react to action emitted by the component.
263
194
 
264
- #### Example
195
+ ### Actions
265
196
 
266
- ```ts
267
- conversation.print([['text', 'Hello world!']]);
268
- ```
197
+ The following actions are emitted from the conversational component.
269
198
 
270
- ## Reading from the conversation
199
+ **Important**: For default actions it is important to call `next()` unless you want to completely stop the execution flow for the particular action. Not doing so will stop any succeeding handlers and may unintentionally break functionality.
200
+
201
+ #### `conversation.user-typing`
202
+
203
+ Is emitted when the user´s typing indicator is changed.
204
+
205
+ | Name | Type | Description |
206
+ | ------------ | -------- | ---------------------------------------------- |
207
+ | `textLength` | `number` | The current text length of the user's message. |
208
+
209
+ #### `conversation.user-submit`
210
+
211
+ Is emitted when the user submits a message.
271
212
 
272
- The second parameter to your provider handler is a `ComponentNode` instance representing the conversational component. From it you can read the component's properties and react to action emitted by the component.
213
+ | Name | Type | Description |
214
+ | ------ | -------- | ------------------- |
215
+ | `text` | `string` | The submitted text. |
273
216
 
274
- The following actions are emitted from the conversational component:
217
+ #### `conversation.action`
275
218
 
276
- > For default actions it is necessary to call `next()` unless you want to completely stop the execution flow for the particular action. Not doing so will stop any succeeding handlers and may unintentionally break functionality.
219
+ Is emitted when the user clicks on an action.
277
220
 
278
- | Action | Name | Type | Description |
279
- | -------------------------- | ------------ | ---------- | --------------------------------------------------------- |
280
- | `conversation.user-typing` | `textLength` | `number` | The current text length of the user's message. |
281
- | `conversation.user-submit` | `text` | `string` | The submitted text. |
282
- | `conversation.action` | `text` | `string` | Key of the submitted action. |
283
- | `conversation.form` | `data` | `FormData` | The form data. |
284
- | `conversation.form` | `formKey` | `string` | The unique key for the form. |
285
- | `conversation.form` | `actionKey` | `string` | The key of the form component responsible for the change. |
221
+ | Name | Type | Description |
222
+ | ------ | -------- | ---------------------------- |
223
+ | `text` | `string` | Key of the submitted action. |
286
224
 
287
- If you want to subscribe to any of the `conversation.form`-actions you have access to the `ComponentNodeController`. Example below:
225
+ #### `conversation.form`
226
+
227
+ Is emitted when the data of a form is changed.
228
+
229
+ | Name | Type | Description |
230
+ | ----------- | ---------- | --------------------------------------------------------- |
231
+ | `data` | `FormData` | The form data. |
232
+ | `formKey` | `string` | The unique key for the form. |
233
+ | `actionKey` | `string` | The key of the form component responsible for the change. |
234
+
235
+ In order to subscribe to any of these actions you have access to the `ComponentNodeController`. Below is an example how to subscribe to the `conversation.form` action.
288
236
 
289
237
  ```ts
290
238
  component.actions.watch('conversation.form', (input, next) => {
@@ -294,7 +242,7 @@ component.actions.watch('conversation.form', (input, next) => {
294
242
 
295
243
  ### Submitting forms
296
244
 
297
- If you want to listen for form events you should subscribe to the `conversation.form` event. By passing a `key` to the form, you are able to target the form in this listener.
245
+ In order to listen for form events you should subscribe to the `conversation.form` event. By passing a `key` to the form, you are able to target the form in this listener.
298
246
 
299
247
  ```ts
300
248
  component.actions.watch('conversation.form', (input, next) => {
@@ -306,51 +254,3 @@ component.actions.watch('conversation.form', (input, next) => {
306
254
  return next(input);
307
255
  });
308
256
  ```
309
-
310
- ### Adding custom list items
311
-
312
- You can add custom list items to the conversation. To do so you have to register your own custom React component, which will be mapped to a key also provided by you.
313
-
314
- #### Example of custom list items
315
-
316
- ```ts
317
- import { registerCustomMessageComponent } from '@telia-ace/widget-conversation';
318
-
319
- registerCustomMessageComponent(container, 'my-custom-list-item', import('./my-custom-list-item'));
320
- ```
321
-
322
- Once the component has been registered it will be available to be used as any other item in the `print` method on the Conversation API.
323
-
324
- ## Custom secondary action
325
-
326
- You can add a secondary action button that's displayed next to the user input field. This button can run any event that you write. You need to add the `secondaryAction` property to the conversation component in the configuration. It accepts an object with the following properties:
327
-
328
- | Name | Type | Description |
329
- | -------- | -------- | ------------------------------------------------------------------- |
330
- | `action` | `string` | An action that will be dispatched when the button is pressed |
331
- | `label` | `string` | Will be used as a "title" and aria-label on the HTML button element |
332
- | `icon` | `string` | An icon to be displayed, defaults to "browse" icon if left empty |
333
-
334
- ```json
335
- "conversation": {
336
- "type": "conversation",
337
- "properties": {
338
- "secondaryAction": {
339
- "action": "my-secondary-action",
340
- "label": "Label for the secondary action",
341
- "icon": "my-icon"
342
- }
343
- // ...other properties
344
- }
345
- }
346
- ```
347
-
348
- When you have added this property to the component, you can create an event for it in your code:
349
-
350
- ```ts
351
- component.actions.watch('conversation.action', (input, next) => {
352
- if (input === 'my-secondary-action') {
353
- // handle action
354
- }
355
- });
356
- ```