/** * Copyright Aquera Inc 2023 * * This source code is licensed under the BSD-3-Clause license found in the * LICENSE file in the root directory of this source tree. */ import {LitElement, html, CSSResultArray, TemplateResult, PropertyValues} from 'lit'; import { customElement, property, query, state} from 'lit/decorators.js'; import {styles} from './nile-table.css'; import NileElement from '../internal/nile-element'; import { NileTableBody } from '../nile-table-body'; import { NileTableCellItem } from '../nile-table-cell-item'; import { NileTableHeaderItem } from '../nile-table-header-item'; /** * Nile table component. * * @tag nile-table * */ @customElement('nile-table') export class NileTable extends NileElement { @query('slot') defaultSlot: HTMLSlotElement; private rows:Array=[]; private primaryRowWidths:Array=[] private resizeObserver:ResizeObserver ; private debounceTimeout:any /** * The styles for nile-table * @remarks If you are extending this class you can extend the base styles with super. Eg `return [super(), myCustomStyles]` */ public static get styles(): CSSResultArray { return [styles]; } connectedCallback(): void { super.connectedCallback() this.addEventListener('nile-body-load',this.handleRows) } protected firstUpdated(_changedProperties: PropertyValues): void { this.updateComplete.then(()=>{ this.handleResizeObserver(); }) } /* #endregion */ /* #region Methods */ /** * Render method * @slot This is a slot test */ public render(): TemplateResult { return html` `; } repaintTable(){ this.realignStructure(); this.handleBodyCssUpdate(); } handleRows(e:CustomEvent){ this.rows=[...this.rows,e.detail.comp] } handleBodyCssUpdate(){ if (this.rows.length<2) return; const tableBodies = this.rows; const firstEl=tableBodies[0].shadowRoot?.querySelector('div.base'); if(firstEl) { firstEl.style.borderTopRightRadius="var(--nile-radius-radius-xl)"; firstEl.style.borderTopLeftRadius = 'var(--nile-radius-radius-xl)'; firstEl.style.borderBottomRightRadius="0px"; firstEl.style.borderBottomLeftRadius = '0px'; firstEl.style.borderBottom = 'none'; } tableBodies.forEach((tb,i)=>{ if(i>0 && i('div.base'); if(el) { el.style.borderTopRightRadius="0px"; el.style.borderTopLeftRadius = "0px"; el.style.borderBottomRightRadius="0px"; el.style.borderBottomLeftRadius = "0px"; el.style.borderBottom = 'none'; } } }) const lastEl=tableBodies[tableBodies.length - 1].shadowRoot?.querySelector('div.base') if(lastEl){ lastEl.style.borderTopRightRadius="0px"; lastEl.style.borderTopLeftRadius = '0px'; lastEl.style.borderBottomRightRadius="var(--nile-radius-radius-xl)"; lastEl.style.borderBottomLeftRadius = 'var(--nile-radius-radius-xl)'; } } getPrimaryColumnWidths(){ const primaryTb=this.rows.find(tb=>tb.type=='primary')!; const widthArray=this.getTableCellFetchQuery(primaryTb).map((e:LitElement)=>e.clientWidth) as Array return widthArray; } realignStructure(){ if (this.rows.length<2) return; const primaryRowWidths=this.getPrimaryColumnWidths(); const secondaryRows=this.rows.filter(tb=>tb.type!='primary'); secondaryRows.forEach((row)=>{ let elements=this.getTableCellFetchQuery(row) elements?.forEach((el:NileTableCellItem|NileTableHeaderItem,ind)=>{ el.style.setProperty('--cell-width',primaryRowWidths.at(ind)+'px') }) }) } getTableCellFetchQuery(row:NileTableBody):Array{ return row?.shadowRoot?. querySelector('slot:not([name])')?. assignedElements()[0] .shadowRoot?.querySelector('slot')?. assignedElements()! } handleResizeObserver(){ const onResize = (entries:ResizeObserverEntry[]): void=> { for (let entry of entries) { if(this.debounceTimeout){ clearTimeout(this.debounceTimeout); } this.debounceTimeout=setTimeout(() => { this.realignStructure(); this.debounceTimeout=null; }, 50); } }; this.resizeObserver=new ResizeObserver(onResize) this.resizeObserver.observe(this); } disconnectedCallback(): void { this.resizeObserver.disconnect() super.disconnectedCallback() } /* #endregion */ } export default NileTable; declare global { interface HTMLElementTagNameMap { 'nile-table': NileTable; } }