Files
bot/apps/builder/src/features/blocks/inputs/pictureChoice/components/PictureChoiceItemNode.tsx
2024-01-25 16:35:16 +01:00

153 lines
4.0 KiB
TypeScript

import {
Fade,
IconButton,
Flex,
Image,
Popover,
Portal,
PopoverContent,
PopoverArrow,
PopoverBody,
PopoverAnchor,
useEventListener,
useColorModeValue,
} from '@chakra-ui/react'
import { ImageIcon, PlusIcon } from '@/components/icons'
import { useTypebot } from '@/features/editor/providers/TypebotProvider'
import { ItemIndices } from '@typebot.io/schemas'
import React, { useRef } from 'react'
import { PictureChoiceItem } from '@typebot.io/schemas/features/blocks/inputs/pictureChoice'
import { useGraph } from '@/features/graph/providers/GraphProvider'
import { PictureChoiceItemSettings } from './PictureChoiceItemSettings'
import { isSvgSrc } from '@typebot.io/lib'
type Props = {
item: PictureChoiceItem
indices: ItemIndices
isMouseOver: boolean
}
export const PictureChoiceItemNode = ({
item,
indices,
isMouseOver,
}: Props) => {
const emptyImageBgColor = useColorModeValue('gray.100', 'gray.700')
const { openedItemId, setOpenedItemId } = useGraph()
const { updateItem, createItem, typebot } = useTypebot()
const ref = useRef<HTMLDivElement | null>(null)
const handlePlusClick = (e: React.MouseEvent) => {
e.stopPropagation()
const itemIndex = indices.itemIndex + 1
createItem({}, { ...indices, itemIndex })
}
const handleMouseDown = (e: React.MouseEvent) => e.stopPropagation()
const openPopover = () => {
setOpenedItemId(item.id)
}
const handleItemChange = (updates: Partial<PictureChoiceItem>) => {
updateItem(indices, { ...item, ...updates })
}
const handleMouseWheel = (e: WheelEvent) => {
e.stopPropagation()
}
useEventListener('wheel', handleMouseWheel, ref.current)
return (
<Popover
placement="right"
isLazy
isOpen={openedItemId === item.id}
closeOnBlur={false}
>
<PopoverAnchor>
<Flex
px={4}
py={2}
justify="center"
w="full"
pos="relative"
onClick={openPopover}
data-testid="item-node"
userSelect="none"
>
{item.pictureSrc ? (
<Image
src={item.pictureSrc}
alt="Picture choice image"
rounded="md"
maxH={isSvgSrc(item.pictureSrc) ? '64px' : '128px'}
w="full"
objectFit={isSvgSrc(item.pictureSrc) ? 'contain' : 'cover'}
p={isSvgSrc(item.pictureSrc) ? '2' : undefined}
userSelect="none"
draggable={false}
/>
) : (
<Flex
width="full"
height="100px"
bgColor={emptyImageBgColor}
rounded="md"
justify="center"
align="center"
>
<ImageIcon />
</Flex>
)}
<Fade
in={isMouseOver}
style={{
position: 'absolute',
bottom: '-15px',
zIndex: 3,
left: '90px',
}}
unmountOnExit
>
<IconButton
aria-label="Add item"
icon={<PlusIcon />}
size="xs"
shadow="md"
colorScheme="gray"
borderWidth={1}
onClick={handlePlusClick}
/>
</Fade>
</Flex>
</PopoverAnchor>
<Portal>
<PopoverContent pos="relative" onMouseDown={handleMouseDown}>
<PopoverArrow />
<PopoverBody
py="6"
overflowY="auto"
maxH="400px"
shadow="lg"
ref={ref}
>
{typebot && (
<PictureChoiceItemSettings
workspaceId={typebot.workspaceId}
typebotId={typebot.id}
item={item}
blockId={
typebot.groups[indices.groupIndex].blocks[indices.blockIndex]
.id
}
onItemChange={handleItemChange}
/>
)}
</PopoverBody>
</PopoverContent>
</Portal>
</Popover>
)
}