Add dark mode (#191)

Closes #189
This commit is contained in:
Baptiste Arnaud
2022-12-20 16:55:43 +01:00
committed by GitHub
parent 054cbb3585
commit 3394fa5e0a
77 changed files with 1782 additions and 601 deletions

View File

@@ -3,6 +3,7 @@ import {
HStack,
Popover,
PopoverTrigger,
useColorModeValue,
useDisclosure,
useEventListener,
} from '@chakra-ui/react'
@@ -26,17 +27,17 @@ import { SourceEndpoint } from '../../Endpoints/SourceEndpoint'
import { useRouter } from 'next/router'
import { SettingsModal } from './SettingsPopoverContent/SettingsModal'
import { BlockSettings } from './SettingsPopoverContent/SettingsPopoverContent'
import { TextBubbleEditor } from '../../../../blocks/bubbles/textBubble/components/TextBubbleEditor'
import { TargetEndpoint } from '../../Endpoints'
import { MediaBubblePopoverContent } from './MediaBubblePopoverContent'
import {
NodePosition,
useBlockDnd,
useDragDistance,
useGraph,
} from '../../../providers'
import { ContextMenu } from '@/components/ContextMenu'
import { setMultipleRefs } from '@/utils/helpers'
import { TextBubbleEditor } from '@/features/blocks/bubbles/textBubble'
import {
NodePosition,
useGraph,
useBlockDnd,
useDragDistance,
} from '../../../providers'
import { hasDefaultConnector } from '../../../utils'
export const BlockNode = ({
@@ -50,6 +51,9 @@ export const BlockNode = ({
indices: { blockIndex: number; groupIndex: number }
onMouseDown?: (blockNodePosition: NodePosition, block: DraggableBlock) => void
}) => {
const bg = useColorModeValue('gray.50', 'gray.850')
const previewingBorderColor = useColorModeValue('blue.400', 'blue.300')
const borderColor = useColorModeValue('gray.200', 'gray.800')
const { query } = useRouter()
const {
setConnectingIds,
@@ -165,7 +169,7 @@ export const BlockNode = ({
<ContextMenu<HTMLDivElement>
renderMenu={() => <BlockNodeContextMenu indices={indices} />}
>
{(ref, isOpened) => (
{(ref, isContextMenuOpened) => (
<Popover
placement="left"
isLazy
@@ -186,12 +190,18 @@ export const BlockNode = ({
flex="1"
userSelect="none"
p="3"
borderWidth={isOpened || isPreviewing ? '2px' : '1px'}
borderColor={isOpened || isPreviewing ? 'blue.400' : 'gray.200'}
margin={isOpened || isPreviewing ? '-1px' : 0}
borderWidth={
isContextMenuOpened || isPreviewing ? '2px' : '1px'
}
borderColor={
isContextMenuOpened || isPreviewing
? previewingBorderColor
: borderColor
}
margin={isContextMenuOpened || isPreviewing ? '-1px' : 0}
rounded="lg"
cursor={'pointer'}
bgColor="gray.50"
bg={bg}
align="flex-start"
w="full"
transition="border-color 0.2s"

View File

@@ -1,5 +1,5 @@
import { BlockIcon } from '@/features/editor'
import { StackProps, HStack } from '@chakra-ui/react'
import { StackProps, HStack, useColorModeValue } from '@chakra-ui/react'
import { StartBlock, Block, BlockIndices } from 'models'
import { BlockNodeContent } from './BlockNodeContent/BlockNodeContent'
@@ -13,7 +13,8 @@ export const BlockNodeOverlay = ({
p="3"
borderWidth="1px"
rounded="lg"
bgColor="white"
borderColor={useColorModeValue('gray.200', 'gray.800')}
bgColor={useColorModeValue('gray.50', 'gray.850')}
cursor={'grab'}
w="264px"
pointerEvents="none"

View File

@@ -10,6 +10,8 @@ import { useEffect, useRef, useState } from 'react'
import { useTypebot } from '@/features/editor'
import { BlockNode } from './BlockNode'
import { BlockNodeOverlay } from './BlockNodeOverlay'
import { PlaceholderNode } from '../PlaceholderNode'
import { isDefined } from 'utils'
type Props = {
groupId: string
@@ -49,7 +51,7 @@ export const BlockNodesList = ({
const isDraggingOnCurrentGroup =
(draggedBlock || draggedBlockType) && mouseOverGroup?.id === groupId
const showSortPlaceholders =
!isStartGroup && (draggedBlock || draggedBlockType)
!isStartGroup && isDefined(draggedBlock || draggedBlockType)
useEffect(() => {
if (mouseOverGroup?.id !== groupId) setExpandedPlaceholderIndex(undefined)
@@ -126,17 +128,10 @@ export const BlockNodesList = ({
transition="none"
pointerEvents={isReadOnly || isStartGroup ? 'none' : 'auto'}
>
<Flex
ref={handlePushElementRef(0)}
h={
showSortPlaceholders && expandedPlaceholderIndex === 0
? '50px'
: '2px'
}
bgColor={'gray.300'}
visibility={showSortPlaceholders ? 'visible' : 'hidden'}
rounded="lg"
transition={showSortPlaceholders ? 'height 200ms' : 'none'}
<PlaceholderNode
isVisible={showSortPlaceholders}
isExpanded={expandedPlaceholderIndex === 0}
onRef={handlePushElementRef(0)}
/>
{typebot &&
blocks.map((block, idx) => (
@@ -148,17 +143,10 @@ export const BlockNodesList = ({
isConnectable={blocks.length - 1 === idx}
onMouseDown={handleBlockMouseDown(idx)}
/>
<Flex
ref={handlePushElementRef(idx + 1)}
h={
showSortPlaceholders && expandedPlaceholderIndex === idx + 1
? '50px'
: '2px'
}
bgColor={'gray.300'}
visibility={showSortPlaceholders ? 'visible' : 'hidden'}
rounded="lg"
transition={showSortPlaceholders ? 'height 200ms' : 'none'}
<PlaceholderNode
isVisible={showSortPlaceholders}
isExpanded={expandedPlaceholderIndex === idx + 1}
onRef={handlePushElementRef(idx + 1)}
/>
</Stack>
))}

View File

@@ -4,6 +4,7 @@ import {
EditablePreview,
IconButton,
Stack,
useColorModeValue,
} from '@chakra-ui/react'
import React, { memo, useCallback, useEffect, useRef, useState } from 'react'
import { Group } from 'models'
@@ -52,6 +53,10 @@ const NonMemoizedDraggableGroupNode = ({
groupIndex,
onGroupDrag,
}: Props & { onGroupDrag: (newCoord: Coordinates) => void }) => {
const bg = useColorModeValue('white', 'gray.900')
const previewingBorderColor = useColorModeValue('blue.400', 'blue.300')
const borderColor = useColorModeValue('white', 'gray.800')
const editableHoverBg = useColorModeValue('gray.100', 'gray.700')
const {
connectingIds,
setConnectingIds,
@@ -172,16 +177,20 @@ const NonMemoizedDraggableGroupNode = ({
renderMenu={() => <GroupNodeContextMenu groupIndex={groupIndex} />}
isDisabled={isReadOnly || isStartGroup}
>
{(ref, isOpened) => (
{(ref, isContextMenuOpened) => (
<Stack
ref={setMultipleRefs([ref, groupRef])}
data-testid="group"
p="4"
rounded="xl"
bgColor="#ffffff"
borderWidth="2px"
bg={bg}
borderWidth={
isConnecting || isContextMenuOpened || isPreviewing ? '2px' : '1px'
}
borderColor={
isConnecting || isOpened || isPreviewing ? 'blue.400' : '#ffffff'
isConnecting || isContextMenuOpened || isPreviewing
? previewingBorderColor
: borderColor
}
w="300px"
transition="border 300ms, box-shadow 200ms"
@@ -208,7 +217,9 @@ const NonMemoizedDraggableGroupNode = ({
pr="8"
>
<EditablePreview
_hover={{ bgColor: 'gray.200' }}
_hover={{
bg: editableHoverBg,
}}
px="1"
userSelect={'none'}
/>

View File

@@ -1,4 +1,4 @@
import { Flex } from '@chakra-ui/react'
import { Flex, useColorModeValue } from '@chakra-ui/react'
import {
Coordinates,
useGraph,
@@ -30,6 +30,9 @@ export const ItemNode = ({
onMouseDown,
connectionDisabled,
}: Props) => {
const previewingBorderColor = useColorModeValue('blue.400', 'blue.300')
const borderColor = useColorModeValue('gray.200', 'gray.700')
const bg = useColorModeValue('white', undefined)
const { typebot } = useTypebot()
const { previewingEdge } = useGraph()
const [isMouseOver, setIsMouseOver] = useState(false)
@@ -59,7 +62,7 @@ export const ItemNode = ({
<ContextMenu<HTMLDivElement>
renderMenu={() => <ItemNodeContextMenu indices={indices} />}
>
{(ref, isOpened) => (
{(ref, isContextMenuOpened) => (
<Flex
data-testid="item"
pos="relative"
@@ -74,10 +77,14 @@ export const ItemNode = ({
_hover={{ shadow: 'md' }}
transition="box-shadow 200ms, border-color 200ms"
rounded="md"
borderWidth={isOpened || isPreviewing ? '2px' : '1px'}
borderColor={isOpened || isPreviewing ? 'blue.400' : 'gray.100'}
margin={isOpened || isPreviewing ? '-1px' : 0}
bgColor="white"
bg={bg}
borderWidth={isContextMenuOpened || isPreviewing ? '2px' : '1px'}
borderColor={
isContextMenuOpened || isPreviewing
? previewingBorderColor
: borderColor
}
margin={isContextMenuOpened || isPreviewing ? '-1px' : 0}
w="full"
>
<ItemNodeContent

View File

@@ -1,4 +1,4 @@
import { Flex, FlexProps } from '@chakra-ui/react'
import { Flex, FlexProps, useColorModeValue } from '@chakra-ui/react'
import { Item } from 'models'
import React, { ReactNode } from 'react'
@@ -12,9 +12,9 @@ export const ItemNodeOverlay = ({ item, ...props }: Props) => {
px="4"
py="2"
rounded="md"
bgColor="white"
bgColor={useColorModeValue('white', 'gray.850')}
borderWidth="1px"
borderColor={'gray.300'}
borderColor={useColorModeValue('gray.200', 'gray.700')}
w="212px"
pointerEvents="none"
shadow="lg"

View File

@@ -1,4 +1,11 @@
import { Flex, Portal, Stack, Text, useEventListener } from '@chakra-ui/react'
import {
Flex,
Portal,
Stack,
Text,
useColorModeValue,
useEventListener,
} from '@chakra-ui/react'
import {
computeNearestPlaceholderIndex,
useBlockDnd,
@@ -10,6 +17,8 @@ import { BlockIndices, BlockWithItems, LogicBlockType, Item } from 'models'
import React, { useEffect, useRef, useState } from 'react'
import { ItemNode } from './ItemNode'
import { SourceEndpoint } from '../../Endpoints'
import { ItemNodeOverlay } from './ItemNodeOverlay'
import { PlaceholderNode } from '../PlaceholderNode'
type Props = {
block: BlockWithItems
@@ -121,13 +130,10 @@ export const ItemNodesList = ({
return (
<Stack flex={1} spacing={1} maxW="full" onClick={stopPropagating}>
<Flex
ref={handlePushElementRef(0)}
h={showPlaceholders && expandedPlaceholderIndex === 0 ? '50px' : '2px'}
bgColor={'gray.300'}
visibility={showPlaceholders ? 'visible' : 'hidden'}
rounded="lg"
transition={showPlaceholders ? 'height 200ms' : 'none'}
<PlaceholderNode
isVisible={showPlaceholders}
isExpanded={expandedPlaceholderIndex === 0}
onRef={handlePushElementRef(0)}
/>
{block.items.map((item, idx) => (
<Stack key={item.id} spacing={1}>
@@ -136,45 +142,14 @@ export const ItemNodesList = ({
indices={{ groupIndex, blockIndex, itemIndex: idx }}
onMouseDown={handleBlockMouseDown(idx)}
/>
<Flex
ref={handlePushElementRef(idx + 1)}
h={
showPlaceholders && expandedPlaceholderIndex === idx + 1
? '50px'
: '2px'
}
bgColor={'gray.300'}
visibility={showPlaceholders ? 'visible' : 'hidden'}
rounded="lg"
transition={showPlaceholders ? 'height 200ms' : 'none'}
<PlaceholderNode
isVisible={showPlaceholders}
isExpanded={expandedPlaceholderIndex === idx + 1}
onRef={handlePushElementRef(idx + 1)}
/>
</Stack>
))}
{isLastBlock && (
<Flex
px="4"
py="2"
borderWidth="1px"
borderColor="gray.300"
bgColor={'gray.50'}
rounded="md"
pos="relative"
align="center"
cursor="not-allowed"
>
<Text color="gray.500">
{block.type === LogicBlockType.CONDITION ? 'Else' : 'Default'}
</Text>
<SourceEndpoint
source={{
groupId: block.groupId,
blockId: block.id,
}}
pos="absolute"
right="-49px"
/>
</Flex>
)}
{isLastBlock && <DefaultItemNode block={block} />}
{draggedItem && draggedItem.blockId === block.id && (
<Portal>
@@ -189,14 +164,38 @@ export const ItemNodesList = ({
w="220px"
transformOrigin="0 0 0"
>
<ItemNode
item={draggedItem}
indices={{ groupIndex, blockIndex, itemIndex: 0 }}
connectionDisabled
/>
<ItemNodeOverlay item={draggedItem} />
</Flex>
</Portal>
)}
</Stack>
)
}
const DefaultItemNode = ({ block }: { block: BlockWithItems }) => {
return (
<Flex
px="4"
py="2"
borderWidth="1px"
borderColor={useColorModeValue('gray.300', undefined)}
bgColor={useColorModeValue('gray.50', 'gray.850')}
rounded="md"
pos="relative"
align="center"
cursor="not-allowed"
>
<Text color="gray.500">
{block.type === LogicBlockType.CONDITION ? 'Else' : 'Default'}
</Text>
<SourceEndpoint
source={{
groupId: block.groupId,
blockId: block.id,
}}
pos="absolute"
right="-49px"
/>
</Flex>
)
}

View File

@@ -0,0 +1,21 @@
import { Flex, useColorModeValue } from '@chakra-ui/react'
import React from 'react'
type Props = {
isVisible: boolean
isExpanded: boolean
onRef: (ref: HTMLDivElement) => void
}
export const PlaceholderNode = ({ isVisible, isExpanded, onRef }: Props) => {
return (
<Flex
ref={onRef}
h={isExpanded ? '50px' : '2px'}
bgColor={useColorModeValue('gray.300', 'gray.700')}
visibility={isVisible ? 'visible' : 'hidden'}
rounded="lg"
transition={isVisible ? 'height 200ms' : 'none'}
/>
)
}