UNPKG

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

Version:

Fluid Design System Angular

222 lines (189 loc) 4.91 kB
import {CommonModule} from '@angular/common'; import { booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, Output, ViewChild } from '@angular/core'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; import {IconComponent} from '../icon/icon.component'; import {CheckboxSize} from './checkbox.model'; @Component({ selector: 'nj-checkbox', templateUrl: './checkbox.component.html', styleUrls: ['./checkbox.component.scss'], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CheckboxComponent), multi: true }], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [IconComponent, CommonModule] }) export class CheckboxComponent implements ControlValueAccessor { private readonly checkboxClassName = 'nj-checkbox'; private _checked: boolean; /** * Input id */ @Input() inputId: string; /** * Input name */ @Input() name: string; /** * Whether input is required or not */ @Input() isRequired?: boolean; /** * Whether the checkbox is checked or not */ @Input() set isChecked(value: boolean) { this._checked = value; this.cdr.markForCheck(); } get isChecked(): boolean { return this._checked; } /** * Checkbox size */ @Input() size?: CheckboxSize = 'md'; /** * Input value */ @Input() value?: string; /** * Whether the checkbox is disabled or not */ @Input() isDisabled?: boolean; /** * Whether the checkbox is in error state */ @Input() hasError?: boolean; /** * Whether the checkbox is in success state */ @Input() hasSuccess?: boolean; /** * Message to display as hint below checkbox */ @Input() subscriptMessage?: string; /** * @Deprecated * Message to display if checkbox is in error state */ @Input() errorMessage?: string; /** * Aria label, for accessibility reasons */ @Input() ariaLabel?: string; /** * Aria labelled by, for accessibility reasons */ @Input() ariaLabelledby?: string; /** * Whether checkbox is only presentational and state handled by a parent, can be useful for lists of checkboxes. * When set to `true`, the checkbox won't have any interaction. */ @Input() isPresentational? = false; /** * Whether the checkbox is in indeterminate state or not. */ @Input({transform: booleanAttribute}) indeterminate: boolean; /** * Output that emits checked value on change only */ @Output() valueChange: EventEmitter<boolean> = new EventEmitter<boolean>(); @ViewChild('input') private _inputElement: ElementRef<HTMLInputElement>; constructor(private cdr: ChangeDetectorRef) { } /** * @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 */ getSubscriptId(): string { return `${this.inputId}-hint`; } private get checkboxSizeClass(): string { return this.size !== 'md' ? `${this.checkboxClassName}--${this.size}` : ''; } protected get checkboxClasses() { return { 'nj-checkbox--error': this.hasError, 'nj-checkbox--success': this.hasSuccess, [this.checkboxSizeClass]: true }; } }