Created
October 13, 2021 11:12
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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