@botpress/webchat 0.5.1 → 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 -49
  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 -41
  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 -107
  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 -148
  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 -2
  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 -89
  272. package/dist/store/index.js +0 -604
  273. package/dist/store/view.d.ts +0 -61
  274. package/dist/store/view.js +0 -365
  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 -410
  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
package/src/main.tsx ADDED
@@ -0,0 +1,33 @@
1
+ import ReactDOM from 'react-dom/client'
2
+ import { App } from './App.tsx'
3
+ import './index.css'
4
+
5
+ import { StrictMode } from 'react'
6
+
7
+ import { install } from '@twind/core'
8
+ import { config } from './twind.config.ts'
9
+ import { ThemeSchema } from './schemas'
10
+ import { prismTheme } from './themes'
11
+ import { WebchatClient } from './client/MessagingClient.ts'
12
+
13
+ export const twObject = install(config)
14
+
15
+ export const webchatClient = new WebchatClient({
16
+ url: 'https://messaging.botpress.cloud',
17
+ clientId: 'b390bfce-4eed-4078-b180-655f8202a12d',
18
+ })
19
+
20
+ //bot a louis
21
+ // 09d8ea5b-2781-4fe4-a0b5-d75798b24c50
22
+
23
+ //hello sarah
24
+ // b390bfce-4eed-4078-b180-655f8202a12d
25
+
26
+ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
27
+ <StrictMode>
28
+ <div className="grid h-screen w-screen grid-flow-col grid-cols-[24rem_1fr] grid-rows-[auto_1fr] gap-8 p-8">
29
+ <App theme={ThemeSchema.parse(prismTheme)} client={webchatClient} />
30
+ <App theme={ThemeSchema.parse(prismTheme)} client={webchatClient} />
31
+ </div>
32
+ </StrictMode>
33
+ )
@@ -0,0 +1,35 @@
1
+ import { PropsWithChildren, ReactNode, useState } from 'react'
2
+ import { Modal } from '../components'
3
+ import { ModalContext } from '../contexts'
4
+
5
+ export type ModalProps = {
6
+ title: string | null
7
+ content: ReactNode | null
8
+ }
9
+
10
+ type Props = PropsWithChildren
11
+
12
+ export const ModalProvider = ({ children }: Props) => {
13
+ const [open, setOpen] = useState(false)
14
+ const [title, setTitle] = useState<string>('')
15
+ const [content, setContent] = useState<ReactNode | null>(null)
16
+
17
+ const showModal = ({ title, content }: { title: string; content: ReactNode }) => {
18
+ setTitle(title)
19
+ setContent(content)
20
+ setOpen(true)
21
+ }
22
+
23
+ const hideModal = () => {
24
+ setOpen(false)
25
+ }
26
+
27
+ return (
28
+ <ModalContext.Provider value={{ hideModal, showModal, title, content, open }}>
29
+ <Modal open={open} onOpenChange={setOpen}>
30
+ <Modal.Content title={title}>{content}</Modal.Content>
31
+ </Modal>
32
+ {children}
33
+ </ModalContext.Provider>
34
+ )
35
+ }
@@ -0,0 +1,107 @@
1
+ import { ComponentProps, ReactNode, useState } from 'react'
2
+ import { Configuration, Renderers, WebchatContext } from '../contexts'
3
+ import { eventEmitter } from '../Utils'
4
+ import { renderers as defaultRenderers } from '../components'
5
+ import { defaultConfiguration } from '../components/dev-tools/configuration'
6
+ import { MessageObject } from '../types'
7
+ import { Theme } from '../schemas'
8
+ import { useAsync, useEffectOnce } from 'react-use'
9
+ import { type WebchatClient, MessageContentSchema } from '../client'
10
+ import { Message } from '@botpress/messaging-socket'
11
+ import { useWebchatStore } from '../hooks'
12
+
13
+ type Props = {
14
+ styles?: Theme
15
+ renderers?: Renderers
16
+ client: WebchatClient
17
+ configuration: Configuration
18
+ children?: ReactNode | ((configuration: Configuration) => ReactNode)
19
+ } & Omit<ComponentProps<typeof WebchatContext.Provider>, 'value' | 'children'>
20
+
21
+ export const WebchatProvider = ({ styles = {}, renderers, client, children, configuration, ...props }: Props) => {
22
+ const [messages, setMessages] = useState<MessageObject[]>([])
23
+ const [state, setWebchatState] = useState({ disableComposer: false })
24
+ const [config, setConfig] = useState(configuration)
25
+ const [theme, setTheme] = useState<Theme>(styles) // TODO: remove this once dev theme switching is figured out
26
+ const addMessageToHistory = useWebchatStore((state) => state.addMessageToHistory)
27
+ const setConversationId = useWebchatStore((state) => state.setConversationId)
28
+ const user = useWebchatStore((state) => state.user)
29
+ const setUser = useWebchatStore((state) => state.setUser)
30
+
31
+ const providerProps = {
32
+ ...props,
33
+ value: {
34
+ theme,
35
+ renderers: { ...defaultRenderers, ...renderers },
36
+ messages,
37
+ eventEmitter,
38
+ configuration,
39
+ setConfiguration: setConfig,
40
+ state,
41
+ setState: (newState: Partial<typeof state>) => setWebchatState({ ...state, ...newState }),
42
+ setTheme,
43
+ client: {
44
+ sendMessage: async (message: string) => {
45
+ await client.sendMessage(message)
46
+ setMessages((messages) => [
47
+ ...messages,
48
+ {
49
+ direction: 'outgoing',
50
+ sender: { name: 'You' },
51
+ timestamp: new Date(),
52
+ block: { type: 'bubble', block: { type: 'text', text: message } },
53
+ },
54
+ ])
55
+
56
+ if (client.userId) {
57
+ addMessageToHistory({ message, userId: client.userId })
58
+ }
59
+ },
60
+ on: client.on,
61
+ restartConversation: async () => {
62
+ await client.newConversation()
63
+ setMessages([])
64
+ },
65
+ },
66
+ },
67
+ }
68
+
69
+ useEffectOnce(() => {
70
+ return client.on('message', (message: Message) => {
71
+ try {
72
+ const payload = MessageContentSchema.parse(message.payload)
73
+ setMessages((messages) => [
74
+ ...messages,
75
+ {
76
+ direction: 'incoming',
77
+ sender: { name: 'Bot', avatar: config.botAvatar },
78
+ timestamp: message.sentOn,
79
+ block: payload,
80
+ },
81
+ ])
82
+ } catch (err) {
83
+ console.error('Invalid message payload')
84
+ }
85
+ })
86
+ })
87
+
88
+ useEffectOnce(() => {
89
+ return client.on('conversation', (conversationId) => {
90
+ setConversationId(conversationId)
91
+ })
92
+ })
93
+
94
+ useAsync(async () => {
95
+ const newUser = await client.connect(user)
96
+ setUser(newUser)
97
+ return () => {
98
+ client.disconnect()
99
+ }
100
+ }, [])
101
+
102
+ return (
103
+ <WebchatContext.Provider {...providerProps}>
104
+ {typeof children === 'function' ? children(config) : children}
105
+ </WebchatContext.Provider>
106
+ )
107
+ }
@@ -0,0 +1,2 @@
1
+ export * from './ModalProvider'
2
+ export * from './WebchatProvider'
@@ -0,0 +1 @@
1
+ export * from './theme'
@@ -0,0 +1,188 @@
1
+ import { CSSProperties } from 'react'
2
+ import { markdownTypes } from '../types'
3
+ import { z } from 'zod'
4
+ import { tw } from '@twind/core'
5
+
6
+ const StyleOptionSchema = z.object({
7
+ className: z
8
+ .string()
9
+ .optional()
10
+ .transform((val) => {
11
+ if (val) {
12
+ return tw(val)
13
+ }
14
+ }),
15
+ style: z
16
+ .object({})
17
+ .passthrough()
18
+ .optional()
19
+ .transform((val) => {
20
+ if (val) {
21
+ return val as CSSProperties
22
+ }
23
+ }),
24
+ })
25
+
26
+ export const BlocksSchema = z.object({
27
+ button: StyleOptionSchema.optional(),
28
+ text: z.record(z.enum(markdownTypes), StyleOptionSchema.optional()),
29
+ image: z
30
+ .object({
31
+ image: StyleOptionSchema.optional(),
32
+ placeholder: StyleOptionSchema.optional(),
33
+ })
34
+ .optional(),
35
+ audio: StyleOptionSchema.optional(),
36
+ video: StyleOptionSchema.optional(),
37
+ file: z
38
+ .object({
39
+ container: StyleOptionSchema.optional(),
40
+ title: StyleOptionSchema.optional(),
41
+ icon: StyleOptionSchema.optional(),
42
+ })
43
+ .optional(),
44
+ location: z
45
+ .object({
46
+ container: StyleOptionSchema.optional(),
47
+ title: StyleOptionSchema.optional(),
48
+ icon: StyleOptionSchema.optional(),
49
+ })
50
+ .optional(),
51
+ column: StyleOptionSchema.optional(),
52
+ row: StyleOptionSchema.optional(),
53
+ bubble: StyleOptionSchema.optional(),
54
+ carousel: z
55
+ .object({
56
+ container: StyleOptionSchema.optional(),
57
+ slidesContainer: StyleOptionSchema.optional(),
58
+ backButton: StyleOptionSchema.optional(),
59
+ nextButton: StyleOptionSchema.optional(),
60
+ })
61
+ .optional(),
62
+ dropdown: z
63
+ .object({
64
+ button: z
65
+ .object({
66
+ container: StyleOptionSchema.optional(),
67
+ icon: StyleOptionSchema.optional(),
68
+ text: StyleOptionSchema.optional(),
69
+ })
70
+ .optional(),
71
+ content: z
72
+ .object({
73
+ container: StyleOptionSchema.optional(),
74
+ item: StyleOptionSchema.optional(),
75
+ })
76
+ .optional(),
77
+ })
78
+ .optional(),
79
+ })
80
+
81
+ export type Theme = z.infer<typeof ThemeSchema>
82
+ export const ThemeSchema = z.object({
83
+ container: StyleOptionSchema.optional(),
84
+ modal: z
85
+ .object({
86
+ overlay: StyleOptionSchema.optional(),
87
+ container: StyleOptionSchema.optional(),
88
+ dialog: z
89
+ .object({
90
+ container: StyleOptionSchema.optional(),
91
+ title: z
92
+ .object({
93
+ container: StyleOptionSchema.optional(),
94
+ text: StyleOptionSchema.optional(),
95
+ closeIcon: StyleOptionSchema.optional(),
96
+ })
97
+ .optional(),
98
+ content: StyleOptionSchema.optional(),
99
+ })
100
+ .optional(),
101
+ })
102
+ .optional(),
103
+ notification: z
104
+ .object({
105
+ container: StyleOptionSchema.optional(),
106
+ title: StyleOptionSchema.optional(),
107
+ description: StyleOptionSchema.optional(),
108
+ icon: StyleOptionSchema.optional(),
109
+ closeIcon: StyleOptionSchema.optional(),
110
+ })
111
+ .optional(),
112
+ header: z
113
+ .object({
114
+ container: StyleOptionSchema.optional(),
115
+ content: z.object({
116
+ container: StyleOptionSchema.optional(),
117
+ title: StyleOptionSchema.optional(),
118
+ description: StyleOptionSchema.optional(),
119
+ avatar: z
120
+ .object({
121
+ container: StyleOptionSchema.optional(),
122
+ image: StyleOptionSchema.optional(),
123
+ fallback: StyleOptionSchema.optional(),
124
+ })
125
+ .optional(),
126
+ actions: z
127
+ .object({
128
+ container: StyleOptionSchema.optional(),
129
+ icons: StyleOptionSchema.optional(),
130
+ })
131
+ .optional(),
132
+ }),
133
+ expandedContent: z
134
+ .object({
135
+ container: StyleOptionSchema.optional(),
136
+ descriptionItems: z
137
+ .object({
138
+ container: StyleOptionSchema.optional(),
139
+ icon: StyleOptionSchema.optional(),
140
+ text: StyleOptionSchema.optional(),
141
+ link: StyleOptionSchema.optional(),
142
+ })
143
+ .optional(),
144
+ })
145
+ .optional(),
146
+ description: z
147
+ .object({
148
+ container: StyleOptionSchema.optional(),
149
+ title: StyleOptionSchema.optional(),
150
+ subtitle: StyleOptionSchema.optional(),
151
+ })
152
+ .optional(),
153
+ newConversationIcon: StyleOptionSchema.optional(),
154
+ })
155
+ .optional(),
156
+ composer: z
157
+ .object({
158
+ container: StyleOptionSchema.optional(),
159
+ input: StyleOptionSchema.optional(),
160
+ button: z
161
+ .object({
162
+ container: StyleOptionSchema.optional(),
163
+ icon: StyleOptionSchema.optional(),
164
+ })
165
+ .optional(),
166
+ })
167
+ .optional(),
168
+ messageList: StyleOptionSchema.optional(),
169
+ message: z
170
+ .object({
171
+ container: StyleOptionSchema.optional(),
172
+ avatar: z
173
+ .object({
174
+ container: StyleOptionSchema.optional(),
175
+ image: StyleOptionSchema.optional(),
176
+ fallback: StyleOptionSchema.optional(),
177
+ })
178
+ .optional(),
179
+ blocks: BlocksSchema.optional(),
180
+ })
181
+ .optional(),
182
+ loadingIndicator: z
183
+ .object({
184
+ container: StyleOptionSchema.optional(),
185
+ loader: StyleOptionSchema.optional(),
186
+ })
187
+ .optional(),
188
+ })
@@ -0,0 +1,8 @@
1
+ import { showToast } from '.'
2
+
3
+ export function copyToClipboard(value: string, description?: string) {
4
+ const message = description ? `The ${description} has been copied to your clipboard.` : 'Copied to clipboard.'
5
+ return navigator.clipboard.writeText(value).then(() => {
6
+ return showToast({ title: message, type: 'success' })
7
+ })
8
+ }
@@ -0,0 +1,39 @@
1
+ import { Dimensions, Options } from '../types'
2
+
3
+ export const getImageSize = (url: string, options: Options = {}): Promise<Dimensions> => {
4
+ return new Promise((resolve, reject) => {
5
+ if (typeof window === 'undefined') {
6
+ return reject('Window is not defined')
7
+ }
8
+
9
+ if (!url) {
10
+ return reject('Url is not defined')
11
+ }
12
+
13
+ let timer: number | null = null
14
+
15
+ const img = new Image()
16
+
17
+ img.addEventListener('load', () => {
18
+ if (timer) {
19
+ clearTimeout(timer)
20
+ }
21
+
22
+ resolve({ width: img.naturalWidth, height: img.naturalHeight })
23
+ })
24
+
25
+ img.addEventListener('error', (event) => {
26
+ if (timer) {
27
+ clearTimeout(timer)
28
+ }
29
+
30
+ reject(`${event.type}: ${event.message}`)
31
+ })
32
+
33
+ img.src = url
34
+
35
+ if (options.timeout) {
36
+ timer = setTimeout(() => reject('Timeout'), options.timeout)
37
+ }
38
+ })
39
+ }
@@ -0,0 +1,3 @@
1
+ export * from './clipboard'
2
+ export * from './images'
3
+ export * from './toast'
@@ -0,0 +1,71 @@
1
+ /* eslint-disable react-refresh/only-export-components */
2
+ import { toast } from 'react-hot-toast'
3
+ import { Transition } from '@headlessui/react'
4
+ import { ReactComponent as CircleCheckIcon } from '../assets/check-circle-bold.svg'
5
+ import { ReactComponent as XCloseIcon } from '../assets/x-close.svg'
6
+ import { ReactComponent as CircleXIcon } from '../assets/x-circle-bold.svg'
7
+ import { FC, PropsWithChildren, ReactNode } from 'react'
8
+ import { useWebchatContext } from '../contexts'
9
+
10
+ type ToastType = ToastProps['type'] | CustomToastProps['type']
11
+ type CustomToastProps = {
12
+ type: 'custom'
13
+ content?: ReactNode
14
+ }
15
+ type ToastProps = {
16
+ type?: 'success' | 'error' | 'neutral'
17
+ title: string
18
+ icon?: FC<{ className?: string; type?: ToastType }>
19
+ description?: string
20
+ }
21
+
22
+ export function showToast(props: ToastProps | CustomToastProps) {
23
+ return toast.custom((t) => (
24
+ <ToastContainer type={props.type} show={t.visible}>
25
+ {props.type === 'custom' ? props.content : <ToastContent {...props} toastId={t.id} />}
26
+ </ToastContainer>
27
+ ))
28
+ }
29
+
30
+ type ToastContentProps = ToastProps & { toastId: string }
31
+ const ToastContent = ({ icon: Icon, type, title, description, toastId }: ToastContentProps) => {
32
+ const {
33
+ theme: { notification: styles },
34
+ } = useWebchatContext()
35
+
36
+ return (
37
+ <>
38
+ {Icon ? <Icon {...styles?.icon} /> : <ToastIcon {...styles?.icon} type={type} />}
39
+ <p {...styles?.title}>{title}</p>
40
+ {description ? <p {...styles?.description}>{description}</p> : null}
41
+ <XCloseIcon {...styles?.closeIcon} onClick={() => toast.dismiss(toastId)} />
42
+ </>
43
+ )
44
+ }
45
+
46
+ type ToastContainerProps = PropsWithChildren<{
47
+ type?: ToastType
48
+ show: boolean
49
+ }>
50
+ const ToastContainer = ({ type, ...props }: ToastContainerProps) => {
51
+ const {
52
+ theme: { notification: styles },
53
+ } = useWebchatContext()
54
+
55
+ return <Transition {...props} {...styles?.container} appear data-type={type ?? 'neutral'} />
56
+ }
57
+
58
+ type ToastIconProps = {
59
+ type?: ToastType
60
+ className?: string
61
+ }
62
+ const ToastIcon = ({ type, className }: ToastIconProps) => {
63
+ switch (type) {
64
+ case 'success':
65
+ return <CircleCheckIcon className={className} />
66
+ case 'error':
67
+ return <CircleXIcon className={className} />
68
+ default:
69
+ return null
70
+ }
71
+ }