Introducing The Forge (#1072)

The Forge allows anyone to easily create their own Typebot Block.

Closes #380
This commit is contained in:
Baptiste Arnaud
2023-12-13 10:22:02 +01:00
committed by GitHub
parent c373108b55
commit 5e019bbb22
184 changed files with 42659 additions and 37411 deletions

View File

@@ -2,6 +2,10 @@ import {
Button,
ButtonProps,
chakra,
FormControl,
FormHelperText,
FormLabel,
HStack,
Menu,
MenuButton,
MenuItem,
@@ -10,7 +14,8 @@ import {
Stack,
} from '@chakra-ui/react'
import { ChevronLeftIcon } from '@/components/icons'
import React from 'react'
import React, { ReactNode } from 'react'
import { MoreInfoTooltip } from './MoreInfoTooltip'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Props<T extends readonly any[]> = {
@@ -18,6 +23,11 @@ type Props<T extends readonly any[]> = {
onItemSelect: (item: T[number]) => void
items: T
placeholder?: string
label?: string
isRequired?: boolean
direction?: 'row' | 'column'
helperText?: ReactNode
moreInfoTooltip?: string
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -25,44 +35,67 @@ export const DropdownList = <T extends readonly any[]>({
currentItem,
onItemSelect,
items,
placeholder = '',
placeholder,
label,
isRequired,
direction = 'column',
helperText,
moreInfoTooltip,
...props
}: Props<T> & ButtonProps) => {
const handleMenuItemClick = (operator: T[number]) => () => {
onItemSelect(operator)
}
return (
<Menu isLazy placement="bottom-end" matchWidth>
<MenuButton
as={Button}
rightIcon={<ChevronLeftIcon transform={'rotate(-90deg)'} />}
colorScheme="gray"
justifyContent="space-between"
textAlign="left"
{...props}
>
<chakra.span noOfLines={1} display="block">
{currentItem ?? placeholder}
</chakra.span>
</MenuButton>
<Portal>
<MenuList maxW="500px" zIndex={1500}>
<Stack maxH={'35vh'} overflowY="scroll" spacing="0">
{items.map((item) => (
<MenuItem
key={item as unknown as string}
maxW="500px"
overflow="hidden"
whiteSpace="nowrap"
textOverflow="ellipsis"
onClick={handleMenuItemClick(item)}
>
{item}
</MenuItem>
))}
</Stack>
</MenuList>
</Portal>
</Menu>
<FormControl
isRequired={isRequired}
as={direction === 'column' ? Stack : HStack}
justifyContent="space-between"
width={label ? 'full' : 'auto'}
spacing={direction === 'column' ? 2 : 3}
>
{label && (
<FormLabel display="flex" flexShrink={0} gap="1" mb="0" mr="0">
{label}{' '}
{moreInfoTooltip && (
<MoreInfoTooltip>{moreInfoTooltip}</MoreInfoTooltip>
)}
</FormLabel>
)}
<Menu isLazy placement="bottom-end" matchWidth>
<MenuButton
as={Button}
rightIcon={<ChevronLeftIcon transform={'rotate(-90deg)'} />}
colorScheme="gray"
justifyContent="space-between"
textAlign="left"
w="full"
{...props}
>
<chakra.span noOfLines={1} display="block">
{currentItem ?? placeholder ?? 'Select an item'}
</chakra.span>
</MenuButton>
<Portal>
<MenuList maxW="500px" zIndex={1500}>
<Stack maxH={'35vh'} overflowY="scroll" spacing="0">
{items.map((item) => (
<MenuItem
key={item as unknown as string}
maxW="500px"
overflow="hidden"
whiteSpace="nowrap"
textOverflow="ellipsis"
onClick={handleMenuItemClick(item)}
>
{item}
</MenuItem>
))}
</Stack>
</MenuList>
</Portal>
</Menu>
{helperText && <FormHelperText>{helperText}</FormHelperText>}
</FormControl>
)
}