add vc-tree demo

pull/165/head
tjz 2018-04-12 22:04:55 +08:00
parent 25631cf541
commit 41a1f85dd5
9 changed files with 232 additions and 47 deletions

View File

@ -1,7 +1,7 @@
import Tabs from '../vc-tabs/src/Tabs'
import isFlexSupported from '../_util/isFlexSupported'
import { hasProp, getComponentFromProp, getComponentName, isEmptyElement, getSlotOptions } from '../_util/props-util'
import { hasProp, getComponentFromProp, isEmptyElement, getSlotOptions } from '../_util/props-util'
import warning from '../_util/warning'
export default {
name: 'ATabs',

View File

@ -0,0 +1,18 @@
@contextmenuPrefixCls: rc-tree-contextmenu;
.@{contextmenuPrefixCls} {
position: absolute;
left: -9999px;
top: -9999px;
z-index: 1070;
display: block;
background-color: #fff;
&-hidden {
display: none;
}
&-inner {
border: 1px solid #ddd;
padding: 10px 20px;
}
}

View File

@ -0,0 +1,75 @@
<script>
/* eslint no-console:0 */
import Tree, { TreeNode } from '../index'
import '../assets/index.less'
import './contextmenu.less'
export default {
data () {
return {
selectedKeys: ['0-1', '0-1-1'],
}
},
methods: {
onSelect (selectedKeys) {
this.selectedKeys = selectedKeys
},
onRightClick (info) {
console.log('right click', info)
this.selectedKeys = [info.node.eventKey]
},
onMouseEnter (info) {
console.log('enter', info)
},
onMouseLeave (info) {
console.log('leave', info)
},
},
render () {
return (
<div>
<h2>right click contextmenu</h2>
<Tree
onRightClick={this.onRightClick}
onSelect={this.onSelect}
selectedKeys={this.selectedKeys}
multiple
defaultExpandAll
showLine
showIcon={false}
>
<TreeNode title='parent 1' key='0-1'>
<TreeNode title='parent 1-0' key='0-1-1'>
<TreeNode title='leaf0' isLeaf />
<TreeNode title='leaf1' isLeaf />
<TreeNode title='leaf2' isLeaf />
</TreeNode>
<TreeNode title='parent 1-1'>
<TreeNode title='leaf' isLeaf />
</TreeNode>
</TreeNode>
</Tree>
<h2>hover popup contextmenu</h2>
<Tree
onMouseenter={this.onMouseEnter} onMouseleave={this.onMouseLeave}
onSelect={this.onSelect}
multiple defaultExpandAll showLine
>
<TreeNode title='parent 1' key='0-1'>
<TreeNode title='parent 1-0' key='0-1-1'>
<TreeNode title='leaf' isLeaf />
<TreeNode title='leaf' />
</TreeNode>
<TreeNode title='parent 1-1'>
<TreeNode title='leaf' />
</TreeNode>
</TreeNode>
</Tree>
</div>
)
},
}
</script>

View File

@ -0,0 +1,11 @@
.draggable-demo{
padding: 0 20px;
.draggable-container {
margin: 10px 30px;
width: 200px;
height: 200px;
overflow: auto;
border: 1px solid #ccc;
}
}

View File

@ -0,0 +1,111 @@
<script>
/* eslint no-console:0 */
import './draggable.less'
import Tree, { TreeNode } from '../index'
import '../assets/index.less'
import { gData } from './util'
import BaseMixin from '../../_util/BaseMixin'
export default {
mixins: [BaseMixin],
data () {
return {
gData,
autoExpandParent: true,
expandedKeys: ['0-0-key', '0-0-0-key', '0-0-0-0-key'],
}
},
methods: {
onDragStart (info) {
console.log('start', info)
},
onDragEnter (info) {
console.log('enter', info)
this.setState({
expandedKeys: info.expandedKeys,
})
},
onDrop (info) {
console.log('drop', info)
const dropKey = info.node.eventKey
const dragKey = info.dragNode.eventKey
const dropPos = info.node.pos.split('-')
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1])
// const dragNodesKeys = info.dragNodesKeys;
const loop = (data, key, callback) => {
data.forEach((item, index, arr) => {
if (item.key === key) {
return callback(item, index, arr)
}
if (item.children) {
return loop(item.children, key, callback)
}
})
}
const data = [...this.gData]
let dragObj
loop(data, dragKey, (item, index, arr) => {
arr.splice(index, 1)
dragObj = item
})
if (info.dropToGap) {
let ar
let i
loop(data, dropKey, (item, index, arr) => {
ar = arr
i = index
})
if (dropPosition === -1) {
ar.splice(i, 0, dragObj)
} else {
ar.splice(i + 1, 0, dragObj)
}
} else {
loop(data, dropKey, (item) => {
item.children = item.children || []
// where to insert
item.children.push(dragObj)
})
}
this.setState({
gData: data,
})
},
onExpand (expandedKeys) {
console.log('onExpand', arguments)
this.setState({
expandedKeys,
autoExpandParent: false,
})
},
},
render () {
const loop = data => {
return data.map((item) => {
if (item.children && item.children.length) {
return <TreeNode key={item.key} title={item.title}>{loop(item.children)}</TreeNode>
}
return <TreeNode key={item.key} title={item.title} />
})
}
return (<div class='draggable-demo'>
<h2>draggable</h2>
<p>drag a node into another node</p>
<div class='draggable-container'>
<Tree
expandedKeys={this.expandedKeys}
onExpand={this.onExpand} autoExpandParent={this.autoExpandParent}
draggable
onDragstart={this.onDragStart}
onDragenter={this.onDragEnter}
onDrop={this.onDrop}
>
{loop(this.gData)}
</Tree>
</div>
</div>)
},
}
</script>

View File

@ -1,7 +1,7 @@
import PropTypes from '../../_util/vue-types'
import classNames from 'classnames'
import warning from 'warning'
import { initDefaultProps, getOptionProps } from '../../_util/props-util'
import { initDefaultProps, getOptionProps, getSlots } from '../../_util/props-util'
import { cloneElement } from '../../_util/vnode'
import BaseMixin from '../../_util/BaseMixin'
import {
@ -162,9 +162,10 @@ const Tree = {
}
return {
...state,
...(this.getSyncProps(props) || {}),
...this.getSyncProps(props),
dragOverNodeKey: '',
dropPosition: null,
dragNodesKeys: [],
}
},
provide () {
@ -203,8 +204,8 @@ const Tree = {
methods: {
onNodeDragStart (event, node) {
const { sExpandedKeys } = this
const { eventKey, children } = node.props
const { eventKey } = node
const children = getSlots(node).default
this.dragNode = node
this.setState({
@ -223,13 +224,13 @@ const Tree = {
*/
onNodeDragEnter (event, node) {
const { sExpandedKeys } = this
const { pos, eventKey } = node.props
const { pos, eventKey } = node
const dropPosition = calcDropPosition(event, node)
// Skip if drag node is self
if (
this.dragNode.props.eventKey === eventKey &&
this.dragNode.eventKey === eventKey &&
dropPosition === 0
) {
this.setState({
@ -268,7 +269,7 @@ const Tree = {
}, 0)
},
onNodeDragOver (event, node) {
const { eventKey } = node.props
const { eventKey } = node
// Update drag position
if (this.dragNode && eventKey === this.dragOverNodeKey) {
@ -297,7 +298,7 @@ const Tree = {
onNodeDrop (event, node) {
const { dragNodesKeys, dropPosition } = this
const { eventKey, pos } = node.props
const { eventKey, pos } = node
this.setState({
dragOverNodeKey: '',
@ -509,46 +510,21 @@ const Tree = {
/**
* Sync state with props if needed
*/
getSyncProps (props = {}, prevProps) {
let needSync = false
getSyncProps (props = {}) {
const newState = {}
const myPrevProps = prevProps || {}
const children = this.$slots.default
function checkSync (name) {
if (props[name] !== myPrevProps[name]) {
needSync = true
return true
}
return false
}
// Children change will affect check box status.
// And no need to check when prev props not provided
if (prevProps && checkSync('children')) {
const { checkedKeys = [], halfCheckedKeys = [] } =
calcCheckedKeys(props.checkedKeys || this.sCheckedKeys, props, children) || {}
newState.sCheckedKeys = checkedKeys
newState.sHalfCheckedKeys = halfCheckedKeys
}
// Re-calculate when autoExpandParent or expandedKeys changed
if (prevProps && (checkSync('autoExpandParent') || checkSync('expandedKeys'))) {
newState.sExpandedKeys = props.autoExpandParent
? calcExpandedKeys(props.expandedKeys, props, children) : props.expandedKeys
}
if (checkSync('selectedKeys')) {
if (props.selectedKeys !== undefined) {
newState.sSelectedKeys = calcSelectedKeys(props.selectedKeys, props, children)
}
if (checkSync('checkedKeys')) {
if (props.checkedKeys !== undefined) {
const { checkedKeys = [], halfCheckedKeys = [] } =
calcCheckedKeys(props.checkedKeys, props, children) || {}
newState.sCheckedKeys = checkedKeys
newState.sHalfCheckedKeys = halfCheckedKeys
}
return needSync ? newState : null
return newState
},
/**

View File

@ -291,11 +291,6 @@ const TreeNode = {
}
},
// Drag usage
setSelectHandle (node) {
this.selectHandle = node
},
getNodeChildren () {
const { $slots: { default: children }} = this
const originList = filterEmpty(children)
@ -497,10 +492,9 @@ const TreeNode = {
)}
draggable={(!disabled && draggable) || undefined}
aria-grabbed={(!disabled && draggable) || undefined}
onMouseenter={this.onMouseEnter}
onMouseleave={this.onMouseLeave}
onContexmenu={this.onContextMenu}
onContextmenu={this.onContextMenu}
onClick={this.onSelectorClick}
onDragstart={this.onDragStart}
>

View File

@ -176,7 +176,7 @@ export function getDragNodesKeys (treeNodes, node) {
export function calcDropPosition (event, treeNode) {
const { clientY } = event
const { top, bottom, height } = treeNode.selectHandle.getBoundingClientRect()
const { top, bottom, height } = treeNode.$refs.selectHandle.getBoundingClientRect()
const des = Math.max(height * DRAG_SIDE_RANGE, DRAG_MIN_GAP)
if (clientY <= top + des) {

View File

@ -3,7 +3,7 @@ import Layout from './components/layout.vue'
const AsyncTestComp = () => {
const d = window.location.hash.replace('#', '')
return {
component: import(`../components/vc-upload/demo/${d}`),
component: import(`../components/vc-tree/demo/${d}`),
}
}