Skip to content
Snippets Groups Projects
Commit 44ec07d0 authored by OZGCloud's avatar OZGCloud
Browse files

Merge pull request 'OZG-7078-a11y-button-in-alfa' (#844) from...

Merge pull request 'OZG-7078-a11y-button-in-alfa' (#844) from OZG-7078-a11y-button-in-alfa into master

Reviewed-on: https://git.ozg-sh.de/ozgcloud-app/alfa/pulls/844


Reviewed-by: default avatarOZGCloud <ozgcloud@mgm-tp.com>
Reviewed-by: default avatarOZGCloud <ozgcloud@mgm-tp.com>
parents db824ee6 fe4b8360
No related branches found
No related tags found
No related merge requests found
Showing
with 278 additions and 13 deletions
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
</ng-template> </ng-template>
</main> </main>
<section class="w-5"> <section class="w-5">
<alfa-build-info *ngIf="apiRoot" [apiRoot]="apiRoot" data-test-id="build-info" /> <common-build-info *ngIf="apiRoot" [apiRoot]="apiRoot" data-test-id="build-info" />
</section> </section>
</div> </div>
</ng-container> </ng-container>
...@@ -111,6 +111,7 @@ services: ...@@ -111,6 +111,7 @@ services:
- OZGCLOUD_VORGANG_BESCHEID_0_FORM_ENGINE_NAME=FormSolutions - OZGCLOUD_VORGANG_BESCHEID_0_FORM_ENGINE_NAME=FormSolutions
- OZGCLOUD_VORGANG_BESCHEID_0_FORM_ID=KFAS_STAGE_KI_10_Haltverbot_LANDESHACKATHON - OZGCLOUD_VORGANG_BESCHEID_0_FORM_ID=KFAS_STAGE_KI_10_Haltverbot_LANDESHACKATHON
- OZGCLOUD_FEATURE_COLLABORATION_ENABLED=true - OZGCLOUD_FEATURE_COLLABORATION_ENABLED=true
- OZGCLOUD_BARRIEREFREIHEIT_URL=http://bam.de
ports: ports:
- 8080:8080 - 8080:8080
- 5000:5000 - 5000:5000
...@@ -140,11 +141,7 @@ services: ...@@ -140,11 +141,7 @@ services:
soft: 65536 soft: 65536
hard: 65536 hard: 65536
healthcheck: healthcheck:
test: test: ['CMD-SHELL', "curl -s 'http://localhost:9200/_cat/health?h=status' | egrep -q '(green|yellow)'"]
[
'CMD-SHELL',
"curl -s 'http://localhost:9200/_cat/health?h=status' | egrep -q '(green|yellow)'",
]
interval: 10s interval: 10s
timeout: 10s timeout: 10s
retries: 5 retries: 5
......
...@@ -29,7 +29,7 @@ import { HeaderE2EComponent } from 'apps/alfa-e2e/src/page-objects/header.po'; ...@@ -29,7 +29,7 @@ import { HeaderE2EComponent } from 'apps/alfa-e2e/src/page-objects/header.po';
import { MainPage, waitForSpinnerToDisappear } from 'apps/alfa-e2e/src/page-objects/main.po'; import { MainPage, waitForSpinnerToDisappear } from 'apps/alfa-e2e/src/page-objects/main.po';
import { isKeyboardFocused, isOdsFocused } from 'apps/alfa-e2e/src/support/angular.util'; import { isKeyboardFocused, isOdsFocused } from 'apps/alfa-e2e/src/support/angular.util';
import { dropCollections, pressTab } from 'apps/alfa-e2e/src/support/cypress-helper'; import { dropCollections, pressTab } from 'apps/alfa-e2e/src/support/cypress-helper';
import { exist, haveFocus } from 'apps/alfa-e2e/src/support/cypress.util'; import { exist, haveFocus, shouldHaveAttribute } from 'apps/alfa-e2e/src/support/cypress.util';
import { initUsermanagerUsers, loginAsSabine } from 'apps/alfa-e2e/src/support/user-util'; import { initUsermanagerUsers, loginAsSabine } from 'apps/alfa-e2e/src/support/user-util';
describe('VorgangList Page', () => { describe('VorgangList Page', () => {
...@@ -42,6 +42,9 @@ describe('VorgangList Page', () => { ...@@ -42,6 +42,9 @@ describe('VorgangList Page', () => {
const navigation: NavigationE2EComponent = mainPage.getNavigation(); const navigation: NavigationE2EComponent = mainPage.getNavigation();
const accTooltip: string = 'Barrierefreiheit';
const accLink: string = 'http://bam.de';
before(() => { before(() => {
initUsermanagerUsers(); initUsermanagerUsers();
...@@ -77,6 +80,17 @@ describe('VorgangList Page', () => { ...@@ -77,6 +80,17 @@ describe('VorgangList Page', () => {
haveFocus(vorgangSearch.getInput()); haveFocus(vorgangSearch.getInput());
}); });
it('should focus accessibility icon', () => {
pressTab();
isOdsFocused(header.getAccessibilityIcon());
});
it('should contain tooltip and link for Barrierefreiheit', () => {
shouldHaveAttribute(header.getAccessibilityIcon().parent(), 'tooltip', accTooltip);
shouldHaveAttribute(header.getAccessibilityIcon(), 'href', accLink);
});
it('should focus help menu icon', () => { it('should focus help menu icon', () => {
pressTab(); pressTab();
......
...@@ -29,11 +29,11 @@ import { VorgangSearchE2EComponent } from '../components/vorgang/vorgang-search. ...@@ -29,11 +29,11 @@ import { VorgangSearchE2EComponent } from '../components/vorgang/vorgang-search.
export class HeaderE2EComponent { export class HeaderE2EComponent {
private readonly locatorLogo: string = 'alfa-logo'; private readonly locatorLogo: string = 'alfa-logo';
private readonly locatorRoot: string = 'header'; private readonly locatorRoot: string = 'header';
private readonly accessibilityIcon: string = 'accessibility-button';
private readonly helpMenu: HelpMenuE2EComponent = new HelpMenuE2EComponent(); private readonly helpMenu: HelpMenuE2EComponent = new HelpMenuE2EComponent();
private readonly userSettings: UserSettingsE2EComponent = new UserSettingsE2EComponent(); private readonly userSettings: UserSettingsE2EComponent = new UserSettingsE2EComponent();
private readonly currentUserProfile: CurrentUserProfileE2EComponent = private readonly currentUserProfile: CurrentUserProfileE2EComponent = new CurrentUserProfileE2EComponent();
new CurrentUserProfileE2EComponent();
private readonly vorgangSearch: VorgangSearchE2EComponent = new VorgangSearchE2EComponent(); private readonly vorgangSearch: VorgangSearchE2EComponent = new VorgangSearchE2EComponent();
public getRoot() { public getRoot() {
...@@ -59,4 +59,8 @@ export class HeaderE2EComponent { ...@@ -59,4 +59,8 @@ export class HeaderE2EComponent {
public getCurrentUserProfile(): CurrentUserProfileE2EComponent { public getCurrentUserProfile(): CurrentUserProfileE2EComponent {
return this.currentUserProfile; return this.currentUserProfile;
} }
public getAccessibilityIcon(): Cypress.Chainable<JQuery<HTMLElement>> {
return cy.getTestElement(this.accessibilityIcon);
}
} }
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
<div class="mat-app-background relative grow"><router-outlet></router-outlet></div> <div class="mat-app-background relative grow"><router-outlet></router-outlet></div>
<section class="mat-app-background right-nav"> <section class="mat-app-background right-nav">
<alfa-build-info *ngIf="apiRoot.resource" [apiRoot]="apiRoot.resource" data-test-id="build-info"></alfa-build-info> <common-build-info *ngIf="apiRoot.resource" [apiRoot]="apiRoot.resource" data-test-id="build-info"></common-build-info>
</section> </section>
</div> </div>
</ozgcloud-spinner> </ozgcloud-spinner>
......
...@@ -28,6 +28,7 @@ export interface ApiRoot { ...@@ -28,6 +28,7 @@ export interface ApiRoot {
buildTime: string; buildTime: string;
javaVersion: string; javaVersion: string;
production: boolean; production: boolean;
barrierefreiheitUrl: string;
} }
export interface ApiRootResource extends ApiRoot, Resource {} export interface ApiRootResource extends ApiRoot, Resource {}
......
...@@ -34,5 +34,6 @@ export function createApiRoot(): ApiRoot { ...@@ -34,5 +34,6 @@ export function createApiRoot(): ApiRoot {
buildTime: '1', buildTime: '1',
javaVersion: '1', javaVersion: '1',
production: false, production: false,
barrierefreiheitUrl: 'https://example.com/',
}; };
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "common", "name": "common",
"$schema": "../../node_modules/nx/schemas/project-schema.json", "$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/common/src", "sourceRoot": "libs/common/src",
"prefix": "lib", "prefix": "common",
"projectType": "library", "projectType": "library",
"tags": [], "tags": [],
"targets": { "targets": {
......
...@@ -21,4 +21,5 @@ ...@@ -21,4 +21,5 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen * Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen. * unter der Lizenz sind dem Lizenztext zu entnehmen.
*/ */
export * from './lib/accessibility-button/accessibility-button.component';
export * from './lib/build-info/build-info.component'; export * from './lib/build-info/build-info.component';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AccessibilityButtonComponent } from './accessibility-button.component';
describe('AccessibilityButtonComponent', () => {
let component: AccessibilityButtonComponent;
let fixture: ComponentFixture<AccessibilityButtonComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AccessibilityButtonComponent],
}).compileComponents();
fixture = TestBed.createComponent(AccessibilityButtonComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { CommonModule } from '@angular/common';
import { Component, Input } from '@angular/core';
import { AccessibilityIconComponent, LinkComponent, TooltipDirective } from '@ods/system';
@Component({
selector: 'common-accessibility-button',
standalone: true,
imports: [CommonModule, AccessibilityIconComponent, LinkComponent, TooltipDirective],
template: `<ods-link [url]="url" [linkTestId]="linkTestId" tooltip="Barrierefreiheit" [openInNewTab]="true">
<ods-accessibility-icon size="large" />
</ods-link>`,
})
export class AccessibilityButtonComponent {
@Input({ required: true }) url!: string;
@Input() linkTestId: string | null = null;
}
...@@ -28,7 +28,7 @@ import * as DateUtil from '@alfa-client/tech-shared'; ...@@ -28,7 +28,7 @@ import * as DateUtil from '@alfa-client/tech-shared';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
@Component({ @Component({
selector: 'alfa-build-info', selector: 'common-build-info',
imports: [CommonModule], imports: [CommonModule],
standalone: true, standalone: true,
templateUrl: './build-info.component.html', templateUrl: './build-info.component.html',
......
...@@ -38,6 +38,7 @@ export * from './lib/form/file-upload-button/file-upload-button.component'; ...@@ -38,6 +38,7 @@ export * from './lib/form/file-upload-button/file-upload-button.component';
export * from './lib/form/radio-button-card/radio-button-card.component'; export * from './lib/form/radio-button-card/radio-button-card.component';
export * from './lib/form/text-input/text-input.component'; export * from './lib/form/text-input/text-input.component';
export * from './lib/form/textarea/textarea.component'; export * from './lib/form/textarea/textarea.component';
export * from './lib/icons/accessibility-icon/accessibility-icon.component';
export * from './lib/icons/admin-logo-icon/admin-logo-icon.component'; export * from './lib/icons/admin-logo-icon/admin-logo-icon.component';
export * from './lib/icons/attachment-icon/attachment-icon.component'; export * from './lib/icons/attachment-icon/attachment-icon.component';
export * from './lib/icons/bescheid-generate-icon/bescheid-generate-icon.component'; export * from './lib/icons/bescheid-generate-icon/bescheid-generate-icon.component';
...@@ -65,6 +66,7 @@ export * from './lib/icons/user-icon/user-icon.component'; ...@@ -65,6 +66,7 @@ export * from './lib/icons/user-icon/user-icon.component';
export * from './lib/icons/users-icon/users-icon.component'; export * from './lib/icons/users-icon/users-icon.component';
export * from './lib/instant-search/instant-search/instant-search.component'; export * from './lib/instant-search/instant-search/instant-search.component';
export * from './lib/instant-search/instant-search/instant-search.model'; export * from './lib/instant-search/instant-search/instant-search.model';
export * from './lib/link/link.component';
export * from './lib/list/list-item/list-item.component'; export * from './lib/list/list-item/list-item.component';
export * from './lib/list/list.component'; export * from './lib/list/list.component';
export * from './lib/navbar/nav-item/nav-item.component'; export * from './lib/navbar/nav-item/nav-item.component';
......
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AccessibilityIconComponent } from './accessibility-icon.component';
describe('AccessibilityIconComponent', () => {
let component: AccessibilityIconComponent;
let fixture: ComponentFixture<AccessibilityIconComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AccessibilityIconComponent],
}).compileComponents();
fixture = TestBed.createComponent(AccessibilityIconComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { CommonModule } from '@angular/common';
import { Component, Input } from '@angular/core';
import { twMerge } from 'tailwind-merge';
import { iconVariants, IconVariants } from '../iconVariants';
@Component({
selector: 'ods-accessibility-icon',
standalone: true,
imports: [CommonModule],
template: `<svg
viewBox="0 0 26 26"
[ngClass]="[twMerge(iconVariants({ size }), 'fill-neutral-500 dark:fill-neutral-400', class)]"
xmlns="http://www.w3.org/2000/svg"
>
<rect x="2" y="2" width="22" height="22" rx="11" />
<path
d="M13 8.87508C12.6828 8.87508 12.3726 8.781 12.1088 8.60473C11.845 8.42846 11.6394 8.17793 11.518 7.8848C11.3966 7.59168 11.3648 7.26914 11.4267 6.95796C11.4886 6.64678 11.6414 6.36095 11.8657 6.1366C12.0901 5.91225 12.3759 5.75947 12.6871 5.69757C12.9983 5.63568 13.3208 5.66744 13.6139 5.78886C13.907 5.91027 14.1576 6.11588 14.3339 6.37969C14.5101 6.64349 14.6042 6.95364 14.6042 7.27092C14.6038 7.69623 14.4346 8.10399 14.1339 8.40473C13.8331 8.70547 13.4253 8.87463 13 8.87508Z"
class="fill-whitetext"
/>
<path
d="M18.0417 8.898L18.0288 8.90144L18.0168 8.90516C17.9881 8.91318 17.9595 8.92178 17.9308 8.93066C17.3977 9.08706 14.8105 9.81638 12.9877 9.81638C11.2939 9.81638 8.94064 9.18618 8.18783 8.97219C8.1129 8.94322 8.03639 8.91855 7.95866 8.89829C7.41439 8.75506 7.04199 9.30792 7.04199 9.81323C7.04199 10.3137 7.49173 10.552 7.94577 10.723V10.731L10.6734 11.583C10.9521 11.6898 11.0266 11.799 11.063 11.8935C11.1813 12.1969 11.0868 12.7976 11.0533 13.0072L10.8871 14.2963L9.96501 19.3434C9.96215 19.3572 9.95957 19.3712 9.95728 19.3855L9.95069 19.4219C9.88423 19.8845 10.224 20.3334 10.8674 20.3334C11.4288 20.3334 11.6766 19.9458 11.784 19.4185C11.784 19.4185 12.5861 14.9047 12.9871 14.9047C13.3882 14.9047 14.2143 19.4185 14.2143 19.4185C14.3218 19.9458 14.5695 20.3334 15.131 20.3334C15.7761 20.3334 16.1158 19.8825 16.0477 19.4185C16.0417 19.3789 16.0345 19.34 16.0259 19.3022L15.0912 14.2969L14.9253 13.0078C14.8053 12.257 14.9018 12.0089 14.9345 11.9508L14.9368 11.9465C14.9677 11.8892 15.1087 11.7609 15.4375 11.6374L17.995 10.7434C18.0107 10.7392 18.0262 10.7342 18.0414 10.7285C18.4998 10.5566 18.9581 10.3188 18.9581 9.81381C18.9581 9.30878 18.586 8.75506 18.0417 8.898Z"
class="fill-whitetext"
/>
</svg>`,
})
export class AccessibilityIconComponent {
@Input() size: IconVariants['size'] = 'medium';
@Input() class: string = '';
readonly iconVariants = iconVariants;
readonly twMerge = twMerge;
}
import type { Meta, StoryObj } from '@storybook/angular';
import { AccessibilityIconComponent } from './accessibility-icon.component';
const meta: Meta<AccessibilityIconComponent> = {
title: 'Icons/Accessibility icon',
component: AccessibilityIconComponent,
excludeStories: /.*Data$/,
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<AccessibilityIconComponent>;
export const Default: Story = {
args: { size: 'large' },
argTypes: {
size: {
control: 'select',
options: ['small', 'medium', 'large', 'extra-large', 'full'],
description: 'Size of icon. Property "full" means 100%',
table: {
defaultValue: { summary: 'medium' },
},
},
},
};
...@@ -34,7 +34,7 @@ import { twMerge } from 'tailwind-merge'; ...@@ -34,7 +34,7 @@ import { twMerge } from 'tailwind-merge';
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
[ngClass]="twMerge(iconVariants({ size }), 'fill-neutral-500', class)" [ngClass]="twMerge(iconVariants({ size }), 'fill-neutral-500 dark:fill-neutral-400', class)"
> >
<path <path
d="M 10.490234 2 C 10.011234 2 9.6017656 2.3385938 9.5097656 2.8085938 L 9.1757812 4.5234375 C 8.3550224 4.8338012 7.5961042 5.2674041 6.9296875 5.8144531 L 5.2851562 5.2480469 C 4.8321563 5.0920469 4.33375 5.2793594 4.09375 5.6933594 L 2.5859375 8.3066406 C 2.3469375 8.7216406 2.4339219 9.2485 2.7949219 9.5625 L 4.1132812 10.708984 C 4.0447181 11.130337 4 11.559284 4 12 C 4 12.440716 4.0447181 12.869663 4.1132812 13.291016 L 2.7949219 14.4375 C 2.4339219 14.7515 2.3469375 15.278359 2.5859375 15.693359 L 4.09375 18.306641 C 4.33275 18.721641 4.8321562 18.908906 5.2851562 18.753906 L 6.9296875 18.1875 C 7.5958842 18.734206 8.3553934 19.166339 9.1757812 19.476562 L 9.5097656 21.191406 C 9.6017656 21.661406 10.011234 22 10.490234 22 L 13.509766 22 C 13.988766 22 14.398234 21.661406 14.490234 21.191406 L 14.824219 19.476562 C 15.644978 19.166199 16.403896 18.732596 17.070312 18.185547 L 18.714844 18.751953 C 19.167844 18.907953 19.66625 18.721641 19.90625 18.306641 L 21.414062 15.691406 C 21.653063 15.276406 21.566078 14.7515 21.205078 14.4375 L 19.886719 13.291016 C 19.955282 12.869663 20 12.440716 20 12 C 20 11.559284 19.955282 11.130337 19.886719 10.708984 L 21.205078 9.5625 C 21.566078 9.2485 21.653063 8.7216406 21.414062 8.3066406 L 19.90625 5.6933594 C 19.66725 5.2783594 19.167844 5.0910937 18.714844 5.2460938 L 17.070312 5.8125 C 16.404116 5.2657937 15.644607 4.8336609 14.824219 4.5234375 L 14.490234 2.8085938 C 14.398234 2.3385937 13.988766 2 13.509766 2 L 10.490234 2 z M 12 8 C 14.209 8 16 9.791 16 12 C 16 14.209 14.209 16 12 16 C 9.791 16 8 14.209 8 12 C 8 9.791 9.791 8 12 8 z" d="M 10.490234 2 C 10.011234 2 9.6017656 2.3385938 9.5097656 2.8085938 L 9.1757812 4.5234375 C 8.3550224 4.8338012 7.5961042 5.2674041 6.9296875 5.8144531 L 5.2851562 5.2480469 C 4.8321563 5.0920469 4.33375 5.2793594 4.09375 5.6933594 L 2.5859375 8.3066406 C 2.3469375 8.7216406 2.4339219 9.2485 2.7949219 9.5625 L 4.1132812 10.708984 C 4.0447181 11.130337 4 11.559284 4 12 C 4 12.440716 4.0447181 12.869663 4.1132812 13.291016 L 2.7949219 14.4375 C 2.4339219 14.7515 2.3469375 15.278359 2.5859375 15.693359 L 4.09375 18.306641 C 4.33275 18.721641 4.8321562 18.908906 5.2851562 18.753906 L 6.9296875 18.1875 C 7.5958842 18.734206 8.3553934 19.166339 9.1757812 19.476562 L 9.5097656 21.191406 C 9.6017656 21.661406 10.011234 22 10.490234 22 L 13.509766 22 C 13.988766 22 14.398234 21.661406 14.490234 21.191406 L 14.824219 19.476562 C 15.644978 19.166199 16.403896 18.732596 17.070312 18.185547 L 18.714844 18.751953 C 19.167844 18.907953 19.66625 18.721641 19.90625 18.306641 L 21.414062 15.691406 C 21.653063 15.276406 21.566078 14.7515 21.205078 14.4375 L 19.886719 13.291016 C 19.955282 12.869663 20 12.440716 20 12 C 20 11.559284 19.955282 11.130337 19.886719 10.708984 L 21.205078 9.5625 C 21.566078 9.2485 21.653063 8.7216406 21.414062 8.3066406 L 19.90625 5.6933594 C 19.66725 5.2783594 19.167844 5.0910937 18.714844 5.2460938 L 17.070312 5.8125 C 16.404116 5.2657937 15.644607 4.8336609 14.824219 4.5234375 L 14.490234 2.8085938 C 14.398234 2.3385937 13.988766 2 13.509766 2 L 10.490234 2 z M 12 8 C 14.209 8 16 9.791 16 12 C 16 14.209 14.209 16 12 16 C 9.791 16 8 14.209 8 12 C 8 9.791 9.791 8 12 8 z"
......
import { getElementFromFixture } from '@alfa-client/test-utils';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
import { LinkComponent } from './link.component';
describe('LinkComponent', () => {
let component: LinkComponent;
let fixture: ComponentFixture<LinkComponent>;
const linkElementSelector: string = getDataTestIdOf('testLink');
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [LinkComponent],
}).compileComponents();
fixture = TestBed.createComponent(LinkComponent);
component = fixture.componentInstance;
component.linkTestId = 'testLink';
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
describe('component', () => {
describe('isFocused', () => {
it('should be set to true on focus', () => {
const linkElement: HTMLLinkElement = getElementFromFixture(fixture, linkElementSelector);
linkElement.focus();
fixture.detectChanges();
expect(component.isFocused).toBe(true);
});
it('should be set to false on blue', () => {
component.isFocused = true;
const linkElement: HTMLLinkElement = getElementFromFixture(fixture, linkElementSelector);
linkElement.dispatchEvent(new Event('blur'));
fixture.detectChanges();
expect(component.isFocused).toBe(false);
});
});
});
});
import { CommonModule } from '@angular/common';
import { Component, Input } from '@angular/core';
import { twMerge } from 'tailwind-merge';
@Component({
selector: 'ods-link',
standalone: true,
imports: [CommonModule],
template: `<a
[target]="openInNewTab ? '_blank' : '_self'"
[href]="url"
[class]="twMerge('block rounded text-text outline-2 outline-offset-2 outline-focus focus-visible:outline', class)"
[attr.data-test-id]="linkTestId"
(focus)="isFocused = true"
(blur)="isFocused = false"
[class.ods-focused]="isFocused"
>
<ng-content />
</a>`,
})
export class LinkComponent {
@Input({ required: true }) url!: string;
@Input() openInNewTab: boolean = false;
@Input() class: string = '';
@Input() linkTestId: string | null = null;
public isFocused: boolean = false;
readonly twMerge = twMerge;
}
import { argsToTemplate, moduleMetadata, type Meta, type StoryObj } from '@storybook/angular';
import { AccessibilityIconComponent } from '../icons/accessibility-icon/accessibility-icon.component';
import { LinkComponent } from './link.component';
const meta: Meta<LinkComponent> = {
title: 'Link',
component: LinkComponent,
decorators: [
moduleMetadata({
imports: [LinkComponent, AccessibilityIconComponent],
}),
],
excludeStories: /.*Data$/,
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<LinkComponent>;
export const Default: Story = {
args: {
url: 'https://www.bundestag.de/',
openInNewTab: true,
},
argTypes: {
url: { description: 'Link to external url' },
openInNewTab: { description: 'Should the link be opened in new tab' },
class: { description: 'CSS/Tailwind class' },
},
render: (args) => ({
props: args,
template: `<ods-link ${argsToTemplate(args)}>
Link with text
</ods-link>`,
}),
};
export const WithIcon: Story = {
args: {
url: 'https://www.bmas.de/DE/Service/Gesetze-und-Gesetzesvorhaben/barrierefreiheitsstaerkungsgesetz.html',
openInNewTab: true,
},
render: (args) => ({
props: args,
template: `<ods-link ${argsToTemplate(args)}>
<ods-accessibility-icon size="large" />
</ods-link>`,
}),
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment