docs(share): 📝 Add code blocks in embed instructions
This commit is contained in:
@@ -0,0 +1,38 @@
|
|||||||
|
import { FlexProps } from '@chakra-ui/layout'
|
||||||
|
import prettier from 'prettier/standalone'
|
||||||
|
import parserHtml from 'prettier/parser-html'
|
||||||
|
import { BubbleParams } from 'typebot-js'
|
||||||
|
import { parseInitBubbleCode, typebotJsHtml } from '../params'
|
||||||
|
import { useTypebot } from 'contexts/TypebotContext'
|
||||||
|
import { CodeEditor } from 'components/shared/CodeEditor'
|
||||||
|
|
||||||
|
type ChatEmbedCodeProps = {
|
||||||
|
withStarterVariables?: boolean
|
||||||
|
onCopied?: () => void
|
||||||
|
} & Pick<BubbleParams, 'button' | 'proactiveMessage'>
|
||||||
|
|
||||||
|
export const ChatEmbedCode = ({
|
||||||
|
proactiveMessage,
|
||||||
|
button,
|
||||||
|
}: ChatEmbedCodeProps & FlexProps) => {
|
||||||
|
const { typebot } = useTypebot()
|
||||||
|
|
||||||
|
const snippet = prettier.format(
|
||||||
|
createSnippet({
|
||||||
|
publishId: typebot?.publicId ?? '',
|
||||||
|
button,
|
||||||
|
proactiveMessage,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
parser: 'html',
|
||||||
|
plugins: [parserHtml],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return <CodeEditor value={snippet} lang="html" isReadOnly />
|
||||||
|
}
|
||||||
|
|
||||||
|
const createSnippet = (params: BubbleParams): string => {
|
||||||
|
const jsCode = parseInitBubbleCode(params)
|
||||||
|
return `${typebotJsHtml}
|
||||||
|
<script>${jsCode}</script>`
|
||||||
|
}
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
import {
|
||||||
|
StackProps,
|
||||||
|
Stack,
|
||||||
|
Heading,
|
||||||
|
HStack,
|
||||||
|
Input,
|
||||||
|
Flex,
|
||||||
|
FormControl,
|
||||||
|
FormLabel,
|
||||||
|
NumberInput,
|
||||||
|
NumberInputField,
|
||||||
|
NumberInputStepper,
|
||||||
|
NumberIncrementStepper,
|
||||||
|
NumberDecrementStepper,
|
||||||
|
Switch,
|
||||||
|
Text,
|
||||||
|
Tag,
|
||||||
|
} from '@chakra-ui/react'
|
||||||
|
import { ColorPicker } from 'components/theme/GeneralSettings/ColorPicker'
|
||||||
|
import { useTypebot } from 'contexts/TypebotContext'
|
||||||
|
import { useState, useEffect } from 'react'
|
||||||
|
import { BubbleParams } from 'typebot-js'
|
||||||
|
|
||||||
|
type ChatEmbedSettingsProps = {
|
||||||
|
onUpdateSettings: (
|
||||||
|
windowSettings: Pick<BubbleParams, 'button' | 'proactiveMessage'>
|
||||||
|
) => void
|
||||||
|
}
|
||||||
|
export const ChatEmbedSettings = ({
|
||||||
|
onUpdateSettings,
|
||||||
|
...props
|
||||||
|
}: ChatEmbedSettingsProps & StackProps) => {
|
||||||
|
const { typebot } = useTypebot()
|
||||||
|
const [proactiveMessageChecked, setProactiveMessageChecked] = useState(false)
|
||||||
|
const [rememberProMessageChecked] = useState(true)
|
||||||
|
const [customIconInputValue, setCustomIconInputValue] = useState('')
|
||||||
|
|
||||||
|
const [inputValues, setInputValues] = useState({
|
||||||
|
messageDelay: '0',
|
||||||
|
messageContent: 'I have a question for you!',
|
||||||
|
})
|
||||||
|
|
||||||
|
const [bubbleColor, setBubbleColor] = useState(
|
||||||
|
typebot?.theme.chat.buttons.backgroundColor ?? '#0042DA'
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (proactiveMessageChecked) {
|
||||||
|
onUpdateSettings({
|
||||||
|
button: {
|
||||||
|
color: bubbleColor,
|
||||||
|
iconUrl: customIconInputValue,
|
||||||
|
},
|
||||||
|
proactiveMessage: {
|
||||||
|
delay: parseInt(inputValues.messageDelay) * 1000,
|
||||||
|
textContent: inputValues.messageContent,
|
||||||
|
rememberClose: rememberProMessageChecked,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
onUpdateSettings({
|
||||||
|
button: {
|
||||||
|
color: bubbleColor,
|
||||||
|
iconUrl: customIconInputValue,
|
||||||
|
},
|
||||||
|
proactiveMessage: undefined,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [
|
||||||
|
inputValues,
|
||||||
|
bubbleColor,
|
||||||
|
rememberProMessageChecked,
|
||||||
|
customIconInputValue,
|
||||||
|
proactiveMessageChecked,
|
||||||
|
])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack {...props}>
|
||||||
|
<Heading fontSize="md" fontWeight="semibold">
|
||||||
|
Chat bubble settings
|
||||||
|
</Heading>
|
||||||
|
<Flex justify="space-between" align="center" mb="4">
|
||||||
|
<Text>Button color</Text>
|
||||||
|
<ColorPicker
|
||||||
|
initialColor={bubbleColor}
|
||||||
|
onColorChange={setBubbleColor}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
<HStack>
|
||||||
|
<Text flexShrink={0}>
|
||||||
|
Custom button icon <Tag>Optional</Tag>
|
||||||
|
</Text>
|
||||||
|
<Input
|
||||||
|
placeholder={'Paste image link (.png, .svg)'}
|
||||||
|
value={customIconInputValue}
|
||||||
|
onChange={(e) => setCustomIconInputValue(e.target.value)}
|
||||||
|
/>
|
||||||
|
</HStack>
|
||||||
|
<Flex alignItems="center">
|
||||||
|
<FormControl
|
||||||
|
display="flex"
|
||||||
|
alignItems="center"
|
||||||
|
w="full"
|
||||||
|
justifyContent="space-between"
|
||||||
|
pr={1}
|
||||||
|
>
|
||||||
|
<FormLabel htmlFor="fullscreen-option" mb="1">
|
||||||
|
Enable popup message?
|
||||||
|
</FormLabel>
|
||||||
|
<Switch
|
||||||
|
id="fullscreen-option"
|
||||||
|
onChange={() =>
|
||||||
|
setProactiveMessageChecked(!proactiveMessageChecked)
|
||||||
|
}
|
||||||
|
isChecked={proactiveMessageChecked}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</Flex>
|
||||||
|
{proactiveMessageChecked && (
|
||||||
|
<>
|
||||||
|
<Flex justify="space-between" align="center" pl="4" mb="2">
|
||||||
|
<Text>Appearance delay</Text>
|
||||||
|
<NumberInput
|
||||||
|
onChange={(messageDelay) =>
|
||||||
|
setInputValues({
|
||||||
|
...inputValues,
|
||||||
|
messageDelay,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
value={inputValues.messageDelay}
|
||||||
|
min={0}
|
||||||
|
>
|
||||||
|
<NumberInputField />
|
||||||
|
<NumberInputStepper>
|
||||||
|
<NumberIncrementStepper />
|
||||||
|
<NumberDecrementStepper />
|
||||||
|
</NumberInputStepper>
|
||||||
|
</NumberInput>
|
||||||
|
</Flex>
|
||||||
|
<Flex justify="space-between" align="center" pl="4" mb="2">
|
||||||
|
<Text>Message content</Text>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
onChange={(e) =>
|
||||||
|
setInputValues({
|
||||||
|
...inputValues,
|
||||||
|
messageContent: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
value={inputValues.messageContent}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import { FlexProps } from '@chakra-ui/react'
|
||||||
|
import parserHtml from 'prettier/parser-html'
|
||||||
|
import prettier from 'prettier/standalone'
|
||||||
|
import { parseInitContainerCode, typebotJsHtml } from '../params'
|
||||||
|
import { IframeParams } from 'typebot-js'
|
||||||
|
import { useTypebot } from 'contexts/TypebotContext'
|
||||||
|
import { CodeEditor } from 'components/shared/CodeEditor'
|
||||||
|
|
||||||
|
type ContainerEmbedCodeProps = {
|
||||||
|
widthLabel: string
|
||||||
|
heightLabel: string
|
||||||
|
withStarterVariables?: boolean
|
||||||
|
onCopied?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ContainerEmbedCode = ({
|
||||||
|
widthLabel,
|
||||||
|
heightLabel,
|
||||||
|
}: ContainerEmbedCodeProps & FlexProps) => {
|
||||||
|
const { typebot } = useTypebot()
|
||||||
|
|
||||||
|
const snippet = prettier.format(
|
||||||
|
parseSnippet({
|
||||||
|
publishId: typebot?.publicId ?? '',
|
||||||
|
heightLabel,
|
||||||
|
widthLabel,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
parser: 'html',
|
||||||
|
plugins: [parserHtml],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return <CodeEditor value={snippet} lang="html" isReadOnly />
|
||||||
|
}
|
||||||
|
|
||||||
|
type SnippetProps = IframeParams &
|
||||||
|
Pick<ContainerEmbedCodeProps, 'widthLabel' | 'heightLabel'>
|
||||||
|
|
||||||
|
const parseSnippet = ({
|
||||||
|
publishId,
|
||||||
|
customDomain,
|
||||||
|
backgroundColor,
|
||||||
|
hiddenVariables,
|
||||||
|
...embedProps
|
||||||
|
}: SnippetProps): string => {
|
||||||
|
const jsCode = parseInitContainerCode({
|
||||||
|
customDomain,
|
||||||
|
hiddenVariables,
|
||||||
|
backgroundColor,
|
||||||
|
publishId,
|
||||||
|
})
|
||||||
|
return `${typebotJsHtml}
|
||||||
|
<div id="typebot-container" style="width: ${embedProps.widthLabel}; height: ${embedProps.heightLabel};"></div>
|
||||||
|
<script>${jsCode}</script>`
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
import {
|
||||||
|
StackProps,
|
||||||
|
Stack,
|
||||||
|
Flex,
|
||||||
|
Heading,
|
||||||
|
FormControl,
|
||||||
|
FormLabel,
|
||||||
|
Switch,
|
||||||
|
Input,
|
||||||
|
HStack,
|
||||||
|
Text,
|
||||||
|
} from '@chakra-ui/react'
|
||||||
|
import { DropdownList } from 'components/shared/DropdownList'
|
||||||
|
import { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
type StandardEmbedWindowSettingsProps = {
|
||||||
|
onUpdateWindowSettings: (windowSettings: {
|
||||||
|
heightLabel: string
|
||||||
|
widthLabel: string
|
||||||
|
}) => void
|
||||||
|
}
|
||||||
|
export const StandardEmbedWindowSettings = ({
|
||||||
|
onUpdateWindowSettings,
|
||||||
|
...props
|
||||||
|
}: StandardEmbedWindowSettingsProps & StackProps) => {
|
||||||
|
const [fullscreen, setFullscreen] = useState(false)
|
||||||
|
const [inputValues, setInputValues] = useState({
|
||||||
|
widthValue: '100',
|
||||||
|
widthType: '%',
|
||||||
|
heightValue: '600',
|
||||||
|
heightType: 'px',
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
onUpdateWindowSettings({
|
||||||
|
widthLabel: fullscreen
|
||||||
|
? '100%'
|
||||||
|
: inputValues.widthValue + inputValues.widthType,
|
||||||
|
heightLabel: fullscreen
|
||||||
|
? '100vh'
|
||||||
|
: inputValues.heightValue + inputValues.heightType,
|
||||||
|
})
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [inputValues, fullscreen])
|
||||||
|
|
||||||
|
const handleWidthTypeSelect = (widthType: string) =>
|
||||||
|
setInputValues({ ...inputValues, widthType })
|
||||||
|
const handleHeightTypeSelect = (heightType: string) =>
|
||||||
|
setInputValues({ ...inputValues, heightType })
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack {...props}>
|
||||||
|
<Flex alignItems="center" justifyContent="space-between">
|
||||||
|
<Heading fontSize="md" fontWeight="semibold" style={{ flexShrink: 0 }}>
|
||||||
|
Window settings
|
||||||
|
</Heading>
|
||||||
|
<FormControl
|
||||||
|
display="flex"
|
||||||
|
alignItems="center"
|
||||||
|
w="full"
|
||||||
|
justifyContent="flex-end"
|
||||||
|
>
|
||||||
|
<FormLabel htmlFor="fullscreen-option" mb="1">
|
||||||
|
Set to fullscreen?
|
||||||
|
</FormLabel>
|
||||||
|
<Switch
|
||||||
|
id="fullscreen-option"
|
||||||
|
onChange={() => setFullscreen(!fullscreen)}
|
||||||
|
isChecked={fullscreen}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
{!fullscreen && (
|
||||||
|
<>
|
||||||
|
<Flex justify="space-between" align="center" mb="2">
|
||||||
|
<Text>Width</Text>
|
||||||
|
<HStack>
|
||||||
|
<Input
|
||||||
|
onChange={(e) =>
|
||||||
|
setInputValues({
|
||||||
|
...inputValues,
|
||||||
|
widthValue: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
w="70px"
|
||||||
|
value={inputValues.widthValue}
|
||||||
|
/>
|
||||||
|
<DropdownList<string>
|
||||||
|
items={['px', '%']}
|
||||||
|
onItemSelect={handleWidthTypeSelect}
|
||||||
|
currentItem={inputValues.widthType}
|
||||||
|
/>
|
||||||
|
</HStack>
|
||||||
|
</Flex>
|
||||||
|
<Flex justify="space-between" align="center" mb="2">
|
||||||
|
<Text>Height</Text>
|
||||||
|
<HStack>
|
||||||
|
<Input
|
||||||
|
onChange={(e) =>
|
||||||
|
setInputValues({
|
||||||
|
...inputValues,
|
||||||
|
heightValue: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
w="70px"
|
||||||
|
value={inputValues.heightValue}
|
||||||
|
/>
|
||||||
|
<DropdownList<string>
|
||||||
|
items={['px', '%']}
|
||||||
|
onItemSelect={handleHeightTypeSelect}
|
||||||
|
currentItem={inputValues.heightType}
|
||||||
|
/>
|
||||||
|
</HStack>
|
||||||
|
</Flex>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { FlexProps } from '@chakra-ui/react'
|
||||||
|
import { CodeEditor } from 'components/shared/CodeEditor'
|
||||||
|
import { useTypebot } from 'contexts/TypebotContext'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
widthLabel: string
|
||||||
|
heightLabel: string
|
||||||
|
onCopied?: () => void
|
||||||
|
}
|
||||||
|
export const IframeEmbedCode = ({
|
||||||
|
widthLabel,
|
||||||
|
heightLabel,
|
||||||
|
}: Props & FlexProps) => {
|
||||||
|
const { typebot } = useTypebot()
|
||||||
|
const src = `https://${typebot?.publicId}.typebot.io`
|
||||||
|
const code = `<iframe src="${src}" width="${widthLabel}" height="${heightLabel}" />`
|
||||||
|
|
||||||
|
return <CodeEditor value={code} lang="html" isReadOnly />
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { FlexProps } from '@chakra-ui/layout'
|
||||||
|
import { CodeEditor } from 'components/shared/CodeEditor'
|
||||||
|
import { useTypebot } from 'contexts/TypebotContext'
|
||||||
|
import parserHtml from 'prettier/parser-html'
|
||||||
|
import prettier from 'prettier/standalone'
|
||||||
|
import { PopupParams } from 'typebot-js'
|
||||||
|
import { parseInitPopupCode, typebotJsHtml } from '../params'
|
||||||
|
|
||||||
|
type PopupEmbedCodeProps = {
|
||||||
|
delay: number
|
||||||
|
withStarterVariables?: boolean
|
||||||
|
onCopied?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PopupEmbedCode = ({ delay }: PopupEmbedCodeProps & FlexProps) => {
|
||||||
|
const { typebot } = useTypebot()
|
||||||
|
const snippet = prettier.format(
|
||||||
|
createSnippet({
|
||||||
|
publishId: typebot?.publicId ?? '',
|
||||||
|
delay,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
parser: 'html',
|
||||||
|
plugins: [parserHtml],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return <CodeEditor value={snippet} lang="html" isReadOnly />
|
||||||
|
}
|
||||||
|
|
||||||
|
const createSnippet = (params: PopupParams): string => {
|
||||||
|
const jsCode = parseInitPopupCode(params)
|
||||||
|
return `${typebotJsHtml}
|
||||||
|
<script>${jsCode}</script>`
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import {
|
||||||
|
StackProps,
|
||||||
|
Stack,
|
||||||
|
Flex,
|
||||||
|
Heading,
|
||||||
|
NumberInput,
|
||||||
|
NumberInputField,
|
||||||
|
NumberInputStepper,
|
||||||
|
NumberIncrementStepper,
|
||||||
|
NumberDecrementStepper,
|
||||||
|
} from '@chakra-ui/react'
|
||||||
|
import { useState, useEffect } from 'react'
|
||||||
|
import { PopupParams } from 'typebot-js'
|
||||||
|
|
||||||
|
type PopupEmbedSettingsProps = {
|
||||||
|
onUpdateSettings: (windowSettings: Pick<PopupParams, 'delay'>) => void
|
||||||
|
}
|
||||||
|
export const PopupEmbedSettings = ({
|
||||||
|
onUpdateSettings,
|
||||||
|
...props
|
||||||
|
}: PopupEmbedSettingsProps & StackProps) => {
|
||||||
|
const [inputValue, setInputValue] = useState(0)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
onUpdateSettings({
|
||||||
|
delay: inputValue * 1000,
|
||||||
|
})
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [inputValue])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack {...props}>
|
||||||
|
<Flex alignItems="center" justifyContent="space-between">
|
||||||
|
<Heading fontSize="md" fontWeight="semibold">
|
||||||
|
Popup settings
|
||||||
|
</Heading>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex justify="space-between" align="center" mb="2">
|
||||||
|
<p>Appearance delay</p>
|
||||||
|
<NumberInput
|
||||||
|
onChange={(_, val) => setInputValue(val)}
|
||||||
|
value={inputValue}
|
||||||
|
min={0}
|
||||||
|
>
|
||||||
|
<NumberInputField />
|
||||||
|
<NumberInputStepper>
|
||||||
|
<NumberIncrementStepper />
|
||||||
|
<NumberDecrementStepper />
|
||||||
|
</NumberInputStepper>
|
||||||
|
</NumberInput>
|
||||||
|
</Flex>
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
154
apps/builder/components/share/codeSnippets/ReactCode.tsx
Normal file
154
apps/builder/components/share/codeSnippets/ReactCode.tsx
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
import { FlexProps } from '@chakra-ui/react'
|
||||||
|
import React from 'react'
|
||||||
|
import { BubbleParams, IframeParams, PopupParams } from 'typebot-js'
|
||||||
|
import {
|
||||||
|
parseInitBubbleCode,
|
||||||
|
parseInitContainerCode,
|
||||||
|
parseInitPopupCode,
|
||||||
|
} from './params'
|
||||||
|
import parserBabel from 'prettier/parser-babel'
|
||||||
|
import prettier from 'prettier/standalone'
|
||||||
|
import { CodeEditor } from 'components/shared/CodeEditor'
|
||||||
|
import { useTypebot } from 'contexts/TypebotContext'
|
||||||
|
|
||||||
|
type StandardReactDivProps = { widthLabel: string; heightLabel: string }
|
||||||
|
export const StandardReactDiv = ({
|
||||||
|
widthLabel,
|
||||||
|
heightLabel,
|
||||||
|
}: StandardReactDivProps) => {
|
||||||
|
const { typebot } = useTypebot()
|
||||||
|
const snippet = prettier.format(
|
||||||
|
parseContainerSnippet({
|
||||||
|
publishId: typebot?.publicId ?? '',
|
||||||
|
heightLabel,
|
||||||
|
widthLabel,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
parser: 'babel',
|
||||||
|
plugins: [parserBabel],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return <CodeEditor value={snippet} lang="js" isReadOnly />
|
||||||
|
}
|
||||||
|
|
||||||
|
type SnippetProps = IframeParams &
|
||||||
|
Pick<StandardReactDivProps, 'widthLabel' | 'heightLabel'>
|
||||||
|
|
||||||
|
const parseContainerSnippet = ({
|
||||||
|
publishId,
|
||||||
|
customDomain,
|
||||||
|
backgroundColor,
|
||||||
|
hiddenVariables,
|
||||||
|
...embedProps
|
||||||
|
}: SnippetProps): string => {
|
||||||
|
const jsCode = parseInitContainerCode({
|
||||||
|
publishId,
|
||||||
|
customDomain,
|
||||||
|
backgroundColor,
|
||||||
|
hiddenVariables,
|
||||||
|
})
|
||||||
|
return `import {initContainer} from "typebot-js";
|
||||||
|
|
||||||
|
const Component = () => {
|
||||||
|
useEffect(()=> {
|
||||||
|
${jsCode}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return <div id="typebot-container" style={{width: "${embedProps.widthLabel}", height: "${embedProps.heightLabel}"}} />
|
||||||
|
}`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PopupEmbedCodeProps = {
|
||||||
|
delay: number
|
||||||
|
withStarterVariables?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PopupReactCode = ({ delay }: PopupEmbedCodeProps & FlexProps) => {
|
||||||
|
const { typebot } = useTypebot()
|
||||||
|
const snippet = prettier.format(
|
||||||
|
parsePopupSnippet({
|
||||||
|
publishId: typebot?.publicId ?? '',
|
||||||
|
delay,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
parser: 'babel',
|
||||||
|
plugins: [parserBabel],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return <CodeEditor value={snippet} lang="js" isReadOnly />
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsePopupSnippet = ({
|
||||||
|
publishId,
|
||||||
|
customDomain,
|
||||||
|
backgroundColor,
|
||||||
|
hiddenVariables,
|
||||||
|
delay,
|
||||||
|
}: PopupParams): string => {
|
||||||
|
const jsCode = parseInitPopupCode({
|
||||||
|
publishId,
|
||||||
|
customDomain,
|
||||||
|
backgroundColor,
|
||||||
|
hiddenVariables,
|
||||||
|
delay,
|
||||||
|
})
|
||||||
|
return `import {initPopup} from "typebot-js";
|
||||||
|
|
||||||
|
const Component = () => {
|
||||||
|
useEffect(()=> {
|
||||||
|
${jsCode}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
}`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatEmbedCodeProps = {
|
||||||
|
withStarterVariables?: boolean
|
||||||
|
} & Pick<BubbleParams, 'button' | 'proactiveMessage'>
|
||||||
|
|
||||||
|
export const ChatReactCode = ({
|
||||||
|
proactiveMessage,
|
||||||
|
button,
|
||||||
|
}: ChatEmbedCodeProps & FlexProps) => {
|
||||||
|
const { typebot } = useTypebot()
|
||||||
|
const snippet = prettier.format(
|
||||||
|
parseBubbleSnippet({
|
||||||
|
publishId: typebot?.publicId ?? '',
|
||||||
|
button,
|
||||||
|
proactiveMessage,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
parser: 'babel',
|
||||||
|
plugins: [parserBabel],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return <CodeEditor value={snippet} lang="js" isReadOnly />
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseBubbleSnippet = ({
|
||||||
|
publishId,
|
||||||
|
customDomain,
|
||||||
|
backgroundColor,
|
||||||
|
hiddenVariables,
|
||||||
|
proactiveMessage,
|
||||||
|
button,
|
||||||
|
}: BubbleParams): string => {
|
||||||
|
const jsCode = parseInitBubbleCode({
|
||||||
|
publishId,
|
||||||
|
customDomain,
|
||||||
|
backgroundColor,
|
||||||
|
hiddenVariables,
|
||||||
|
proactiveMessage,
|
||||||
|
button,
|
||||||
|
})
|
||||||
|
return `import {initBubble} from "typebot-js";
|
||||||
|
|
||||||
|
const Component = () => {
|
||||||
|
useEffect(()=> {
|
||||||
|
${jsCode}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return <></>
|
||||||
|
}`
|
||||||
|
}
|
||||||
142
apps/builder/components/share/codeSnippets/params.ts
Normal file
142
apps/builder/components/share/codeSnippets/params.ts
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import {
|
||||||
|
BubbleParams,
|
||||||
|
ButtonParams,
|
||||||
|
IframeParams,
|
||||||
|
PopupParams,
|
||||||
|
ProactiveMessageParams,
|
||||||
|
} from 'typebot-js'
|
||||||
|
import parserBabel from 'prettier/parser-babel'
|
||||||
|
import prettier from 'prettier/standalone'
|
||||||
|
|
||||||
|
const parseStringParam = (fieldName: string, fieldValue?: string) =>
|
||||||
|
fieldValue ? `${fieldName}: "${fieldValue}",` : ``
|
||||||
|
|
||||||
|
const parseNonStringParam = (
|
||||||
|
fieldName: string,
|
||||||
|
fieldValue?: number | boolean
|
||||||
|
) => (fieldValue ? `${fieldName}: ${fieldValue},` : ``)
|
||||||
|
|
||||||
|
const parseCustomDomain = (domain?: string): string =>
|
||||||
|
parseStringParam('customDomain', domain)
|
||||||
|
|
||||||
|
const parseHiddenVariables = (
|
||||||
|
variables: { [key: string]: string | undefined } | undefined
|
||||||
|
): string => (variables ? `hiddenVariables: ${JSON.stringify(variables)},` : ``)
|
||||||
|
|
||||||
|
const parseBackgroundColor = (bgColor?: string): string =>
|
||||||
|
parseStringParam('backgroundColor', bgColor)
|
||||||
|
|
||||||
|
const parseDelay = (delay?: number) => parseNonStringParam('delay', delay)
|
||||||
|
|
||||||
|
const parseButton = (button?: ButtonParams): string => {
|
||||||
|
if (!button) return ''
|
||||||
|
const iconUrlString = parseStringParam('iconUrl', button.iconUrl)
|
||||||
|
const buttonColorstring = parseStringParam('color', button.color)
|
||||||
|
return `button: {${iconUrlString}${buttonColorstring}},`
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseProactiveMessage = (
|
||||||
|
proactiveMessage?: ProactiveMessageParams
|
||||||
|
): string => {
|
||||||
|
if (!proactiveMessage) return ``
|
||||||
|
const { avatarUrl, textContent, delay, rememberClose } = proactiveMessage
|
||||||
|
const avatarUrlString = parseStringParam('avatarUrl', avatarUrl)
|
||||||
|
const textContentString = parseStringParam('textContent', textContent)
|
||||||
|
const rememberCloseString = parseNonStringParam(
|
||||||
|
'rememberClose',
|
||||||
|
rememberClose
|
||||||
|
)
|
||||||
|
const delayString = parseNonStringParam('delay', delay)
|
||||||
|
return `proactiveMessage: {${avatarUrlString}${textContentString}${rememberCloseString}${delayString}},`
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseIframeParams = ({
|
||||||
|
customDomain,
|
||||||
|
hiddenVariables,
|
||||||
|
backgroundColor,
|
||||||
|
}: Pick<
|
||||||
|
IframeParams,
|
||||||
|
'customDomain' | 'hiddenVariables' | 'backgroundColor'
|
||||||
|
>) => ({
|
||||||
|
customDomainString: parseCustomDomain(customDomain),
|
||||||
|
hiddenVariablesString: parseHiddenVariables(hiddenVariables),
|
||||||
|
bgColorString: parseBackgroundColor(backgroundColor),
|
||||||
|
})
|
||||||
|
|
||||||
|
const parsePopupParams = ({ delay }: Pick<PopupParams, 'delay'>) => ({
|
||||||
|
delayString: parseDelay(delay),
|
||||||
|
})
|
||||||
|
|
||||||
|
const parseBubbleParams = ({
|
||||||
|
button,
|
||||||
|
proactiveMessage,
|
||||||
|
}: Pick<BubbleParams, 'button' | 'proactiveMessage'>) => ({
|
||||||
|
proactiveMessageString: parseProactiveMessage(proactiveMessage),
|
||||||
|
buttonString: parseButton(button),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const parseInitContainerCode = ({
|
||||||
|
publishId,
|
||||||
|
customDomain,
|
||||||
|
backgroundColor,
|
||||||
|
hiddenVariables,
|
||||||
|
}: IframeParams) => {
|
||||||
|
const { customDomainString, hiddenVariablesString, bgColorString } =
|
||||||
|
parseIframeParams({
|
||||||
|
customDomain,
|
||||||
|
hiddenVariables,
|
||||||
|
backgroundColor,
|
||||||
|
})
|
||||||
|
return prettier.format(
|
||||||
|
`Typebot.initContainer("typebot-container", {
|
||||||
|
publishId: "${publishId}",${bgColorString}${customDomainString}${hiddenVariablesString}
|
||||||
|
});`,
|
||||||
|
{ parser: 'babel', plugins: [parserBabel] }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const parseInitPopupCode = ({
|
||||||
|
publishId,
|
||||||
|
customDomain,
|
||||||
|
hiddenVariables,
|
||||||
|
backgroundColor,
|
||||||
|
delay,
|
||||||
|
}: PopupParams) => {
|
||||||
|
const { customDomainString, hiddenVariablesString, bgColorString } =
|
||||||
|
parseIframeParams({
|
||||||
|
customDomain,
|
||||||
|
hiddenVariables,
|
||||||
|
backgroundColor,
|
||||||
|
})
|
||||||
|
const { delayString } = parsePopupParams({ delay })
|
||||||
|
return prettier.format(
|
||||||
|
`var typebotCommands = Typebot.initPopup({publishId: "${publishId}",${delayString}${bgColorString}${customDomainString}${hiddenVariablesString}});`,
|
||||||
|
{ parser: 'babel', plugins: [parserBabel] }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const parseInitBubbleCode = ({
|
||||||
|
publishId,
|
||||||
|
customDomain,
|
||||||
|
hiddenVariables,
|
||||||
|
backgroundColor,
|
||||||
|
button,
|
||||||
|
proactiveMessage,
|
||||||
|
}: BubbleParams) => {
|
||||||
|
const { customDomainString, hiddenVariablesString, bgColorString } =
|
||||||
|
parseIframeParams({
|
||||||
|
customDomain,
|
||||||
|
hiddenVariables,
|
||||||
|
backgroundColor,
|
||||||
|
})
|
||||||
|
const { buttonString, proactiveMessageString } = parseBubbleParams({
|
||||||
|
button,
|
||||||
|
proactiveMessage,
|
||||||
|
})
|
||||||
|
return prettier.format(
|
||||||
|
`var typebotCommands = Typebot.initBubble({publishId: "${publishId}",${bgColorString}${customDomainString}${hiddenVariablesString}${proactiveMessageString}${buttonString}});`,
|
||||||
|
{ parser: 'babel', plugins: [parserBabel] }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const typebotJsHtml = `<script src="https://unpkg.com/typebot-js@2.0.20"></script>`
|
||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
ReactModal,
|
ReactModal,
|
||||||
NotionModal,
|
NotionModal,
|
||||||
IframeModal,
|
IframeModal,
|
||||||
|
WixModal,
|
||||||
} from './modals'
|
} from './modals'
|
||||||
|
|
||||||
export type ModalProps = {
|
export type ModalProps = {
|
||||||
@@ -82,7 +83,7 @@ export const integrationsList = [
|
|||||||
<EmbedButton
|
<EmbedButton
|
||||||
logo={<WixLogo height={100} width="90px" />}
|
logo={<WixLogo height={100} width="90px" />}
|
||||||
label="Wix"
|
label="Wix"
|
||||||
Modal={WebflowModal}
|
Modal={WixModal}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
@@ -128,7 +129,7 @@ export const integrationsList = [
|
|||||||
),
|
),
|
||||||
(props: Pick<ModalProps, 'publicId' | 'isPublished'>) => (
|
(props: Pick<ModalProps, 'publicId' | 'isPublished'>) => (
|
||||||
<EmbedButton
|
<EmbedButton
|
||||||
logo={<IframeLogo height={100} width={80} />}
|
logo={<IframeLogo height={100} width="70px" />}
|
||||||
label="Iframe"
|
label="Iframe"
|
||||||
Modal={IframeModal}
|
Modal={IframeModal}
|
||||||
{...props}
|
{...props}
|
||||||
@@ -136,7 +137,7 @@ export const integrationsList = [
|
|||||||
),
|
),
|
||||||
(props: Pick<ModalProps, 'publicId' | 'isPublished'>) => (
|
(props: Pick<ModalProps, 'publicId' | 'isPublished'>) => (
|
||||||
<EmbedButton
|
<EmbedButton
|
||||||
logo={<OtherLogo height={100} width={80} />}
|
logo={<OtherLogo height={100} width="70px" />}
|
||||||
label="Other"
|
label="Other"
|
||||||
Modal={JavascriptModal}
|
Modal={JavascriptModal}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -1,14 +1,27 @@
|
|||||||
import { OrderedList, ListItem, Tag } from '@chakra-ui/react'
|
import { OrderedList, ListItem, Tag } from '@chakra-ui/react'
|
||||||
|
import { ChatEmbedCode } from 'components/share/codeSnippets/Chat/EmbedCode'
|
||||||
|
import { ChatEmbedSettings } from 'components/share/codeSnippets/Chat/EmbedSettings'
|
||||||
|
import { StandardEmbedWindowSettings } from 'components/share/codeSnippets/Container/EmbedSettings'
|
||||||
|
import {
|
||||||
|
parseInitContainerCode,
|
||||||
|
typebotJsHtml,
|
||||||
|
} from 'components/share/codeSnippets/params'
|
||||||
|
import { PopupEmbedCode } from 'components/share/codeSnippets/Popup/EmbedCode'
|
||||||
|
import { PopupEmbedSettings } from 'components/share/codeSnippets/Popup/EmbedSettings'
|
||||||
|
import { CodeEditor } from 'components/shared/CodeEditor'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
import { BubbleParams } from 'typebot-js'
|
||||||
|
import { ModalProps } from '../../EmbedButton'
|
||||||
|
|
||||||
type GtmInstructionsProps = {
|
type GtmInstructionsProps = {
|
||||||
type: 'standard' | 'popup' | 'bubble'
|
type: 'standard' | 'popup' | 'bubble'
|
||||||
|
publicId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GtmInstructions = ({ type }: GtmInstructionsProps) => {
|
export const GtmInstructions = ({ type, publicId }: GtmInstructionsProps) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'standard': {
|
case 'standard': {
|
||||||
return <StandardInstructions />
|
return <StandardInstructions publicId={publicId} />
|
||||||
}
|
}
|
||||||
case 'popup': {
|
case 'popup': {
|
||||||
return <PopupInstructions />
|
return <PopupInstructions />
|
||||||
@@ -19,23 +32,21 @@ export const GtmInstructions = ({ type }: GtmInstructionsProps) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const StandardInstructions = () => {
|
const StandardInstructions = ({ publicId }: Pick<ModalProps, 'publicId'>) => {
|
||||||
// const [windowSizes, setWindowSizes] = useState({
|
const [windowSizes, setWindowSizes] = useState({
|
||||||
// height: '100%',
|
height: '100%',
|
||||||
// width: '100%',
|
width: '100%',
|
||||||
// })
|
})
|
||||||
|
|
||||||
// const jsCode = parseInitContainerCode({
|
const jsCode = parseInitContainerCode({
|
||||||
// publishId: chatbot?.publishId ?? '',
|
publishId: publicId,
|
||||||
// backgroundColor: chatbot?.themeColors.chatbotBackground.value,
|
})
|
||||||
// customDomain: chatbot?.customDomains[0],
|
const headCode = `${typebotJsHtml}
|
||||||
// })
|
<script>
|
||||||
// const headCode = `${typebotJsHtml}
|
${jsCode}
|
||||||
// <script>
|
</script>`
|
||||||
// ${jsCode}
|
|
||||||
// </script>`
|
|
||||||
|
|
||||||
// const elementCode = `<div id="typebot-container" style="background-color: ${backgroundColor}; height: ${windowSizes.height}; width: ${windowSizes.width}"></div>`
|
const elementCode = `<div id="typebot-container" style="height: ${windowSizes.height}; width: ${windowSizes.width}"></div>`
|
||||||
return (
|
return (
|
||||||
<OrderedList spacing={2} mb={4}>
|
<OrderedList spacing={2} mb={4}>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
@@ -46,16 +57,12 @@ const StandardInstructions = () => {
|
|||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
Paste the code below:
|
Paste the code below:
|
||||||
{/* <CodeEditor
|
<CodeEditor value={headCode} mt={2} isReadOnly lang="html" />
|
||||||
code={headCode}
|
|
||||||
mt={2}
|
|
||||||
onCopied={() => sendGtmCopyEvent('standard')}
|
|
||||||
/> */}
|
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
On your webpage, you need to have an element on which the typebot will
|
On your webpage, you need to have an element on which the typebot will
|
||||||
go. It needs to have the id <Tag>typebot-container</Tag>:
|
go. It needs to have the id <Tag>typebot-container</Tag>:
|
||||||
{/* <StandardEmbedWindowSettings
|
<StandardEmbedWindowSettings
|
||||||
my={4}
|
my={4}
|
||||||
onUpdateWindowSettings={(sizes) =>
|
onUpdateWindowSettings={(sizes) =>
|
||||||
setWindowSizes({
|
setWindowSizes({
|
||||||
@@ -64,14 +71,14 @@ const StandardInstructions = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<CodeBlock code={elementCode} mt={2} /> */}
|
<CodeEditor value={elementCode} mt={2} isReadOnly lang="html" />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</OrderedList>
|
</OrderedList>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const PopupInstructions = () => {
|
const PopupInstructions = () => {
|
||||||
// const [inputValue, setInputValue] = useState(0)
|
const [inputValue, setInputValue] = useState(0)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OrderedList spacing={2} mb={4}>
|
<OrderedList spacing={2} mb={4}>
|
||||||
@@ -83,29 +90,26 @@ const PopupInstructions = () => {
|
|||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
Paste the code below:
|
Paste the code below:
|
||||||
{/* <PopupEmbedSettings
|
<PopupEmbedSettings
|
||||||
mb={4}
|
my={4}
|
||||||
onUpdateSettings={(settings) => setInputValue(settings.delay ?? 0)}
|
onUpdateSettings={(settings) => setInputValue(settings.delay ?? 0)}
|
||||||
/>
|
/>
|
||||||
<PopupEmbedCode
|
<PopupEmbedCode delay={inputValue} />
|
||||||
delay={inputValue}
|
|
||||||
onCopied={() => sendGtmCopyEvent('popup')}
|
|
||||||
/> */}
|
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</OrderedList>
|
</OrderedList>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const BubbleInstructions = () => {
|
const BubbleInstructions = () => {
|
||||||
// const [inputValues, setInputValues] = useState<
|
const [inputValues, setInputValues] = useState<
|
||||||
// Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
||||||
// >({
|
>({
|
||||||
// proactiveMessage: undefined,
|
proactiveMessage: undefined,
|
||||||
// button: {
|
button: {
|
||||||
// color: '',
|
color: '',
|
||||||
// iconUrl: '',
|
iconUrl: '',
|
||||||
// },
|
},
|
||||||
// })
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OrderedList spacing={2} mb={4}>
|
<OrderedList spacing={2} mb={4}>
|
||||||
@@ -117,14 +121,10 @@ const BubbleInstructions = () => {
|
|||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
Paste the code below:
|
Paste the code below:
|
||||||
{/* <ChatEmbedSettings
|
<ChatEmbedSettings
|
||||||
onUpdateSettings={(settings) => setInputValues({ ...settings })}
|
onUpdateSettings={(settings) => setInputValues({ ...settings })}
|
||||||
/>
|
/>
|
||||||
<ChatEmbedCode
|
<ChatEmbedCode my={4} {...inputValues} />
|
||||||
mt={4}
|
|
||||||
{...inputValues}
|
|
||||||
onCopied={() => sendGtmCopyEvent('bubble')}
|
|
||||||
/> */}
|
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</OrderedList>
|
</OrderedList>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,12 @@ import { capitalize } from 'utils'
|
|||||||
import { PublishFirstInfo } from 'components/shared/Info'
|
import { PublishFirstInfo } from 'components/shared/Info'
|
||||||
import { GtmInstructions } from './GtmInstructions'
|
import { GtmInstructions } from './GtmInstructions'
|
||||||
|
|
||||||
export const GtmModal = ({ isOpen, onClose, isPublished }: ModalProps) => {
|
export const GtmModal = ({
|
||||||
|
isOpen,
|
||||||
|
onClose,
|
||||||
|
isPublished,
|
||||||
|
publicId,
|
||||||
|
}: ModalProps) => {
|
||||||
const [chosenEmbedType, setChosenEmbedType] = useState<
|
const [chosenEmbedType, setChosenEmbedType] = useState<
|
||||||
'standard' | 'popup' | 'bubble' | undefined
|
'standard' | 'popup' | 'bubble' | undefined
|
||||||
>()
|
>()
|
||||||
@@ -53,7 +58,7 @@ export const GtmModal = ({ isOpen, onClose, isPublished }: ModalProps) => {
|
|||||||
{!chosenEmbedType ? (
|
{!chosenEmbedType ? (
|
||||||
<ChooseEmbedTypeList onSelectEmbedType={setChosenEmbedType} />
|
<ChooseEmbedTypeList onSelectEmbedType={setChosenEmbedType} />
|
||||||
) : (
|
) : (
|
||||||
<GtmInstructions type={chosenEmbedType} />
|
<GtmInstructions type={chosenEmbedType} publicId={publicId} />
|
||||||
)}
|
)}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter />
|
<ModalFooter />
|
||||||
|
|||||||
@@ -9,16 +9,13 @@ import {
|
|||||||
ModalFooter,
|
ModalFooter,
|
||||||
Text,
|
Text,
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
|
import { StandardEmbedWindowSettings } from 'components/share/codeSnippets/Container/EmbedSettings'
|
||||||
|
import { IframeEmbedCode } from 'components/share/codeSnippets/Iframe/EmbedCode'
|
||||||
import { PublishFirstInfo } from 'components/shared/Info'
|
import { PublishFirstInfo } from 'components/shared/Info'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { ModalProps } from '../EmbedButton'
|
import { ModalProps } from '../EmbedButton'
|
||||||
|
|
||||||
export const IframeModal = ({
|
export const IframeModal = ({ isPublished, isOpen, onClose }: ModalProps) => {
|
||||||
isPublished,
|
|
||||||
publicId,
|
|
||||||
isOpen,
|
|
||||||
onClose,
|
|
||||||
}: ModalProps) => {
|
|
||||||
const [inputValues, setInputValues] = useState({
|
const [inputValues, setInputValues] = useState({
|
||||||
heightLabel: '100%',
|
heightLabel: '100%',
|
||||||
widthLabel: '100%',
|
widthLabel: '100%',
|
||||||
@@ -33,6 +30,12 @@ export const IframeModal = ({
|
|||||||
<ModalBody as={Stack} spacing={4}>
|
<ModalBody as={Stack} spacing={4}>
|
||||||
{!isPublished && <PublishFirstInfo />}
|
{!isPublished && <PublishFirstInfo />}
|
||||||
<Text>Paste this anywhere in your HTML code:</Text>
|
<Text>Paste this anywhere in your HTML code:</Text>
|
||||||
|
<StandardEmbedWindowSettings
|
||||||
|
onUpdateWindowSettings={(settings) =>
|
||||||
|
setInputValues({ ...settings })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<IframeEmbedCode {...inputValues} />
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter />
|
<ModalFooter />
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
import { Stack, Tag, Text } from '@chakra-ui/react'
|
import { Stack, Tag, Text } from '@chakra-ui/react'
|
||||||
|
import { ChatEmbedCode } from 'components/share/codeSnippets/Chat/EmbedCode'
|
||||||
|
import { ChatEmbedSettings } from 'components/share/codeSnippets/Chat/EmbedSettings'
|
||||||
|
import { ContainerEmbedCode } from 'components/share/codeSnippets/Container/EmbedCode'
|
||||||
|
import { StandardEmbedWindowSettings } from 'components/share/codeSnippets/Container/EmbedSettings'
|
||||||
|
import { PopupEmbedCode } from 'components/share/codeSnippets/Popup/EmbedCode'
|
||||||
|
import { PopupEmbedSettings } from 'components/share/codeSnippets/Popup/EmbedSettings'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { BubbleParams } from 'typebot-js'
|
||||||
|
|
||||||
type JavascriptInstructionsProps = {
|
type JavascriptInstructionsProps = {
|
||||||
type: 'standard' | 'popup' | 'bubble'
|
type: 'standard' | 'popup' | 'bubble'
|
||||||
@@ -21,75 +29,61 @@ export const JavascriptInstructions = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const StandardInstructions = () => {
|
const StandardInstructions = () => {
|
||||||
// const [inputValues, setInputValues] = useState({
|
const [inputValues, setInputValues] = useState({
|
||||||
// heightLabel: '100%',
|
heightLabel: '100%',
|
||||||
// widthLabel: '100%',
|
widthLabel: '100%',
|
||||||
// })
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack spacing={4}>
|
||||||
<Text>
|
<Text>
|
||||||
Paste this anywhere in the <Tag>body</Tag>
|
Paste this anywhere in the <Tag>body</Tag>
|
||||||
</Text>
|
</Text>
|
||||||
{/* <StandardEmbedWindowSettings
|
<StandardEmbedWindowSettings
|
||||||
onUpdateWindowSettings={(settings) => setInputValues({ ...settings })}
|
onUpdateWindowSettings={(settings) => setInputValues({ ...settings })}
|
||||||
/>
|
/>
|
||||||
<ContainerEmbedCode
|
<ContainerEmbedCode withStarterVariables={true} {...inputValues} mt={4} />
|
||||||
withStarterVariables={true}
|
|
||||||
{...inputValues}
|
|
||||||
mt={4}
|
|
||||||
onCopied={() => sendJsCopyEvent('standard')}
|
|
||||||
/> */}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const PopupInstructions = () => {
|
const PopupInstructions = () => {
|
||||||
// const [inputValue, setInputValue] = useState(0)
|
const [inputValue, setInputValue] = useState(0)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack spacing={4}>
|
||||||
<Text>
|
<Text>
|
||||||
Paste this anywhere in the <Tag>body</Tag>
|
Paste this anywhere in the <Tag>body</Tag>
|
||||||
</Text>
|
</Text>
|
||||||
{/* <StandardEmbedWindowSettings
|
<PopupEmbedSettings
|
||||||
onUpdateWindowSettings={(settings) => setInputValues({ ...settings })}
|
mb={4}
|
||||||
|
onUpdateSettings={(settings) => setInputValue(settings.delay ?? 0)}
|
||||||
/>
|
/>
|
||||||
<ContainerEmbedCode
|
<PopupEmbedCode delay={inputValue} />
|
||||||
withStarterVariables={true}
|
|
||||||
{...inputValues}
|
|
||||||
mt={4}
|
|
||||||
onCopied={() => sendJsCopyEvent('standard')}
|
|
||||||
/> */}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const BubbleInstructions = () => {
|
const BubbleInstructions = () => {
|
||||||
// const [inputValues, setInputValues] = useState<
|
const [inputValues, setInputValues] = useState<
|
||||||
// Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
||||||
// >({
|
>({
|
||||||
// proactiveMessage: undefined,
|
proactiveMessage: undefined,
|
||||||
// button: {
|
button: {
|
||||||
// color: '',
|
color: '',
|
||||||
// iconUrl: '',
|
iconUrl: '',
|
||||||
// },
|
},
|
||||||
// })
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack spacing={4}>
|
||||||
<Text>
|
<Text>
|
||||||
Paste this anywhere in the <Tag>body</Tag>
|
Paste this anywhere in the <Tag>body</Tag>
|
||||||
</Text>
|
</Text>
|
||||||
{/* <StandardEmbedWindowSettings
|
<ChatEmbedSettings
|
||||||
onUpdateWindowSettings={(settings) => setInputValues({ ...settings })}
|
onUpdateSettings={(settings) => setInputValues({ ...settings })}
|
||||||
/>
|
/>
|
||||||
<ContainerEmbedCode
|
<ChatEmbedCode {...inputValues} />
|
||||||
withStarterVariables={true}
|
|
||||||
{...inputValues}
|
|
||||||
mt={4}
|
|
||||||
onCopied={() => sendJsCopyEvent('standard')}
|
|
||||||
/> */}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
import { Stack, Text } from '@chakra-ui/react'
|
import { Stack, Text } from '@chakra-ui/react'
|
||||||
|
import { ChatEmbedSettings } from 'components/share/codeSnippets/Chat/EmbedSettings'
|
||||||
|
import { StandardEmbedWindowSettings } from 'components/share/codeSnippets/Container/EmbedSettings'
|
||||||
|
import { PopupEmbedSettings } from 'components/share/codeSnippets/Popup/EmbedSettings'
|
||||||
|
import {
|
||||||
|
ChatReactCode,
|
||||||
|
PopupReactCode,
|
||||||
|
StandardReactDiv,
|
||||||
|
} from 'components/share/codeSnippets/ReactCode'
|
||||||
import { CodeEditor } from 'components/shared/CodeEditor'
|
import { CodeEditor } from 'components/shared/CodeEditor'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { BubbleParams } from 'typebot-js'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
type: 'standard' | 'popup' | 'bubble'
|
type: 'standard' | 'popup' | 'bubble'
|
||||||
@@ -20,58 +30,57 @@ export const ReactInstructions = ({ type }: Props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const StandardInstructions = () => {
|
const StandardInstructions = () => {
|
||||||
// const [inputValues, setInputValues] = useState({
|
const [inputValues, setInputValues] = useState({
|
||||||
// heightLabel: '100%',
|
heightLabel: '100%',
|
||||||
// widthLabel: '100%',
|
widthLabel: '100%',
|
||||||
// })
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack spacing={4}>
|
<Stack spacing={4}>
|
||||||
{/* <InstallPackageInstruction /> */}
|
<InstallPackageInstruction />
|
||||||
{/* <StandardEmbedWindowSettings
|
<StandardEmbedWindowSettings
|
||||||
onUpdateWindowSettings={(settings) => setInputValues({ ...settings })}
|
onUpdateWindowSettings={(settings) => setInputValues({ ...settings })}
|
||||||
/> */}
|
/>
|
||||||
{/* <Text>{t('insert-the-typebot-container')}</Text>
|
<Text>Insert the typebot container</Text>
|
||||||
<StandardReactDiv {...inputValues} /> */}
|
<StandardReactDiv {...inputValues} />
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const PopupInstructions = () => {
|
const PopupInstructions = () => {
|
||||||
// const [inputValue, setInputValue] = useState(0)
|
const [inputValue, setInputValue] = useState(0)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack spacing={4}>
|
<Stack spacing={4}>
|
||||||
{/* <InstallPackageInstruction />
|
<InstallPackageInstruction />
|
||||||
<PopupEmbedSettings
|
<PopupEmbedSettings
|
||||||
onUpdateSettings={(settings) => setInputValue(settings.delay ?? 0)}
|
onUpdateSettings={(settings) => setInputValue(settings.delay ?? 0)}
|
||||||
/>
|
/>
|
||||||
<Text>{t('initialize-the-typebot')}</Text>
|
<Text>Initialize the typebot</Text>
|
||||||
<PopupReactCode withStarterVariables={true} delay={inputValue} /> */}
|
<PopupReactCode withStarterVariables={true} delay={inputValue} />
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const BubbleInstructions = () => {
|
const BubbleInstructions = () => {
|
||||||
// const { t } = useTranslation()
|
const [inputValues, setInputValues] = useState<
|
||||||
// const [inputValues, setInputValues] = useState<
|
Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
||||||
// Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
>({
|
||||||
// >({
|
proactiveMessage: undefined,
|
||||||
// proactiveMessage: undefined,
|
button: {
|
||||||
// button: {
|
color: '',
|
||||||
// color: '',
|
iconUrl: '',
|
||||||
// iconUrl: '',
|
},
|
||||||
// },
|
})
|
||||||
// })
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack spacing={4}>
|
<Stack spacing={4}>
|
||||||
{/* <InstallPackageInstruction />
|
<InstallPackageInstruction />
|
||||||
<ChatEmbedSettings
|
<ChatEmbedSettings
|
||||||
onUpdateSettings={(settings) => setInputValues({ ...settings })}
|
onUpdateSettings={(settings) => setInputValues({ ...settings })}
|
||||||
/>
|
/>
|
||||||
<Text>{t('initialize-the-typebot')}</Text>
|
<Text>Initialize the typebot</Text>
|
||||||
<ChatReactCode withStarterVariables={true} {...inputValues} mt={4} /> */}
|
<ChatReactCode withStarterVariables={true} {...inputValues} mt={4} />
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,32 @@
|
|||||||
import { OrderedList, ListItem, Tag } from '@chakra-ui/react'
|
import { OrderedList, ListItem, Tag } from '@chakra-ui/react'
|
||||||
|
import { ChatEmbedCode } from 'components/share/codeSnippets/Chat/EmbedCode'
|
||||||
|
import { ChatEmbedSettings } from 'components/share/codeSnippets/Chat/EmbedSettings'
|
||||||
|
import { StandardEmbedWindowSettings } from 'components/share/codeSnippets/Container/EmbedSettings'
|
||||||
|
import {
|
||||||
|
parseInitContainerCode,
|
||||||
|
typebotJsHtml,
|
||||||
|
} from 'components/share/codeSnippets/params'
|
||||||
|
import { PopupEmbedCode } from 'components/share/codeSnippets/Popup/EmbedCode'
|
||||||
|
import { PopupEmbedSettings } from 'components/share/codeSnippets/Popup/EmbedSettings'
|
||||||
|
import { CodeEditor } from 'components/shared/CodeEditor'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { BubbleParams } from 'typebot-js'
|
||||||
|
import { ModalProps } from '../../EmbedButton'
|
||||||
|
import parserHtml from 'prettier/parser-html'
|
||||||
|
import prettier from 'prettier/standalone'
|
||||||
|
|
||||||
type ShopifyInstructionsProps = {
|
type ShopifyInstructionsProps = {
|
||||||
type: 'standard' | 'popup' | 'bubble'
|
type: 'standard' | 'popup' | 'bubble'
|
||||||
|
publicId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ShopifyInstructions = ({ type }: ShopifyInstructionsProps) => {
|
export const ShopifyInstructions = ({
|
||||||
|
type,
|
||||||
|
publicId,
|
||||||
|
}: ShopifyInstructionsProps) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'standard': {
|
case 'standard': {
|
||||||
return <StandardInstructions />
|
return <StandardInstructions publicId={publicId} />
|
||||||
}
|
}
|
||||||
case 'popup': {
|
case 'popup': {
|
||||||
return <PopupInstructions />
|
return <PopupInstructions />
|
||||||
@@ -18,24 +37,30 @@ export const ShopifyInstructions = ({ type }: ShopifyInstructionsProps) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const StandardInstructions = () => {
|
const StandardInstructions = ({ publicId }: Pick<ModalProps, 'publicId'>) => {
|
||||||
// const backgroundColor = chatbot?.themeColors.siteBackground.value
|
const [windowSizes, setWindowSizes] = useState({
|
||||||
// const [windowSizes, setWindowSizes] = useState({
|
height: '100%',
|
||||||
// height: '100%',
|
width: '100%',
|
||||||
// width: '100%',
|
})
|
||||||
// })
|
|
||||||
|
|
||||||
// const jsCode = parseInitContainerCode({
|
const jsCode = parseInitContainerCode({
|
||||||
// publishId: chatbot?.publishId ?? '',
|
publishId: publicId,
|
||||||
// customDomain: chatbot?.customDomains[0],
|
})
|
||||||
// backgroundColor: chatbot?.themeColors.chatbotBackground.value,
|
const headCode = prettier.format(
|
||||||
// })
|
`${typebotJsHtml}<script>${jsCode}</script>`,
|
||||||
// const headCode = `${typebotJsHtml}
|
{
|
||||||
// <script>
|
parser: 'html',
|
||||||
// ${jsCode}
|
plugins: [parserHtml],
|
||||||
// </script>`
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// const elementCode = `<div id="typebot-container" style="background-color: ${backgroundColor}; height: ${windowSizes.height}; width: ${windowSizes.width}"></div>`
|
const elementCode = prettier.format(
|
||||||
|
`<div id="typebot-container" style="height: ${windowSizes.height}; width: ${windowSizes.width}"></div>`,
|
||||||
|
{
|
||||||
|
parser: 'html',
|
||||||
|
plugins: [parserHtml],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OrderedList spacing={2} mb={4}>
|
<OrderedList spacing={2} mb={4}>
|
||||||
@@ -46,17 +71,13 @@ const StandardInstructions = () => {
|
|||||||
<ListItem>
|
<ListItem>
|
||||||
In <Tag>Layout {'>'} theme.liquid</Tag> file, paste this code just
|
In <Tag>Layout {'>'} theme.liquid</Tag> file, paste this code just
|
||||||
before the closing <Tag>head</Tag> tag:
|
before the closing <Tag>head</Tag> tag:
|
||||||
{/* <CodeBlock
|
<CodeEditor value={headCode} mt={2} lang="html" isReadOnly />
|
||||||
code={headCode}
|
|
||||||
mt={2}
|
|
||||||
onCopied={() => sendShopifyCopyEvent('standard')}
|
|
||||||
/> */}
|
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
Then, you can place an element on which the typebot will go in any file
|
Then, you can place an element on which the typebot will go in any file
|
||||||
in the <Tag>body</Tag> tags. It needs to have the id{' '}
|
in the <Tag>body</Tag> tags. It needs to have the id{' '}
|
||||||
<Tag>typebot-container</Tag>:
|
<Tag>typebot-container</Tag>:
|
||||||
{/* <StandardEmbedWindowSettings
|
<StandardEmbedWindowSettings
|
||||||
my={4}
|
my={4}
|
||||||
onUpdateWindowSettings={(sizes) =>
|
onUpdateWindowSettings={(sizes) =>
|
||||||
setWindowSizes({
|
setWindowSizes({
|
||||||
@@ -65,14 +86,14 @@ const StandardInstructions = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<CodeBlock code={elementCode} mt={2} /> */}
|
<CodeEditor value={elementCode} mt={2} lang="html" isReadOnly />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</OrderedList>
|
</OrderedList>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const PopupInstructions = () => {
|
const PopupInstructions = () => {
|
||||||
// const [inputValue, setInputValue] = useState(0)
|
const [inputValue, setInputValue] = useState(0)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OrderedList spacing={2} mb={4}>
|
<OrderedList spacing={2} mb={4}>
|
||||||
@@ -83,29 +104,26 @@ const PopupInstructions = () => {
|
|||||||
<ListItem>
|
<ListItem>
|
||||||
In <Tag>Layout {'>'} theme.liquid</Tag> file, paste this code just
|
In <Tag>Layout {'>'} theme.liquid</Tag> file, paste this code just
|
||||||
before the closing <Tag>head</Tag> tag:
|
before the closing <Tag>head</Tag> tag:
|
||||||
{/* <PopupEmbedSettings
|
<PopupEmbedSettings
|
||||||
mb={4}
|
my="4"
|
||||||
onUpdateSettings={(settings) => setInputValue(settings.delay ?? 0)}
|
onUpdateSettings={(settings) => setInputValue(settings.delay ?? 0)}
|
||||||
/>
|
/>
|
||||||
<PopupEmbedCode
|
<PopupEmbedCode delay={inputValue} />
|
||||||
delay={inputValue}
|
|
||||||
onCopied={() => sendShopifyCopyEvent('popup')}
|
|
||||||
/> */}
|
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</OrderedList>
|
</OrderedList>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const BubbleInstructions = () => {
|
const BubbleInstructions = () => {
|
||||||
// const [inputValues, setInputValues] = useState<
|
const [inputValues, setInputValues] = useState<
|
||||||
// Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
||||||
// >({
|
>({
|
||||||
// proactiveMessage: undefined,
|
proactiveMessage: undefined,
|
||||||
// button: {
|
button: {
|
||||||
// color: '',
|
color: '',
|
||||||
// iconUrl: '',
|
iconUrl: '',
|
||||||
// },
|
},
|
||||||
// })
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OrderedList spacing={2} mb={4}>
|
<OrderedList spacing={2} mb={4}>
|
||||||
@@ -116,14 +134,11 @@ const BubbleInstructions = () => {
|
|||||||
<ListItem>
|
<ListItem>
|
||||||
In <Tag>Layout {'>'} theme.liquid</Tag> file, paste this code just
|
In <Tag>Layout {'>'} theme.liquid</Tag> file, paste this code just
|
||||||
before the closing <Tag>head</Tag> tag:
|
before the closing <Tag>head</Tag> tag:
|
||||||
{/* <ChatEmbedSettings
|
<ChatEmbedSettings
|
||||||
onUpdateSettings={(settings) => setInputValues({ ...settings })}
|
my="4"
|
||||||
/>
|
onUpdateSettings={(settings) => setInputValues({ ...settings })}
|
||||||
<ChatEmbedCode
|
/>
|
||||||
mt={4}
|
<ChatEmbedCode mt={4} {...inputValues} />
|
||||||
{...inputValues}
|
|
||||||
onCopied={() => sendShopifyCopyEvent('bubble')}
|
|
||||||
/> */}
|
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</OrderedList>
|
</OrderedList>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,12 @@ import { capitalize } from 'utils'
|
|||||||
import { PublishFirstInfo } from 'components/shared/Info'
|
import { PublishFirstInfo } from 'components/shared/Info'
|
||||||
import { ShopifyInstructions } from './ShopifyInstructions'
|
import { ShopifyInstructions } from './ShopifyInstructions'
|
||||||
|
|
||||||
export const ShopifyModal = ({ isOpen, onClose, isPublished }: ModalProps) => {
|
export const ShopifyModal = ({
|
||||||
|
isOpen,
|
||||||
|
onClose,
|
||||||
|
isPublished,
|
||||||
|
publicId,
|
||||||
|
}: ModalProps) => {
|
||||||
const [chosenEmbedType, setChosenEmbedType] = useState<
|
const [chosenEmbedType, setChosenEmbedType] = useState<
|
||||||
'standard' | 'popup' | 'bubble' | undefined
|
'standard' | 'popup' | 'bubble' | undefined
|
||||||
>()
|
>()
|
||||||
@@ -53,7 +58,7 @@ export const ShopifyModal = ({ isOpen, onClose, isPublished }: ModalProps) => {
|
|||||||
{!chosenEmbedType ? (
|
{!chosenEmbedType ? (
|
||||||
<ChooseEmbedTypeList onSelectEmbedType={setChosenEmbedType} />
|
<ChooseEmbedTypeList onSelectEmbedType={setChosenEmbedType} />
|
||||||
) : (
|
) : (
|
||||||
<ShopifyInstructions type={chosenEmbedType} />
|
<ShopifyInstructions type={chosenEmbedType} publicId={publicId} />
|
||||||
)}
|
)}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter />
|
<ModalFooter />
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
import { OrderedList, ListItem, Tag, Text, Stack } from '@chakra-ui/react'
|
import { OrderedList, ListItem, Tag, Text, Stack } from '@chakra-ui/react'
|
||||||
|
import { ChatEmbedCode } from 'components/share/codeSnippets/Chat/EmbedCode'
|
||||||
|
import { ChatEmbedSettings } from 'components/share/codeSnippets/Chat/EmbedSettings'
|
||||||
|
import { ContainerEmbedCode } from 'components/share/codeSnippets/Container/EmbedCode'
|
||||||
|
import { PopupEmbedCode } from 'components/share/codeSnippets/Popup/EmbedCode'
|
||||||
|
import { PopupEmbedSettings } from 'components/share/codeSnippets/Popup/EmbedSettings'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { BubbleParams } from 'typebot-js'
|
||||||
|
|
||||||
type WebflowInstructionsProps = {
|
type WebflowInstructionsProps = {
|
||||||
type: 'standard' | 'popup' | 'bubble'
|
type: 'standard' | 'popup' | 'bubble'
|
||||||
@@ -21,8 +28,22 @@ export const WebflowInstructions = ({ type }: WebflowInstructionsProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const StandardInstructions = () => (
|
const StandardInstructions = () => (
|
||||||
<Stack>
|
<OrderedList spacing={2} mb={4}>
|
||||||
<Text>In the Webflow editor:</Text>
|
<ListItem>
|
||||||
|
Press <Tag>A</Tag> to open the <Tag>Add elements</Tag> panel
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
Add an <Tag>embed</Tag> element from the <Tag>components</Tag>
|
||||||
|
section and paste this code:
|
||||||
|
<ContainerEmbedCode widthLabel="100%" heightLabel="100%" my={4} />
|
||||||
|
</ListItem>
|
||||||
|
</OrderedList>
|
||||||
|
)
|
||||||
|
|
||||||
|
const PopupInstructions = () => {
|
||||||
|
const [inputValue, setInputValue] = useState(0)
|
||||||
|
|
||||||
|
return (
|
||||||
<OrderedList spacing={2} mb={4}>
|
<OrderedList spacing={2} mb={4}>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
Press <Tag>A</Tag> to open the <Tag>Add elements</Tag> panel
|
Press <Tag>A</Tag> to open the <Tag>Add elements</Tag> panel
|
||||||
@@ -30,78 +51,41 @@ const StandardInstructions = () => (
|
|||||||
<ListItem>
|
<ListItem>
|
||||||
Add an <Tag>embed</Tag> element from the <Tag>components</Tag>
|
Add an <Tag>embed</Tag> element from the <Tag>components</Tag>
|
||||||
section and paste this code:
|
section and paste this code:
|
||||||
{/* <ContainerEmbedCode
|
<PopupEmbedSettings
|
||||||
widthLabel="100%"
|
onUpdateSettings={(settings) => setInputValue(settings.delay ?? 0)}
|
||||||
heightLabel="100%"
|
my={4}
|
||||||
mt={4}
|
/>
|
||||||
onCopied={() => sendWebflowCopyEvent('standard')}
|
<PopupEmbedCode delay={inputValue} mt={4} />
|
||||||
/> */}
|
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</OrderedList>
|
</OrderedList>
|
||||||
</Stack>
|
|
||||||
)
|
|
||||||
|
|
||||||
const PopupInstructions = () => {
|
|
||||||
// const [inputValue, setInputValue] = useState(0)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Stack>
|
|
||||||
<Text>In the Webflow editor</Text>
|
|
||||||
<OrderedList spacing={2} mb={4}>
|
|
||||||
<ListItem>
|
|
||||||
Press <Tag>A</Tag> to open the <Tag>Add elements</Tag> panel
|
|
||||||
</ListItem>
|
|
||||||
<ListItem>
|
|
||||||
Add an <Tag>embed</Tag> element from the <Tag>components</Tag>
|
|
||||||
section and paste this code:
|
|
||||||
{/* <PopupEmbedSettings
|
|
||||||
onUpdateSettings={(settings) => setInputValue(settings.delay ?? 0)}
|
|
||||||
mt={4}
|
|
||||||
/>
|
|
||||||
<PopupEmbedCode
|
|
||||||
delay={inputValue}
|
|
||||||
mt={4}
|
|
||||||
onCopied={() => sendWebflowCopyEvent('popup')}
|
|
||||||
/> */}
|
|
||||||
</ListItem>
|
|
||||||
</OrderedList>
|
|
||||||
</Stack>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const BubbleInstructions = () => {
|
const BubbleInstructions = () => {
|
||||||
// const [inputValues, setInputValues] = useState<
|
const [inputValues, setInputValues] = useState<
|
||||||
// Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
||||||
// >({
|
>({
|
||||||
// proactiveMessage: undefined,
|
proactiveMessage: undefined,
|
||||||
// button: {
|
button: {
|
||||||
// color: '',
|
color: '',
|
||||||
// iconUrl: '',
|
iconUrl: '',
|
||||||
// },
|
},
|
||||||
// })
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<OrderedList spacing={2} mb={4}>
|
||||||
<Text>In the Webflow editor</Text>
|
<ListItem>
|
||||||
<OrderedList spacing={2} mb={4}>
|
Press <Tag>A</Tag> to open the <Tag>Add elements</Tag> panel
|
||||||
<ListItem>
|
</ListItem>
|
||||||
Press <Tag>A</Tag> to open the <Tag>Add elements</Tag> panel
|
<ListItem>
|
||||||
</ListItem>
|
Add an <Tag>embed</Tag> element from the <Tag>components</Tag>
|
||||||
<ListItem>
|
section and paste this code:
|
||||||
Add an <Tag>embed</Tag> element from the <Tag>components</Tag>
|
<ChatEmbedSettings
|
||||||
section and paste this code:
|
onUpdateSettings={(settings) => setInputValues({ ...settings })}
|
||||||
{/* <ChatEmbedSettings
|
my={4}
|
||||||
onUpdateSettings={(settings) => setInputValues({ ...settings })}
|
/>
|
||||||
mt={4}
|
<ChatEmbedCode withStarterVariables={true} {...inputValues} my={4} />
|
||||||
/>
|
</ListItem>
|
||||||
<ChatEmbedCode
|
</OrderedList>
|
||||||
withStarterVariables={true}
|
|
||||||
{...inputValues}
|
|
||||||
mt={4}
|
|
||||||
onCopied={() => sendWebflowCopyEvent('bubble')}
|
|
||||||
/> */}
|
|
||||||
</ListItem>
|
|
||||||
</OrderedList>
|
|
||||||
</Stack>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
import { ListItem, OrderedList, Tag } from '@chakra-ui/react'
|
import { ListItem, OrderedList, Tag } from '@chakra-ui/react'
|
||||||
|
import { ChatEmbedCode } from 'components/share/codeSnippets/Chat/EmbedCode'
|
||||||
|
import { ChatEmbedSettings } from 'components/share/codeSnippets/Chat/EmbedSettings'
|
||||||
|
import { ContainerEmbedCode } from 'components/share/codeSnippets/Container/EmbedCode'
|
||||||
|
import { PopupEmbedCode } from 'components/share/codeSnippets/Popup/EmbedCode'
|
||||||
|
import { PopupEmbedSettings } from 'components/share/codeSnippets/Popup/EmbedSettings'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
import { BubbleParams } from 'typebot-js'
|
||||||
|
|
||||||
type WixInstructionsProps = {
|
type WixInstructionsProps = {
|
||||||
type: 'standard' | 'popup' | 'bubble'
|
type: 'standard' | 'popup' | 'bubble'
|
||||||
@@ -21,24 +27,23 @@ export const WixInstructions = ({ type }: WixInstructionsProps) => {
|
|||||||
|
|
||||||
const StandardInstructions = () => {
|
const StandardInstructions = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<OrderedList spacing={2} mb={4}>
|
||||||
<OrderedList spacing={2} mb={4}>
|
<ListItem>
|
||||||
<ListItem>
|
In the Wix Website Editor:
|
||||||
In the Wix Website Editor:
|
<Tag>
|
||||||
<Tag>
|
Add {'>'} Embed {'>'} Embed a Widget
|
||||||
Add {'>'} Embed {'>'} Embed a Widget
|
</Tag>
|
||||||
</Tag>
|
</ListItem>
|
||||||
</ListItem>
|
<ListItem>
|
||||||
<ListItem>
|
Click on <Tag>Enter code</Tag> and paste this code:
|
||||||
Click on <Tag>Enter code</Tag> and paste this code:
|
</ListItem>
|
||||||
</ListItem>
|
<ContainerEmbedCode widthLabel="100%" heightLabel="100%" />
|
||||||
</OrderedList>
|
</OrderedList>
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const PopupInstructions = () => {
|
const PopupInstructions = () => {
|
||||||
// const [inputValue, setInputValue] = useState(0)
|
const [inputValue, setInputValue] = useState(0)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -52,45 +57,49 @@ const PopupInstructions = () => {
|
|||||||
<ListItem>
|
<ListItem>
|
||||||
Click <Tag>+ Add Custom Code</Tag> at the top right.
|
Click <Tag>+ Add Custom Code</Tag> at the top right.
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>Paste this snippet in the code box:</ListItem>
|
<ListItem>
|
||||||
|
Paste this snippet in the code box:
|
||||||
|
<PopupEmbedSettings
|
||||||
|
onUpdateSettings={(settings) => setInputValue(settings.delay ?? 0)}
|
||||||
|
my={4}
|
||||||
|
/>
|
||||||
|
<PopupEmbedCode delay={inputValue} />
|
||||||
|
</ListItem>
|
||||||
</OrderedList>
|
</OrderedList>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const BubbleInstructions = () => {
|
const BubbleInstructions = () => {
|
||||||
// const [inputValues, setInputValues] = useState<
|
const [inputValues, setInputValues] = useState<
|
||||||
// Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
Pick<BubbleParams, 'proactiveMessage' | 'button'>
|
||||||
// >({
|
>({
|
||||||
// proactiveMessage: undefined,
|
proactiveMessage: undefined,
|
||||||
// button: {
|
button: {
|
||||||
// color: '',
|
color: '',
|
||||||
// iconUrl: '',
|
iconUrl: '',
|
||||||
// },
|
},
|
||||||
// })
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<OrderedList spacing={2} mb={4}>
|
||||||
<OrderedList spacing={2} mb={4}>
|
<ListItem>
|
||||||
<ListItem>
|
Go to <Tag>Settings</Tag> in your dashboard on Wix
|
||||||
Go to <Tag>Settings</Tag> in your dashboard on Wix
|
</ListItem>
|
||||||
</ListItem>
|
<ListItem>
|
||||||
<ListItem>
|
Click on <Tag>Custom Code</Tag> under <Tag>Advanced</Tag>
|
||||||
Click on <Tag>Custom Code</Tag> under <Tag>Advanced</Tag>
|
</ListItem>
|
||||||
</ListItem>
|
<ListItem>
|
||||||
<ListItem>
|
Click <Tag>+ Add Custom Code</Tag> at the top right.
|
||||||
Click <Tag>+ Add Custom Code</Tag> at the top right.
|
</ListItem>
|
||||||
</ListItem>
|
<ListItem>
|
||||||
<ListItem>Paste this snippet in the code box:</ListItem>
|
Paste this snippet in the code box:{' '}
|
||||||
</OrderedList>
|
<ChatEmbedSettings
|
||||||
{/* <ChatEmbedSettings
|
my="4"
|
||||||
onUpdateSettings={(settings) => setInputValues({ ...settings })}
|
onUpdateSettings={(settings) => setInputValues({ ...settings })}
|
||||||
/>
|
/>
|
||||||
<ChatEmbedCode
|
<ChatEmbedCode {...inputValues} />
|
||||||
mt={4}
|
</ListItem>
|
||||||
{...inputValues}
|
</OrderedList>
|
||||||
onCopied={() => sendWixCopyEvent('bubble')}
|
|
||||||
/> */}
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ import { Box, BoxProps } from '@chakra-ui/react'
|
|||||||
import { EditorState, EditorView, basicSetup } from '@codemirror/basic-setup'
|
import { EditorState, EditorView, basicSetup } from '@codemirror/basic-setup'
|
||||||
import { json } from '@codemirror/lang-json'
|
import { json } from '@codemirror/lang-json'
|
||||||
import { css } from '@codemirror/lang-css'
|
import { css } from '@codemirror/lang-css'
|
||||||
|
import { javascript } from '@codemirror/lang-javascript'
|
||||||
|
import { html } from '@codemirror/lang-html'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
value: string
|
value: string
|
||||||
lang?: 'css' | 'json'
|
lang?: 'css' | 'json' | 'js' | 'html'
|
||||||
onChange?: (value: string) => void
|
onChange?: (value: string) => void
|
||||||
isReadOnly?: boolean
|
isReadOnly?: boolean
|
||||||
}
|
}
|
||||||
@@ -24,7 +26,11 @@ export const CodeEditor = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!editorView.current || !isReadOnly) return
|
if (!editorView.current || !isReadOnly) return
|
||||||
editorView.current.dispatch({
|
editorView.current.dispatch({
|
||||||
changes: { from: 0, insert: value },
|
changes: {
|
||||||
|
from: 0,
|
||||||
|
to: editorView.current.state.doc.length,
|
||||||
|
insert: value,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [value])
|
}, [value])
|
||||||
@@ -36,6 +42,14 @@ export const CodeEditor = ({
|
|||||||
}, [plainTextValue])
|
}, [plainTextValue])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const editor = initEditor(value)
|
||||||
|
return () => {
|
||||||
|
editor?.destroy()
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const initEditor = (value: string) => {
|
||||||
if (!editorContainer.current) return
|
if (!editorContainer.current) return
|
||||||
const updateListenerExtension = EditorView.updateListener.of((update) => {
|
const updateListenerExtension = EditorView.updateListener.of((update) => {
|
||||||
if (update.docChanged && onChange)
|
if (update.docChanged && onChange)
|
||||||
@@ -48,6 +62,8 @@ export const CodeEditor = ({
|
|||||||
]
|
]
|
||||||
if (lang === 'json') extensions.push(json())
|
if (lang === 'json') extensions.push(json())
|
||||||
if (lang === 'css') extensions.push(css())
|
if (lang === 'css') extensions.push(css())
|
||||||
|
if (lang === 'js') extensions.push(javascript())
|
||||||
|
if (lang === 'html') extensions.push(html())
|
||||||
const editor = new EditorView({
|
const editor = new EditorView({
|
||||||
state: EditorState.create({
|
state: EditorState.create({
|
||||||
extensions,
|
extensions,
|
||||||
@@ -58,13 +74,8 @@ export const CodeEditor = ({
|
|||||||
changes: { from: 0, insert: value },
|
changes: { from: 0, insert: value },
|
||||||
})
|
})
|
||||||
editorView.current = editor
|
editorView.current = editor
|
||||||
return () => {
|
return editor
|
||||||
editor.destroy()
|
}
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
return <Box ref={editorContainer} data-testid="code-editor" {...props} />
|
||||||
<Box ref={editorContainer} h="200px" data-testid="code-editor" {...props} />
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
"@chakra-ui/react": "^1.8.1",
|
"@chakra-ui/react": "^1.8.1",
|
||||||
"@codemirror/basic-setup": "^0.19.1",
|
"@codemirror/basic-setup": "^0.19.1",
|
||||||
"@codemirror/lang-css": "^0.19.3",
|
"@codemirror/lang-css": "^0.19.3",
|
||||||
|
"@codemirror/lang-html": "^0.19.4",
|
||||||
|
"@codemirror/lang-javascript": "^0.19.7",
|
||||||
"@codemirror/lang-json": "^0.19.1",
|
"@codemirror/lang-json": "^0.19.1",
|
||||||
"@codemirror/text": "^0.19.6",
|
"@codemirror/text": "^0.19.6",
|
||||||
"@emotion/react": "^11.7.1",
|
"@emotion/react": "^11.7.1",
|
||||||
@@ -69,7 +71,8 @@
|
|||||||
"swr": "^1.2.0",
|
"swr": "^1.2.0",
|
||||||
"use-debounce": "^7.0.1",
|
"use-debounce": "^7.0.1",
|
||||||
"use-immer": "^0.6.0",
|
"use-immer": "^0.6.0",
|
||||||
"utils": "*"
|
"utils": "*",
|
||||||
|
"typebot-js": "2.0.21"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.18.1",
|
"@playwright/test": "^1.18.1",
|
||||||
@@ -79,6 +82,7 @@
|
|||||||
"@types/node": "^16.11.9",
|
"@types/node": "^16.11.9",
|
||||||
"@types/nprogress": "^0.2.0",
|
"@types/nprogress": "^0.2.0",
|
||||||
"@types/papaparse": "^5.3.1",
|
"@types/papaparse": "^5.3.1",
|
||||||
|
"@types/prettier": "^2.4.4",
|
||||||
"@types/qs": "^6.9.7",
|
"@types/qs": "^6.9.7",
|
||||||
"@types/react": "^17.0.38",
|
"@types/react": "^17.0.38",
|
||||||
"@types/react-table": "^7.7.9",
|
"@types/react-table": "^7.7.9",
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { ItemBase, ItemType } from '.'
|
import { ItemBase, ItemType } from '.'
|
||||||
import { Item } from './item'
|
|
||||||
import { StepBase } from './steps'
|
import { StepBase } from './steps'
|
||||||
|
|
||||||
export type InputStep =
|
export type InputStep =
|
||||||
|
|||||||
52
yarn.lock
52
yarn.lock
@@ -1110,7 +1110,7 @@
|
|||||||
"@codemirror/state" "^0.19.0"
|
"@codemirror/state" "^0.19.0"
|
||||||
"@codemirror/view" "^0.19.23"
|
"@codemirror/view" "^0.19.23"
|
||||||
|
|
||||||
"@codemirror/highlight@^0.19.0", "@codemirror/highlight@^0.19.6":
|
"@codemirror/highlight@^0.19.0", "@codemirror/highlight@^0.19.6", "@codemirror/highlight@^0.19.7":
|
||||||
version "0.19.7"
|
version "0.19.7"
|
||||||
resolved "https://registry.yarnpkg.com/@codemirror/highlight/-/highlight-0.19.7.tgz#91a0c9994c759f5f153861e3aae74ff9e7c7c35b"
|
resolved "https://registry.yarnpkg.com/@codemirror/highlight/-/highlight-0.19.7.tgz#91a0c9994c759f5f153861e3aae74ff9e7c7c35b"
|
||||||
integrity sha512-3W32hBCY0pbbv/xidismw+RDMKuIag+fo4kZIbD7WoRj+Ttcaxjf+vP6RttRHXLaaqbWh031lTeON8kMlDhMYw==
|
integrity sha512-3W32hBCY0pbbv/xidismw+RDMKuIag+fo4kZIbD7WoRj+Ttcaxjf+vP6RttRHXLaaqbWh031lTeON8kMlDhMYw==
|
||||||
@@ -1130,7 +1130,7 @@
|
|||||||
"@codemirror/state" "^0.19.2"
|
"@codemirror/state" "^0.19.2"
|
||||||
"@codemirror/view" "^0.19.0"
|
"@codemirror/view" "^0.19.0"
|
||||||
|
|
||||||
"@codemirror/lang-css@^0.19.3":
|
"@codemirror/lang-css@^0.19.0", "@codemirror/lang-css@^0.19.3":
|
||||||
version "0.19.3"
|
version "0.19.3"
|
||||||
resolved "https://registry.yarnpkg.com/@codemirror/lang-css/-/lang-css-0.19.3.tgz#7a17adf78c6fcdab4ad5ee4e360631c41e949e4a"
|
resolved "https://registry.yarnpkg.com/@codemirror/lang-css/-/lang-css-0.19.3.tgz#7a17adf78c6fcdab4ad5ee4e360631c41e949e4a"
|
||||||
integrity sha512-tyCUJR42/UlfOPLb94/p7dN+IPsYSIzHbAHP2KQHANj0I+Orqp+IyIOS++M8TuCX4zkWh9dvi8s92yy/Tn8Ifg==
|
integrity sha512-tyCUJR42/UlfOPLb94/p7dN+IPsYSIzHbAHP2KQHANj0I+Orqp+IyIOS++M8TuCX4zkWh9dvi8s92yy/Tn8Ifg==
|
||||||
@@ -1141,6 +1141,33 @@
|
|||||||
"@codemirror/state" "^0.19.0"
|
"@codemirror/state" "^0.19.0"
|
||||||
"@lezer/css" "^0.15.2"
|
"@lezer/css" "^0.15.2"
|
||||||
|
|
||||||
|
"@codemirror/lang-html@^0.19.4":
|
||||||
|
version "0.19.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@codemirror/lang-html/-/lang-html-0.19.4.tgz#e6eec28462f18842a0e108732a214a7416b5e333"
|
||||||
|
integrity sha512-GpiEikNuCBeFnS+/TJSeanwqaOfNm8Kkp9WpVNEPZCLyW1mAMCuFJu/3xlWYeWc778Hc3vJqGn3bn+cLNubgCA==
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/autocomplete" "^0.19.0"
|
||||||
|
"@codemirror/highlight" "^0.19.6"
|
||||||
|
"@codemirror/lang-css" "^0.19.0"
|
||||||
|
"@codemirror/lang-javascript" "^0.19.0"
|
||||||
|
"@codemirror/language" "^0.19.0"
|
||||||
|
"@codemirror/state" "^0.19.0"
|
||||||
|
"@lezer/common" "^0.15.0"
|
||||||
|
"@lezer/html" "^0.15.0"
|
||||||
|
|
||||||
|
"@codemirror/lang-javascript@^0.19.0", "@codemirror/lang-javascript@^0.19.7":
|
||||||
|
version "0.19.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@codemirror/lang-javascript/-/lang-javascript-0.19.7.tgz#84581ef6abf2a16d78f017ffc96c2d6227de5eb5"
|
||||||
|
integrity sha512-DL9f3JLqOEHH9cIwEqqjnP5bkjdVXeECksLtV+/MbPm+l4H+AG+PkwZaJQ2oR1GfPZKh8MVSIE94aGWNkJP8WQ==
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/autocomplete" "^0.19.0"
|
||||||
|
"@codemirror/highlight" "^0.19.7"
|
||||||
|
"@codemirror/language" "^0.19.0"
|
||||||
|
"@codemirror/lint" "^0.19.0"
|
||||||
|
"@codemirror/state" "^0.19.0"
|
||||||
|
"@codemirror/view" "^0.19.0"
|
||||||
|
"@lezer/javascript" "^0.15.1"
|
||||||
|
|
||||||
"@codemirror/lang-json@^0.19.1":
|
"@codemirror/lang-json@^0.19.1":
|
||||||
version "0.19.1"
|
version "0.19.1"
|
||||||
resolved "https://registry.yarnpkg.com/@codemirror/lang-json/-/lang-json-0.19.1.tgz#616588d1422529965243c10af6c44ad0b9134fb0"
|
resolved "https://registry.yarnpkg.com/@codemirror/lang-json/-/lang-json-0.19.1.tgz#616588d1422529965243c10af6c44ad0b9134fb0"
|
||||||
@@ -1633,6 +1660,20 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@lezer/lr" "^0.15.0"
|
"@lezer/lr" "^0.15.0"
|
||||||
|
|
||||||
|
"@lezer/html@^0.15.0":
|
||||||
|
version "0.15.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@lezer/html/-/html-0.15.0.tgz#572c9444bc39c1afc0529a70e089abf7254edf5d"
|
||||||
|
integrity sha512-ErmgP/Vv0AhYJvs/Ekb9oue4IzBHemKLi7K8tJ0jgS+20Y8FGC9foK6knCXtEHqdPaxVGQH9PVp7gecLnzLd9Q==
|
||||||
|
dependencies:
|
||||||
|
"@lezer/lr" "^0.15.0"
|
||||||
|
|
||||||
|
"@lezer/javascript@^0.15.1":
|
||||||
|
version "0.15.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@lezer/javascript/-/javascript-0.15.3.tgz#833a4c5650bae07805b9af88de6706368844dc55"
|
||||||
|
integrity sha512-8jA2NpOfpWwSPZxRhd9BxK2ZPvGd7nLE3LFTJ5AbMhXAzMHeMjneV6GEVd7dAIee85dtap0jdb6bgOSO0+lfwA==
|
||||||
|
dependencies:
|
||||||
|
"@lezer/lr" "^0.15.0"
|
||||||
|
|
||||||
"@lezer/json@^0.15.0":
|
"@lezer/json@^0.15.0":
|
||||||
version "0.15.0"
|
version "0.15.0"
|
||||||
resolved "https://registry.yarnpkg.com/@lezer/json/-/json-0.15.0.tgz#b96c1161eb8514e05f4eaaec95c68376e76e539f"
|
resolved "https://registry.yarnpkg.com/@lezer/json/-/json-0.15.0.tgz#b96c1161eb8514e05f4eaaec95c68376e76e539f"
|
||||||
@@ -2208,6 +2249,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
|
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
|
||||||
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
|
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
|
||||||
|
|
||||||
|
"@types/prettier@^2.4.4":
|
||||||
|
version "2.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17"
|
||||||
|
integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==
|
||||||
|
|
||||||
"@types/prop-types@*":
|
"@types/prop-types@*":
|
||||||
version "15.7.4"
|
version "15.7.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
|
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
|
||||||
@@ -8061,7 +8107,7 @@ type-fest@^0.21.3:
|
|||||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
||||||
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
||||||
|
|
||||||
typebot-js@^2.0.21:
|
typebot-js@2.0.21, typebot-js@^2.0.21:
|
||||||
version "2.0.21"
|
version "2.0.21"
|
||||||
resolved "https://registry.yarnpkg.com/typebot-js/-/typebot-js-2.0.21.tgz#1211ef4ffbf8f69facf538721073ec17660283b9"
|
resolved "https://registry.yarnpkg.com/typebot-js/-/typebot-js-2.0.21.tgz#1211ef4ffbf8f69facf538721073ec17660283b9"
|
||||||
integrity sha512-7a0vODc1MLYe2u9TtaO7u0Sz9V9+3Tk+YeY2cXjDgWEhFWNcUPyBZOJZMB5EDir5/togTMTIYr/TCm6fyGRi2Q==
|
integrity sha512-7a0vODc1MLYe2u9TtaO7u0Sz9V9+3Tk+YeY2cXjDgWEhFWNcUPyBZOJZMB5EDir5/togTMTIYr/TCm6fyGRi2Q==
|
||||||
|
|||||||
Reference in New Issue
Block a user