2
0

(js) Add placement option for bubble embed

Allows you to place the bubble embed on the bottom left corner
of your site
This commit is contained in:
Baptiste Arnaud
2023-05-31 10:22:58 +02:00
parent b2ea8fc059
commit 57f3e5c004
9 changed files with 74 additions and 26 deletions

View File

@ -129,6 +129,7 @@ export const Bubble = (props: BubbleProps) => {
<Show when={isPreviewMessageDisplayed()}>
<PreviewMessage
{...previewMessage()}
placement={bubbleProps.theme?.placement}
previewMessageTheme={bubbleProps.theme?.previewMessage}
buttonSize={bubbleProps.theme?.button?.size}
onClick={handlePreviewMessageClick}
@ -137,6 +138,7 @@ export const Bubble = (props: BubbleProps) => {
</Show>
<BubbleButton
{...bubbleProps.theme?.button}
placement={bubbleProps.theme?.placement}
toggleBot={toggleBot}
isBotOpened={isBotOpened()}
/>
@ -146,16 +148,20 @@ export const Bubble = (props: BubbleProps) => {
height: 'calc(100% - 80px)',
transition:
'transform 200ms cubic-bezier(0, 1.2, 1, 1), opacity 150ms ease-out',
'transform-origin': 'bottom right',
'transform-origin':
props.theme?.placement === 'left' ? 'bottom left' : 'bottom right',
transform: isBotOpened() ? 'scale3d(1, 1, 1)' : 'scale3d(0, 0, 1)',
'box-shadow': 'rgb(0 0 0 / 16%) 0px 5px 40px',
'background-color': bubbleProps.theme?.chatWindow?.backgroundColor,
'z-index': 42424242,
}}
class={
'fixed sm:right-5 rounded-lg w-full sm:w-[400px] max-h-[704px]' +
'fixed rounded-lg w-full sm:w-[400px] max-h-[704px]' +
(isBotOpened() ? ' opacity-1' : ' opacity-0 pointer-events-none') +
(props.theme?.button?.size === 'large' ? ' bottom-24' : ' bottom-20')
(props.theme?.button?.size === 'large'
? ' bottom-24'
: ' bottom-20') +
(props.theme?.placement === 'left' ? ' left-5' : ' right-5')
}
>
<Show when={isBotStarted()}>

View File

@ -1,12 +1,13 @@
import { Show } from 'solid-js'
import { isNotDefined, isSvgSrc } from '@typebot.io/lib'
import { ButtonTheme } from '../types'
import { BubbleTheme, ButtonTheme } from '../types'
import { isLight } from '@typebot.io/lib/hexToRgb'
type Props = ButtonTheme & {
isBotOpened: boolean
toggleBot: () => void
}
type Props = Pick<BubbleTheme, 'placement'> &
ButtonTheme & {
isBotOpened: boolean
toggleBot: () => void
}
const defaultButtonColor = '#0042DA'
const defaultDarkIconColor = '#27272A'
@ -20,8 +21,9 @@ export const BubbleButton = (props: Props) => (
part="button"
onClick={() => props.toggleBot()}
class={
'fixed bottom-5 right-5 shadow-md rounded-full hover:scale-110 active:scale-95 transition-transform duration-200 flex justify-center items-center animate-fade-in' +
(props.size === 'large' ? ' w-16 h-16' : ' w-12 h-12')
'fixed bottom-5 shadow-md rounded-full hover:scale-110 active:scale-95 transition-transform duration-200 flex justify-center items-center animate-fade-in' +
(props.size === 'large' ? ' w-16 h-16' : ' w-12 h-12') +
(props.placement === 'left' ? ' left-5' : ' right-5')
}
style={{
'background-color': props.backgroundColor ?? defaultButtonColor,
@ -49,6 +51,7 @@ export const BubbleButton = (props: Props) => (
</Show>
<Show when={props.customIconSrc && isImageSrc(props.customIconSrc)}>
<img
part="button-icon"
src={props.customIconSrc}
class={
'duration-200 transition' +

View File

@ -1,19 +1,18 @@
import { createSignal, Show } from 'solid-js'
import {
BubbleTheme,
ButtonTheme,
PreviewMessageParams,
PreviewMessageTheme,
} from '../types'
export type PreviewMessageProps = Pick<
PreviewMessageParams,
'avatarUrl' | 'message'
> & {
buttonSize: ButtonTheme['size']
previewMessageTheme?: PreviewMessageTheme
onClick: () => void
onCloseClick: () => void
}
export type PreviewMessageProps = Pick<BubbleTheme, 'placement'> &
Pick<PreviewMessageParams, 'avatarUrl' | 'message'> & {
buttonSize: ButtonTheme['size']
previewMessageTheme?: PreviewMessageTheme
onClick: () => void
onCloseClick: () => void
}
const defaultBackgroundColor = '#F7F8FF'
const defaultTextColor = '#303235'
@ -27,8 +26,9 @@ export const PreviewMessage = (props: PreviewMessageProps) => {
part="preview-message"
onClick={() => props.onClick()}
class={
'fixed right-5 max-w-[256px] rounded-md duration-200 flex items-center gap-4 shadow-md animate-fade-in cursor-pointer hover:shadow-lg p-4' +
(props.buttonSize === 'large' ? ' bottom-24' : ' bottom-20')
'fixed max-w-[256px] rounded-md duration-200 flex items-center gap-4 shadow-md animate-fade-in cursor-pointer hover:shadow-lg p-4' +
(props.buttonSize === 'large' ? ' bottom-24' : ' bottom-20') +
(props.placement === 'left' ? ' left-5' : ' right-5')
}
style={{
'background-color':

View File

@ -8,6 +8,7 @@ export type BubbleTheme = {
chatWindow?: ChatWindowTheme
button?: ButtonTheme
previewMessage?: PreviewMessageTheme
placement?: 'left' | 'right'
}
export type ChatWindowTheme = {