Skip to content

Instantly share code, notes, and snippets.

@nemethmik
Created October 13, 2021 11:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nemethmik/2e8f93e10c08b0cdf88428cc3a8634d7 to your computer and use it in GitHub Desktop.
Save nemethmik/2e8f93e10c08b0cdf88428cc3a8634d7 to your computer and use it in GitHub Desktop.
A single-page show case using Lit-html and LitElement directly in an HTML page featuring Shadow DOM custom elements with Bootstrap support, Custom Event handling and a lot more.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link id=bootstrap href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title>Lit Shadow Web Components</title>
</head>
<body>
<style>
button{color:red}
</style>
<!-- WARNING: slots work only in Shadow DOM-->
<div id=root></div>
<script type="module">
import { LitElement, html, css, render } from "https://unpkg.com/lit-element/lit-element.js?module"
class BLitElement extends LitElement {
connectedCallback() {
super.connectedCallback()
let linkElem = document.getElementById("bootstrap")
if(linkElem && linkElem.href && linkElem.href.includes("bootstrap")) {
//console.log("Bootrap link element found",linkElem)
linkElem = linkElem.cloneNode(true)
linkElem.removeAttribute("id") // To keep the bootstrap ID globally unique
} else {
console.warn("Bootrap link element not found; creating a default link. Add an id=bootstrap to your link element.")
linkElem = document.createElement("link")
linkElem.setAttribute("rel", "stylesheet")
linkElem.setAttribute("href", "https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css")
}
this.shadowRoot.appendChild(linkElem)
}
}
window.customElements.define('simple-greeting',class extends BLitElement {
static styles = css`p { color: blue }`
static properties = {name: {type: String},}
constructor() {
super();
this.name = "Somebody"
}
render() {
return html`<p>Hello, ${this.name}!</p>`
}
})
window.customElements.define("my-counter", class extends BLitElement {
static properties = {count:{type:Number}, label:{type:String} }
constructor() {
super()
this.label = "Up"
this.count = 0
}
render() { return html`
<p>
<slot>Counter</slot>
<span>${this.count}</span>
<button @click=${this.increment}>
<slot name=btn-label>${this.label}</slot>
</button>
</p>
`}
_dispatchCounterChangeEvent() {
// console.log("Dispatching counterchange")
this.dispatchEvent(new CustomEvent("counterchange",{detail:this.count,composed:true,bubbles:true}))
}
increment() {
this.count++
this._dispatchCounterChangeEvent()
}
decrement() {
this.count--
this._dispatchCounterChangeEvent()
}
})
function decrementAllCounters() {
const counters = document.querySelectorAll("my-counter")
counters.forEach((c => c.decrement()))
}
render(html`<!-- NO FLICKER -->
<h1>Lit Shadow Web Components</h1>
<button @click=${decrementAllCounters}>Decrement All Counters</button>
<simple-greeting name=Lit></simple-greeting>
<my-counter count=10>Click to Count<span slot=btn-label>Increment</span></my-counter>
<my-counter label="INC"></my-counter>
<my-counter><b>My Counter</b></my-counter>
<my-counter><div slot=btn-label>Click Me</div></my-counter>
`, document.getElementById("root"))
</script>
<div id=counterdisplay></div>
<script type="module">
import { LitElement, html, css, render } from "https://unpkg.com/lit-element/lit-element.js?module"
//console.log("Adding event listener")
document.body.addEventListener("counterchange",(e) => {
const count/*:Number*/ = e.detail
// console.log("counterchange",e)
const counterMonitor = document.getElementById("counterdisplay")
const maxCount = parseInt(counterMonitor.getAttribute("maxcount") ?? "0")
if(count > maxCount) {
counterMonitor.setAttribute("maxcount",count)
render(html`
<p>New Max Counter Value ${count}</p>
`,counterMonitor)
}
})
</script>
<h1>Additional Counters</h1>
<simple-greeting name=Counters></simple-greeting>
<my-counter count=10>Click to Count<span slot=btn-label>Increment</span></my-counter>
<my-counter label="INC"></my-counter>
<my-counter><b>My Counter</b></my-counter>
<my-counter><div slot=btn-label>Click Me</div></my-counter>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment