2
0

feat(ui): 💄 Face lift

This commit is contained in:
Baptiste Arnaud
2022-01-19 09:44:21 +01:00
parent f49b5143cf
commit 44b478550f
23 changed files with 306 additions and 136 deletions

View File

@ -99,15 +99,17 @@ export const ChoiceItemNode = ({
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
justifyContent="center"
shadow="sm"
_hover={{ shadow: 'md' }}
transition="box-shadow 200ms"
borderWidth="1px"
rounded="md"
px="4"
py="2"
borderColor={isOpened ? 'blue.400' : 'gray.300'}
>
<Editable
ref={ref}
px="4"
py="2"
rounded="md"
bgColor="green.200"
borderWidth="2px"
borderColor={isOpened ? 'blue.400' : 'gray.400'}
defaultValue={item.content ?? 'Click to edit'}
flex="1"
startWithEditView={!isDefined(item.content)}
@ -115,7 +117,10 @@ export const ChoiceItemNode = ({
onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove}
>
<EditablePreview />
<EditablePreview
w="full"
color={item.content !== 'Click to edit' ? 'inherit' : 'gray.500'}
/>
<EditableInput />
</Editable>
{typebot && isSingleChoiceInput(typebot.steps.byId[item.stepId]) && (
@ -138,6 +143,8 @@ export const ChoiceItemNode = ({
aria-label="Add item"
icon={<PlusIcon />}
size="xs"
shadow="md"
colorScheme="blue"
onClick={handlePlusClick}
/>
</Fade>

View File

@ -15,11 +15,12 @@ export const ChoiceItemNodeOverlay = ({
px="4"
py="2"
rounded="md"
bgColor="green.200"
borderWidth="2px"
borderColor={'gray.400'}
bgColor="white"
borderWidth="1px"
borderColor={'gray.300'}
w="212px"
pointerEvents="none"
shadow="lg"
{...props}
>
{item.content ?? 'Click to edit'}

View File

@ -44,14 +44,17 @@ export const ChoiceItemsList = ({ step }: ChoiceItemsListProps) => {
}
useEventListener('mousemove', handleStepMove)
const handleMouseUp = (e: React.MouseEvent<HTMLDivElement>) => {
if (expandedPlaceholderIndex === undefined || !draggedChoiceItem) return
e.stopPropagation()
const handleMouseUp = (e: MouseEvent) => {
if (!draggedChoiceItem) return
if (expandedPlaceholderIndex !== -1) {
e.stopPropagation()
createChoiceItem(draggedChoiceItem, expandedPlaceholderIndex)
}
setMouseOverBlockId(undefined)
setExpandedPlaceholderIndex(undefined)
setDraggedChoiceItem(undefined)
createChoiceItem(draggedChoiceItem, expandedPlaceholderIndex)
}
useEventListener('mouseup', handleMouseUp, undefined, { capture: true })
const handleStepMouseDown = (
{ absolute, relative }: { absolute: Coordinates; relative: Coordinates },
@ -76,15 +79,10 @@ export const ChoiceItemsList = ({ step }: ChoiceItemsListProps) => {
const stopPropagating = (e: React.MouseEvent) => e.stopPropagation()
return (
<Stack
flex={1}
spacing={1}
onMouseUpCapture={handleMouseUp}
onClick={stopPropagating}
>
<Stack flex={1} spacing={1} onClick={stopPropagating}>
<Flex
h={expandedPlaceholderIndex === 0 ? '50px' : '2px'}
bgColor={'gray.400'}
bgColor={'gray.300'}
visibility={showSortPlaceholders ? 'visible' : 'hidden'}
rounded="lg"
transition={showSortPlaceholders ? 'height 200ms' : 'none'}
@ -107,7 +105,7 @@ export const ChoiceItemsList = ({ step }: ChoiceItemsListProps) => {
? '50px'
: '2px'
}
bgColor={'gray.400'}
bgColor={'gray.300'}
visibility={showSortPlaceholders ? 'visible' : 'hidden'}
rounded="lg"
transition={showSortPlaceholders ? 'height 200ms' : 'none'}
@ -118,13 +116,15 @@ export const ChoiceItemsList = ({ step }: ChoiceItemsListProps) => {
<Flex
px="4"
py="2"
bgColor="gray.200"
borderWidth="2px"
borderWidth="1px"
borderColor="gray.300"
bgColor="gray.50"
rounded="md"
pos="relative"
align="center"
cursor="not-allowed"
>
<Text>Default</Text>
<Text color="gray.500">Default</Text>
<SourceEndpoint
source={{
blockId: step.blockId,
@ -140,7 +140,6 @@ export const ChoiceItemsList = ({ step }: ChoiceItemsListProps) => {
<Portal>
<ChoiceItemNodeOverlay
item={draggedChoiceItem}
onMouseUp={handleMouseUp}
pos="fixed"
top="0"
left="0"

View File

@ -0,0 +1,34 @@
import {
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalCloseButton,
ModalBody,
ModalFooter,
ModalBodyProps,
} from '@chakra-ui/react'
import React from 'react'
type Props = {
isOpen: boolean
onClose: () => void
}
export const SettingsModal = ({
isOpen,
onClose,
...props
}: Props & ModalBodyProps) => {
return (
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader />
<ModalCloseButton />
<ModalBody {...props}>{props.children}</ModalBody>
<ModalFooter />
</ModalContent>
</Modal>
)
}

View File

@ -4,7 +4,11 @@ import {
PopoverBody,
useEventListener,
Portal,
Stack,
IconButton,
Flex,
} from '@chakra-ui/react'
import { ExpandIcon } from 'assets/icons'
import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
import {
InputStep,
@ -30,9 +34,10 @@ import { SetVariableSettingsBody } from './bodies/SetVariableSettingsBody'
type Props = {
step: Step
onExpandClick: () => void
}
export const SettingsPopoverContent = ({ step }: Props) => {
export const SettingsPopoverContent = ({ step, onExpandClick }: Props) => {
const ref = useRef<HTMLDivElement | null>(null)
const handleMouseDown = (e: React.MouseEvent) => e.stopPropagation()
@ -44,15 +49,33 @@ export const SettingsPopoverContent = ({ step }: Props) => {
<Portal>
<PopoverContent onMouseDown={handleMouseDown}>
<PopoverArrow />
<PopoverBody p="6" overflowY="scroll" maxH="400px" ref={ref}>
<SettingsPopoverBodyContent step={step} />
<PopoverBody
px="6"
pb="6"
pt="4"
overflowY="scroll"
maxH="400px"
ref={ref}
shadow="lg"
>
<Stack>
<Flex justifyContent="flex-end">
<IconButton
aria-label="expand"
icon={<ExpandIcon />}
size="xs"
onClick={onExpandClick}
/>
</Flex>
<StepSettings step={step} />
</Stack>
</PopoverBody>
</PopoverContent>
</Portal>
)
}
const SettingsPopoverBodyContent = ({ step }: Props) => {
export const StepSettings = ({ step }: { step: Step }) => {
const { updateStep } = useTypebot()
const handleOptionsChange = (options: StepOptions) =>
updateStep(step.id, { options } as Partial<InputStep>)

View File

@ -107,22 +107,20 @@ export const ComparisonsList = ({
>
<Stack
key={comparisonId}
bgColor="blue.50"
p="4"
rounded="md"
flex="1"
borderWidth="1px"
>
<VariableSearchInput
initialVariableId={comparisons.byId[comparisonId].variableId}
onSelectVariable={handleVariableSelected(comparisonId)}
bgColor="white"
placeholder="Search for a variable"
/>
<DropdownList<ComparisonOperators>
currentItem={comparisons.byId[comparisonId].comparisonOperator}
onItemSelect={handleComparisonOperatorSelected(comparisonId)}
items={Object.values(ComparisonOperators)}
bgColor="white"
/>
{comparisons.byId[comparisonId].comparisonOperator !==
ComparisonOperators.IS_SET && (
@ -130,7 +128,6 @@ export const ComparisonsList = ({
delay={100}
initialValue={comparisons.byId[comparisonId].value ?? ''}
onChange={handleValueChange(comparisonId)}
bgColor="white"
placeholder="Type a value..."
/>
)}
@ -141,16 +138,22 @@ export const ComparisonsList = ({
aria-label="Remove comparison"
onClick={deleteComparison(comparisonId)}
pos="absolute"
left="-10px"
top="-10px"
left="-15px"
top="-15px"
size="sm"
shadow="md"
/>
</Fade>
</Flex>
</>
))}
<Button leftIcon={<PlusIcon />} onClick={createComparison} flexShrink={0}>
Add
<Button
leftIcon={<PlusIcon />}
onClick={createComparison}
flexShrink={0}
colorScheme="blue"
>
Add a comparison
</Button>
</Stack>
)

View File

@ -87,16 +87,22 @@ export const ExtractCellList = ({
aria-label="Remove cell"
onClick={deleteCell(cellId)}
pos="absolute"
left="-10px"
top="-10px"
left="-15px"
top="-15px"
size="sm"
shadow="md"
/>
</Fade>
</Flex>
</>
))}
<Button leftIcon={<PlusIcon />} onClick={createCell} flexShrink={0}>
Add
<Button
leftIcon={<PlusIcon />}
onClick={createCell}
flexShrink={0}
colorScheme="blue"
>
Add a value
</Button>
</Stack>
)
@ -118,12 +124,11 @@ export const CellWithVariableIdStack = ({
onCellChange({ ...cell, variableId: variable.id })
}
return (
<Stack bgColor="blue.50" p="4" rounded="md" flex="1">
<Stack p="4" rounded="md" flex="1" borderWidth="1px">
<DropdownList<string>
currentItem={cell.column}
onItemSelect={handleColumnSelect}
items={columns}
bgColor="white"
placeholder="Select a column"
/>
<VariableSearchInput

View File

@ -87,16 +87,22 @@ export const UpdateCellList = ({
aria-label="Remove cell"
onClick={deleteCell(cellId)}
pos="absolute"
left="-10px"
top="-10px"
left="-15px"
top="-15px"
size="sm"
shadow="md"
/>
</Fade>
</Flex>
</>
))}
<Button leftIcon={<PlusIcon />} onClick={createCell} flexShrink={0}>
Add
<Button
leftIcon={<PlusIcon />}
onClick={createCell}
flexShrink={0}
colorScheme="blue"
>
Add a value
</Button>
</Stack>
)
@ -118,12 +124,11 @@ export const CellWithValueStack = ({
onCellChange({ ...cell, value })
}
return (
<Stack bgColor="blue.50" p="4" rounded="md" flex="1">
<Stack p="4" rounded="md" flex="1" borderWidth="1px">
<DropdownList<string>
currentItem={cell.column}
onItemSelect={handleColumnSelect}
items={columns}
bgColor="white"
placeholder="Select a column"
/>
<InputWithVariable

View File

@ -1,4 +1,4 @@
import { Box, BoxProps } from '@chakra-ui/react'
import { Box, BoxProps, Flex } from '@chakra-ui/react'
import { ConnectingSourceIds, useGraph } from 'contexts/GraphContext'
import React, { MouseEvent, useEffect, useRef } from 'react'
@ -28,14 +28,20 @@ export const SourceEndpoint = ({
}, [ref])
return (
<Box
<Flex
ref={ref}
boxSize="15px"
boxSize="18px"
rounded="full"
bgColor="gray.500"
onMouseDown={handleMouseDown}
cursor="pointer"
cursor="copy"
borderWidth="1px"
borderColor="gray.400"
bgColor="white"
justify="center"
align="center"
{...props}
/>
>
<Box bgColor="gray.400" rounded="full" boxSize="7px" />
</Flex>
)
}

View File

@ -4,6 +4,7 @@ import {
HStack,
Popover,
PopoverTrigger,
useDisclosure,
useEventListener,
} from '@chakra-ui/react'
import React, { useEffect, useMemo, useState } from 'react'
@ -28,6 +29,8 @@ import { SourceEndpoint } from './SourceEndpoint'
import { hasDefaultConnector } from 'services/typebots'
import { TargetEndpoint } from './TargetEndpoint'
import { useRouter } from 'next/router'
import { SettingsModal } from './SettingsPopoverContent/SettingsModal'
import { StepSettings } from './SettingsPopoverContent/SettingsPopoverContent'
export const StepNode = ({
step,
@ -54,6 +57,11 @@ export const StepNode = ({
const [isEditing, setIsEditing] = useState<boolean>(
isTextBubbleStep(step) && step.content.plainText === ''
)
const {
isOpen: isModalOpen,
onOpen: onModalOpen,
onClose: onModalClose,
} = useDisclosure()
useEffect(() => {
setIsConnecting(
@ -190,8 +198,8 @@ export const StepNode = ({
flex="1"
userSelect="none"
p="3"
borderWidth="2px"
borderColor={isConnecting || isOpened ? 'blue.400' : 'gray.400'}
borderWidth="1px"
borderColor={isConnecting || isOpened ? 'blue.400' : 'gray.300'}
rounded="lg"
cursor={'pointer'}
bgColor="white"
@ -213,7 +221,7 @@ export const StepNode = ({
}}
pos="absolute"
right="15px"
top="19px"
top="18px"
/>
)}
</HStack>
@ -237,7 +245,12 @@ export const StepNode = ({
)}
</Flex>
</PopoverTrigger>
{hasPopover(step) && <SettingsPopoverContent step={step} />}
{hasPopover(step) && (
<SettingsPopoverContent step={step} onExpandClick={onModalOpen} />
)}
<SettingsModal isOpen={isModalOpen} onClose={onModalClose}>
<StepSettings step={step} />
</SettingsModal>
</Popover>
)}
</ContextMenu>

View File

@ -16,6 +16,7 @@ export const StepNodeOverlay = ({
cursor={'grab'}
w="264px"
pointerEvents="none"
shadow="lg"
{...props}
>
<StepIcon type={step.type} />