Skip to content
Snippets Groups Projects
button.component.ts 4.05 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-4 rounded-lg text-sm font-medium box-border',
    
        'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2',
    
          variant: {
    
    Oliver Schmidt's avatar
    Oliver Schmidt committed
            primary: 'bg-primary text-whitetext shadow-md hover:enabled:bg-primary-hover',
    
              'border border-primary bg-background-50 text-primary shadow-md hover:enabled:bg-ghost-hover focus-visible:border-background-200',
    
            ghost:
              'border-2 border-transparent hover:enabled:bg-ghost-hover text-primary focus-visible:border-background-200 font-semibold',
    
            medium: 'h-9 py-2 px-4 min-w-32',
    
            fit: 'h-fit p-2',
    
          disabled: {
            false: null,
            true: ['opacity-70', 'cursor-not-allowed'],
          },
    
          destructive: {
            false: 'outline-focus',
    
            true: 'outline-destructive',
    
        },
        defaultVariants: {
    
          variant: 'primary',
    
          size: 'medium',
    
          disabled: false,
    
        compoundVariants: [
          {
            variant: 'primary',
            destructive: true,
    
            class: '[&]:hover:enabled:bg-destructive-primary-hover [&]:bg-destructive [&]:outline-destructive',
    
          },
          {
            variant: 'outline',
            destructive: true,
    
            class: '[&]:border-destructive [&]:text-destructive [&]:hover:enabled:bg-destructive-hover',
    
          },
          {
            variant: 'ghost',
            destructive: true,
    
            class: '[&]:text-destructive [&]:hover:enabled:bg-destructive-hover',
    
      },
    );
    type ButtonVariants = VariantProps<typeof buttonVariants>;
    
    
    @Component({
      selector: 'ods-button',
      standalone: true,
    
      imports: [CommonModule, SpinnerIconComponent],
      template: `<button
        type="button"
    
        [ngClass]="buttonVariants({ size, variant, disabled, destructive })"
    
        [disabled]="isDisabled"
        [attr.aria-disabled]="isDisabled"
    
        [attr.aria-label]="text"
    
    OZGCloud's avatar
    OZGCloud committed
        [attr.data-test-id]="dataTestId"
    
        (click)="clickEmitter.emit()"
      >
        <ng-content *ngIf="!isLoading" select="[icon]"></ng-content>
    
        <ods-spinner-icon *ngIf="isLoading" [size]="spinnerSize"></ods-spinner-icon>
    
        <div *ngIf="text" class="flex-grow">{{ text }}</div>
    
    })
    export class ButtonComponent {
      @Input() text: string = '';
    
      @Input() dataTestId: string = '';
    
      @Input() disabled: boolean = false;
    
      @Input() 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;
      }
    
      readonly buttonVariants = buttonVariants;