import{html as t,render as e,Directives as o}from"../../third_party/lit-html/lit-html.js";const r=e=>{const o=String(e);return t`${o}`};var s=Object.freeze({__proto__:null,stringRenderer:r,codeBlockRenderer:e=>t`<code>${e}</code>`});const i=new Set(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"]);function n(t,e){const o=t.cells.find(t=>t.columnId===e);if(void 0===o)throw new Error(`Found a row that was missing an entry for column ${e}.`);return o}function l(t){return t.renderer?t.renderer(t.value):r(t.value)}function a(t){if("string"==typeof t.value)return t.value;const o=l(t),r=document.createElement("div");return e(o,r),r.innerText}const d=t=>{const{columns:e,rows:o}=t,r=e.some(t=>!0===t.sortable)?0:o.findIndex(t=>!t.hidden)+1;return[e.findIndex(t=>!t.hidden),r]};class c extends Event{constructor(t,e){super("column-header-click"),this.data={column:t,columnIndex:e}}}const h=new Set([" ","Enter"]);class u extends HTMLElement{constructor(){super(...arguments),this.shadow=this.attachShadow({mode:"open"}),this.columns=[],this.rows=[],this.sortState=null,this.focusableCell=[0,1],this.hasRenderedAtLeastOnce=!1}get data(){return{columns:this.columns,rows:this.rows,activeSort:this.sortState}}set data(t){if(this.columns=t.columns,this.rows=t.rows,this.sortState=t.activeSort,this.hasRenderedAtLeastOnce||(this.focusableCell=d({columns:this.columns,rows:this.rows})),this.hasRenderedAtLeastOnce){const[t,e]=this.focusableCell,o=t>this.columns.length,r=e>this.rows.length;this.focusableCell=o||r?[o?this.columns.length:t,r?this.rows.length:e]:d({columns:this.columns,rows:this.rows})}this.render()}scrollToBottomIfRequired(){if(!1===this.hasRenderedAtLeastOnce)return;const t=this.getCurrentlyFocusableCell();if(t&&t===this.shadow.activeElement)return;const e=this.shadow.querySelector("tbody tr:not(.hidden):last-child");e&&e.scrollIntoView()}getCurrentlyFocusableCell(){const[t,e]=this.focusableCell;return this.shadow.querySelector(`[data-row-index="${e}"][data-col-index="${t}"]`)}focusCell([t,e]){const[o,r]=this.focusableCell;o===t&&r===e||(this.focusableCell=[t,e],this.render());const s=this.getCurrentlyFocusableCell();if(!s)throw new Error("Unexpected error: could not find cell marked as focusable");s!==this.shadow.activeElement&&s.focus()}onTableKeyDown(t){const e=t.key;if(h.has(e)){const t=this.getCurrentlyFocusableCell(),[e,o]=this.focusableCell,r=this.columns[e];t&&0===o&&r&&r.sortable&&this.onColumnHeaderClick(r,e)}if(!function(t){return i.has(t)}(e))return;const o=function(t){const{key:e,currentFocusedCell:o,columns:r,rows:s}=t,[i,n]=o;switch(e){case"ArrowLeft":{if(i===r.findIndex(t=>!t.hidden))return[i,n];let t=i;for(let e=t-1;e>=0;e--){if(!r[e].hidden){t=e;break}}return[t,n]}case"ArrowRight":{let t=i;for(let e=t+1;e<r.length;e++){if(!r[e].hidden){t=e;break}}return[t,n]}case"ArrowUp":{const t=r.some(t=>!0===t.sortable)?0:1;if(n===t)return[i,n];let e=n;for(let o=n-1;o>=t;o--){if(0===o){e=0;break}if(!s[o-1].hidden){e=o;break}}return[i,e]}case"ArrowDown":{if(0===n){const t=s.findIndex(t=>!t.hidden);return t>-1?[i,t+1]:[i,n]}let t=n;for(let e=t+1;e<s.length+1;e++){if(!s[e-1].hidden){t=e;break}}return[i,t]}}}({key:e,currentFocusedCell:this.focusableCell,columns:this.columns,rows:this.rows});this.focusCell(o)}onColumnHeaderClick(t,e){this.dispatchEvent(new c(t,e))}ariaSortForHeader(t){return!t.sortable||this.sortState&&this.sortState.columnId===t.id?this.sortState&&this.sortState.columnId===t.id?"ASC"===this.sortState.direction?"ascending":"descending":void 0:"none"}renderEmptyRow(){const e=this.columns.filter(t=>!t.hidden).map((e,r)=>{const s=o.classMap({firstVisibleColumn:0===r});return t`<td class=${s}></td>`});return t`<tr>${e}</tr>`}render(){const r=this.columns.findIndex(t=>!t.hidden),s=this.columns.some(t=>!0===t.sortable),i=this.rows.filter(t=>!t.hidden).length;e(t`
    <style>
      :host {
        --table-divider-color: #aaa;
        --toolbar-bg-color: #f3f3f3;
        --selected-row-color: rgb(212, 212, 212);
        --selection-bg-color: #1a73e8;

        height: 100%;
        display: block;
      }
      /* Ensure that vertically we don't overflow */
      .wrapping-container {
        overflow-y: scroll;
        /* Use max-height instead of height to ensure that the
           table does not use more space than necessary. */
        height: 100%;
        position: relative;
      }

      table {
        border-spacing: 0;
        width: 100%;
        height: 100%;
        /* To make sure that we properly hide overflowing text
           when horizontal space is too narrow. */
        table-layout: fixed;
      }

      tr {
        outline: none;
      }


      tbody tr.selected {
        background-color: var(--selected-row-color);
      }

      table:focus tr.selected {
        background-color: var(--selection-bg-color)
      }

      td, th {
        padding: 1px 4px;
        /* Divider between each cell, except the first one (see below) */
        border-left: 1px solid var(--table-divider-color);
        line-height: 18px;
        height: 18px;
        user-select: text;
        /* Ensure that text properly cuts off if horizontal space is too narrow */
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
      }
      /* There is no divider before the first cell */
      td.firstVisibleColumn, th.firstVisibleColumn {
        border-left: none;
      }

      th {
        font-weight: normal;
        text-align: left;
        border-bottom: 1px solid var(--table-divider-color);
        position: sticky;
        top: 0;
        z-index: 2;
        background-color: var(--toolbar-bg-color);
      }

      .hidden {
        display: none;
      }

      [aria-sort]:hover {
        cursor: pointer;
      }

      [aria-sort="descending"]::after {
        content: " ";
        border-left: 0.3em solid transparent;
        border-right: 0.3em solid transparent;
        border-top: 0.3em solid black;
        position: absolute;
        right: 0.5em;
        top: 0.6em;
      }
      [aria-sort="ascending"]::after {
        content: " ";
        border-bottom: 0.3em solid black;
        border-left: 0.3em solid transparent;
        border-right: 0.3em solid transparent;
        position: absolute;
        right: 0.5em;
        top: 0.6em;
      }
    </style>
    <div class="wrapping-container">
      <table
        aria-rowcount=${this.rows.length}
        aria-colcount=${this.columns.length}
        @keydown=${this.onTableKeyDown}
      >
        <colgroup>
          ${this.columns.filter(t=>!t.hidden).map(e=>{const o=function(t,e){const o=t.filter(t=>!t.hidden).reduce((t,e)=>t+e.widthWeighting,0),r=t.find(t=>t.id===e);if(!r)throw new Error("Could not find column with ID "+e);if(r.widthWeighting<1)throw new Error(`Error with column ${e}: width weightings must be >= 1.`);return r.hidden?0:Math.round(r.widthWeighting/o*100)}(this.columns,e.id);return t`<col style=${`width: ${o}%`}>`})}
        </colgroup>
        <thead>
          <tr>
            ${this.columns.map((e,i)=>{const n=o.classMap({hidden:!0===e.hidden,firstVisibleColumn:i===r}),l=s&&i===this.focusableCell[0]&&0===this.focusableCell[1];return t`<th class=${n}
                data-grid-header-cell=${e.id}
                @click=${()=>{this.focusCell([i,0]),this.onColumnHeaderClick(e,i)}}
                title=${e.title}
                aria-sort=${o.ifDefined(this.ariaSortForHeader(e))}
                aria-colindex=${i+1}
                data-row-index='0'
                data-col-index=${i}
                tabindex=${o.ifDefined(s?l?"0":"-1":void 0)}
              >${e.title}</th>`})}
          </tr>
        </thead>
        <tbody>
          ${0===i?this.renderEmptyRow():this.rows.map((e,s)=>{const i=this.getCurrentlyFocusableCell(),[,d]=this.focusableCell,c=s+1,h=!!i&&(i===document.activeElement&&c===d),u=o.classMap({selected:h,hidden:!0===e.hidden});return t`
              <tr
                aria-rowindex=${s+1}
                class=${u}
              >${this.columns.map((s,i)=>{const d=n(e,s.id),h=o.classMap({hidden:!0===s.hidden,firstVisibleColumn:i===r}),u=i===this.focusableCell[0]&&c===this.focusableCell[1],f=a(d),m=l(d);return t`<td
                  class=${h}
                  title=${f}
                  tabindex=${u?"0":"-1"}
                  aria-colindex=${i+1}
                  data-row-index=${c}
                  data-col-index=${i}
                  data-grid-value-cell-for-column=${s.id}
                  @click=${()=>{this.focusCell([i,c])}}
                >${m}</td>`})}
            `})}
        </tbody>
      </table>
    </div>
    `,this.shadow,{eventContext:this}),this.scrollToBottomIfRequired(),this.hasRenderedAtLeastOnce=!0}}customElements.define("devtools-data-grid",u);var f=Object.freeze({__proto__:null,ColumnHeaderClickEvent:c,DataGrid:u});class m extends HTMLElement{constructor(){super(...arguments),this.shadow=this.attachShadow({mode:"open"}),this.columns=[],this.rows=[],this.originalColumns=[],this.originalRows=[],this.sortState=null}get data(){return{columns:this.originalColumns,rows:this.originalRows,filterText:this.filterText}}set data(t){this.originalColumns=t.columns,this.originalRows=t.rows,this.filterText=t.filterText,this.columns=[...this.originalColumns],this.rows=this.cloneAndFilterRows(t.rows,this.filterText),this.render()}cloneAndFilterRows(t,e){return e?t.map(t=>{const o=t.cells.some(t=>a(t).toLowerCase().includes(e.toLowerCase()));return{...t,hidden:!o}}):[...t]}sortRows(t){const{columnId:e,direction:o}=t;this.rows.sort((t,r)=>{const s=n(t,e),i=n(r,e),l=a(s).toUpperCase(),d=a(i).toUpperCase();return l<d?"ASC"===o?-1:1:l>d?"ASC"===o?1:-1:0}),this.render()}onColumnHeaderClick(t){const{column:e}=t.data;if(this.sortState&&this.sortState.columnId===e.id){const{columnId:t,direction:e}=this.sortState;this.sortState="DESC"===e?null:{columnId:t,direction:"DESC"}}else this.sortState={columnId:e.id,direction:"ASC"};this.sortState?this.sortRows(this.sortState):(this.rows=[...this.originalRows],this.render())}render(){e(t`
      <style>
        :host {
          display: block;
          height: 100%;
          overflow: hidden;
        }
      </style>
      <devtools-data-grid .data=${{columns:this.columns,rows:this.rows,activeSort:this.sortState}}
        @column-header-click=${this.onColumnHeaderClick}
      ></devtools-data-grid>
    `,this.shadow,{eventContext:this})}}customElements.define("devtools-data-grid-controller",m);var w=Object.freeze({__proto__:null,DataGridController:m});export{f as DataGrid,w as DataGridController,s as DataGridRenderers};
