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); |
+ } |
+} |