⚡ (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:
@ -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()}>
|
||||
|
@ -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' +
|
||||
|
@ -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':
|
||||
|
@ -8,6 +8,7 @@ export type BubbleTheme = {
|
||||
chatWindow?: ChatWindowTheme
|
||||
button?: ButtonTheme
|
||||
previewMessage?: PreviewMessageTheme
|
||||
placement?: 'left' | 'right'
|
||||
}
|
||||
|
||||
export type ChatWindowTheme = {
|
||||
|
Reference in New Issue
Block a user