2
0

🦴 Add theme page backbone

This commit is contained in:
Baptiste Arnaud
2021-12-23 09:37:42 +01:00
parent 6ee0647384
commit 30ddb143b4
35 changed files with 784 additions and 87 deletions

View File

@ -4,10 +4,9 @@
:root {
--typebot-container-bg-image: none;
--typebot-container-bg-color: #f7f8ff;
--typebot-container-font-family: 'Inter';
--typebot-container-bg-color: transparent;
--typebot-container-font-family: 'Open Sans';
--typebot-chat-view-max-width: 700px;
--typebot-chat-view-bg-color: #ffffff;
--typebot-chat-view-color: #303235;
--typebot-button-active-bg-color: #0042da;
@ -318,7 +317,6 @@ textarea {
.typebot-chat-view {
max-width: var(--typebot-chat-view-max-width);
background-color: var(--typebot-chat-view-bg-color);
}
.typebot-button.active {

View File

@ -3,6 +3,8 @@ import { PublicTypebot } from '..'
import { Block } from '..'
import { ChatBlock } from './ChatBlock/ChatBlock'
import { useFrame } from 'react-frame-component'
import { setCssVariablesValue } from '../services/theme'
export const ConversationContainer = ({
typebot,
@ -11,6 +13,7 @@ export const ConversationContainer = ({
typebot: PublicTypebot
onNewBlockVisisble: (blockId: string) => void
}) => {
const { document: frameDocument } = useFrame()
const [displayedBlocks, setDisplayedBlocks] = useState<Block[]>([])
const [isConversationEnded, setIsConversationEnded] = useState(false)
@ -28,6 +31,10 @@ export const ConversationContainer = ({
if (firstBlockId) displayNextBlock(firstBlockId)
}, [])
useEffect(() => {
setCssVariablesValue(typebot.theme, frameDocument.body.style)
}, [typebot.theme, frameDocument])
return (
<div
className="overflow-y-scroll w-full lg:w-3/4 min-h-full rounded lg:px-5 px-3 pt-10 relative scrollable-container typebot-chat-view"

View File

@ -1,5 +1,5 @@
import React from 'react'
import { PublicTypebot } from '../models'
import React, { useMemo } from 'react'
import { BackgroundType, PublicTypebot } from '../models'
import { TypebotContext } from '../contexts/TypebotContext'
import Frame from 'react-frame-component'
//@ts-ignore
@ -9,25 +9,47 @@ import { ResultContext } from '../contexts/ResultsContext'
export type TypebotViewerProps = {
typebot: PublicTypebot
onNewBlockVisisble: (blockId: string) => void
onNewBlockVisisble?: (blockId: string) => void
}
export const TypebotViewer = ({
typebot,
onNewBlockVisisble,
}: TypebotViewerProps) => {
const containerBgColor = useMemo(
() =>
typebot.theme.general.background.type === BackgroundType.COLOR
? typebot.theme.general.background.content
: 'transparent',
[typebot.theme.general.background]
)
const handleNewBlockVisible = (blockId: string) => {
if (onNewBlockVisisble) onNewBlockVisisble(blockId)
}
return (
<Frame
id="typebot-iframe"
head={<style>{style}</style>}
style={{ width: '100%' }}
>
<style
dangerouslySetInnerHTML={{
__html: `@import url('https://fonts.googleapis.com/css2?family=${typebot.theme.general.font}:wght@300;400;600&display=swap');`,
}}
/>
<TypebotContext typebot={typebot}>
<ResultContext typebotId={typebot.id}>
<div className="flex text-base overflow-hidden bg-cover h-screen w-screen typebot-container flex-col items-center">
<div
className="flex text-base overflow-hidden bg-cover h-screen w-screen flex-col items-center typebot-container"
style={{
// We set this as inline style to avoid color flashing (due to SSR)
backgroundColor: containerBgColor,
}}
>
<div className="flex w-full h-full justify-center">
<ConversationContainer
typebot={typebot}
onNewBlockVisisble={onNewBlockVisisble}
onNewBlockVisisble={handleNewBlockVisible}
/>
</div>
</div>

View File

@ -1,10 +1,11 @@
import { PublicTypebot as PublicTypebotFromPrisma } from 'db'
import { Block, StartBlock } from '.'
import { Block, StartBlock, Theme } from '.'
export type PublicTypebot = Omit<
PublicTypebotFromPrisma,
'blocks' | 'startBlock'
'blocks' | 'startBlock' | 'theme'
> & {
blocks: Block[]
startBlock: StartBlock
theme: Theme
}

View File

@ -1,8 +1,12 @@
import { Typebot as TypebotFromPrisma } from 'db'
export type Typebot = Omit<TypebotFromPrisma, 'blocks' | 'startBlock'> & {
export type Typebot = Omit<
TypebotFromPrisma,
'blocks' | 'startBlock' | 'theme'
> & {
blocks: Block[]
startBlock: StartBlock
theme: Theme
}
export type StartBlock = {
@ -53,11 +57,20 @@ export type TextInputStep = StepBase & {
type: StepType.TEXT_INPUT
}
export type Button = {
id: string
content: string
target: {
type: 'block' | 'step'
id: string
export type Theme = {
general: {
font: string
background: Background
}
}
export enum BackgroundType {
COLOR = 'Color',
IMAGE = 'Image',
NONE = 'None',
}
export type Background = {
type: BackgroundType
content: string
}

View File

@ -0,0 +1,25 @@
import { BackgroundType, Theme } from '../models'
const cssVariableNames = {
container: {
bg: {
image: '--typebot-container-bg-image',
color: '--typebot-container-bg-color',
},
fontFamily: '--typebot-container-font-family',
},
}
export const setCssVariablesValue = (
theme: Theme,
documentStyle: CSSStyleDeclaration
) => {
const { background, font } = theme.general
documentStyle.setProperty(
background.type === BackgroundType.IMAGE
? cssVariableNames.container.bg.image
: cssVariableNames.container.bg.color,
background.content
)
documentStyle.setProperty(cssVariableNames.container.fontFamily, font)
}