Files
rio/frontend/code/components/checkbox.ts
2024-10-04 15:04:57 +02:00

84 lines
2.8 KiB
TypeScript

import { applyIcon } from "../designApplication";
import { ComponentBase, ComponentState } from "./componentBase";
export type CheckboxState = ComponentState & {
_type_: "Checkbox-builtin";
is_on?: boolean;
is_sensitive?: boolean;
};
export class CheckboxComponent extends ComponentBase {
declare state: Required<CheckboxState>;
private checkboxElement: HTMLInputElement;
private borderElement: HTMLElement;
private checkElement: HTMLElement;
createElement(): HTMLElement {
let element = document.createElement("div");
element.classList.add("rio-checkbox");
// Use an actual checkbox input for semantics. This helps e.g. screen
// readers to understand the element.
this.checkboxElement = document.createElement("input");
this.checkboxElement.type = "checkbox";
element.appendChild(this.checkboxElement);
// This will display a border around the checkbox at all times
this.borderElement = document.createElement("div");
this.borderElement.classList.add("rio-checkbox-border");
element.appendChild(this.borderElement);
// This will display a check mark when the checkbox is on
this.checkElement = document.createElement("div");
this.checkElement.classList.add("rio-checkbox-check");
element.appendChild(this.checkElement);
// Initialize the icons
applyIcon(
this.checkElement,
"material/check_small",
"var(--rio-local-bg)"
);
// Listen for changes to the checkbox state
this.checkboxElement.addEventListener("change", () => {
this.setStateAndNotifyBackend({
is_on: this.checkboxElement.checked,
});
});
return element;
}
updateElement(
deltaState: CheckboxState,
latentComponents: Set<ComponentBase>
): void {
super.updateElement(deltaState, latentComponents);
if (deltaState.is_on !== undefined) {
if (deltaState.is_on) {
this.element.classList.add("is-on");
} else {
this.element.classList.remove("is-on");
}
// Assign the new value to the checkbox element, but only if it
// differs from the current value, to avoid immediately triggering
// the event again.
if (this.checkboxElement.checked !== deltaState.is_on) {
this.checkboxElement.checked = deltaState.is_on;
}
}
if (deltaState.is_sensitive === true) {
this.element.classList.remove("rio-disabled-input");
this.checkboxElement.disabled = false;
} else if (deltaState.is_sensitive === false) {
this.element.classList.add("rio-disabled-input");
this.checkboxElement.disabled = true;
}
}
}