feat(editor): ✨ Custom icon on typebot
This commit is contained in:
@ -1,31 +1,59 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Button, Flex, HStack, Stack, Text } from '@chakra-ui/react'
|
||||
import { ChangeEvent, useEffect, useState } from 'react'
|
||||
import {
|
||||
Button,
|
||||
Flex,
|
||||
HStack,
|
||||
Stack,
|
||||
Text,
|
||||
Input as ClassicInput,
|
||||
SimpleGrid,
|
||||
GridItem,
|
||||
} from '@chakra-ui/react'
|
||||
import { SearchContextManager } from '@giphy/react-components'
|
||||
import { UploadButton } from '../buttons/UploadButton'
|
||||
import { GiphySearch } from './GiphySearch'
|
||||
import { useTypebot } from 'contexts/TypebotContext'
|
||||
import { useDebounce } from 'use-debounce'
|
||||
import { Input } from '../Textbox'
|
||||
import { BaseEmoji, emojiIndex } from 'emoji-mart'
|
||||
import { emojis } from './emojis'
|
||||
|
||||
type Props = {
|
||||
url?: string
|
||||
onSubmit: (url: string) => void
|
||||
isEmojiEnabled?: boolean
|
||||
isGiphyEnabled?: boolean
|
||||
onSubmit: (url: string) => void
|
||||
onClose?: () => void
|
||||
}
|
||||
|
||||
export const ImageUploadContent = ({
|
||||
url,
|
||||
onSubmit,
|
||||
isEmojiEnabled = false,
|
||||
isGiphyEnabled = true,
|
||||
onClose,
|
||||
}: Props) => {
|
||||
const [currentTab, setCurrentTab] = useState<'link' | 'upload' | 'giphy'>(
|
||||
'upload'
|
||||
)
|
||||
const [currentTab, setCurrentTab] = useState<
|
||||
'link' | 'upload' | 'giphy' | 'emoji'
|
||||
>(isEmojiEnabled ? 'emoji' : 'upload')
|
||||
|
||||
const handleSubmit = (url: string) => {
|
||||
onSubmit(url)
|
||||
onClose && onClose()
|
||||
}
|
||||
|
||||
const handleSubmit = (url: string) => onSubmit(url)
|
||||
return (
|
||||
<Stack>
|
||||
<HStack>
|
||||
{isEmojiEnabled && (
|
||||
<Button
|
||||
variant={currentTab === 'emoji' ? 'solid' : 'ghost'}
|
||||
onClick={() => setCurrentTab('emoji')}
|
||||
size="sm"
|
||||
>
|
||||
Emoji
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant={currentTab === 'upload' ? 'solid' : 'ghost'}
|
||||
onClick={() => setCurrentTab('upload')}
|
||||
@ -61,7 +89,7 @@ const BodyContent = ({
|
||||
url,
|
||||
onSubmit,
|
||||
}: {
|
||||
tab: 'upload' | 'link' | 'giphy'
|
||||
tab: 'upload' | 'link' | 'giphy' | 'emoji'
|
||||
url?: string
|
||||
onSubmit: (url: string) => void
|
||||
}) => {
|
||||
@ -72,6 +100,8 @@ const BodyContent = ({
|
||||
return <EmbedLinkContent initialUrl={url} onNewUrl={onSubmit} />
|
||||
case 'giphy':
|
||||
return <GiphyContent onNewUrl={onSubmit} />
|
||||
case 'emoji':
|
||||
return <EmojiContent onEmojiSelected={onSubmit} />
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,6 +144,55 @@ const EmbedLinkContent = ({ initialUrl, onNewUrl }: ContentProps) => {
|
||||
)
|
||||
}
|
||||
|
||||
const EmojiContent = ({
|
||||
onEmojiSelected,
|
||||
}: {
|
||||
onEmojiSelected: (emoji: string) => void
|
||||
}) => {
|
||||
const [searchValue, setSearchValue] = useState('')
|
||||
const [filteredEmojis, setFilteredEmojis] = useState<string[]>(emojis)
|
||||
|
||||
const handleEmojiClick = (emoji: string) => () => onEmojiSelected(emoji)
|
||||
|
||||
const handleSearchChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
setSearchValue(e.target.value)
|
||||
setFilteredEmojis(
|
||||
emojiIndex.search(e.target.value)?.map((o) => (o as BaseEmoji).native) ??
|
||||
emojis
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<ClassicInput
|
||||
placeholder="Search..."
|
||||
value={searchValue}
|
||||
onChange={handleSearchChange}
|
||||
/>
|
||||
<SimpleGrid
|
||||
maxH="350px"
|
||||
overflowY="scroll"
|
||||
overflowX="hidden"
|
||||
spacing={0}
|
||||
columns={7}
|
||||
>
|
||||
{filteredEmojis.map((emoji) => (
|
||||
<GridItem key={emoji}>
|
||||
<Button
|
||||
onClick={handleEmojiClick(emoji)}
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
fontSize="xl"
|
||||
>
|
||||
{emoji}
|
||||
</Button>
|
||||
</GridItem>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
const GiphyContent = ({ onNewUrl }: ContentProps) => {
|
||||
if (!process.env.NEXT_PUBLIC_GIPHY_API_KEY)
|
||||
return <Text>NEXT_PUBLIC_GIPHY_API_KEY is missing in environment</Text>
|
||||
|
Reference in New Issue
Block a user