Created
February 8, 2024 16:57
-
-
Save krhoyt/c0fbb7ad1fbb1bdf8e808115e6d62487 to your computer and use it in GitHub Desktop.
Template attempting to show the many facets of a baseline web standards-based component. Not intended to function as a component.
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
export default class HoytTemplate extends HTMLElement { | |
constructor() { | |
super(); | |
const template = document.createElement( 'template' ); | |
template.innerHTML = /* template */ ` | |
<style> | |
:host { | |
box-sizing: border-box; | |
display: inline-block; | |
position: relative; | |
} | |
:host( [a-boolean] ) { | |
display: none; | |
} | |
hoyt-component::part( inner ) { | |
--component-stylet: var( --my-component-style, #123456 ); | |
} | |
</style> | |
<hoyt-component exportparts="inner: outer" part="also-outer"></hoyt-component> | |
`; | |
// Properties | |
this._anArray = []; | |
this._aDate = null; | |
this._anObject = null; | |
// Events | |
this.onComponentClick = this.onComponentClick.bind( this ); | |
// Root | |
this.attachShadow( {mode: 'open'} ); | |
this.shadowRoot.appendChild( template.content.cloneNode( true ) ); | |
// Elements | |
this.$component = this.shadowRoot.querySelector( 'hoyt-component' ); | |
} | |
onComponentClick( evt ) { | |
this.dipatchEvent( new CustomEvent( 'krh-event', { | |
bubbles: true, | |
cancelable: false, | |
composed: true, | |
detail: { | |
'abc': 123 | |
} | |
} ) ); | |
} | |
// When attributes change | |
_render() { | |
this.$component.aBoolean = this.aInteger === null ? false : true; | |
} | |
// Promote properties | |
// Values may be set before module load | |
_upgrade( property ) { | |
if( this.hasOwnProperty( property ) ) { | |
const value = this[property]; | |
delete this[property]; | |
this[property] = value; | |
} | |
} | |
// Setup | |
connectedCallback() { | |
this.$component.addEventListener( 'click', this.onComponentClick ); | |
this._upgrade( 'anArray' ); | |
this._upgrade( 'aBoolean' ); | |
this._upgrade( 'aDate' ); | |
this._upgrade( 'aFloat' ); | |
this._upgrade( 'anInteger' ); | |
this._upgrade( 'anObject' ); | |
this._upgrade( 'aString' ); | |
this._render(); | |
} | |
// Set down | |
diconnectedCallback() { | |
this.$component.removeEventListener( 'click', this.onComponentClick ); | |
} | |
// Watched attributes | |
static get observedAttributes() { | |
return [ | |
'a-boolean', | |
'a-float', | |
'an-integer', | |
'a-string' | |
]; | |
} | |
// Observed attribute has changed | |
// Update render | |
attributeChangedCallback( name, old, value ) { | |
this._render(); | |
} | |
// Properties | |
// Not reflected | |
// Array, Date, Object, null | |
get anArray() { | |
return this._anArray.length === 0 ? null : this._anArray; | |
} | |
set anArray( value ) { | |
this._anArray = value === null ? [] : [... value]; | |
} | |
get aDate() { | |
return this._aDate; | |
} | |
set aDate( value ) { | |
this._aDate = value === null ? null : new Date( value.getTime() ); | |
} | |
get anObject() { | |
return this._anObject; | |
} | |
set anObject( value ) { | |
this._anObject = Object.assign( value, {} ); | |
} | |
// Attributes | |
// Reflected | |
// Boolean, Float, Integer, String, null | |
get aBoolean() { | |
return this.hasAttribute( 'a-boolean' ); | |
} | |
set aBoolean( value ) { | |
if( value !== null ) { | |
if( typeof value === 'boolean' ) { | |
value = value.toString(); | |
} | |
if( value === 'false' ) { | |
this.removeAttribute( 'a-boolean' ); | |
} else { | |
this.setAttribute( 'a-boolean', '' ); | |
} | |
} else { | |
this.removeAttribute( 'a-boolean' ); | |
} | |
} | |
get aFloat() { | |
if( this.hasAttribute( 'a-float' ) ) { | |
return parseFloat( this.getAttribute( 'a-float' ) ); | |
} | |
return null; | |
} | |
set aFloat( value ) { | |
if( value !== null ) { | |
this.setAttribute( 'a-float', value ); | |
} else { | |
this.removeAttribute( 'a-float' ); | |
} | |
} | |
get anInteger() { | |
if( this.hasAttribute( 'an-integer' ) ) { | |
return parseInt( this.getAttribute( 'an-integer' ) ); | |
} | |
return null; | |
} | |
set anInteger( value ) { | |
if( value !== null ) { | |
this.setAttribute( 'an-integer', value ); | |
} else { | |
this.removeAttribute( 'an-integer' ); | |
} | |
} | |
get aString() { | |
if( this.hasAttribute( 'a-string' ) ) { | |
return this.getAttribute( 'a-string' ); | |
} | |
return null; | |
} | |
set aString( value ) { | |
if( value !== null ) { | |
this.setAttribute( 'a-string', value ); | |
} else { | |
this.removeAttribute( 'a-string' ); | |
} | |
} | |
} | |
window.customElements.define( 'krh-template', HoytTemplate ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment