ng-toggle-button
Version:
Angular toggle button switch
351 lines (344 loc) • 17.9 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, EventEmitter, forwardRef, Output, Input, Component, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import * as i2 from '@angular/common';
import { CommonModule } from '@angular/common';
class NgToggleConfig {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgToggleConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgToggleConfig, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgToggleConfig, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}] });
const DEFAULT_COLOR_CHECKED = '#0099CC';
const DEFAULT_COLOR_UNCHECKED = '#e0e0e0';
const DEFAULT_LABEL_CHECKED = '';
const DEFAULT_LABEL_UNCHECKED = '';
const DEFAULT_SWITCH_COLOR = '#fff';
const DISABLED_COLOR = '#dbdbdb';
const DISABLED_BUTTON_COLOR = 'silver';
let nextUniqueId = 0;
class NgToggleComponent {
constructor(config, _elementRef) {
this.config = config;
this._elementRef = _elementRef;
this.value = this.config.value || true;
this.name = this.config.name || '';
this.disabled = this.config.disabled || false;
this.height = this.config.height || 25;
this.width = this.config.width || 45;
this.margin = this.config.margin || 2;
this.fontSize = this.config.fontSize || undefined;
this.speed = this.config.speed || 300;
this.color = this.config.color;
this.switchColor = this.config.switchColor;
this.labels = this.config.labels || true;
this.fontColor = this.config.fontColor || undefined;
this.values = this.config.values || { checked: true, unchecked: false };
this.textAlign = this.config.textAlign || {
checked: 'left',
unchecked: 'right',
};
this.id = '';
this.ariaLabel = null;
this.ariaLabelledby = null;
this.cssColors = false;
this.change = new EventEmitter();
this.valueChange = new EventEmitter();
this.onChange = (_) => { };
this.onTouch = () => { };
this._uniqueId = 'ng-toggle-' + (++nextUniqueId);
this.id = this.id || this._uniqueId;
this.ariaLabel = this.ariaLabel || this.name || this.id;
}
ngOnInit() {
this.setToogle();
}
onInput(value) {
this.value = value;
this.onTouch();
this.onChange(this.value);
}
writeValue(value) {
this.value = value;
this.setToogle();
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouch = fn;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
setToogle() {
const value = this.value;
let index = Object.values(this.values).findIndex(el => el == value);
if (index > -1)
this.toggled = Object.keys(this.values)[index] == 'checked' ? true : false;
}
ngOnChanges(changes) {
for (const propName in changes) {
const chng = changes[propName];
if (propName == 'value')
this.writeValue(chng.currentValue);
}
}
get coreStyle() {
return {
width: px(this.width),
height: px(this.height),
transition: `all ${this.speed}ms`,
backgroundColor: this.cssColors
? null
: (this.disabled ? this.colorDisabled : this.colorCurrent),
borderRadius: px(Math.round(this.height / 2))
};
}
get buttonRadius() {
const radius = this.height - this.margin * 2;
return radius > 0 ? radius : 0;
}
get distance() {
return px(this.width - this.height + this.margin);
}
get buttonStyle() {
const transition = `all ${this.speed}ms`;
const margin = px(this.margin);
const transform = this.toggled
? translate(this.distance, margin)
: translate(margin, margin);
let background = this.switchColor
? this.switchColorCurrent
: null;
background = this.disabled ? this.switchColorDisabled : background;
return {
width: px(this.buttonRadius),
height: px(this.buttonRadius),
transition,
transform,
background,
};
}
get labelStyle() {
return {
lineHeight: px(this.height),
fontSize: this.fontSize ? px(this.fontSize) : null,
color: this.fontColor ? this.fontColorCurrent : null,
width: px(this.width - this.buttonRadius - this.margin),
};
}
get labelLeftStyle() {
return {
...this.labelStyle,
textAlign: this.textAlign.checked || this.textAlign
};
}
get labelRightStyle() {
return {
...this.labelStyle,
textAlign: this.textAlign.unchecked || this.textAlign
};
}
get colorChecked() {
let { color } = this;
if (!isObject(color)) {
return color || DEFAULT_COLOR_CHECKED;
}
return get(color, 'checked', DEFAULT_COLOR_CHECKED);
}
get colorUnchecked() {
return get(this.color, 'unchecked', DEFAULT_COLOR_UNCHECKED);
}
get colorDisabled() {
return get(this.color, 'disabled', DISABLED_COLOR);
}
get colorCurrent() {
return this.toggled
? this.colorChecked
: this.colorUnchecked;
}
get labelChecked() {
return get(this.labels, 'checked', DEFAULT_LABEL_CHECKED);
}
get labelUnchecked() {
return get(this.labels, 'unchecked', DEFAULT_LABEL_UNCHECKED);
}
get switchColorChecked() {
return get(this.switchColor, 'checked', DEFAULT_SWITCH_COLOR);
}
get switchColorUnchecked() {
return get(this.switchColor, 'unchecked', DEFAULT_SWITCH_COLOR);
}
get switchColorDisabled() {
return get(this.switchColor, 'disabled', DISABLED_BUTTON_COLOR);
}
get switchColorCurrent() {
if (!isObject(this.switchColor)) {
return this.switchColor || DEFAULT_SWITCH_COLOR;
}
return this.toggled
? this.switchColorChecked
: this.switchColorUnchecked;
}
get fontColorChecked() {
return get(this.fontColor, 'checked', DEFAULT_SWITCH_COLOR);
}
get fontColorUnchecked() {
return get(this.fontColor, 'unchecked', DEFAULT_SWITCH_COLOR);
}
get fontColorDisabled() {
return get(this.fontColor, 'disabled', DEFAULT_SWITCH_COLOR);
}
get fontColorCurrent() {
if (!isObject(this.fontColor)) {
return this.fontColor || DEFAULT_SWITCH_COLOR;
}
if (this.disabled) {
return this.fontColorDisabled;
}
return this.toggled
? this.fontColorChecked
: this.fontColorUnchecked;
}
get label() {
if (this.ariaLabelledby) {
return this.ariaLabelledby;
}
return this.ariaLabel ? null : `${this._uniqueId}-label`;
}
toggle(event) {
const toggled = !this.toggled;
this.toggled = toggled;
this.value = this.getValue(toggled);
this.onTouch();
this.onChange(this.value);
this.valueChange.emit(this.value);
}
getValue(key) {
return key === true ? this.values['checked'] : this.values['unchecked'];
}
onFocus(event) {
if (!this.focused && event.relatedTarget) {
this.focused = true;
}
}
onFocusout(event) {
if (!this._elementRef.nativeElement.contains(event.relatedTarget)) {
this.focused = false;
this.onTouch();
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgToggleComponent, deps: [{ token: NgToggleConfig }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: NgToggleComponent, isStandalone: true, selector: "ng-toggle", inputs: { value: "value", name: "name", disabled: "disabled", height: "height", width: "width", margin: "margin", fontSize: "fontSize", speed: "speed", color: "color", switchColor: "switchColor", labels: "labels", fontColor: "fontColor", values: "values", textAlign: "textAlign", id: "id", ariaLabel: ["aria-label", "ariaLabel"], ariaLabelledby: ["aria-labelledby", "ariaLabelledby"], ariaDescribedby: ["aria-describedby", "ariaDescribedby"] }, outputs: { change: "change", valueChange: "valueChange" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgToggleComponent),
multi: true
}
], usesOnChanges: true, ngImport: i0, template: "<label class=\"ng-toggle-switch\" [for]=\"id\" [attr.id]=\"label\">\n <input\n type=\"checkbox\"\n class=\"ng-toggle-switch-input\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n (change)=\"toggle($event)\"\n (focusin)=\"onFocus($event)\"\n (focusout)=\"onFocusout($event)\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"label\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-checked]=\"toggled\"\n role=\"checkbox\"\n >\n <div\n class=\"ng-toggle-switch-core\"\n [ngClass]=\"{'ng-toggle-focused': focused}\"\n [ngStyle]=\"coreStyle\"\n >\n <div\n class=\"ng-toggle-switch-button\"\n [ngStyle]=\"buttonStyle\">\n </div>\n </div>\n <ng-container *ngIf=\"labels\">\n <span\n class=\"ng-toggle-switch-label ng-toggle-left\"\n [ngStyle]=\"labelLeftStyle\"\n *ngIf=\"toggled\"\n >\n {{labelChecked}}\n </span>\n <span\n class=\"ng-toggle-switch-label ng-toggle-right\"\n [ngStyle]=\"labelRightStyle\"\n *ngIf=\"!toggled\"\n >\n {{labelUnchecked}}\n </span>\n </ng-container>\n</label>", styles: ["label{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}.ng-toggle-switch{display:inline-block;position:relative;vertical-align:middle;-webkit-user-select:none;user-select:none;font-size:10px;cursor:pointer}.ng-toggle-switch .ng-toggle-switch-input{opacity:0;position:absolute;width:1px;height:1px}.ng-toggle-switch .ng-toggle-switch-label{position:absolute;top:0;font-weight:600;color:#fff;z-index:1;padding:0 10px;box-sizing:border-box}.ng-toggle-switch .ng-toggle-switch-label.ng-toggle-left{left:0}.ng-toggle-switch .ng-toggle-switch-label.ng-toggle-right{right:0}.ng-toggle-switch .ng-toggle-switch-core{display:block;position:relative;box-sizing:border-box;outline:0;margin:0;transition:border-color .3s,background-color .3s;-webkit-user-select:none;user-select:none}.ng-toggle-switch .ng-toggle-switch-core .ng-toggle-switch-button{display:block;position:absolute;overflow:hidden;top:0;left:0;border-radius:100%;background-color:#fff;z-index:2}.ng-toggle-switch.disabled{pointer-events:none;opacity:.6}.ng-toggle-focused{box-shadow:0 0 4px 3px #999}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgToggleComponent, decorators: [{
type: Component,
args: [{ selector: 'ng-toggle', standalone: true, imports: [CommonModule], providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgToggleComponent),
multi: true
}
], template: "<label class=\"ng-toggle-switch\" [for]=\"id\" [attr.id]=\"label\">\n <input\n type=\"checkbox\"\n class=\"ng-toggle-switch-input\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n (change)=\"toggle($event)\"\n (focusin)=\"onFocus($event)\"\n (focusout)=\"onFocusout($event)\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"label\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-checked]=\"toggled\"\n role=\"checkbox\"\n >\n <div\n class=\"ng-toggle-switch-core\"\n [ngClass]=\"{'ng-toggle-focused': focused}\"\n [ngStyle]=\"coreStyle\"\n >\n <div\n class=\"ng-toggle-switch-button\"\n [ngStyle]=\"buttonStyle\">\n </div>\n </div>\n <ng-container *ngIf=\"labels\">\n <span\n class=\"ng-toggle-switch-label ng-toggle-left\"\n [ngStyle]=\"labelLeftStyle\"\n *ngIf=\"toggled\"\n >\n {{labelChecked}}\n </span>\n <span\n class=\"ng-toggle-switch-label ng-toggle-right\"\n [ngStyle]=\"labelRightStyle\"\n *ngIf=\"!toggled\"\n >\n {{labelUnchecked}}\n </span>\n </ng-container>\n</label>", styles: ["label{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}.ng-toggle-switch{display:inline-block;position:relative;vertical-align:middle;-webkit-user-select:none;user-select:none;font-size:10px;cursor:pointer}.ng-toggle-switch .ng-toggle-switch-input{opacity:0;position:absolute;width:1px;height:1px}.ng-toggle-switch .ng-toggle-switch-label{position:absolute;top:0;font-weight:600;color:#fff;z-index:1;padding:0 10px;box-sizing:border-box}.ng-toggle-switch .ng-toggle-switch-label.ng-toggle-left{left:0}.ng-toggle-switch .ng-toggle-switch-label.ng-toggle-right{right:0}.ng-toggle-switch .ng-toggle-switch-core{display:block;position:relative;box-sizing:border-box;outline:0;margin:0;transition:border-color .3s,background-color .3s;-webkit-user-select:none;user-select:none}.ng-toggle-switch .ng-toggle-switch-core .ng-toggle-switch-button{display:block;position:absolute;overflow:hidden;top:0;left:0;border-radius:100%;background-color:#fff;z-index:2}.ng-toggle-switch.disabled{pointer-events:none;opacity:.6}.ng-toggle-focused{box-shadow:0 0 4px 3px #999}\n"] }]
}], ctorParameters: () => [{ type: NgToggleConfig }, { type: i0.ElementRef }], propDecorators: { value: [{
type: Input
}], name: [{
type: Input
}], disabled: [{
type: Input
}], height: [{
type: Input
}], width: [{
type: Input
}], margin: [{
type: Input
}], fontSize: [{
type: Input
}], speed: [{
type: Input
}], color: [{
type: Input
}], switchColor: [{
type: Input
}], labels: [{
type: Input
}], fontColor: [{
type: Input
}], values: [{
type: Input
}], textAlign: [{
type: Input
}], id: [{
type: Input
}], ariaLabel: [{
type: Input,
args: ['aria-label']
}], ariaLabelledby: [{
type: Input,
args: ['aria-labelledby']
}], ariaDescribedby: [{
type: Input,
args: ['aria-describedby']
}], change: [{
type: Output
}], valueChange: [{
type: Output
}] } });
const isObject = (value) => {
return typeof value === 'object';
};
const has = (object, key) => {
return isObject(object) && object.hasOwnProperty(key);
};
const get = (object, key, defaultValue) => {
return has(object, key) ? object[key] : defaultValue;
};
const px = value => {
return `${value}px`;
};
const translate = (x, y) => {
return `translate(${x}, ${y})`;
};
class NgToggleModule {
static forRoot(config = {}) {
return {
ngModule: NgToggleModule,
providers: [
{
provide: NgToggleConfig,
useValue: config
}
]
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgToggleModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: NgToggleModule, imports: [NgToggleComponent], exports: [NgToggleComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgToggleModule, providers: [NgToggleConfig], imports: [NgToggleComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgToggleModule, decorators: [{
type: NgModule,
args: [{
imports: [NgToggleComponent],
exports: [NgToggleComponent],
providers: [NgToggleConfig]
}]
}] });
/*
* Public API Surface of ng-toogle
*/
/**
* Generated bundle index. Do not edit.
*/
export { NgToggleComponent, NgToggleConfig, NgToggleModule, get, has, isObject, px, translate };
//# sourceMappingURL=ng-toggle-button.mjs.map