145 lines
3.8 KiB
JavaScript
145 lines
3.8 KiB
JavaScript
|
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////// 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);
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////// Public Methods //////////////////////////////
|
||
|
|
||
|
// The check box is checked
|
||
|
get checked() { return this.element.getAttribute("aria-checked")=="true"; }
|
||
|
set checked(checked) {
|
||
|
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;
|
||
|
this.checked = checked;
|
||
|
this.element.dispatchEvent(new Event("input"));
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export { register };
|