| Index: js/io-toggle.js |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/js/io-toggle.js |
| @@ -0,0 +1,85 @@ |
| +/* globals module, require */ |
| + |
| +"use strict"; |
| + |
| +const IOElement = require("./io-element"); |
| + |
| +class IOToggle extends IOElement |
| +{ |
| + // action, checked, and disabled should be reflected down the button |
| + static get observedAttributes() |
| + { |
| + return ["action", "checked", "disabled"]; |
| + } |
| + |
| + created() |
| + { |
| + this.addEventListener("click", this); |
| + this.render(); |
| + } |
| + |
| + get checked() |
| + { |
| + return this.hasAttribute("checked"); |
| + } |
| + |
| + set checked(value) |
| + { |
| + booleanAttribute.call(this, "checked", value); |
| + this.render(); |
| + } |
| + |
| + get disabled() |
| + { |
| + return this.hasAttribute("disabled"); |
| + } |
| + |
| + set disabled(value) |
| + { |
| + booleanAttribute.call(this, "disabled", value); |
| + this.firstElementChild.disabled = this._disabled; |
| + } |
| + |
| + onclick(event) |
| + { |
| + if (!this.disabled) |
| + { |
| + this.checked = !this.checked; |
| + this.dispatchEvent(new CustomEvent("change", { |
| + bubbles: true, |
| + cancelable: true, |
| + detail: this.checked |
| + })); |
| + } |
| + } |
| + |
| + render() |
| + { |
| + this.html` |
| + <button |
| + role="checkbox" |
| + data-action="${this.action}" |
| + aria-checked="${this.checked}" |
| + aria-disabled="${this.disabled}" |
| + />`; |
| + } |
| +} |
| + |
| +IOToggle.define("io-toggle"); |
| + |
| +function asBoolean(value) |
| +{ |
| + return typeof value === "string" ? JSON.parse(value) : !!value; |
| +} |
| + |
| +function booleanAttribute(name, value) |
| +{ |
| + if (asBoolean(value)) |
| + { |
| + this.setAttribute(name, "true"); |
| + } |
| + else |
| + { |
| + this.removeAttribute(name); |
| + } |
| +} |