@servoy/jw-bootstrap-switch-ng2
Version:
Bootstrap Switch for Angular 18+
527 lines (521 loc) • 20.7 kB
JavaScript
import * as i0 from '@angular/core';
import { forwardRef, EventEmitter, Input, HostListener, ViewChild, Output, Component, NgModule } from '@angular/core';
import * as i2 from '@angular/forms';
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
const callback = () => {
};
const CUSTOM_INPUT = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => JwBootstrapSwitchNg2Component),
multi: true
};
class JwBootstrapSwitchNg2Component {
$on() {
return this.on.nativeElement;
}
$off() {
return this.off.nativeElement;
}
$label() {
return this.label.nativeElement;
}
$container() {
return this.container.nativeElement;
}
/**
* @description: Function to set the Classes for the Wrapper Div
* @returns string
*/
getWrapperClasses() {
let output = this.baseClass + ' ' + this.baseClass + '-' + this._wrapperClass;
if (this._focused) {
output += ' ' + this.baseClass + '-focused';
}
if (this.readonly) {
output += ' ' + this.baseClass + '-readonly';
}
if (this._size != null) {
output += ' ' + this.baseClass + '-' + this._size;
}
if (this._innerState) {
output += ' ' + this.baseClass + '-on';
}
else {
output += ' ' + this.baseClass + '-off';
}
if (this._animate) {
output += ' ' + this.baseClass + '-animate';
}
if (this.disabled) {
output += ' ' + this.baseClass + '-disabled';
}
if (this._indeterminate || this._innerState === null || typeof this._innerState === 'undefined') {
output += ' ' + this.baseClass + '-indeterminate';
}
if (this.inverse) {
output += ' ' + this.baseClass + '-inverse';
}
return output;
}
/**
* @description Function to set the css classes for #on
* @returns string
*/
getOnClasses() {
let output = this.baseClass + '-handle-on';
if (this._onColor) {
output += ' ' + this.baseClass + '-' + this._onColor;
}
return output;
}
/**
* @description Function to set the css classes for #off
* @returns string
*/
getOffClasses() {
let output = this.baseClass + '-handle-off';
if (this._offColor) {
output += ' ' + this.baseClass + '-' + this._offColor;
}
return output;
}
/**
* @description Function set the marging of the #label when change the state
* @returns string
*/
getLabelMarginLeft() {
let width = (this.inverse) ? -this.handleWidth : 0;
if (this._indeterminate || this._innerState === null || typeof this._innerState === 'undefined') {
width = -(this.handleWidth / 2);
}
else if (this._dragEnd) {
width = this._dragEnd;
}
else if (!this._innerState) {
if (!this.inverse) {
width = -this.handleWidth;
}
else {
width = 0;
}
}
return width + 'px';
}
constructor(cd, render) {
this.cd = cd;
this.render = render;
// Defining Default Options for Switch
this.handleWidth = 0;
this.labelWidth = 0;
this.labelText = '';
this.inverse = false;
this.baseClass = 'bootstrap-switch';
this.onText = 'ON';
this.offText = 'OFF';
this.disabled = false;
this.readonly = false;
this._focused = false;
this._size = 'normal';
this._animate = true;
this._innerAnimate = true;
this._indeterminate = false;
this._onColor = 'primary';
this._offColor = 'default';
this._wrapperClass = 'wrapper';
this._innerState = false;
this._innerHandleWidth = 'auto';
this._innerLabelWidth = 'auto';
this._dragStart = null;
this._dragEnd = null;
this._onTouchedCallback = callback;
this._onChangeCallback = callback;
this.changeState = new EventEmitter();
}
ngOnChanges(changes) {
if (changes['setLabelText'] ||
changes['setOnText'] ||
changes['setHandleWidth'] ||
changes['setLabelWidth'] ||
changes['setOffText'] ||
changes['setSize']) {
this.calculateWith(true);
}
}
ngAfterViewInit() {
this.calculateWith();
}
onClick() {
if (!this.disabled && !this.readonly && !this._dragEnd) {
this.setStateValue(!this._innerState);
}
else if (this._dragEnd) {
this._dragEnd = null;
}
}
onKeyDown(e) {
if (!e.which || this.disabled || this.readonly) {
return;
}
switch (e.which) {
case 37:
e.preventDefault();
e.stopImmediatePropagation();
this.setStateValue(false);
break;
case 39:
e.preventDefault();
e.stopImmediatePropagation();
this.setStateValue(true);
break;
}
}
onDragStart(e) {
if (e.target === this.$label()) {
if (this._dragStart || this.disabled || this.readonly) {
return;
}
e.preventDefault();
e.stopPropagation();
this._dragStart = (e.pageX || e.touches[0].pageX) - parseInt(this.$container().style.marginLeft, 10);
if (this._animate) {
this._animate = !this._animate;
}
}
}
onDragMove(e) {
if (this._dragStart) {
e.preventDefault();
const difference = (e.pageX || e.touches[0].pageX) - this._dragStart;
if (difference < -Number(this.handleWidth) || difference > 0) {
return;
}
this._dragEnd = difference;
}
}
onDragEnd(e, removeDragEnd = false) {
if (this._dragStart) {
e.preventDefault();
e.stopPropagation();
if (this._dragEnd) {
const state = this._dragEnd > -(Number(this.handleWidth) / 2);
this.setStateValue((this.inverse) ? !state : state);
}
this._dragStart = null;
if (removeDragEnd) {
this._dragEnd = null;
}
if (this._innerAnimate) {
this._animate = true;
}
}
}
onTouchStart(e) {
this.onDragStart(e);
}
onMouseDown(e) {
this.onDragStart(e);
}
onTouchMove(e) {
this.onDragMove(e);
}
onMouseMove(e) {
this.onDragMove(e);
}
onMouseUp(e) {
this.onDragEnd(e);
}
onTouchEnd(e) {
this.onDragEnd(e, true);
}
onMouseLeave(e) {
this.onDragEnd(e, true);
}
onFocus() {
this._focused = true;
}
onBlur() {
this._focused = false;
this._onTouchedCallback();
}
/**
* @description Function to make recalculate the size of the elements when options change
* @param disableAnimation
*/
calculateWith(disableAnimation = false) {
if (disableAnimation && this._innerAnimate) {
this._animate = false;
}
setTimeout(() => {
this.render.setStyle(this.$on(), 'width', 'auto');
this.render.setStyle(this.$off(), 'width', 'auto');
this.render.setStyle(this.$label(), 'width', 'auto');
const width = (this._innerHandleWidth === 'auto')
? Math.max(this.$on().offsetWidth, this.$off().offsetWidth)
: this._innerHandleWidth;
if (this.$label().offsetWidth < width) {
if (this._innerLabelWidth === 'auto') {
this.labelWidth = Number(width);
}
else {
this.labelWidth = Number(this._innerLabelWidth);
}
}
else {
if (this._innerLabelWidth === 'auto') {
this.labelWidth = this.$label().offsetWidth;
}
else {
this.labelWidth = Number(this._innerLabelWidth);
}
}
this.handleWidth = Number(width);
this.render.setStyle(this.$label(), 'width', this.labelWidth + 'px');
this.render.setStyle(this.$on(), 'width', this.handleWidth + 'px');
this.render.setStyle(this.$off(), 'width', this.handleWidth + 'px');
setTimeout(() => {
if (disableAnimation && this._innerAnimate) {
this._animate = true;
}
});
this.cd.markForCheck();
});
}
// Functions to set inputs and the private variables of the Switch
set setBaseClass(value) {
this.baseClass = value;
}
set setWrapperClass(value) {
this._wrapperClass = value;
}
set setOffText(value) {
this.offText = (value) ? value : 'OFF';
}
set setLabelText(value) {
this.labelText = value;
}
set setOnText(value) {
this.onText = (value) ? value : 'ON';
}
set setSize(value) {
if (value) {
this._size = value;
}
}
set setAnimate(value) {
this._animate = value;
this._innerAnimate = value;
}
set setOnColor(value) {
if (value) {
this._onColor = value;
}
}
set setOffColor(value) {
if (value) {
this._offColor = value;
}
}
set setDisabled(value) {
this.disabled = value;
}
set setReadOnly(value) {
this.readonly = value;
}
set setIndeterminate(value) {
this._indeterminate = value;
}
set setInverse(value) {
this.inverse = value;
}
set setHandleWidth(value) {
this._innerHandleWidth = (typeof (value) !== 'undefined') ? value : 'auto';
}
set setLabelWidth(value) {
this._innerLabelWidth = (typeof (value) !== 'undefined') ? value : 'auto';
}
get value() {
return this._innerState;
}
set value(v) {
if (v === null || typeof v === 'undefined') {
this._indeterminate = true;
}
this.setStateValue(v);
}
setStateValue(v) {
if (v !== this._innerState) {
this._onChangeCallback(v);
this.changeState.emit({
previousValue: this._innerState,
currentValue: v
});
this._innerState = v;
}
}
writeValue(value) {
if (value !== this._innerState) {
this._innerState = value;
this.cd.markForCheck();
}
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
registerOnChange(fn) {
this._onChangeCallback = fn;
}
registerOnTouched(fn) {
this._onTouchedCallback = fn;
}
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: JwBootstrapSwitchNg2Component, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: JwBootstrapSwitchNg2Component, isStandalone: false, selector: "bSwitch", inputs: { setBaseClass: ["switch-base-class", "setBaseClass"], setWrapperClass: ["switch-wrapper-class", "setWrapperClass"], setOffText: ["switch-off-text", "setOffText"], setLabelText: ["switch-label-text", "setLabelText"], setOnText: ["switch-on-text", "setOnText"], setSize: ["switch-size", "setSize"], setAnimate: ["switch-animate", "setAnimate"], setOnColor: ["switch-on-color", "setOnColor"], setOffColor: ["switch-off-color", "setOffColor"], setDisabled: ["switch-disabled", "setDisabled"], setReadOnly: ["switch-readonly", "setReadOnly"], setIndeterminate: ["switch-indeterminate", "setIndeterminate"], setInverse: ["switch-inverse", "setInverse"], setHandleWidth: ["switch-handle-width", "setHandleWidth"], setLabelWidth: ["switch-label-width", "setLabelWidth"] }, outputs: { changeState: "changeState" }, host: { listeners: { "click": "onClick()", "keydown": "onKeyDown($event)", "touchstart": "onTouchStart($event)", "mousedown": "onMouseDown($event)", "touchmove": "onTouchMove($event)", "mousemove": "onMouseMove($event)", "mouseup": "onMouseUp($event)", "touchend": "onTouchEnd($event)", "mouseleave": "onMouseLeave($event)" } }, providers: [CUSTOM_INPUT], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }, { propertyName: "on", first: true, predicate: ["on"], descendants: true }, { propertyName: "label", first: true, predicate: ["label"], descendants: true }, { propertyName: "off", first: true, predicate: ["off"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
<div [ngClass]="getWrapperClasses()" [style.width]="(handleWidth + labelWidth ) +'px'">
<div #container [ngClass]="baseClass + '-container'"
[style.width]="((handleWidth * 2) + labelWidth) +'px'"
[style.margin-left]="getLabelMarginLeft()"><!--
--><span #on [innerHTML]="(inverse) ? offText : onText"
[ngClass]="(inverse) ? getOffClasses() : getOnClasses()"></span><!--
--><span #label [ngClass]="baseClass + '-label'"> {{ labelText }}</span><!--
--><span #off [innerHTML]="(inverse) ? onText : offText"
[ngClass]="(inverse) ? getOnClasses() : getOffClasses()"></span><!--
--><input type="checkbox" [(ngModel)]="value" [readonly]="readonly" [disabled]="disabled"
(focus)="onFocus()" (blur)="onBlur()">
</div>
</div>`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: JwBootstrapSwitchNg2Component, decorators: [{
type: Component,
args: [{
selector: 'bSwitch',
providers: [CUSTOM_INPUT],
template: `
<div [ngClass]="getWrapperClasses()" [style.width]="(handleWidth + labelWidth ) +'px'">
<div #container [ngClass]="baseClass + '-container'"
[style.width]="((handleWidth * 2) + labelWidth) +'px'"
[style.margin-left]="getLabelMarginLeft()"><!--
--><span #on [innerHTML]="(inverse) ? offText : onText"
[ngClass]="(inverse) ? getOffClasses() : getOnClasses()"></span><!--
--><span #label [ngClass]="baseClass + '-label'"> {{ labelText }}</span><!--
--><span #off [innerHTML]="(inverse) ? onText : offText"
[ngClass]="(inverse) ? getOnClasses() : getOffClasses()"></span><!--
--><input type="checkbox" [(ngModel)]="value" [readonly]="readonly" [disabled]="disabled"
(focus)="onFocus()" (blur)="onBlur()">
</div>
</div>`,
standalone: false
}]
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }], propDecorators: { changeState: [{
type: Output
}], container: [{
type: ViewChild,
args: ['container']
}], on: [{
type: ViewChild,
args: ['on']
}], label: [{
type: ViewChild,
args: ['label']
}], off: [{
type: ViewChild,
args: ['off']
}], onClick: [{
type: HostListener,
args: ['click']
}], onKeyDown: [{
type: HostListener,
args: ['keydown', ['$event']]
}], onTouchStart: [{
type: HostListener,
args: ['touchstart', ['$event']]
}], onMouseDown: [{
type: HostListener,
args: ['mousedown', ['$event']]
}], onTouchMove: [{
type: HostListener,
args: ['touchmove', ['$event']]
}], onMouseMove: [{
type: HostListener,
args: ['mousemove', ['$event']]
}], onMouseUp: [{
type: HostListener,
args: ['mouseup', ['$event']]
}], onTouchEnd: [{
type: HostListener,
args: ['touchend', ['$event']]
}], onMouseLeave: [{
type: HostListener,
args: ['mouseleave', ['$event']]
}], setBaseClass: [{
type: Input,
args: ['switch-base-class']
}], setWrapperClass: [{
type: Input,
args: ['switch-wrapper-class']
}], setOffText: [{
type: Input,
args: ['switch-off-text']
}], setLabelText: [{
type: Input,
args: ['switch-label-text']
}], setOnText: [{
type: Input,
args: ['switch-on-text']
}], setSize: [{
type: Input,
args: ['switch-size']
}], setAnimate: [{
type: Input,
args: ['switch-animate']
}], setOnColor: [{
type: Input,
args: ['switch-on-color']
}], setOffColor: [{
type: Input,
args: ['switch-off-color']
}], setDisabled: [{
type: Input,
args: ['switch-disabled']
}], setReadOnly: [{
type: Input,
args: ['switch-readonly']
}], setIndeterminate: [{
type: Input,
args: ['switch-indeterminate']
}], setInverse: [{
type: Input,
args: ['switch-inverse']
}], setHandleWidth: [{
type: Input,
args: ['switch-handle-width']
}], setLabelWidth: [{
type: Input,
args: ['switch-label-width']
}] } });
class JwBootstrapSwitchNg2Module {
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: JwBootstrapSwitchNg2Module, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.3", ngImport: i0, type: JwBootstrapSwitchNg2Module, declarations: [JwBootstrapSwitchNg2Component], imports: [CommonModule,
FormsModule], exports: [JwBootstrapSwitchNg2Component] }); }
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: JwBootstrapSwitchNg2Module, imports: [CommonModule,
FormsModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: JwBootstrapSwitchNg2Module, decorators: [{
type: NgModule,
args: [{
imports: [
CommonModule,
FormsModule
],
declarations: [JwBootstrapSwitchNg2Component],
exports: [JwBootstrapSwitchNg2Component]
}]
}] });
/*
* Public API Surface of jw-bootstrap-switch-ng2
*/
/**
* Generated bundle index. Do not edit.
*/
export { JwBootstrapSwitchNg2Component, JwBootstrapSwitchNg2Module };
//# sourceMappingURL=servoy-jw-bootstrap-switch-ng2.mjs.map