UNPKG

@decidables/decidables-elements

Version:

decidables-elements: Basic UI Web Components for the decidables project

181 lines (135 loc) 4.25 kB
import {css, html} from 'lit'; import DecidablesElement from './decidables-element'; export default class DecidablesSwitch extends DecidablesElement { static get properties() { return { checked: { attribute: 'checked', type: Boolean, reflect: true, }, disabled: { attribute: 'disabled', type: Boolean, reflect: true, }, }; } constructor() { super(); // Attributes this.checked = false; this.disabled = false; } changed(event) { this.checked = event.target.checked; this.dispatchEvent(new CustomEvent('change', { detail: { checked: this.checked, }, bubbles: true, })); } static get styles() { return [ super.styles, css` :host { display: flex; flex-direction: column; align-items: center; justify-content: center; } /* Adapted from https://codepen.io/guuslieben/pen/YyPRVP */ input[type=checkbox] { /* visuallyhidden: https://github.com/h5bp/html5-boilerplate/blob/master/dist/doc/css.md */ position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; white-space: nowrap; border: 0; clip-path: inset(100%); /* May cause a performance issue: https://github.com/h5bp/html5-boilerplate/issues/2021 */ } input[type=checkbox] + label { order: 1; margin: 0 0.25rem 0.25rem; font-weight: 400; } input[type=checkbox] + label + label { position: relative; min-width: 24px; padding: 0 0 36px; margin: 0.25rem 0.25rem 0; font-weight: 400; outline: none; } input[type=checkbox] + label + label::before, input[type=checkbox] + label + label::after { position: absolute; left: 50%; margin: 0; outline: 0; content: ""; transform: translate(-50%, 0); transition: all var(---transition-duration) ease; } input[type=checkbox] + label + label::before { bottom: 1px; width: 8px; height: 34px; background-color: var(---color-element-disabled); border-radius: 4px; } input[type=checkbox] + label + label::after { bottom: 0; width: 18px; height: 18px; background-color: var(---color-element-enabled); border-radius: 50%; box-shadow: var(---shadow-2); } input[type=checkbox]:checked + label + label::after { transform: translate(-50%, -100%); } input[type=checkbox]:disabled + label + label::after { background-color: var(---color-element-disabled); box-shadow: none; } input[type=checkbox]:enabled + label, input[type=checkbox]:enabled + label + label { cursor: pointer; } input[type=checkbox]:enabled + label:hover + label::after, input[type=checkbox]:enabled + label + label:hover::after { box-shadow: var(---shadow-4); } input[type=checkbox]:enabled + label:active + label::after, input[type=checkbox]:enabled + label + label:active::after { box-shadow: var(---shadow-8); } input[type=checkbox]:enabled:focus-visible + label + label::after { box-shadow: var(---shadow-4); } input[type=checkbox]:enabled:focus-visible + label + label:active::after, input[type=checkbox]:enabled:focus-visible:active + label + label::after { box-shadow: var(---shadow-8); } `, ]; } render() { return html` <input type="checkbox" id="switch" ?checked=${this.checked} ?disabled=${this.disabled} @change=${this.changed.bind(this)}> <label for="switch"> <slot name="off-label"></slot> </label> <label for="switch"> <slot></slot> </label> `; } } customElements.define('decidables-switch', DecidablesSwitch);