UNPKG

cjd-parkball

Version:

> 中后台业务组件库,中后台就像公园,进入需要买门票(登录),所以以 Parkball(公园球) 命名,公园内必定捕获!作为一个组件库,提供使用方法文档,方便开发者的调用

248 lines (235 loc) 7.43 kB
import React from 'react' import { Tree, Input, Icon } from '../..' import './index.scss' const { TreeNode } = Tree const { Search } = Input export default class LayerTree extends React.Component { constructor () { super() this.onAddItem = this.onAddItem.bind(this) this.onTreeHover = this.onTreeHover.bind(this) this.onTreeOut = this.onTreeOut.bind(this) this.onTreeItemHover = this.onTreeItemHover.bind(this) this.onTreeItemOut = this.onTreeItemOut.bind(this) this.onTreeItemEdit = this.onTreeItemEdit.bind(this) this.onTreeItemDel = this.onTreeItemDel.bind(this) this.onItemIconHover = this.onItemIconHover.bind(this) this.onSelect = this.onSelect.bind(this) } state = { searchValue: '', searchLevel: 0, hoverActiveLevel: -1, hoverActiveItemIndex: -1, editItemIndex: -1, activeEditLevel: -1, selectedItem: '', } onTreeHover = (index) => { this.setState({ hoverActiveLevel: index, }) } onTreeOut = (et) => { if (et.currentTarget.contains(et.target)) { return 0 } this.setState({ hoverActiveLevel: -1, }) return 1 } onTreeItemHover = (level, index) => { setTimeout(() => { const { hoverActiveLevel } = this.state if (level === hoverActiveLevel + 1) { this.setState({ hoverActiveItemIndex: index, }) } }, 0) } onTreeItemOut = (et) => { if (et.currentTarget.contains(et.target)) { return 0 } this.setState({ hoverActiveItemIndex: -1, }) return 1 } onItemIconHover = (et) => { et.preventDefault() et.stopPropagation() } onChange = (searchLevel, e) => { const { value } = e.target this.setState({ searchValue: value, searchLevel, }) } onSelect = (itemKey) => { const { onSelect } = this.props const { selectedItem } = this.state const { hoverActiveLevel, hoverActiveItemIndex } = this.state const selectedItemId = `${hoverActiveLevel}-${hoverActiveItemIndex}` if (selectedItem !== selectedItemId) { onSelect({ key: itemKey, level: hoverActiveLevel + 1, index: hoverActiveItemIndex, }) this.setState({ selectedItem: selectedItemId, }) } } onAddItem = (level, value, et) => { const { onAdd } = this.props typeof onAdd === 'function' && onAdd({ level, value, et, }) } onTreeItemClick4Edit = (level, index, et) => { et.preventDefault() et.stopPropagation() this.setState({ editItemIndex: index, activeEditLevel: level, }) } onTreeItemEdit = (level, index, value, et) => { et.preventDefault() et.stopPropagation() const { onEdit } = this.props typeof onEdit === 'function' && onEdit({ level, index, value, et, }) this.setState({ editItemIndex: -1, }) } onTreeItemDel = (level, index, et) => { et.preventDefault() et.stopPropagation() const { onDel } = this.props typeof onDel === 'function' && onDel({ level, index, et, }) } render () { const indexMap = [ '一级类目', '二级类目', '三级类目', '四级类目', ] const { layerTreeData, detailTpl, layerTreeHeight, detailWidth, } = this.props const { searchValue, searchLevel, hoverActiveLevel, hoverActiveItemIndex, editItemIndex, activeEditLevel, } = this.state const layerTreeItemWidth = 180 const layerTreeItemMargin = 30 const layerTreeDetailWidth = detailWidth || 400 const LayerTreeWidth = ((layerTreeItemWidth + layerTreeItemMargin) * layerTreeData.length) + (detailTpl && detailTpl.tpl ? layerTreeDetailWidth : 0) const loop = (data, sl) => { const filteredIndex = [] const filterData = sl === searchLevel ? data.filter((i, index) => { if (new RegExp(searchValue).test(i.key)) { filteredIndex.push(index) return true } return false }) : data return filterData.map((item, i) => { const index = item.title.indexOf(searchValue) const beforeStr = item.title.substr(0, index) const afterStr = item.title.substr(index + searchValue.length) const titleText = (index > -1 && sl === searchLevel) ? (<div style={{ display: 'inline-block' }}> {beforeStr} <span style={{ color: '#f50' }}> {searchValue} </span>{afterStr} </div>) : item.title /* eslint-disable jsx-a11y/mouse-events-have-key-events */ const title = (sl === activeEditLevel && (filteredIndex[i] || i) === editItemIndex) ? (<Search className="tree-item__edit" placeholder="" size="small" enterButton="确定" onSearch={this.onTreeItemEdit.bind(this, sl, filteredIndex[i] || i)} />) : (<span className="tree-item" onMouseOver={this.onTreeItemHover.bind(this, sl, filteredIndex[i] || i)} onMouseOut={this.onTreeItemOut} > {titleText} {sl === hoverActiveLevel + 1 && (filteredIndex[i] || i) === hoverActiveItemIndex ? <span className="tree-item__icons" onFocus={this.onItemIconHover} onMouseOver={this.onItemIconHover} > <Icon className="tree-item__icon" type="edit" onClick={this.onTreeItemClick4Edit.bind(this, sl, filteredIndex[i] || i)} /> {item.isDeletable ? <Icon className="tree-item__icon" type="delete" onClick={this.onTreeItemDel.bind(this, sl, filteredIndex[i] || i)} /> : ''} </span> : ''} </span>) return <TreeNode key={item.key} title={title} /> }) } return ( /* eslint-disable jsx-a11y/mouse-events-have-key-events */ <div className="layer-tree" style={{ width: `${LayerTreeWidth}px`, height: `${layerTreeHeight || 300}px`, }} > {layerTreeData.map((data, index) => { if (detailTpl && detailTpl.layerLevel <= index + 1) { return '' } return (<div key={index} className={`layer-tree__item layer-tree__item--${index}`} onMouseOver={this.onTreeHover.bind(this, index)} onMouseOut={this.onTreeOut} > <div className="layer-tree__item--title">{indexMap[index]}</div> <Search style={{ marginBottom: 8 }} placeholder="Search" onChange={this.onChange.bind(this, index + 1)} /> <Tree showIcon={false} onSelect={this.onSelect} > {loop(data, index + 1)} </Tree> {index === hoverActiveLevel ? <Search className="tree-item__add" placeholder="" enterButton="添加" onSearch={this.onAddItem.bind(this, index + 1)} /> : ''} </div>) })} {detailTpl && layerTreeData.length + 1 >= detailTpl.layerLevel && detailTpl.tpl ? <div className="layer-tree__detail" style={{ width: `${layerTreeDetailWidth - 60}px` }}>{detailTpl.tpl(detailTpl.tplData)}</div> : ''} </div> ) } }