mirror of
https://github.com/rio-labs/rio.git
synced 2026-01-04 20:29:55 -06:00
84 lines
2.8 KiB
TypeScript
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 {
|
|
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.add('is-sensitive');
|
|
this.checkboxElement.disabled = false;
|
|
} else if (deltaState.is_sensitive === false) {
|
|
this.element.classList.remove('is-sensitive');
|
|
this.checkboxElement.disabled = true;
|
|
}
|
|
}
|
|
}
|