diff --git a/alfa-client/apps/demo/project.json b/alfa-client/apps/demo/project.json index e0876536a2ce6b9dceee56779f8430f18de63694..33b6d437bfaeb6c4a3308851f0a7b99670fe4fe7 100644 --- a/alfa-client/apps/demo/project.json +++ b/alfa-client/apps/demo/project.json @@ -8,24 +8,23 @@ "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", - "outputs": [ - "{options.outputPath}" - ], + "outputs": ["{options.outputPath}"], "options": { "outputPath": "dist/apps/demo", "index": "apps/demo/src/index.html", "main": "apps/demo/src/main.ts", - "polyfills": [ - "zone.js" - ], + "polyfills": ["zone.js"], "tsConfig": "apps/demo/tsconfig.app.json", "assets": [ "apps/demo/src/favicon.ico", - "apps/demo/src/assets" - ], - "styles": [ - "apps/demo/src/styles.scss" + "apps/demo/src/assets", + { + "input": "libs/design-system/src/assets", + "glob": "**/*", + "output": "assets/icons" + } ], + "styles": ["apps/demo/src/styles.scss"], "scripts": [] }, "configurations": { @@ -75,15 +74,11 @@ }, "lint": { "executor": "@nx/eslint:lint", - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nx/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}" - ], + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { "jestConfig": "apps/demo/jest.config.ts" } @@ -95,4 +90,4 @@ } } } -} \ No newline at end of file +} diff --git a/alfa-client/apps/demo/src/app/app.component.html b/alfa-client/apps/demo/src/app/app.component.html index 22a2f09c8bd01b957ed678fd264ac675685cf402..9dce1e1daf89e810cb8c7da7cc037107418f7c80 100644 --- a/alfa-client/apps/demo/src/app/app.component.html +++ b/alfa-client/apps/demo/src/app/app.component.html @@ -57,6 +57,14 @@ </div> <div class="my-12"> + <h2 class="heading-2">Icons</h2> + <div class="mb-6 flex"> + <ods-icon name="account-circle" size="xxl" /> + <ods-icon name="accessibility" size="extra-large" color="text" /> + <ods-icon name="accessibility" size="large" color="error" /> + <ods-icon name="accessibility" class="fill-red-500" /> + <ods-icon name="accessibility" size="small" /> + </div> <h1 class="mb-6 text-2xl font-semibold text-text">Auswertungen</h1> <ods-button text="Auswertung hinzufügen" /> <ul class="mt-6 divide-y divide-gray-300 rounded-md bg-background-50 text-text shadow-sm ring-1 ring-gray-300"> @@ -582,21 +590,21 @@ </div> <div class="mt-4"> - <ods-file-upload-button class="w-72" [isLoading]="false" id="upload117"> + <ods-file-upload-button class="w-72" [isLoading]="false" id="upload117" dataTestId="demo-upload-1"> <ods-bescheid-upload-icon icon /> <ods-spinner-icon spinner size="extra-large" /> <p text class="text-center">Bescheiddokument<br />hochladen</p></ods-file-upload-button > </div> <div class="mt-4"> - <ods-file-upload-button class="w-72" [isLoading]="true" id="upload117"> + <ods-file-upload-button class="w-72" [isLoading]="true" id="upload117" dataTestId="demo-upload-2"> <ods-bescheid-upload-icon icon /> <ods-spinner-icon spinner size="extra-large" /> <p text class="text-center">Bescheiddokument<br />hochladen</p></ods-file-upload-button > </div> <div class="mt-4"> - <ods-file-upload-button class="w-72" [isLoading]="true" id="upload130"> + <ods-file-upload-button class="w-72" [isLoading]="true" id="upload130" dataTestId="demo-upload-3"> <ods-attachment-icon icon /> <ods-spinner-icon spinner size="medium" /> <div text class="text-center">Anhang hochladen</div></ods-file-upload-button diff --git a/alfa-client/apps/demo/src/app/app.component.ts b/alfa-client/apps/demo/src/app/app.component.ts index 044bdfb401a44a53ba51c8566ec041366d5a937a..1e18d64a6bc767490fbd66705111c574fa5903a0 100644 --- a/alfa-client/apps/demo/src/app/app.component.ts +++ b/alfa-client/apps/demo/src/app/app.component.ts @@ -39,6 +39,7 @@ import { ErrorMessageComponent, FieldsetComponent, FileUploadButtonComponent, + IconComponent, InstantSearchComponent, RadioButtonCardComponent, SaveIconComponent, @@ -90,6 +91,7 @@ import { CustomStepperComponent } from './components/cdk-demo/custom-stepper.com TextareaComponent, ErrorMessageComponent, TooltipDirective, + IconComponent, ], selector: 'app-root', templateUrl: './app.component.html', diff --git a/alfa-client/apps/demo/src/app/app.config.ts b/alfa-client/apps/demo/src/app/app.config.ts index 9c33c3403709b95b3c778d0bcf687c325f75a2e3..a0ecda43e8675693014dc4457718e39022e41a4b 100644 --- a/alfa-client/apps/demo/src/app/app.config.ts +++ b/alfa-client/apps/demo/src/app/app.config.ts @@ -21,10 +21,17 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideRouter, withEnabledBlockingInitialNavigation } from '@angular/router'; +import { provideAngularSvgIcon } from 'angular-svg-icon'; import { appRoutes } from './app.routes'; export const appConfig: ApplicationConfig = { - providers: [provideRouter(appRoutes, withEnabledBlockingInitialNavigation())], + providers: [ + provideRouter(appRoutes, withEnabledBlockingInitialNavigation()), + provideZoneChangeDetection({ eventCoalescing: true }), + provideHttpClient(), + provideAngularSvgIcon(), + ], }; diff --git a/alfa-client/libs/design-system/src/assets/accessibility.svg b/alfa-client/libs/design-system/src/assets/accessibility.svg new file mode 100644 index 0000000000000000000000000000000000000000..5f0c8a919799a0fd30ff127f548c5076e00b0583 --- /dev/null +++ b/alfa-client/libs/design-system/src/assets/accessibility.svg @@ -0,0 +1,9 @@ +<svg viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"> + <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> \ No newline at end of file diff --git a/alfa-client/libs/design-system/src/assets/account-circle.svg b/alfa-client/libs/design-system/src/assets/account-circle.svg new file mode 100644 index 0000000000000000000000000000000000000000..e6e1d1517a3912b9fe6f68403a034c3561c78f8b --- /dev/null +++ b/alfa-client/libs/design-system/src/assets/account-circle.svg @@ -0,0 +1,4 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"> + <path + d="M12.75 2C7.23 2 2.75 6.48 2.75 12C2.75 17.52 7.23 22 12.75 22C18.27 22 22.75 17.52 22.75 12C22.75 6.48 18.27 2 12.75 2ZM7.82 18.28C8.25 17.38 10.87 16.5 12.75 16.5C14.63 16.5 17.26 17.38 17.68 18.28C16.32 19.36 14.61 20 12.75 20C10.89 20 9.18 19.36 7.82 18.28ZM19.11 16.83C17.68 15.09 14.21 14.5 12.75 14.5C11.29 14.5 7.82 15.09 6.39 16.83C5.37 15.49 4.75 13.82 4.75 12C4.75 7.59 8.34 4 12.75 4C17.16 4 20.75 7.59 20.75 12C20.75 13.82 20.13 15.49 19.11 16.83ZM12.75 6C10.81 6 9.25 7.56 9.25 9.5C9.25 11.44 10.81 13 12.75 13C14.69 13 16.25 11.44 16.25 9.5C16.25 7.56 14.69 6 12.75 6ZM12.75 11C11.92 11 11.25 10.33 11.25 9.5C11.25 8.67 11.92 8 12.75 8C13.58 8 14.25 8.67 14.25 9.5C14.25 10.33 13.58 11 12.75 11Z" /> +</svg> \ No newline at end of file diff --git a/alfa-client/libs/design-system/src/index.ts b/alfa-client/libs/design-system/src/index.ts index c17fdb29f53e0948d6f7b3a61d0d3725c18e2ffc..0c5d7568d8df069b619b5a8c77184491b8a1c8e2 100644 --- a/alfa-client/libs/design-system/src/index.ts +++ b/alfa-client/libs/design-system/src/index.ts @@ -44,6 +44,7 @@ export * from './lib/form/text-input/text-input.component'; export * from './lib/form/textarea/textarea.component'; export * from './lib/forwarding-item/forwarding-item-info/forwarding-item-info.component'; export * from './lib/forwarding-item/forwarding-item.component'; +export * from './lib/icon/icon.component'; export * from './lib/icons/accessibility-icon/accessibility-icon.component'; export * from './lib/icons/account-circle-icon/account-circle-icon.component'; export * from './lib/icons/admin-logo-icon/admin-logo-icon.component'; diff --git a/alfa-client/libs/design-system/src/lib/icon/icon.component.spec.ts b/alfa-client/libs/design-system/src/lib/icon/icon.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..90024846fc5d491465a96f8ef6638ad1b8a6b691 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icon/icon.component.spec.ts @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2025 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 { ComponentFixture, TestBed } from '@angular/core/testing'; +import { IconComponent } from './icon.component'; + +describe('IconComponent', () => { + let component: IconComponent; + let fixture: ComponentFixture<IconComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [IconComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(IconComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/alfa-client/libs/design-system/src/lib/icon/icon.component.ts b/alfa-client/libs/design-system/src/lib/icon/icon.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..1681095e6551acbe305ca7993fd996cab15a2142 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icon/icon.component.ts @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2025 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 { Component, Input } from '@angular/core'; +import { SvgIconComponent } from 'angular-svg-icon'; +import { VariantProps, cva } from 'class-variance-authority'; +import { twMerge } from 'tailwind-merge'; + +const iconVariants = cva('', { + variants: { + size: { + full: 'size-full', + small: 'size-4', + medium: 'size-6', + large: 'size-8', + 'extra-large': 'size-10', + xxl: 'size-12', + }, + color: { + primary: 'fill-primary', + text: 'fill-text', + whitetext: 'fill-whitetext', + error: 'fill-error', + }, + }, +}); + +type IconVariants = VariantProps<typeof iconVariants>; + +@Component({ + selector: 'ods-icon', + standalone: true, + imports: [CommonModule, SvgIconComponent], + template: `<svg-icon [src]="'assets/icons/' + name + '.svg'" [svgClass]="twMerge(iconVariants({ size, color }), class)" />`, + styles: [':host {@apply block w-fit}'], +}) +export class IconComponent { + @Input({ required: true }) name!: string; + @Input() class: string; + @Input() size: IconVariants['size'] = 'medium'; + @Input() color: IconVariants['color'] = 'primary'; + + readonly iconVariants = iconVariants; + readonly twMerge = twMerge; +} diff --git a/alfa-client/libs/design-system/src/lib/icon/icon.stories.ts b/alfa-client/libs/design-system/src/lib/icon/icon.stories.ts new file mode 100644 index 0000000000000000000000000000000000000000..6f92ea55f26a052607f3858f7bc957449d4782e4 --- /dev/null +++ b/alfa-client/libs/design-system/src/lib/icon/icon.stories.ts @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2025 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 { moduleMetadata, type Meta, type StoryObj } from '@storybook/angular'; + +import { IconComponent } from './icon.component'; + +const meta: Meta<IconComponent> = { + title: 'Icon', + component: IconComponent, + decorators: [ + moduleMetadata({ + imports: [IconComponent], + }), + ], + excludeStories: /.*Data$/, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj<IconComponent>; + +export const Default: Story = { + args: {}, +}; diff --git a/alfa-client/package.json b/alfa-client/package.json index d4e51a736a56e6aebfb6e3c8943ca998363833d7..94a5710a8b8db9d7134f1ff79c45c4def8ac05a1 100644 --- a/alfa-client/package.json +++ b/alfa-client/package.json @@ -73,6 +73,7 @@ "@nx/angular": "19.8.8", "angular-oauth2-oidc": "17.0.2", "angular-oauth2-oidc-jwks": "17.0.2", + "angular-svg-icon": "^19.1.1", "class-variance-authority": "^0.7.0", "date-fns": "^2.30.0", "file-saver": "2.0.5", diff --git a/alfa-client/pnpm-lock.yaml b/alfa-client/pnpm-lock.yaml index c447ee766cd2cdc982a9fcdb64d528ddd73d27e5..c01bfa47f1a6e40c958bf214e5d20cf8f350385b 100644 --- a/alfa-client/pnpm-lock.yaml +++ b/alfa-client/pnpm-lock.yaml @@ -71,6 +71,9 @@ importers: angular-oauth2-oidc-jwks: specifier: 17.0.2 version: 17.0.2 + angular-svg-icon: + specifier: ^19.1.1 + version: 19.1.1(@angular/common@18.2.8(@angular/core@18.2.8(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.8(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1) class-variance-authority: specifier: ^0.7.0 version: 0.7.0 @@ -4362,6 +4365,13 @@ packages: '@angular/common': '>=14.0.0' '@angular/core': '>=14.0.0' + angular-svg-icon@19.1.1: + resolution: {integrity: sha512-4uKVdkc68ii2nadJAqJDbRfMFaD3JZ4AK2S28PjGDvXfvtE5T28lm/CFZA3MKqUesUZlneJAaOX4cpC3pvoCZQ==} + peerDependencies: + '@angular/common': '>=19.0.0' + '@angular/core': '>=19.0.0' + rxjs: '>=6.6.3' + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -16432,6 +16442,13 @@ snapshots: '@angular/core': 18.2.8(rxjs@7.8.1)(zone.js@0.14.10) tslib: 2.8.1 + angular-svg-icon@19.1.1(@angular/common@18.2.8(@angular/core@18.2.8(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.8(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1): + dependencies: + '@angular/common': 18.2.8(@angular/core@18.2.8(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1) + '@angular/core': 18.2.8(rxjs@7.8.1)(zone.js@0.14.10) + rxjs: 7.8.1 + tslib: 2.8.1 + ansi-colors@4.1.3: {} ansi-escapes@4.3.2: