UNPKG

web-ui-pack

Version:
161 lines (160 loc) 4.95 kB
import { WUPCssIconHover, WUPcssHidden } from "../styles"; import WUPBaseControl from "./baseControl"; const tagName = "wup-switch"; export default class WUPSwitchControl extends WUPBaseControl { #ctr = this.constructor; static get $styleRoot() { return `:root { --ctrl-switch-padding: 1em; --ctrl-switch-on: #fff; --ctrl-switch-off: #fff; --ctrl-switch-off-bg: #9f9f9f; --ctrl-switch-on-bg: #00778d; --ctrl-switch-shadow: #0003; --ctrl-switch-h: var(--ctrl-icon-size); --ctrl-switch-w: calc(var(--ctrl-icon-size) * 2.8); --ctrl-switch-r: calc(var(--ctrl-icon-size) * 1.4); } [wupdark] { --ctrl-switch-on: #e7e7e7; --ctrl-switch-off: #e7e7e7; --ctrl-switch-off-bg: #707070; --ctrl-switch-shadow: #000; }`; } static get $style() { return `${super.$style} :host { background: none; cursor: pointer; } :host[readonly] { cursor: initial; } :host label { display: flex; gap: 0.5em; padding: var(--ctrl-switch-padding); } :host strong { box-sizing: border-box; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-weight: normal; text-decoration: none; color: inherit; } :host [bar] { display: inline-flex; align-items: center; overflow: visible; width: var(--ctrl-switch-w); min-width: var(--ctrl-switch-w); height: var(--ctrl-switch-h); border-radius: 999px; color: whitesmoke; background: var(--ctrl-switch-off-bg); } ${WUPCssIconHover(":host", "[thumb]")} :host [thumb] { z-index: 2; display: inline-block; height: var(--ctrl-switch-r); width: var(--ctrl-switch-r); background: var(--ctrl-switch-off); box-shadow: 0 1px 4px 0 var(--ctrl-switch-shadow); border-radius: 50%; transform: translateX(-1px); } :host input { ${WUPcssHidden} } :host[checked] [bar] { background-color: var(--ctrl-switch-on-bg); } :host[checked] [thumb] { background: var(--ctrl-switch-on); transform: translateX(var(--ctrl-switch-w)) translateX(calc(-100% + 1px)); } :host[w-reverse] label { flex-direction: row-reverse; } :host[w-reverse] strong { margin-right: auto; } @media not all and (prefers-reduced-motion) { :host [bar] { transition: background-color var(--anim); } :host [thumb] { transition: transform var(--anim); } }`; } static $isEqual(v1, v2) { return !!v1 === !!v2; } static get observedAttributes() { const arr = super.observedAttributes; arr.push("defaultchecked"); return arr; } static $defaults = { ...WUPBaseControl.$defaults, validationRules: { ...WUPBaseControl.$defaults.validationRules }, reverse: false, }; get $value() { return !!super.$value; } set $value(v) { super.$value = !!v; } parse(text) { return text === "" || text === "1" || text.toLowerCase() === "true"; } valueToStorage(v) { return v ? "1" : null; } renderControl() { this.$refInput.id = this.#ctr.$uniqueId; this.$refLabel.setAttribute("for", this.$refInput.id); this.$refInput.type = "checkbox"; this.$refLabel.appendChild(this.$refInput); this.$refLabel.appendChild(this.$refTitle); const sp = document.createElement("span"); sp.setAttribute("bar", ""); sp.appendChild(document.createElement("span")).setAttribute("thumb", ""); this.$refLabel.appendChild(sp); this.appendChild(this.$refLabel); } gotReady() { super.gotReady(); this.$refInput.oninput = (e) => this.gotInput(e); } gotInput(e) { const el = e.target; if (this.$isReadOnly) { el.checked = !el.checked; } else { this.setValue(el.checked, 3); } } setValue(v, reason) { const r = super.setValue(v, reason); this.$refInput.checked = !!v; this.setAttr("checked", this.$refInput.checked, true); return r; } gotChanges(propsChanged) { super.gotChanges(propsChanged); this.setAttr("w-reverse", this._opts.reverse, true); } gotFormChanges(propsChanged) { super.gotFormChanges(propsChanged); this.setAttr.call(this.$refInput, "aria-readonly", this.$isReadOnly); } attributeChangedCallback(name, oldValue, newValue) { if (name === "defaultchecked") { name = "initvalue"; } super.attributeChangedCallback(name, oldValue, newValue); } } customElements.define(tagName, WUPSwitchControl);