feat: modify pivot style & add operation menu to pivot item (#1726)

This commit is contained in:
Qi
2023-03-28 18:16:47 +08:00
committed by GitHub
parent 99be6183e6
commit 751ad9716f
22 changed files with 374 additions and 122 deletions

View File

@@ -1,13 +1,18 @@
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { useDrag, useDrop } from 'react-dnd';
import {
StyledCollapse,
StyledNodeLine,
StyledTreeNodeContainer,
StyledTreeNodeItem,
StyledTreeNodeWrapper,
} from './styles';
import type { Node, NodeLIneProps, TreeNodeProps } from './types';
import type {
Node,
NodeLIneProps,
TreeNodeItemProps,
TreeNodeProps,
} from './types';
const NodeLine = <N,>({
node,
@@ -39,30 +44,21 @@ const NodeLine = <N,>({
return <StyledNodeLine ref={drop} show={isOver && allowDrop} isTop={isTop} />;
};
export const TreeNode = <N,>({
const TreeNodeItem = <N,>({
node,
index,
allDrop = true,
allowDrop,
collapsed,
setCollapsed,
...otherProps
}: TreeNodeProps<N>) => {
const { onAdd, onDelete, onDrop, indent } = otherProps;
const [collapsed, setCollapsed] = useState(false);
const [{ isDragging }, drag] = useDrag(() => ({
type: 'node',
item: node,
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
}));
}: TreeNodeItemProps<N>) => {
const { onAdd, onDelete, onDrop } = otherProps;
const [{ canDrop, isOver }, drop] = useDrop(
() => ({
accept: 'node',
drop: (item: Node<N>, monitor) => {
const didDrop = monitor.didDrop();
if (didDrop || item.id === node.id || !allDrop) {
if (didDrop || item.id === node.id || !allowDrop) {
return;
}
onDrop?.(item, node, {
@@ -73,42 +69,75 @@ export const TreeNode = <N,>({
},
collect: monitor => ({
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
canDrop: monitor.canDrop() && allowDrop,
}),
}),
[onDrop, allDrop]
[onDrop, allowDrop]
);
useEffect(() => {
if (isOver && canDrop) {
setCollapsed(false);
}
}, [isOver, canDrop]);
return (
<div ref={drop}>
{node.render?.(node, {
isOver: !!(isOver && canDrop),
onAdd: () => onAdd?.(node),
onDelete: () => onDelete?.(node),
collapsed,
setCollapsed,
})}
</div>
);
};
export const TreeNode = <N,>({
node,
index,
allowDrop = true,
...otherProps
}: TreeNodeProps<N>) => {
const { indent } = otherProps;
const [collapsed, setCollapsed] = useState(false);
const [{ isDragging }, drag] = useDrag(() => ({
type: 'node',
item: node,
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
}));
return (
<StyledTreeNodeContainer ref={drag} isDragging={isDragging}>
<StyledTreeNodeItem
ref={drop}
isOver={isOver && !isDragging}
canDrop={canDrop}
>
<StyledTreeNodeWrapper>
{index === 0 && (
<NodeLine
node={node}
{...otherProps}
allowDrop={!isDragging && allDrop}
allowDrop={!isDragging && allowDrop}
isTop={true}
/>
)}
{node.render?.(node, {
onAdd: () => onAdd?.(node),
onDelete: () => onDelete?.(node),
collapsed,
setCollapsed,
})}
<TreeNodeItem
node={node}
index={index}
allowDrop={allowDrop}
collapsed={collapsed}
setCollapsed={setCollapsed}
{...otherProps}
/>
{(!node.children?.length || collapsed) && (
<NodeLine
node={node}
{...otherProps}
allowDrop={!isDragging && allDrop}
allowDrop={!isDragging && allowDrop}
/>
)}
</StyledTreeNodeItem>
</StyledTreeNodeWrapper>
<StyledCollapse in={!collapsed} indent={indent}>
{node.children &&
node.children.map((childNode, index) => (
@@ -116,7 +145,7 @@ export const TreeNode = <N,>({
key={childNode.id}
node={childNode}
index={index}
allDrop={isDragging ? false : allDrop}
allowDrop={isDragging ? false : allowDrop}
{...otherProps}
/>
))}

View File

@@ -1,7 +1,7 @@
import MuiCollapse from '@mui/material/Collapse';
import type { CSSProperties } from 'react';
import { styled } from '../../styles';
import { alpha, styled } from '../../styles';
export const StyledCollapse = styled(MuiCollapse)<{
indent?: CSSProperties['paddingLeft'];
@@ -10,12 +10,8 @@ export const StyledCollapse = styled(MuiCollapse)<{
paddingLeft: indent,
};
});
export const StyledTreeNodeItem = styled('div')<{
isOver?: boolean;
canDrop?: boolean;
}>(({ isOver, canDrop, theme }) => {
export const StyledTreeNodeWrapper = styled('div')(() => {
return {
background: isOver && canDrop ? theme.colors.hoverBackground : '',
position: 'relative',
};
});
@@ -23,6 +19,7 @@ export const StyledTreeNodeContainer = styled('div')<{ isDragging: boolean }>(
({ isDragging, theme }) => {
return {
background: isDragging ? theme.colors.hoverBackground : '',
// opacity: isDragging ? 0.4 : 1,
};
}
);
@@ -32,11 +29,14 @@ export const StyledNodeLine = styled('div')<{ show: boolean; isTop?: boolean }>(
return {
position: 'absolute',
left: '0',
...(isTop ? { top: '0' } : { bottom: '0' }),
...(isTop ? { top: '-1px' } : { bottom: '-1px' }),
width: '100%',
paddingTop: '3px',
borderBottom: '3px solid',
paddingTop: '2x',
borderTop: '2px solid',
borderColor: show ? theme.colors.primaryColor : 'transparent',
boxShadow: show
? `0px 0px 8px ${alpha(theme.colors.primaryColor, 0.35)}`
: 'none',
zIndex: 1,
};
}

View File

@@ -6,6 +6,7 @@ export type Node<N> = {
render?: (
node: Node<N>,
eventsAndStatus: {
isOver: boolean;
onAdd: () => void;
onDelete: () => void;
collapsed: boolean;
@@ -33,9 +34,14 @@ type CommonProps<N> = {
export type TreeNodeProps<N> = {
node: Node<N>;
index: number;
allDrop?: boolean;
allowDrop?: boolean;
} & CommonProps<N>;
export type TreeNodeItemProps<N> = {
collapsed: boolean;
setCollapsed: (collapsed: boolean) => void;
} & TreeNodeProps<N>;
export type TreeViewProps<N> = {
data: Node<N>[];
} & CommonProps<N>;