2
0

🐛 (js) Fix dynamic avatar on mount

This commit is contained in:
Baptiste Arnaud
2023-03-10 16:00:57 +01:00
parent 9785a0df5c
commit 883d519875
6 changed files with 70 additions and 33 deletions

View File

@@ -5,15 +5,18 @@ import {
HStack, HStack,
Popover, Popover,
PopoverContent, PopoverContent,
PopoverTrigger,
Stack, Stack,
Switch, Switch,
Image, Image,
Flex, Flex,
Box, Box,
Portal,
PopoverAnchor,
useDisclosure,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import { ImageUploadContent } from '@/components/ImageUploadContent' import { ImageUploadContent } from '@/components/ImageUploadContent'
import { DefaultAvatar } from '../DefaultAvatar' import { DefaultAvatar } from '../DefaultAvatar'
import { useOutsideClick } from '@/hooks/useOutsideClick'
type Props = { type Props = {
uploadFilePath: string uploadFilePath: string
@@ -30,11 +33,21 @@ export const AvatarForm = ({
isDefaultCheck = false, isDefaultCheck = false,
onAvatarChange, onAvatarChange,
}: Props) => { }: Props) => {
const { isOpen, onOpen, onClose } = useDisclosure()
const isChecked = avatarProps ? avatarProps.isEnabled : isDefaultCheck const isChecked = avatarProps ? avatarProps.isEnabled : isDefaultCheck
const handleOnCheck = () => const handleOnCheck = () =>
onAvatarChange({ ...avatarProps, isEnabled: !isChecked }) onAvatarChange({ ...avatarProps, isEnabled: !isChecked })
const handleImageUrl = (url: string) => const handleImageUrl = (url: string) =>
onAvatarChange({ isEnabled: isChecked, url }) onAvatarChange({ isEnabled: isChecked, url })
const popoverContainerRef = React.useRef<HTMLDivElement>(null)
useOutsideClick({
ref: popoverContainerRef,
handler: () => {
console.log('close')
onClose()
},
})
const isDefaultAvatar = !avatarProps?.url || avatarProps.url.includes('{{') const isDefaultAvatar = !avatarProps?.url || avatarProps.url.includes('{{')
return ( return (
@@ -47,36 +60,45 @@ export const AvatarForm = ({
<Switch isChecked={isChecked} id={title} onChange={handleOnCheck} /> <Switch isChecked={isChecked} id={title} onChange={handleOnCheck} />
</HStack> </HStack>
{isChecked && ( {isChecked && (
<Popover isLazy> <Flex ref={popoverContainerRef}>
<PopoverTrigger> <Popover isLazy isOpen={isOpen}>
{isDefaultAvatar ? ( <PopoverAnchor>
<Box> {isDefaultAvatar ? (
<DefaultAvatar <Box onClick={onOpen}>
<DefaultAvatar
cursor="pointer"
_hover={{ filter: 'brightness(.9)' }}
/>
</Box>
) : (
<Image
onClick={onOpen}
src={avatarProps.url}
alt="Website image"
cursor="pointer" cursor="pointer"
_hover={{ filter: 'brightness(.9)' }} _hover={{ filter: 'brightness(.9)' }}
transition="filter 200ms"
rounded="full"
boxSize="40px"
objectFit="cover"
/> />
</Box> )}
) : ( </PopoverAnchor>
<Image <Portal>
src={avatarProps.url} <PopoverContent
alt="Website image" p="4"
cursor="pointer" onMouseDown={(e) => e.stopPropagation()}
_hover={{ filter: 'brightness(.9)' }} onPointerDown={(e) => e.stopPropagation()}
transition="filter 200ms" >
rounded="full" <ImageUploadContent
boxSize="40px" filePath={uploadFilePath}
objectFit="cover" defaultUrl={avatarProps?.url}
/> onSubmit={handleImageUrl}
)} />
</PopoverTrigger> </PopoverContent>
<PopoverContent p="4"> </Portal>
<ImageUploadContent </Popover>
filePath={uploadFilePath} </Flex>
defaultUrl={avatarProps?.url}
onSubmit={handleImageUrl}
/>
</PopoverContent>
</Popover>
)} )}
</Flex> </Flex>
</Stack> </Stack>

View File

@@ -2854,6 +2854,13 @@
"options": { "options": {
"type": "object", "type": "object",
"properties": { "properties": {
"task": {
"type": "string",
"enum": [
"Show widget",
"Close widget"
]
},
"baseUrl": { "baseUrl": {
"type": "string" "type": "string"
}, },

View File

@@ -33,5 +33,5 @@
"path": "node_modules/cz-emoji" "path": "node_modules/cz-emoji"
} }
}, },
"packageManager": "pnpm@7.28.0" "packageManager": "pnpm@7.29.1"
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@typebot.io/js", "name": "@typebot.io/js",
"version": "0.0.23", "version": "0.0.24",
"description": "Javascript library to display typebots on your website", "description": "Javascript library to display typebots on your website",
"type": "module", "type": "module",
"main": "dist/index.js", "main": "dist/index.js",

View File

@@ -1,10 +1,18 @@
import { isMobile } from '@/utils/isMobileSignal' import { isMobile } from '@/utils/isMobileSignal'
import { createSignal, Show } from 'solid-js' import { createEffect, createSignal, Show } from 'solid-js'
import { isNotEmpty } from 'utils' import { isNotEmpty } from 'utils'
import { DefaultAvatar } from './DefaultAvatar' import { DefaultAvatar } from './DefaultAvatar'
export const Avatar = (props: { initialAvatarSrc?: string }) => { export const Avatar = (props: { initialAvatarSrc?: string }) => {
const [avatarSrc] = createSignal(props.initialAvatarSrc) const [avatarSrc, setAvatarSrc] = createSignal(props.initialAvatarSrc)
createEffect(() => {
if (
avatarSrc()?.startsWith('{{') &&
props.initialAvatarSrc?.startsWith('http')
)
setAvatarSrc(props.initialAvatarSrc)
})
return ( return (
<Show <Show

View File

@@ -1,6 +1,6 @@
{ {
"name": "@typebot.io/react", "name": "@typebot.io/react",
"version": "0.0.23", "version": "0.0.24",
"description": "React library to display typebots on your website", "description": "React library to display typebots on your website",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",