let register = Toolkit => Toolkit.Checkbox = // Check box class Checkbox extends Toolkit.Component { ///////////////////////// Initialization Methods ////////////////////////// constructor(app, options = {}) { super(app, options = Object.assign({ class : "tk checkbox", role : "checkbox", tabIndex: "0" }, options, { style: Object.assign({ alignItems : "center", display : "inline-grid", gridTemplateColumns: "max-content auto" }, options.style || {}) })); // Configure element this.element.setAttribute("aria-checked", "false"); this.addEventListener("keydown" , e=>this.onKeyDown (e)); this.addEventListener("pointerdown", e=>this.onPointerDown(e)); this.addEventListener("pointermove", e=>this.onPointerMove(e)); this.addEventListener("pointerup" , e=>this.onPointerUp (e)); // Icon area this.box = document.createElement("div"); this.box.className = "tk box"; this.append(this.box); // Display text this.uiLabel = new Toolkit.Label(app); this.add(this.uiLabel); // Configure options this.checked = options.checked; this.disabled = !!options.disabled; this.instant = !!options.instant; } ///////////////////////////// Event Handlers ////////////////////////////// // Key press onKeyDown(e) { if ( !(e.altKey || e.ctrlKey || e.shiftKey || this.disabled) && (e.key == " " || e.key == "Enter") ) this.setChecked(!this.checked); } // Pointer down onPointerDown(e) { // Gain focus if (!this.disabled) this.element.focus(); else e.preventDefault(); // Do not drag if ( e.button != 0 || this.disabled || this.element.hasPointerCapture(e.pointerId) ) return; // Begin dragging this.element.setPointerCapture(e.pointerId); // Use instant activation if (this.instant) return this.onPointerUp(e); // Do not use instant activation this.element.classList.add("pushed"); Toolkit.handle(e); } // Pointer move onPointerMove(e) { // Do not drag if (!this.element.hasPointerCapture(e.pointerId)) return; // Process dragging this.element.classList[this.isWithin(e) ? "add" : "remove"]("pushed"); Toolkit.handle(e); } // Pointer up onPointerUp(e) { // Do not activate if (e.button != 0 || !this.element.hasPointerCapture(e.pointerId)) return; // End dragging this.element.releasePointerCapture(e.pointerId); this.element.classList.remove("pushed"); Toolkit.handle(e); // Activate the check box if applicable if (this.isWithin(e)) this.setChecked(this.checked !== true); } ///////////////////////////// Public Methods ////////////////////////////// // The check box is checked get checked() { let ret = this.element.getAttribute("aria-checked"); return ret == "mixed" ? ret : ret == "true"; } set checked(checked) { checked = checked == "mixed" ? checked : !!checked; if (checked == this.checked) return; this.element.setAttribute("aria-checked", checked); } // Specify the display text setText(text, localize) { this.uiLabel.setText(text, localize); } ///////////////////////////// Package Methods ///////////////////////////// // Update localization strings localize() { this.uiLabel.localize(); this.localizeTitle(); } ///////////////////////////// Private Methods ///////////////////////////// // Specify the checked state setChecked(checked) { checked = !!checked; if (checked == this.checked) return; let previous = this.checked this.checked = checked; this.element.dispatchEvent( Object.assign(new Event("input"), { previous: previous })); } } export { register };