From 61e4ca13132ca72294620c7df18a2644367a8908 Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Tue, 31 May 2022 09:59:34 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20=F0=9F=93=9D=20Explain=20how=20to=20pas?= =?UTF-8?q?s=20parent=20URL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../share/codeSnippets/Chat/EmbedSettings.tsx | 97 ++++++++++--- .../components/share/codeSnippets/params.ts | 11 +- apps/docs/docs/editor/blocks/set-variable.md | 12 +- apps/docs/docs/embed/html-javascript.md | 127 ++++++++++++++++++ apps/docs/docs/embed/javascript-commands.md | 65 --------- .../typebot-js/src/embedTypes/chat/button.ts | 18 ++- packages/typebot-js/src/types.ts | 1 + 7 files changed, 229 insertions(+), 102 deletions(-) create mode 100644 apps/docs/docs/embed/html-javascript.md delete mode 100644 apps/docs/docs/embed/javascript-commands.md diff --git a/apps/builder/components/share/codeSnippets/Chat/EmbedSettings.tsx b/apps/builder/components/share/codeSnippets/Chat/EmbedSettings.tsx index 12678dfc9..2333d511b 100644 --- a/apps/builder/components/share/codeSnippets/Chat/EmbedSettings.tsx +++ b/apps/builder/components/share/codeSnippets/Chat/EmbedSettings.tsx @@ -14,10 +14,11 @@ import { NumberDecrementStepper, Switch, Text, - Tag, + Image, } from '@chakra-ui/react' import { ColorPicker } from 'components/theme/GeneralSettings/ColorPicker' import { useTypebot } from 'contexts/TypebotContext' +import { useUser } from 'contexts/UserContext' import { useState, useEffect } from 'react' import { BubbleParams } from 'typebot-js' @@ -30,30 +31,41 @@ export const ChatEmbedSettings = ({ onUpdateSettings, ...props }: ChatEmbedSettingsProps & StackProps) => { + const { user } = useUser() const { typebot } = useTypebot() const [proactiveMessageChecked, setProactiveMessageChecked] = useState(false) + const [isCustomIconChecked, setIsCustomIconChecked] = useState(false) + const [rememberProMessageChecked] = useState(true) const [customIconInputValue, setCustomIconInputValue] = useState('') const [inputValues, setInputValues] = useState({ messageDelay: '0', messageContent: 'I have a question for you!', + avatarUrl: typebot?.theme.chat.hostAvatar?.url ?? user?.image ?? '', }) const [bubbleColor, setBubbleColor] = useState( typebot?.theme.chat.buttons.backgroundColor ?? '#0042DA' ) + const [bubbleIconColor, setIconBubbleColor] = useState( + typebot?.theme.chat.buttons.color ?? '#FFFFFF' + ) + useEffect(() => { if (proactiveMessageChecked) { onUpdateSettings({ button: { color: bubbleColor, - iconUrl: customIconInputValue, + iconUrl: isCustomIconChecked ? customIconInputValue : undefined, + iconColor: + bubbleIconColor === '#FFFFFF' ? undefined : bubbleIconColor, }, proactiveMessage: { delay: parseInt(inputValues.messageDelay) * 1000, textContent: inputValues.messageContent, + avatarUrl: inputValues.avatarUrl, rememberClose: rememberProMessageChecked, }, }) @@ -61,43 +73,66 @@ export const ChatEmbedSettings = ({ onUpdateSettings({ button: { color: bubbleColor, - iconUrl: customIconInputValue, + iconUrl: isCustomIconChecked ? customIconInputValue : undefined, + iconColor: + bubbleIconColor === '#FFFFFF' ? undefined : bubbleIconColor, }, proactiveMessage: undefined, }) } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ inputValues, bubbleColor, rememberProMessageChecked, customIconInputValue, + bubbleIconColor, proactiveMessageChecked, + isCustomIconChecked, ]) return ( - + Chat bubble settings - + Button color - - - Custom button icon Optional - - setCustomIconInputValue(e.target.value)} + + Icon color + + + + Custom button icon? + + setIsCustomIconChecked(!isCustomIconChecked)} + isChecked={isCustomIconChecked} + /> + + {isCustomIconChecked && ( + <> + + Url: + setCustomIconInputValue(e.target.value)} + minW="0" + /> + + + )} {proactiveMessageChecked && ( <> - + + + {inputValues.avatarUrl && ( + // eslint-disable-next-line jsx-a11y/alt-text + + )} + {inputValues.messageContent} + + + Appearance delay @@ -139,7 +190,21 @@ export const ChatEmbedSettings = ({ - + + Avatar URL + + setInputValues({ + ...inputValues, + avatarUrl: e.target.value, + }) + } + value={inputValues.avatarUrl} + placeholder={'Paste image link (.png, .jpg)'} + /> + + Message content { if (!button) return '' const iconUrlString = parseStringParam('iconUrl', button.iconUrl) const buttonColorstring = parseStringParam('color', button.color) - return `button: {${iconUrlString}${buttonColorstring}},` + const buttonIconColorString = parseStringParam('iconColor', button.iconColor) + return `button: {${iconUrlString}${buttonColorstring}${buttonIconColorString}},` } const parseProactiveMessage = ( proactiveMessage?: ProactiveMessageParams ): string => { if (!proactiveMessage) return `` - const { avatarUrl, textContent, delay, rememberClose } = proactiveMessage + const { avatarUrl, textContent, delay } = 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}},` + return `proactiveMessage: {${avatarUrlString}${textContentString}${delayString}},` } const parseIframeParams = ({ diff --git a/apps/docs/docs/editor/blocks/set-variable.md b/apps/docs/docs/editor/blocks/set-variable.md index 9264262c9..e40310c2d 100644 --- a/apps/docs/docs/editor/blocks/set-variable.md +++ b/apps/docs/docs/editor/blocks/set-variable.md @@ -42,12 +42,8 @@ A popular request also is to set a variable to the current URL. Here is the valu window.location.href ``` -It will not give you the parent URL if you embed the bot on your site. A more bullet proof value would then be: +:::caution +It will not give you the parent URL if you embed the bot on your site. -```js -window.location != window.parent.location - ? document.referrer - : document.location.href -``` - -It checks whether or not the bot is embedded and return the appropriate URL. +A more bullet proof option is to pass the URL as a hidden variable in the embed code options. You can find an example [here](../../embed/html-javascript#additional-configuration). +::: diff --git a/apps/docs/docs/embed/html-javascript.md b/apps/docs/docs/embed/html-javascript.md new file mode 100644 index 000000000..ee8f54720 --- /dev/null +++ b/apps/docs/docs/embed/html-javascript.md @@ -0,0 +1,127 @@ +--- +sidebar_position: 4 +--- + +# HTML & Javascript + +## Standard + +You can get the standard HTML and Javascript code by clicking on the "HTML & Javascript" button in the "Share" tab of your typebot. + +There, you can change the container dimensions. Here is a code example: + +```html + +
+ +``` + +This code is creating a container with a 100% width (will match parent width) and 600px height. + +## Popup + +You can get the popup HTML and Javascript code by clicking on the "HTML & Javascript" button in the "Share" tab of your typebot. + +Here is an example: + +```html + + +``` + +This code will automatically trigger the popup window after 3 seconds. + +### Open or Close a popup + +You can use these commands: + +```js +Typebot.getPopupActions().open() +``` + +```js +Typebot.getPopupActions().close() +``` + +You can bind these commands on a button element, for example: + +```html + +``` + +## Bubble + +You can get the bubble HTML and Javascript code by clicking on the "HTML & Javascript" button in the "Share" tab of your typebot. + +Here is an example: + +```html + + +``` + +This code will automatically trigger the popup window after 3 seconds. + +### Open or close the proactive message + +You can use this command: + +```js +Typebot.getBubbleActions().openProactiveMessage() +``` + +You can bind this command on a button element, for example: + +```html + +``` + +### Open or close the typebot + +You can use these commands: + +```js +Typebot.getBubbleActions().open() +``` + +```js +Typebot.getBubbleActions().close() +``` + +You can bind these commands on a button element, for example: + +```html + +``` + +## Additional configuration + +You can add hidden variable values in your embed code by adding the `hiddenVariables` option. Here is an example: + +```js +Typebot.initContainer('typebot-container', { + url: 'https://viewer.typebot.io/my-typebot', + hiddenVariables: { + 'Current URL': window.location.href, + 'User name': 'John Doe', + }, +}) +``` + +It will populate the `Current URL` variable with the parent URL and the `User name` variable with "John Doe". diff --git a/apps/docs/docs/embed/javascript-commands.md b/apps/docs/docs/embed/javascript-commands.md deleted file mode 100644 index 8fd0247e5..000000000 --- a/apps/docs/docs/embed/javascript-commands.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Javascript library - -Typebot Javascript library is open-source ([check out the repository](https://github.com/baptisteArno/typebot.io/tree/main/packages/typebot-js)). Feel free to contribute if you're a developer and wish to improve its features. - -Whenever a typebot is embedded on your website, you have access to commands to automatically trigger actions on your embedding depending on its type. - -## Popup - -### Open or Close a popup - -You can use these commands: - -```js -Typebot.getPopupActions().open() -``` - -```js -Typebot.getPopupActions().close() -``` - -You can bind these commands on a button element, for example: - -```html - -``` - -## Bubble - -### Open or close the proactive message - -You can use this command: - -```js -Typebot.getBubbleActions().openProactiveMessage() -``` - -You can bind this command on a button element, for example: - -```html - -``` - -### Open or close the typebot - -You can use these commands: - -```js -Typebot.getBubbleActions().open() -``` - -```js -Typebot.getBubbleActions().close() -``` - -You can bind these commands on a button element, for example: - -```html - -``` diff --git a/packages/typebot-js/src/embedTypes/chat/button.ts b/packages/typebot-js/src/embedTypes/chat/button.ts index 9f4a9abc0..eaf2a5ca0 100644 --- a/packages/typebot-js/src/embedTypes/chat/button.ts +++ b/packages/typebot-js/src/embedTypes/chat/button.ts @@ -4,16 +4,21 @@ export const createButton = (params?: ButtonParams): HTMLButtonElement => { const button = document.createElement('button') button.id = 'typebot-bubble-button' button.style.backgroundColor = params?.color ?? '#0042DA' - button.appendChild(createButtonIcon(params?.iconUrl, params?.iconStyle)) - button.appendChild(createCloseIcon(params?.closeIconColor)) + button.appendChild( + createButtonIcon(params?.iconUrl, params?.iconColor, params?.iconStyle) + ) + button.appendChild( + createCloseIcon(params?.iconColor ?? params?.closeIconColor) + ) return button } const createButtonIcon = ( src?: string, + iconColor?: string, style?: string ): SVGElement | HTMLElement => { - if (!src) return createDefaultIcon() + if (!src) return createDefaultIcon(iconColor) const icon = document.createElement('img') icon.classList.add('icon') icon.src = src @@ -21,20 +26,21 @@ const createButtonIcon = ( return icon } -const createDefaultIcon = (): SVGElement => { +const createDefaultIcon = (iconColor?: string): SVGElement => { const icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg') icon.setAttribute('viewBox', '0 0 24 24') icon.innerHTML = typebotLogoSvgTextContent() icon.classList.add('icon') + icon.style.stroke = iconColor ?? '#ffffff' return icon } -const createCloseIcon = (closeIconColor?: string): SVGElement => { +const createCloseIcon = (iconColor?: string): SVGElement => { const icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg') icon.setAttribute('viewBox', '0 0 24 24') icon.innerHTML = closeSvgPath icon.classList.add('close-icon') - icon.style.stroke = closeIconColor ?? '#ffffff' + icon.style.stroke = iconColor ?? '#ffffff' return icon } diff --git a/packages/typebot-js/src/types.ts b/packages/typebot-js/src/types.ts index 8526c9c43..78daeaa2c 100644 --- a/packages/typebot-js/src/types.ts +++ b/packages/typebot-js/src/types.ts @@ -30,6 +30,7 @@ export type ButtonParams = { color?: string iconUrl?: string iconStyle?: string + iconColor?: string closeIconColor?: string }