@tarienna/ng-tri-state-checkbox
Version:
A TriStateCheckbox for Angular 9
280 lines (272 loc) • 10.8 kB
JavaScript
import { __decorate } from 'tslib';
import { Renderer2, Input, ViewChild, Component, forwardRef, ViewEncapsulation, ElementRef, HostListener, Directive, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR, CheckboxControlValueAccessor, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
var TriStateCheckboxState;
(function (TriStateCheckboxState) {
TriStateCheckboxState["NONE"] = "NONE";
TriStateCheckboxState["SOME"] = "SOME";
TriStateCheckboxState["ALL"] = "ALL";
})(TriStateCheckboxState || (TriStateCheckboxState = {}));
var NgTriStateCheckboxComponent_1;
let NgTriStateCheckboxComponent = NgTriStateCheckboxComponent_1 = class NgTriStateCheckboxComponent {
constructor(renderer) {
this.renderer = renderer;
this.checkboxClass = 'tri-state-checkbox-default';
this._isDisabled = false;
this.controls = new Map();
this.currentState = TriStateCheckboxState.NONE;
this.onChanged = (_) => { };
this.onTouched = () => { };
}
ngOnDestroy() {
this.controls.clear();
}
registerOnChange(fn) {
if (typeof fn === 'function') {
this.onChanged = fn;
}
else {
this.onChanged = (_) => { };
}
}
registerOnTouched(fn) {
if (typeof fn === 'function') {
this.onTouched = fn;
}
else {
this.onTouched = () => { };
}
}
setDisabledState(isDisabled) {
this._isDisabled = isDisabled;
for (const currentControl of this.controls.keys()) {
currentControl.setDisabled(isDisabled);
}
}
get isDisabled() {
return this._isDisabled;
}
addControl(control) {
if (!!control) {
this.controls.set(control, control.readValue());
this.refreshState();
setTimeout(() => {
this.emitValueChanged();
});
}
}
removeControl(control) {
this.controls.delete(control);
this.refreshState();
setTimeout(() => {
this.emitValueChanged();
});
}
changeControlValue(control, value) {
this.controls.set(control, value);
this.refreshState();
this.emitValueChanged();
}
refreshState() {
this.currentState = this.getState();
this.refreshCheckboxState();
}
getState() {
let anyWasFalse = false;
let result = TriStateCheckboxState.NONE;
for (const currentValue of this.controls.values()) {
if (!!currentValue) {
result = TriStateCheckboxState.SOME;
}
if (!currentValue) {
anyWasFalse = true;
}
}
if (!anyWasFalse && result === TriStateCheckboxState.SOME) {
result = TriStateCheckboxState.ALL;
}
return result;
}
onClick() {
const currentState = this.getState();
if (currentState === TriStateCheckboxState.SOME || currentState === TriStateCheckboxState.ALL) {
// gets unselected
this.writeAllControlValues(false);
this.currentState = TriStateCheckboxState.NONE;
}
else if (currentState === TriStateCheckboxState.NONE) {
this.writeAllControlValues(true);
this.currentState = TriStateCheckboxState.ALL;
}
this.refreshCheckboxState();
this.emitValueChanged();
}
writeAllControlValues(nValue) {
for (const currentControl of this.controls.keys()) {
if (currentControl) {
currentControl.writeValue(nValue);
}
}
}
refreshCheckboxState() {
if (this.customCheckbox && this.customCheckbox.nativeElement) {
let checked = false;
let indeterminate = false;
if (this.currentState === TriStateCheckboxState.ALL) {
checked = true;
indeterminate = false;
}
else if (this.currentState === TriStateCheckboxState.SOME) {
checked = true;
indeterminate = true;
}
this.renderer.setProperty(this.customCheckbox.nativeElement, 'checked', checked);
// Browser Support for indeterminate: https://caniuse.com/#search=indeterminate
this.customCheckbox.nativeElement.indeterminate = indeterminate;
}
}
emitValueChanged() {
const values = [];
for (const value of this.controls.values()) {
if (!!value) {
values.push(value);
}
}
this.onChanged(values);
this.onTouched();
}
reset() {
this.writeAllControlValues(false);
this.refreshState();
this.emitValueChanged();
}
writeValue(obj) {
if (!!obj && obj.hasOwnProperty('length') && obj.length > 0) {
console.warn('It\'s currently not possible to set values. Maybe later there is a solution to do that.');
}
}
};
NgTriStateCheckboxComponent.ctorParameters = () => [
{ type: Renderer2 }
];
__decorate([
Input()
], NgTriStateCheckboxComponent.prototype, "checkboxClass", void 0);
__decorate([
ViewChild('customCheckbox', { static: false })
], NgTriStateCheckboxComponent.prototype, "customCheckbox", void 0);
NgTriStateCheckboxComponent = NgTriStateCheckboxComponent_1 = __decorate([
Component({
selector: 'ng-tri-state-checkbox',
template: "<input type=\"checkbox\" [class]=\"checkboxClass\" (change)=\"onClick()\" #customCheckbox [disabled]=\"isDisabled\">\n",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgTriStateCheckboxComponent_1),
multi: true
}
],
exportAs: 'ngTriStateCheckbox',
encapsulation: ViewEncapsulation.None,
styles: [".tri-state-checkbox-default{height:1rem;width:1rem;display:block;position:relative;pointer-events:auto;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-image:none;border:1px solid #adb5bd;border-radius:.15rem;box-sizing:border-box}.tri-state-checkbox-default:checked:not(:indeterminate){background-color:#0099da;color:#fff}.tri-state-checkbox-default:checked:not(:indeterminate):after{content:\"\";display:block;position:absolute;top:-1px;left:-1px;width:1rem;height:1rem;pointer-events:none;color:#fff;background-color:#0099da;background-repeat:no-repeat;background-size:50% 50%;background-position:50%;background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e\");border:1px solid #0099da;border-radius:.15rem}.tri-state-checkbox-default:indeterminate{background-color:#fff;color:#adb5bd;border-color:#0099da}.tri-state-checkbox-default:indeterminate:after{content:\"\";display:block;position:absolute;top:calc(.225rem - 1px);left:calc(.225rem - 1px);width:.55rem;height:.55rem;pointer-events:none;background-color:#0099da;border:1px solid #0099da;border-radius:.15rem}"]
})
], NgTriStateCheckboxComponent);
var NgTriStateControlDirective_1;
let NgTriStateControlDirective = NgTriStateControlDirective_1 = class NgTriStateControlDirective extends CheckboxControlValueAccessor {
constructor(renderer, elementRef) {
super(renderer, elementRef);
this.renderer = renderer;
this.elementRef = elementRef;
this.checkedValue = null;
this.isDisabled = false;
}
ngOnInit() {
if (!!this.registry) {
this.registry.addControl(this);
}
}
ngOnDestroy() {
if (!!this.registry) {
this.registry.removeControl(this);
}
}
ngOnChanges(changes) {
if (changes && changes.hasOwnProperty('registry') && !changes.registry.firstChange) {
const registerChanged = changes.registry;
if (!!registerChanged.previousValue) {
registerChanged.previousValue.removeControl(this);
}
if (!!registerChanged.currentValue) {
registerChanged.currentValue.addControl(this);
}
}
}
readValue() {
if (this.checkedValue) {
return !!this.value ? this.value : this.checkedValue;
}
return null;
}
writeValue(value) {
super.writeValue(value);
this.checkedValue = value;
this.updateValueOnRegistry();
}
setDisabled(state) {
this.isDisabled = state;
super.setDisabledState(state);
}
updateValueOnRegistry() {
if (!!this.registry) {
this.registry.changeControlValue(this, this.readValue());
}
}
onChangeValue(value) {
this.checkedValue = value;
this.updateValueOnRegistry();
}
};
NgTriStateControlDirective.ctorParameters = () => [
{ type: Renderer2 },
{ type: ElementRef }
];
__decorate([
Input()
], NgTriStateControlDirective.prototype, "value", void 0);
__decorate([
Input('ngTriStateControl')
], NgTriStateControlDirective.prototype, "registry", void 0);
__decorate([
HostListener('change', ['$event.target.checked'])
], NgTriStateControlDirective.prototype, "onChangeValue", null);
NgTriStateControlDirective = NgTriStateControlDirective_1 = __decorate([
Directive({
selector: 'input[type=checkbox][ngTriStateControl]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgTriStateControlDirective_1),
multi: true
}
],
exportAs: 'ngTriStateControl'
})
], NgTriStateControlDirective);
let NgTriStateCheckboxModule = class NgTriStateCheckboxModule {
};
NgTriStateCheckboxModule = __decorate([
NgModule({
declarations: [NgTriStateCheckboxComponent, NgTriStateControlDirective],
imports: [CommonModule, FormsModule, ReactiveFormsModule],
exports: [NgTriStateCheckboxComponent, NgTriStateControlDirective]
})
], NgTriStateCheckboxModule);
/*
* Public API Surface of ng-tri-state-checkbox
*/
/**
* Generated bundle index. Do not edit.
*/
export { NgTriStateCheckboxComponent, NgTriStateCheckboxModule, NgTriStateControlDirective };
//# sourceMappingURL=tarienna-ng-tri-state-checkbox.js.map