Web Components
Posted on October 1, 2021
Tags: javascript
1 Setup
- project
- dist
- src
- my-element.js
- index.html
- package.json
- vite.config.js (optional)
{"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");
.innerHTML = `
template <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
}
}
.define('my-component',MyComponent)
customElements</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>