@kindly/react-chat 2.41.4 → 2.41.5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kindly/react-chat",
3
- "version": "2.41.4",
3
+ "version": "2.41.5",
4
4
  "description": "Kindly Chat react component",
5
5
  "repository": "https://github.com/kindly-ai/kindly-chat/tree/main/packages/react-chat",
6
6
  "main": "dist/index.js",
@@ -33,7 +33,6 @@
33
33
  "@babel/runtime-corejs3": "^7.15.4",
34
34
  "axios": "^0.21.1",
35
35
  "classnames": "^2.2.6",
36
- "date-fns": "^2.16.1",
37
36
  "dompurify": "^2.0.7",
38
37
  "file-saver": "2.0.2",
39
38
  "framer-motion": "^1.11.1",
@@ -45,7 +44,7 @@
45
44
  "polished": "^3.4.3",
46
45
  "prop-types": "^15.7.2",
47
46
  "react-children-utilities": "^2.8.0",
48
- "react-hook-form": "^7.32.2",
47
+ "react-hook-form": "^7.43.1",
49
48
  "react-idle-timer": "^4.2.12",
50
49
  "react-redux": "^7.1.1",
51
50
  "react-shadow": "^20.0.0",
@@ -65,9 +64,9 @@
65
64
  "react-dom": ">=16.9.0"
66
65
  },
67
66
  "devDependencies": {
68
- "@babel/core": "^7.20.12",
67
+ "@babel/core": "^7.21.0",
69
68
  "@babel/plugin-proposal-class-properties": "^7.18.6",
70
- "@babel/plugin-transform-runtime": "^7.19.6",
69
+ "@babel/plugin-transform-runtime": "^7.21.0",
71
70
  "@babel/preset-env": "^7.20.2",
72
71
  "@babel/preset-react": "^7.18.6",
73
72
  "@storybook/addon-a11y": "^6.5.16",
@@ -79,29 +78,29 @@
79
78
  "@storybook/jest": "^0.0.10",
80
79
  "@storybook/manager-webpack5": "^6.5.16",
81
80
  "@storybook/react": "^6.5.16",
82
- "@storybook/test-runner": "^0.8.0",
81
+ "@storybook/test-runner": "^0.9.4",
83
82
  "@storybook/testing-library": "^0.0.13",
84
83
  "@testing-library/jest-dom": "^5.16.5",
85
84
  "@testing-library/react": "^11.2.7",
86
- "@types/react": "^16.14.32",
87
- "@types/react-dom": "^16.9.16",
88
- "axe-playwright": "^1.1.11",
89
- "babel-jest": "^29.4.1",
85
+ "@types/react": "^16.14.35",
86
+ "@types/react-dom": "^16.9.18",
87
+ "axe-playwright": "^1.2.3",
88
+ "babel-jest": "^29.4.3",
90
89
  "babel-loader": "^9.1.2",
91
90
  "babel-plugin-styled-components": "^1.13.3",
92
91
  "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
93
92
  "babel-plugin-transform-remove-console": "^6.9.4",
94
- "browserslist": "^4.21.4",
95
- "chromatic": "^6.10.1",
93
+ "browserslist": "^4.21.5",
94
+ "chromatic": "^6.17.1",
96
95
  "clean-webpack-plugin": "^4.0.0",
97
96
  "dotenv": "8.6.0",
98
97
  "express": "^4.18.2",
99
98
  "file-loader": "^6.2.0",
100
99
  "html-webpack-plugin": "^5.5.0",
101
100
  "husky": "3.1.0",
102
- "jest": "^29.4.1",
103
- "jest-each": "^29.4.1",
104
- "jest-environment-jsdom": "^29.4.1",
101
+ "jest": "^29.4.3",
102
+ "jest-each": "^29.4.3",
103
+ "jest-environment-jsdom": "^29.4.3",
105
104
  "jest-junit": "^15.0.0",
106
105
  "lodash.clonedeep": "^4.5.0",
107
106
  "process": "^0.11.10",
@@ -116,7 +115,7 @@
116
115
  "url-loader": "^4.1.1",
117
116
  "wait-on": "^6.0.1",
118
117
  "webpack": "^5.75.0",
119
- "webpack-bundle-analyzer": "^4.7.0",
118
+ "webpack-bundle-analyzer": "^4.8.0",
120
119
  "webpack-cli": "^5.0.1",
121
120
  "webpack-dev-server": "^4.11.1",
122
121
  "webpack-merge": "^5.8.0"
@@ -129,5 +128,5 @@
129
128
  "pusher-js": "8.0.1"
130
129
  }
131
130
  },
132
- "gitHead": "2902badc395a6dfd28ea96d126b2681e5b961b33"
131
+ "gitHead": "05968afdf3bf67d1ba109d2f41011eabc53629e5"
133
132
  }
@@ -0,0 +1,136 @@
1
+ import cloneDeep from 'lodash.clonedeep';
2
+ import set from 'lodash.set';
3
+ import React from 'react';
4
+
5
+ import KindlyChatButton from '../../../src/features/KindlyChatButton/KindlyChatButton';
6
+ import settingsJSON from '../../assets/settingsJson';
7
+ import withContainer from '../../decorators/withContainer';
8
+ import withMockProvider from '../../decorators/withProvider';
9
+
10
+ const defaultBotSettings = {
11
+ welcomePage: settingsJSON.welcome_page,
12
+ feedbackForm: settingsJSON.feedback_form,
13
+ maintenanceAlert: settingsJSON.maintenance_alert,
14
+ ...settingsJSON.settings,
15
+ ...settingsJSON,
16
+ };
17
+
18
+ function Template(args, context) {
19
+ return <KindlyChatButton {...args} {...context} />;
20
+ }
21
+
22
+ export default {
23
+ title: 'Screen/Chat/DateTime',
24
+ component: KindlyChatButton,
25
+ decorators: [withContainer, withMockProvider],
26
+ argTypes: {
27
+ initialStateModifierFromArgs: {
28
+ table: {
29
+ disable: true,
30
+ },
31
+ },
32
+ },
33
+ };
34
+
35
+ const todayTime = new Date();
36
+ todayTime.setHours(13);
37
+ todayTime.setMinutes(37);
38
+ const created = todayTime.toISOString();
39
+
40
+ const defaultParameters = {
41
+ botSettings: defaultBotSettings,
42
+ initialStateModifier: {
43
+ chatbubble: {
44
+ active: true,
45
+ chatHasStarted: true,
46
+ currentLanguage: 'en',
47
+ },
48
+ messages: {
49
+ chatMessages: [
50
+ {
51
+ session_id: '1',
52
+ bot_id: 1234,
53
+ chat_id: '1',
54
+ chat_source: 'web',
55
+ chat_language_code: 'en',
56
+ from_bot: true,
57
+ sender: 'BOT',
58
+ message: 'Why did the calendar get in trouble at work?',
59
+ message_format: 'txt',
60
+ exchange_type: 'greeting',
61
+ exchange_id: '1',
62
+ reply_type: 'STANDARD',
63
+ created,
64
+ id: '1',
65
+ },
66
+ {
67
+ id: '2',
68
+ created,
69
+ message: 'Because it took a day off!',
70
+ status: null,
71
+ },
72
+ ],
73
+ messageSentTime: '2020-12-01T12:00:00.000Z',
74
+ lastMessageSeen: {
75
+ id: '2',
76
+ index: 2,
77
+ },
78
+ },
79
+ },
80
+ };
81
+
82
+ export const WithTime = Template.bind({});
83
+ WithTime.parameters = {
84
+ ...defaultParameters,
85
+ };
86
+ WithTime.args = {
87
+ language: 'en',
88
+ initialStateModifierFromArgs: ({ language }) => {
89
+ const withTimeStateModifier = cloneDeep(defaultParameters.initialStateModifier);
90
+ return set(withTimeStateModifier, 'chatbubble.currentLanguage', language);
91
+ },
92
+ };
93
+ WithTime.argTypes = {
94
+ language: { options: ['en', 'nb', 'en-GB', 'en-US', 'sv', 'fi', 'en-CA', 'nn'], control: { type: 'select' } },
95
+ };
96
+ WithTime.parameters = {
97
+ ...defaultParameters,
98
+ };
99
+
100
+ export const WithNorwegianTime = Template.bind({});
101
+ const withNorwegianTimeParameters = cloneDeep(defaultParameters);
102
+ set(withNorwegianTimeParameters, 'initialStateModifier.chatbubble.currentLanguage', 'nb');
103
+
104
+ WithNorwegianTime.parameters = {
105
+ ...withNorwegianTimeParameters,
106
+ };
107
+
108
+ export const WithDate = Template.bind({});
109
+ const withDateParameters = cloneDeep(defaultParameters);
110
+ set(withDateParameters, 'initialStateModifier.messages.chatMessages[0].created', '2020-12-01T12:00:00.000Z');
111
+ set(withDateParameters, 'initialStateModifier.messages.chatMessages[1].created', '2020-12-01T12:00:00.000Z');
112
+
113
+ WithDate.parameters = {
114
+ ...withDateParameters,
115
+ };
116
+ WithDate.args = {
117
+ language: 'en',
118
+ initialStateModifierFromArgs: ({ language }) => {
119
+ const withDateStateModifier = cloneDeep(withDateParameters.initialStateModifier);
120
+ return set(withDateStateModifier, 'chatbubble.currentLanguage', language);
121
+ },
122
+ };
123
+ WithDate.argTypes = {
124
+ language: { options: ['en', 'nb', 'en-GB', 'en-US', 'sv', 'fi', 'en-CA', 'nn'], control: { type: 'select' } },
125
+ };
126
+ WithDate.parameters = {
127
+ ...defaultParameters,
128
+ };
129
+
130
+ export const WithNorwegianDate = Template.bind({});
131
+ const withNorwegianDateParameters = cloneDeep(withDateParameters);
132
+ set(withNorwegianDateParameters, 'initialStateModifier.chatbubble.currentLanguage', 'nb');
133
+
134
+ WithNorwegianDate.parameters = {
135
+ ...withNorwegianDateParameters,
136
+ };
@@ -78,15 +78,77 @@ FormActive.parameters = {
78
78
  cancel_text: 'You have cancelled/exited this form',
79
79
  },
80
80
  fields: [
81
+ {
82
+ input_type: FIELDS.CHECKBOX,
83
+ order: 1,
84
+ required: true,
85
+ slug: 'checkbox-field',
86
+ attributes: {
87
+ options: [
88
+ {
89
+ value: 'volvo',
90
+ label: 'Volvo',
91
+ },
92
+ {
93
+ value: 'mercedes',
94
+ label: 'Mercedes',
95
+ },
96
+ {
97
+ value: 'audi',
98
+ label: 'Audi',
99
+ },
100
+ ],
101
+ },
102
+ texts: {
103
+ label: 'Checkbox',
104
+ },
105
+ validators: [],
106
+ },
107
+ {
108
+ input_type: FIELDS.SELECT,
109
+ order: 2,
110
+ required: true,
111
+ slug: 'select-field',
112
+ attributes: {
113
+ default_value: '2',
114
+ options: [
115
+ {
116
+ value: '1',
117
+ label: 'One',
118
+ },
119
+ {
120
+ value: '2',
121
+ label: 'Two',
122
+ },
123
+ {
124
+ value: '3',
125
+ label: 'Three',
126
+ },
127
+ {
128
+ value: '4',
129
+ label: 'Four',
130
+ },
131
+ {
132
+ value: 'Very long message',
133
+ label: 'Very long message, this is a very long message',
134
+ },
135
+ ],
136
+ },
137
+ texts: {
138
+ label: 'Select',
139
+ placeholder_text: 'Please select option',
140
+ },
141
+ validators: [],
142
+ },
81
143
  {
82
144
  input_type: FIELDS.TEXT,
83
- order: 0,
145
+ order: 3,
84
146
  slug: 'first-name-field',
85
147
  texts: {
86
148
  label: 'First name',
87
149
  help_text: 'Please input your name here',
88
150
  placeholder_text: 'First name',
89
- required_text: 'This field is absolutely required',
151
+ // required_text: 'This field is absolutely required',
90
152
  },
91
153
  required: true,
92
154
  validators: [
@@ -98,7 +160,7 @@ FormActive.parameters = {
98
160
  },
99
161
  {
100
162
  input_type: FIELDS.TEXT,
101
- order: 1,
163
+ order: 4,
102
164
  slug: 'text-field',
103
165
  texts: {
104
166
  label: 'Text field',
@@ -118,7 +180,7 @@ FormActive.parameters = {
118
180
  },
119
181
  {
120
182
  input_type: FIELDS.EMAIL,
121
- order: 2,
183
+ order: 5,
122
184
  slug: 'email-field',
123
185
  texts: {
124
186
  label: 'Email',
@@ -127,7 +189,7 @@ FormActive.parameters = {
127
189
  },
128
190
  {
129
191
  input_type: FIELDS.NUMBER,
130
- order: 3,
192
+ order: 6,
131
193
  affix: 'PREFIX',
132
194
  slug: 'number-field',
133
195
  texts: {
@@ -146,7 +208,7 @@ FormActive.parameters = {
146
208
  },
147
209
  {
148
210
  input_type: FIELDS.RANGE,
149
- order: 4,
211
+ order: 7,
150
212
  affix: 'SUFFIX',
151
213
  slug: 'range-field',
152
214
  attributes: {
@@ -167,13 +229,76 @@ FormActive.parameters = {
167
229
  },
168
230
  ],
169
231
  },
232
+ ],
233
+ },
234
+ },
235
+ ],
236
+ },
237
+ },
238
+ };
239
+ FormActive.play = async ({ canvasElement }) => {
240
+ await within(canvasElement).findByText('Please input your name here', undefined, { timeout: 5000 });
241
+ const textPlaceholderValue = 'Free text';
242
+ const textInput = await within(canvasElement).findByPlaceholderText(textPlaceholderValue);
243
+ await userEvent.type(textInput, 'This');
244
+ await expect(textInput.value).toBe('This');
245
+ await fireEvent(await within(canvasElement).getByRole('button', { name: /submit/i }), new MouseEvent('click'));
246
+ // await within(canvasElement).findByText('This field is absolutely required');
247
+ await within(canvasElement).findByText('This field should be at least 5 characters long');
248
+ const textInputStyle = window.getComputedStyle(textInput);
249
+ expect(textInputStyle.border).not.toContain('#00000000');
250
+ expect(textInputStyle.border).not.toContain('transparent');
251
+ await userEvent.type(textInput, ' is too long');
252
+ await expect(textInput.value).toBe('This is too lon');
253
+ const emailPlaceholderValue = 'Email';
254
+ const emailInput = await within(canvasElement).findByPlaceholderText(emailPlaceholderValue);
255
+ await userEvent.type(emailInput, 'this@is@not@an@email');
256
+
257
+ const chatBody = await within(canvasElement).findByTestId('chat-body-container');
258
+ await wait(300); // wait for the autoscroll to finish, so we can bottom for the Chromatic snapshot
259
+ fireEvent.scroll(chatBody, { target: { scrollTop: chatBody.clientHeight } });
260
+ };
261
+
262
+ export const FormActive2 = Template.bind({});
263
+ FormActive2.parameters = {
264
+ ...defaultParameters,
265
+ initialStateModifier: {
266
+ ...defaultParameters.initialStateModifier,
267
+ messages: {
268
+ chatMessages: [
269
+ {
270
+ chat_source: 'web',
271
+ chat_language_code: 'en',
272
+ from_bot: true,
273
+ sender: 'BOT',
274
+ message: '',
275
+ message_format: 'txt',
276
+ buttons: [],
277
+ created: '2022-06-15T19:03:46.186495Z',
278
+ id: '1',
279
+ form: {
280
+ submission_id: 'submissionId',
281
+ id: 'formId',
282
+ dialogue_id: '2',
283
+ submit_dialogue_id: 'c0d685d3-3f11-41b8-9cfd-e35d54df2c95',
284
+ abandon_dialogue_id: 'b1cde0f3-0715-48eb-8482-a9355fa11ba8',
285
+ languageCode: 'en',
286
+ texts: {
287
+ title: 'This is a form',
288
+ error_text: 'There was an error around here',
289
+ submit_button_text: 'Submit',
290
+ cancel_button_text: 'Exit',
291
+ unanswered_text: 'You failed to answer this form',
292
+ cancel_text: 'You have cancelled/exited this form',
293
+ },
294
+ fields: [
170
295
  {
171
296
  input_type: FIELDS.SELECT,
172
297
  order: 5,
173
298
  required: true,
174
299
  slug: 'select-field',
175
300
  attributes: {
176
- default_value: '5',
301
+ default_value: '2',
177
302
  options: [
178
303
  {
179
304
  value: '1',
@@ -203,6 +328,51 @@ FormActive.parameters = {
203
328
  },
204
329
  validators: [],
205
330
  },
331
+ {
332
+ input_type: FIELDS.CHECKBOX,
333
+ order: 6,
334
+ required: true,
335
+ slug: 'checkbox-cars',
336
+ attributes: {
337
+ options: [
338
+ {
339
+ value: 'volvo',
340
+ label: 'Volvo',
341
+ },
342
+ {
343
+ value: 'mercedes',
344
+ label: 'Mercedes',
345
+ },
346
+ {
347
+ value: 'Very long text',
348
+ label:
349
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
350
+ },
351
+ ],
352
+ },
353
+ texts: {
354
+ label: 'Checkbox',
355
+ },
356
+ validators: [],
357
+ },
358
+ {
359
+ input_type: FIELDS.CHECKBOX,
360
+ order: 6,
361
+ required: true,
362
+ slug: 'checkbox-terms',
363
+ attributes: {
364
+ options: [
365
+ {
366
+ value: 'terms',
367
+ label: 'Terms and conditions',
368
+ },
369
+ ],
370
+ },
371
+ texts: {
372
+ label: 'Accept our terms to continue',
373
+ },
374
+ validators: [],
375
+ },
206
376
  ],
207
377
  },
208
378
  },
@@ -210,23 +380,10 @@ FormActive.parameters = {
210
380
  },
211
381
  },
212
382
  };
213
- FormActive.play = async ({ canvasElement }) => {
214
- await within(canvasElement).findByText('Please input your name here', undefined, { timeout: 5000 });
215
- const textPlaceholderValue = 'Free text';
216
- const textInput = await within(canvasElement).findByPlaceholderText(textPlaceholderValue);
217
- await userEvent.type(textInput, 'This');
218
- await expect(textInput.value).toBe('This');
383
+ FormActive2.play = async ({ canvasElement }) => {
384
+ await within(canvasElement).findByText('Submit', undefined, { timeout: 5000 });
219
385
  await fireEvent(await within(canvasElement).getByRole('button', { name: /submit/i }), new MouseEvent('click'));
220
- await within(canvasElement).findByText('This field is absolutely required');
221
- await within(canvasElement).findByText('This field should be at least 5 characters long');
222
- const textInputStyle = window.getComputedStyle(textInput);
223
- expect(textInputStyle.border).not.toContain('#00000000');
224
- expect(textInputStyle.border).not.toContain('transparent');
225
- await userEvent.type(textInput, ' is too long');
226
- await expect(textInput.value).toBe('This is too lon');
227
- const emailPlaceholderValue = 'Email';
228
- const emailInput = await within(canvasElement).findByPlaceholderText(emailPlaceholderValue);
229
- await userEvent.type(emailInput, 'this@is@not@an@email');
386
+
230
387
  const selectPlaceholderValue = 'Please select option';
231
388
  const selectInput = await within(canvasElement).findByPlaceholderText(selectPlaceholderValue);
232
389
  const selectInputStyle = window.getComputedStyle(selectInput);
@@ -235,6 +392,9 @@ FormActive.play = async ({ canvasElement }) => {
235
392
  await userEvent.selectOptions(selectInput, 'Very long message');
236
393
  await expect(selectInputStyle.border).toContain('rgba(0, 0, 0, 0)');
237
394
 
395
+ const checkboxTerms = await within(canvasElement).findByLabelText('Terms and conditions');
396
+ await userEvent.click(checkboxTerms);
397
+
238
398
  const chatBody = await within(canvasElement).findByTestId('chat-body-container');
239
399
  await wait(300); // wait for the autoscroll to finish, so we can bottom for the Chromatic snapshot
240
400
  fireEvent.scroll(chatBody, { target: { scrollTop: chatBody.clientHeight } });
@@ -282,7 +442,6 @@ FormWithoutTitle.parameters = {
282
442
  label: 'First name',
283
443
  help_text: 'Please input your name here',
284
444
  placeholder_text: 'First name',
285
- required_text: 'This field is absolutely required',
286
445
  },
287
446
  required: true,
288
447
  validators: [
@@ -322,6 +481,7 @@ FormSuccess.parameters = {
322
481
  'number-field': '42',
323
482
  'range-field': '7',
324
483
  'select-field': '2',
484
+ 'checkbox-field': 'audi'
325
485
  },
326
486
  },
327
487
  },
@@ -332,6 +492,8 @@ FormSuccess.parameters = {
332
492
  FormSuccess.play = async ({ canvasElement }) => {
333
493
  const selectFieldLabel = await within(canvasElement).findByText('Two');
334
494
  await expect(selectFieldLabel).toBeInTheDocument();
495
+ const checkboxFieldLabel = await within(canvasElement).findByText('Audi');
496
+ await expect(checkboxFieldLabel).toBeInTheDocument();
335
497
  const shouldNotDisplay = await within(canvasElement).queryByText('Should not display');
336
498
  await expect(shouldNotDisplay).not.toBeInTheDocument();
337
499
  };