Skip to content

Commit

Permalink
feat: 增加子节点展开相关参数expandAll、expandable、onExpand
Browse files Browse the repository at this point in the history
  • Loading branch information
twp0217 committed Sep 9, 2021
1 parent 0cf161a commit 7ec0223
Show file tree
Hide file tree
Showing 14 changed files with 200 additions and 37 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# 1.0.0 (2021-09-08)

### Features

- 上传版本 1.0.0 ([63060e9](https://github.com/twp0217/react-org-chart/commit/63060e98760e60fd185933b0728beb07544a74e9))
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,13 @@ export default () => {

### OrgChartProps

| 名称 | 类型 | 默认值 | 说明 |
| ---------- | --------------------------------------------------------------------- | ------ | -------------- |
| data | NodeDataType | - | 数据 |
| className | string | - | 类名 |
| style | React.CSSProperties | - | 样式 |
| renderNode | (node: NodeDataType, originNode: React.ReactNode) => React.ReactNode; | - | 自定义渲染节点 |
| onClick | (node: NodeDataType) => void | - | 点击事件 |
| 名称 | 类型 | 默认值 | 说明 |
| ---------- | --------------------------------------------------------------------- | ------ | --------------------- |
| data | NodeDataType | - | 数据 |
| className | string | - | 类名 |
| style | React.CSSProperties | - | 样式 |
| expandAll | boolean | true | 是否展开所有子节点 |
| expandable | boolean | false | 是否允许子节点展开 |
| renderNode | (node: NodeDataType, originNode: React.ReactNode) => React.ReactNode; | - | 自定义渲染节点 |
| onExpand | (expanded: boolean, node: NodeDataType) => void | - | 展开/收起节点时的回调 |
| onClick | (node: NodeDataType) => void | - | 点击节点时的回调 |
4 changes: 4 additions & 0 deletions docs/demo/basic.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
order: 1
---

## basic

<code src="../examples/basic.tsx" />
4 changes: 4 additions & 0 deletions docs/demo/event.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
order: 9
---

## event

<code src="../examples/event.tsx" />
7 changes: 7 additions & 0 deletions docs/demo/expandAll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
order: 3
---

## expandAll

<code src="../examples/expandAll.tsx" />
7 changes: 7 additions & 0 deletions docs/demo/expandable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
order: 2
---

## expandable

<code src="../examples/expandable.tsx" />
6 changes: 5 additions & 1 deletion docs/examples/event.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ export default () => {
console.log('onClick', node);
};

const onExpand = (expanded: boolean, node: NodeDataType) => {
console.log('onExpand', expanded, node);
};

return (
<div
style={{
overflow: 'auto',
textAlign: 'center',
}}
>
<OrgChart data={data} onClick={onClick} />
<OrgChart data={data} expandable onClick={onClick} onExpand={onExpand} />
</div>
);
};
45 changes: 45 additions & 0 deletions docs/examples/expandAll.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import OrgChart, { NodeDataType } from '@twp0217/react-org-chart';

export default () => {
const data: NodeDataType = {
key: 0,
label: '科技有限公司',
children: [
{
key: 1,
label: '研发部',
children: [
{ key: 11, label: '开发-前端' },
{ key: 12, label: '开发-后端' },
{ key: 13, label: 'UI设计' },
{ key: 14, label: '产品经理' },
],
},
{
key: 2,
label: '销售部',
children: [
{ key: 21, label: '销售一部' },
{ key: 22, label: '销售二部' },
],
},
{ key: 3, label: '财务部' },
{ key: 4, label: '人事部' },
],
};

const [expandAll, setExpandAll] = React.useState<boolean>(false);

return (
<div>
<div>
<button onClick={() => setExpandAll(!expandAll)}>
{expandAll ? '收起' : '展开'}
</button>
</div>
<br />
<OrgChart expandable data={data} expandAll={expandAll} />
</div>
);
};
8 changes: 8 additions & 0 deletions docs/examples/expandable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import OrgChart from '@twp0217/react-org-chart';

export default () => {
const data = require('./data.json');

return <OrgChart data={data} expandable />;
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@twp0217/react-org-chart",
"version": "1.0.0",
"version": "1.1.0",
"scripts": {
"start": "dumi dev",
"docs:build": "dumi build",
Expand Down
77 changes: 62 additions & 15 deletions src/OrgChart.module.less
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@node-color: #1890ff;
@line-width: 1px;
@line-color: @node-color;
@expand-icon-size: 16px;

.orgChartContainer {
display: inline-block;
Expand All @@ -12,26 +13,72 @@
line-height: 1.5715;

tr {
&.lines td {
height: 20px;
&.hidden {
display: none !important;
}

.vertical {
width: @line-width;
height: 100%;
background-color: @line-color;
&.lines {
position: relative;

.expand-icon {
display: inline-block;
}
width: @expand-icon-size;
height: @expand-icon-size;
border-radius: 50%;
background-color: @line-color;
position: absolute;
left: 50%;
bottom: 0;
margin-left: -@expand-icon-size / 2;
margin-bottom: -@expand-icon-size / 2;
z-index: 99;
cursor: pointer;

&.left {
border-right: @line-width solid @line-color;
}
&::before {
content: '';
width: 8px;
height: 2px;
background-color: #fff;
position: absolute;
top: 7px;
left: 4px;
}
&::after {
content: '';
width: 2px;
height: 8px;
background-color: #fff;
position: absolute;
top: 4px;
left: 7px;
}

&.right {
border-left: @line-width solid transparent;
&:hover {
background-color: darken(@line-color, 5%);
}
}

&.top {
border-top: @line-width solid @line-color;
td {
height: 20px;

.vertical-line {
width: @line-width;
height: 100%;
background-color: @line-color;
display: inline-block;
}

&.left {
border-right: @line-width solid @line-color;
}

&.right {
border-left: @line-width solid transparent;
}

&.top {
border-top: @line-width solid @line-color;
}
}
}
}
Expand All @@ -44,7 +91,7 @@
.node {
display: inline-block;
border: 1px solid @node-color;
padding: 0 0.5rem;
padding: 0.5rem;
margin: 0 5px;
cursor: pointer;
}
Expand Down
4 changes: 2 additions & 2 deletions src/OrgChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { OrgChartProps } from './interface';
import styles from './OrgChart.module.less';

const OrgChart = (props: OrgChartProps) => {
const { data, className, style, renderNode, onClick } = props;
const { data, className, style, ...otherProps } = props;

return !!data ? (
<div
className={classNames(styles.orgChartContainer, className)}
style={style}
>
<DefaultOrgChart data={data} renderNode={renderNode} onClick={onClick} />
<DefaultOrgChart {...otherProps} data={data} />
</div>
) : null;
};
Expand Down
48 changes: 37 additions & 11 deletions src/components/DefaultOrgChart.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import { NodeDataType, OrgChartComponentProps, RenderNode } from '../interface';
import { NodeDataType, OrgChartComponentProps } from '../interface';
import classNames from 'classnames';
import React from 'react';

const DefaultOrgChart = (props: OrgChartComponentProps) => {
const { data, renderNode: customRenderNode, onClick } = props;
const {
data,
expandAll = true,
expandable = false,
renderNode: customRenderNode,
onExpand,
onClick,
} = props;

const [expanded, setExpanded] = React.useState<boolean>(false);

const childrenLength = data.children?.length || 0;
const colSpan: number = childrenLength * 2;
Expand Down Expand Up @@ -36,14 +45,29 @@ const DefaultOrgChart = (props: OrgChartComponentProps) => {
);
};

/**
* 处理展开
*/
const handleExpandChange = () => {
const newExpanded = !expanded;
setExpanded(newExpanded);
onExpand && onExpand(newExpanded, data);
};

/**
* 渲染垂直线
* @returns
*/
const renderVerticalLine = (): React.ReactNode => {
return (
<td colSpan={colSpan}>
<div className="vertical"></div>
<div className="vertical-line"></div>
{expandable ? (
<div
className="expand-icon"
onClick={() => handleExpandChange()}
></div>
) : null}
</td>
);
};
Expand Down Expand Up @@ -80,17 +104,15 @@ const DefaultOrgChart = (props: OrgChartComponentProps) => {
if (datas.length > 0) {
return (
<>
<tr className="lines">{renderVerticalLine()}</tr>
<tr className="lines">{renderConnectLines()}</tr>
<tr className="nodes">
<tr className={'lines'}>{renderVerticalLine()}</tr>
<tr className={classNames('lines', { hidden: !expanded })}>
{renderConnectLines()}
</tr>
<tr className={classNames('nodes', { hidden: !expanded })}>
{datas.map((data) => {
return (
<td key={data.key} colSpan={2}>
<DefaultOrgChart
data={data}
renderNode={customRenderNode}
onClick={onClick}
/>
<DefaultOrgChart {...props} data={data} />
</td>
);
})}
Expand All @@ -101,6 +123,10 @@ const DefaultOrgChart = (props: OrgChartComponentProps) => {
return;
};

React.useEffect(() => {
setExpanded(expandAll);
}, [expandAll]);

return (
<table>
<tbody>
Expand Down
3 changes: 3 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ export type RenderNode = (

export interface OrgChartComponentProps {
data: NodeDataType;
expandAll?: boolean;
expandable?: boolean;
renderNode?: RenderNode;
onExpand?: (expanded: boolean, node: NodeDataType) => void;
onClick?: (node: NodeDataType) => void;
}

Expand Down

0 comments on commit 7ec0223

Please sign in to comment.