Skip to content

Latest commit

 

History

History
196 lines (178 loc) · 5 KB

table.md

File metadata and controls

196 lines (178 loc) · 5 KB

Table

notebook.json

{
  "dataFiles": [
    ["planets.csv.md", "planets.csv"]
  ]
}

data-table.js

export class DataTable extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({mode: 'open'})
  }

  connectedCallback() {
    const style = document.createElement('style')
    style.textContent = `
      th, td {
        padding: 3px 5px;
      }
      th {
        background-color: #78c;
      }
      td {
        background-color: #aaa;
        text-align: right;
      }
      td:first-child {
        text-align: left;
      }
    `
    this.shadowRoot.append(style)
  }

  set data(data) {
    const tableHead = document.createElement('thead')
    const tableHeadRow = document.createElement('tr')
    tableHeadRow.append(...data[0].map(s => {
      const th = document.createElement('th')
      th.innerText = s
      return th
    }))
    tableHead.append(tableHeadRow)
    const tableBody = document.createElement('tbody')
    tableBody.append(...data.slice(1).map(row => {
      const tableRow = document.createElement('tr')
      tableRow.append(...row.map(s => {
        const td = document.createElement('td')
        td.innerText = s
        return td
      }))
      return tableRow
    }))
    if (this.table) {
      this.table.replaceChildren(tableHead, tableBody)
    } else {
      this.table = document.createElement('table')
      this.table.append(tableHead, tableBody)
      this.shadowRoot.append(this.table)
    }
  }
}

app-view.js

export class AppView extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({mode: 'open'})
    this.dataTable = document.createElement('data-table')
    this.shadowRoot.append(this.dataTable)
    const data = this.data
    const rows = this.data.split("\n").map(row => Array.from(row.matchAll(/([^",]+)|"([^"]*)"[,$]/g)).map(m => m[2] ?? m[1]))
    this.dataTable.data = rows
  }

  connectedCallback() {
    const globalStyle = document.createElement('style')
    globalStyle.textContent = `
      body {
        margin: 0;
        padding: 0;
      }
      html {
        box-sizing: border-box;
      }
      *, *:before, *:after {
        box-sizing: inherit;
      }
    `
    document.head.append(globalStyle)

    const style = document.createElement('style')
    style.textContent = `
    `
    this.shadowRoot.append(style)
  }

  get data() {
    if (!this._data) {
      for (const block of readBlocksWithNames(__source)) {
        if (block.name === 'planets.csv') {
          this._data = __source.slice(...block.contentRange)
          return this._data
        }
      }
      for (const block of readBlocksWithNames(__source)) {
        if (block.name === 'planets.csv.md') {
          const blockContent = __source.slice(...block.contentRange)
          for (const subBlock of readBlocksWithNames(blockContent)) {
            if (subBlock.name === 'planets.csv') {
              this._data = blockContent.slice(...subBlock.contentRange)
              return this._data
            }
          }
        }
      }
    }
    return this._data
  }
}

app.js

import {DataTable} from '/data-table.js'
import {AppView} from '/app-view.js'

customElements.define('data-table', DataTable)
customElements.define('app-view', AppView)

async function setup() {
  const appView = document.createElement('app-view')
  document.body.append(appView)
}

await setup()

thumbnail.svg

<svg viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg" fill="#111">
  <style>
    svg {
      background-color: #000;
    }
    .color1 {
      fill: #78c;
    }
    .color2 {
      fill: #aaa;
    }
  </style>
  <g transform="translate(10, 20)">
    <rect x="20" y="20" width="60" height="20" class="color1" />
    <rect x="90" y="20" width="60" height="20" class="color1" />
    <rect x="160" y="20" width="60" height="20" class="color1" />
  </g>
  <g transform="translate(10, 50)">
    <rect x="20" y="20" width="60" height="20" class="color2" />
    <rect x="90" y="20" width="60" height="20" class="color2" />
    <rect x="160" y="20" width="60" height="20" class="color2" />
  </g>
  <g transform="translate(10, 80)">
    <rect x="20" y="20" width="60" height="20" class="color2" />
    <rect x="90" y="20" width="60" height="20" class="color2" />
    <rect x="160" y="20" width="60" height="20" class="color2" />
  </g>
  <g transform="translate(10, 110)">
    <rect x="20" y="20" width="60" height="20" class="color2" />
    <rect x="90" y="20" width="60" height="20" class="color2" />
    <rect x="160" y="20" width="60" height="20" class="color2" />
  </g>
  <g transform="translate(10, 140)">
    <rect x="20" y="20" width="60" height="20" class="color2" />
    <rect x="90" y="20" width="60" height="20" class="color2" />
    <rect x="160" y="20" width="60" height="20" class="color2" />
  </g>
  <g transform="translate(10, 170)">
    <rect x="20" y="20" width="60" height="20" class="color2" />
    <rect x="90" y="20" width="60" height="20" class="color2" />
    <rect x="160" y="20" width="60" height="20" class="color2" />
  </g>
</svg>