@botpress/webchat 0.5.0 → 1.0.0

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 (295) hide show
  1. package/dist/App.d.ts +10 -0
  2. package/dist/Utils/colors.d.ts +18 -0
  3. package/dist/Utils/eventEmitter.d.ts +12 -0
  4. package/dist/Utils/index.d.ts +2 -0
  5. package/dist/client/MessagingClient.d.ts +27 -0
  6. package/dist/client/adapters/Audio.d.ts +19 -0
  7. package/dist/client/adapters/Card.d.ts +188 -0
  8. package/dist/client/adapters/Carousel.d.ts +147 -0
  9. package/dist/client/adapters/Choice.d.ts +45 -0
  10. package/dist/client/adapters/Dropdown.d.ts +46 -0
  11. package/dist/client/adapters/File.d.ts +19 -0
  12. package/dist/client/adapters/Image.d.ts +19 -0
  13. package/dist/client/adapters/Location.d.ts +27 -0
  14. package/dist/client/adapters/Message.d.ts +433 -0
  15. package/dist/client/adapters/Text.d.ts +20 -0
  16. package/dist/client/adapters/Utils.d.ts +5 -0
  17. package/dist/client/adapters/Video.d.ts +19 -0
  18. package/dist/client/adapters/Voice.d.ts +15 -0
  19. package/dist/client/adapters/index.d.ts +12 -0
  20. package/dist/client/index.d.ts +2 -0
  21. package/dist/components/Avatar.d.ts +6 -0
  22. package/dist/components/Block.d.ts +4 -0
  23. package/dist/components/Composer.d.ts +12 -14
  24. package/dist/components/Container.d.ts +2 -12
  25. package/dist/components/Header.d.ts +36 -26
  26. package/dist/components/LoadingIndicator.d.ts +2 -0
  27. package/dist/components/Message.d.ts +7 -0
  28. package/dist/components/MessageList.d.ts +2 -0
  29. package/dist/components/Modal.d.ts +17 -0
  30. package/dist/components/RestartConversation.d.ts +5 -0
  31. package/dist/components/Webchat.d.ts +6 -0
  32. package/dist/components/dev-tools/DevTools.d.ts +1 -0
  33. package/dist/components/dev-tools/configuration.d.ts +2 -0
  34. package/dist/components/dev-tools/helpers.d.ts +5 -0
  35. package/dist/components/index.d.ts +12 -0
  36. package/dist/components/renderers/Audio.d.ts +3 -0
  37. package/dist/components/renderers/Bubble.d.ts +5 -0
  38. package/dist/components/renderers/Button.d.ts +4 -0
  39. package/dist/components/renderers/Carousel.d.ts +3 -0
  40. package/dist/components/renderers/Column.d.ts +5 -0
  41. package/dist/components/renderers/Dropdown.d.ts +5 -0
  42. package/dist/components/renderers/File.d.ts +3 -0
  43. package/dist/components/renderers/Image.d.ts +3 -0
  44. package/dist/components/renderers/Location.d.ts +3 -0
  45. package/dist/components/renderers/Row.d.ts +5 -0
  46. package/dist/components/renderers/Text.d.ts +4 -0
  47. package/dist/components/renderers/Video.d.ts +3 -0
  48. package/dist/components/renderers/index.d.ts +2 -0
  49. package/dist/contexts/ComposerContext.d.ts +8 -0
  50. package/dist/contexts/MessageContext.d.ts +8 -0
  51. package/dist/contexts/ModalContext.d.ts +14 -0
  52. package/dist/contexts/WebchatContext.d.ts +56 -0
  53. package/dist/contexts/index.d.ts +4 -0
  54. package/dist/hooks/index.d.ts +3 -0
  55. package/dist/hooks/useImageSize.d.ts +2 -0
  56. package/dist/hooks/useRefresh.d.ts +10 -0
  57. package/dist/hooks/useWebchatStore.d.ts +30 -0
  58. package/dist/index.d.ts +3 -17
  59. package/dist/index.js +43569 -48
  60. package/dist/index.umd.cjs +702 -0
  61. package/dist/main.d.ts +11 -13
  62. package/dist/providers/ModalProvider.d.ts +8 -0
  63. package/dist/providers/WebchatProvider.d.ts +13 -0
  64. package/dist/providers/index.d.ts +2 -0
  65. package/dist/schemas/index.d.ts +1 -0
  66. package/dist/schemas/theme.d.ts +3371 -0
  67. package/dist/services/clipboard.d.ts +1 -0
  68. package/dist/services/images.d.ts +2 -0
  69. package/dist/services/index.d.ts +3 -0
  70. package/dist/services/toast.d.ts +17 -0
  71. package/dist/themes/dawn.d.ts +2 -0
  72. package/dist/themes/duskTheme.d.ts +2 -0
  73. package/dist/themes/eggplant.d.ts +2 -0
  74. package/dist/themes/galaxy.d.ts +2 -0
  75. package/dist/themes/index.d.ts +6 -0
  76. package/dist/themes/midnight.d.ts +2 -0
  77. package/dist/themes/prism.d.ts +2 -0
  78. package/dist/twind.config.d.ts +9 -0
  79. package/dist/types/block-type.d.ts +93 -0
  80. package/dist/types/image.d.ts +11 -0
  81. package/dist/types/index.d.ts +2 -0
  82. package/dist/vite.svg +1 -0
  83. package/index.html +18 -0
  84. package/package.json +60 -48
  85. package/public/vite.svg +1 -0
  86. package/src/App.tsx +41 -0
  87. package/src/Utils/colors.ts +45 -0
  88. package/src/Utils/eventEmitter.ts +31 -0
  89. package/src/Utils/index.ts +2 -0
  90. package/src/assets/check-circle-bold.svg +5 -0
  91. package/src/assets/chevron-up.svg +3 -0
  92. package/src/assets/file-05.svg +6 -0
  93. package/src/assets/globe-02.svg +6 -0
  94. package/src/assets/help-circle.svg +3 -0
  95. package/src/assets/info-circle.svg +3 -0
  96. package/src/assets/lock-01.svg +4 -0
  97. package/src/assets/mail-01.svg +6 -0
  98. package/src/assets/minus-circle.svg +3 -0
  99. package/src/assets/phone.svg +6 -0
  100. package/src/assets/send-03.svg +4 -0
  101. package/src/assets/share-04.svg +5 -0
  102. package/src/assets/slash-circle-01.svg +3 -0
  103. package/src/assets/x-circle-bold.svg +5 -0
  104. package/src/assets/x-close.svg +3 -0
  105. package/src/assets/x.svg +3 -0
  106. package/src/client/MessagingClient.ts +87 -0
  107. package/src/client/adapters/Audio.ts +10 -0
  108. package/src/client/adapters/Card.ts +104 -0
  109. package/src/client/adapters/Carousel.ts +11 -0
  110. package/src/client/adapters/Choice.ts +48 -0
  111. package/src/client/adapters/Dropdown.ts +39 -0
  112. package/src/client/adapters/File.ts +10 -0
  113. package/src/client/adapters/Image.ts +10 -0
  114. package/src/client/adapters/Location.ts +18 -0
  115. package/src/client/adapters/Message.ts +26 -0
  116. package/src/client/adapters/Text.ts +11 -0
  117. package/src/client/adapters/Utils.ts +11 -0
  118. package/src/client/adapters/Video.ts +10 -0
  119. package/src/client/adapters/Voice.ts +9 -0
  120. package/src/client/adapters/index.ts +12 -0
  121. package/src/client/index.ts +2 -0
  122. package/src/components/Avatar.tsx +22 -0
  123. package/src/components/Block.tsx +17 -0
  124. package/src/components/Composer.tsx +115 -0
  125. package/src/components/Container.tsx +17 -0
  126. package/src/components/Header.tsx +141 -0
  127. package/src/components/LoadingIndicator.tsx +15 -0
  128. package/src/components/Message.tsx +52 -0
  129. package/src/components/MessageList.tsx +75 -0
  130. package/src/components/Modal.tsx +49 -0
  131. package/src/components/RestartConversation.tsx +52 -0
  132. package/src/components/Webchat.tsx +68 -0
  133. package/src/components/dev-tools/DevTools.tsx +496 -0
  134. package/src/components/dev-tools/configuration.tsx +27 -0
  135. package/src/components/dev-tools/helpers.ts +21 -0
  136. package/src/components/index.ts +12 -0
  137. package/src/components/renderers/Audio.tsx +11 -0
  138. package/src/components/renderers/Bubble.tsx +12 -0
  139. package/src/components/renderers/Button.tsx +59 -0
  140. package/src/components/renderers/Carousel.tsx +51 -0
  141. package/src/components/renderers/Column.tsx +22 -0
  142. package/src/components/renderers/Dropdown.tsx +170 -0
  143. package/src/components/renderers/File.tsx +13 -0
  144. package/src/components/renderers/Image.tsx +63 -0
  145. package/src/components/renderers/Location.tsx +16 -0
  146. package/src/components/renderers/Row.tsx +22 -0
  147. package/src/components/renderers/Text.tsx +32 -0
  148. package/src/components/renderers/Video.tsx +11 -0
  149. package/src/components/renderers/index.ts +28 -0
  150. package/src/contexts/ComposerContext.ts +16 -0
  151. package/src/contexts/MessageContext.ts +16 -0
  152. package/src/contexts/ModalContext.ts +19 -0
  153. package/src/contexts/WebchatContext.ts +61 -0
  154. package/src/contexts/index.ts +4 -0
  155. package/src/hooks/index.ts +3 -0
  156. package/src/hooks/useImageSize.ts +30 -0
  157. package/src/hooks/useRefresh.ts +33 -0
  158. package/src/hooks/useWebchatStore.ts +45 -0
  159. package/src/index.css +18 -0
  160. package/src/index.ts +3 -0
  161. package/src/main.tsx +33 -0
  162. package/src/providers/ModalProvider.tsx +35 -0
  163. package/src/providers/WebchatProvider.tsx +107 -0
  164. package/src/providers/index.ts +2 -0
  165. package/src/schemas/index.ts +1 -0
  166. package/src/schemas/theme.ts +188 -0
  167. package/src/services/clipboard.ts +8 -0
  168. package/src/services/images.ts +39 -0
  169. package/src/services/index.ts +3 -0
  170. package/src/services/toast.tsx +71 -0
  171. package/src/themes/dawn.ts +277 -0
  172. package/src/themes/duskTheme.ts +349 -0
  173. package/src/themes/eggplant.ts +353 -0
  174. package/src/themes/galaxy.ts +323 -0
  175. package/src/themes/index.ts +6 -0
  176. package/src/themes/midnight.ts +276 -0
  177. package/src/themes/prism.ts +349 -0
  178. package/src/twind.config.ts +31 -0
  179. package/src/types/block-type.ts +150 -0
  180. package/src/types/image.ts +10 -0
  181. package/src/types/index.ts +2 -0
  182. package/src/vite-env.d.ts +1 -0
  183. package/tailwind.config.js +0 -0
  184. package/tsconfig.json +30 -0
  185. package/tsconfig.node.json +10 -0
  186. package/vite.config.ts +31 -0
  187. package/README.md +0 -31
  188. package/assets/fonts/roboto/roboto.woff2 +0 -0
  189. package/assets/fonts/roboto/roboto500.woff2 +0 -0
  190. package/assets/fonts/roboto.css +0 -128
  191. package/assets/notification.mp3 +0 -0
  192. package/dist/components/Composer.js +0 -118
  193. package/dist/components/Container.js +0 -62
  194. package/dist/components/ConversationList.d.ts +0 -10
  195. package/dist/components/ConversationList.js +0 -41
  196. package/dist/components/Footer.d.ts +0 -3
  197. package/dist/components/Footer.js +0 -21
  198. package/dist/components/Header.js +0 -181
  199. package/dist/components/VoiceRecorder.d.ts +0 -10
  200. package/dist/components/VoiceRecorder.js +0 -137
  201. package/dist/components/common/Avatar/index.d.ts +0 -9
  202. package/dist/components/common/Avatar/index.js +0 -13
  203. package/dist/components/common/BotInfo/index.d.ts +0 -10
  204. package/dist/components/common/BotInfo/index.js +0 -102
  205. package/dist/components/common/BotInfo/style.scss +0 -88
  206. package/dist/components/common/ConfirmDialog/index.d.ts +0 -11
  207. package/dist/components/common/ConfirmDialog/index.js +0 -78
  208. package/dist/components/common/ConfirmDialog/style.module.scss +0 -48
  209. package/dist/components/common/Dialog/index.d.ts +0 -17
  210. package/dist/components/common/Dialog/index.js +0 -57
  211. package/dist/components/common/Dialog/style.module.scss +0 -29
  212. package/dist/components/common/ToolTip/index.d.ts +0 -10
  213. package/dist/components/common/ToolTip/index.js +0 -163
  214. package/dist/components/common/ToolTip/style.module.scss +0 -108
  215. package/dist/components/common/ToolTip/utils.d.ts +0 -15
  216. package/dist/components/common/ToolTip/utils.js +0 -78
  217. package/dist/components/common/variables.scss +0 -38
  218. package/dist/components/messages/InlineFeedback.d.ts +0 -11
  219. package/dist/components/messages/InlineFeedback.js +0 -56
  220. package/dist/components/messages/Message.d.ts +0 -11
  221. package/dist/components/messages/Message.js +0 -106
  222. package/dist/components/messages/MessageGroup.d.ts +0 -23
  223. package/dist/components/messages/MessageGroup.js +0 -63
  224. package/dist/components/messages/MessageList.d.ts +0 -10
  225. package/dist/components/messages/MessageList.js +0 -154
  226. package/dist/core/api.d.ts +0 -23
  227. package/dist/core/api.js +0 -117
  228. package/dist/core/constants.d.ts +0 -14
  229. package/dist/core/constants.js +0 -29
  230. package/dist/core/socket.d.ts +0 -14
  231. package/dist/core/socket.js +0 -57
  232. package/dist/declaration.d.ts +0 -1
  233. package/dist/declaration.js +0 -1
  234. package/dist/fonts/roboto.d.ts +0 -4
  235. package/dist/fonts/roboto.js +0 -9
  236. package/dist/globals.d.ts +0 -7
  237. package/dist/globals.js +0 -2
  238. package/dist/icons/Add.d.ts +0 -6
  239. package/dist/icons/Add.js +0 -10
  240. package/dist/icons/Cancel.d.ts +0 -5
  241. package/dist/icons/Cancel.js +0 -10
  242. package/dist/icons/Chat.d.ts +0 -6
  243. package/dist/icons/Chat.js +0 -9
  244. package/dist/icons/Close.d.ts +0 -3
  245. package/dist/icons/Close.js +0 -10
  246. package/dist/icons/Delete.d.ts +0 -3
  247. package/dist/icons/Delete.js +0 -11
  248. package/dist/icons/Download.d.ts +0 -3
  249. package/dist/icons/Download.js +0 -10
  250. package/dist/icons/Email.d.ts +0 -3
  251. package/dist/icons/Email.js +0 -8
  252. package/dist/icons/Information.d.ts +0 -3
  253. package/dist/icons/Information.js +0 -12
  254. package/dist/icons/List.d.ts +0 -3
  255. package/dist/icons/List.js +0 -15
  256. package/dist/icons/Microphone.d.ts +0 -5
  257. package/dist/icons/Microphone.js +0 -12
  258. package/dist/icons/Phone.d.ts +0 -3
  259. package/dist/icons/Phone.js +0 -8
  260. package/dist/icons/Reload.d.ts +0 -3
  261. package/dist/icons/Reload.js +0 -10
  262. package/dist/icons/ThumbsDown.d.ts +0 -3
  263. package/dist/icons/ThumbsDown.js +0 -11
  264. package/dist/icons/ThumbsUp.d.ts +0 -3
  265. package/dist/icons/ThumbsUp.js +0 -11
  266. package/dist/icons/Website.d.ts +0 -3
  267. package/dist/icons/Website.js +0 -8
  268. package/dist/main.js +0 -336
  269. package/dist/store/composer.d.ts +0 -17
  270. package/dist/store/composer.js +0 -98
  271. package/dist/store/index.d.ts +0 -82
  272. package/dist/store/index.js +0 -576
  273. package/dist/store/view.d.ts +0 -61
  274. package/dist/store/view.js +0 -361
  275. package/dist/translations/ar.json +0 -30
  276. package/dist/translations/de.json +0 -32
  277. package/dist/translations/en.json +0 -40
  278. package/dist/translations/es.json +0 -19
  279. package/dist/translations/fr.json +0 -40
  280. package/dist/translations/index.d.ts +0 -9
  281. package/dist/translations/index.js +0 -95
  282. package/dist/translations/it.json +0 -38
  283. package/dist/translations/pt.json +0 -19
  284. package/dist/translations/ru.json +0 -24
  285. package/dist/translations/uk.json +0 -24
  286. package/dist/typings.d.ts +0 -378
  287. package/dist/typings.js +0 -2
  288. package/dist/utils/analytics.d.ts +0 -5
  289. package/dist/utils/analytics.js +0 -37
  290. package/dist/utils/index.d.ts +0 -3
  291. package/dist/utils/index.js +0 -27
  292. package/dist/utils/storage.d.ts +0 -16
  293. package/dist/utils/storage.js +0 -129
  294. package/dist/utils/webchatEvents.d.ts +0 -2
  295. package/dist/utils/webchatEvents.js +0 -14
@@ -0,0 +1,496 @@
1
+ import { tx } from '@twind/core'
2
+ import { useState } from 'react'
3
+ import { HexColorPicker } from 'react-colorful'
4
+ import { z } from 'zod'
5
+ import { useWebchatContext } from '../../contexts'
6
+ import { ThemeSchema } from '../../schemas'
7
+ import { buildDawnTheme, buildMidnightTheme, duskTheme, eggplantTheme, galaxyTheme, prismTheme } from '../../themes'
8
+ import { MessageObject } from '../../types'
9
+ import { messageInBubble } from './helpers'
10
+
11
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
12
+ const messagesToSend: Record<string, MessageObject> = {
13
+ shortText: messageInBubble({
14
+ type: 'text',
15
+ text: 'Hello, World!',
16
+ }),
17
+ md: messageInBubble({
18
+ type: 'text',
19
+ //text example using multiple markdown features
20
+ text: '# Hello, World! \n ## This is a markdown message. \n\n ### Heading 3 \n\n You can use **bold**, _italic_, and `code`.\n\nYou can also use [links](https://www.google.com) and\n\n- Lists\n- Like\n- This\n\nAnd even\n1. Numbered\n2. Lists\n3. Like\n4. This',
21
+ }),
22
+ longText: messageInBubble({
23
+ type: 'text',
24
+ text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec euismod, nisl eget tempor aliquam, nisl nisl aliquet nisl, eget aliquam nisl nisl eget nisl. Donec euismod, nisl eget tempor aliquam, nisl nisl aliquet nisl, eget aliquam nisl nisl eget nisl.',
25
+ }),
26
+ portraitImage: {
27
+ direction: 'incoming',
28
+ sender: {
29
+ name: 'Bot',
30
+ },
31
+ timestamp: new Date(),
32
+
33
+ block: {
34
+ type: 'image',
35
+ url: `https://picsum.photos/1080/1920`,
36
+ },
37
+ },
38
+ landscapeImage: {
39
+ direction: 'incoming',
40
+ sender: {
41
+ name: 'Bot',
42
+ },
43
+ timestamp: new Date(),
44
+ block: {
45
+ type: 'image',
46
+ url: `https://picsum.photos/1920/1080`,
47
+ },
48
+ },
49
+ squareImage: {
50
+ direction: 'incoming',
51
+ sender: {
52
+ name: 'Bot',
53
+ },
54
+ timestamp: new Date(),
55
+
56
+ block: {
57
+ type: 'image',
58
+ url: `https://picsum.photos/1920/1920`,
59
+ },
60
+ },
61
+ video: {
62
+ direction: 'incoming',
63
+ sender: {
64
+ name: 'Bot',
65
+ },
66
+ timestamp: new Date(),
67
+ block: {
68
+ type: 'video',
69
+ url: 'https://spg-test-public-files.s3.us-east-1.amazonaws.com/sample-mp4-file-small.mp4',
70
+ },
71
+ },
72
+ audio: {
73
+ direction: 'incoming',
74
+ sender: {
75
+ name: 'Bot',
76
+ },
77
+ timestamp: new Date(),
78
+ block: {
79
+ type: 'audio',
80
+ url: 'https://soundbible.com/mp3/MP5_SMG-GunGuru-703432894.mp3',
81
+ },
82
+ },
83
+ button: {
84
+ direction: 'incoming',
85
+ sender: {
86
+ name: 'Bot',
87
+ },
88
+ timestamp: new Date(),
89
+ block: {
90
+ type: 'button',
91
+ variant: 'action',
92
+ text: 'Button',
93
+ buttonValue: 'Hello, World!',
94
+ },
95
+ },
96
+ disableInput: {
97
+ direction: 'incoming',
98
+ disableInput: true,
99
+ sender: {
100
+ name: 'Bot',
101
+ },
102
+ timestamp: new Date(),
103
+ block: {
104
+ type: 'button',
105
+ variant: 'action',
106
+ text: 'Button',
107
+ buttonValue: 'Hello, World!',
108
+ },
109
+ },
110
+ location: {
111
+ direction: 'incoming',
112
+ sender: {
113
+ name: 'Bot',
114
+ },
115
+ timestamp: new Date(),
116
+ block: {
117
+ type: 'location',
118
+ latitude: 40.7128,
119
+ longitude: -74.006,
120
+ title: 'New York, NY',
121
+ },
122
+ },
123
+ rowOfButtons: {
124
+ direction: 'incoming',
125
+ sender: {
126
+ name: 'Bot',
127
+ },
128
+ timestamp: new Date(),
129
+ block: {
130
+ type: 'row',
131
+ blocks: [
132
+ {
133
+ type: 'button',
134
+ variant: 'action',
135
+ groupId: 'group1',
136
+ text: 'Button 1',
137
+ buttonValue: 'Button 1',
138
+ },
139
+ {
140
+ type: 'button',
141
+ variant: 'action',
142
+ groupId: 'group1',
143
+ text: 'Button 2',
144
+ buttonValue: 'Button 2',
145
+ },
146
+ {
147
+ type: 'button',
148
+ variant: 'link',
149
+ groupId: 'group1',
150
+ text: 'Button 3',
151
+ buttonValue: 'Button 3',
152
+ },
153
+ ],
154
+ },
155
+ },
156
+ card: messageInBubble({
157
+ type: 'column',
158
+ horizontalAlignment: 'center',
159
+ blocks: [
160
+ {
161
+ type: 'image',
162
+ url: 'https://picsum.photos/700/350',
163
+ },
164
+ {
165
+ type: 'text',
166
+ text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
167
+ },
168
+ {
169
+ type: 'row',
170
+ horizontalAlignment: 'center',
171
+ blocks: [
172
+ {
173
+ type: 'button',
174
+ text: 'Button A',
175
+ variant: 'action',
176
+ groupId: 'group1',
177
+ buttonValue: 'Button A',
178
+ },
179
+ {
180
+ type: 'button',
181
+ text: 'Button B',
182
+ variant: 'action',
183
+ groupId: 'group1',
184
+ buttonValue: 'Button B',
185
+ },
186
+ {
187
+ type: 'button',
188
+ text: 'Button C',
189
+ variant: 'link',
190
+ groupId: 'group1',
191
+ buttonValue: 'Button C',
192
+ },
193
+ ],
194
+ },
195
+ ],
196
+ }),
197
+ carousel: {
198
+ direction: 'incoming',
199
+ sender: {
200
+ name: 'Bot',
201
+ },
202
+ timestamp: new Date(),
203
+ block: {
204
+ type: 'carousel',
205
+ blocks: [
206
+ {
207
+ type: 'image',
208
+ url: `https://picsum.photos/${Math.floor(Math.random() * 1920)}/${Math.floor(Math.random() * 1920)}`,
209
+ },
210
+ {
211
+ type: 'image',
212
+ url: `https://picsum.photos/${Math.floor(Math.random() * 1920)}/${Math.floor(Math.random() * 1920)}`,
213
+ },
214
+ {
215
+ type: 'image',
216
+ url: `https://picsum.photos/${Math.floor(Math.random() * 1920)}/${Math.floor(Math.random() * 1920)}`,
217
+ },
218
+ {
219
+ type: 'image',
220
+ url: `https://picsum.photos/${Math.floor(Math.random() * 1920)}/${Math.floor(Math.random() * 1920)}`,
221
+ },
222
+ {
223
+ type: 'image',
224
+ url: `https://picsum.photos/${Math.floor(Math.random() * 1920)}/${Math.floor(Math.random() * 1920)}`,
225
+ },
226
+ {
227
+ type: 'image',
228
+ url: `https://picsum.photos/${Math.floor(Math.random() * 1920)}/${Math.floor(Math.random() * 1920)}`,
229
+ },
230
+ {
231
+ type: 'column',
232
+ horizontalAlignment: 'center',
233
+ blocks: [
234
+ {
235
+ type: 'image',
236
+ url: 'https://picsum.photos/300/350',
237
+ },
238
+ {
239
+ type: 'text',
240
+ text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
241
+ },
242
+ {
243
+ type: 'row',
244
+ horizontalAlignment: 'center',
245
+ blocks: [
246
+ {
247
+ type: 'button',
248
+ text: 'Button A',
249
+ variant: 'action',
250
+ groupId: 'group1',
251
+ buttonValue: 'Button A',
252
+ },
253
+ {
254
+ type: 'button',
255
+ text: 'Button B',
256
+ variant: 'action',
257
+ groupId: 'group1',
258
+ buttonValue: 'Button B',
259
+ },
260
+ {
261
+ type: 'button',
262
+ text: 'Button C',
263
+ variant: 'link',
264
+ groupId: 'group1',
265
+ buttonValue: 'Button C',
266
+ },
267
+ {
268
+ type: 'button',
269
+ text: 'Button C',
270
+ variant: 'link',
271
+ groupId: 'group1',
272
+ buttonValue: 'Button C',
273
+ },
274
+ {
275
+ type: 'button',
276
+ text: 'Button C',
277
+ variant: 'link',
278
+ groupId: 'group1',
279
+ buttonValue: 'Button C',
280
+ },
281
+ {
282
+ type: 'button',
283
+ text: 'Button C',
284
+ variant: 'link',
285
+ groupId: 'group1',
286
+ buttonValue: 'Button C',
287
+ },
288
+ ],
289
+ },
290
+ ],
291
+ },
292
+ ],
293
+ },
294
+ },
295
+ }
296
+
297
+ const configSchema = z
298
+ .object({
299
+ composerPlaceholder: z.string().optional(),
300
+ botConversationDescription: z.string().optional(),
301
+ botId: z.string().optional(),
302
+ hostUrl: z.string().optional(),
303
+ messagingUrl: z.string(),
304
+ clientId: z.string(),
305
+ lazySocket: z.boolean().optional(),
306
+ botName: z.string().optional(),
307
+ avatarUrl: z.string().optional(),
308
+ phoneNumber: z
309
+ .string()
310
+ .optional()
311
+ .transform((val) => {
312
+ if (val) {
313
+ return { title: val }
314
+ }
315
+ }),
316
+ termsConditions: z
317
+ .string()
318
+ .optional()
319
+ .transform((val) => {
320
+ if (val) {
321
+ return { title: val, link: val }
322
+ }
323
+ }),
324
+ privacyPolicy: z
325
+ .string()
326
+ .optional()
327
+ .transform((val) => {
328
+ if (val) {
329
+ return { title: val, link: val }
330
+ }
331
+ }),
332
+ emailAddress: z
333
+ .string()
334
+ .optional()
335
+ .transform((val) => {
336
+ if (val) {
337
+ return { title: val }
338
+ }
339
+ }),
340
+ website: z
341
+ .string()
342
+ .optional()
343
+ .transform((val) => {
344
+ if (val) {
345
+ return { title: val, link: val }
346
+ }
347
+ }),
348
+ showPoweredBy: z.boolean().optional(),
349
+ })
350
+ .transform((val) => {
351
+ console.log(val)
352
+ return {
353
+ ...val,
354
+ ...(val.avatarUrl && { botAvatar: val.avatarUrl }),
355
+ ...(val.botConversationDescription && { botDescription: val.botConversationDescription }),
356
+ ...(val.emailAddress && { email: val.emailAddress }),
357
+ ...(val.termsConditions && { termsOfService: val.termsConditions }),
358
+ ...(val.phoneNumber && { phone: val.phoneNumber }),
359
+ }
360
+ })
361
+
362
+ function parseWebchatScript(script: string) {
363
+ const scriptRegex = /<script\b[^>]*>([\s\S]*?)<\/script>/gm
364
+ const initRegex = /window\.botpressWebChat\.init\(([\s\S]*?)\);/gm
365
+
366
+ let match
367
+ let initObject
368
+
369
+ while ((match = scriptRegex.exec(script)) !== null) {
370
+ const scriptContent = match[1]
371
+ const initMatch = initRegex.exec(scriptContent)
372
+
373
+ if (initMatch !== null) {
374
+ initObject = JSON.parse(initMatch[1])
375
+ break
376
+ }
377
+ }
378
+
379
+ const config = configSchema.parse(initObject)
380
+
381
+ return config
382
+ }
383
+
384
+ export const DevTools = () => {
385
+ const [newMessageDirection, setNewMessageDirection] = useState<MessageObject['direction']>('incoming')
386
+ const { setTheme: setStyles, setConfiguration } = useWebchatContext()
387
+ const [currentTheme, setCurrentTheme] = useState<'dawn' | 'midnight' | 'prism' | 'galaxy' | 'eggplant' | 'dusk'>(
388
+ 'prism'
389
+ )
390
+ const [color, setColor] = useState<string>()
391
+
392
+ const [webchatScript, setWebchatScript] = useState('')
393
+
394
+ const themes = {
395
+ dawn: buildDawnTheme('#dc2626'),
396
+ midnight: buildMidnightTheme('#dc2626'),
397
+ prism: prismTheme,
398
+ galaxy: galaxyTheme,
399
+ eggplant: eggplantTheme,
400
+ dusk: duskTheme,
401
+ } as const
402
+
403
+ return (
404
+ <div>
405
+ <div className="item flex flex-wrap gap-4 rounded-lg border border-gray-200 bg-gray-50 p-2">
406
+ <div className="flex w-fit items-center">
407
+ <input
408
+ type="checkbox"
409
+ className="mr-2 h-4 w-4 rounded"
410
+ checked={newMessageDirection === 'outgoing'}
411
+ onChange={() => setNewMessageDirection((direction) => (direction === 'incoming' ? 'outgoing' : 'incoming'))}
412
+ />
413
+ <label className="font-medium capitalize text-gray-700">{newMessageDirection}</label>
414
+ </div>
415
+ <div className="flex w-fit items-center">
416
+ <label className="font-medium capitalize text-gray-700">Theme</label>
417
+ <select
418
+ className="ml-2 rounded-lg border border-gray-200 bg-gray-50 p-1 px-3 text-sm capitalize"
419
+ onChange={(e) => {
420
+ setStyles(ThemeSchema.parse(themes[e.target.value as keyof typeof themes]))
421
+ setCurrentTheme(e.target.value as keyof typeof themes)
422
+ }}
423
+ >
424
+ <option value="prism">Prism</option>
425
+ <option value="galaxy">Galaxy</option>
426
+ <option value="eggplant">Eggplant</option>
427
+ <option value="dusk">Dusk</option>
428
+ <option value="dawn">Dawn</option>
429
+ <option value="midnight">Midnight</option>
430
+ </select>
431
+ </div>
432
+
433
+ {/* {Object.entries(messagesToSend).map(([key, message]) => (
434
+ <button
435
+ key={key}
436
+ className={tx(' rounded-lg border p-1 px-3 text-sm capitalize', {
437
+ 'border-gray-200 bg-white text-gray-800': newMessageDirection === 'incoming',
438
+ 'border-blue-600 bg-blue-600 font-medium text-white': newMessageDirection === 'outgoing',
439
+ })}
440
+ onClick={() => client.addMessage({ ...message, direction: newMessageDirection })}
441
+ >
442
+ {splitCamelCase(key)}
443
+ </button>
444
+ ))}
445
+ <button className="rounded-lg p-1 px-3 font-medium text-red-600" onClick={() => client.clearMessages()}>
446
+ Clear
447
+ </button> */}
448
+ </div>
449
+ <div className="flex items-center gap-6">
450
+ <textarea
451
+ value={webchatScript}
452
+ onChange={(e) => setWebchatScript(e.target.value)}
453
+ className="grow whitespace-pre-wrap border border-gray-300 bg-gray-50 font-mono"
454
+ />
455
+ <button
456
+ onClick={() => {
457
+ try {
458
+ const config = parseWebchatScript(webchatScript)
459
+ console.log(config)
460
+ // setClient(new WebchatClient({ clientId: config.clientId, url: config.messagingUrl }))
461
+ setConfiguration((prevConfig) => {
462
+ return {
463
+ ...prevConfig,
464
+ ...config,
465
+ }
466
+ })
467
+ } catch (err) {
468
+ console.error(err)
469
+ }
470
+ }}
471
+ className={tx(
472
+ 'h-fit rounded-lg border p-1 px-3 py-2 text-sm capitalize hover:bg-gray-100 active:bg-gray-200',
473
+ {
474
+ 'border-gray-200 bg-white text-gray-800': newMessageDirection === 'incoming',
475
+ 'border-blue-600 bg-blue-600 font-medium text-white': newMessageDirection === 'outgoing',
476
+ }
477
+ )}
478
+ >
479
+ Update webchat
480
+ </button>
481
+ </div>
482
+ {(currentTheme === 'dawn' || currentTheme === 'midnight') && (
483
+ <div className="flex w-fit flex-wrap items-center gap-4">
484
+ <HexColorPicker
485
+ color={color}
486
+ onChange={(color) => {
487
+ setColor(color)
488
+ currentTheme === 'dawn' && setStyles(buildDawnTheme(color))
489
+ currentTheme === 'midnight' && setStyles(buildMidnightTheme(color))
490
+ }}
491
+ />
492
+ </div>
493
+ )}
494
+ </div>
495
+ )
496
+ }
@@ -0,0 +1,27 @@
1
+ import { Configuration } from '../../contexts'
2
+
3
+ export const defaultConfiguration: Configuration = {
4
+ composerPlaceholder: 'What would you like to know?',
5
+ botName: 'Customer service',
6
+ botAvatar: 'https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50',
7
+ botDescription:
8
+ 'Welcome to webchat this is some description talking about what it is. This might be a bit longer when expanded.',
9
+ email: {
10
+ title: 'christophe.sirois@botpress.com',
11
+ },
12
+ phone: {
13
+ title: '581-456-8631',
14
+ },
15
+ website: {
16
+ title: 'https://botpress.com',
17
+ link: 'https://botpress.com',
18
+ },
19
+ termsOfService: {
20
+ title: 'Terms of service',
21
+ link: 'https://botpress.com/terms',
22
+ },
23
+ privacyPolicy: {
24
+ title: 'Privacy policy',
25
+ link: 'https://botpress.com/privacy',
26
+ },
27
+ } as const
@@ -0,0 +1,21 @@
1
+ import { BlockObject, MessageObject } from '../../types'
2
+
3
+ type Direction = 'incoming' | 'outgoing' | 'system'
4
+
5
+ export function messageInBubble(block: BlockObject, direction?: Direction): MessageObject {
6
+ return {
7
+ direction: direction || 'incoming',
8
+ sender: {
9
+ name: 'Bot',
10
+ },
11
+ timestamp: new Date(),
12
+ block: {
13
+ type: 'bubble',
14
+ block,
15
+ },
16
+ }
17
+ }
18
+
19
+ export function splitCamelCase(text: string): string {
20
+ return text.replace(/([a-z])([A-Z])/g, '$1 $2')
21
+ }
@@ -0,0 +1,12 @@
1
+ export * from './Avatar'
2
+ export * from './Block'
3
+ export * from './Composer'
4
+ export * from './Container'
5
+ export * from './Header'
6
+ export * from './LoadingIndicator'
7
+ export * from './Message'
8
+ export * from './MessageList'
9
+ export * from './Modal'
10
+ export * from './RestartConversation'
11
+ export * from './Webchat'
12
+ export * from './renderers'
@@ -0,0 +1,11 @@
1
+ import { forwardRef } from 'react'
2
+ import { CommonBlockProps, AudioBlock } from '../../types'
3
+
4
+ type Props = CommonBlockProps & AudioBlock
5
+ export const Audio = forwardRef<HTMLAudioElement, Props>(({ url, type, styles, ...props }, ref) => {
6
+ return (
7
+ <div>
8
+ <audio {...props} controls src={url} {...styles?.[type]} ref={ref} />
9
+ </div>
10
+ )
11
+ })
@@ -0,0 +1,12 @@
1
+ import { ComponentProps, forwardRef } from 'react'
2
+ import { BubbleBlock, CommonBlockProps } from '../../types'
3
+ import { Block } from '../Block'
4
+
5
+ type Props = CommonBlockProps & BubbleBlock & ComponentProps<'div'>
6
+ export const Bubble = forwardRef<HTMLDivElement, Props>(({ block, styles, type, ...props }, ref) => {
7
+ return (
8
+ <div {...props} {...styles?.[type]} ref={ref}>
9
+ <Block styles={styles} block={block} />
10
+ </div>
11
+ )
12
+ })
@@ -0,0 +1,59 @@
1
+ import { ComponentProps, useEffect, useState } from 'react'
2
+ import { ButtonBlock, CommonBlockProps } from '../../types'
3
+ import { useWebchatContext } from '../../contexts'
4
+
5
+ type Props = CommonBlockProps & ButtonBlock
6
+ export const Button = ({ text, buttonValue, type, styles, variant, groupId, reusable, ...props }: Props) => {
7
+ const { eventEmitter, client } = useWebchatContext()
8
+ const [activated, setActivated] = useState(false)
9
+ const [groupActivated, setGroupActivated] = useState(false)
10
+ const [disabled, setDisabled] = useState(false)
11
+
12
+ useEffect(() => {
13
+ if (!groupId) return
14
+ return eventEmitter.on(`button-group-${groupId}-click`, () => {
15
+ setGroupActivated(true)
16
+ if (!reusable) setDisabled(true)
17
+ })
18
+ }, [eventEmitter, groupId, reusable])
19
+
20
+ function onClick() {
21
+ if (groupId) {
22
+ eventEmitter.emit(`button-group-${groupId}-click`)
23
+ }
24
+ setActivated(true)
25
+ if (!reusable) setDisabled(true)
26
+ if (variant === 'link') return
27
+ client.sendMessage(buttonValue)
28
+ }
29
+
30
+ return (
31
+ <ButtonOrAnchor
32
+ {...props}
33
+ variant={variant}
34
+ onClick={onClick}
35
+ disabled={disabled}
36
+ data-activated={activated ? '' : undefined}
37
+ data-group-activated={groupActivated ? '' : undefined}
38
+ data-type={variant}
39
+ value={buttonValue}
40
+ {...styles?.[type]}
41
+ >
42
+ {text}
43
+ </ButtonOrAnchor>
44
+ )
45
+ }
46
+ type ButtonOrAnchorProps =
47
+ | ({ variant: 'action' } & ComponentProps<'button'>)
48
+ | ({ variant: 'link'; value: string } & ComponentProps<'a'>)
49
+ const ButtonOrAnchor = (props: ButtonOrAnchorProps) => {
50
+ if (props.variant === 'link') {
51
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
52
+ const { value, variant, ...rest } = props
53
+ return <a {...rest} href={value} target="_blank" rel="noopener noreferrer" />
54
+ }
55
+
56
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
57
+ const { variant, ...rest } = props
58
+ return <button {...rest} />
59
+ }
@@ -0,0 +1,51 @@
1
+ import { forwardRef, useCallback, useEffect, useState } from 'react'
2
+ import { CarouselBlock, CommonBlockProps } from '../../types'
3
+ import useEmblaCarousel, { EmblaCarouselType } from 'embla-carousel-react'
4
+ import { Block } from '../Block'
5
+ import { ChevronRightIcon, ChevronLeftIcon } from '@heroicons/react/24/solid'
6
+
7
+ type Props = CommonBlockProps & CarouselBlock
8
+ export const Carousel = forwardRef<HTMLDivElement, Props>(({ type, styles, blocks }, ref) => {
9
+ const [emblaRef, emblaApi] = useEmblaCarousel({ skipSnaps: true })
10
+
11
+ const [prevBtnDisabled, setPrevBtnDisabled] = useState(true)
12
+ const [nextBtnDisabled, setNextBtnDisabled] = useState(true)
13
+
14
+ const scrollPrev = useCallback(() => emblaApi && emblaApi.scrollPrev(), [emblaApi])
15
+ const scrollNext = useCallback(() => emblaApi && emblaApi.scrollNext(), [emblaApi])
16
+
17
+ const carouselStyles = styles?.[type]
18
+
19
+ const onSelect = useCallback((emblaApi: EmblaCarouselType) => {
20
+ setPrevBtnDisabled(!emblaApi.canScrollPrev())
21
+ setNextBtnDisabled(!emblaApi.canScrollNext())
22
+ }, [])
23
+
24
+ useEffect(() => {
25
+ if (!emblaApi) return
26
+ onSelect(emblaApi)
27
+ emblaApi.on('reInit', onSelect)
28
+ emblaApi.on('select', onSelect)
29
+ }, [emblaApi, onSelect])
30
+
31
+ return (
32
+ <div {...carouselStyles?.container} data-container="carousel" ref={emblaRef}>
33
+ <div ref={ref} {...carouselStyles?.slidesContainer}>
34
+ {blocks.map((block, index) => (
35
+ <Block key={index} styles={styles} block={block} />
36
+ ))}
37
+ </div>
38
+ <ChevronLeftIcon
39
+ {...carouselStyles?.backButton}
40
+ data-disabled={prevBtnDisabled ? '' : undefined}
41
+ onClick={scrollPrev}
42
+ />
43
+
44
+ <ChevronRightIcon
45
+ {...carouselStyles?.nextButton}
46
+ data-disabled={nextBtnDisabled ? '' : undefined}
47
+ onClick={scrollNext}
48
+ />
49
+ </div>
50
+ )
51
+ })