UNPKG

@engie-group/fluid-design-system-angular

Version:

Fluid Design System Angular

224 lines (193 loc) 4.86 kB
import {CommonModule} from '@angular/common'; import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; @Component({ selector: 'nj-toggle', templateUrl: './toggle.component.html', styleUrls: ['./toggle.component.scss'], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ToggleComponent), multi: true }], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, standalone: true, imports: [CommonModule] }) export class ToggleComponent implements ControlValueAccessor, AfterViewInit { /** * @ignore */ private toggleClassName = 'nj-toggle'; /** * @ignore */ private _checked: boolean; /** * Input id */ @Input() inputId: string; /** * Input name */ @Input() name: string; /** * Input size */ @Input() size: 'md' | 'lg' = 'md'; /** * Whether input is required or not */ @Input() required: boolean; /** * Whether the toggle is checked or not */ @Input() set isChecked(value: boolean) { this._checked = value; this.cdr.markForCheck(); } get isChecked(): boolean { return this._checked; } /** * Whether the toggle is disabled or not */ @Input() isDisabled: boolean; /** * Whether the toggle color is inherited from parent */ @Input() isColorInherited?: boolean; /** * Text alternative for assistive technologies * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label */ @Input() ariaLabel: string; /** * Text alternative for assistive technologies based on visible text * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-labelledby */ @Input() ariaLabelledby: string; /** * Output that emits checked value on change only */ @Output() valueChange: EventEmitter<boolean> = new EventEmitter<boolean>(); /** * @ignore */ @ViewChild('input') private _inputElement: ElementRef<HTMLInputElement>; /** * @ignore */ @ViewChild('iconWrapper') iconWrapper; /** * Whether toggle has an icon */ hasIcon: boolean; constructor(private cdr: ChangeDetectorRef) { } // Check if icon is provided on load ngAfterViewInit() { this.hasIcon = this.iconWrapper?.nativeElement && this.iconWrapper.nativeElement.innerHTML !== ''; } /** * @ignore */ private _onChange = (_: any): void => { }; /** * @ignore */ private _onTouched = (): void => { }; /** * @ignore */ _onChangeEvent(event: Event) { event.stopPropagation(); if (this._inputElement?.nativeElement) { this.isChecked = this._inputElement.nativeElement.checked; this._onChange(this.isChecked); this.valueChange.emit(this.isChecked); } } /** * @ignore */ _onInputClick(event: Event) { // We have to stop propagation for click events on the visually hidden input element. // By default, when a user clicks on a label element, a generated click event will be // dispatched on the associated input element. Since we are using a label element as our // root container, the click event on the `slide-toggle` will be executed twice. // The real click event will bubble up, and the generated click event also tries to bubble up. // This will lead to multiple click events. // Preventing bubbling for the second event will solve that issue. event.stopPropagation(); } /** * Implemented as part of ControlValueAccessor. * @ignore */ writeValue(value: any): void { this.isChecked = !!value; } /** * Implemented as part of ControlValueAccessor. * @ignore */ registerOnChange(fn: any): void { this._onChange = fn; } /** * Implemented as part of ControlValueAccessor. * @ignore */ registerOnTouched(fn: any): void { this._onTouched = fn; } /** * Implemented as part of ControlValueAccessor. * @ignore */ setDisabledState(isDisabled: boolean): void { this.isDisabled = isDisabled; this.cdr.markForCheck(); } /** * @ignore */ getToggleSizeClass(): string { let sizeModifier: string; switch (this.size) { case 'lg': sizeModifier = 'lg'; break; default: break; } return sizeModifier ? `${this.toggleClassName}--${sizeModifier}` : ''; } /** * @ignore */ getToggleIsDisabledClass(): string { return this.isDisabled ? `${this.toggleClassName}--disabled` : ''; } getToggleInheritColorClass(): string { return this.isColorInherited ? `${this.toggleClassName}--inherit` : ''; } }