Skip to content

Commit

Permalink
feat(Tree): add renderChildNodes prop (#1273)
Browse files Browse the repository at this point in the history
* feat(Tree): add renderChildNodes prop
  • Loading branch information
myronliu347 authored and youluna committed Nov 14, 2019
1 parent e25e236 commit aede069
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 4 deletions.
81 changes: 81 additions & 0 deletions docs/tree/demo/render-child-nodes.md
@@ -0,0 +1,81 @@
# 平铺叶子节点

- order: 9

当最后一级都是叶子节点时,平铺展示

:::lang=en-us
# Tile leaf nodes

- order: 9

When the last level is all leaf nodes, the tiling display.
:::

---

````jsx
import { Tree } from '@alifd/next';

const TreeNode = Tree.Node;


const formatDataSource = (data) => {
return data.map((it) => {
return {
...it,
key: it.value,
children: formatDataSource(it.children || [])
};
});
}

class Demo extends React.Component {
constructor(props) {
super(props);

this.state = {
data: []
};
}

componentDidMount() {
fetch('https://os.alipayobjects.com/rmsportal/ODDwqcDFTLAguOvWEolX.json')
.then(response => response.json())
.then(data => this.setState({ data: formatDataSource([data[0]]) }))
.catch(e => console.log(e));
}

render() {
return <Tree checkable renderChildNodes={(nodes) => {
if (nodes.filter((node) => !node.props.children || node.props.children.length === 0).length !== nodes.length) {
<ul role="group" className={`next-tree-child-tree`}>
{nodes}
</ul>
}
return <ul role="group" className="next-tree-child-tree custom-leaf-tree">{nodes}</ul>;
}} defaultExpandAll dataSource={this.state.data}/>;
}
}

ReactDOM.render(<Demo />, mountNode);
````

```css
.custom-leaf-tree {
padding-left: 20px;
display: block;
font-size: 0;
white-space: normal;
}
.custom-leaf-tree .next-tree-switcher{
display: none;
}

.custom-leaf-tree .next-tree-node {
margin-left: 0 !important;
margin-right: 8px;
width: 68px;
display: inline-block;
}
```
1 change: 1 addition & 0 deletions docs/tree/index.en-us.md
Expand Up @@ -54,6 +54,7 @@ Folders, organizational structures, taxonomy, countries, regions, etc. Most of t
| isLabelBlock | sets whether or not the node occupies the remaining space, it is generally used to add elements to the right side of each node (base flex, only Internet Explorer 10+ is supported) | Boolean | false |
| isNodeBlock | set whether the node fills a row | Boolean/Object | false |
| animation | whether to enable expand and collapse animation | Boolean | true |
| renderChildNodes | Render child nodes<br><br>**签名**:<br>Function(nodes: Array) => ReactNode<br>**params**:<br>_nodes_: {Array} child nodes<br>**返回值**:<br>{ReactNode} <br> | Function | - |

### Tree.Node

Expand Down
1 change: 1 addition & 0 deletions docs/tree/index.md
Expand Up @@ -55,6 +55,7 @@
| isNodeBlock | 设置节点是否占满一行 | Boolean/Object | false |
| animation | 是否开启展开收起动画 | Boolean | true |
| focusedKey | 当前获得焦点的子菜单或菜单项 key 值 | String | - |
| renderChildNodes | 渲染子节点<br><br>**签名**:<br>Function(nodes: Array) => ReactNode<br>**参数**:<br>_nodes_: {Array} 所有的子节点<br>**返回值**:<br>{ReactNode} 返回节点<br> | Function | - |

### Tree.Node

Expand Down
18 changes: 14 additions & 4 deletions src/tree/view/tree-node.jsx
Expand Up @@ -439,14 +439,24 @@ export default class TreeNode extends Component {

renderChildTree(hasChildTree) {
const { prefix, children, expanded, root } = this.props;
const { animation } = root.props;
const { animation, renderChildNodes } = root.props;

let childTree =
expanded && hasChildTree ? (
if (!expanded || !hasChildTree) {
return null;
}

let childTree;

if (renderChildNodes) {
childTree = renderChildNodes(children);
} else {
childTree = (
<ul role="group" className={`${prefix}tree-child-tree`}>
{children}
</ul>
) : null;
);
}

if (animation) {
childTree = <Expand animationAppear={false}>{childTree}</Expand>;
}
Expand Down
6 changes: 6 additions & 0 deletions src/tree/view/tree.jsx
Expand Up @@ -229,6 +229,12 @@ export default class Tree extends Component {
* 当前获得焦点的子菜单或菜单项 key 值
*/
focusedKey: PropTypes.string,
/**
* 渲染子节点
* @param {Array<ReactNode>} nodes 所有的子节点
* @return {ReactNode} 返回节点
*/
renderChildNodes: PropTypes.func,
focusable: PropTypes.bool,
autoFocus: PropTypes.bool,
onItemFocus: PropTypes.func,
Expand Down
35 changes: 35 additions & 0 deletions test/tree/index-spec.js
Expand Up @@ -284,6 +284,41 @@ describe('Tree', () => {
assertTree({ dataSource }, mountNode);
});

it('should support render child nodes', () => {
ReactDOM.render(
<Tree
checkable
editable
defaultExpandAll
defaultSelectedKeys={['1']}
defaultCheckedKeys={['3']}
renderChildNodes={(nodes) => {
if (
nodes.filter(
(node) => !node.props.children ||
node.props.children.length === 0
).length !== nodes.length) {
return <ul role="group" className={`next-tree-child-tree`}>{nodes}</ul>;
}
return <ul className="custom-child-tree">{nodes}</ul>;
}}
>
<TreeNode key="1" label="Component">
<TreeNode key="2" label="Form" selectable={false}>
<TreeNode key="4" label="Input" />
<TreeNode aria-label="select one" key="5" label="Select" disabled />
</TreeNode>
<TreeNode key="3" label="Display">
<TreeNode key="6" label="Table" />
</TreeNode>
</TreeNode>
</Tree>,
mountNode
);

assert(!!document.querySelector('.custom-child-tree'));
})

it('should support defaultExpandedKeys and onExpand', () => {
let called = false;
const handleExpand = (expandedKeys, extra) => {
Expand Down
4 changes: 4 additions & 0 deletions types/tree/index.d.ts
Expand Up @@ -235,6 +235,10 @@ export interface TreeProps extends HTMLAttributesWeak, CommonProps {
* 当前获得焦点的子菜单或菜单项 key 值
*/
focusedKey?: string;
/**
* 渲染子节点
*/
renderChildNodes?: (nodes: React.ReactNode) => React.ReactNode;
}

export default class Tree extends React.Component<TreeProps, any> {
Expand Down

0 comments on commit aede069

Please sign in to comment.