• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import {LitTableColumn} from "./lit-table-column.js";
17import {element} from "../BaseElement.js";
18import "../utils/Template.js"
19import {TableRowObject} from "./TableRowObject.js";
20
21@element('lit-table')
22export class LitTable extends HTMLElement {
23    meauseRowElement: HTMLDivElement | undefined
24    currentRecycleList: HTMLDivElement[] = []
25    currentTreeDivList: HTMLDivElement[] = []
26    public rememberScrollTop = false
27    private ds: Array<any> = []
28    private recycleDs: Array<any> = []
29    private normalDs: Array<any> = []
30    private gridTemplateColumns: any
31    /*Grid css layout descriptions are obtained according to the clustern[] nested structure*/
32    private st: HTMLSlotElement | null | undefined
33    private tableElement: HTMLDivElement | null | undefined
34    private theadElement: HTMLDivElement | null | undefined
35    private columns: Array<Element> | null | undefined
36    private tbodyElement: HTMLDivElement | undefined | null
37    private treeElement: HTMLDivElement | undefined | null
38    private tableColumns: NodeListOf<LitTableColumn> | undefined
39    private colCount: number = 0
40    private currentScrollTop: number = 0
41    private isRecycleList: boolean = true
42    private isScrollXOutSide: boolean = false;
43    constructor() {
44        super();
45        const shadowRoot = this.attachShadow({mode: 'open'});
46        shadowRoot.innerHTML = `
47        <style>
48        :host{
49            display: grid;
50            grid-template-columns: repeat(1,1fr);
51            width: 100%;
52            flex:1;
53        }
54        .tr{
55            display: grid;
56            grid-column-gap: 5px;
57            min-width:100%;
58        }
59        .tr:nth-of-type(even){
60        }
61
62        .tr{
63            background-color: var(--dark-background,#FFFFFF);
64        }
65        .tr:hover{
66            background-color: var(--dark-background6,#DEEDFF);
67        }
68        .td{
69            box-sizing: border-box;
70            padding: 3px;
71            display: flex;
72            justify-content: flex-start;
73            align-items: center;
74            width: 100%;
75            height: auto;
76            cursor: pointer;
77        }
78        .td text{
79            overflow: hidden;
80            text-overflow: ellipsis;
81            white-space: nowrap;
82        }
83        .tr[selected]{
84            background-color: var(--dark-background6,#DEEDFF);
85        }
86        .td-order{
87        }
88        .td-order:before{
89
90        }
91        :host([grid-line]) .td{
92            border-left: 1px solid #f0f0f0;
93        }
94        :host([grid-line]) .td:last-of-type{
95            border-right: 1px solid #f0f0f0;
96        }
97        .table{
98            width: 100%;
99             color: var(--dark-color2,#262626);
100        }
101        .thead{
102            display: grid;
103            position: sticky;
104            top: 0;
105            font-weight: bold;
106            font-size: .9rem;
107            color: var(--dark-color1,#000);
108            background-color: var(--dark-background,#FFFFFF);
109            z-index: 1;
110        }
111        .tbody{
112            width: 100%;
113            top: 0;
114            left: 0;
115            right:0;
116            bottom:0;
117            display: flex;
118            flex-direction: row
119            row-gap: 1px;
120            column-gap: 1px;
121        }
122        .tree{
123            overflow-x:hidden;
124            overflow-y:hidden;
125            display: grid;
126            grid-template-columns: 1fr;
127            row-gap: 1px;
128            column-gap: 1px;
129            position:relative;
130        }
131        .tree:hover{
132            overflow-x: overlay;
133        }
134        .tree-first-body{
135            min-width: 100%;
136            box-sizing: border-box;
137            display:flex;
138            align-items:center;
139            white-space: nowrap;
140            cursor: pointer;
141        }
142        .tree-first-body:hover{
143            background-color: var(--dark-background6,#DEEDFF); /*antd #fafafa 42b983*/
144        }
145        .body{
146            display: grid;
147            grid-template-columns: 1fr;
148            row-gap: 1px;
149            column-gap: 1px;
150            flex:1;
151            position: relative;
152        }
153        :host([grid-line])  .tbody{
154            border-bottom: 1px solid #f0f0f0;
155            background-color: #f0f0f0;
156        }
157        .th{
158            grid-column-gap: 5px;
159            display: grid;
160            background-color: var(--dark-background,#FFFFFF);
161        }
162
163        .tree-icon{
164            font-size: 1.2rem;
165            width: 20px;
166            height: 20px;
167            padding-right: 5px;
168            padding-left: 5px;
169            cursor: pointer;
170        }
171        .tree-icon:hover{
172            color: #42b983;
173        }
174        .row-checkbox,row-checkbox-all{
175
176        }
177        :host([no-head]) .thead{
178            display: none;
179        }
180        .up-svg{
181            position: absolute;
182            right: 5px;
183            top: 8px;
184            bottom: 8px;
185            width: 15px;
186            height: 15px;
187        }
188        .down-svg{
189            position: absolute;
190            top: 8px;
191            right: 5px;
192            bottom: 8px;
193            width: 15px;
194            height: 15px;
195        }
196        .mouse-select{
197            background-color: var(--dark-background6,#DEEDFF);
198        }
199        .mouse-in{
200            background-color: var(--dark-background6,#DEEDFF);
201        }
202        .export{
203            width:30px;
204            height:30px;
205            cursor:pointer;
206            color:var(--dark-background6,#262626);
207            box-sizing: border-box;
208            position:fixed;
209            right:30px;
210            bottom:15px;
211        }
212        </style>
213
214        <slot id="slot" style="display: none"></slot>
215        <slot name="head"></slot>
216        <div class="table" style="overflow-x:auto;">
217            <div class="thead"></div>
218            <div class="tbody">
219                <div class="tree"></div>
220                <div class="body"></div>
221        </div>
222        </div>
223        `
224    }
225
226    static get observedAttributes() {
227        return ['scroll-y', 'selectable', 'no-head', 'grid-line', 'defaultOrderColumn']
228    }
229
230    get selectable() {
231        return this.hasAttribute('selectable');
232    }
233
234    set selectable(value) {
235        if (value) {
236            this.setAttribute('selectable', '');
237        } else {
238            this.removeAttribute('selectable');
239        }
240    }
241
242    get scrollY() {
243        return this.getAttribute('scroll-y') || 'auto';
244    }
245
246    set scrollY(value) {
247        this.setAttribute('scroll-y', value);
248    }
249
250
251    get dataSource() {
252        return this.ds || [];
253    }
254
255    set dataSource(value) {
256        this.ds = value;
257        this.isRecycleList = false
258        if (this.hasAttribute('tree')) {
259            this.renderTreeTable();
260        } else {
261            this.renderTable();
262        }
263    }
264
265    get recycleDataSource() {
266        return this.ds || [];
267    }
268
269    set recycleDataSource(value) {
270        this.isScrollXOutSide = this.tableElement!.scrollWidth > this.tableElement!.clientWidth
271        this.isRecycleList = true
272        this.ds = value;
273        if (this.rememberScrollTop) {
274            this.currentScrollTop = this.tableElement!.scrollTop;
275            this.tableElement!.scrollTop = 0
276        } else {
277            this.tableElement!.scrollTop = 0
278        }
279        if (this.hasAttribute('tree')) {
280            this.recycleDs = this.meauseTreeRowElement(value)
281        } else {
282            this.recycleDs = this.meauseAllRowHeight(value)
283        }
284    }
285
286    move1px() {
287        this.tableElement!.scrollTop = this.tableElement!.scrollTop + 1
288    }
289
290    dataExportInit() {
291        let exportDiv = this.shadowRoot!.querySelector<HTMLDivElement>(".export")
292        exportDiv && (exportDiv.onclick = () => {
293            this.exportData()
294        });
295        let tab = document?.querySelector("body > sp-application")?.shadowRoot?.querySelector("#sp-system-trace")
296            ?.shadowRoot?.querySelector("div > trace-sheet")?.shadowRoot?.querySelector("#tabs");
297        if (tab != undefined) {
298            new ResizeObserver(() => {
299                if (tab && tab.clientHeight > (38 + 70)) {
300                    exportDiv!.style.visibility = "visible";
301                } else {
302                    exportDiv!.style.visibility = "hidden";
303                }
304            }).observe(tab)
305        }
306    }
307
308    exportData() {
309        let formatData: any[] = this.formatExportData(this.ds)
310        let link = document.createElement('a')
311        link.download = new Date().getTime() + '.json'
312        link.href = 'data:text/plain,' + JSON.stringify(formatData, null, 4)
313        link.click()
314    }
315
316    formatExportData(dataSource: any[]): any[] {
317        if (dataSource == undefined || dataSource.length == 0) {
318            return []
319        }
320        if (this.columns == undefined) {
321            return []
322        }
323        return dataSource.map((item) => {
324            let formatData: any = {}
325            this.columns!.forEach((column) => {
326                let dataIndex = column.getAttribute('data-index')
327                let columnName = column.getAttribute('title')
328                if (columnName == "") {
329                    columnName = dataIndex
330                }
331                if (dataIndex && columnName && item[dataIndex] != undefined) {
332                    formatData[columnName] = item[dataIndex]
333                }
334            })
335            if (item.children != undefined) {
336                formatData.children = this.formatExportData(item.children)
337            }
338            return formatData
339        })
340    }
341
342
343    //当 custom element首次被插入文档DOM时,被调用。
344    connectedCallback() {
345        this.st = this.shadowRoot?.querySelector('#slot');
346        this.tableElement = this.shadowRoot?.querySelector('.table');
347        this.theadElement = this.shadowRoot?.querySelector('.thead');
348        this.treeElement = this.shadowRoot?.querySelector('.tree');
349        this.tbodyElement = this.shadowRoot?.querySelector('.body');
350        this.tableColumns = this.querySelectorAll<LitTableColumn>('lit-table-column');
351        this.colCount = this.tableColumns!.length;
352        this.tableElement?.addEventListener("copy",(e)=>{
353            // @ts-ignore
354            let clipboardData = e.clipboardData || window.clipboardData;
355            if(!clipboardData) return ;
356            // @ts-ignore
357            let text = window.getSelection().toString();
358            if(text){
359                e.preventDefault();
360                let length = this.tableColumns?.length||1;
361                let strings = text.split("\n");
362                let formatStr = ""
363                for (let i = 0; i < strings.length; i++) {
364                    if(i%length != 0){
365                        formatStr+="    "
366                    }
367                    formatStr+=strings[i]
368                    if(i!=0&&i%length == length - 1){
369                        formatStr += "\n"
370                    }
371                }
372                clipboardData.setData('text/plain', formatStr)
373            }
374        })
375        this.st?.addEventListener('slotchange', () => {
376            this.theadElement!.innerHTML = '';
377            setTimeout(() => {
378                this.columns = this.st!.assignedElements();
379                let rowElement = document.createElement('div');
380                rowElement.classList.add('th');
381                if (this.selectable) {
382                    let box = document.createElement('div');
383                    box.style.display = 'flex';
384                    box.style.justifyContent = 'center';
385                    box.style.alignItems = 'center';
386                    box.style.gridArea = "_checkbox_";
387                    box.classList.add('td');
388                    box.style.backgroundColor = "#ffffff66";
389                    let checkbox = document.createElement('lit-checkbox');
390                    checkbox.classList.add('row-checkbox-all');
391                    checkbox.onchange = (e: any) => {
392                        this.shadowRoot!.querySelectorAll('.row-checkbox').forEach((a: any) => a.checked = e.detail.checked);
393                        if (e.detail.checked) {
394                            this.shadowRoot!.querySelectorAll('.tr').forEach(a => a.setAttribute('checked', ''));
395                        } else {
396                            this.shadowRoot!.querySelectorAll('.tr').forEach(a => a.removeAttribute('checked'));
397                        }
398                    }
399                    box.appendChild(checkbox);
400                    rowElement.appendChild(box);
401                }
402                let area: Array<any> = [], gridTemplateColumns: Array<any> = [];
403                let resolvingArea = (columns: any, x: any, y: any) => {
404                    columns.forEach((a: any, i: any) => {
405                        if (!area[y]) area[y] = []
406                        let key = a.getAttribute('key') || a.getAttribute('title')
407                        if (a.tagName === 'LIT-TABLE-GROUP') {
408                            let len = a.querySelectorAll('lit-table-column').length;
409                            let children = [...a.children].filter(a => a.tagName !== 'TEMPLATE');
410                            if (children.length > 0) {
411                                resolvingArea(children, x, y + 1);
412                            }
413                            for (let j = 0; j < len; j++) {
414                                area[y][x] = {x, y, t: key};
415                                x++;
416                            }
417                            let h = document.createElement('div');
418                            h.classList.add('td');
419                            h.style.justifyContent = a.getAttribute('align')
420                            h.style.borderBottom = '1px solid #f0f0f0'
421                            h.style.gridArea = key;
422                            h.innerText = a.title;
423                            if (a.hasAttribute('fixed')) {
424                                this.fixed(h, a.getAttribute('fixed'), "#42b983")
425                            }
426                            rowElement.append(h);
427                        } else if (a.tagName === 'LIT-TABLE-COLUMN') {
428                            area[y][x] = {x, y, t: key};
429                            x++;
430                            let h: any = document.createElement('div');
431                            h.classList.add('td');
432                            if (a.hasAttribute('order')) {
433                                h.sortType = 0;
434                                h.classList.add('td-order');
435                                h.style.position = "relative"
436                                let NS = "http://www.w3.org/2000/svg";
437                                let upSvg: any = document.createElementNS(NS, "svg");
438                                let upPath: any = document.createElementNS(NS, "path");
439                                upSvg.setAttribute('fill', 'var(--dark-color1,#212121)');
440                                upSvg.setAttribute('viewBox', '0 0 1024 1024');
441                                upSvg.setAttribute('stroke', 'var(--dark-color1,#212121)');
442                                upSvg.classList.add('up-svg');
443                                upPath.setAttribute("d", "M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z");
444                                upSvg.appendChild(upPath);
445                                let downSvg: any = document.createElementNS(NS, "svg");
446                                let downPath: any = document.createElementNS(NS, "path");
447                                downSvg.setAttribute('fill', 'var(--dark-color1,#212121)');
448                                downSvg.setAttribute('viewBox', '0 0 1024 1024');
449                                downSvg.setAttribute('stroke', 'var(--dark-color1,#212121)');
450                                downSvg.classList.add('down-svg');
451                                downPath.setAttribute("d", "M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z");
452                                downSvg.appendChild(downPath)
453                                if (i == 0) {
454                                    h.sortType = 0; // 默认以第一列 降序排序 作为默认排序
455                                    upSvg.setAttribute('fill', 'var(--dark-color1,#212121)');
456                                    downSvg.setAttribute('fill', 'var(--dark-color1,#212121)');
457                                }
458                                upSvg.style.display = 'none';
459                                downSvg.style.display = 'none';
460                                h.appendChild(upSvg);
461                                h.appendChild(downSvg);
462                                h.onclick = () => {
463                                    this?.shadowRoot?.querySelectorAll('.td-order svg').forEach((it: any) => {
464                                        it.setAttribute('fill', 'var(--dark-color1,#212121)');
465                                        it.sortType = 0;
466                                        it.style.display = 'none';
467                                    })
468                                    if (h.sortType == undefined || h.sortType == null) {
469                                        h.sortType = 0;
470                                    } else if (h.sortType === 2) {
471                                        h.sortType = 0;
472                                    } else {
473                                        h.sortType += 1;
474                                    }
475                                    switch (h.sortType) {
476                                        case 1:
477                                            upSvg.setAttribute('fill', 'var(--dark-color1,#212121)');
478                                            downSvg.setAttribute('fill', 'var(--dark-color1,#212121)');
479                                            upSvg.style.display = 'block';
480                                            downSvg.style.display = 'none';
481                                            break;
482                                        case 2:
483                                            upSvg.setAttribute('fill', 'var(--dark-color1,#212121)');
484                                            downSvg.setAttribute('fill', 'var(--dark-color1,#212121)');
485                                            upSvg.style.display = 'none';
486                                            downSvg.style.display = 'block';
487                                            break;
488                                        default:
489                                            upSvg.setAttribute('fill', "var(--dark-color1,#212121)");
490                                            downSvg.setAttribute('fill', "var(--dark-color1,#212121)");
491                                            upSvg.style.display = 'none';
492                                            downSvg.style.display = 'none';
493                                            break;
494                                    }
495                                    this.dispatchEvent(new CustomEvent("column-click", {
496                                        detail: {
497                                            sort: h.sortType, key: key
498                                        }, composed: true
499                                    }))
500                                }
501                            }
502                            h.style.justifyContent = a.getAttribute('align')
503                            gridTemplateColumns.push(a.getAttribute('width') || '1fr');
504                            h.style.gridArea = key;
505                            let titleLabel = document.createElement("label");
506                            titleLabel.textContent = a.title;
507                            h.appendChild(titleLabel);
508                            if (a.hasAttribute('fixed')) {
509                                this.fixed(h, a.getAttribute('fixed'), "#42b983")
510                            }
511                            rowElement.append(h);
512                        }
513                    })
514                }
515                resolvingArea(this.columns, 0, 0);
516                area.forEach((rows, j, array) => {
517                    for (let i = 0; i < this.colCount; i++) {
518                        if (!rows[i]) rows[i] = array[j - 1][i];
519                    }
520                })
521                this.gridTemplateColumns = gridTemplateColumns.join(' ');
522                if (this.selectable) {
523                    let s = area.map(a => '"_checkbox_ ' + (a.map((aa: any) => aa.t).join(' ')) + '"').join(' ');
524                    rowElement.style.gridTemplateColumns = "60px " + gridTemplateColumns.join(' ');
525                    rowElement.style.gridTemplateRows = `repeat(${area.length},1fr)`
526                    rowElement.style.gridTemplateAreas = s
527                } else {
528                    let s = area.map(a => '"' + (a.map((aa: any) => aa.t).join(' ')) + '"').join(' ');
529                    rowElement.style.gridTemplateColumns = gridTemplateColumns.join(' ');
530                    rowElement.style.gridTemplateRows = `repeat(${area.length},1fr)`
531                    rowElement.style.gridTemplateAreas = s
532                }
533                this.theadElement!.innerHTML = ''
534                this.theadElement!.append(rowElement);
535                this.treeElement!.style.top = this.theadElement?.clientHeight + "px"
536            });
537
538        });
539
540        this.shadowRoot!.addEventListener("load", function (event) {
541        });
542    }
543
544    // Is called when the custom element is removed from the document DOM.
545    disconnectedCallback() {
546
547    }
548
549    // It is called when the custom element is moved to a new document.
550    adoptedCallback() {
551    }
552
553    // It is called when a custom element adds, deletes, or modifies its own properties.
554    attributeChangedCallback(name: string, oldValue: string, newValue: string) {
555
556    }
557
558    fixed(td: HTMLElement, placement: string, bgColor: string) {
559        td.style.position = 'sticky';
560        if (placement === "left") {
561            td.style.left = '0px';
562            td.style.boxShadow = '3px 0px 5px #33333333'
563        } else if (placement === "right") {
564            td.style.right = '0px';
565            td.style.boxShadow = '-3px 0px 5px #33333333'
566        }
567    }
568
569    renderTable() {
570        if (!this.columns) return;
571        if (!this.ds) return; // If no data source is set, it is returned directly
572        this.normalDs = []
573        this.tbodyElement!.innerHTML = '';// Clear the table contents
574        this.ds.forEach((rowData: any) => {
575            let rowElement = document.createElement('div');
576            rowElement.classList.add('tr');
577            // @ts-ignore
578            rowElement.data = rowData;
579            let gridTemplateColumns: Array<any> = []
580            // If the table is configured with selectable (select row mode) add a checkbox at the head of the line alone
581            if (this.selectable) {
582                let box = document.createElement('div');
583                box.style.display = 'flex';
584                box.style.justifyContent = 'center';
585                box.style.alignItems = 'center';
586                box.classList.add('td');
587                let checkbox = document.createElement('lit-checkbox');
588                checkbox.classList.add('row-checkbox');
589                checkbox.onchange = (e: any) => {// Checkbox checking affects whether the div corresponding to the row has a checked attribute for marking
590                    if (e.detail.checked) {
591                        rowElement.setAttribute('checked', "");
592                    } else {
593                        rowElement.removeAttribute('checked');
594                    }
595                }
596                box.appendChild(checkbox);
597                rowElement.appendChild(box);
598            }
599            this.tableColumns!.forEach(cl => {
600                let dataIndex = cl.getAttribute('data-index') || '1';
601                gridTemplateColumns.push(cl.getAttribute('width') || '1fr')
602                if (cl.template) {// If you customize the rendering, you get the nodes from the template
603                    // @ts-ignore
604                    let cloneNode = cl.template.render(rowData).content.cloneNode(true);
605                    let d = document.createElement('div');
606                    d.classList.add('td');
607                    d.style.wordBreak = 'break-all'
608                    d.style.whiteSpace = 'pre-wrap'
609                    d.style.justifyContent = cl.getAttribute('align') || ''
610                    if (cl.hasAttribute('fixed')) {
611                        this.fixed(d, cl.getAttribute('fixed') || '', "#ffffff")
612                    }
613                    d.append(cloneNode);
614                    rowElement.append(d);
615                } else {
616                    let td = document.createElement('div');
617                    td.classList.add('td');
618                    td.style.wordBreak = 'break-all'
619                    td.style.whiteSpace = 'pre-wrap'
620                    td.title = rowData[dataIndex]
621                    td.style.justifyContent = cl.getAttribute('align') || ''
622                    if (cl.hasAttribute('fixed')) {
623                        this.fixed(td, cl.getAttribute('fixed') || '', "#ffffff")
624                    }
625                    td.innerHTML = this.formatName(rowData[dataIndex]);
626                    rowElement.append(td);
627                }
628
629            })
630            if (this.selectable) { // If the table with selection is preceded by a 60px column
631                rowElement.style.gridTemplateColumns = '60px ' + gridTemplateColumns.join(' ');
632            } else {
633                rowElement.style.gridTemplateColumns = gridTemplateColumns.join(' ');
634            }
635            rowElement.onclick = e => {
636                this.dispatchEvent(new CustomEvent('row-click', {
637                    detail: {
638                        rowData, data: rowData, callBack: (isSelected: boolean) => {//是否爲单选
639                            if (isSelected) {
640                                this.clearAllSelection(rowData)
641                            }
642                            this.setSelectedRow(rowData.isSelected, [rowElement])
643                        }
644                    }, composed: true
645                }));
646            }
647            this.normalDs.push(rowElement);
648            this.tbodyElement!.append(rowElement);
649        })
650    }
651
652
653    renderTreeTable() {
654        if (!this.columns) return;
655        if (!this.ds) return;
656        this.tbodyElement!.innerHTML = '';
657        this.treeElement!.innerHTML = '';
658        let ids = JSON.parse(this.getAttribute('tree') || `["id","pid"]`);
659        let toTreeData = (data: any, id: any, pid: any) => {
660            let cloneData = JSON.parse(JSON.stringify(data));
661            return cloneData.filter((father: any) => {
662                let branchArr = cloneData.filter((child: any) => father[id] == child[pid]);
663                branchArr.length > 0 ? father['children'] = branchArr : '';
664                return !father[pid];
665            });
666        }
667        let treeData = toTreeData(this.ds, ids[0], ids[1]);
668        let offset = 30;
669        let offsetVal = offset;
670        const drawRow = (arr: any, parentNode: any) => {
671            arr.forEach((rowData: any) => {
672                let rowElement = document.createElement('div');
673                rowElement.classList.add('tr');
674                // @ts-ignore
675                rowElement.data = rowData;
676                let gridTemplateColumns: Array<any> = [];
677                if (this.selectable) {
678                    let box = document.createElement('div');
679                    box.style.display = 'flex';
680                    box.style.justifyContent = 'center';
681                    box.style.alignItems = 'center';
682                    box.classList.add('td');
683                    let checkbox = document.createElement('lit-checkbox');
684                    checkbox.classList.add('row-checkbox');
685                    checkbox.onchange = (e: any) => {
686                        if (e.detail.checked) {
687                            rowElement.setAttribute('checked', "");
688                        } else {
689                            rowElement.removeAttribute('checked');
690                        }
691                        const changeChildNode = (rowElement: any, checked: any) => {
692                            let id = rowElement.getAttribute('id');
693                            let pid = rowElement.getAttribute('pid');
694                            this.shadowRoot!.querySelectorAll(`div[pid=${id}]`).forEach(a => {
695                                // @ts-ignore
696                                a.querySelector('.row-checkbox')!.checked = checked;
697                                if (checked) {
698                                    a.setAttribute('checked', '');
699                                } else {
700                                    a.removeAttribute('checked');
701                                }
702                                changeChildNode(a, checked);
703                            });
704                        };
705                        changeChildNode(rowElement, e.detail.checked);
706                    }
707                    box.appendChild(checkbox);
708                    rowElement.appendChild(box);
709                }
710                this.tableColumns!.forEach((cl, index) => {
711                    let dataIndex = cl.getAttribute('data-index');
712                    let td;
713                    if (index !== 0) {
714                        gridTemplateColumns.push(cl.getAttribute('width') || '1fr')
715                        if (cl.template) {
716                            // @ts-ignore
717                            let cloneNode = cl.template.render(rowData).content.cloneNode(true);
718                            td = document.createElement('div');
719                            td.classList.add('td');
720                            td.style.wordBreak = 'break-all'
721                            td.style.justifyContent = cl.getAttribute('align') || ''
722                            if (cl.hasAttribute('fixed')) {
723                                this.fixed(td, cl.getAttribute('fixed') || '', "#ffffff")
724                            }
725                            td.append(cloneNode);
726                        } else {
727                            td = document.createElement('div');
728                            td.classList.add('td');
729                            td.style.wordBreak = 'break-all'
730                            td.style.justifyContent = cl.getAttribute('align') || ''
731                            if (cl.hasAttribute('fixed')) {
732                                this.fixed(td, cl.getAttribute('fixed') || '', "#ffffff")
733                            }
734                            // @ts-ignore
735                            td.innerHTML = this.formatName(rowData[dataIndex]);
736                        }
737                        rowElement.append(td)
738                    } else {
739                        this.treeElement!.style.width = cl.getAttribute('width') || "260px"
740                        let treeElement = document.createElement('div');
741                        treeElement.classList.add("tree-first-body")
742                        if (cl.template) {
743                            // @ts-ignore
744                            let cloneNode = cl.template.render(rowData).content.cloneNode(true);
745                            td = document.createElement('div');
746                            td.classList.add('td');
747                            td.style.justifyContent = cl.getAttribute('align') || ''
748                            if (cl.hasAttribute('fixed')) {
749                                this.fixed(td, cl.getAttribute('fixed') || '', "#ffffff")
750                            }
751                            td.append(cloneNode);
752                        } else {
753                            td = document.createElement('div');
754                            td.classList.add('td');
755                            td.style.justifyContent = cl.getAttribute('align') || ''
756                            if (cl.hasAttribute('fixed')) {
757                                this.fixed(td, cl.getAttribute('fixed') || '', "#ffffff")
758                            }
759                            // @ts-ignore
760                            td.innerHTML = this.formatName(rowData[dataIndex]);
761                        }
762                        if (rowData.children && rowData.children.length > 0) {
763                            let btn = document.createElement('lit-icon');
764                            btn.classList.add('tree-icon');
765                            // @ts-ignore
766                            btn.name = 'minus-square';
767                            treeElement.append(btn);
768                            treeElement.append(td)
769                            treeElement.style.paddingLeft = (offsetVal - 30) + 'px';
770                        } else {
771                            treeElement.append(td)
772                            treeElement.style.paddingLeft = offsetVal + 'px';
773                        }
774                        this.treeElement!.append(treeElement);
775                    }
776
777                })
778                if (this.selectable) {
779                    rowElement.style.gridTemplateColumns = '60px ' + gridTemplateColumns.join(' ');
780                } else {
781                    rowElement.style.gridTemplateColumns = gridTemplateColumns.join(' ');
782                }
783                rowElement.onclick = e => {
784                    this.dispatchEvent(new CustomEvent('row-click', {detail: rowData, composed: true}));
785                }
786                rowElement.style.cursor = 'pointer'
787                parentNode.append(rowElement);
788                rowElement.setAttribute('id', rowData[ids[0]]);
789                rowElement.setAttribute('pid', rowData[ids[1]]);
790                rowElement.setAttribute('expend', '');
791                if (rowData.children && rowData.children.length > 0) {
792                    offsetVal = offsetVal + offset;
793                    drawRow(rowData.children, parentNode);
794                    offsetVal = offsetVal - offset;
795                }
796            });
797        };
798        drawRow(treeData, this.tbodyElement);
799    }
800
801    getCheckRows() {
802        // @ts-ignore
803        return [...this.shadowRoot!.querySelectorAll('div[class=tr][checked]')].map(a => a.data).map(a => {
804            delete a['children'];
805            return a;
806        });
807    }
808
809    deleteRowsCondition(fn: any) {
810        this.shadowRoot!.querySelectorAll("div[class=tr]").forEach(tr => {
811            // @ts-ignore
812            if (fn(tr.data)) {
813                tr.remove();
814            }
815        })
816    }
817
818    meauseElementHeight(rowData: any) {
819        return 27;
820    }
821
822    meauseTreeElementHeight(rowData: any, depth: number) {
823        return 27;
824    }
825
826    meauseAllRowHeight(list: any[]): TableRowObject[] {
827        this.tbodyElement!.innerHTML = '';
828        this.meauseRowElement = undefined
829        let head = this.shadowRoot!.querySelector(".th");
830        this.tbodyElement && (this.tbodyElement.style.width = head?.clientWidth + "px")
831        this.currentRecycleList = []
832        let headHeight = 0
833        let totalHeight = headHeight;
834        let visibleObjects: TableRowObject[] = [];
835        list.forEach((rowData, index) => {
836            let height = this.meauseElementHeight(rowData);
837            let tableRowObject = new TableRowObject();
838            tableRowObject.height = height
839            tableRowObject.top = totalHeight
840            tableRowObject.data = rowData
841            tableRowObject.rowIndex = index
842            if (Math.max(totalHeight, this.tableElement!.scrollTop + headHeight) <= Math.min(totalHeight + height, this.tableElement!.scrollTop + this.tableElement!.clientHeight + headHeight)) {
843                let newTableElement = this.createNewTableElement(tableRowObject);
844                newTableElement.style.transform = `translateY(${totalHeight}px)`
845                this.tbodyElement?.append(newTableElement)
846                this.currentRecycleList.push(newTableElement)
847            }
848            totalHeight += height
849            visibleObjects.push(tableRowObject)
850        })
851        this.tbodyElement && (this.tbodyElement.style.height = totalHeight + (this.isScrollXOutSide?0:0) + "px")
852        this.tableElement && (this.tableElement.onscroll = (event) => {
853            let top = this.tableElement!.scrollTop;
854            let skip = 0;
855            for (let i = 0; i < visibleObjects.length; i++) {
856                if (visibleObjects[i].top <= top && visibleObjects[i].top + visibleObjects[i].height >= top) {
857                    skip = i
858                    break;
859                }
860            }
861            let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0);
862            if (reduce == 0) {
863                return
864            }
865            while (reduce <= this.tableElement!.clientHeight) {
866                let newTableElement = this.createNewTableElement(visibleObjects[skip]);
867                this.tbodyElement?.append(newTableElement)
868                this.currentRecycleList.push(newTableElement)
869                reduce += newTableElement.clientHeight
870            }
871            for (let i = 0; i < this.currentRecycleList.length; i++) {
872                this.freshCurrentLine(this.currentRecycleList[i], visibleObjects[i + skip])
873            }
874        })
875        return visibleObjects
876    }
877
878    meauseTreeRowElement(list: any[]): TableRowObject[] {
879        this.meauseRowElement = undefined
880        this.tbodyElement!.innerHTML = '';
881        this.treeElement!.innerHTML = '';
882        let headHeight = this.theadElement?.clientHeight || 0
883        let totalHeight = 0
884        let visibleObjects: TableRowObject[] = []
885        this.currentRecycleList = []
886        this.currentTreeDivList = []
887        let resetAllHeight = (list: any[], depth: number, parentNode?: TableRowObject) => {
888            list.forEach((item) => {
889                let tableRowObject = new TableRowObject();
890                tableRowObject.depth = depth
891                tableRowObject.data = item
892                tableRowObject.top = totalHeight
893                tableRowObject.height = this.meauseTreeElementHeight(tableRowObject, depth)
894                if (parentNode != undefined) {
895                    parentNode.children.push(tableRowObject)
896                }
897                if (Math.max(totalHeight, this.tableElement!.scrollTop) <= Math.min(totalHeight + tableRowObject.height, this.tableElement!.scrollTop + this.tableElement!.clientHeight - headHeight)) {
898                    let newTableElement = this.createNewTreeTableElement(tableRowObject);
899                    newTableElement.style.transform = `translateY(${totalHeight}px)`
900                    this.tbodyElement?.append(newTableElement)
901                    if (this.treeElement?.lastChild) {
902                        (this.treeElement?.lastChild as HTMLElement).style.height = tableRowObject.height + "px";
903                    }
904                    this.currentRecycleList.push(newTableElement)
905                }
906                totalHeight += tableRowObject.height
907                visibleObjects.push(tableRowObject)
908                if (item.children != undefined && item.children.length > 0) {
909                    resetAllHeight(item.children, depth + 1, tableRowObject)
910                }
911            })
912        }
913        resetAllHeight(list, 0)
914        this.tbodyElement && (this.tbodyElement.style.height = totalHeight + "px")
915        this.treeElement!.style.height = (this.tableElement!.clientHeight - this.theadElement!.clientHeight) + "px"
916        this.tableElement && (this.tableElement.onscroll = (event) => {
917            let visibleObjects = this.recycleDs.filter((item) => {
918                return !item.rowHidden
919            })
920            let top = this.tableElement!.scrollTop;
921            this.treeElement!.style.transform = `translateY(${top}px)`
922            let skip = 0;
923            for (let i = 0; i < visibleObjects.length; i++) {
924                if (visibleObjects[i].top <= top && visibleObjects[i].top + visibleObjects[i].height >= top) {
925                    skip = i
926                    break;
927                }
928            }
929            let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0);
930            if (reduce == 0) {
931                return
932            }
933            while (reduce <= this.tableElement!.clientHeight) {
934                let newTableElement = this.createNewTreeTableElement(visibleObjects[skip]);
935                this.tbodyElement?.append(newTableElement)
936                if (this.treeElement?.lastChild) {
937                    (this.treeElement?.lastChild as HTMLElement).style.height = visibleObjects[skip].height + "px";
938                }
939                this.currentRecycleList.push(newTableElement)
940                reduce += newTableElement.clientHeight
941            }
942            for (let i = 0; i < this.currentRecycleList.length; i++) {
943                this.freshCurrentLine(this.currentRecycleList[i], visibleObjects[i + skip], (this.treeElement?.children[i] as HTMLElement));
944            }
945        })
946        return visibleObjects
947    }
948
949
950    createNewTreeTableElement(rowData: TableRowObject): any {
951        let newTableElement = document.createElement('div');
952        newTableElement.classList.add('tr');
953        let gridTemplateColumns: Array<any> = [];
954        let treeTop = 0;
955        if (this.treeElement!.children?.length > 0) {
956            let transX = Number((this.treeElement?.lastChild as HTMLElement).style.transform.replace(/[^0-9]/ig, ""));
957            treeTop += (transX + rowData.height)
958        }
959        this?.columns?.forEach((column: any, index) => {
960            let dataIndex = column.getAttribute('data-index') || '1';
961            let td: any
962            if (index === 0) {
963                if (column.template) {
964                    td = column.template.render(rowData.data).content.cloneNode(true);
965                    td.template = column.template
966                } else {
967                    td = document.createElement('div')
968                    td.innerHTML = this.formatName(rowData.data[dataIndex]);
969                    td.dataIndex = dataIndex
970                }
971                if (rowData.data.children && rowData.data.children.length > 0) {
972                    let btn = this.createExpandBtn(rowData)
973                    td.insertBefore(btn, td.firstChild);
974                    td.style.paddingLeft = rowData.depth * 15 + 'px';
975                } else {
976                    td.style.paddingLeft = rowData.depth * 15 + 20 + 'px';
977                }
978                (td as any).data = rowData.data
979                td.classList.add('tree-first-body');
980                td.style.position = 'absolute';
981                td.style.top = '0px'
982                td.style.left = '0px'
983                td.onmouseenter = () => {
984                    let indexOf = this.currentTreeDivList.indexOf(td);
985                    this.currentRecycleList.forEach((row)=>{
986                        row.classList.remove('mouse-in')
987                    })
988                    if (indexOf >= 0 && indexOf < this.currentRecycleList.length && td.innerHTML != "") {
989                        this.setMouseIn(true, [newTableElement]);
990                    }
991                }
992                td.onmouseleave = () => {
993                    let indexOf = this.currentTreeDivList.indexOf(td);
994                    if (indexOf >= 0 && indexOf < this.currentRecycleList.length) {
995                        this.setMouseIn(false, [newTableElement]);
996                    }
997                }
998                td.onclick = () => {
999                    let indexOf = this.currentTreeDivList.indexOf(td);
1000                    this.dispatchRowClickEvent(rowData, [(this.treeElement?.children[indexOf] as HTMLElement), newTableElement])
1001                }
1002                this.treeElement!.style.width = column.getAttribute('width')
1003                this.treeElement?.append(td)
1004                this.currentTreeDivList.push(td)
1005            } else {
1006                gridTemplateColumns.push(column.getAttribute('width') || '1fr')
1007                td = document.createElement('div')
1008                td.classList.add('td');
1009                td.style.overflow = 'hidden'
1010                td.style.textOverflow = 'ellipsis'
1011                td.style.whiteSpace = "nowrap"
1012                td.title = rowData.data[dataIndex]
1013                td.dataIndex = dataIndex
1014                td.style.justifyContent = column.getAttribute('align') || 'flex-start'
1015                if (column.template) {
1016                    td.appendChild(column.template.render(rowData.data).content.cloneNode(true));
1017                    td.template = column.template
1018                } else {
1019                    td.innerHTML = this.formatName(rowData.data[dataIndex]);
1020                }
1021                newTableElement.append(td)
1022            }
1023        });
1024        (this.treeElement?.lastChild as HTMLElement).style.transform = `translateY(${treeTop}px)`;
1025        (newTableElement as any).data = rowData.data
1026        newTableElement.style.gridTemplateColumns = gridTemplateColumns.join(' ');
1027        newTableElement.style.position = 'absolute';
1028        newTableElement.style.top = '0px'
1029        newTableElement.style.left = '0px'
1030        newTableElement.style.cursor = 'pointer'
1031        newTableElement.onmouseenter = () => {
1032            if ((newTableElement as any).data.isSelected) return;
1033            let indexOf = this.currentRecycleList.indexOf(newTableElement);
1034            this.currentTreeDivList.forEach((row)=>{
1035                row.classList.remove('mouse-in')
1036            })
1037            if (indexOf >= 0 && indexOf < this.treeElement!.children.length) {
1038                this.setMouseIn(true, [(this.treeElement?.children[indexOf] as HTMLElement)]);
1039            }
1040        }
1041        newTableElement.onmouseleave = () => {
1042            if ((newTableElement as any).data.isSelected) return;
1043            let indexOf = this.currentRecycleList.indexOf(newTableElement);
1044            if (indexOf >= 0 && indexOf < this.treeElement!.children.length) {
1045                this.setMouseIn(false, [(this.treeElement?.children[indexOf] as HTMLElement)]);
1046            }
1047        }
1048        newTableElement.onclick = e => {
1049            let indexOf = this.currentRecycleList.indexOf(newTableElement);
1050            this.dispatchRowClickEvent(rowData, [(this.treeElement?.children[indexOf] as HTMLElement), newTableElement])
1051        }
1052        return newTableElement
1053    }
1054
1055    createExpandBtn(rowData: any) {
1056        let btn: any = document.createElement('lit-icon');
1057        btn.classList.add('tree-icon');
1058        // @ts-ignore
1059        if (rowData.expanded) {
1060            btn.name = 'minus-square';
1061        } else {
1062            btn.name = 'plus-square';
1063        }
1064        btn.onclick = (e: Event) => {
1065            const resetNodeHidden = (hidden: boolean, rowData: any) => {
1066                if (rowData.children.length > 0) {
1067                    if (hidden) {
1068                        rowData.children.forEach((child: any) => {
1069                            child.rowHidden = true
1070                            resetNodeHidden(hidden, child)
1071                        })
1072                    } else {
1073                        rowData.children.forEach((child: any) => {
1074                            child.rowHidden = !rowData.expanded
1075                            if (rowData.expanded) {
1076                                resetNodeHidden(hidden, child)
1077                            }
1078                        })
1079                    }
1080                }
1081            }
1082            const foldNode = () => {
1083                rowData.expanded = false
1084                resetNodeHidden(true, rowData)
1085            };
1086            const expendNode = () => {
1087                rowData.expanded = true
1088                resetNodeHidden(false, rowData)
1089            }
1090            if (rowData.expanded) {
1091                foldNode()
1092            } else {
1093                expendNode()
1094            }
1095            this.reMeauseHeight()
1096            e.stopPropagation();
1097        };
1098        return btn
1099    }
1100
1101    reMeauseHeight() {
1102        if (this.currentRecycleList.length == 0) {
1103            return
1104        }
1105        let totalHeight = 0
1106        this.recycleDs.forEach((it) => {
1107            if (!it.rowHidden) {
1108                it.top = totalHeight
1109                totalHeight += it.height
1110            }
1111        })
1112        this.tbodyElement && (this.tbodyElement.style.height = totalHeight + (this.isScrollXOutSide?0:0) + "px")
1113        this.treeElement!.style.height = (this.tableElement!.clientHeight - this.theadElement!.clientHeight) + "px"
1114        let visibleObjects = this.recycleDs.filter((item) => {
1115            return !item.rowHidden
1116        })
1117        let top = this.tableElement!.scrollTop;
1118        let skip = 0;
1119        for (let i = 0; i < visibleObjects.length; i++) {
1120            if (visibleObjects[i].top <= top && visibleObjects[i].top + visibleObjects[i].height >= top) {
1121                skip = i
1122                break;
1123            }
1124        }
1125        let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0);
1126        if (reduce == 0) {
1127            return
1128        }
1129        while (reduce <= this.tableElement!.clientHeight) {
1130            let newTableElement
1131            if (this.hasAttribute('tree')) {
1132                newTableElement = this.createNewTreeTableElement(visibleObjects[skip]);
1133            } else {
1134                newTableElement = this.createNewTableElement(visibleObjects[skip])
1135            }
1136            this.tbodyElement?.append(newTableElement)
1137            if (this.hasAttribute('tree')) {
1138                if (this.treeElement?.lastChild) {
1139                    (this.treeElement?.lastChild as HTMLElement).style.height = visibleObjects[skip].height + "px";
1140                }
1141            }
1142            this.currentRecycleList.push(newTableElement)
1143            reduce += newTableElement.clientHeight
1144        }
1145        for (let i = 0; i < this.currentRecycleList.length; i++) {
1146            if (this.hasAttribute('tree')) {
1147                this.freshCurrentLine(this.currentRecycleList[i], visibleObjects[i + skip], (this.treeElement?.children[i] as HTMLElement))
1148            } else {
1149                this.freshCurrentLine(this.currentRecycleList[i], visibleObjects[i + skip])
1150            }
1151        }
1152    }
1153
1154    createNewTableElement(rowData: any): any {
1155        let newTableElement = document.createElement('div');
1156        newTableElement.classList.add('tr');
1157        let gridTemplateColumns: Array<any> = [];
1158        this?.columns?.forEach((column: any) => {
1159            let dataIndex = column.getAttribute('data-index') || '1';
1160            gridTemplateColumns.push(column.getAttribute('width') || '1fr')
1161            let td: any
1162            td = document.createElement('div')
1163            td.classList.add('td');
1164            td.style.overflow = 'hidden'
1165            td.style.textOverflow = 'ellipsis'
1166            td.style.whiteSpace = "nowrap"
1167            td.dataIndex = dataIndex
1168            td.style.justifyContent = column.getAttribute('align') || 'flex-start'
1169            td.title = rowData.data[dataIndex]
1170            if (column.template) {
1171                td.appendChild(column.template.render(rowData.data).content.cloneNode(true));
1172                td.template = column.template
1173            } else {
1174                td.innerHTML = this.formatName(rowData.data[dataIndex]);
1175            }
1176            newTableElement.append(td)
1177        })
1178        newTableElement.onclick = () => {
1179            this.dispatchRowClickEvent(rowData, [newTableElement])
1180        }
1181        if (rowData.data.isSelected != undefined) {
1182            this.setSelectedRow(rowData.data.isSelected, [newTableElement])
1183        }
1184        (newTableElement as any).data = rowData.data
1185        newTableElement.style.cursor = "pointer"
1186        newTableElement.style.gridTemplateColumns = gridTemplateColumns.join(' ');
1187        newTableElement.style.position = 'absolute';
1188        newTableElement.style.top = '0px'
1189        newTableElement.style.left = '0px'
1190        return newTableElement
1191    }
1192
1193    freshCurrentLine(element: HTMLElement, rowObject: TableRowObject, firstElement?: HTMLElement) {
1194        if (!rowObject) {
1195            if (firstElement) {
1196                firstElement.style.display = 'none'
1197            }
1198            element.style.display = 'none'
1199            return
1200        }
1201        let childIndex = -1
1202        element.childNodes.forEach((child) => {
1203            if (child.nodeType != 1) return
1204            childIndex++;
1205            let idx = firstElement != undefined ? childIndex + 1 : childIndex;
1206            if (firstElement != undefined && childIndex == 0) {
1207                (firstElement as any).data = rowObject.data
1208                if ((this.columns![0] as any).template) {
1209                    firstElement.innerHTML = (this.columns![0] as any).template.render(rowObject.data).content.cloneNode(true).innerHTML
1210                } else {
1211                    let dataIndex = this.columns![0].getAttribute('data-index') || '1';
1212                    firstElement.innerHTML = this.formatName(rowObject.data[dataIndex])
1213                    firstElement.title = rowObject.data[dataIndex]
1214                }
1215                if (rowObject.children && rowObject.children.length > 0) {
1216                    let btn = this.createExpandBtn(rowObject)
1217                    firstElement.insertBefore(btn, firstElement.firstChild);
1218                    firstElement.style.paddingLeft = 15 * rowObject.depth + "px"
1219                } else {
1220                    firstElement.style.paddingLeft = 20 + 15 * rowObject.depth + "px"
1221                }
1222                firstElement.onclick = () => {
1223                    this.dispatchRowClickEvent(rowObject, [firstElement, element])
1224                }
1225                firstElement.style.transform = `translateY(${rowObject.top - this.tableElement!.scrollTop}px)`
1226                if (rowObject.data.isSelected != undefined) {
1227                    this.setSelectedRow(rowObject.data.isSelected, [firstElement])
1228                } else {
1229                    this.setSelectedRow(false, [firstElement])
1230                }
1231            }
1232            let dataIndex = this.columns![idx].getAttribute('data-index') || '1';
1233            if ((this.columns![idx] as any).template) {
1234                (child as HTMLElement).innerHTML = "";
1235                (child as HTMLElement).appendChild((this.columns![idx] as any).template.render(rowObject.data).content.cloneNode(true));
1236                (child as HTMLElement).title = rowObject.data[dataIndex];
1237            } else {
1238                (child as HTMLElement).innerHTML = this.formatName(rowObject.data[dataIndex]);
1239                (child as HTMLElement).title = rowObject.data[dataIndex];
1240            }
1241        })
1242        if (element.style.display == 'none') {
1243            element.style.display = 'grid'
1244        }
1245        element.style.transform = `translateY(${rowObject.top}px)`
1246        if (firstElement && firstElement.style.display == 'none') {
1247            firstElement.style.display = 'flex'
1248        }
1249        element.onclick = e => {
1250            if (firstElement != undefined) {
1251                this.dispatchRowClickEvent(rowObject, [firstElement, element])
1252            } else {
1253                this.dispatchRowClickEvent(rowObject, [element])
1254            }
1255        }
1256        (element as any).data = rowObject.data
1257        if (rowObject.data.isSelected != undefined) {
1258            this.setSelectedRow(rowObject.data.isSelected, [element])
1259        } else {
1260            this.setSelectedRow(false, [element])
1261        }
1262    }
1263
1264    setSelectedRow(isSelected: boolean, rows: any[]) {
1265        if (isSelected) {
1266            rows.forEach((row) => {
1267                if (row.classList.contains("mouse-in")) row.classList.remove('mouse-in');
1268                row.classList.add('mouse-select')
1269            })
1270        } else {
1271            rows.forEach((row) => {
1272                row.classList.remove('mouse-select')
1273            })
1274        }
1275    }
1276
1277    setMouseIn(isMouseIn: boolean, rows: any[]) {
1278        if (isMouseIn) {
1279            rows.forEach((row) => {
1280                row.classList.add('mouse-in')
1281            })
1282        } else {
1283            rows.forEach((row) => {
1284                row.classList.remove('mouse-in')
1285            })
1286        }
1287    }
1288
1289    scrollToData(data: any) {
1290        if (this.isRecycleList) {
1291            if (this.recycleDs.length > 0) {
1292                let filter = this.recycleDs.filter((item) => {
1293                    return item.data == data
1294                });
1295                if (filter.length > 0) {
1296                    this.tableElement!.scrollTop = filter[0].top
1297                }
1298                this.setCurrentSelection(data)
1299            }
1300        } else {
1301            if (this.normalDs.length > 0) {
1302                let filter = this.normalDs.filter((item) => {
1303                    return item.data == data
1304                });
1305                if (filter.length > 0) {
1306                    this.tableElement!.scrollTop = filter[0].top
1307                }
1308            }
1309        }
1310
1311
1312    }
1313
1314    expandList(datasource: any[]) {
1315        let filter = this.recycleDs.filter((item) => {
1316            return datasource.indexOf(item.data) != -1
1317        });
1318        if (filter.length > 0) {
1319            filter.forEach((item) => {
1320                item.expanded = true
1321                item.rowHidden = false
1322            })
1323        }
1324        this.reMeauseHeight()
1325    }
1326
1327    clearAllSelection(rowObjectData: any) {
1328        if (this.isRecycleList) {
1329            this.recycleDs.forEach((item) => {
1330                if (item.data != rowObjectData && item.data.isSelected) {
1331                    item.data.isSelected = false
1332                }
1333            })
1334            this.setSelectedRow(false, this.currentTreeDivList)
1335            this.setSelectedRow(false, this.currentRecycleList)
1336        } else {
1337            this.dataSource.forEach((item) => {
1338                if (item != rowObjectData && item.isSelected) {
1339                    item.isSelected = false
1340                }
1341            })
1342            this.setSelectedRow(false, this.normalDs)
1343        }
1344
1345    }
1346
1347    setCurrentSelection(data: any) {
1348        if (this.isRecycleList) {
1349            if (data.isSelected != undefined) {
1350                this.currentTreeDivList.forEach((item) => {
1351                    if ((item as any).data == data) {
1352                        this.setSelectedRow(data.isSelected, [item])
1353                    }
1354                })
1355                this.currentRecycleList.forEach((item) => {
1356                    if ((item as any).data == data) {
1357                        this.setSelectedRow(data.isSelected, [item])
1358                    }
1359                })
1360            }
1361        } else {
1362            if (data.isSelected != undefined) {
1363                this.normalDs.forEach((item) => {
1364                    if ((item as any).data == data) {
1365                        this.setSelectedRow(data.isSelected, [item])
1366                    }
1367                })
1368            }
1369        }
1370
1371    }
1372
1373    dispatchRowClickEvent(rowObject: any, elements: any[]) {
1374        this.dispatchEvent(new CustomEvent('row-click', {
1375            detail: {
1376                ...rowObject.data, data: rowObject.data, callBack: (isSelected: boolean) => {//是否爲单选
1377                    if (isSelected) {
1378                        this.clearAllSelection(rowObject.data)
1379                    }
1380                    this.setSelectedRow(rowObject.data.isSelected, elements)
1381                }
1382            }, composed: true,
1383        }));
1384    }
1385
1386    formatName(name:any){
1387        if(name!=undefined&&name!==null){
1388            return name.toString().replace("<","&lt;").replace(">","&gt;")
1389        }
1390        return ""
1391    }
1392}
1393