Skip to content

Instantly share code, notes, and snippets.

@tomhodgins
Last active October 20, 2020 03:03
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 tomhodgins/2c051b62284ffa2de7c9aa406688aa6f to your computer and use it in GitHub Desktop.
Save tomhodgins/2c051b62284ffa2de7c9aa406688aa6f to your computer and use it in GitHub Desktop.
class CustomElement extends HTMLElement {
constructor() {
super()
this.shadow = this.attachShadow({mode: 'open'})
this.stylesheet = `
:host,
:host * {
box-sizing: border-box;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-kerning: auto;
}
`
}
static get observedAttributes() {
return [
'boolean',
'custom'
]
}
attributeChangedCallback(name, oldValue, newValue) {
if (
name === 'boolean'
&& newValue !== oldValue
) {
this.updateContent()
}
if (
name === 'custom'
&& newValue !== oldValue
) {
this.updateContent()
}
}
get boolean() {
return this.hasAttribute('boolean')
}
set boolean(value = '') {
return value
? this.setAttribute('boolean', '')
: this.removeAttribute('boolean')
}
get custom() {
return this.getAttribute('custom')
}
set custom(value = '') {
return this.setAttribute('custom', value)
}
updateContent() {
this.shadow.innerHTML = ''
this.shadow.append(
((strings, ...expressions) =>
document.implementation
.createHTMLDocument()
.createRange()
.createContextualFragment(
strings.reduce((output, string, index) =>
output + expressions[index - 1] + string
)
)
)`
<p>Custom Element ShadowDOM</p>
<slot></slot>
<p>Boolean property set to: ${this.boolean}</p>
<p>Custom property set to: ${this.custom}</p>
<style>${this.stylesheet}</style>
`
)
}
connectedCallback() {
this.updateContent()
// Add event listeners here
}
disconnectedCallback() {
// Remove event listeners here
}
}
// Register with HTML parser as a custom element definition
customElements.define('custom-element', CustomElement)
// Demo as string of HTML
document.body.innerHTML += `
<custom-element boolean custom=attribute>
<p>Custom Element Light DOM</p>
</custom-element>
`
// Demo as DOM
document.body.append(
Object.assign(
document.createElement('custom-element'),
{
boolean: true,
custom: 'attribute',
innerHTML: `<p>Custom Element Light DOM</p>`
}
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment