Angular Toggle Button

agnusdei·2023년 7월 5일
0
post-thumbnail
post-custom-banner


<label
  class="relative flex items-center w-16 p-0.5 cursor-pointer rounded-3xl border transition-all"
  [ngClass]="
    value ? 'bg-primary-100 border-primary-300' : 'bg-gray-100 border-gray-300'
  "
>
  <input
    type="checkbox"
    class="hidden"
    [ngModel]="value"
    (change)="handleChange($event)"
    [disabled]="disabled"
  />
  <div
    class="z-0 transition-all rounded-full w-7 h-7"
    [ngClass]="
      value
        ? 'scale-105 translate-x-full bg-primary'
        : 'translate-x-0 scale-50 bg-gray-400'
    "
  >
    <lepi-icon
      *ngIf="iconName && value"
      [name]="iconName"
      [class]="iconClass"
      class="z-10 w-3 h-3 bg-white"
    />
  </div>
</label>
/* eslint-disable @typescript-eslint/no-empty-function */
import { CommonModule } from '@angular/common';
import {
  AfterViewInit,
  Component,
  Injector,
  Input,
  booleanAttribute,
  signal,
} from '@angular/core';
import {
  ControlValueAccessor,
  FormControl,
  FormsModule,
  NG_VALUE_ACCESSOR,
  NgControl,
  ReactiveFormsModule,
} from '@angular/forms';
import { IconComponent } from '../icon/icon.component';

@Component({
  selector: 'lepi-toggle',
  templateUrl: './toggle.component.html',
  styleUrls: ['./toggle.component.scss'],
  standalone: true,
  imports: [CommonModule, FormsModule, ReactiveFormsModule, IconComponent],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: ToggleComponent,
      multi: true,
    },
  ],
})
export class ToggleComponent implements AfterViewInit, ControlValueAccessor {
  @Input({ transform: booleanAttribute }) disabled = false;
  @Input() iconName?: string;
  @Input() iconClass?: string;

  _value = signal<boolean>(false);
  value = false;
  control?: FormControl;

  constructor(private readonly injector: Injector) {}

  ngAfterViewInit(): void {
    const ngControl: NgControl | null = this.injector.get(NgControl, null);
    if (ngControl) {
      this.control = ngControl.control as FormControl;
    }
  }

  onChange = (ev?: any) => {};

  onTouched = () => {};

  writeValue(obj: boolean): void {
    this.value = obj;
    this._value.set(obj);
  }

  handleChange(ev: any) {
    ev.stopPropagation();
    this.value = ev.target.checked;
    this._value.set(this.value);
    this.onChange(this.value);
    this.onTouched();
  }

  registerOnChange(fn: (value: any) => void): void {
    this.onChange = fn;
  }

  registerOnTouched = () => {};

  setDisabledState?(disabled: boolean): void {
    this.disabled = disabled;
  }
}
post-custom-banner

0개의 댓글