From 08138b612c2e6e40a4a3ec8aad2ded5fe345bd6b Mon Sep 17 00:00:00 2001 From: cc <33281802+matuancc@users.noreply.github.com> Date: Sat, 16 Jul 2022 17:30:07 +0800 Subject: [PATCH] =?UTF-8?q?refactor(tree):=20=E9=87=8D=E6=9E=84tree?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20(#878=EF=BC=8C#845)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react-tree/src/TreeNode.tsx | 44 ++++-- packages/react-tree/src/index.tsx | 7 +- packages/react-tree/src/style/index.ts | 183 +++++++++++++++++++++++++ 3 files changed, 219 insertions(+), 15 deletions(-) create mode 100644 packages/react-tree/src/style/index.ts diff --git a/packages/react-tree/src/TreeNode.tsx b/packages/react-tree/src/TreeNode.tsx index 5bd0fb3760..b7b85f6b8b 100644 --- a/packages/react-tree/src/TreeNode.tsx +++ b/packages/react-tree/src/TreeNode.tsx @@ -3,6 +3,14 @@ import { CSSTransition } from 'react-transition-group'; import Icon, { IconProps } from '@uiw/react-icon'; import { IProps, noop } from '@uiw/utils'; import { TreeData, TreeProps, getChildKeys } from './'; +import { + CSSTransitionWarp, + TreeNodeUl, + TreeNodeUlLidiv, + TreeNodeUlLidivSpan, + TreeNodeUlLidivSpanIcon, + TreeNodeUlLidivSpanDiv, +} from './style/index'; interface TreeNodeIconProps { isOpen: boolean; @@ -21,6 +29,7 @@ interface DisabledObj { interface TreeNodeProps IconProps['type']> extends IProps { data: TreeData[]; level: number; + isOpen?: boolean; parent?: TreeData; icon?: T; iconAnimation?: boolean; @@ -79,7 +88,8 @@ export default function TreeNode(props: TreeNodeProps) { }, []); return ( - (props: TreeNodeProps) { onEntered={onEntered} onEntering={onEntering} > -
    (props: TreeNodeProps) { } return (
  • -
    - + onItemClick(item, evn)} + onClick={(evn: React.MouseEvent) => onItemClick(item, evn)} > - (props: TreeNodeProps) { .join(' ') .trim()} /> - -
    + disabledObj.onClick?.(item, evn)} + judgeSelected={selected} + judgeisSelected={isSelected} + isDisabled={disabledObj.disabled} className={[ `${prefixCls}-title`, selected && isSelected ? 'selected' : null, @@ -178,8 +198,8 @@ export default function TreeNode(props: TreeNodeProps) { ) : (
    -
    + + {item.children && ( (props: TreeNodeProps) {
  • ); })} -
-
+ + ); } diff --git a/packages/react-tree/src/index.tsx b/packages/react-tree/src/index.tsx index f599402a53..f5eee248b4 100644 --- a/packages/react-tree/src/index.tsx +++ b/packages/react-tree/src/index.tsx @@ -2,7 +2,8 @@ import React, { useEffect, useState } from 'react'; import { IconProps } from '@uiw/react-icon'; import { IProps, HTMLDivProps, noop } from '@uiw/utils'; import TreeNode from './TreeNode'; -import './style/index.less'; +// import './style/index.less'; +import { TreeNodeDiv } from './style/index'; export type TreeRenderTitleNode = { selected?: boolean; @@ -219,7 +220,7 @@ export default function Tree(props: TreeProps) { onChange?.(item.key, selKeys); } return ( -
+ -
+ ); } diff --git a/packages/react-tree/src/style/index.ts b/packages/react-tree/src/style/index.ts new file mode 100644 index 0000000000..0ed7e2c1e9 --- /dev/null +++ b/packages/react-tree/src/style/index.ts @@ -0,0 +1,183 @@ +import styled, { css } from 'styled-components'; +import { getThemeVariantValue } from '@uiw/utils'; +import { TreeRenderTitleNode, TreeProps } from '../index'; + +interface CSSTransitionWarpProps extends TreeRenderTitleNode { + defaultTheme?: Record; + isOpen: boolean; + level: number; +} +interface TreeNodeUlLidivProps { + defaultTheme?: Record; +} + +interface TreeNodeUlLidivSpanIconProps { + defaultTheme?: Record; + isIcon?: string; + isNoChild?: boolean; + isIconAnimation?: boolean; + isItemIsOpen?: boolean; +} +interface TreeNodeUlLidivSpanDivProps { + judgeSelected?: boolean; + judgeisSelected?: boolean; + isDisabled?: string | null; +} +interface TreeNodeDivProps extends TreeProps { + defaultTheme?: Record; +} + +export const CSSTransitionWarp = styled.div` + font-size: ${(props) => getThemeVariantValue(props, 'fontSizeCSSTransitionWarpDefault')}; +`; + +CSSTransitionWarp.defaultProps = { + defaultTheme: { + fontSizeCSSTransitionWarpDefault: '14px', + }, +}; + +export const TreeNodeUl = styled.ul` + padding: 0 !important; + transition: 0.3s all; + overflow: hidden; + margin: 0; + ul { + padding-left: 18px !important; + margin-bottom: 0; + } + li { + list-style: none !important; + & + li { + margin-top: 2px !important; + } + &:first-child { + padding-top: 3px; + } + } + + ${(props) => props.level !== 1 && props.isOpen && css``} + + ${(props) => + props.level !== 1 && + !props.isOpen && + css` + height: 0; + `} +`; + +export const TreeNodeUlLidiv = styled.div` + line-height: initial; + & > * { + vertical-align: middle; + } +`; + +export const TreeNodeUlLidivSpan = styled.div` + cursor: pointer; + position: relative; + z-index: 1; + width: 14px; + height: 14px; + line-height: 14px; + display: inline-block; + text-align: center; + &:hover { + color: ${(props) => getThemeVariantValue(props, 'colorTreeNodeUlLidivSpanDefault')}; + } + .w-icon { + transition: 0.3s all; + transform: ${(props) => getThemeVariantValue(props, 'transformTreeNodeUlLidivSpanDefault')}; + } +`; + +TreeNodeUlLidivSpan.defaultProps = { + defaultTheme: { + colorTreeNodeUlLidivSpanDefault: '#2ea3f4', + transformTreeNodeUlLidivSpanDefault: 'scale(0.79) rotate(0deg)', + }, +}; + +export const TreeNodeUlLidivSpanIcon = styled.div` + ${(props) => + props.isNoChild && + !props.isIcon && + css` + display: none; + `} + + ${(props) => + props.isItemIsOpen && + props.isIconAnimation && + css` + transform: ${(props) => getThemeVariantValue(props, 'transformTreeNodeUlLidivSpanIconDefault')}; + `} +`; + +TreeNodeUlLidivSpanIcon.defaultProps = { + defaultTheme: { + transformTreeNodeUlLidivSpanIconDefault: 'scale(0.79) rotate(90deg) !important;', + }, +}; + +export const TreeNodeUlLidivSpanDiv = styled.div` + display: inline-block; + padding: 2px 5px; + cursor: pointer; + + ${(props) => + props.judgeSelected && + props.judgeisSelected && + css` + background-color: #d5e8fc; + `} + + ${(props) => + props.judgeSelected && + css` + cursor: not-allowed; + `} + + > * { + vertical-align: middle; + } +`; + +export const TreeNodeDiv = styled.div` + li { + position: relative; + li { + &:before, + &::after { + content: ' '; + border-left: 1px solid #d9d9d9; + left: -12px; + position: absolute; + } + &::after { + height: 100%; + top: 5px; + } + &:last-child::after { + height: 16px; + top: -18px; + } + &:before { + content: ' '; + width: 10px; + height: 16px; + border-bottom: 1px solid #d9d9d9; + top: -2px; + } + &:last-child::before { + border-radius: ${(props) => getThemeVariantValue(props, 'borderRadiusTreeNodeDivDefault')}; + } + } + } +`; + +TreeNodeDiv.defaultProps = { + defaultTheme: { + borderRadiusTreeNodeDivDefault: '0 0 0 3px;', + }, +};