Examples

Autonomous My App Application

To offer a simple application to using web components inside the application, Using attributes to configure the application we can pass in run time requirements as attributes. Bootstraped from a bootstrap file, by importing into a bigger application or direct as html script (ensure you build fallback for IE support).

<my-app></my-app>

MyApp Usage <my-app>


<!-- Polyfill -->
<script src="/node_modules/promise-polyfill/dist/polyfill.min.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>

<!-- Bootstrap component only, ensure you have built fallback for IE support too (.js)! -->
<script type="module" src="./your/path/my-app.mjs"></script>
<script nomodule src="./your/path/my-app.js"></script>

<!-- Or add your switch import to a bootstrap js file/app using ES6 import and use that instead of the component directly... -->
<script type="module" src="./your/path/index.mjs"></script>
<script nomodule src="./your/path/index.js"></script>

<!-- example basic fouc resolution -->
<style>
	[fouc] { opacity: 0; transition: opacity 200ms ease-in-out; }
	[fouc="loaded"] { opacity: 1; }
</style>

...

<div class="info">
	<div class="class">
		<div class="row" fouc>
			<div class="col-sm-12">
				<my-app></my-app>
			</div>
		</div>
	</div>
</div>

...

<!-- fouc for individual components -->
<script> setTimeout(() => document.querySelector('[fouc]').setAttribute('fouc', 'loaded'), 1000); </script>
						

MyApp Class my-app.mjs


import { CustomHTMLElement, html } from '../../../node_modules/custom-web-component/index.js';

import '../Components/material-icon-general.mjs';
import '../Components/my-box-select.mjs';
import '../Components/my-switch.mjs';

/**
 * @public @name MyApp
 * @extends CustomHTMLElement
 * @description Library web component putting a sliding switch on teh screen
 */
class MyApp extends CustomHTMLElement {

	/**
     * @public @constructor @name constructor
	 * @description Triggered when component is instantiated (but not ready or in DOM, must call super() first)
	 */
	constructor() {
		super();

		this.selected = '2';
		this.switched = '';
		this.switchedValue = '';
		console.log('constructor');
	}

	/**
	 * @public @static @name template
	 * @description Template function to return web component UI
	 * @return {TemplateResult} HTML template result
	 */
	static template() {
		return html`
			<style>
			    :host {
					display: inline-block;
					width: 100%;
					height: 62px;
					box-sizing: border-box;
				}

				my-switch {
					width: auto;
					display: inline-block;
				}

				.value {
					padding: 5px;
					background: red;
					color: white;
					border-radius: 3px;
				}

				.label {
					padding: 5px;
					background: green;
					color: white;
					border-radius: 3px;
				}
			</style>

			<div class="box">
				<h1>Hello World</h1>
				<h2>This is MyApp() <my-app></my-app></h2>
				<p>Here we have a set of components being loaded into my app. Check your console (F12) and see the lifecycle hooks in action.</p>
				<p>You can use these hooks to hit API's, run login scripts and bootstrap a single page routing system if your making a full single page app that has routing.</p>
				<div class="inner-box">
					<material-icon-general name="accessibility"></material-icon-general>
					<material-icon-general name="accessible"></material-icon-general>
					<material-icon-general name="accountBalance"></material-icon-general>
					<material-icon-general name="accountBalanceWallet"></material-icon-general>
					<material-icon-general name="accountBox"></material-icon-general>
					<material-icon-general name="accountCircle"></material-icon-general>
					<material-icon-general name="add"></material-icon-general>
					<material-icon-general name="addAlert"></material-icon-general>
					<material-icon-general name="addBox"></material-icon-general>
					<material-icon-general name="addCircle"></material-icon-general>
					<material-icon-general name="addCircleOutline"></material-icon-general>
					<material-icon-general name="addShoppingCart"></material-icon-general>
					<material-icon-general name="alarm"></material-icon-general>
					<material-icon-general name="alarmAdd"></material-icon-general>
					<material-icon-general name="alarmOff"></material-icon-general>
				</div>
				<div class="inner-box">
					<my-box-select label="Hello" .value="${this.selected}" @change="${this._selected.bind(this)}">
						<option value="1">One</option>
						<option value="2">Two</option>
						<option value="3">Three</option>
						<option value="4">Four</option>
					</my-box-select>
			<p>You selected: <span class="value">${this.selected}</span></p>
				</div>
				<div class="inner-box">
					<my-switch value="1" label="Dave" @change="${this._switched.bind(this, 'Dave')}"></my-switch>
					<my-switch label="John" @change="${this._switched.bind(this, 'John')}"></my-switch>
					<my-switch value="1" label="Fred" @change="${this._switched.bind(this, 'Fred')}"></my-switch>
					<my-switch label="Bill" @change="${this._switched.bind(this, 'Bill')}"></my-switch>
					<my-switch value="1" label="Michael" @change="${this._switched.bind(this, 'Michael')}"></my-switch>
				</div>
			<p>You switched: <span class="label" ?hidden="${!this.switched}">${this.switched}</span> <span class="value" ?hidden="${!this.switched}">${this.switchedValue}</span></p>
			</div>
		`;
	}

	/**
	 * @public @static @get @name observedProperties
	 * @description Provide properties to watch for changes
	 * @return {Array} Array of property names as strings
	 */
	static get observedProperties() { return ['value'] }

	/**
	 * @public @name propertyChanged
	 * @description Callback run when a custom elements properties change
	 * @param {String} property The property name
	 * @param {Mixed} oldValue The old value
	 * @param {Mixed} newValue The new value
	 */
	propertyChanged(property, oldValue, newValue) { console.log('property changed') }

	/**
	 * @public @static @get @name observedAttributes
	 * @description Provide attributes to watch for changes
	 * @return {Array} Array of attribute names as strings
	 */
	static get observedAttributes() { return ['disabled', 'label'] }

	/**
	 * @public @name attributeChanged
	 * @description Callback run when a custom elements attributes change
	 * @param {String} attribute The attribute name
	 * @param {Mixed} oldValue The old value
	 * @param {Mixed} newValue The new value
	 */
	attributeChanged(attribute, oldValue, newValue) { console.log('attribute changed') }

	/**
	 * @public @name constructed
	 * @description Lifecycle hook that gets called when the element is finished contructing, perfect for setting up properties
	 */
	constructed() { console.log('constructed') }

	/**
	 * @public @name connected
	 * @description Lifecycle hook that gets called when the element is finished contructing, perfect for setting up properties
	 */
	connected() { console.log('connected') }

	/**
	 * @public @name disconnected
	 * @description Lifecycle hook that gets called when the element is finished contructing, perfect for setting up properties
	 */
	disconnected() { console.log('disconnected') }

	/**
	 * @public @name _selected
	 * @description Selected a value on box select
	 * @param {Event} ev The event that kicked the method
	 */
	_selected(ev) { 
		this.selected = ev.target.value;
		this.updateTemplate();
	}

	/**
	 * @public @name _switched
	 * @description Switched a value on switch
	 * @param {String} name The name sent in
	 * @param {Event} ev The event that kicked the method
	 */
	_switched(name, ev) {
		this.switched = name;
		this.switchedValue = ev.target.value;
		this.updateTemplate();
	}
}

// bootstrap the class as a new web component
customElements.define('my-app', MyApp);