Examples

Autonomous Switch Component

To offer a simple toggle switch, mirroring the same attributes as other form controls. Using attributes such as value, disabled to offer a drop in control for configuring something off or on. Bootstraped from a bootstrap file, by importing into a bigger application or direct as html script (ensure you build fallback for IE support).

<my-switch></my-switch>

MySwitch Usage <my-switch>


<!-- 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-switch.mjs"></script>
<script nomodule src="./your/path/my-switch.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-4">
				<my-switch></my-switch>
			</div>
			<div class="col-sm-4">
				<my-switch value="1"></my-switch>
			</div>
			<div class="col-sm-4">
				<my-switch value="1" disabled></my-switch>
			</div>
		</div>
	</div>
</div>

...

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

MySwitch Class my-switch.mjs


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

/**
* @public @name MySwitch
* @extends CustomHTMLElement
* @description Library web component putting a sliding switch on teh screen
*/
class MySwitch 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.value;
	}

	/**
	* @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;
				}

				.control-switch {
					display: block;
					width: inherit;
					height: inherit;
					text-align: var(--my-switch--text-align, left);
				}

				.control-switch [invisible] {
					opacity: 0;
				}

				.control-switch label {
					display: block;
					height: 20px;
					font-size: 14px;
					flex: 1 1;
					text-align: var(--my-switch--label--text-align, left);
					color: var(--my-switch--label--color, #111);
					font-weight: var(--my-switch--label--font-weight, normal);
				}

				.control-switch .switch-box {
					display: inline-block;
					position: relative;
					margin: 1px;
					width: 80px;
					height: 30px;
					border-radius: var(--my-switch--border-radius, 0px);
					border: var(--my-switch--border, 1px solid black);
					box-sizing: border-box;
				}

				.control-switch .switch-box .switch-blob {
					display: block;
					position: absolute;
					left: 1px;
					top: 1px;
					height: 26px;
					width: 36px;
					color: var(--my-switch--color, white);
					background: var(--my-switch--background, #222);
					border-radius: var(--my-switch--border-radius, 0px);
					text-align: center;
					font-size: 12px;
					line-height: 26px;
					cursor: default;
					transition: left 0.1s ease-in-out;
				}

				.control-switch .switch-box .switch-blob[on] {
					left: 41px;
				}

				:host(:hover) .control-switch .switch-box .switch-blob {
					background: var(--my-switch--background--hover, black);
				}

				:host([justify="center"]) .control-switch {
					text-align: center;
				}

				:host([justify="right"]) .control-switch {
					text-align: right;
				}

				:host([disabled]) .control-switch .switch-box {
					pointer-events: none;
					cursor: not-allowed;
					opacity: var(--my-switch--disabled--opacity, 0.6);
				}
			</style>

			<div class="control-switch">
				<label ?invisible="${!this.hasAttribute('label')}">${this.getAttribute('label')}</label>
				<div class="switch-box" @click="${this._changeEvent.bind(this)}">
					<div class="switch-blob" ?on="${this.value}">${this.value ? 'ON' : 'OFF'}</div>
				</div>
			</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) { this.updateTemplate() }

	/**
	* @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) { this.updateTemplate() }

	/**
	* @public @name constructed
	* @description Lifecycle hook that gets called when the element is finished contructing, perfect for setting up
	properties
	*/
	constructed() { this.value = this.hasAttribute('value') ? true : this.value }

	/**
	* @private @name _event
	* @description Detect an event, update a property and dispatch an event
	* @param {Event} ev Any event that kicks the function
	*/
	_changeEvent(ev) {
	if (this.hasAttribute('disabled')) return;

		this.value = !this.value;
		this.dispatchEvent(new CustomEvent('change', { detail: this.value }));
	}
}

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