645 lines
19 KiB
Vue
645 lines
19 KiB
Vue
<script lang="ts">
|
|
import { type PropType } from "vue"
|
|
import { getDefaultColor } from "../../core/util/xCoreColorUtil.uts"
|
|
import { checkIsCssUnit, getUid } from "../../core/util/xCoreUtil.uts"
|
|
import { xConfig } from "../../config/xConfig.uts"
|
|
import { flatChildrensId, setChildrenByid, findParentNode } from "../x-tree/util.uts"
|
|
type callbackType = (id : string) => Promise<UTSJSONObject[]>
|
|
|
|
/**
|
|
* @name 树子节点 xTreeItem
|
|
* @description xTree内部子组件,不可引用。
|
|
* @page /pages/index/tree
|
|
* @category 表单组件
|
|
* @constant 平台兼容
|
|
* | Harmony | H5 | andriod | IOS | 小程序 | UTS | UNIAPP-X SDK | version |
|
|
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
| ☑ | ☑ | ☑️ | ☑️ | ☑️ | ☑️ | 4.76+ | 1.1.18 |
|
|
*/
|
|
export default {
|
|
data() {
|
|
return {
|
|
nowIds: [] as string[],
|
|
showChildren: true,
|
|
openFLoderIds: [] as string[],
|
|
tid: 0,
|
|
_list: [] as UTSJSONObject[],
|
|
nowediteItem:null as null|UTSJSONObject,
|
|
showModal:false,
|
|
nowediteItemText:"",
|
|
nowediteItemId:"",
|
|
editeType:"change",//change/add,
|
|
newItem:null as null|UTSJSONObject
|
|
}
|
|
},
|
|
emits: [
|
|
/**
|
|
* 选中切换时触发
|
|
* @@param {string[]} ids - 打开的id数组
|
|
*/
|
|
'change',
|
|
/**
|
|
* 节点标签被点击
|
|
* @@param {UTSJSONObject} item - 打开的id数组
|
|
*/
|
|
'childrenClick',
|
|
/**
|
|
* 父节点展开和关闭
|
|
* @@param {string[]} ids - 打开的id数组
|
|
*/
|
|
'openFolderChange',
|
|
'setChildrenData',
|
|
'update:modelValue'
|
|
],
|
|
props: {
|
|
idList: {
|
|
type: Array as PropType<string[]>,
|
|
default: () : string[] => [] as string[]
|
|
},
|
|
list: {
|
|
type: Array as PropType<UTSJSONObject[]>,
|
|
default: () : UTSJSONObject[] => [] as UTSJSONObject[]
|
|
},
|
|
idKey: {
|
|
type: String,
|
|
default: "id"
|
|
},
|
|
labelKey: {
|
|
type: String,
|
|
default: "text"
|
|
},
|
|
folderId: {
|
|
type: Array as PropType<string[]>,
|
|
default: () : string[] => [] as string[]
|
|
},
|
|
/**
|
|
* 选中时的高亮颜色或者主题
|
|
*/
|
|
color: {
|
|
type: String,
|
|
default: ""
|
|
},
|
|
/**
|
|
* 用户交互时是否禁用选中交互
|
|
* 但不影响你赋值选中
|
|
*/
|
|
disabledParentBox: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
/**
|
|
* 是否允许选中父级的时候把它的所有子级也选上。
|
|
*/
|
|
parentSelectedFullChildren: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
/**
|
|
* 是否停用选中功能,只能是已读状态了
|
|
* 但不影响你赋值选中
|
|
*/
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
beforeOpenFloder: {
|
|
type: Function as PropType<callbackType>,
|
|
default: (itemId : string) : Promise<UTSJSONObject[]> => {
|
|
return Promise.resolve([] as UTSJSONObject[])
|
|
}
|
|
},
|
|
/**
|
|
* 关闭和打开时图标/图片地址
|
|
* 必须为长度2,第一项关闭时图标,第2项关闭时图标
|
|
*/
|
|
floaderIcon:{
|
|
type:Array as PropType<string[]>,
|
|
default:():string[] => ['folder-add-line','folder-open-fill'] as string[]
|
|
},
|
|
/**
|
|
* 是否显示默认前置开和关的图标
|
|
*/
|
|
showFloaderIcon:{
|
|
type:Boolean,
|
|
default:true
|
|
},
|
|
/**
|
|
* 是否显示选中的box图标
|
|
*/
|
|
showChecked:{
|
|
type:Boolean,
|
|
default:false
|
|
},
|
|
/**
|
|
* 选中与未选中时的图标/图片地址
|
|
* 必须为长度2,第一项未选中,第二项选中时图标
|
|
*/
|
|
checkedIcon:{
|
|
type:Array as PropType<string[]>,
|
|
default:():string[] => ['checkbox-blank-line','checkbox-fill'] as string[]
|
|
},
|
|
},
|
|
computed: {
|
|
|
|
_checkedIcon() : string[] {
|
|
return this.checkedIcon
|
|
},
|
|
_showChecked() : boolean {
|
|
return this.showChecked
|
|
},
|
|
_showFloaderIcon() : boolean {
|
|
return this.showFloaderIcon
|
|
},
|
|
_floaderIcon() : string[] {
|
|
return this.floaderIcon;
|
|
},
|
|
_childrenList() : UTSJSONObject[] {
|
|
return this.list;
|
|
},
|
|
_folderId() : string[] {
|
|
return this.openFLoderIds
|
|
},
|
|
_color() : string {
|
|
return this.color
|
|
},
|
|
_disabledParentBox() : boolean {
|
|
return this.disabledParentBox
|
|
},
|
|
_disabled() : boolean {
|
|
return this.disabled
|
|
},
|
|
_parentSelectedFullChildren() : boolean {
|
|
return this.parentSelectedFullChildren
|
|
},
|
|
_fontSize() : string {
|
|
|
|
if (xConfig.fontScale == 1) return '16';
|
|
return (16 * xConfig.fontScale).toString()
|
|
},
|
|
_itemColor() : string {
|
|
if (xConfig.dark == 'dark') return 'white'
|
|
return '#666';
|
|
}
|
|
},
|
|
watch: {
|
|
folderId(newVal : string[]) {
|
|
|
|
if (newVal.join("") == this.openFLoderIds.join("")) return;
|
|
|
|
this.openFLoderIds = newVal
|
|
},
|
|
list() {
|
|
// this.$forceUpdate()
|
|
this._list = this.list;
|
|
},
|
|
idList(newVal : string[]) {
|
|
if (newVal.join("") == this.nowIds.join("")) return;
|
|
this.nowIds = newVal;
|
|
}
|
|
},
|
|
mounted() {
|
|
this._list = this.list;
|
|
this.openFLoderIds = this.folderId
|
|
this.nowIds = this.idList;
|
|
},
|
|
methods: {
|
|
async childrenEvent(item : UTSJSONObject) : Promise<any> {
|
|
let id = item.getString(this.idKey)
|
|
if (id == null) {
|
|
return Promise.resolve(true);
|
|
}
|
|
|
|
this.$emit("childrenClick", item)
|
|
|
|
let idsIndex = -1;
|
|
for (let i = 0; i < this.openFLoderIds.length; i++) {
|
|
if (this.openFLoderIds[i] == id) {
|
|
idsIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 先判断 是不是父级,就是有没有children要展开。有就展开或者 关闭。没有不操作。
|
|
let children = this.getChildren(item)
|
|
let isOpenChildren = item.getArray('children')
|
|
// 只有有children字段的才可以异步打开继续加载数据。
|
|
if (isOpenChildren == null) {
|
|
this.checkBoxClickEvent(item)
|
|
return Promise.resolve(true);
|
|
}
|
|
|
|
if (idsIndex == -1 && children.length == 0) {
|
|
|
|
// 没有子级再判断有没有异步加载的数据。
|
|
let asyncList = await this.beforeOpenFloder(id)
|
|
let resultList = asyncList as UTSJSONObject[]
|
|
if (resultList.length > 0) {
|
|
let n = setChildrenByid(this._list, id, this.idKey, resultList)
|
|
item.set('children', resultList)
|
|
children = resultList
|
|
|
|
this.$emit('setChildrenData', id, this._list)
|
|
}
|
|
}
|
|
|
|
if (children.length == 0) {
|
|
// 没有子级触发title事件就行或者直接选中操作。
|
|
// this.checkBoxClickEvent(item)
|
|
|
|
return Promise.resolve(true);
|
|
}
|
|
|
|
|
|
if (idsIndex > -1) {
|
|
this.openFLoderIds.splice(idsIndex, 1)
|
|
} else {
|
|
this.openFLoderIds.push(id)
|
|
}
|
|
|
|
this.$emit('openFolderChange', this.openFLoderIds.slice(0), idsIndex == -1 ? 'open' : 'close', id)
|
|
|
|
return Promise.resolve(true);
|
|
},
|
|
setChildrenDataEnd(id : string, item : UTSJSONObject[]) {
|
|
let parent = findParentNode(this._list, id, this.idKey) as UTSJSONObject | null
|
|
|
|
if (parent == null) {
|
|
let index = this._list.findIndex((item) : boolean => id == item.getString(this.idKey)!)
|
|
if (index > -1) {
|
|
this._list[index].set('children', item)
|
|
this.$emit('setChildrenData', id, this._list)
|
|
}
|
|
} else {
|
|
let index = this._list.findIndex((item) : boolean => item!.getString(this.idKey) != parent!.getString(this.idKey)!)
|
|
if (index > -1) {
|
|
this._list[index].set('children', item)
|
|
this.$emit('setChildrenData', id, this._list)
|
|
}
|
|
}
|
|
|
|
|
|
},
|
|
isInOpenFloder(item : UTSJSONObject) : boolean {
|
|
let id = item.getString(this.idKey)
|
|
if (id == null) {
|
|
return false;
|
|
}
|
|
if (this.openFLoderIds.includes(id)) return true;
|
|
return false
|
|
},
|
|
getListItemHeight(item : UTSJSONObject) : number {
|
|
let id = item.getString(this.idKey)
|
|
if (id == null || !this.isInOpenFloder(item)) {
|
|
return 1;
|
|
}
|
|
let children = this.getChildren(item)
|
|
if (children.length == 0) return 1;
|
|
return children.length + 1
|
|
},
|
|
getChildren(item : UTSJSONObject) : UTSJSONObject[] {
|
|
let c = item.getArray<UTSJSONObject>('children')
|
|
if (c == null) return [] as UTSJSONObject[]
|
|
return c;
|
|
},
|
|
updateIds() {
|
|
// this.$emit()
|
|
},
|
|
|
|
openFolderChangeEnd(ids : string[], type : string, id : string) {
|
|
// let fullIds = new Set(this.openFLoderIds.concat(ids))
|
|
// let idsreal = [] as string[]
|
|
// fullIds.forEach((val : string) => {
|
|
// idsreal.push(val)
|
|
// })
|
|
// this.openFLoderIds = ids
|
|
this.$emit('openFolderChange', ids.slice(0), type, id)
|
|
},
|
|
childrenClickEnd(item : UTSJSONObject) {
|
|
this.$emit("childrenClick", item)
|
|
},
|
|
checkBoxClickEvent(item : UTSJSONObject) {
|
|
|
|
if (this.isDisabled(item)) {
|
|
return;
|
|
}
|
|
|
|
let id = item.getString(this.idKey)
|
|
if (id == null) {
|
|
return;
|
|
}
|
|
let idsIndex = -1;
|
|
for (let i = 0; i < this.nowIds.length; i++) {
|
|
if (this.nowIds[i] == id) {
|
|
idsIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
let sids = this.nowIds.slice(0)
|
|
|
|
let indeterminate = this.isIndeterminate(item)
|
|
let selected = this.isSelected(item)
|
|
|
|
if(idsIndex>-1){
|
|
sids.splice(idsIndex, 1)
|
|
if (this._parentSelectedFullChildren && this.getChildren(item).length > 0) {
|
|
let tmepids = flatChildrensId(item, this.idKey)
|
|
sids = sids.filter((el) : boolean => !tmepids.includes(el))
|
|
}
|
|
|
|
//如果不存在选中中,它可能是半选状态或者完全没有选中.
|
|
}else{
|
|
sids.push(id)
|
|
// 如果允许单选父,不影响子,需要单独处理,其它交给父组件处理
|
|
if (this._parentSelectedFullChildren && this.getChildren(item).length > 0) {
|
|
let tmepids = flatChildrensId(item, this.idKey)
|
|
// tmepids = tmepids.filter((yid:string):string => !this.nowIds.includes(yid))
|
|
sids = sids.concat(tmepids)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.nowIds = sids;
|
|
// 更新父节点状态
|
|
// this.updateParentNodeStatus();
|
|
this.$emit('change', this.nowIds.slice(0))
|
|
},
|
|
changeEnd(ids : string[]) {
|
|
// 当子节点状态变化时,更新当前节点状态
|
|
this.nowIds = ids.slice(0);
|
|
this.$emit('change', ids.slice(0))
|
|
},
|
|
|
|
|
|
isSelected(item : UTSJSONObject) : boolean {
|
|
let id = item.getString(this.idKey)
|
|
id = id == null ? "" : id;
|
|
return this.nowIds.includes(id)
|
|
},
|
|
// 检查节点是否处于半选状态(部分子节点被选中)
|
|
isIndeterminate(item : UTSJSONObject) : boolean {
|
|
// 如果节点已被选中,则不是半选状态
|
|
if (this.isSelected(item)) return false;
|
|
|
|
// 获取所有子节点ID
|
|
let children = this.getChildren(item);
|
|
if (children.length === 0) return false;
|
|
|
|
// 获取所有可选的子节点ID
|
|
let allChildrenIds = flatChildrensId(item, this.idKey);
|
|
if (allChildrenIds.length === 0) return false;
|
|
|
|
// 检查是否有部分子节点被选中
|
|
let selectedChildrenCount = 0;
|
|
for (let i = 0; i < allChildrenIds.length; i++) {
|
|
if (this.nowIds.includes(allChildrenIds[i])) {
|
|
selectedChildrenCount++;
|
|
|
|
}
|
|
}
|
|
|
|
// 如果有部分子节点被选中(不是全部也不是零个),则是半选状态
|
|
return selectedChildrenCount > 0 && selectedChildrenCount < allChildrenIds.length;
|
|
},
|
|
// 是否被禁用选择
|
|
isDisabled(item : UTSJSONObject) : boolean {
|
|
let children = this.getChildren(item)
|
|
// 自己的单独的禁用状态
|
|
let disabled = item.getBoolean("disabled")
|
|
disabled = disabled == null ? false : disabled
|
|
// 父级
|
|
if (children.length > 0) {
|
|
return this._disabledParentBox || disabled || this._disabled
|
|
}
|
|
return disabled || this._disabled
|
|
},
|
|
editeclick(){
|
|
if(this.nowediteItem==null) return;
|
|
if(this.nowediteItemText==''){
|
|
uni.showToast({title:"标题不能为空",icon:'none'})
|
|
return;
|
|
}
|
|
let item = this.nowediteItem!
|
|
let id = item.getString(this.idKey)!
|
|
|
|
if(this.editeType=='change'){
|
|
item.set(this.labelKey,this.nowediteItemText)
|
|
item.set(this.idKey,this.nowediteItemId)
|
|
let index = this._list.findIndex((item) : boolean => id == item.getString(this.idKey)!)
|
|
if (index > -1) {
|
|
this._list[index] = item
|
|
this.$emit('setChildrenData', id, this._list)
|
|
}
|
|
}else if(this.editeType == 'add'&&this.newItem!=null){
|
|
id = this.nowediteItemId
|
|
if(id==''){
|
|
id = Math.random().toString(16).substring(1,20)
|
|
}
|
|
this.newItem!.set(this.labelKey,this.nowediteItemText)
|
|
this.newItem!.set(this.idKey,id)
|
|
|
|
let nextChildre = this.getChildren(item)
|
|
if(nextChildre.length==0){
|
|
this.newItem!.set('children',[this.newItem!] as UTSJSONObject[])
|
|
}else{
|
|
nextChildre.push(this.newItem! as UTSJSONObject)
|
|
}
|
|
let index = this._list.findIndex((item) : boolean => id == item.getString(this.idKey)!)
|
|
if (index > -1) {
|
|
this._list[index] = item
|
|
this.$emit('setChildrenData', id, this._list)
|
|
}
|
|
|
|
this.nowediteItemId = ''
|
|
this.nowediteItemText = ''
|
|
}
|
|
|
|
|
|
},
|
|
isShowEdite(item:UTSJSONObject):Boolean{
|
|
let showEditeLabel = item.getBoolean('showEdite')
|
|
return showEditeLabel == true;
|
|
},
|
|
isShowAdd(item:UTSJSONObject):Boolean{
|
|
let showEditeLabel = item.getBoolean('showAdd')
|
|
return showEditeLabel == true;
|
|
},
|
|
|
|
isShowRemove(item:UTSJSONObject):Boolean{
|
|
let showEditeLabel = item.getBoolean('showRemove')
|
|
return showEditeLabel == true;
|
|
},
|
|
showModalEdte(item:UTSJSONObject,editeType:string){
|
|
if(editeType == 'add'){
|
|
let newitem = {
|
|
disabled:false,
|
|
showEdite:false,
|
|
showRemove:true
|
|
} as UTSJSONObject
|
|
newitem.set(this.labelKey,"")
|
|
newitem.set(this.idKey,"")
|
|
this.newItem = newitem
|
|
}
|
|
let disabled = this.isDisabled(item)
|
|
this.editeType = editeType;
|
|
if(disabled) return;
|
|
this.nowediteItem = item;
|
|
if(editeType == 'change'){
|
|
this.nowediteItemText = item.getString(this.labelKey)==null?'':item.getString(this.labelKey)!
|
|
this.nowediteItemId = item.getString(this.idKey)==null?'':item.getString(this.idKey)!
|
|
}else if(editeType == 'add'){
|
|
this.nowediteItemId = ''
|
|
this.nowediteItemText = ''
|
|
}
|
|
this.showModal = true;
|
|
},
|
|
removeItem(item:UTSJSONObject){
|
|
console.log(this._list)
|
|
let t = this;
|
|
uni.showModal({
|
|
title:"提醒",
|
|
content:"确认删除?",
|
|
success(res){
|
|
if(res.confirm){
|
|
|
|
let id = item.getString(t.idKey)!
|
|
let index = t._list.findIndex((item:UTSJSONObject) : boolean => id == item.getString(t.idKey)!)
|
|
if (index > -1) {
|
|
t._list.splice(index,1)
|
|
t.$emit('setChildrenData', id, t._list)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<template>
|
|
<view class="xTree">
|
|
<!-- 'add'?'添加下级':'修改内容'" -->
|
|
<x-modal height="auto" @confirm="editeclick"
|
|
:title="editeType=='add'?(i18n!.t('tmui4x.tree.addTitle')):(i18n!.t('tmui4x.tree.changeTitle'))"
|
|
v-model:show="showModal">
|
|
<view v-if="nowediteItem!=null">
|
|
<x-input dark-bg-color="" height="48" v-model="nowediteItemText">
|
|
<template v-slot:inputLeft>
|
|
<!-- 标题值 -->
|
|
<x-text _style="padding:0 12px">
|
|
{{i18n!.t('tmui4x.tree.inputTitle')}}
|
|
</x-text>
|
|
</template>
|
|
</x-input>
|
|
<view style="height:10px"></view>
|
|
<x-input dark-bg-color="" height="48" :placeholder="i18n!.t('tmui4x.tree.inputTips1')" v-model="nowediteItemId">
|
|
<template v-slot:inputLeft>
|
|
<!-- 标识ID -->
|
|
<x-text _style="padding:0 12px">{{i18n!.t('tmui4x.tree.inputId')}}</x-text>
|
|
</template>
|
|
</x-input>
|
|
</view>
|
|
</x-modal>
|
|
<view class="xTreeItemCell" v-for="(item,index) in _list" :key="index">
|
|
<view
|
|
:hover-start-time="5" :hover-stay-time="30" :hover-class="getChildren(item).length>0?'hoverClass':'hoverClassOff'"
|
|
@click.stop="childrenEvent(item)" :style="{height:'50px'}" class="xTreeItemCellWrap">
|
|
<view class="xTreeItemCellWrapLeft">
|
|
<view v-if="item.getArray('children')!=null&&_showFloaderIcon" class="xTreeItemCellWrapLeftIcon">
|
|
<x-icon color="#333333" v-if="!isInOpenFloder(item)" font-size="21"
|
|
:name="_floaderIcon[0]"></x-icon>
|
|
<x-icon :color="_color" v-if="isInOpenFloder(item)" font-size="21"
|
|
:name="_floaderIcon[1]"></x-icon>
|
|
|
|
</view>
|
|
<text :style="{color:isSelected(item)?_color:_itemColor,fontSize:_fontSize}"
|
|
class="xTreeItemCellWrapLeftText">{{item.getString(labelKey)}}</text>
|
|
</view>
|
|
<view v-if="isShowAdd(item)" :hover-start-time="5" :hover-stay-time="30" hover-class="hoverClass"
|
|
@click.stop="showModalEdte(item,'add')" style="margin-right:10px;" >
|
|
<x-icon :color="!isDisabled(item)?_color:'#cecece'" font-size="21"
|
|
name="add-large-line"></x-icon>
|
|
</view>
|
|
<view v-if="isShowEdite(item)" :hover-start-time="5" :hover-stay-time="30" hover-class="hoverClass"
|
|
@click.stop="showModalEdte(item,'change')" style="margin-right:10px;" >
|
|
<x-icon :color="!isDisabled(item)?_color:'#cecece'" font-size="21"
|
|
name="edit-box-line"></x-icon>
|
|
</view>
|
|
<view v-if="isShowRemove(item)" :hover-start-time="5" :hover-stay-time="30" hover-class="hoverClass"
|
|
@click.stop="removeItem(item)" style="margin-right:10px;" >
|
|
<x-icon :color="!isDisabled(item)?_color:'#cecece'" font-size="21"
|
|
name="delete-bin-2-line"></x-icon>
|
|
</view>
|
|
<view v-if="_showChecked" :hover-start-time="5" :hover-stay-time="30" hover-class="hoverClass"
|
|
@click.stop="checkBoxClickEvent(item)" :style="{opacity:isDisabled(item)?'0.3':'1'}">
|
|
<x-icon v-if="_parentSelectedFullChildren" :color="isSelected(item) || isIndeterminate(item) ? _color : '#cecece'" font-size="21"
|
|
:name="isSelected(item) ? _checkedIcon[1] : (isIndeterminate(item) ? 'indeterminate-circle-line' : _checkedIcon[0])"></x-icon>
|
|
<x-icon v-else :color="isSelected(item) ? _color : '#cecece'" font-size="21"
|
|
:name="isSelected(item) ? _checkedIcon[1] : _checkedIcon[0]"></x-icon>
|
|
|
|
|
|
</view>
|
|
</view>
|
|
<x-tree-item
|
|
:checkedIcon="checkedIcon"
|
|
:showChecked="_showChecked"
|
|
:showFloaderIcon="showFloaderIcon"
|
|
:floaderIcon="floaderIcon"
|
|
@childrenClick="childrenClickEnd" @openFolderChange="openFolderChangeEnd"
|
|
@setChildrenData="setChildrenDataEnd" :beforeOpenFloder="beforeOpenFloder"
|
|
:parentSelectedFullChildren="_parentSelectedFullChildren" :disabled="_disabled"
|
|
:disabledParentBox="_disabledParentBox" @change="changeEnd" :idList="nowIds" :color="_color"
|
|
:folderId="openFLoderIds" :idKey="idKey" :labelKey="labelKey" style="margin-left: 30px;"
|
|
v-if="isInOpenFloder(item)&&showChildren" :list="getChildren(item)" v-model="nowIds"></x-tree-item>
|
|
</view>
|
|
|
|
</view>
|
|
</template>
|
|
<style scoped>
|
|
.hoverClass {
|
|
background-color: rgba(0, 0, 0, 0.03);
|
|
}
|
|
.hoverClassOff {
|
|
background-color: transparent;
|
|
}
|
|
.xTreeItemCellWrapLeftText {
|
|
flex: 1;
|
|
text-overflow: ellipsis;
|
|
lines: 2;
|
|
/* #ifndef APP */
|
|
display: -webkit-box;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
word-break: break-all;
|
|
-webkit-line-clamp: 2;
|
|
/* #endif */
|
|
}
|
|
|
|
.xTreeItemCellWrapLeftIcon {
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: flex-start;
|
|
align-items: center;
|
|
width: 30px;
|
|
}
|
|
|
|
.xTreeItemCellWrapLeft {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: flex-start;
|
|
align-items: center;
|
|
}
|
|
|
|
.xTreeItemCellWrap {
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
border-bottom: 1px solid rgba(0, 0, 0, 0.03);
|
|
|
|
}
|
|
</style> |