Web: Components: added props newItems and onClickBadge() for render Badge witch counter new Items
This commit is contained in:
parent
34cb8329ae
commit
e965e529c6
@ -15,7 +15,7 @@ import { TreeMenu } from "asc-web-components";
|
||||
### Properties TreeMenu
|
||||
|
||||
| Props | Type | Required | Values | Default | Description |
|
||||
| --------------------- | :----------------: | :------: | :----: | :-----: | ------------------------------------------------------------------------------------------------------- |
|
||||
| ----------------------- | :------------: | :------: | :----: | :-----: | ------------------------------------------------------------------------------------------------------- |
|
||||
| `autoExpandParent` | `bool` | - | - | `false` | Whether auto expand parent treeNodes |
|
||||
| `checkable` | `bool` | - | - | `false` | Whether support checked |
|
||||
| `className` | `string` | - | - | - | Accepts class |
|
||||
@ -43,7 +43,7 @@ import { TreeMenu } from "asc-web-components";
|
||||
| `loadData` | `func` | - | - | - | load data asynchronously and the return value should be a promise |
|
||||
| `isFullFillSelection` | `bool` | - | - | `true` | to select the selection style of the active node |
|
||||
| `gapBetweenNodes` | `string` | - | - | `15` | for setting the spacing between nodes |
|
||||
|`gapBetweenNodesTablet`| `string` | - | - | - | to set spacing between nodes on tablets and phones (if necessary) |
|
||||
| `gapBetweenNodesTablet` | `string` | - | - | - | to set spacing between nodes on tablets and phones (if necessary) |
|
||||
| `isEmptyRootNode` | `bool` | - | - | `false` | swipe the root node to the left if there are no nested elements |
|
||||
|
||||
### Properties TreeNode
|
||||
@ -59,3 +59,5 @@ import { TreeMenu } from "asc-web-components";
|
||||
| `key` | `bool` | - | - | - | it's used with tree props's (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys. you'd better to set it, and it must be unique in the tree's all treeNodes |
|
||||
| `style` | `object` | - | - | - | set style to treeNode |
|
||||
| `title` | `string`,`element` | - | - | - | tree/subTree's title |
|
||||
| `newItems` | `number` | - | - | - | If value > 0 then a badge with the number of new elements will be displayed |
|
||||
| `onBadgeClick` | `func` | - | - | - | call when click on badge |
|
||||
|
@ -1,8 +1,10 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import styled, { css } from 'styled-components';
|
||||
import PropTypes from 'prop-types';
|
||||
import Tree from 'rc-tree';
|
||||
import React from "react";
|
||||
import styled, { css } from "styled-components";
|
||||
import PropTypes from "prop-types";
|
||||
import Tree from "rc-tree";
|
||||
|
||||
import Badge from "../badge";
|
||||
|
||||
const StyledTreeMenu = styled(Tree)`
|
||||
margin: 0;
|
||||
@ -18,31 +20,32 @@ const StyledTreeMenu = styled(Tree)`
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
${props => props.isEmptyRootNode &&
|
||||
${props =>
|
||||
props.isEmptyRootNode &&
|
||||
css`
|
||||
& > li > span.rc-tree-switcher-noop {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
}
|
||||
`}
|
||||
.rc-tree-node-content-wrapper {
|
||||
margin-bottom: ${props => +props.gapBetweenNodes - 15 + 'px;'};
|
||||
position: static !important;
|
||||
margin-bottom: ${props => +props.gapBetweenNodes - 15 + "px;"};
|
||||
@media(max-width: 1024px) {
|
||||
margin-bottom: ${props => props.gapBetweenNodesTablet
|
||||
? +props.gapBetweenNodesTablet - 15 + 'px;'
|
||||
: +props.gapBetweenNodes - 15 + 'px;'
|
||||
};
|
||||
margin-bottom: ${props =>
|
||||
props.gapBetweenNodesTablet
|
||||
? +props.gapBetweenNodesTablet - 15 + "px;"
|
||||
: +props.gapBetweenNodes - 15 + "px;"};
|
||||
}
|
||||
};
|
||||
${props => !props.isFullFillSelection &&
|
||||
${props =>
|
||||
!props.isFullFillSelection &&
|
||||
css`
|
||||
& .rc-tree-node-selected {
|
||||
span.rc-tree-node-selected {
|
||||
width: min-content !important;
|
||||
padding-right: 5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
`
|
||||
max-width: 85%;
|
||||
}
|
||||
`}
|
||||
|
||||
& .rc-tree-node-selected .rc-tree-title {
|
||||
${props => !props.isFullFillSelection && "width: 85%;"}
|
||||
@ -69,9 +72,9 @@ const StyledTreeMenu = styled(Tree)`
|
||||
.rc-tree-child-tree-open {
|
||||
display: block;
|
||||
${props => props.disableSwitch && "margin: 0 0 25px 0;"}
|
||||
margin-left: ${props => props.disableSwitch ? "27px" : "8px"};
|
||||
margin-left: ${props => (props.disableSwitch ? "27px" : "8px")};
|
||||
li:first-child{
|
||||
margin-top: ${props => props.disableSwitch ? "10px" : "6px"};
|
||||
margin-top: ${props => (props.disableSwitch ? "10px" : "6px")};
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
@ -102,40 +105,117 @@ const StyledTreeMenu = styled(Tree)`
|
||||
margin-right: 2px;
|
||||
vertical-align: top;
|
||||
}
|
||||
${props => props.switcherIcon != null ?
|
||||
css`
|
||||
li span.rc-tree-switcher{
|
||||
${props =>
|
||||
props.switcherIcon != null
|
||||
? css`
|
||||
li span.rc-tree-switcher {
|
||||
background: none;
|
||||
}
|
||||
`
|
||||
: ''
|
||||
}
|
||||
${props => props.disableSwitch ?
|
||||
css`
|
||||
li span.rc-tree-switcher{
|
||||
: ""}
|
||||
${props =>
|
||||
props.disableSwitch
|
||||
? css`
|
||||
li span.rc-tree-switcher {
|
||||
height: 0;
|
||||
margin: 0;
|
||||
width: 0;
|
||||
}
|
||||
`
|
||||
: ``
|
||||
}
|
||||
: ``}
|
||||
`;
|
||||
|
||||
const TreeMenu = React.forwardRef((props, ref) => {
|
||||
//console.log("TreeMenu render");
|
||||
const { defaultExpandAll, defaultExpandParent, showIcon, showLine, multiple, disabled, draggable, checkable, children, switcherIcon, icon,
|
||||
onDragStart, onDrop, onSelect, onDragEnter, onDragEnd, onDragLeave, onDragOver, onCheck, onExpand, onLoad, onMouseEnter, onMouseLeave, onRightClick,
|
||||
defaultSelectedKeys, expandedKeys, defaultExpandedKeys, defaultCheckedKeys, selectedKeys, className, id, style, loadData, disableSwitch,
|
||||
isFullFillSelection, gapBetweenNodes, gapBetweenNodesTablet, isEmptyRootNode } = props;
|
||||
const {
|
||||
defaultExpandAll,
|
||||
defaultExpandParent,
|
||||
showIcon,
|
||||
showLine,
|
||||
multiple,
|
||||
disabled,
|
||||
draggable,
|
||||
checkable,
|
||||
children,
|
||||
switcherIcon,
|
||||
icon,
|
||||
onDragStart,
|
||||
onDrop,
|
||||
onSelect,
|
||||
onDragEnter,
|
||||
onDragEnd,
|
||||
onDragLeave,
|
||||
onDragOver,
|
||||
onCheck,
|
||||
onExpand,
|
||||
onLoad,
|
||||
onMouseEnter,
|
||||
onMouseLeave,
|
||||
onRightClick,
|
||||
defaultSelectedKeys,
|
||||
expandedKeys,
|
||||
defaultExpandedKeys,
|
||||
defaultCheckedKeys,
|
||||
selectedKeys,
|
||||
className,
|
||||
id,
|
||||
style,
|
||||
loadData,
|
||||
disableSwitch,
|
||||
isFullFillSelection,
|
||||
gapBetweenNodes,
|
||||
gapBetweenNodesTablet,
|
||||
isEmptyRootNode
|
||||
} = props;
|
||||
|
||||
const expandedKeysProp = expandedKeys ? { expandedKeys: expandedKeys } : {};
|
||||
|
||||
const onTreeNodeSelect = (data, e) => {
|
||||
const result = e.selected ? data : [e.node.props.eventKey];
|
||||
onSelect(result, e);
|
||||
};
|
||||
|
||||
const renderChildren = children => {
|
||||
const items = [];
|
||||
|
||||
React.Children.forEach(children, (child, i) => {
|
||||
if (
|
||||
child.props.newItems > 0 &&
|
||||
typeof child.props.newItems === "number"
|
||||
) {
|
||||
const el = React.cloneElement(child, {
|
||||
key: child.props.id,
|
||||
icon: (
|
||||
<>
|
||||
{child.props.icon}
|
||||
<Badge
|
||||
data-id={child.props.id}
|
||||
className="newItem"
|
||||
key={child.props.id + "-badge"}
|
||||
label={child.props.newItems}
|
||||
backgroundColor="#ED7309"
|
||||
color="#FFF"
|
||||
fontSize="11px"
|
||||
fontWeight={800}
|
||||
borderRadius="11px"
|
||||
padding="0 5px"
|
||||
onClick={child.props.onBadgeClick}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
});
|
||||
items.push(el);
|
||||
} else {
|
||||
items.push(child);
|
||||
}
|
||||
});
|
||||
return items;
|
||||
};
|
||||
|
||||
const modifiedChildren = renderChildren(children);
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledTreeMenu
|
||||
id={id}
|
||||
style={style}
|
||||
@ -152,40 +232,35 @@ const TreeMenu = React.forwardRef((props, ref) => {
|
||||
defaultExpandAll={!!defaultExpandAll}
|
||||
defaultExpandParent={!!defaultExpandParent}
|
||||
icon={icon}
|
||||
|
||||
selectedKeys={selectedKeys}
|
||||
defaultSelectedKeys={defaultSelectedKeys}
|
||||
defaultExpandedKeys={defaultExpandedKeys}
|
||||
defaultCheckedKeys={defaultCheckedKeys}
|
||||
|
||||
onDragStart={onDragStart}
|
||||
onDrop={onDrop}
|
||||
onDragEnd={onDragEnd}
|
||||
onDragLeave={onDragLeave}
|
||||
onDragOver={onDragOver}
|
||||
|
||||
switcherIcon={switcherIcon}
|
||||
onSelect={onTreeNodeSelect}
|
||||
onDragEnter={onDragEnter}
|
||||
|
||||
onCheck={onCheck}
|
||||
onExpand={onExpand}
|
||||
|
||||
onLoad={onLoad}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
onRightClick={onRightClick}
|
||||
|
||||
disableSwitch={disableSwitch}
|
||||
isFullFillSelection={isFullFillSelection}
|
||||
gapBetweenNodes={gapBetweenNodes}
|
||||
gapBetweenNodesTablet={gapBetweenNodesTablet}
|
||||
isEmptyRootNode={isEmptyRootNode}
|
||||
>
|
||||
{children}
|
||||
{modifiedChildren}
|
||||
</StyledTreeMenu>
|
||||
</>
|
||||
);
|
||||
})
|
||||
});
|
||||
|
||||
TreeMenu.propTypes = {
|
||||
checkable: PropTypes.bool,
|
||||
@ -216,15 +291,15 @@ TreeMenu.propTypes = {
|
||||
gapBetweenNodes: PropTypes.string,
|
||||
gapBetweenNodesTablet: PropTypes.string,
|
||||
isEmptyRootNode: PropTypes.bool
|
||||
}
|
||||
};
|
||||
|
||||
TreeMenu.defaultProps = {
|
||||
disableSwitch: false,
|
||||
isFullFillSelection: true,
|
||||
gapBetweenNodes: '15',
|
||||
gapBetweenNodes: "15",
|
||||
isEmptyRootNode: false
|
||||
}
|
||||
};
|
||||
|
||||
TreeMenu.displayName = "TreeMenu";
|
||||
|
||||
export default TreeMenu
|
||||
export default TreeMenu;
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import styled, { css } from 'styled-components';
|
||||
import { Icons } from '../../icons';
|
||||
import { getCssFromSvg } from '../../icons/get-css-from-svg';
|
||||
import {TreeNode} from 'rc-tree';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import React from "react";
|
||||
import styled, { css } from "styled-components";
|
||||
import { Icons } from "../../icons";
|
||||
import { getCssFromSvg } from "../../icons/get-css-from-svg";
|
||||
import { TreeNode } from "rc-tree";
|
||||
import ReactDOMServer from "react-dom/server";
|
||||
|
||||
var checkboxIcon,
|
||||
checkboxСheckedIcon,
|
||||
@ -17,21 +17,73 @@ var checkboxIcon,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
treeIcon;
|
||||
|
||||
(function(){
|
||||
checkboxIcon = getCssFromSvg(ReactDOMServer.renderToString(<Icons.CheckboxIcon />));
|
||||
сheckboxDisabledIcon = getCssFromSvg(ReactDOMServer.renderToString(<Icons.CheckboxIcon isfill={true} color="#F8F9F9" />));
|
||||
сheckboxHoverIcon = getCssFromSvg(ReactDOMServer.renderToString(<Icons.CheckboxIcon isfill={true} color="white" />));
|
||||
(function() {
|
||||
checkboxIcon = getCssFromSvg(
|
||||
ReactDOMServer.renderToString(<Icons.CheckboxIcon />)
|
||||
);
|
||||
сheckboxDisabledIcon = getCssFromSvg(
|
||||
ReactDOMServer.renderToString(
|
||||
<Icons.CheckboxIcon isfill={true} color="#F8F9F9" />
|
||||
)
|
||||
);
|
||||
сheckboxHoverIcon = getCssFromSvg(
|
||||
ReactDOMServer.renderToString(
|
||||
<Icons.CheckboxIcon isfill={true} color="white" />
|
||||
)
|
||||
);
|
||||
|
||||
checkboxСheckedIcon= getCssFromSvg(ReactDOMServer.renderToString(<Icons.CheckboxCheckedIcon />));
|
||||
checkboxCheckedDisabledIcon= getCssFromSvg(ReactDOMServer.renderToString(<Icons.CheckboxCheckedIcon isfill={true} color="#F8F9F9" isStroke={true} stroke="#ECEEF1" />));
|
||||
checkboxCheckedHoverIcon = getCssFromSvg(ReactDOMServer.renderToString(<Icons.CheckboxCheckedIcon isfill={true} color="white" isStroke={true} stroke="#A3A9AE" />));
|
||||
checkboxСheckedIcon = getCssFromSvg(
|
||||
ReactDOMServer.renderToString(<Icons.CheckboxCheckedIcon />)
|
||||
);
|
||||
checkboxCheckedDisabledIcon = getCssFromSvg(
|
||||
ReactDOMServer.renderToString(
|
||||
<Icons.CheckboxCheckedIcon
|
||||
isfill={true}
|
||||
color="#F8F9F9"
|
||||
isStroke={true}
|
||||
stroke="#ECEEF1"
|
||||
/>
|
||||
)
|
||||
);
|
||||
checkboxCheckedHoverIcon = getCssFromSvg(
|
||||
ReactDOMServer.renderToString(
|
||||
<Icons.CheckboxCheckedIcon
|
||||
isfill={true}
|
||||
color="white"
|
||||
isStroke={true}
|
||||
stroke="#A3A9AE"
|
||||
/>
|
||||
)
|
||||
);
|
||||
|
||||
сheckboxIndeterminateIcon = getCssFromSvg(ReactDOMServer.renderToString(<Icons.CheckboxIndeterminateIcon />));
|
||||
checkboxIndeterminateDisabledIcon = getCssFromSvg(ReactDOMServer.renderToString(<Icons.CheckboxIndeterminateIcon isfill={true} color="#F8F9F9" isStroke={true} stroke="#ECEEF1" />));
|
||||
checkboxIndeterminateHoverIcon = getCssFromSvg(ReactDOMServer.renderToString(<Icons.CheckboxIndeterminateIcon isfill={true} color="white" isStroke={true} stroke="#A3A9AE" />));
|
||||
сheckboxIndeterminateIcon = getCssFromSvg(
|
||||
ReactDOMServer.renderToString(<Icons.CheckboxIndeterminateIcon />)
|
||||
);
|
||||
checkboxIndeterminateDisabledIcon = getCssFromSvg(
|
||||
ReactDOMServer.renderToString(
|
||||
<Icons.CheckboxIndeterminateIcon
|
||||
isfill={true}
|
||||
color="#F8F9F9"
|
||||
isStroke={true}
|
||||
stroke="#ECEEF1"
|
||||
/>
|
||||
)
|
||||
);
|
||||
checkboxIndeterminateHoverIcon = getCssFromSvg(
|
||||
ReactDOMServer.renderToString(
|
||||
<Icons.CheckboxIndeterminateIcon
|
||||
isfill={true}
|
||||
color="white"
|
||||
isStroke={true}
|
||||
stroke="#A3A9AE"
|
||||
/>
|
||||
)
|
||||
);
|
||||
|
||||
treeIcon = getCssFromSvg(ReactDOMServer.renderToString(<Icons.CatalogFolderIcon />));
|
||||
}());
|
||||
treeIcon = getCssFromSvg(
|
||||
ReactDOMServer.renderToString(<Icons.CatalogFolderIcon />)
|
||||
);
|
||||
})();
|
||||
|
||||
const TreeNodeMenu = styled(TreeNode)`
|
||||
|
||||
@ -82,10 +134,10 @@ const TreeNodeMenu = styled(TreeNode)`
|
||||
padding: 0;
|
||||
}
|
||||
.rc-tree-node-content-wrapper {
|
||||
width: ${props => props.disableSwitch ? "90%" : "108%"};
|
||||
width: ${props => (props.disableSwitch ? "90%" : "108%")};
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
/*min-width: ${props => props.disableSwitch ? "160px" : "190px"};*/
|
||||
/*min-width: ${props => (props.disableSwitch ? "160px" : "190px")};*/
|
||||
overflow: hidden;
|
||||
|
||||
cursor: pointer;
|
||||
@ -94,10 +146,10 @@ const TreeNodeMenu = styled(TreeNode)`
|
||||
vertical-align: top;
|
||||
|
||||
left: 0;
|
||||
background: ${props => props.dragging ? "#F8F7BF" : "none"};
|
||||
background: ${props => (props.dragging ? "#F8F7BF" : "none")};
|
||||
|
||||
:hover {
|
||||
background: ${props => props.dragging ? "#EFEFB2" : "none"};
|
||||
background: ${props => (props.dragging ? "#EFEFB2" : "none")};
|
||||
}
|
||||
}
|
||||
span.rc-tree-switcher,
|
||||
@ -117,7 +169,7 @@ const TreeNodeMenu = styled(TreeNode)`
|
||||
background-attachment: scroll;
|
||||
}
|
||||
span.rc-tree-iconEle {
|
||||
display: ${props => props.icon ? 'inline-block' : 'none'};
|
||||
display: ${props => (props.icon ? "inline-block" : "none")};
|
||||
}
|
||||
span.rc-tree-switcher
|
||||
{
|
||||
@ -214,32 +266,49 @@ const TreeNodeMenu = styled(TreeNode)`
|
||||
}
|
||||
span.rc-tree-title{
|
||||
display: inline-block;
|
||||
width: ${props => !props.disableSwitch
|
||||
? props.icon ? 'calc(100% - 44px)' : 'calc(100% - 20px)'
|
||||
: '100%'};
|
||||
width: ${props =>
|
||||
!props.disableSwitch
|
||||
? props.icon
|
||||
? "calc(100% - 44px)"
|
||||
: "calc(100% - 20px)"
|
||||
: "100%"};
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: #333;
|
||||
padding-left: ${props => (props.icon || props.disableSwitch) ? '0' : '20px'};
|
||||
padding-left: ${props =>
|
||||
props.icon || props.disableSwitch ? "0" : "20px"};
|
||||
}
|
||||
span.rc-tree-title:first-child{
|
||||
max-width: 100%;
|
||||
}
|
||||
.newItem {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 2px;
|
||||
}
|
||||
.rc-tree-node-selected {
|
||||
background: #DFE2E3;
|
||||
mix-blend-mode: normal;
|
||||
border-radius: 3px;
|
||||
z-index: 0;
|
||||
${props => props.disableSwitch &&
|
||||
${props =>
|
||||
props.disableSwitch &&
|
||||
css`
|
||||
min-width: 0;
|
||||
width: auto;
|
||||
`
|
||||
}
|
||||
`}
|
||||
:hover {
|
||||
background: #DFE2E3;
|
||||
}
|
||||
overflow: visible;
|
||||
|
||||
|
||||
}
|
||||
.newItem {
|
||||
position: absolute;
|
||||
right: -30px;
|
||||
top: 2px;
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -1,24 +1,27 @@
|
||||
import React, { useState } from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { withKnobs, boolean, text, select, number } from '@storybook/addon-knobs/react';
|
||||
import withReadme from 'storybook-readme/with-readme';
|
||||
import Readme from './README.md';
|
||||
import TreeMenu from '.';
|
||||
import TreeNode from './sub-components/tree-node';
|
||||
import { Icons } from '../icons';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import {
|
||||
withKnobs,
|
||||
boolean,
|
||||
text,
|
||||
select,
|
||||
number
|
||||
} from "@storybook/addon-knobs/react";
|
||||
import withReadme from "storybook-readme/with-readme";
|
||||
import Readme from "./README.md";
|
||||
import TreeMenu from ".";
|
||||
import TreeNode from "./sub-components/tree-node";
|
||||
import { Icons } from "../icons";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
|
||||
const iconNames = Object.keys(Icons);
|
||||
|
||||
const treeData = [
|
||||
{
|
||||
key: '0-0', children:
|
||||
[
|
||||
{ key: '0-0-0' },
|
||||
{ key: '0-0-1' }
|
||||
],
|
||||
},
|
||||
key: "0-0",
|
||||
children: [{ key: "0-0-0" }, { key: "0-0-1" }],
|
||||
newItems: 1
|
||||
}
|
||||
];
|
||||
|
||||
const TreeMenuStory = props => {
|
||||
@ -28,22 +31,32 @@ const TreeMenuStory = props => {
|
||||
const [gData, setGData] = useState(data);
|
||||
const [autoExpandParent, setAutoExpandParent] = useState(true);
|
||||
|
||||
const [expandedKeys, setExpandedKeys] = useState(['0-0-key', '0-0-0-key', '0-0-0-0-key']);
|
||||
const [expandedKeys, setExpandedKeys] = useState([
|
||||
"0-0-key",
|
||||
"0-0-0-key",
|
||||
"0-0-0-0-key"
|
||||
]);
|
||||
|
||||
const onDragStart = (info) => {
|
||||
const onDragStart = info => {
|
||||
info.event.persist();
|
||||
};
|
||||
|
||||
const onDragEnter = (info) => {
|
||||
const onDragEnter = info => {
|
||||
setExpandedKeys(info.expandedKeys);
|
||||
};
|
||||
|
||||
const onDrop = (info) => {
|
||||
const onBadgeClick = e => {
|
||||
const id = e.currentTarget.dataset.id;
|
||||
console.log("Clocked on badge: ", id);
|
||||
};
|
||||
|
||||
const onDrop = info => {
|
||||
info.event.persist();
|
||||
const dropKey = info.node.props.eventKey;
|
||||
const dragKey = info.dragNode.props.eventKey;
|
||||
const dropPos = info.node.props.pos.split('-');
|
||||
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
|
||||
const dropPos = info.node.props.pos.split("-");
|
||||
const dropPosition =
|
||||
info.dropPosition - Number(dropPos[dropPos.length - 1]);
|
||||
|
||||
const loop = (treeData, key, callback) => {
|
||||
treeData.forEach((item, index, arr) => {
|
||||
@ -66,7 +79,7 @@ const TreeMenuStory = props => {
|
||||
});
|
||||
|
||||
if (!info.dropToGap) {
|
||||
loop(treeData, dropKey, (item) => {
|
||||
loop(treeData, dropKey, item => {
|
||||
item.children = item.children || [];
|
||||
item.children.push(dragObj);
|
||||
});
|
||||
@ -75,7 +88,7 @@ const TreeMenuStory = props => {
|
||||
info.node.props.expanded &&
|
||||
dropPosition === 1
|
||||
) {
|
||||
loop(treeData, dropKey, (item) => {
|
||||
loop(treeData, dropKey, item => {
|
||||
item.children = item.children || [];
|
||||
item.children.unshift(dragObj);
|
||||
});
|
||||
@ -94,65 +107,90 @@ const TreeMenuStory = props => {
|
||||
}
|
||||
setGData(treeData);
|
||||
};
|
||||
const onExpand = (expandedKeys) => {
|
||||
const onExpand = expandedKeys => {
|
||||
setExpandedKeys(expandedKeys);
|
||||
setAutoExpandParent(false);
|
||||
}
|
||||
};
|
||||
|
||||
const getTreeNodes = tree => {
|
||||
return tree.map((item) => {
|
||||
return tree.map(item => {
|
||||
if (item.children && item.children.length) {
|
||||
return <TreeNode title={text('title', 'Title')} key={item.key} icon={React.createElement(Icons[select('icon', iconNames, 'CatalogFolderIcon')], { size: "scale", isfill: true, color: "dimgray" })} >{getTreeNodes(item.children)}</TreeNode>;
|
||||
return (
|
||||
<TreeNode
|
||||
title={text("title", "Title")}
|
||||
key={item.key}
|
||||
icon={React.createElement(
|
||||
Icons[select("icon", iconNames, "CatalogFolderIcon")],
|
||||
{ size: "scale", isfill: true, color: "dimgray" }
|
||||
)}
|
||||
>
|
||||
{getTreeNodes(item.children)}
|
||||
</TreeNode>
|
||||
);
|
||||
}
|
||||
return <TreeNode key={item.key} title={text('title', 'Title')} icon={React.createElement(Icons[select('icon', iconNames, 'CatalogFolderIcon')], { size: "scale", isfill: true, color: "dimgray" })} ></TreeNode>;
|
||||
return (
|
||||
<TreeNode
|
||||
key={item.key}
|
||||
title={text("title", "Title")}
|
||||
onBadgeClick={onBadgeClick}
|
||||
newItems={item.newItems}
|
||||
icon={React.createElement(
|
||||
Icons[select("icon", iconNames, "CatalogFolderIcon")],
|
||||
{ size: "scale", isfill: true, color: "dimgray" }
|
||||
)}
|
||||
></TreeNode>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
const switcherIcon = (obj) => {
|
||||
const switcherIcon = obj => {
|
||||
if (obj.isLeaf) {
|
||||
return null;
|
||||
}
|
||||
if (obj.expanded) {
|
||||
return <Icons.ExpanderDownIcon size="scale" isfill={true} color="dimgray"></Icons.ExpanderDownIcon>
|
||||
return (
|
||||
<Icons.ExpanderDownIcon
|
||||
size="scale"
|
||||
isfill={true}
|
||||
color="dimgray"
|
||||
></Icons.ExpanderDownIcon>
|
||||
);
|
||||
} else {
|
||||
return <Icons.ExpanderRightIcon size="scale" isfill={true} color="dimgray"></Icons.ExpanderRightIcon>
|
||||
return (
|
||||
<Icons.ExpanderRightIcon
|
||||
size="scale"
|
||||
isfill={true}
|
||||
color="dimgray"
|
||||
></Icons.ExpanderRightIcon>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ width: "250px", margin: "20px" }}>
|
||||
<TreeMenu
|
||||
checkable={boolean('checkable', false)}
|
||||
draggable={boolean('draggable', false)}
|
||||
disabled={boolean('disabled', false)}
|
||||
badgeLabel={number('badgeLabel')}
|
||||
multiple={boolean('multiple', false)}
|
||||
showIcon={boolean('showIcon', true)}
|
||||
isFullFillSelection={boolean('isFullFillSelection', true)}
|
||||
gapBetweenNodes={text('gapBetweenNodes')}
|
||||
gapBetweenNodesTablet={text('gapBetweenNodesTablet')}
|
||||
isEmptyRootNode={boolean('isEmptyRootNode', false)}
|
||||
|
||||
defaultExpandAll={boolean('defaultExpandAll', false)}
|
||||
defaultExpandParent={boolean('defaultExpandParent', true)}
|
||||
|
||||
checkable={boolean("checkable", false)}
|
||||
draggable={boolean("draggable", false)}
|
||||
disabled={boolean("disabled", false)}
|
||||
badgeLabel={number("badgeLabel")}
|
||||
multiple={boolean("multiple", false)}
|
||||
showIcon={boolean("showIcon", true)}
|
||||
isFullFillSelection={boolean("isFullFillSelection", true)}
|
||||
gapBetweenNodes={text("gapBetweenNodes")}
|
||||
gapBetweenNodesTablet={text("gapBetweenNodesTablet")}
|
||||
isEmptyRootNode={boolean("isEmptyRootNode", false)}
|
||||
defaultExpandAll={boolean("defaultExpandAll", false)}
|
||||
defaultExpandParent={boolean("defaultExpandParent", true)}
|
||||
onExpand={onExpand}
|
||||
autoExpandParent={autoExpandParent}
|
||||
expandedKeys={expandedKeys}
|
||||
|
||||
onDragStart={(info) => onDragStart(info)}
|
||||
onDrop={(info) => onDrop(info)}
|
||||
onDragStart={info => onDragStart(info)}
|
||||
onDrop={info => onDrop(info)}
|
||||
onDragEnter={onDragEnter}
|
||||
|
||||
switcherIcon={switcherIcon}
|
||||
|
||||
onSelect={action("select")}
|
||||
onLoad={action("load")}
|
||||
|
||||
onCheck={action("check")}
|
||||
|
||||
onRightClick={action("rightClick")}
|
||||
>
|
||||
{getTreeNodes(gData)}
|
||||
@ -161,9 +199,7 @@ const TreeMenuStory = props => {
|
||||
);
|
||||
};
|
||||
|
||||
storiesOf('Components|Tree', module)
|
||||
storiesOf("Components|Tree", module)
|
||||
.addDecorator(withKnobs)
|
||||
.addDecorator(withReadme(Readme))
|
||||
.add('base', () => <TreeMenuStory data={treeData} />);
|
||||
|
||||
|
||||
.add("base", () => <TreeMenuStory data={treeData} />);
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import TreeMenu from '.';
|
||||
import TreeNode from './sub-components/tree-node';
|
||||
import React from "react";
|
||||
import { mount } from "enzyme";
|
||||
import TreeMenu from ".";
|
||||
import TreeNode from "./sub-components/tree-node";
|
||||
|
||||
describe('<TreeMenu />', () => {
|
||||
it('renders without error', () => {
|
||||
describe("<TreeMenu />", () => {
|
||||
it("renders without error", () => {
|
||||
const wrapper = mount(
|
||||
<TreeMenu
|
||||
checkable={false}
|
||||
@ -15,10 +15,7 @@ describe('<TreeMenu />', () => {
|
||||
showLine={false}
|
||||
>
|
||||
<TreeNode title="Parent" key="0-0">
|
||||
<TreeNode
|
||||
title="Child"
|
||||
key="0-0-0"
|
||||
></TreeNode>
|
||||
<TreeNode title="Child" key="0-0-0"></TreeNode>
|
||||
</TreeNode>
|
||||
</TreeMenu>
|
||||
);
|
||||
@ -26,7 +23,7 @@ describe('<TreeMenu />', () => {
|
||||
expect(wrapper).toExist();
|
||||
});
|
||||
|
||||
it('accepts id', () => {
|
||||
it("accepts id", () => {
|
||||
const wrapper = mount(
|
||||
<TreeMenu
|
||||
id="testId"
|
||||
@ -38,18 +35,15 @@ describe('<TreeMenu />', () => {
|
||||
showLine={false}
|
||||
>
|
||||
<TreeNode title="Parent" key="0-0">
|
||||
<TreeNode
|
||||
title="Child"
|
||||
key="0-0-0"
|
||||
></TreeNode>
|
||||
<TreeNode title="Child" key="0-0-0"></TreeNode>
|
||||
</TreeNode>
|
||||
</TreeMenu>
|
||||
);
|
||||
|
||||
expect(wrapper.prop('id')).toEqual('testId');
|
||||
expect(wrapper.prop("id")).toEqual("testId");
|
||||
});
|
||||
|
||||
it('accepts className', () => {
|
||||
it("accepts className", () => {
|
||||
const wrapper = mount(
|
||||
<TreeMenu
|
||||
className="test"
|
||||
@ -61,21 +55,18 @@ describe('<TreeMenu />', () => {
|
||||
showLine={false}
|
||||
>
|
||||
<TreeNode title="Parent" key="0-0">
|
||||
<TreeNode
|
||||
title="Child"
|
||||
key="0-0-0"
|
||||
></TreeNode>
|
||||
<TreeNode title="Child" key="0-0-0"></TreeNode>
|
||||
</TreeNode>
|
||||
</TreeMenu>
|
||||
);
|
||||
|
||||
expect(wrapper.prop('className')).toEqual('test');
|
||||
expect(wrapper.prop("className")).toEqual("test");
|
||||
});
|
||||
|
||||
it('accepts style', () => {
|
||||
it("accepts style", () => {
|
||||
const wrapper = mount(
|
||||
<TreeMenu
|
||||
style={{ color: 'red' }}
|
||||
style={{ color: "red" }}
|
||||
checkable={false}
|
||||
draggable={true}
|
||||
disabled={false}
|
||||
@ -84,64 +75,45 @@ describe('<TreeMenu />', () => {
|
||||
showLine={false}
|
||||
>
|
||||
<TreeNode title="Parent" key="0-0">
|
||||
<TreeNode
|
||||
title="Child"
|
||||
key="0-0-0"
|
||||
></TreeNode>
|
||||
<TreeNode title="Child" key="0-0-0"></TreeNode>
|
||||
</TreeNode>
|
||||
</TreeMenu>
|
||||
);
|
||||
|
||||
expect(wrapper.getDOMNode().style).toHaveProperty('color', 'red');
|
||||
expect(wrapper.getDOMNode().style).toHaveProperty("color", "red");
|
||||
});
|
||||
it('accepts isFullFillSelection', () => {
|
||||
it("accepts isFullFillSelection", () => {
|
||||
const wrapper = mount(
|
||||
<TreeMenu
|
||||
isFullFillSelection={false}
|
||||
>
|
||||
<TreeMenu isFullFillSelection={false}>
|
||||
<TreeNode title="Parent" key="0-0">
|
||||
<TreeNode
|
||||
title="Child"
|
||||
key="0-0-0"
|
||||
></TreeNode>
|
||||
<TreeNode title="Child" key="0-0-0"></TreeNode>
|
||||
</TreeNode>
|
||||
</TreeMenu>
|
||||
);
|
||||
|
||||
expect(wrapper.prop('isFullFillSelection')).toEqual(false);
|
||||
expect(wrapper.prop("isFullFillSelection")).toEqual(false);
|
||||
});
|
||||
it('accepts gapBetweenNodes and gapBetweenNodesTablet', () => {
|
||||
it("accepts gapBetweenNodes and gapBetweenNodesTablet", () => {
|
||||
const wrapper = mount(
|
||||
<TreeMenu
|
||||
gapBetweenNodes='22'
|
||||
gapBetweenNodesTablet='24'
|
||||
>
|
||||
<TreeMenu gapBetweenNodes="22" gapBetweenNodesTablet="24">
|
||||
<TreeNode title="Parent" key="0-0">
|
||||
<TreeNode
|
||||
title="Child"
|
||||
key="0-0-0"
|
||||
></TreeNode>
|
||||
<TreeNode title="Child" key="0-0-0"></TreeNode>
|
||||
</TreeNode>
|
||||
</TreeMenu>
|
||||
);
|
||||
|
||||
expect(wrapper.prop('gapBetweenNodes')).toEqual('22');
|
||||
expect(wrapper.prop('gapBetweenNodesTablet')).toEqual('24');
|
||||
expect(wrapper.prop("gapBetweenNodes")).toEqual("22");
|
||||
expect(wrapper.prop("gapBetweenNodesTablet")).toEqual("24");
|
||||
});
|
||||
it('accepts isEmptyRootNode', () => {
|
||||
it("accepts isEmptyRootNode", () => {
|
||||
const wrapper = mount(
|
||||
<TreeMenu
|
||||
isEmptyRootNode={true}
|
||||
>
|
||||
<TreeMenu isEmptyRootNode={true}>
|
||||
<TreeNode title="Parent" key="0-0">
|
||||
<TreeNode
|
||||
title="Child"
|
||||
key="0-0-0"
|
||||
></TreeNode>
|
||||
<TreeNode title="Child" key="0-0-0"></TreeNode>
|
||||
</TreeNode>
|
||||
</TreeMenu>
|
||||
);
|
||||
|
||||
expect(wrapper.prop('isEmptyRootNode')).toEqual(true);
|
||||
expect(wrapper.prop("isEmptyRootNode")).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user