From e06f8186f61bcc4abc5cec8984de00c623088d8b Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Fri, 7 Apr 2023 11:30:54 +0200 Subject: [PATCH] :zap: (imageBubble) Add redirect on image click option Closes #448 --- .../image/components/ImageBubbleSettings.tsx | 80 +++++++++++++++++++ .../nodes/block/MediaBubblePopoverContent.tsx | 12 ++- packages/embeds/js/package.json | 2 +- .../js/src/components/bubbles/HostBubble.tsx | 2 +- .../bubbles/image/components/ImageBubble.tsx | 43 ++++++---- packages/embeds/react/package.json | 2 +- .../schemas/features/blocks/bubbles/image.ts | 6 ++ 7 files changed, 121 insertions(+), 26 deletions(-) create mode 100644 apps/builder/src/features/blocks/bubbles/image/components/ImageBubbleSettings.tsx diff --git a/apps/builder/src/features/blocks/bubbles/image/components/ImageBubbleSettings.tsx b/apps/builder/src/features/blocks/bubbles/image/components/ImageBubbleSettings.tsx new file mode 100644 index 000000000..408cf8d5a --- /dev/null +++ b/apps/builder/src/features/blocks/bubbles/image/components/ImageBubbleSettings.tsx @@ -0,0 +1,80 @@ +import { ImageUploadContent } from '@/components/ImageUploadContent' +import { TextInput } from '@/components/inputs' +import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel' +import { Stack } from '@chakra-ui/react' +import { isDefined, isNotEmpty } from '@typebot.io/lib' +import { ImageBubbleBlock } from '@typebot.io/schemas' +import React, { useState } from 'react' + +type Props = { + typebotId: string + block: ImageBubbleBlock + onContentChange: (content: ImageBubbleBlock['content']) => void +} + +export const ImageBubbleSettings = ({ + typebotId, + block, + onContentChange, +}: Props) => { + const [showClickLinkInput, setShowClickLinkInput] = useState( + isNotEmpty(block.content.clickLink?.url) + ) + + const updateImage = (url: string) => { + onContentChange({ ...block.content, url }) + } + + const updateClickLinkUrl = (url: string) => { + onContentChange({ + ...block.content, + clickLink: { ...block.content.clickLink, url }, + }) + } + + const updateClickLinkAltText = (alt: string) => { + onContentChange({ + ...block.content, + clickLink: { ...block.content.clickLink, alt }, + }) + } + + const toggleClickLink = () => { + if (isDefined(block.content.clickLink) && showClickLinkInput) { + onContentChange({ ...block.content, clickLink: undefined }) + } + setShowClickLinkInput(!showClickLinkInput) + } + + return ( + + + + + {showClickLinkInput && ( + <> + + + + )} + + + ) +} diff --git a/apps/builder/src/features/graph/components/nodes/block/MediaBubblePopoverContent.tsx b/apps/builder/src/features/graph/components/nodes/block/MediaBubblePopoverContent.tsx index 4bbbb8c6f..6b7989511 100644 --- a/apps/builder/src/features/graph/components/nodes/block/MediaBubblePopoverContent.tsx +++ b/apps/builder/src/features/graph/components/nodes/block/MediaBubblePopoverContent.tsx @@ -1,6 +1,6 @@ -import { ImageUploadContent } from '@/components/ImageUploadContent' import { AudioBubbleForm } from '@/features/blocks/bubbles/audio/components/AudioBubbleForm' import { EmbedUploadContent } from '@/features/blocks/bubbles/embed/components/EmbedUploadContent' +import { ImageBubbleSettings } from '@/features/blocks/bubbles/image/components/ImageBubbleSettings' import { VideoUploadContent } from '@/features/blocks/bubbles/video/components/VideoUploadContent' import { Portal, @@ -46,15 +46,13 @@ export const MediaBubbleContent = ({ block, onContentChange, }: Props) => { - const handleImageUrlChange = (url: string) => onContentChange({ url }) - switch (block.type) { case BubbleBlockType.IMAGE: { return ( - ) } diff --git a/packages/embeds/js/package.json b/packages/embeds/js/package.json index a1fb77270..ae2034529 100644 --- a/packages/embeds/js/package.json +++ b/packages/embeds/js/package.json @@ -1,6 +1,6 @@ { "name": "@typebot.io/js", - "version": "0.0.33", + "version": "0.0.34", "description": "Javascript library to display typebots on your website", "type": "module", "main": "dist/index.js", diff --git a/packages/embeds/js/src/components/bubbles/HostBubble.tsx b/packages/embeds/js/src/components/bubbles/HostBubble.tsx index c183b4e69..c62e585bb 100644 --- a/packages/embeds/js/src/components/bubbles/HostBubble.tsx +++ b/packages/embeds/js/src/components/bubbles/HostBubble.tsx @@ -37,7 +37,7 @@ export const HostBubble = (props: Props) => { diff --git a/packages/embeds/js/src/features/blocks/bubbles/image/components/ImageBubble.tsx b/packages/embeds/js/src/features/blocks/bubbles/image/components/ImageBubble.tsx index 50f1da589..6b4e76c0a 100644 --- a/packages/embeds/js/src/features/blocks/bubbles/image/components/ImageBubble.tsx +++ b/packages/embeds/js/src/features/blocks/bubbles/image/components/ImageBubble.tsx @@ -3,7 +3,7 @@ import type { ImageBubbleContent } from '@typebot.io/schemas' import { createSignal, onCleanup, onMount } from 'solid-js' type Props = { - url: ImageBubbleContent['url'] + content: ImageBubbleContent onTransitionEnd: () => void } @@ -38,6 +38,21 @@ export const ImageBubble = (props: Props) => { if (typingTimeout) clearTimeout(typingTimeout) }) + const Image = ( + {props.content.clickLink?.alt + ) + return (
@@ -51,21 +66,17 @@ export const ImageBubble = (props: Props) => { > {isTyping() ? : null}
-
- Bubble image -
+ {props.content.clickLink ? ( + + {Image} + + ) : ( +
{Image}
+ )}
diff --git a/packages/embeds/react/package.json b/packages/embeds/react/package.json index dd6e2cdbd..753afcb97 100644 --- a/packages/embeds/react/package.json +++ b/packages/embeds/react/package.json @@ -1,6 +1,6 @@ { "name": "@typebot.io/react", - "version": "0.0.33", + "version": "0.0.34", "description": "React library to display typebots on your website", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/schemas/features/blocks/bubbles/image.ts b/packages/schemas/features/blocks/bubbles/image.ts index 721373c02..aedde666f 100644 --- a/packages/schemas/features/blocks/bubbles/image.ts +++ b/packages/schemas/features/blocks/bubbles/image.ts @@ -4,6 +4,12 @@ import { BubbleBlockType } from './enums' export const imageBubbleContentSchema = z.object({ url: z.string().optional(), + clickLink: z + .object({ + url: z.string().optional(), + alt: z.string().optional(), + }) + .optional(), }) export const imageBubbleBlockSchema = blockBaseSchema.merge(