@botonic/react 0.30.4 → 0.30.5-alpha.1

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 (36) hide show
  1. package/lib/cjs/components/button.d.ts +11 -10
  2. package/lib/cjs/components/button.js +39 -25
  3. package/lib/cjs/components/button.js.map +1 -1
  4. package/lib/cjs/components/index-types.d.ts +4 -0
  5. package/lib/cjs/contexts.js +3 -0
  6. package/lib/cjs/contexts.js.map +1 -1
  7. package/lib/cjs/index-types.d.ts +5 -3
  8. package/lib/cjs/webchat/cover-component/index.d.ts +6 -0
  9. package/lib/cjs/webchat/cover-component/index.js +21 -0
  10. package/lib/cjs/webchat/cover-component/index.js.map +1 -0
  11. package/lib/cjs/webchat/hooks/use-webchat.d.ts +3 -3
  12. package/lib/cjs/webchat/hooks/use-webchat.js.map +1 -1
  13. package/lib/cjs/webchat/webchat.js +10 -15
  14. package/lib/cjs/webchat/webchat.js.map +1 -1
  15. package/lib/esm/components/button.d.ts +11 -10
  16. package/lib/esm/components/button.js +39 -25
  17. package/lib/esm/components/button.js.map +1 -1
  18. package/lib/esm/components/index-types.d.ts +4 -0
  19. package/lib/esm/contexts.js +3 -0
  20. package/lib/esm/contexts.js.map +1 -1
  21. package/lib/esm/index-types.d.ts +5 -3
  22. package/lib/esm/webchat/cover-component/index.d.ts +6 -0
  23. package/lib/esm/webchat/cover-component/index.js +17 -0
  24. package/lib/esm/webchat/cover-component/index.js.map +1 -0
  25. package/lib/esm/webchat/hooks/use-webchat.d.ts +3 -3
  26. package/lib/esm/webchat/hooks/use-webchat.js.map +1 -1
  27. package/lib/esm/webchat/webchat.js +10 -15
  28. package/lib/esm/webchat/webchat.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/components/{button.jsx → button.tsx} +49 -20
  31. package/src/components/index-types.ts +4 -0
  32. package/src/contexts.tsx +3 -0
  33. package/src/index-types.ts +7 -3
  34. package/src/webchat/cover-component/index.tsx +31 -0
  35. package/src/webchat/hooks/use-webchat.ts +2 -2
  36. package/src/webchat/webchat.jsx +43 -46
@@ -8,6 +8,7 @@ import { resolveImage } from '../util/environment'
8
8
  import { renderComponent } from '../util/react'
9
9
  import { generateWebviewUrlWithParams } from '../util/webviews'
10
10
  import { ButtonsDisabler } from './buttons-disabler'
11
+ import { ButtonProps } from './index-types'
11
12
 
12
13
  const StyledButton = styled.button`
13
14
  display: flex;
@@ -24,10 +25,10 @@ const StyledButton = styled.button`
24
25
  border: 1px solid ${COLORS.SEASHELL_WHITE};
25
26
  cursor: pointer;
26
27
  outline: 0;
27
- border-top-right-radius: ${props => props.top || '0px'};
28
- border-top-left-radius: ${props => props.top || '0px'};
29
- border-bottom-right-radius: ${props => props.bottom || '0px'};
30
- border-bottom-left-radius: ${props => props.bottom || '0px'};
28
+ border-top-right-radius: 0px;
29
+ border-top-left-radius: 0px;
30
+ border-bottom-right-radius: 0px;
31
+ border-bottom-left-radius: 0px;
31
32
  overflow: hidden;
32
33
  `
33
34
 
@@ -35,7 +36,7 @@ export const StyledUrlImage = styled.img`
35
36
  width: 20px;
36
37
  `
37
38
 
38
- export const Button = props => {
39
+ export const Button = (props: ButtonProps) => {
39
40
  const {
40
41
  webchatState,
41
42
  openWebview,
@@ -50,15 +51,19 @@ export const Button = props => {
50
51
  webchatState.theme,
51
52
  props
52
53
  )
54
+
53
55
  const handleClick = event => {
54
56
  event.preventDefault()
57
+
55
58
  const type = getThemeProperty(
56
59
  WEBCHAT.CUSTOM_PROPERTIES.buttonMessageType,
57
60
  INPUT.TEXT
58
61
  )
59
- if (props.webview) openWebview(props.webview, props.params)
60
- else if (props.path) {
61
- type == INPUT.POSTBACK
62
+
63
+ if (props.webview) {
64
+ openWebview(props.webview, props.params)
65
+ } else if (props.path) {
66
+ type === INPUT.POSTBACK
62
67
  ? sendPayload(`__PATH_PAYLOAD__${props.path}`)
63
68
  : sendInput({
64
69
  type: INPUT.TEXT,
@@ -67,7 +72,7 @@ export const Button = props => {
67
72
  payload: `__PATH_PAYLOAD__${props.path}`,
68
73
  })
69
74
  } else if (props.payload) {
70
- type == INPUT.POSTBACK
75
+ type === INPUT.POSTBACK
71
76
  ? sendPayload(props.payload)
72
77
  : sendInput({
73
78
  type: INPUT.TEXT,
@@ -78,11 +83,15 @@ export const Button = props => {
78
83
  } else if (props.url) {
79
84
  window.open(props.url, props.target || '_blank')
80
85
  }
81
- if (props.onClick) props.onClick()
86
+
87
+ if (props.onClick) {
88
+ props.onClick()
89
+ }
90
+
82
91
  if (props.setDisabled) {
83
92
  props.setDisabled(true)
84
93
  const messageToUpdate = webchatState.messagesJSON.filter(
85
- m => m.id == props.parentId
94
+ m => m.id === props.parentId
86
95
  )[0]
87
96
  const updatedMsg = ButtonsDisabler.getUpdatedMessage(messageToUpdate, {
88
97
  autoDisable,
@@ -116,6 +125,7 @@ export const Button = props => {
116
125
  const CustomButton = getThemeProperty(
117
126
  WEBCHAT.CUSTOM_PROPERTIES.customButton
118
127
  )
128
+
119
129
  if (CustomButton) {
120
130
  return (
121
131
  <div className={getClassName(true)} onClick={e => handleClick(e)}>
@@ -133,6 +143,7 @@ export const Button = props => {
133
143
  WEBCHAT.CUSTOM_PROPERTIES.buttonStyleBackground,
134
144
  COLORS.SOLID_WHITE
135
145
  )
146
+
136
147
  const buttonTextColor = hover
137
148
  ? getThemeProperty(
138
149
  WEBCHAT.CUSTOM_PROPERTIES.buttonHoverTextColor,
@@ -169,7 +180,6 @@ export const Button = props => {
169
180
  backgroundColor: buttonBgColor,
170
181
  ...(props.disabled && autoDisable && disabledStyle),
171
182
  }}
172
- bottom={props.bottomRadius}
173
183
  >
174
184
  {props.children}
175
185
  {props.url && urlIcon && (
@@ -187,43 +197,62 @@ export const Button = props => {
187
197
  if (props.webview) {
188
198
  return (
189
199
  <button
200
+ // @ts-ignore
201
+ // eslint-disable-next-line react/no-unknown-property
190
202
  url={generateWebviewUrlWithParams(props.webview, props.params)}
191
203
  {...disabledProps}
192
204
  >
193
205
  {props.children}
194
206
  </button>
195
207
  )
196
- } else if (props.path) {
208
+ }
209
+
210
+ if (props.path) {
197
211
  const payload = `__PATH_PAYLOAD__${props.path}`
198
212
  return (
213
+ // @ts-ignore
214
+ // eslint-disable-next-line react/no-unknown-property
199
215
  <button payload={payload} {...disabledProps}>
200
216
  {props.children}
201
217
  </button>
202
218
  )
203
- } else if (props.payload) {
219
+ }
220
+
221
+ if (props.payload) {
204
222
  return (
223
+ // @ts-ignore
224
+ // eslint-disable-next-line react/no-unknown-property
205
225
  <button payload={props.payload} {...disabledProps}>
206
226
  {props.children}
207
227
  </button>
208
228
  )
209
- } else if (props.url) {
229
+ }
230
+
231
+ if (props.url) {
210
232
  return (
233
+ // @ts-ignore
234
+ // eslint-disable-next-line react/no-unknown-property
211
235
  <button url={props.url} target={props.target} {...disabledProps}>
212
236
  {props.children}
213
237
  </button>
214
238
  )
215
- } else if (props.onClick) {
239
+ }
240
+
241
+ if (props.onClick) {
216
242
  return null
217
243
  }
218
- throw new Error('Button missing payload, path, webviews, url or onClick')
244
+
245
+ throw new Error('Button missing payload, path, webview, url or onClick')
219
246
  }
220
247
 
221
248
  return renderComponent({ renderBrowser, renderNode })
222
249
  }
223
250
 
224
- Button.serialize = buttonProps => {
225
- let payload = buttonProps.payload
226
- if (buttonProps.path) payload = `__PATH_PAYLOAD__${buttonProps.path}`
251
+ Button.serialize = (buttonProps: ButtonProps) => {
252
+ const payload = buttonProps.path
253
+ ? `__PATH_PAYLOAD__${buttonProps.path}`
254
+ : buttonProps.payload
255
+
227
256
  return {
228
257
  button: {
229
258
  payload,
@@ -49,6 +49,9 @@ export interface ButtonProps {
49
49
  autodisable?: boolean
50
50
  disabled?: boolean
51
51
  disabledstyle?: boolean
52
+ children: string
53
+ setDisabled?: (disabled: boolean) => void
54
+ parentId?: string
52
55
  }
53
56
 
54
57
  export interface ReplyProps {
@@ -101,6 +104,7 @@ export interface BlobProps {
101
104
  }
102
105
 
103
106
  export interface ThemeProps extends StyleProp {
107
+ coverComponent?: CoverComponentOptions
104
108
  mobileBreakpoint?: number
105
109
  mobileStyle?: any
106
110
  webview?: StyleProp & { header?: StyleProp }
package/src/contexts.tsx CHANGED
@@ -72,6 +72,9 @@ export const WebchatContext = createContext<WebchatContextProps>({
72
72
  return
73
73
  },
74
74
  theme: {},
75
+ toggleCoverComponent: () => {
76
+ return
77
+ },
75
78
  toggleWebchat: () => {
76
79
  return
77
80
  },
@@ -148,15 +148,18 @@ export interface Event {
148
148
  message?: MessageInfo
149
149
  }
150
150
 
151
+ // ClientInput: type for sendInput and updateLatestInput function without message_id and bot_interaction_id because backend set this values
152
+ export type ClientInput = Omit<CoreInput, 'message_id' | 'bot_interaction_id'>
153
+
151
154
  export interface WebchatContextProps {
152
155
  addMessage: (message: WebchatMessage) => void
153
156
  closeWebview: () => Promise<void>
154
157
  getThemeProperty: (property: string, defaultValue?: any) => any
155
- openWebview: (webviewComponent: Webview) => void
158
+ openWebview: (webviewComponent: Webview, params?: any) => void
156
159
  resetUnreadMessages: () => void
157
160
  resolveCase: () => void
158
161
  sendAttachment: (attachment: File) => Promise<void>
159
- sendInput: (input: CoreInput) => Promise<void>
162
+ sendInput: (input: ClientInput) => Promise<void>
160
163
  sendPayload: (payload: string) => Promise<void>
161
164
  sendText: (text: string, payload?: string) => Promise<void>
162
165
  setLastMessageVisible: (isLastMessageVisible: boolean) => void
@@ -164,7 +167,8 @@ export interface WebchatContextProps {
164
167
  toggleWebchat: (toggle: boolean) => void
165
168
  toggleEmojiPicker: (toggle: boolean) => void
166
169
  togglePersistentMenu: (toggle: boolean) => void
167
- updateLatestInput: (input: CoreInput) => void
170
+ toggleCoverComponent: (toggle: boolean) => void
171
+ updateLatestInput: (input: ClientInput) => void
168
172
  updateMessage: (message: WebchatMessage) => void
169
173
  updateReplies: (replies: boolean) => void
170
174
  updateUser: (user: Partial<CoreSessionUser>) => void
@@ -0,0 +1,31 @@
1
+ import React, { useContext } from 'react'
2
+
3
+ import { WEBCHAT } from '../../constants'
4
+ import { WebchatContext } from '../../contexts'
5
+
6
+ interface Props {
7
+ component: any
8
+ componentProps: any
9
+ }
10
+
11
+ export const CoverComponent = ({ component, componentProps }: Props) => {
12
+ const { getThemeProperty, toggleCoverComponent, webchatState } =
13
+ useContext(WebchatContext)
14
+
15
+ const Cover = component
16
+
17
+ const coverComponentProps = getThemeProperty(
18
+ WEBCHAT.CUSTOM_PROPERTIES.coverComponentProps,
19
+ componentProps
20
+ )
21
+
22
+ const closeCoverComponent = () => {
23
+ toggleCoverComponent(false)
24
+ }
25
+
26
+ if (!Cover || !webchatState.isCoverComponentOpen) {
27
+ return null
28
+ }
29
+
30
+ return <Cover closeComponent={closeCoverComponent} {...coverComponentProps} />
31
+ }
@@ -3,7 +3,7 @@ import { useReducer, useRef } from 'react'
3
3
 
4
4
  import { ThemeProps, Webview } from '../../components/index-types'
5
5
  import { COLORS, WEBCHAT } from '../../constants'
6
- import { WebchatMessage } from '../../index-types'
6
+ import { ClientInput, WebchatMessage } from '../../index-types'
7
7
  import { WebchatAction } from '../actions'
8
8
  import { DevSettings, ErrorMessage, WebchatState } from '../index-types'
9
9
  import { webchatReducer } from '../webchat-reducer'
@@ -74,7 +74,7 @@ export function useWebchat() {
74
74
  const updateReplies = replies =>
75
75
  webchatDispatch({ type: WebchatAction.UPDATE_REPLIES, payload: replies })
76
76
 
77
- const updateLatestInput = (input: Input) =>
77
+ const updateLatestInput = (input: ClientInput) =>
78
78
  webchatDispatch({ type: WebchatAction.UPDATE_LATEST_INPUT, payload: input })
79
79
 
80
80
  const updateTyping = (typing: boolean) =>
@@ -44,6 +44,7 @@ import {
44
44
  import { ChatArea } from './chat-area'
45
45
  import { OpenedPersistentMenu } from './components/opened-persistent-menu'
46
46
  import { BotonicContainerId } from './constants'
47
+ import { CoverComponent } from './cover-component'
47
48
  import { WebchatHeader } from './header'
48
49
  import {
49
50
  useComponentWillMount,
@@ -407,37 +408,18 @@ export const Webchat = forwardRef((props, ref) => {
407
408
  (props.coverComponent.component || props.coverComponent)
408
409
  )
409
410
  }
410
- const CoverComponent = getCoverComponent()
411
-
412
- const closeCoverComponent = () => {
413
- toggleCoverComponent(false)
414
- }
411
+ const coverComponent = getCoverComponent()
412
+ const coverComponentProps = props.coverComponent?.props
415
413
 
416
414
  useEffect(() => {
417
- if (!CoverComponent) return
415
+ if (!coverComponent) return
418
416
  if (
419
417
  !botonicState ||
420
- (botonicState.messages && botonicState.messages.length == 0)
418
+ (botonicState.messages && botonicState.messages.length === 0)
421
419
  )
422
420
  toggleCoverComponent(true)
423
421
  }, [])
424
422
 
425
- const coverComponent = () => {
426
- const coverComponentProps = getThemeProperty(
427
- WEBCHAT.CUSTOM_PROPERTIES.coverComponentProps,
428
- props.coverComponent && props.coverComponent.props
429
- )
430
-
431
- if (CoverComponent && webchatState.isCoverComponentOpen)
432
- return (
433
- <CoverComponent
434
- closeComponent={closeCoverComponent}
435
- {...coverComponentProps}
436
- />
437
- )
438
- return null
439
- }
440
-
441
423
  const messageComponentFromInput = input => {
442
424
  let messageComponent = null
443
425
  if (isText(input)) {
@@ -708,6 +690,7 @@ export const Webchat = forwardRef((props, ref) => {
708
690
  toggleWebchat,
709
691
  toggleEmojiPicker,
710
692
  togglePersistentMenu,
693
+ toggleCoverComponent,
711
694
  updateLatestInput,
712
695
  updateMessage,
713
696
  updateReplies,
@@ -744,36 +727,50 @@ export const Webchat = forwardRef((props, ref) => {
744
727
  toggleWebchat(false)
745
728
  }}
746
729
  />
747
- {webchatState.error.message && (
748
- <ErrorMessageContainer>
749
- <ErrorMessage>{webchatState.error.message}</ErrorMessage>
750
- </ErrorMessageContainer>
751
- )}
752
- <ChatArea />
753
730
 
754
- {webchatState.isPersistentMenuOpen && (
755
- <DarkenBackground component={persistentMenu()} />
756
- )}
757
- {!webchatState.handoff && userInputEnabled && (
758
- <InputPanel
759
- persistentMenu={props.persistentMenu}
760
- enableEmojiPicker={props.enableEmojiPicker}
761
- enableAttachments={props.enableAttachments}
762
- handleAttachment={handleAttachment}
763
- textareaRef={textareaRef}
764
- host={host}
765
- onUserInput={props.onUserInput}
731
+ {webchatState.isCoverComponentOpen ? (
732
+ <CoverComponent
733
+ component={coverComponent}
734
+ componentProps={coverComponentProps}
766
735
  />
736
+ ) : (
737
+ <>
738
+ {webchatState.error.message && (
739
+ <ErrorMessageContainer>
740
+ <ErrorMessage>{webchatState.error.message}</ErrorMessage>
741
+ </ErrorMessageContainer>
742
+ )}
743
+
744
+ <ChatArea />
745
+
746
+ {webchatState.isPersistentMenuOpen && (
747
+ <DarkenBackground component={persistentMenu()} />
748
+ )}
749
+
750
+ {!webchatState.handoff && userInputEnabled && (
751
+ <InputPanel
752
+ persistentMenu={props.persistentMenu}
753
+ enableEmojiPicker={props.enableEmojiPicker}
754
+ enableAttachments={props.enableAttachments}
755
+ handleAttachment={handleAttachment}
756
+ textareaRef={textareaRef}
757
+ host={host}
758
+ onUserInput={props.onUserInput}
759
+ />
760
+ )}
761
+
762
+ {webchatState.webview && webchatWebview()}
763
+
764
+ {webchatState.isCustomComponentRendered &&
765
+ customComponent &&
766
+ _renderCustomComponent()}
767
+ </>
767
768
  )}
768
- {webchatState.webview && webchatWebview()}
769
- {webchatState.isCoverComponentOpen && coverComponent()}
770
- {webchatState.isCustomComponentRendered &&
771
- customComponent &&
772
- _renderCustomComponent()}
773
769
  </StyledWebchat>
774
770
  )}
775
771
  </WebchatContext.Provider>
776
772
  )
773
+
777
774
  return props.shadowDOM ? (
778
775
  <StyleSheetManager target={host}>{WebchatComponent}</StyleSheetManager>
779
776
  ) : (