Web Components

Posted on October 1, 2021
Tags: javascript

1 Setup

{
  "name": "myproject",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "homepage": "https://lambdajasonyang.github.io/llama2downloader/",
  "scripts": {
    "dev": "vite --host",
    "build": "vite build",
    "preview": "vite preview --host",
    "predeploy": "npm run build",
    "deploy": "gh-pages -d dist -t true"
  },
  "dependencies": {
    "@spectrum-web-components/button": "^0.35.0",
    "@spectrum-web-components/field-label": "^0.35.0",
    "@spectrum-web-components/sidenav": "^0.34.0",
    "@spectrum-web-components/tabs": "^0.35.0",
    "@spectrum-web-components/textfield": "^0.35.0",
    "@spectrum-web-components/theme": "^0.34.0",
    "@spectrum-web-components/top-nav": "^0.34.0",
    "d3": "^7.8.5",
    "lit": "^2.7.6"
  },
  "devDependencies": {
    "gh-pages": "^5.0.0",
    "vite": "^4.4.5"
  }
}
import { defineConfig } from 'vite';

export default defineConfig({
  base: "/llama2downloader/", //fix relative links for github pages gh-pages package
  build: {
    rollupOptions: {
      input: {
        main: './index.html',
        main2: './index2.html',
        // List all files you want in your build outside of src
      }
    }
  }
})

<!doctype html>
<html lang="en">
  <head>

    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + Lit</title>
    
    <script type="module" src="/src/my-element.js"></script>

  </head>
  <body>
    
      <h1>Hello</h1>
    
      <my-element></my-element>
  </body>
</html>
import { LitElement, css, html } from 'lit'

import '@spectrum-web-components/theme/sp-theme.js';
import '@spectrum-web-components/theme/src/themes.js';

import '@spectrum-web-components/button/sp-button.js';
import '@spectrum-web-components/button/sp-clear-button.js';
import '@spectrum-web-components/button/sp-close-button.js';

import '@spectrum-web-components/textfield/sp-textfield.js';

/**
 * An example element.
 *
 * @slot - This element has a slot
 * @csspart button - The button
 */
export class MyElement extends LitElement {
  static get properties() {
    return {
      inputlink : {type:String},
      outputlicense: {type:String},
      docsHint: { type: String },

      count: { type: Number },
    }
  }

  constructor() {
    super()
    this.docsHint = 'Click on the Vite and Lit logos to learn more'
    this.count = 0
  }

  render() {
    return html`
        <sp-theme
            theme="spectrum"
            color="light"
            scale="medium"
            style="background-color: var(--spectrum-gray-100)"
        >

        <sp-textfield @input=${(e)=>{this.inputlink = e.target.value}}></sp-textfield>
            <sp-button @click=${()=>console.log(this.inputlink)}>
                Click me!
            </sp-button>
        </sp-theme>

        <sp-textfield></sp-textfield>
    `
  }

  _onClick() {
    this.count++
  }

  
  
}

window.customElements.define('my-element', MyElement)

2 Vanilla Webcomponent

<!DOCTYPE html>
<html>
<head>
  <title>demo</title>

</head>
<body>


  <script>


class MyComponent extends HTMLElement {
  constructor(){
    super()
    this.attachShadow({ mode: 'open' });
    this.count = 0
  }
  connectedCallback(){
   const mytemplate = this.template()
   this.shadowRoot.appendChild(mytemplate.content.cloneNode(true)); 
   
   this.shadowRoot.querySelector("#hi").onclick = () => {
     this.updateDOM(()=>{this.count++;})
     }
   this.shadowRoot.querySelector("#lo").onclick = () => {
     this.updateDOM(()=>{this.count--;})
     }
   
  }
  template() {
      const template = document.createElement("template");
      template.innerHTML = `
        <button id="hi">hi</button>
        <div id="count">${this.count}</div>
        <slot name="my-text">My default text</slot>
        <button id="lo">lo</button>
        `
      return template;
  }
  updateDOM(sideeffect){
    sideeffect()
   this.shadowRoot.querySelector("#count").textContent = this.count 
   
  }
}

customElements.define('my-component',MyComponent)
  </script>
  <my-component>
    <h1 slot="my-text"><p>Injected "my-text" slot by using attribute `slot="my-text"` in my h1 dom element </p></h1>
  </my-component>
</body>
</html>