structure tree can toggle show children & hide slotName

This commit is contained in:
Bowen Tan 2021-10-15 15:13:18 +08:00
parent 259db6be0f
commit 7ab90ca6ec
3 changed files with 88 additions and 26 deletions

View File

@ -1,27 +1,53 @@
import { DeleteIcon } from '@chakra-ui/icons';
import { HStack, IconButton, Text } from '@chakra-ui/react';
import { ChevronDownIcon, ChevronRightIcon, DeleteIcon } from '@chakra-ui/icons';
import { Box, HStack, IconButton, Text } from '@chakra-ui/react';
type Props = {
title: string;
isSelected: boolean;
onClick: () => void;
onClickRemove: () => void;
noChevron: boolean;
isExpanded?: boolean;
onToggleExpanded?: () => void;
};
export const ComponentItemView: React.FC<Props> = props => {
const { title, isSelected, onClick, onClickRemove } = props;
const {
title,
isSelected,
noChevron,
isExpanded,
onClick,
onToggleExpanded,
onClickRemove,
} = props;
const expandIcon = (
<IconButton
position="absolute"
left="-5"
aria-label="showChildren"
size="xs"
variant="unstyled"
onClick={onToggleExpanded}
icon={isExpanded ? <ChevronDownIcon /> : <ChevronRightIcon />}
/>
);
return (
<HStack width="full" justify="space-between">
<Text color={isSelected ? 'red.500' : 'black'} onClick={onClick}>
{title}
</Text>
<IconButton
variant="ghost"
size="sm"
aria-label="remove"
icon={<DeleteIcon />}
onClick={onClickRemove}
/>
</HStack>
<Box width="full">
{noChevron ? null : expandIcon}
<HStack width="full" justify="space-between">
<Text color={isSelected ? 'red.500' : 'black'} onClick={onClick}>
{title}
</Text>
<IconButton
variant="ghost"
size="smx"
aria-label="remove"
icon={<DeleteIcon />}
onClick={onClickRemove}
/>
</HStack>
</Box>
);
};

View File

@ -1,6 +1,6 @@
import { Box, Text } from '@chakra-ui/react';
import { Box, Text, VStack } from '@chakra-ui/react';
import { ApplicationComponent } from '@meta-ui/core';
import React, { useMemo } from 'react';
import React, { useMemo, useState } from 'react';
import { eventBus } from '../../eventBus';
import { registry } from '../../metaUI';
import {
@ -20,6 +20,7 @@ type Props = {
export const ComponentTree: React.FC<Props> = props => {
const { component, childrenMap, selectedComponentId, onSelectComponent } = props;
const slots = registry.getComponentByType(component.type).spec.slots;
const [isExpanded, setIsExpanded] = useState(true);
const slotsEle = useMemo(() => {
if (slots.length === 0) {
@ -49,6 +50,8 @@ export const ComponentTree: React.FC<Props> = props => {
);
}
const onDrop = (e: React.DragEvent) => {
e.stopPropagation();
e.preventDefault();
const creatingComponent = e.dataTransfer?.getData('component') || '';
eventBus.send(
@ -56,12 +59,21 @@ export const ComponentTree: React.FC<Props> = props => {
new CreateComponentOperation(creatingComponent, component.id, slot)
);
};
const slotName = (
<Text color="gray.500" fontWeight="medium" onDrop={onDrop}>
Slot: {slot}
</Text>
);
return (
<Box key={slot} paddingLeft="6">
<Text color="gray.500" fontWeight="medium" onDrop={onDrop}>
Slot: {slot}
</Text>
{slotContent}
<Box key={slot} paddingLeft="5" width="full" onDrop={onDrop}>
{/* although component can have multiple slots, but for now, most components have only one slot
so we hide slot name to save more view area */}
{slots.length > 1 ? slotName : null}
<VStack spacing="2" width="full" alignItems="start">
{slotContent}
</VStack>
</Box>
);
});
@ -71,8 +83,28 @@ export const ComponentTree: React.FC<Props> = props => {
eventBus.send('operation', new RemoveComponentOperation(component.id));
};
const onDropInComponent = (e: React.DragEvent) => {
e.stopPropagation();
e.preventDefault();
if (slots.length === 0) return;
const creatingComponent = e.dataTransfer?.getData('component') || '';
eventBus.send(
'operation',
new CreateComponentOperation(creatingComponent, component.id, 'content')
);
};
return (
<Box key={component.id} width="full">
<VStack
key={component.id}
position="relative"
spacing="2"
width="full"
alignItems="start"
onDrop={onDropInComponent}
>
<ComponentItemView
title={component.id}
isSelected={component.id === selectedComponentId}
@ -80,8 +112,11 @@ export const ComponentTree: React.FC<Props> = props => {
onSelectComponent(component.id);
}}
onClickRemove={onClickRemove}
noChevron={slots.length === 0}
isExpanded={isExpanded}
onToggleExpanded={() => setIsExpanded(prev => !prev)}
/>
{slotsEle}
</Box>
{isExpanded ? slotsEle : null}
</VStack>
);
};

View File

@ -66,12 +66,13 @@ export const StructureTree: React.FC<Props> = props => {
onSelectComponent(dummy.id);
}}
onClickRemove={onClickRemove}
noChevron={true}
/>
);
});
return (
<VStack spacing="2" padding="4" alignItems="start">
<VStack spacing="2" padding="5" alignItems="start">
<Text fontSize="lg" fontWeight="bold">
Components
</Text>