1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ciimport './LitTreeNode'; 17fb726d48Sopenharmony_ciimport { BaseElement, element } from '../BaseElement'; 18fb726d48Sopenharmony_ciimport { type LitTreeNode } from './LitTreeNode'; 19fb726d48Sopenharmony_ci 20fb726d48Sopenharmony_ciexport interface TreeItemData { 21fb726d48Sopenharmony_ci key: string; 22fb726d48Sopenharmony_ci title: string; 23fb726d48Sopenharmony_ci icon?: string; //节点的自定义图标 设置show-icon才会生效 24fb726d48Sopenharmony_ci selected?: boolean; //控制是否选择该节点 25fb726d48Sopenharmony_ci checked?: boolean; 26fb726d48Sopenharmony_ci disable?: boolean; //控制是否显示checkbox 27fb726d48Sopenharmony_ci children?: Array<TreeItemData> | null | undefined; 28fb726d48Sopenharmony_ci} 29fb726d48Sopenharmony_ci 30fb726d48Sopenharmony_ci@element('lit-tree') 31fb726d48Sopenharmony_ciexport class LitTree extends BaseElement { 32fb726d48Sopenharmony_ci private _treeData: Array<TreeItemData> = []; 33fb726d48Sopenharmony_ci private currentSelectedNode: unknown; 34fb726d48Sopenharmony_ci private currentSelectedData: unknown; 35fb726d48Sopenharmony_ci private proxyData: unknown; 36fb726d48Sopenharmony_ci private nodeList: Array<LitTreeNode> = []; 37fb726d48Sopenharmony_ci private contextMenu: HTMLDivElement | null | undefined; 38fb726d48Sopenharmony_ci private srcDragElement: unknown; 39fb726d48Sopenharmony_ci private dragDirection: string | null | undefined; 40fb726d48Sopenharmony_ci 41fb726d48Sopenharmony_ci static get observedAttributes(): string[] { 42fb726d48Sopenharmony_ci return ['show-line', 'show-icon', 'checkable', 'foldable', 'dragable', 'multiple']; //foldable 表示点击目录是否可以折叠 43fb726d48Sopenharmony_ci } 44fb726d48Sopenharmony_ci 45fb726d48Sopenharmony_ci set treeData(value: Array<TreeItemData>) { 46fb726d48Sopenharmony_ci this._treeData = value; 47fb726d48Sopenharmony_ci this.shadowRoot!.querySelector('#root')!.innerHTML = ''; 48fb726d48Sopenharmony_ci this.nodeList = []; 49fb726d48Sopenharmony_ci this.drawTree(this.shadowRoot!.querySelector('#root'), value, true); 50fb726d48Sopenharmony_ci 51fb726d48Sopenharmony_ci /*双向绑定*/ 52fb726d48Sopenharmony_ci const handler = { 53fb726d48Sopenharmony_ci get: (target: unknown, propkey: unknown): unknown => { 54fb726d48Sopenharmony_ci //@ts-ignore 55fb726d48Sopenharmony_ci return target[propkey]; 56fb726d48Sopenharmony_ci }, 57fb726d48Sopenharmony_ci set: (target: unknown, propkey: unknown, value: unknown, receiver: unknown): boolean => { 58fb726d48Sopenharmony_ci //@ts-ignore 59fb726d48Sopenharmony_ci if (target[propkey] !== value) { 60fb726d48Sopenharmony_ci //@ts-ignore 61fb726d48Sopenharmony_ci if (!value.children) { 62fb726d48Sopenharmony_ci //@ts-ignore 63fb726d48Sopenharmony_ci value.children = new Proxy([], handler); 64fb726d48Sopenharmony_ci } else { 65fb726d48Sopenharmony_ci //@ts-ignore 66fb726d48Sopenharmony_ci value.children = new Proxy(value.children, handler); 67fb726d48Sopenharmony_ci } //@ts-ignore 68fb726d48Sopenharmony_ci target[propkey] = value; 69fb726d48Sopenharmony_ci if (!this.currentSelectedNode) { 70fb726d48Sopenharmony_ci this._insertNode(null, value); 71fb726d48Sopenharmony_ci } else { 72fb726d48Sopenharmony_ci //@ts-ignore 73fb726d48Sopenharmony_ci if (this.currentSelectedNode.nextElementSibling) { 74fb726d48Sopenharmony_ci //@ts-ignore 75fb726d48Sopenharmony_ci this._insertNode(this.currentSelectedNode.nextElementSibling, value); 76fb726d48Sopenharmony_ci } else { 77fb726d48Sopenharmony_ci //@ts-ignore 78fb726d48Sopenharmony_ci this.currentSelectedNode.setAttribute('show-arrow', 'true'); 79fb726d48Sopenharmony_ci let ul = document.createElement('ul'); 80fb726d48Sopenharmony_ci // @ts-ignore 81fb726d48Sopenharmony_ci ul.open = 'true'; 82fb726d48Sopenharmony_ci ul.style.transition = '.3s all'; //@ts-ignore 83fb726d48Sopenharmony_ci this.currentSelectedNode.parentElement.append(ul); //@ts-ignore 84fb726d48Sopenharmony_ci this.currentSelectedNode.arrow = true; 85fb726d48Sopenharmony_ci this._insertNode(ul, value); 86fb726d48Sopenharmony_ci } 87fb726d48Sopenharmony_ci } 88fb726d48Sopenharmony_ci } 89fb726d48Sopenharmony_ci return true; 90fb726d48Sopenharmony_ci }, 91fb726d48Sopenharmony_ci }; 92fb726d48Sopenharmony_ci let setProxy = (v: Array<TreeItemData>): void => { 93fb726d48Sopenharmony_ci v.forEach((a) => { 94fb726d48Sopenharmony_ci if (!a.children) { 95fb726d48Sopenharmony_ci //@ts-ignore 96fb726d48Sopenharmony_ci a.children = new Proxy([], handler); 97fb726d48Sopenharmony_ci } else { 98fb726d48Sopenharmony_ci //@ts-ignore 99fb726d48Sopenharmony_ci a.children = new Proxy(a.children, handler); 100fb726d48Sopenharmony_ci setProxy(a.children || []); 101fb726d48Sopenharmony_ci } 102fb726d48Sopenharmony_ci }); 103fb726d48Sopenharmony_ci }; 104fb726d48Sopenharmony_ci setProxy(this._treeData); 105fb726d48Sopenharmony_ci this.proxyData = new Proxy(this._treeData, handler); 106fb726d48Sopenharmony_ci } 107fb726d48Sopenharmony_ci 108fb726d48Sopenharmony_ci get multiple(): boolean { 109fb726d48Sopenharmony_ci return this.hasAttribute('multiple'); 110fb726d48Sopenharmony_ci } 111fb726d48Sopenharmony_ci 112fb726d48Sopenharmony_ci set multiple(value: boolean) { 113fb726d48Sopenharmony_ci if (value) { 114fb726d48Sopenharmony_ci this.setAttribute('multiple', ''); 115fb726d48Sopenharmony_ci } else { 116fb726d48Sopenharmony_ci this.removeAttribute('multiple'); 117fb726d48Sopenharmony_ci } 118fb726d48Sopenharmony_ci } 119fb726d48Sopenharmony_ci 120fb726d48Sopenharmony_ci get treeData(): TreeItemData[] { 121fb726d48Sopenharmony_ci //@ts-ignore 122fb726d48Sopenharmony_ci return this.proxyData; 123fb726d48Sopenharmony_ci } 124fb726d48Sopenharmony_ci 125fb726d48Sopenharmony_ci set onSelect(fn: unknown) { 126fb726d48Sopenharmony_ci //@ts-ignore 127fb726d48Sopenharmony_ci this.addEventListener('onSelect', fn); 128fb726d48Sopenharmony_ci } 129fb726d48Sopenharmony_ci 130fb726d48Sopenharmony_ci set onChange(fn: unknown) { 131fb726d48Sopenharmony_ci //@ts-ignore 132fb726d48Sopenharmony_ci this.addEventListener('onChange', fn); 133fb726d48Sopenharmony_ci } 134fb726d48Sopenharmony_ci 135fb726d48Sopenharmony_ci set foldable(value: unknown) { 136fb726d48Sopenharmony_ci if (value) { 137fb726d48Sopenharmony_ci this.setAttribute('foldable', ''); 138fb726d48Sopenharmony_ci } else { 139fb726d48Sopenharmony_ci this.removeAttribute('foldable'); 140fb726d48Sopenharmony_ci } 141fb726d48Sopenharmony_ci } 142fb726d48Sopenharmony_ci 143fb726d48Sopenharmony_ci //当 custom element首次被插入文档DOM时,被调用。 144fb726d48Sopenharmony_ci connectedCallback(): void { 145fb726d48Sopenharmony_ci this.onclick = (ev): void => { 146fb726d48Sopenharmony_ci this.contextMenu!.style.display = 'none'; 147fb726d48Sopenharmony_ci this.currentSelectedData = null; 148fb726d48Sopenharmony_ci this.currentSelectedNode = null; 149fb726d48Sopenharmony_ci this.selectedNode(null); 150fb726d48Sopenharmony_ci }; 151fb726d48Sopenharmony_ci } 152fb726d48Sopenharmony_ci 153fb726d48Sopenharmony_ci getCheckdKeys(): unknown[] { 154fb726d48Sopenharmony_ci //@ts-ignore 155fb726d48Sopenharmony_ci return Array.from(this.shadowRoot!.querySelectorAll('lit-tree-node[checked]')).map((a: unknown) => a.data.key); 156fb726d48Sopenharmony_ci } 157fb726d48Sopenharmony_ci 158fb726d48Sopenharmony_ci getCheckdNodes(): unknown[] { 159fb726d48Sopenharmony_ci //@ts-ignore 160fb726d48Sopenharmony_ci return Array.from(this.shadowRoot!.querySelectorAll('lit-tree-node[checked]')).map((a: unknown) => a.data); 161fb726d48Sopenharmony_ci } 162fb726d48Sopenharmony_ci 163fb726d48Sopenharmony_ci //展开所有节点 164fb726d48Sopenharmony_ci expandKeys(keys: Array<string>): void { 165fb726d48Sopenharmony_ci keys.forEach((k) => 166fb726d48Sopenharmony_ci //@ts-ignore 167fb726d48Sopenharmony_ci this.shadowRoot!.querySelectorAll(`lit-tree-node[key='${k}']`).forEach((b: unknown) => b.expand()) 168fb726d48Sopenharmony_ci ); 169fb726d48Sopenharmony_ci } 170fb726d48Sopenharmony_ci 171fb726d48Sopenharmony_ci collapseKeys(keys: Array<string>): void { 172fb726d48Sopenharmony_ci keys.forEach((k) => 173fb726d48Sopenharmony_ci //@ts-ignore 174fb726d48Sopenharmony_ci this.shadowRoot!.querySelectorAll(`lit-tree-node[key='${k}']`).forEach((b: unknown) => b.collapse()) 175fb726d48Sopenharmony_ci ); 176fb726d48Sopenharmony_ci } 177fb726d48Sopenharmony_ci 178fb726d48Sopenharmony_ci checkedKeys(keys: Array<string>): void { 179fb726d48Sopenharmony_ci keys.forEach((k) => 180fb726d48Sopenharmony_ci this.shadowRoot!.querySelectorAll(`lit-tree-node[key='${k}']`).forEach((b: unknown) => { 181fb726d48Sopenharmony_ci //@ts-ignore 182fb726d48Sopenharmony_ci b.setAttribute('checked', 'true'); 183fb726d48Sopenharmony_ci //@ts-ignore 184fb726d48Sopenharmony_ci b.checkHandler(); 185fb726d48Sopenharmony_ci }) 186fb726d48Sopenharmony_ci ); 187fb726d48Sopenharmony_ci } 188fb726d48Sopenharmony_ci 189fb726d48Sopenharmony_ci uncheckedKeys(keys: Array<string>): void { 190fb726d48Sopenharmony_ci keys.forEach((k) => 191fb726d48Sopenharmony_ci this.shadowRoot!.querySelectorAll(`lit-tree-node[key='${k}']`).forEach((b: unknown) => { 192fb726d48Sopenharmony_ci //@ts-ignore 193fb726d48Sopenharmony_ci b.removeAttribute('checked'); //@ts-ignore 194fb726d48Sopenharmony_ci b.removeAttribute('missing'); //@ts-ignore 195fb726d48Sopenharmony_ci b.checkHandler(); 196fb726d48Sopenharmony_ci }) 197fb726d48Sopenharmony_ci ); 198fb726d48Sopenharmony_ci } 199fb726d48Sopenharmony_ci 200fb726d48Sopenharmony_ci drawTree(parent: unknown, array: Array<TreeItemData>, topDepth: boolean = false): void { 201fb726d48Sopenharmony_ci array.forEach((a: TreeItemData) => { 202fb726d48Sopenharmony_ci let li: HTMLLIElement = document.createElement('li'); 203fb726d48Sopenharmony_ci let node: LitTreeNode = document.createElement('lit-tree-node') as LitTreeNode; 204fb726d48Sopenharmony_ci node.title = a.title; 205fb726d48Sopenharmony_ci node.setAttribute('key', a.key); 206fb726d48Sopenharmony_ci node.topDepth = topDepth; 207fb726d48Sopenharmony_ci this.treeNodeDragable(node, a); 208fb726d48Sopenharmony_ci // @ts-ignore 209fb726d48Sopenharmony_ci li.data = a; 210fb726d48Sopenharmony_ci li.append(node); //@ts-ignore 211fb726d48Sopenharmony_ci parent.append(li); 212fb726d48Sopenharmony_ci let ul: HTMLUListElement = document.createElement('ul'); 213fb726d48Sopenharmony_ci // @ts-ignore 214fb726d48Sopenharmony_ci ul.open = 'true'; 215fb726d48Sopenharmony_ci ul.style.transition = '.3s all'; 216fb726d48Sopenharmony_ci this.addEvent(a, node, li, ul); 217fb726d48Sopenharmony_ci // node 添加右键菜单功能 218fb726d48Sopenharmony_ci node.oncontextmenu = (ev): void => { 219fb726d48Sopenharmony_ci ev.preventDefault(); 220fb726d48Sopenharmony_ci this.selectedNode(node); 221fb726d48Sopenharmony_ci this.currentSelectedNode = node; 222fb726d48Sopenharmony_ci this.currentSelectedData = node.data; 223fb726d48Sopenharmony_ci this.contextMenu!.style.display = 'block'; 224fb726d48Sopenharmony_ci this.contextMenu!.style.left = ev.pageX + 'px'; 225fb726d48Sopenharmony_ci this.contextMenu!.style.top = ev.pageY + 'px'; 226fb726d48Sopenharmony_ci }; 227fb726d48Sopenharmony_ci }); 228fb726d48Sopenharmony_ci this.oncontextmenu = (ev): void => { 229fb726d48Sopenharmony_ci ev.preventDefault(); 230fb726d48Sopenharmony_ci this.contextMenu!.style.display = 'block'; 231fb726d48Sopenharmony_ci this.contextMenu!.style.left = ev.pageX + 'px'; 232fb726d48Sopenharmony_ci this.contextMenu!.style.top = ev.pageY + 'px'; 233fb726d48Sopenharmony_ci }; 234fb726d48Sopenharmony_ci } 235fb726d48Sopenharmony_ci 236fb726d48Sopenharmony_ci treeNodeDragable(node: LitTreeNode, a: TreeItemData): void { 237fb726d48Sopenharmony_ci let that = this; 238fb726d48Sopenharmony_ci if (this.hasAttribute('dragable')) { 239fb726d48Sopenharmony_ci node.draggable = true; 240fb726d48Sopenharmony_ci document.ondragover = function (e) { 241fb726d48Sopenharmony_ci e.preventDefault(); 242fb726d48Sopenharmony_ci }; 243fb726d48Sopenharmony_ci //在拖动目标上触发事件 (源元素) 244fb726d48Sopenharmony_ci node.ondrag = (ev) => this.onDrag(ev); //元素正在拖动时触发 245fb726d48Sopenharmony_ci node.ondragstart = (ev) => this.onDragStart(ev); //用户开始拖动元素时触发 246fb726d48Sopenharmony_ci node.ondragend = (ev) => this.onDragEnd(ev); // 用户完成元素拖动后触发 247fb726d48Sopenharmony_ci //释放目标时触发的事件: 248fb726d48Sopenharmony_ci node.ondragenter = (ev) => this.onDragEnter(ev); //当被鼠标拖动的对象进入其容器范围内时触发此事件 249fb726d48Sopenharmony_ci node.ondragover = (ev) => this.onDragOver(ev); //当某被拖动的对象在另一对象容器范围内拖动时触发此事件 250fb726d48Sopenharmony_ci node.ondragleave = (ev) => this.onDragLeave(ev); //当被鼠标拖动的对象离开其容器范围内时触发此事件 251fb726d48Sopenharmony_ci node.ondrop = (ev) => this.onDrop(ev); //在一个拖动过程中,释放鼠标键时触发此事件 252fb726d48Sopenharmony_ci } 253fb726d48Sopenharmony_ci node.selected = a.selected || false; //是否选中行 254fb726d48Sopenharmony_ci node.checked = a.checked || false; // 是否勾选 255fb726d48Sopenharmony_ci node.data = a; 256fb726d48Sopenharmony_ci node.addEventListener('change', (e: unknown): void => { 257fb726d48Sopenharmony_ci //@ts-ignore 258fb726d48Sopenharmony_ci if (e.detail && !this.multiple) { 259fb726d48Sopenharmony_ci this.nodeList.forEach((item) => { 260fb726d48Sopenharmony_ci item.checked = item.data!.key === node.data!.key; 261fb726d48Sopenharmony_ci item.data!.checked = item.checked; 262fb726d48Sopenharmony_ci }); 263fb726d48Sopenharmony_ci } 264fb726d48Sopenharmony_ci let litTreeNodes = this.nodeList.filter((it) => it.checked); 265fb726d48Sopenharmony_ci if (litTreeNodes.length === 0) { 266fb726d48Sopenharmony_ci node.checked = true; 267fb726d48Sopenharmony_ci node.data!.checked = true; 268fb726d48Sopenharmony_ci } //@ts-ignore 269fb726d48Sopenharmony_ci that.dispatchEvent(new CustomEvent('onChange', { detail: { data: (node as unknown).data, checked: e.detail } })); 270fb726d48Sopenharmony_ci }); 271fb726d48Sopenharmony_ci node.multiple = this.hasAttribute('multiple'); 272fb726d48Sopenharmony_ci node.checkable = this.getAttribute('checkable') || 'false'; 273fb726d48Sopenharmony_ci this.nodeList.push(node); 274fb726d48Sopenharmony_ci } 275fb726d48Sopenharmony_ci 276fb726d48Sopenharmony_ci addEvent(a: TreeItemData, node: LitTreeNode, li: HTMLLIElement, ul: HTMLUListElement): void { 277fb726d48Sopenharmony_ci if (a.children && a.children.length > 0) { 278fb726d48Sopenharmony_ci if (this.hasAttribute('show-icon')) { 279fb726d48Sopenharmony_ci if (a.icon) { 280fb726d48Sopenharmony_ci //@ts-ignore 281fb726d48Sopenharmony_ci (node as unknown).iconName = a.icon; 282fb726d48Sopenharmony_ci } else { 283fb726d48Sopenharmony_ci //@ts-ignore 284fb726d48Sopenharmony_ci (node as unknown).iconName = 'folder'; 285fb726d48Sopenharmony_ci } 286fb726d48Sopenharmony_ci } else { 287fb726d48Sopenharmony_ci node.iconName = ''; 288fb726d48Sopenharmony_ci } 289fb726d48Sopenharmony_ci node.arrow = true; 290fb726d48Sopenharmony_ci li.append(ul); 291fb726d48Sopenharmony_ci this.drawTree(ul, a.children); 292fb726d48Sopenharmony_ci } else { 293fb726d48Sopenharmony_ci if (this.hasAttribute('show-icon')) { 294fb726d48Sopenharmony_ci if (a.icon) { 295fb726d48Sopenharmony_ci node.iconName = a.icon; 296fb726d48Sopenharmony_ci } else { 297fb726d48Sopenharmony_ci node.iconName = 'file'; 298fb726d48Sopenharmony_ci } 299fb726d48Sopenharmony_ci } else { 300fb726d48Sopenharmony_ci node.iconName = ''; 301fb726d48Sopenharmony_ci } 302fb726d48Sopenharmony_ci node.arrow = false; 303fb726d48Sopenharmony_ci } 304fb726d48Sopenharmony_ci li.onclick = (e): void => { 305fb726d48Sopenharmony_ci e.stopPropagation(); 306fb726d48Sopenharmony_ci if (this.hasAttribute('foldable')) { 307fb726d48Sopenharmony_ci // @ts-ignore 308fb726d48Sopenharmony_ci if (li.data.children && li.data.children.length > 0) { 309fb726d48Sopenharmony_ci node.autoExpand(); 310fb726d48Sopenharmony_ci } else { 311fb726d48Sopenharmony_ci // @ts-ignore 312fb726d48Sopenharmony_ci this.dispatchEvent(new CustomEvent('onSelect', { detail: li.data })); 313fb726d48Sopenharmony_ci this.selectedNode(node); 314fb726d48Sopenharmony_ci } 315fb726d48Sopenharmony_ci } else { 316fb726d48Sopenharmony_ci // @ts-ignore 317fb726d48Sopenharmony_ci this.dispatchEvent(new CustomEvent('onSelect', { detail: li.data })); 318fb726d48Sopenharmony_ci this.selectedNode(node); 319fb726d48Sopenharmony_ci } 320fb726d48Sopenharmony_ci }; 321fb726d48Sopenharmony_ci } 322fb726d48Sopenharmony_ci 323fb726d48Sopenharmony_ci //取消所有节点的选中状态 然后选中当前node节点 324fb726d48Sopenharmony_ci selectedNode(node: LitTreeNode | null | undefined): void { 325fb726d48Sopenharmony_ci this.shadowRoot!.querySelectorAll<LitTreeNode>('lit-tree-node').forEach((a) => { 326fb726d48Sopenharmony_ci a.selected = false; 327fb726d48Sopenharmony_ci }); 328fb726d48Sopenharmony_ci if (node) { 329fb726d48Sopenharmony_ci node.selected = true; 330fb726d48Sopenharmony_ci } 331fb726d48Sopenharmony_ci } 332fb726d48Sopenharmony_ci 333fb726d48Sopenharmony_ci closeContextMenu(): void { 334fb726d48Sopenharmony_ci this.contextMenu!.style.display = 'none'; 335fb726d48Sopenharmony_ci } 336fb726d48Sopenharmony_ci 337fb726d48Sopenharmony_ci onDrag(e: MouseEvent): void { } 338fb726d48Sopenharmony_ci 339fb726d48Sopenharmony_ci onDragStart(ev: MouseEvent): undefined { 340fb726d48Sopenharmony_ci this.srcDragElement = ev.target; 341fb726d48Sopenharmony_ci (ev.target! as LitTreeNode).open = 'true'; 342fb726d48Sopenharmony_ci (ev.target! as LitTreeNode).autoExpand(); 343fb726d48Sopenharmony_ci return undefined; 344fb726d48Sopenharmony_ci } 345fb726d48Sopenharmony_ci 346fb726d48Sopenharmony_ci onDragEnd(ev: MouseEvent): undefined { 347fb726d48Sopenharmony_ci this.srcDragElement = null; 348fb726d48Sopenharmony_ci return undefined; 349fb726d48Sopenharmony_ci } 350fb726d48Sopenharmony_ci 351fb726d48Sopenharmony_ci onDragEnter(ev: MouseEvent): undefined { 352fb726d48Sopenharmony_ci (ev.target as LitTreeNode).style.backgroundColor = '#42b98333'; 353fb726d48Sopenharmony_ci return undefined; 354fb726d48Sopenharmony_ci } 355fb726d48Sopenharmony_ci 356fb726d48Sopenharmony_ci onDragOver(ev: MouseEvent): undefined { 357fb726d48Sopenharmony_ci let node = ev.target as LitTreeNode; //@ts-ignore 358fb726d48Sopenharmony_ci if (this.srcDragElement.data.key === node.data!.key) { 359fb726d48Sopenharmony_ci return undefined; 360fb726d48Sopenharmony_ci } //@ts-ignore 361fb726d48Sopenharmony_ci let rect = (ev.currentTarget! as unknown).getBoundingClientRect(); 362fb726d48Sopenharmony_ci if (ev.clientX >= rect.left + rect.width / 3 && ev.clientX < rect.left + rect.width) { 363fb726d48Sopenharmony_ci //bottom-right 364fb726d48Sopenharmony_ci this.dragDirection = 'bottom-right'; 365fb726d48Sopenharmony_ci node.drawLine('bottom-right'); 366fb726d48Sopenharmony_ci } else if (ev.clientY >= rect.top && ev.clientY < rect.top + rect.height / 2) { 367fb726d48Sopenharmony_ci //上面 368fb726d48Sopenharmony_ci this.dragDirection = 'top'; 369fb726d48Sopenharmony_ci node.drawLine('top'); 370fb726d48Sopenharmony_ci } else if (ev.clientY <= rect.bottom && ev.clientY > rect.top + rect.height / 2) { 371fb726d48Sopenharmony_ci //下面 372fb726d48Sopenharmony_ci this.dragDirection = 'bottom'; 373fb726d48Sopenharmony_ci node.drawLine('bottom'); 374fb726d48Sopenharmony_ci } 375fb726d48Sopenharmony_ci return undefined; 376fb726d48Sopenharmony_ci } 377fb726d48Sopenharmony_ci 378fb726d48Sopenharmony_ci onDragLeave(ev: MouseEvent): undefined { 379fb726d48Sopenharmony_ci (ev.target as LitTreeNode).style.backgroundColor = '#ffffff00'; 380fb726d48Sopenharmony_ci (ev.target as LitTreeNode).drawLine(''); 381fb726d48Sopenharmony_ci return undefined; 382fb726d48Sopenharmony_ci } 383fb726d48Sopenharmony_ci 384fb726d48Sopenharmony_ci onDrop(ev: MouseEvent): undefined { 385fb726d48Sopenharmony_ci (ev.target as LitTreeNode).style.backgroundColor = '#ffffff00'; 386fb726d48Sopenharmony_ci (ev.target as LitTreeNode).drawLine(''); 387fb726d48Sopenharmony_ci //移动的不是node节点 而是上层的li节点 388fb726d48Sopenharmony_ci //@ts-ignore 389fb726d48Sopenharmony_ci let srcData = this.srcDragElement.data; //获取原节点的data数据 390fb726d48Sopenharmony_ci let dstData = (ev.target as LitTreeNode).data; //获取目标节点的data数据 391fb726d48Sopenharmony_ci if (srcData.key === dstData!.key) { 392fb726d48Sopenharmony_ci return undefined; 393fb726d48Sopenharmony_ci } //同一个节点不用处理 394fb726d48Sopenharmony_ci //@ts-ignore 395fb726d48Sopenharmony_ci let srcElement = this.srcDragElement.parentElement; 396fb726d48Sopenharmony_ci let srcParentElement = srcElement.parentElement; 397fb726d48Sopenharmony_ci let dstElement = (ev.target as LitTreeNode).parentElement; 398fb726d48Sopenharmony_ci srcElement.parentElement.removeChild(srcElement); //node li ul 从 ul 中移除 li 399fb726d48Sopenharmony_ci if (this.dragDirection === 'top') { 400fb726d48Sopenharmony_ci dstElement!.parentElement!.insertBefore(srcElement, dstElement); 401fb726d48Sopenharmony_ci } else if (this.dragDirection === 'bottom') { 402fb726d48Sopenharmony_ci dstElement!.parentElement!.insertBefore(srcElement, dstElement!.nextSibling); 403fb726d48Sopenharmony_ci } else if (this.dragDirection === 'bottom-right') { 404fb726d48Sopenharmony_ci let ul = dstElement!.querySelector('ul'); 405fb726d48Sopenharmony_ci if (!ul) { 406fb726d48Sopenharmony_ci ul = document.createElement('ul'); 407fb726d48Sopenharmony_ci ul.style.cssText = 'transition: all 0.3s ease 0s;'; 408fb726d48Sopenharmony_ci dstElement!.appendChild(ul); 409fb726d48Sopenharmony_ci } 410fb726d48Sopenharmony_ci dstElement!.querySelector<LitTreeNode>('lit-tree-node')!.arrow = true; //拖动进入子节点,需要开启箭头 411fb726d48Sopenharmony_ci ul.appendChild(srcElement); 412fb726d48Sopenharmony_ci } 413fb726d48Sopenharmony_ci let ul1 = dstElement!.querySelector('ul'); //如果拖动后目标节点的子节点没有记录,需要关闭arrow箭头 414fb726d48Sopenharmony_ci if (ul1) { 415fb726d48Sopenharmony_ci if (ul1.childElementCount === 0) { 416fb726d48Sopenharmony_ci (ul1.previousElementSibling! as LitTreeNode).arrow = false; 417fb726d48Sopenharmony_ci } 418fb726d48Sopenharmony_ci } 419fb726d48Sopenharmony_ci if (srcParentElement.childElementCount === 0) { 420fb726d48Sopenharmony_ci srcParentElement.previousElementSibling.arrow = false; 421fb726d48Sopenharmony_ci } //如果拖动的原节点的父节点没有子节点需要 关闭arrow箭头 422fb726d48Sopenharmony_ci //拖动调整结构后修改 data树形数据结构 423fb726d48Sopenharmony_ci this.removeDataNode(this._treeData, srcData); 424fb726d48Sopenharmony_ci this.addDataNode(this._treeData, srcData, dstData!.key, this.dragDirection!); 425fb726d48Sopenharmony_ci this.dispatchEvent( 426fb726d48Sopenharmony_ci new CustomEvent('drop', { 427fb726d48Sopenharmony_ci detail: { 428fb726d48Sopenharmony_ci treeData: this._treeData, 429fb726d48Sopenharmony_ci srcData: srcData, 430fb726d48Sopenharmony_ci dstData: dstData, 431fb726d48Sopenharmony_ci type: this.dragDirection, 432fb726d48Sopenharmony_ci }, 433fb726d48Sopenharmony_ci }) 434fb726d48Sopenharmony_ci ); 435fb726d48Sopenharmony_ci ev.stopPropagation(); 436fb726d48Sopenharmony_ci return undefined; 437fb726d48Sopenharmony_ci } 438fb726d48Sopenharmony_ci 439fb726d48Sopenharmony_ci //移除treeData中指定的节点 通过key匹配 440fb726d48Sopenharmony_ci removeDataNode(arr: Array<TreeItemData>, d: TreeItemData): void { 441fb726d48Sopenharmony_ci let delIndex = arr.findIndex((v) => v.key === d.key); 442fb726d48Sopenharmony_ci if (delIndex > -1) { 443fb726d48Sopenharmony_ci arr.splice(delIndex, 1); 444fb726d48Sopenharmony_ci return; 445fb726d48Sopenharmony_ci } 446fb726d48Sopenharmony_ci for (let i = 0; i < arr.length; i++) { 447fb726d48Sopenharmony_ci if (arr[i].children && arr[i].children!.length > 0) { 448fb726d48Sopenharmony_ci this.removeDataNode(arr[i].children!, d); 449fb726d48Sopenharmony_ci } 450fb726d48Sopenharmony_ci } 451fb726d48Sopenharmony_ci } 452fb726d48Sopenharmony_ci 453fb726d48Sopenharmony_ci //中array中匹配到key为k的节点, t='bottom-right' 把d加入到该节点的children中去 t='top' 添加到找到的节点前面 t='bottom' 添加到找到的节点后面 454fb726d48Sopenharmony_ci addDataNode(arr: Array<TreeItemData>, d: TreeItemData, k: string, t: string): void { 455fb726d48Sopenharmony_ci for (let i = 0; i < arr.length; i++) { 456fb726d48Sopenharmony_ci if (arr[i].key === k) { 457fb726d48Sopenharmony_ci if (t === 'bottom-right') { 458fb726d48Sopenharmony_ci if (!arr[i].children) { 459fb726d48Sopenharmony_ci arr[i].children = []; 460fb726d48Sopenharmony_ci } 461fb726d48Sopenharmony_ci arr[i].children!.push(d); 462fb726d48Sopenharmony_ci } else if (t === 'top') { 463fb726d48Sopenharmony_ci arr.splice(i, 0, d); 464fb726d48Sopenharmony_ci } else if (t === 'bottom') { 465fb726d48Sopenharmony_ci arr.splice(i + 1, 0, d); 466fb726d48Sopenharmony_ci } 467fb726d48Sopenharmony_ci return; 468fb726d48Sopenharmony_ci } else { 469fb726d48Sopenharmony_ci if (arr[i].children) { 470fb726d48Sopenharmony_ci this.addDataNode(arr[i].children || [], d, k, t); 471fb726d48Sopenharmony_ci } 472fb726d48Sopenharmony_ci } 473fb726d48Sopenharmony_ci } 474fb726d48Sopenharmony_ci } 475fb726d48Sopenharmony_ci 476fb726d48Sopenharmony_ci insert(obj: TreeItemData): void { 477fb726d48Sopenharmony_ci if (this.currentSelectedData) { 478fb726d48Sopenharmony_ci //@ts-ignore 479fb726d48Sopenharmony_ci this.currentSelectedData.children.push(obj); 480fb726d48Sopenharmony_ci } else { 481fb726d48Sopenharmony_ci this.treeData.push(obj); 482fb726d48Sopenharmony_ci } 483fb726d48Sopenharmony_ci } 484fb726d48Sopenharmony_ci insertNodeDragEvent(insertNode: LitTreeNode) { 485fb726d48Sopenharmony_ci if (this.hasAttribute('dragable')) { 486fb726d48Sopenharmony_ci insertNode.draggable = true; 487fb726d48Sopenharmony_ci document.ondragover = function (e): void { 488fb726d48Sopenharmony_ci e.preventDefault(); 489fb726d48Sopenharmony_ci }; 490fb726d48Sopenharmony_ci //在拖动目标上触发事件 (源元素) 491fb726d48Sopenharmony_ci insertNode.ondrag = (ev): void => this.onDrag(ev); //元素正在拖动时触发 492fb726d48Sopenharmony_ci insertNode.ondragstart = (ev): undefined => this.onDragStart(ev); //用户开始拖动元素时触发 493fb726d48Sopenharmony_ci insertNode.ondragend = (ev): undefined => this.onDragEnd(ev); // 用户完成元素拖动后触发 494fb726d48Sopenharmony_ci //释放目标时触发的事件: 495fb726d48Sopenharmony_ci insertNode.ondragenter = (ev): undefined => this.onDragEnter(ev); //当被鼠标拖动的对象进入其容器范围内时触发此事件 496fb726d48Sopenharmony_ci insertNode.ondragover = (ev): undefined => this.onDragOver(ev); //当某被拖动的对象在另一对象容器范围内拖动时触发此事件 497fb726d48Sopenharmony_ci insertNode.ondragleave = (ev): undefined => this.onDragLeave(ev); //当被鼠标拖动的对象离开其容器范围内时触发此事件 498fb726d48Sopenharmony_ci insertNode.ondrop = (ev): undefined => this.onDrop(ev); //在一个拖动过程中,释放鼠标键时触发此事件 499fb726d48Sopenharmony_ci } 500fb726d48Sopenharmony_ci } 501fb726d48Sopenharmony_ci _insertNode(parent: unknown, a: unknown): void { 502fb726d48Sopenharmony_ci if (!parent) { 503fb726d48Sopenharmony_ci parent = this.shadowRoot!.querySelector('#root'); 504fb726d48Sopenharmony_ci } 505fb726d48Sopenharmony_ci let li: HTMLLIElement = document.createElement('li'); 506fb726d48Sopenharmony_ci let insertNode: LitTreeNode = document.createElement('lit-tree-node') as LitTreeNode; //@ts-ignore 507fb726d48Sopenharmony_ci insertNode.title = a.title; //@ts-ignore 508fb726d48Sopenharmony_ci insertNode.setAttribute('key', a.key); 509fb726d48Sopenharmony_ci this.setDragableOfEvent(insertNode); 510fb726d48Sopenharmony_ci if (this.hasAttribute('dragable')) { 511fb726d48Sopenharmony_ci insertNode.draggable = true; 512fb726d48Sopenharmony_ci document.ondragover = function (e): void { 513fb726d48Sopenharmony_ci e.preventDefault(); 514fb726d48Sopenharmony_ci }; 515fb726d48Sopenharmony_ci //在拖动目标上触发事件 (源元素) 516fb726d48Sopenharmony_ci insertNode.ondrag = (ev): void => this.onDrag(ev); //元素正在拖动时触发 517fb726d48Sopenharmony_ci insertNode.ondragstart = (ev): undefined => this.onDragStart(ev); //用户开始拖动元素时触发 518fb726d48Sopenharmony_ci insertNode.ondragend = (ev): undefined => this.onDragEnd(ev); // 用户完成元素拖动后触发 519fb726d48Sopenharmony_ci //释放目标时触发的事件: 520fb726d48Sopenharmony_ci insertNode.ondragenter = (ev): undefined => this.onDragEnter(ev); //当被鼠标拖动的对象进入其容器范围内时触发此事件 521fb726d48Sopenharmony_ci insertNode.ondragover = (ev): undefined => this.onDragOver(ev); //当某被拖动的对象在另一对象容器范围内拖动时触发此事件 522fb726d48Sopenharmony_ci insertNode.ondragleave = (ev): undefined => this.onDragLeave(ev); //当被鼠标拖动的对象离开其容器范围内时触发此事件 523fb726d48Sopenharmony_ci insertNode.ondrop = (ev): undefined => this.onDrop(ev); //在一个拖动过程中,释放鼠标键时触发此事件 524fb726d48Sopenharmony_ci } //@ts-ignore 525fb726d48Sopenharmony_ci insertNode.selected = a.selected || false; //是否选中行 526fb726d48Sopenharmony_ci //@ts-ignore 527fb726d48Sopenharmony_ci insertNode.checked = a.checked || false; // 是否勾选 528fb726d48Sopenharmony_ci //@ts-ignore 529fb726d48Sopenharmony_ci insertNode.data = a; 530fb726d48Sopenharmony_ci insertNode.addEventListener('change', (e: unknown) => { 531fb726d48Sopenharmony_ci //@ts-ignore 532fb726d48Sopenharmony_ci if (e.detail && !this.multiple) { 533fb726d48Sopenharmony_ci this.nodeList.forEach((node) => { 534fb726d48Sopenharmony_ci node.checked = node.data!.key === insertNode.data!.key; 535fb726d48Sopenharmony_ci }); 536fb726d48Sopenharmony_ci } //@ts-ignore 537fb726d48Sopenharmony_ci this.dispatchEvent(new CustomEvent('onChange', { detail: { data: insertNode.data, checked: e.detail } })); 538fb726d48Sopenharmony_ci }); 539fb726d48Sopenharmony_ci this.nodeList.push(insertNode); 540fb726d48Sopenharmony_ci insertNode.checkable = this.getAttribute('checkable') || 'false'; 541fb726d48Sopenharmony_ci insertNode.multiple = this.hasAttribute('multiple'); 542fb726d48Sopenharmony_ci // @ts-ignore 543fb726d48Sopenharmony_ci li.data = a; 544fb726d48Sopenharmony_ci li.append(insertNode); //@ts-ignore 545fb726d48Sopenharmony_ci parent.append(li); 546fb726d48Sopenharmony_ci let ul: HTMLUListElement = document.createElement('ul'); 547fb726d48Sopenharmony_ci // @ts-ignore 548fb726d48Sopenharmony_ci ul.open = 'true'; 549fb726d48Sopenharmony_ci ul.style.transition = '.3s all'; 550fb726d48Sopenharmony_ci this.setChildren(a, insertNode, li, ul); 551fb726d48Sopenharmony_ci // node 添加右键菜单功能 552fb726d48Sopenharmony_ci this.addedRightClickMenuFunction(insertNode); 553fb726d48Sopenharmony_ci } 554fb726d48Sopenharmony_ci 555fb726d48Sopenharmony_ci addedRightClickMenuFunction(insertNode: LitTreeNode): void { 556fb726d48Sopenharmony_ci insertNode.oncontextmenu = (ev): void => { 557fb726d48Sopenharmony_ci ev.preventDefault(); 558fb726d48Sopenharmony_ci this.selectedNode(insertNode); 559fb726d48Sopenharmony_ci this.currentSelectedNode = insertNode; 560fb726d48Sopenharmony_ci this.currentSelectedData = insertNode.data; 561fb726d48Sopenharmony_ci this.contextMenu!.style.display = 'block'; 562fb726d48Sopenharmony_ci this.contextMenu!.style.left = ev.pageX + 'px'; 563fb726d48Sopenharmony_ci this.contextMenu!.style.top = ev.pageY + 'px'; 564fb726d48Sopenharmony_ci }; 565fb726d48Sopenharmony_ci } 566fb726d48Sopenharmony_ci 567fb726d48Sopenharmony_ci setDragableOfEvent(insertNode: LitTreeNode): void { 568fb726d48Sopenharmony_ci if (this.hasAttribute('dragable')) { 569fb726d48Sopenharmony_ci insertNode.draggable = true; 570fb726d48Sopenharmony_ci document.ondragover = function (e): void { 571fb726d48Sopenharmony_ci e.preventDefault(); 572fb726d48Sopenharmony_ci }; 573fb726d48Sopenharmony_ci //在拖动目标上触发事件 (源元素) 574fb726d48Sopenharmony_ci insertNode.ondrag = (ev): void => this.onDrag(ev); //元素正在拖动时触发 575fb726d48Sopenharmony_ci insertNode.ondragstart = (ev): undefined => this.onDragStart(ev); //用户开始拖动元素时触发 576fb726d48Sopenharmony_ci insertNode.ondragend = (ev): undefined => this.onDragEnd(ev); // 用户完成元素拖动后触发 577fb726d48Sopenharmony_ci //释放目标时触发的事件: 578fb726d48Sopenharmony_ci insertNode.ondragenter = (ev): undefined => this.onDragEnter(ev); //当被鼠标拖动的对象进入其容器范围内时触发此事件 579fb726d48Sopenharmony_ci insertNode.ondragover = (ev): undefined => this.onDragOver(ev); //当某被拖动的对象在另一对象容器范围内拖动时触发此事件 580fb726d48Sopenharmony_ci insertNode.ondragleave = (ev): undefined => this.onDragLeave(ev); //当被鼠标拖动的对象离开其容器范围内时触发此事件 581fb726d48Sopenharmony_ci insertNode.ondrop = (ev): undefined => this.onDrop(ev); //在一个拖动过程中,释放鼠标键时触发此事件 582fb726d48Sopenharmony_ci } 583fb726d48Sopenharmony_ci } 584fb726d48Sopenharmony_ci 585fb726d48Sopenharmony_ci setChildren(a: unknown, insertNode: LitTreeNode, li: HTMLLIElement, ul: HTMLUListElement): void { 586fb726d48Sopenharmony_ci //@ts-ignore 587fb726d48Sopenharmony_ci if (a.children && a.children.length > 0) { 588fb726d48Sopenharmony_ci if (this.hasAttribute('show-icon')) { 589fb726d48Sopenharmony_ci //@ts-ignore 590fb726d48Sopenharmony_ci if (a.icon) { 591fb726d48Sopenharmony_ci //@ts-ignore 592fb726d48Sopenharmony_ci insertNode.iconName = a.icon; 593fb726d48Sopenharmony_ci } else { 594fb726d48Sopenharmony_ci insertNode.iconName = 'folder'; 595fb726d48Sopenharmony_ci } 596fb726d48Sopenharmony_ci } else { 597fb726d48Sopenharmony_ci insertNode.iconName = ''; 598fb726d48Sopenharmony_ci } 599fb726d48Sopenharmony_ci insertNode.arrow = true; 600fb726d48Sopenharmony_ci li.append(ul); //@ts-ignore 601fb726d48Sopenharmony_ci this.drawTree(ul, a.children); 602fb726d48Sopenharmony_ci } else { 603fb726d48Sopenharmony_ci if (this.hasAttribute('show-icon')) { 604fb726d48Sopenharmony_ci //@ts-ignore 605fb726d48Sopenharmony_ci if (a.icon) { 606fb726d48Sopenharmony_ci //@ts-ignore 607fb726d48Sopenharmony_ci insertNode.iconName = a.icon; 608fb726d48Sopenharmony_ci } else { 609fb726d48Sopenharmony_ci insertNode.iconName = 'file'; 610fb726d48Sopenharmony_ci } 611fb726d48Sopenharmony_ci } else { 612fb726d48Sopenharmony_ci insertNode.iconName = ''; 613fb726d48Sopenharmony_ci } 614fb726d48Sopenharmony_ci insertNode.arrow = false; 615fb726d48Sopenharmony_ci } 616fb726d48Sopenharmony_ci li.onclick = (e): void => { 617fb726d48Sopenharmony_ci e.stopPropagation(); 618fb726d48Sopenharmony_ci if (this.hasAttribute('foldable')) { 619fb726d48Sopenharmony_ci // @ts-ignore 620fb726d48Sopenharmony_ci if (li.data.children && li.data.children.length > 0) { 621fb726d48Sopenharmony_ci insertNode.autoExpand(); 622fb726d48Sopenharmony_ci } else { 623fb726d48Sopenharmony_ci // @ts-ignore 624fb726d48Sopenharmony_ci this.dispatchEvent(new CustomEvent('onSelect', { detail: li.data })); 625fb726d48Sopenharmony_ci this.selectedNode(insertNode); 626fb726d48Sopenharmony_ci } 627fb726d48Sopenharmony_ci } else { 628fb726d48Sopenharmony_ci // @ts-ignore 629fb726d48Sopenharmony_ci this.dispatchEvent(new CustomEvent('onSelect', { detail: li.data })); 630fb726d48Sopenharmony_ci this.selectedNode(insertNode); 631fb726d48Sopenharmony_ci } 632fb726d48Sopenharmony_ci }; 633fb726d48Sopenharmony_ci } 634fb726d48Sopenharmony_ci 635fb726d48Sopenharmony_ci initElements(): void { 636fb726d48Sopenharmony_ci this.contextMenu = this.shadowRoot!.querySelector<HTMLDivElement>('#contextMenu'); 637fb726d48Sopenharmony_ci } 638fb726d48Sopenharmony_ci 639fb726d48Sopenharmony_ci initHtml(): string { 640fb726d48Sopenharmony_ci return ` 641fb726d48Sopenharmony_ci <style> 642fb726d48Sopenharmony_ci :host{ 643fb726d48Sopenharmony_ci display: flex; 644fb726d48Sopenharmony_ci color:#333; 645fb726d48Sopenharmony_ci width: 100%; 646fb726d48Sopenharmony_ci height: 100%; 647fb726d48Sopenharmony_ci overflow: auto; 648fb726d48Sopenharmony_ci } 649fb726d48Sopenharmony_ci :host *{ 650fb726d48Sopenharmony_ci box-sizing: border-box; 651fb726d48Sopenharmony_ci } 652fb726d48Sopenharmony_ci ul,li{ 653fb726d48Sopenharmony_ci list-style-type: none; 654fb726d48Sopenharmony_ci position:relative; 655fb726d48Sopenharmony_ci cursor:pointer; 656fb726d48Sopenharmony_ci overflow: hidden; 657fb726d48Sopenharmony_ci } 658fb726d48Sopenharmony_ci :host([show-line]) ul{ 659fb726d48Sopenharmony_ci padding-left:10px; 660fb726d48Sopenharmony_ci border-left: 1px solid #d9d9d9; 661fb726d48Sopenharmony_ci overflow: hidden; 662fb726d48Sopenharmony_ci } 663fb726d48Sopenharmony_ci :host(:not([show-line])) ul{ 664fb726d48Sopenharmony_ci padding-left: 10px; 665fb726d48Sopenharmony_ci overflow: hidden; 666fb726d48Sopenharmony_ci } 667fb726d48Sopenharmony_ci /*ul>li:after{content:' ';position:absolute;top:50%;left:-45px;width:45px;border:none;border-top:1px solid #d9d9d9;}*/ 668fb726d48Sopenharmony_ci #root{ 669fb726d48Sopenharmony_ci width: 100%; 670fb726d48Sopenharmony_ci height: 100%; 671fb726d48Sopenharmony_ci } 672fb726d48Sopenharmony_ci .context-menu { 673fb726d48Sopenharmony_ci position: absolute; 674fb726d48Sopenharmony_ci box-shadow: 0 0 10px #00000077; 675fb726d48Sopenharmony_ci pointer-events: auto; 676fb726d48Sopenharmony_ci z-index: 999; 677fb726d48Sopenharmony_ci transition: all .3s; 678fb726d48Sopenharmony_ci } 679fb726d48Sopenharmony_ci </style> 680fb726d48Sopenharmony_ci <ul id="root" style="margin: 0;overflow: hidden"></ul> 681fb726d48Sopenharmony_ci <div id="contextMenu" class="context-menu" style="display:none"> 682fb726d48Sopenharmony_ci <slot name="contextMenu"></slot> 683fb726d48Sopenharmony_ci </div> 684fb726d48Sopenharmony_ci `; 685fb726d48Sopenharmony_ci } 686fb726d48Sopenharmony_ci} 687fb726d48Sopenharmony_ci 688fb726d48Sopenharmony_ciif (!customElements.get('lit-tree')) { 689fb726d48Sopenharmony_ci customElements.define('lit-tree', LitTree); 690fb726d48Sopenharmony_ci} 691