2
0
Files
bot/packages/embeds/js/src/utils/setCssVariablesValue.ts
2023-07-06 16:00:41 +02:00

200 lines
5.5 KiB
TypeScript

import {
Background,
ChatTheme,
ContainerColors,
GeneralTheme,
InputColors,
Theme,
} from '@typebot.io/schemas'
import { BackgroundType } from '@typebot.io/schemas/features/typebot/theme/enums'
import { isLight, hexToRgb } from '@typebot.io/lib/hexToRgb'
import { isNotEmpty } from '@typebot.io/lib'
const cssVariableNames = {
general: {
bgImage: '--typebot-container-bg-image',
bgColor: '--typebot-container-bg-color',
fontFamily: '--typebot-container-font-family',
color: '--typebot-container-color',
},
chat: {
hostBubbles: {
bgColor: '--typebot-host-bubble-bg-color',
color: '--typebot-host-bubble-color',
},
guestBubbles: {
bgColor: '--typebot-guest-bubble-bg-color',
color: '--typebot-guest-bubble-color',
},
inputs: {
bgColor: '--typebot-input-bg-color',
color: '--typebot-input-color',
placeholderColor: '--typebot-input-placeholder-color',
},
buttons: {
bgColor: '--typebot-button-bg-color',
bgColorRgb: '--typebot-button-bg-color-rgb',
color: '--typebot-button-color',
},
checkbox: {
bgColor: '--typebot-checkbox-bg-color',
color: '--typebot-checkbox-color',
},
},
} as const
export const setCssVariablesValue = (
theme: Theme | undefined,
container: HTMLDivElement
) => {
if (!theme) return
const documentStyle = container?.style
if (!documentStyle) return
if (theme.general) setGeneralTheme(theme.general, documentStyle)
if (theme.chat) setChatTheme(theme.chat, documentStyle)
}
const setGeneralTheme = (
generalTheme: GeneralTheme,
documentStyle: CSSStyleDeclaration
) => {
const { background, font } = generalTheme
if (background) setTypebotBackground(background, documentStyle)
if (font) documentStyle.setProperty(cssVariableNames.general.fontFamily, font)
}
const setChatTheme = (
chatTheme: ChatTheme,
documentStyle: CSSStyleDeclaration
) => {
const { hostBubbles, guestBubbles, buttons, inputs, roundness } = chatTheme
if (hostBubbles) setHostBubbles(hostBubbles, documentStyle)
if (guestBubbles) setGuestBubbles(guestBubbles, documentStyle)
if (buttons) setButtons(buttons, documentStyle)
if (inputs) setInputs(inputs, documentStyle)
if (roundness) setRoundness(roundness, documentStyle)
}
const setHostBubbles = (
hostBubbles: ContainerColors,
documentStyle: CSSStyleDeclaration
) => {
if (hostBubbles.backgroundColor)
documentStyle.setProperty(
cssVariableNames.chat.hostBubbles.bgColor,
hostBubbles.backgroundColor
)
if (hostBubbles.color)
documentStyle.setProperty(
cssVariableNames.chat.hostBubbles.color,
hostBubbles.color
)
}
const setGuestBubbles = (
guestBubbles: ContainerColors,
documentStyle: CSSStyleDeclaration
) => {
if (guestBubbles.backgroundColor)
documentStyle.setProperty(
cssVariableNames.chat.guestBubbles.bgColor,
guestBubbles.backgroundColor
)
if (guestBubbles.color)
documentStyle.setProperty(
cssVariableNames.chat.guestBubbles.color,
guestBubbles.color
)
}
const setButtons = (
buttons: ContainerColors,
documentStyle: CSSStyleDeclaration
) => {
if (buttons.backgroundColor) {
documentStyle.setProperty(
cssVariableNames.chat.buttons.bgColor,
buttons.backgroundColor
)
documentStyle.setProperty(
cssVariableNames.chat.buttons.bgColorRgb,
hexToRgb(buttons.backgroundColor).join(', ')
)
}
if (buttons.color)
documentStyle.setProperty(
cssVariableNames.chat.buttons.color,
buttons.color
)
}
const setInputs = (inputs: InputColors, documentStyle: CSSStyleDeclaration) => {
if (inputs.backgroundColor)
documentStyle.setProperty(
cssVariableNames.chat.inputs.bgColor,
inputs.backgroundColor
)
if (inputs.color)
documentStyle.setProperty(cssVariableNames.chat.inputs.color, inputs.color)
if (inputs.placeholderColor)
documentStyle.setProperty(
cssVariableNames.chat.inputs.placeholderColor,
inputs.placeholderColor
)
}
const setTypebotBackground = (
background: Background,
documentStyle: CSSStyleDeclaration
) => {
documentStyle.setProperty(cssVariableNames.general.bgImage, null)
documentStyle.setProperty(cssVariableNames.general.bgColor, null)
documentStyle.setProperty(
background?.type === BackgroundType.IMAGE
? cssVariableNames.general.bgImage
: cssVariableNames.general.bgColor,
parseBackgroundValue(background)
)
const backgroundColor =
(BackgroundType.COLOR && isNotEmpty(background.content)
? background.content
: '#ffffff') ?? '#ffffff'
documentStyle.setProperty(
cssVariableNames.chat.checkbox.bgColor,
(BackgroundType.COLOR ? background.content : '#ffffff') ?? '#ffffff'
)
documentStyle.setProperty(
cssVariableNames.general.color,
isLight(backgroundColor) ? '#303235' : '#ffffff'
)
}
const parseBackgroundValue = ({ type, content }: Background) => {
switch (type) {
case BackgroundType.NONE:
return 'transparent'
case BackgroundType.COLOR:
return content ?? '#ffffff'
case BackgroundType.IMAGE:
return `url(${content})`
}
}
const setRoundness = (
roundness: NonNullable<ChatTheme['roundness']>,
documentStyle: CSSStyleDeclaration
) => {
switch (roundness) {
case 'none':
documentStyle.setProperty('--typebot-border-radius', '0')
break
case 'medium':
documentStyle.setProperty('--typebot-border-radius', '6px')
break
case 'large':
documentStyle.setProperty('--typebot-border-radius', '20px')
break
}
}