Skip to content
Snippets Groups Projects
button.component.ts 5.28 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
     * Ministerpräsidenten des Landes Schleswig-Holstein
     * Staatskanzlei
     * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
     *
     * Lizenziert unter der EUPL, Version 1.2 oder - sobald
     * diese von der Europäischen Kommission genehmigt wurden -
     * Folgeversionen der EUPL ("Lizenz");
     * Sie dürfen dieses Werk ausschließlich gemäß
     * dieser Lizenz nutzen.
     * Eine Kopie der Lizenz finden Sie hier:
     *
     * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
     *
     * Sofern nicht durch anwendbare Rechtsvorschriften
     * gefordert oder in schriftlicher Form vereinbart, wird
     * die unter der Lizenz verbreitete Software "so wie sie
     * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
     * ausdrücklich oder stillschweigend - verbreitet.
     * Die sprachspezifischen Genehmigungen und Beschränkungen
     * unter der Lizenz sind dem Lizenztext zu entnehmen.
     */
    
    import { CommonModule } from '@angular/common';
    
    import { booleanAttribute, Component, EventEmitter, Input, Output } from '@angular/core';
    import { cva, VariantProps } from 'class-variance-authority';
    
    import { IconVariants } from '../icons/iconVariants';
    
    import { SpinnerIconComponent } from '../icons/spinner-icon/spinner-icon.component';
    
    
    export const buttonVariants = cva(
    
        'flex items-center gap-3 rounded-lg text-sm font-medium box-border',
    
        'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 outline-focus',
    
          variant: {
    
            primary: 'bg-primary text-whitetext shadow-md hover:bg-primary-hover focus-visible:bg-primary-hover',
    
              'border border-primary bg-background-50 text-primary shadow-md hover:bg-ghost-hover focus-visible:bg-ghost-hover focus-visible:border-background-200',
    
    Albert Bruns's avatar
    Albert Bruns committed
            outline_error:
    
              'border border-error bg-background-50 text-error shadow-md hover:bg-ghost-hover focus-visible:bg-ghost-hover focus-visible:border-background-200',
    
            ghost:
    
              'border border-transparent hover:bg-ghost-hover text-primary focus-visible:border-background-200 focus-visible:bg-ghost-hover font-semibold [&]:focus-visible:outline-offset-1',
    
            medium: 'h-9 py-2 px-4 min-w-32',
    
            fit: 'h-fit p-2',
    
          disabled: {
            false: null,
    
            true: '[&]:outline-disabled-button cursor-not-allowed',
    
          destructive: {
    
            false: null,
            true: '[&]:outline-destructive',
    
        },
        defaultVariants: {
    
          variant: 'primary',
    
          size: 'medium',
    
          disabled: false,
    
        compoundVariants: [
          {
            variant: 'primary',
            destructive: true,
    
            class: '[&]:hover:bg-destructive-primary-hover [&]:bg-destructive [&]:focus-visible:bg-destructive-primary-hover',
    
          },
          {
            variant: 'outline',
            destructive: true,
    
              '[&]:border-destructive [&]:text-destructive [&]:hover:bg-destructive-hover [&]:focus-visible:bg-destructive-hover',
    
          },
          {
            variant: 'ghost',
            destructive: true,
    
            class: '[&]:text-destructive [&]:hover:bg-destructive-hover [&]:focus-visible:bg-destructive-hover',
          },
          {
            variant: 'primary',
            disabled: true,
            class: '[&]:bg-disabled-button [&]:hover:bg-disabled-button/90 [&]:focus-visible:bg-disabled-button/90',
          },
          {
            variant: 'outline',
            disabled: true,
            class:
              '[&]:text-disabled-button [&]:border-disabled-button [&]:hover:bg-disabled-button/10 [&]:focus-visible:bg-disabled-button/10',
          },
          {
            variant: 'ghost',
            disabled: true,
            class: '[&]:text-disabled-button [&]:hover:bg-disabled-button/10 [&]:focus-visible:bg-disabled-button/10',
    
    export type ButtonVariants = VariantProps<typeof buttonVariants>;
    
    
    @Component({
      selector: 'ods-button',
      standalone: true,
    
      imports: [CommonModule, SpinnerIconComponent],
    
      template: ` <button
        type="submit"
    
        [ngClass]="buttonVariants({ size, variant, disabled: isDisabled, destructive })"
    
        [attr.aria-disabled]="isDisabled"
    
        [attr.aria-label]="text"
    
    OZGCloud's avatar
    OZGCloud committed
        [attr.data-test-id]="dataTestId"
    
        [attr.data-test-class]="dataTestClass"
    
        (click)="onClick()"
    
        @if (isLoading) {
          <ods-spinner-icon [class]="isDisabled && 'fill-disabled-button'" [size]="spinnerSize" data-test-class="spinner" />
        } @else {
          <ng-content select="[icon]" />
        }
        @if (text) {
          <p class="flex-grow">{{ text }}</p>
        }
    
    })
    export class ButtonComponent {
      @Input() text: string = '';
    
      @Input() dataTestId: string = '';
    
      @Input() dataTestClass: string = '';
    
      @Input({ transform: booleanAttribute }) disabled: boolean = false;
      @Input({ transform: booleanAttribute }) isLoading: boolean = false;
    
      @Input({ transform: booleanAttribute }) destructive: boolean = false;
    
      @Input() variant: ButtonVariants['variant'];
      @Input() size: ButtonVariants['size'];
    
      @Input() spinnerSize: IconVariants['size'] = 'medium';
    
    
      @Output() public clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
    
    
      get isDisabled() {
        return this.disabled || this.isLoading;
      }
    
    
    Albert Bruns's avatar
    Albert Bruns committed
      public onClick(): void {
    
        if (!this.isDisabled) {
          this.clickEmitter.emit();
        }
      }
    
    
      readonly buttonVariants = buttonVariants;