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