diff --git a/alfa-client/libs/design-system/src/lib/button/button.component.spec.ts b/alfa-client/libs/design-system/src/lib/button/button.component.spec.ts index f9b51e92773381274fced66dc61d1af73171d2a8..75f8afba23a4ceced80e25438d6df2ef66730d09 100644 --- a/alfa-client/libs/design-system/src/lib/button/button.component.spec.ts +++ b/alfa-client/libs/design-system/src/lib/button/button.component.spec.ts @@ -54,7 +54,7 @@ describe('ButtonComponent', () => { expect(component.clickEmitter.emit).toHaveBeenCalled(); }); - it('should NOT emit click', () => { + it('should NOT emit click if button is disabled', () => { component.disabled = true; fixture.detectChanges(); diff --git a/alfa-client/libs/design-system/src/lib/button/button.component.ts b/alfa-client/libs/design-system/src/lib/button/button.component.ts index 7d0f0f35b9420a4dafad53b07f79586ceceb9cfc..a513012d4ce3b249df6abb552c21c2163067092e 100644 --- a/alfa-client/libs/design-system/src/lib/button/button.component.ts +++ b/alfa-client/libs/design-system/src/lib/button/button.component.ts @@ -31,18 +31,18 @@ import { SpinnerIconComponent } from '../icons/spinner-icon/spinner-icon.compone 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', + 'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 outline-focus', ], { variants: { variant: { - primary: 'bg-primary text-whitetext shadow-md hover:enabled:bg-primary-hover focus-visible:bg-primary-hover', + primary: 'bg-primary text-whitetext shadow-md hover:bg-primary-hover focus-visible:bg-primary-hover', outline: - 'border border-primary bg-background-50 text-primary shadow-md hover:enabled:bg-ghost-hover focus-visible:bg-ghost-hover focus-visible:border-background-200', + 'border border-primary bg-background-50 text-primary shadow-md hover:bg-ghost-hover focus-visible:bg-ghost-hover focus-visible:border-background-200', outline_error: - 'border border-error bg-background-50 text-error shadow-md hover:enabled:bg-ghost-hover focus-visible:bg-ghost-hover focus-visible:border-background-200', + '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:enabled:bg-ghost-hover text-primary focus-visible:border-background-200 focus-visible:bg-ghost-hover font-semibold [&]:focus-visible:outline-offset-1', + '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', }, size: { medium: 'h-9 py-2 px-4 min-w-32', @@ -50,11 +50,11 @@ export const buttonVariants = cva( }, disabled: { false: null, - true: ['opacity-70', 'cursor-not-allowed'], + true: '[&]:outline-disabled-button cursor-not-allowed', }, destructive: { - false: 'outline-focus', - true: 'outline-destructive', + false: null, + true: '[&]:outline-destructive', }, }, defaultVariants: { @@ -66,19 +66,34 @@ export const buttonVariants = cva( { variant: 'primary', destructive: true, - class: - '[&]:hover:enabled:bg-destructive-primary-hover [&]:bg-destructive [&]:outline-destructive [&]:focus-visible:bg-destructive-primary-hover', + class: '[&]:hover:bg-destructive-primary-hover [&]:bg-destructive [&]:focus-visible:bg-destructive-primary-hover', }, { variant: 'outline', destructive: true, class: - '[&]:border-destructive [&]:text-destructive [&]:hover:enabled:bg-destructive-hover [&]:focus-visible:bg-destructive-hover', + '[&]:border-destructive [&]:text-destructive [&]:hover:bg-destructive-hover [&]:focus-visible:bg-destructive-hover', }, { variant: 'ghost', destructive: true, - class: '[&]:text-destructive [&]:hover:enabled:bg-destructive-hover [&]:focus-visible:bg-destructive-hover', + 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', }, ], }, @@ -89,7 +104,7 @@ export type ButtonVariants = VariantProps<typeof buttonVariants>; selector: 'ods-button', standalone: true, imports: [CommonModule, SpinnerIconComponent], - template: ` <button + template: `<button type="button" [ngClass]="buttonVariants({ size, variant, disabled: isDisabled, destructive })" [attr.aria-disabled]="isDisabled" @@ -98,17 +113,22 @@ export type ButtonVariants = VariantProps<typeof buttonVariants>; [attr.data-test-class]="dataTestClass" (click)="onClick()" > - <ng-content *ngIf="!isLoading" select="[icon]"></ng-content> - <ods-spinner-icon *ngIf="isLoading" [size]="spinnerSize" data-test-class="spinner"></ods-spinner-icon> - <div *ngIf="text" class="flex-grow">{{ text }}</div> + @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> + } </button>`, }) export class ButtonComponent { @Input() text: string = ''; @Input() dataTestId: string = ''; @Input() dataTestClass: string = ''; - @Input() disabled: boolean = false; - @Input() isLoading: boolean = false; + @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']; diff --git a/alfa-client/libs/design-system/src/lib/icons/spinner-icon/spinner-icon.component.ts b/alfa-client/libs/design-system/src/lib/icons/spinner-icon/spinner-icon.component.ts index d361292b08e026c2f05e245276dae53b82fa2805..20ca2f1c2affe64e1a2aab8b81576c2c40a68e3e 100644 --- a/alfa-client/libs/design-system/src/lib/icons/spinner-icon/spinner-icon.component.ts +++ b/alfa-client/libs/design-system/src/lib/icons/spinner-icon/spinner-icon.component.ts @@ -24,6 +24,7 @@ import { NgClass } from '@angular/common'; import { Component, Input } from '@angular/core'; +import { twMerge } from 'tailwind-merge'; import { IconVariants, iconVariants } from '../iconVariants'; @Component({ @@ -33,8 +34,7 @@ import { IconVariants, iconVariants } from '../iconVariants'; template: ` <svg xmlns="http://www.w3.org/2000/svg" - [ngClass]="iconVariants({ size })" - class="animate-spin fill-primary text-gray-200 dark:text-gray-600" + [ngClass]="twMerge('animate-spin fill-primary text-gray-200 dark:text-gray-600', iconVariants({ size }), class)" aria-hidden="true" viewBox="0 0 100 100" fill="none" @@ -53,6 +53,8 @@ import { IconVariants, iconVariants } from '../iconVariants'; }) export class SpinnerIconComponent { @Input() size: IconVariants['size'] = 'full'; + @Input() class: string; - iconVariants = iconVariants; + readonly iconVariants = iconVariants; + readonly twMerge = twMerge; } diff --git a/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css b/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css index a3c8f7b01b5e1b8342761bf3190841ef059b5cc8..333257d60e54034a148f8f864ae42132d1a7643e 100644 --- a/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css +++ b/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css @@ -18,6 +18,7 @@ --color-disabled: 206 14% 95%; --color-disabled-dark: 208 12% 65%; + --color-disabled-button: 0 0% 42%; --color-destructive: 360, 71%, 49%, 1; --color-destructive-hover: 360, 71%, 49%, 0.07; @@ -59,6 +60,7 @@ --color-disabled: 206 14% 15%; --color-disabled-dark: 208 12% 33%; + --color-disabled-button: 0 0% 68%; --color-destructive: 360, 71%, 49%, 1; --color-destructive-hover: 360, 71%, 49%, 0.2; diff --git a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js index cf2abfcb2f32821bcb410f4d9bcd817f2aa2efb0..9c5ba7a4e53f673e8ac6c1b27e08f63936647d7f 100644 --- a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js +++ b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js @@ -146,6 +146,7 @@ module.exports = { focus: 'hsl(var(--color-focus))', disabled: { dark: 'hsl(var(--color-disabled-dark) / <alpha-value>)', + button: 'hsl(var(--color-disabled-button) / <alpha-value>)', DEFAULT: 'hsl(var(--color-disabled) / <alpha-value>)', }, destructive: 'hsla(var(--color-destructive))', diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.html index d0dd3c9c055bfc74030ddd0a0c19ddacafa8976b..4196535914833b542fdf6b2f9323ac8af647414e 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.html +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.html @@ -1,3 +1,9 @@ -<ods-button-with-spinner [disabled]="disabled" text="Weiterleiten" variant="outline" dataTestId="forwarding-button"> - <ods-forward-vorgang-icon icon class="fill-primary" /> -</ods-button-with-spinner> \ No newline at end of file +<ods-button-with-spinner + [disabled]="disabled" + text="Weiterleiten" + [tooltip]="tooltip" + tooltipPosition="above" + dataTestId="forwarding-button" +> + <ods-forward-vorgang-icon icon class="fill-whitetext" /> +</ods-button-with-spinner> diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.spec.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.spec.ts index ec3ee8288b888a029f6de545b97636ec3c5aae5d..9a3db6373c7684f12cddad89ba28689a306b1ee5 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.spec.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.spec.ts @@ -23,4 +23,20 @@ describe('ForwardingButtonComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + describe('component', () => { + describe('set disabled', () => { + it('should set tooltip text', () => { + component.disabled = true; + + expect(component.tooltip).not.toBe(''); + }); + + it('should set empty tooltip', () => { + component.disabled = false; + + expect(component.tooltip).toBe(''); + }); + }); + }); }); diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.ts b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.ts index 63fec70d17fb549ab13163155fe3ca596446209a..05e20b8b4d98e7c1b1988a5920c2d8d446a621de 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.ts +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-button/forwarding-button.component.ts @@ -1,13 +1,23 @@ import { Component, Input } from '@angular/core'; import { ButtonWithSpinnerComponent } from '@ods/component'; -import { ForwardVorgangIconComponent } from '@ods/system'; +import { ForwardVorgangIconComponent, TooltipDirective } from '@ods/system'; @Component({ selector: 'alfa-forwarding-button', standalone: true, - imports: [ButtonWithSpinnerComponent, ForwardVorgangIconComponent], + imports: [ButtonWithSpinnerComponent, ForwardVorgangIconComponent, TooltipDirective], templateUrl: './forwarding-button.component.html', }) export class ForwardingButtonComponent { - @Input() disabled: boolean; + @Input() set disabled(value: boolean) { + this._disabled = value; + this.tooltip = value ? 'Bitte ein Amt oder Stelle auswählen' : ''; + } + + public tooltip: string; + private _disabled: boolean; + + get disabled() { + return this._disabled; + } } diff --git a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.html b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.html index 3d60550c444dcbc34d9f229e91c1133e6a5af9ac..f557b1c6c740deee4c324f20d66c2e9172b85b19 100644 --- a/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.html +++ b/alfa-client/libs/forwarding/src/lib/forwarding-dialog-container/forwarding-dialog/forwarding-dialog.component.html @@ -1,20 +1,18 @@ -<div class="flex w-[620px] max-w-full flex-col gap-4 bg-background-100 p-8"> - <div class="flex items-center justify-between" > +<div class="flex w-[860px] max-w-full flex-col gap-4 bg-background-100 p-8"> + <div class="flex items-center justify-between"> <h1 class="text-xl font-semibold text-primary">Vorgang weiterleiten</h1> <ods-cancel-dialog-button showAsIconButton="true" /> </div> @if (!selectedSearchResult) { <alfa-search-zustaendige-stelle-form-container cdkFocusInitial focusOnSearchField="true" data-test-id="zufi-search" /> + <div class="h-[calc(50vh)]"></div> } @else { - <alfa-forwarding-item-in-dialog - [organisationsEinheitResource]="selectedSearchResult" - data-test-id="forwarding-item" - /> + <alfa-forwarding-item-in-dialog [organisationsEinheitResource]="selectedSearchResult" data-test-id="forwarding-item" /> } <div class="flex gap-4"> - <alfa-forwarding-button [disabled]="!selectedSearchResult"/> + <alfa-forwarding-button [disabled]="!selectedSearchResult" /> <ods-cancel-dialog-button /> </div> </div>