UNPKG

@kern-ux-annex/kern-angular-kit

Version:

Angular-Umsetzung der KERN UX-Standard Komponenten

1 lines 204 kB
{"version":3,"file":"kern-ux-annex-kern-angular-kit.mjs","sources":["../../../projects/kern-angular-kit/src/lib/directives/typography/kern-title/kern-title.ts","../../../projects/kern-angular-kit/src/lib/components/kern-accordion/kern-accordion.ts","../../../projects/kern-angular-kit/src/lib/components/kern-accordion/kern-accordion.html","../../../projects/kern-angular-kit/src/lib/components/kern-accordion/kern-accordion-group.ts","../../../projects/kern-angular-kit/src/lib/components/kern-icon/kern-icon.ts","../../../projects/kern-angular-kit/src/lib/components/kern-icon/kern-icon.html","../../../projects/kern-angular-kit/src/lib/components/kern-alert/kern-alert.ts","../../../projects/kern-angular-kit/src/lib/components/kern-alert/kern-alert.html","../../../projects/kern-angular-kit/src/lib/services/unique-id.ts","../../../projects/kern-angular-kit/src/lib/directives/typography/kern-label/kern-label.ts","../../../projects/kern-angular-kit/src/lib/components/kern-button/kern-button.ts","../../../projects/kern-angular-kit/src/lib/components/kern-button/kern-button.html","../../../projects/kern-angular-kit/src/lib/components/kern-dialog/kern-dialog.ts","../../../projects/kern-angular-kit/src/lib/components/kern-dialog/kern-dialog.html","../../../projects/kern-angular-kit/src/lib/components/kern-loader/kern-loader.ts","../../../projects/kern-angular-kit/src/lib/components/kern-loader/kern-loader.html","../../../projects/kern-angular-kit/src/lib/components/kern-badge/kern-badge.ts","../../../projects/kern-angular-kit/src/lib/components/kern-badge/kern-badge.html","../../../projects/kern-angular-kit/src/lib/directives/typography/kern-preline/kern-preline.ts","../../../projects/kern-angular-kit/src/lib/directives/typography/kern-subline/kern-subline.ts","../../../projects/kern-angular-kit/src/lib/components/kern-card/kern-card.ts","../../../projects/kern-angular-kit/src/lib/components/kern-card/kern-card.html","../../../projects/kern-angular-kit/src/lib/components/kern-divider/kern-divider.ts","../../../projects/kern-angular-kit/src/lib/components/kern-divider/kern-divider.html","../../../projects/kern-angular-kit/src/lib/components/kern-link/kern-link.ts","../../../projects/kern-angular-kit/src/lib/components/kern-link/kern-link.html","../../../projects/kern-angular-kit/src/lib/components/kern-progress/kern-progress.ts","../../../projects/kern-angular-kit/src/lib/components/kern-progress/kern-progress.html","../../../projects/kern-angular-kit/src/lib/components/grid/kern-container/kern-container.ts","../../../projects/kern-angular-kit/src/lib/components/kern-kopfzeile/kern-kopfzeile.ts","../../../projects/kern-angular-kit/src/lib/components/kern-kopfzeile/kern-kopfzeile.html","../../../projects/kern-angular-kit/src/lib/components/typography/kern-heading/kern-heading.ts","../../../projects/kern-angular-kit/src/lib/directives/typography/kern-body/kern-body.ts","../../../projects/kern-angular-kit/src/lib/directives/typography/kern-list/kern-list.ts","../../../projects/kern-angular-kit/src/lib/utils/control-value-accessor.directive.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-checkbox/kern-input-checkbox.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-checkbox/kern-input-checkbox.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-error/kern-input-error.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-hint/kern-input-hint.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-fieldset/kern-fieldset.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-fieldset/kern-fieldset.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-date/kern-input-date.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-date/kern-input-date.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-email/kern-input-email.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-email/kern-input-email.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-file/kern-input-file.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-file/kern-input-file.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-number/kern-input-number.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-number/kern-input-number.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-password/kern-input-password.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-password/kern-input-password.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-radio/kern-input-radio.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-radio/kern-input-radio.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-select/kern-input-select.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-select/kern-input-select.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-tel/kern-input-tel.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-tel/kern-input-tel.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-text/kern-input-text.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-text/kern-input-text.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-textarea/kern-input-textarea.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-textarea/kern-input-textarea.html","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-url/kern-input-url.ts","../../../projects/kern-angular-kit/src/lib/components/form-inputs/kern-input-url/kern-input-url.html","../../../projects/kern-angular-kit/src/lib/components/data-display/kern-table/kern-table.ts","../../../projects/kern-angular-kit/src/lib/components/data-display/kern-table/kern-table.html","../../../projects/kern-angular-kit/src/lib/components/data-display/kern-description-list/kern-description-list.ts","../../../projects/kern-angular-kit/src/lib/components/data-display/kern-description-list/kern-description-list.html","../../../projects/kern-angular-kit/src/lib/components/data-display/kern-tasklist/kern-tasklist.ts","../../../projects/kern-angular-kit/src/lib/components/data-display/kern-tasklist/kern-tasklist.html","../../../projects/kern-angular-kit/src/lib/components/data-display/kern-summary/kern-summary.ts","../../../projects/kern-angular-kit/src/lib/components/data-display/kern-summary/kern-summary.html","../../../projects/kern-angular-kit/src/lib/components/data-display/kern-summary/kern-summary-group.ts","../../../projects/kern-angular-kit/src/lib/components/grid/kern-row/kern-row.ts","../../../projects/kern-angular-kit/src/lib/components/grid/kern-col/kern-col.ts","../../../projects/kern-angular-kit/src/lib/kern-angular-kit.module.ts","../../../projects/kern-angular-kit/src/lib/schemas/component-schemas.ts","../../../projects/kern-angular-kit/src/lib/schemas/angular-elements.ts","../../../projects/kern-angular-kit/src/public-api.ts","../../../projects/kern-angular-kit/src/kern-ux-annex-kern-angular-kit.ts"],"sourcesContent":["import { Directive, input } from '@angular/core';\n\n@Directive({\n host: {\n class: 'kern-title',\n '[class.kern-title--small]': 'size() === \"small\"',\n '[class.kern-title--large]': 'size() === \"large\"'\n },\n selector:\n 'h1[kernTitle], h2[kernTitle], h3[kernTitle], h4[kernTitle], h5[kernTitle], h6[kernTitle], span[kernTitle], caption[kernTitle], p[kernTitle]',\n standalone: true\n})\nexport class KernTitle {\n readonly size = input<'default' | 'small' | 'large'>('default');\n}\n","import { Component, input } from '@angular/core';\nimport { KernTitle } from '../../directives/typography/kern-title/kern-title';\n\n@Component({\n selector: 'kern-accordion',\n imports: [KernTitle],\n templateUrl: './kern-accordion.html',\n styles: ':host { display: contents; }'\n})\nexport class KernAccordion {\n readonly title = input.required<string>();\n readonly open = input<boolean>(false);\n}\n","<details class=\"kern-accordion\" [open]=\"open()\">\n <summary class=\"kern-accordion__header\">\n <span kernTitle>{{ title() }}</span>\n </summary>\n <section class=\"kern-accordion__body\">\n <ng-content />\n </section>\n</details>\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'kern-accordion-group',\n host: { class: 'kern-accordion-group' },\n template: `<ng-content />`\n})\nexport class KernAccordionGroup {}\n","import { Component, input } from '@angular/core';\n\n@Component({\n selector: 'kern-icon',\n templateUrl: './kern-icon.html',\n styles: ':host { display: contents; }'\n})\nexport class KernIcon {\n readonly name = input.required<string>();\n readonly ariaHidden = input<boolean>(true);\n readonly size = input<'default' | 'small' | 'large' | 'x-large'>('default');\n}\n","<span\n class=\"kern-icon kern-icon--{{ name() }}\"\n [attr.aria-hidden]=\"ariaHidden()\"\n [class.kern-icon--small]=\"size() === 'small'\"\n [class.kern-icon--large]=\"size() === 'large'\"\n [class.kern-icon--x-large]=\"size() === 'x-large'\"\n></span>\n","import { Component, input } from '@angular/core';\nimport { KernIcon } from '../kern-icon/kern-icon';\nimport { KernTitle } from '../../directives/typography/kern-title/kern-title';\n\n@Component({\n selector: 'kern-alert',\n imports: [KernIcon, KernTitle],\n templateUrl: './kern-alert.html',\n styleUrl: './kern-alert.css'\n})\nexport class KernAlert {\n readonly title = input.required<string>();\n readonly variant = input<'info' | 'success' | 'warning' | 'danger'>('info');\n}\n","<div class=\"kern-alert kern-alert--{{ variant() }}\" role=\"alert\">\n <div class=\"kern-alert__header\">\n <kern-icon [name]=\"variant()\"></kern-icon>\n <span kernTitle>{{ title() }}</span>\n </div>\n <div class=\"kern-alert__body\"><ng-content /></div>\n</div>\n","import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class UniqueIdService {\n private counter: number = 0;\n\n getUniqueId(prefix: string = ''): string {\n return prefix + '_' + (this.counter++).toString();\n }\n}\n","import {\n booleanAttribute,\n Directive,\n ElementRef,\n inject,\n input,\n OnChanges,\n Renderer2,\n SimpleChanges\n} from '@angular/core';\n\n@Directive({\n host: {\n class: 'kern-label',\n '[class.kern-label--small]': 'size() === \"small\"',\n '[class.kern-label--large]': 'size() === \"large\"',\n '[class.kern-sr-only]': 'srOnly()'\n },\n selector:\n 'label[kernLabel], legend[kernLabel], span[kernLabel], p[kernLabel]',\n standalone: true\n})\nexport class KernLabel implements OnChanges {\n private optionalSpan?: HTMLElement;\n\n private readonly elementRef = inject(ElementRef);\n private readonly renderer = inject(Renderer2);\n\n readonly size = input<'default' | 'small' | 'large'>('default');\n readonly optional = input<boolean, unknown>(false, {\n transform: booleanAttribute\n });\n readonly srOnly = input<boolean, unknown>(false, {\n transform: booleanAttribute\n });\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['optional']) {\n if (this.optional()) {\n if (!this.optionalSpan) {\n this.optionalSpan = this.renderer.createElement('span');\n this.renderer.addClass(this.optionalSpan, 'kern-label__optional');\n\n this.renderer.setAttribute(\n this.optionalSpan,\n 'i18n',\n '@@kernAngularKit.label.optional'\n );\n\n this.renderer.setProperty(\n this.optionalSpan,\n 'textContent',\n '- Optional'\n );\n\n this.renderer.appendChild(\n this.elementRef.nativeElement,\n this.optionalSpan\n );\n }\n } else if (this.optionalSpan) {\n this.renderer.removeChild(\n this.elementRef.nativeElement,\n this.optionalSpan\n );\n\n this.optionalSpan = undefined;\n }\n }\n }\n}\n","import { Component, input, output } from '@angular/core';\nimport { KernLabel } from '../../directives/typography/kern-label/kern-label';\n\n@Component({\n selector: 'kern-button',\n imports: [KernLabel],\n templateUrl: './kern-button.html',\n styles: ':host { display: contents; }'\n})\nexport class KernButton {\n readonly variant = input<'primary' | 'secondary' | 'tertiary'>('primary');\n readonly block = input<boolean>(false);\n readonly disabled = input<boolean>(false);\n readonly type = input<'button' | 'submit' | 'reset'>('button');\n readonly iconLeft = input<string | null>(null);\n readonly iconRight = input<string | null>(null);\n readonly srOnlyLabel = input<boolean>(false);\n\n readonly clickEvent = output<Event>();\n}\n","<button\n class=\"kern-btn kern-btn--{{ variant() }}\"\n [class.kern-btn--block]=\"block()\"\n [type]=\"type()\"\n [disabled]=\"disabled()\"\n (click)=\"clickEvent.emit($event)\"\n>\n @if (iconLeft()) {\n <span class=\"kern-icon kern-icon--{{ iconLeft() }}\" aria-hidden=\"true\"></span>\n }\n <span kernLabel [srOnly]=\"srOnlyLabel()\"><ng-content /></span>\n @if (iconRight()) {\n <span class=\"kern-icon kern-icon--{{ iconRight() }}\" aria-hidden=\"true\"></span>\n }\n</button>\n","import {\n Component,\n ElementRef,\n output,\n viewChild,\n input,\n inject,\n computed\n} from '@angular/core';\nimport { UniqueIdService } from '../../services/unique-id';\nimport { KernButton } from '../kern-button/kern-button';\nimport { KernTitle } from '../../directives/typography/kern-title/kern-title';\n\n@Component({\n selector: 'kern-dialog',\n imports: [KernButton, KernTitle],\n templateUrl: './kern-dialog.html'\n})\nexport class KernDialog {\n readonly dialogId = input<string>();\n readonly title = input.required<string>();\n readonly btnCloseLabelText = input<string>('Schließen');\n readonly btnPrimaryLabelText = input<string | null>(null);\n readonly btnSecondaryLabelText = input<string | null>(null);\n\n readonly cancelEvent = output<Event>();\n readonly btnPrimaryClickEvent = output<Event>();\n readonly btnSecondaryClickEvent = output<Event>();\n\n private readonly generatedId = inject(UniqueIdService).getUniqueId('dialog');\n\n protected readonly effectiveId = computed(\n () => this.dialogId() ?? this.generatedId\n );\n\n private readonly dialog =\n viewChild.required<ElementRef<HTMLDialogElement>>('dialog');\n\n public showModal() {\n this.dialog().nativeElement?.showModal();\n }\n\n public closeModal() {\n this.dialog().nativeElement?.close();\n }\n}\n","<dialog\n #dialog\n [id]=\"effectiveId()\"\n class=\"kern-dialog\"\n [attr.aria-describedby]=\"effectiveId() + '_heading'\"\n (cancel)=\"cancelEvent.emit($event)\"\n>\n <header class=\"kern-dialog__header\">\n <h2 kernTitle size=\"large\" id=\"{{ effectiveId() }}_heading\">{{ title() }}</h2>\n <kern-button variant=\"tertiary\" iconLeft=\"close\" [srOnlyLabel]=\"true\" (clickEvent)=\"dialog.close()\">\n {{ btnCloseLabelText() }}\n </kern-button>\n </header>\n <section class=\"kern-dialog__body\">\n <ng-content />\n </section>\n @if (btnPrimaryLabelText() || btnSecondaryLabelText()) {\n <footer class=\"kern-dialog__footer\">\n @if (btnSecondaryLabelText()) {\n <kern-button variant=\"secondary\" (clickEvent)=\"btnSecondaryClickEvent.emit($event)\">\n {{ btnSecondaryLabelText() }}\n </kern-button>\n }\n @if (btnPrimaryLabelText()) {\n <kern-button (clickEvent)=\"btnPrimaryClickEvent.emit($event)\">\n {{ btnPrimaryLabelText() }}\n </kern-button>\n }\n </footer>\n }\n</dialog>\n","import { Component, input } from '@angular/core';\n\n@Component({\n selector: 'kern-loader',\n templateUrl: './kern-loader.html'\n})\nexport class KernLoader {\n readonly text = input<string>('Wird geladen...');\n}\n","<div class=\"kern-loader kern-loader--visible\" role=\"status\">\n <span class=\"kern-sr-only\">{{ text() }}</span>\n</div>\n","import { Component, input } from '@angular/core';\nimport { KernIcon } from '../kern-icon/kern-icon';\nimport { KernLabel } from '../../directives/typography/kern-label/kern-label';\n\n@Component({\n selector: 'kern-badge',\n imports: [KernIcon, KernLabel],\n templateUrl: './kern-badge.html'\n})\nexport class KernBadge {\n readonly variant = input<'info' | 'success' | 'warning' | 'danger'>('info');\n readonly icon = input<string | null>(null);\n}\n","<span class=\"kern-badge kern-badge--{{ variant() }}\">\n @if (icon()) {\n <kern-icon [name]=\"icon()!\" />\n }\n <span kernLabel size=\"small\">\n <ng-content />\n </span>\n</span>\n","import { Directive, input } from '@angular/core';\n\n@Directive({\n host: {\n class: 'kern-preline',\n '[class.kern-preline--small]': 'size() === \"small\"',\n '[class.kern-preline--large]': 'size() === \"large\"'\n },\n selector:\n 'h1[kernPreline], h2[kernPreline], h3[kernPreline], h4[kernPreline], h5[kernPreline], h6[kernPreline], span[kernPreline], p[kernPreline]',\n standalone: true\n})\nexport class KernPreline {\n readonly size = input<'default' | 'small' | 'large'>('default');\n}\n","import { Directive, input } from '@angular/core';\n\n@Directive({\n host: {\n class: 'kern-subline',\n '[class.kern-subline--small]': 'size() === \"small\"',\n '[class.kern-subline--large]': 'size() === \"large\"'\n },\n selector:\n 'h1[kernSubline], h2[kernSubline], h3[kernSubline], h4[kernSubline], h5[kernSubline], h6[kernSubline], span[kernSubline], p[kernSubline]',\n standalone: true\n})\nexport class KernSubline {\n readonly size = input<'default' | 'small' | 'large'>('default');\n}\n","import { Component, input, output } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { KernPreline } from '../../directives/typography/kern-preline/kern-preline';\nimport { KernTitle } from '../../directives/typography/kern-title/kern-title';\nimport { KernSubline } from '../../directives/typography/kern-subline/kern-subline';\nimport { KernButton } from '../kern-button/kern-button';\n\n@Component({\n selector: 'kern-card',\n imports: [NgTemplateOutlet, KernPreline, KernTitle, KernSubline, KernButton],\n templateUrl: './kern-card.html',\n styles: ':host { display: contents; }'\n})\nexport class KernCard {\n readonly title = input<string | null>(null);\n readonly titleLinkHref = input<string | null>(null);\n readonly titleLinkTarget = input<'_self' | '_blank' | '_parent' | '_top'>(\n '_self'\n );\n readonly preline = input<string | null>(null);\n readonly subline = input<string | null>(null);\n readonly imgSrc = input<string | null>(null);\n readonly imgAlt = input<string | null>(null);\n readonly size = input<'default' | 'small' | 'large'>('default');\n readonly headingLevel = input<'1' | '2' | '3' | '4' | '5'>('2');\n readonly btnPrimaryLabelText = input<string | null>(null);\n readonly btnSecondaryLabelText = input<string | null>(null);\n\n readonly titleLinkClickEvent = output<Event>();\n readonly btnPrimaryClickEvent = output<Event>();\n readonly btnSecondaryClickEvent = output<Event>();\n}\n","<article\n class=\"kern-card\"\n [class.kern-card--active]=\"title() && titleLinkHref()\"\n [class.kern-card--small]=\"size() === 'small'\"\n [class.kern-card--large]=\"size() === 'large'\"\n>\n @if (imgSrc()) {\n <div class=\"kern-card__media\">\n <img [src]=\"imgSrc()\" [attr.alt]=\"imgAlt()\" />\n </div>\n }\n <div class=\"kern-card__container\">\n @if (title() || preline() || subline()) {\n <header class=\"kern-card__header\">\n @if (preline()) {\n <p kernPreline>{{ preline() }}</p>\n }\n @if (title()) {\n <ng-template #headingContent>\n @if (titleLinkHref()) {\n <a\n [href]=\"titleLinkHref()\"\n class=\"kern-link--stretched\"\n [target]=\"titleLinkTarget()\"\n [attr.rel]=\"titleLinkTarget() === '_blank' ? 'noopener noreferrer' : null\"\n (click)=\"titleLinkClickEvent.emit($event)\"\n >\n {{ title() }}\n </a>\n } @else {\n {{ title() }}\n }\n </ng-template>\n\n @switch (headingLevel()) {\n @case ('1') {\n <h1 kernTitle><ng-container [ngTemplateOutlet]=\"headingContent\" /></h1>\n }\n @case ('2') {\n <h2 kernTitle><ng-container [ngTemplateOutlet]=\"headingContent\" /></h2>\n }\n @case ('3') {\n <h3 kernTitle><ng-container [ngTemplateOutlet]=\"headingContent\" /></h3>\n }\n @case ('4') {\n <h4 kernTitle><ng-container [ngTemplateOutlet]=\"headingContent\" /></h4>\n }\n @case ('5') {\n <h5 kernTitle><ng-container [ngTemplateOutlet]=\"headingContent\" /></h5>\n }\n }\n }\n @if (subline()) {\n @switch (headingLevel()) {\n @case ('1') {\n <h2 kernSubline>{{ subline() }}</h2>\n }\n @case ('2') {\n <h3 kernSubline>{{ subline() }}</h3>\n }\n @case ('3') {\n <h4 kernSubline>{{ subline() }}</h4>\n }\n @case ('4') {\n <h5 kernSubline>{{ subline() }}</h5>\n }\n @case ('5') {\n <h6 kernSubline>{{ subline() }}</h6>\n }\n }\n }\n </header>\n }\n <section class=\"kern-card__body\">\n <ng-content />\n </section>\n @if (btnPrimaryLabelText() || btnSecondaryLabelText()) {\n <footer class=\"kern-card__footer\">\n @if (btnPrimaryLabelText()) {\n <kern-button (clickEvent)=\"btnPrimaryClickEvent.emit($event)\">\n {{ btnPrimaryLabelText() }}\n </kern-button>\n }\n @if (btnSecondaryLabelText()) {\n <kern-button variant=\"secondary\" (clickEvent)=\"btnSecondaryClickEvent.emit($event)\">\n {{ btnSecondaryLabelText() }}\n </kern-button>\n }\n </footer>\n }\n </div>\n</article>\n","import { Component, input } from '@angular/core';\n\n@Component({\n selector: 'kern-divider',\n templateUrl: './kern-divider.html'\n})\nexport class KernDivider {\n readonly ariaHidden = input<boolean>(true);\n}\n","<hr class=\"kern-divider\" [attr.aria-hidden]=\"ariaHidden()\" />\n","import { Component, input, output } from '@angular/core';\nimport { KernIcon } from '../kern-icon/kern-icon';\n\n@Component({\n selector: 'kern-link',\n templateUrl: './kern-link.html',\n imports: [KernIcon],\n styles: ':host { display: contents; }'\n})\nexport class KernLink {\n readonly href = input<string | null>(null);\n readonly target = input<'_self' | '_blank' | '_parent' | '_top'>('_self');\n readonly small = input<boolean>(false);\n readonly stretched = input<boolean>(false);\n readonly iconLeft = input<string | null>(null);\n readonly iconRight = input<string | null>(null);\n readonly linkDescribedBy = input<string | null>(null);\n\n readonly clickEvent = output<Event>();\n}\n","<a\n class=\"kern-link\"\n [class.kern-link--small]=\"small()\"\n [class.kern-link--stretched]=\"stretched()\"\n [href]=\"href()\"\n [target]=\"target()\"\n [attr.rel]=\"target() === '_blank' ? 'noopener noreferrer' : null\"\n [attr.aria-describedby]=\"linkDescribedBy() || null\"\n (click)=\"clickEvent.emit($event)\"\n>\n @if (iconLeft()) {\n <kern-icon [name]=\"iconLeft()!\"></kern-icon>\n }\n <ng-content />\n @if (iconRight()) {\n <kern-icon [name]=\"iconRight()!\"></kern-icon>\n }\n</a>\n","import { Component, computed, inject, input } from '@angular/core';\nimport { KernLabel } from '../../directives/typography/kern-label/kern-label';\nimport { UniqueIdService } from '../../services/unique-id';\n\n@Component({\n selector: 'kern-progress',\n imports: [KernLabel],\n host: { class: 'kern-progress' },\n templateUrl: './kern-progress.html'\n})\nexport class KernProgress {\n readonly progressId = input<string>();\n readonly value = input.required<number>();\n readonly max = input<number>(100);\n readonly label = input<string | null>(null);\n readonly labelPosition = input<'top' | 'bottom'>('top');\n\n private readonly generatedId =\n inject(UniqueIdService).getUniqueId('progress');\n\n protected readonly effectiveId = computed(\n () => this.progressId() ?? this.generatedId\n );\n}\n","@if (label() && labelPosition() === 'top') {\n <label kernLabel [for]=\"effectiveId()\">{{ label() }}</label>\n}\n<progress [value]=\"value()\" [max]=\"max()\" [id]=\"effectiveId()\"></progress>\n@if (label() && labelPosition() === 'bottom') {\n <label kernLabel [for]=\"effectiveId()\">{{ label() }}</label>\n}\n","import { Component, input } from '@angular/core';\n\n@Component({\n selector: 'kern-container',\n host: {\n '[class.kern-container]': '!fluid()',\n '[class.kern-container-fluid]': 'fluid()'\n },\n template: '<ng-content />',\n styles: ':host { display: block; }'\n})\nexport class KernContainer {\n readonly fluid = input<boolean>(false);\n}\n","import { Component, input } from '@angular/core';\nimport { KernContainer } from '../grid/kern-container/kern-container';\n\n@Component({\n selector: 'kern-kopfzeile',\n imports: [KernContainer],\n host: { class: 'kern-kopfzeile' },\n templateUrl: './kern-kopfzeile.html',\n styles: ':host { display: block; }'\n})\nexport class KernKopfzeile {\n readonly fluid = input<boolean>(false);\n}\n","<kern-container [fluid]=\"fluid()\">\n <div class=\"kern-kopfzeile__content\">\n <span class=\"kern-kopfzeile__flagge\" aria-hidden=\"true\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 16\">\n <path fill=\"#000\" d=\"M0 .5h24v5.333H0z\" />\n <path fill=\"red\" d=\"M0 5.833h24v5.333H0z\" />\n <path fill=\"#FACA2C\" d=\"M0 11.167h24V16.5H0z\" />\n </svg>\n </span>\n <span class=\"kern-kopfzeile__label\" i18n=\"@@kernAngularKit.kopfzeile.label\">\n Offizielle Website – Bundesrepublik Deutschland\n </span>\n </div>\n</kern-container>\n","import {\n Component,\n input,\n computed,\n ElementRef,\n Renderer2,\n AfterViewInit,\n inject\n} from '@angular/core';\n\n@Component({\n selector: 'kern-heading',\n template: `<ng-content />`,\n styles: ':host { display: contents; }'\n})\nexport class KernHeading implements AfterViewInit {\n private readonly elementRef = inject(ElementRef);\n private readonly renderer = inject(Renderer2);\n\n readonly level = input<'1' | '2' | '3' | '4' | '5' | '6'>('1');\n readonly size = input<\n 'display' | 'x-large' | 'large' | 'medium' | 'small' | undefined\n >(undefined);\n\n // Compute the CSS class based on level (with default size mapping) and optional size override\n private readonly cssClass = computed(() => {\n const sizeOverride = this.size();\n const effectiveSize =\n sizeOverride || this.getDefaultSizeForLevel(this.level());\n\n // Map to actual CSS classes available for kern-heading\n if (effectiveSize === 'display') {\n return 'kern-heading-display';\n } else if (effectiveSize === 'x-large') {\n return 'kern-heading-x-large';\n } else if (effectiveSize === 'large') {\n return 'kern-heading-large';\n } else if (effectiveSize === 'medium') {\n return 'kern-heading-medium';\n } else if (effectiveSize === 'small') {\n return 'kern-heading-small';\n } else {\n // Default case\n return 'kern-heading-medium';\n }\n });\n\n ngAfterViewInit() {\n const hostElement = this.elementRef.nativeElement;\n const level = this.level();\n\n // Create the appropriate heading element\n const headingElement = this.renderer.createElement(`h${level}`);\n\n // Add CSS class\n this.renderer.addClass(headingElement, this.cssClass());\n\n // Move all child nodes (including ng-content) to the heading element\n while (hostElement.firstChild) {\n this.renderer.appendChild(headingElement, hostElement.firstChild);\n }\n\n // Add the heading element to the host\n this.renderer.appendChild(hostElement, headingElement);\n }\n\n // Map HTML heading levels to default KERN heading sizes\n private getDefaultSizeForLevel(level: string): string {\n const levelToSizeMap: Record<string, string> = {\n '1': 'display', // h1 -> kern-heading-display (largest)\n '2': 'x-large', // h2 -> kern-heading-x-large\n '3': 'large', // h3 -> kern-heading-large\n '4': 'medium', // h4 -> kern-heading-medium\n '5': 'small', // h5 -> kern-heading-small\n '6': 'small' // h6 -> kern-heading-small (smallest available)\n };\n return levelToSizeMap[level] || 'medium';\n }\n}\n","import { Directive, input } from '@angular/core';\n\n@Directive({\n host: {\n class: 'kern-body',\n '[class.kern-body--small]': 'size() === \"small\"',\n '[class.kern-body--large]': 'size() === \"large\"',\n '[class.kern-body--bold]': 'weight() === \"bold\"',\n '[class.kern-body--muted]': 'weight() === \"muted\"'\n },\n selector: 'p[kernBody], span[kernBody]',\n standalone: true\n})\nexport class KernBody {\n readonly size = input<'default' | 'small' | 'large'>('default');\n readonly weight = input<'default' | 'bold' | 'muted'>('default');\n}\n","import { Directive, input } from '@angular/core';\n\n@Directive({\n host: {\n class: 'kern-list',\n '[class.kern-list--small]': 'size() === \"small\"',\n '[class.kern-list--large]': 'size() === \"large\"',\n '[class.kern-list--bullet]': 'type() === \"bullet\"',\n '[class.kern-list--number]': 'type() === \"number\"'\n },\n selector: 'ul[kernList], ol[kernList]',\n standalone: true\n})\nexport class KernList {\n readonly size = input<'default' | 'small' | 'large'>('default');\n readonly type = input<'simple' | 'bullet' | 'number'>('simple');\n}\n","import { Directive, forwardRef, signal } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\n@Directive({\n selector: '[kernControlValueAccessor]',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => ControlValueAccessorDirective),\n multi: true\n }\n ]\n})\nexport class ControlValueAccessorDirective<TValue = unknown>\n implements ControlValueAccessor\n{\n value = signal<TValue>(null as TValue);\n disabled = signal(false);\n\n onChange: (value: TValue) => void = (_value: TValue) => {};\n onTouched: () => void = () => {};\n\n changeValue(value: TValue): void {\n this.value.set(value);\n this.onChange(value);\n }\n\n markTouched() {\n this.onTouched();\n }\n\n writeValue(value: TValue) {\n this.value.set(value);\n }\n\n registerOnChange(onChange: (value: TValue) => void) {\n this.onChange = onChange;\n }\n\n registerOnTouched(onTouched: () => void) {\n this.onTouched = onTouched;\n }\n\n setDisabledState?(isDisabled: boolean) {\n this.disabled.set(isDisabled);\n }\n}\n","import { Component, computed, inject, input, TemplateRef } from '@angular/core';\nimport { UniqueIdService } from '../../../services/unique-id';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ControlValueAccessorDirective } from '../../../utils/control-value-accessor.directive';\nimport { KernLabel } from '../../../directives/typography/kern-label/kern-label';\n\n@Component({\n selector: 'kern-input-checkbox',\n imports: [NgTemplateOutlet, KernLabel],\n templateUrl: './kern-input-checkbox.html',\n hostDirectives: [ControlValueAccessorDirective]\n})\nexport class KernInputCheckbox {\n protected readonly cva = inject(ControlValueAccessorDirective);\n\n readonly inputId = input<string>();\n readonly labelTemplate = input<TemplateRef<unknown> | null>(null);\n readonly labelText = input<string | null>(null);\n readonly error = input<boolean>(false);\n readonly titleText = input<string | null>(null);\n\n private readonly generatedId =\n inject(UniqueIdService).getUniqueId('input-checkbox');\n\n protected readonly effectiveId = computed(\n () => this.inputId() ?? this.generatedId\n );\n\n protected onChange(event: Event) {\n const { checked } = event.target as HTMLInputElement;\n this.cva.changeValue(checked);\n }\n}\n","<div class=\"kern-form-check\">\n <input\n [id]=\"effectiveId()\"\n [name]=\"effectiveId()\"\n type=\"checkbox\"\n class=\"kern-form-check__checkbox\"\n [class.kern-form-check__checkbox--error]=\"error()\"\n [disabled]=\"cva.disabled()\"\n [checked]=\"cva.value()\"\n (change)=\"onChange($event)\"\n [attr.title]=\"titleText()\"\n [attr.aria-labelledby]=\"effectiveId() + '-label'\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n />\n\n <label kernLabel [id]=\"effectiveId() + '-label'\" [for]=\"effectiveId()\">\n @if (labelTemplate() !== null) {\n <ng-container [ngTemplateOutlet]=\"labelTemplate()\" />\n } @else {\n {{ labelText() ?? '' }}\n }\n </label>\n</div>\n","import { Component, input } from '@angular/core';\nimport { KernIcon } from '../../kern-icon/kern-icon';\nimport { KernBody } from '../../../directives/typography/kern-body/kern-body';\n\n@Component({\n selector: 'kern-input-error',\n imports: [KernIcon, KernBody],\n template: `<p class=\"kern-error\" [id]=\"effectiveId() + '-error'\" role=\"alert\">\n <kern-icon name=\"danger\" />\n <span kernBody>{{ text() }}</span>\n </p>`,\n styles: ':host { display: contents; }'\n})\nexport class KernInputError {\n effectiveId = input.required<string>();\n text = input.required<string>();\n}\n","import { Component, input, TemplateRef } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\n\n@Component({\n selector: 'kern-input-hint',\n imports: [NgTemplateOutlet],\n host: { class: 'kern-hint' },\n template: `@if (hint().template; as templateRef) {\n <ng-container [ngTemplateOutlet]=\"templateRef\" />\n } @else {\n {{ hint().text }}\n }`\n})\nexport class KernInputHint {\n readonly hint = input.required<\n { template: TemplateRef<unknown> | null; text: string },\n TemplateRef<unknown> | string\n >({\n transform: (value: TemplateRef<unknown> | string) => {\n return {\n template: value instanceof TemplateRef ? value : null,\n text: typeof value === 'string' ? value : ''\n };\n }\n });\n}\n","import { Component, computed, inject, input, TemplateRef } from '@angular/core';\nimport { UniqueIdService } from '../../../services/unique-id';\nimport { KernInputError } from '../kern-input-error/kern-input-error';\nimport { KernInputHint } from '../kern-input-hint/kern-input-hint';\nimport { KernLabel } from '../../../directives/typography/kern-label/kern-label';\n\n@Component({\n selector: 'kern-fieldset',\n templateUrl: './kern-fieldset.html',\n imports: [KernLabel, KernInputError, KernInputHint]\n})\nexport class KernFieldset {\n readonly fieldsetId = input<string>();\n readonly legendText = input.required<string>();\n readonly legendSize = input<'default' | 'small' | 'large'>('large');\n readonly optional = input<boolean>(false);\n readonly disabled = input<boolean>(false);\n readonly hintTemplate = input<TemplateRef<unknown> | null>(null);\n readonly hintText = input<string | null>(null);\n readonly errorText = input<string | null>(null);\n readonly horizontalAlignment = input<boolean>(false);\n\n private readonly generatedId =\n inject(UniqueIdService).getUniqueId('fieldset');\n\n protected readonly effectiveId = computed(\n () => this.fieldsetId() ?? this.generatedId\n );\n\n protected readonly fieldsetDescribedBy = computed(() => {\n return this.hintTemplate() !== null || this.hintText()\n ? this.effectiveId() + '-hint'\n : null;\n });\n}\n","<fieldset\n class=\"kern-fieldset\"\n [class.kern-fieldset--error]=\"errorText()\"\n [attr.aria-describedby]=\"fieldsetDescribedBy()\"\n [id]=\"effectiveId()\"\n>\n <legend kernLabel [size]=\"legendSize()\" [optional]=\"optional()\">\n {{ legendText() }}\n </legend>\n\n @if (hintTemplate() || hintText(); as hint) {\n <kern-input-hint [hint]=\"hint\" />\n }\n\n <div class=\"kern-fieldset__body\" [class.kern-fieldset__body--horizontal]=\"horizontalAlignment()\">\n <ng-content />\n </div>\n\n @if (errorText(); as errorText) {\n <kern-input-error [effectiveId]=\"effectiveId()\" [text]=\"errorText\" />\n }\n</fieldset>\n","import {\n AfterViewInit,\n Component,\n ElementRef,\n forwardRef,\n viewChild,\n input,\n inject,\n computed,\n TemplateRef\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n FormsModule,\n NG_VALUE_ACCESSOR\n} from '@angular/forms';\nimport { UniqueIdService } from '../../../services/unique-id';\nimport { KernLabel } from '../../../directives/typography/kern-label/kern-label';\nimport { KernFieldset } from '../kern-fieldset/kern-fieldset';\n\ntype DatePart = 'day' | 'month' | 'year';\n\n@Component({\n selector: 'kern-input-date',\n imports: [FormsModule, KernLabel, KernFieldset],\n templateUrl: './kern-input-date.html',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n multi: true,\n useExisting: forwardRef(() => KernInputDate)\n }\n ]\n})\nexport class KernInputDate implements ControlValueAccessor, AfterViewInit {\n readonly fieldsetId = input<string>();\n readonly labelText = input.required<string>();\n readonly optional = input<boolean>(false);\n readonly readonly = input<boolean>(false);\n readonly hintTemplate = input<TemplateRef<unknown> | null>(null);\n readonly hintText = input<string | null>(null);\n readonly errorText = input<string | null>(null);\n\n private readonly generatedId =\n inject(UniqueIdService).getUniqueId('fieldset-date');\n\n protected readonly effectiveId = computed(\n () => this.fieldsetId() ?? this.generatedId\n );\n\n protected readonly inputDescribedBy = computed(() => {\n return this.errorText() ? this.effectiveId() + '-error' : null;\n });\n\n private readonly dayInput =\n viewChild.required<ElementRef<HTMLInputElement>>('dayInput');\n private readonly monthInput =\n viewChild.required<ElementRef<HTMLInputElement>>('monthInput');\n private readonly yearInput =\n viewChild.required<ElementRef<HTMLInputElement>>('yearInput');\n\n private day: number | null = null;\n private month: number | null = null;\n private year: number | null = null;\n\n onChange: (value: string | null) => void = (value: string | null) => {};\n onTouched: () => void = () => {};\n\n writeValue(value: string | null) {\n this.day = null;\n this.month = null;\n this.year = null;\n\n if (value !== null) {\n const [yearStr, monthStr, dayStr] = value.split('-');\n\n const day: number = parseInt(dayStr ?? '', 10);\n if (!isNaN(day) && day >= 1 && day <= 31) {\n this.day = day;\n }\n\n const month: number = parseInt(monthStr ?? '', 10);\n if (!isNaN(month) && month >= 1 && month <= 12) {\n this.month = month;\n }\n\n const year: number = parseInt(yearStr ?? '', 10);\n if (!isNaN(year) && year >= 1000 && year <= 9999) {\n this.year = year;\n }\n }\n\n this.renderValue();\n }\n\n ngAfterViewInit(): void {\n this.renderValue();\n }\n\n registerOnChange(fn: (value: string | null) => void) {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void) {\n this.onTouched = fn;\n }\n\n protected onKeydown(event: KeyboardEvent, type: DatePart) {\n if (!event.target || !(event.target instanceof HTMLInputElement)) {\n return;\n }\n\n if (event.code === 'Enter' || event.code === 'NumpadEnter') {\n this.onBlur(event, type);\n } else if (\n event.key === '.' ||\n event.key === '-' ||\n event.code === 'Space'\n ) {\n event.preventDefault();\n\n switch (type) {\n case 'day':\n this.monthInput().nativeElement.focus();\n break;\n case 'month':\n this.yearInput().nativeElement.focus();\n break;\n }\n }\n }\n\n protected onInput(event: Event, type: DatePart) {\n if (!event.target) {\n return;\n }\n\n const input = event.target as HTMLInputElement;\n input.value = input.value.replace(/\\D/g, '');\n const value: number = parseInt(input.value, 10);\n\n switch (type) {\n case 'day':\n if (isNaN(value) || value < 1 || value > 31) {\n this.day = null;\n } else {\n this.day = value;\n }\n break;\n case 'month':\n if (isNaN(value) || value < 1 || value > 12) {\n this.month = null;\n } else {\n this.month = value;\n }\n break;\n case 'year':\n if (isNaN(value) || value < 1000 || value > 9999) {\n this.year = null;\n } else {\n this.year = value;\n }\n break;\n }\n }\n\n private renderValue(): void {\n const dayInput = this.dayInput().nativeElement;\n const monthInput = this.monthInput().nativeElement;\n const yearInput = this.yearInput().nativeElement;\n\n if (!dayInput || !monthInput || !yearInput) {\n return;\n }\n\n if (this.day === null) {\n dayInput.value = '';\n } else {\n dayInput.value = this.day.toString().padStart(2, '0');\n }\n\n if (this.month === null) {\n monthInput.value = '';\n } else {\n monthInput.value = this.month.toString().padStart(2, '0');\n }\n\n if (this.year === null) {\n yearInput.value = '';\n } else {\n yearInput.value = this.year.toString();\n }\n }\n\n protected onBlur(event: Event, type: DatePart) {\n if (!event.target) {\n return;\n }\n\n this.onInput(event, type);\n\n this.renderValue();\n this.onChange(this.value);\n\n if (\n (this.day !== null && this.month !== null && this.year !== null) ||\n type === 'year'\n ) {\n this.onTouched();\n }\n }\n\n public get value(): string | null {\n if (this.day === null || this.month === null || this.year === null) {\n return null;\n }\n\n return (\n this.year.toString() +\n '-' +\n this.month.toString().padStart(2, '0') +\n '-' +\n this.day.toString().padStart(2, '0')\n );\n }\n\n protected onPaste(event: ClipboardEvent) {\n if (!event.clipboardData) {\n return;\n }\n\n const pasted = event.clipboardData.getData('text').trim();\n\n const match = /^(\\d{1,2})\\.(\\d{1,2})\\.(\\d{4})$/.exec(pasted);\n if (match) {\n event.preventDefault();\n\n const [, dayStr, monthStr, yearStr] = match;\n\n const day = parseInt(dayStr, 10);\n const month = parseInt(monthStr, 10);\n const year = parseInt(yearStr, 10);\n\n if (\n day >= 1 &&\n day <= 31 &&\n month >= 1 &&\n month <= 12 &&\n year >= 1000 &&\n year <= 9999\n ) {\n this.day = day;\n this.month = month;\n this.year = year;\n\n this.renderValue();\n this.onChange(this.value);\n this.onTouched();\n }\n }\n }\n}\n","<kern-fieldset\n [fieldsetId]=\"effectiveId()\"\n [legendText]=\"labelText()\"\n legendSize=\"default\"\n [optional]=\"optional()\"\n [hintText]=\"hintText()\"\n [hintTemplate]=\"hintTemplate()\"\n [errorText]=\"errorText()\"\n [horizontalAlignment]=\"true\"\n>\n <div class=\"kern-form-input\">\n <label kernLabel [for]=\"effectiveId() + '-day'\" [id]=\"effectiveId() + '-day-label'\">\n <span i18n=\"@@kernAngularKit.inputDate.day\">Tag</span>\n </label>\n\n <input\n #dayInput\n [id]=\"effectiveId() + '-day'\"\n class=\"kern-form-input__input kern-form-input__input--width-2\"\n [class.kern-form-input__input--error]=\"errorText()\"\n type=\"text\"\n inputmode=\"numeric\"\n [readonly]=\"readonly()\"\n [attr.aria-describedby]=\"inputDescribedBy()\"\n [attr.aria-invalid]=\"errorText() ? 'true' : null\"\n [attr.aria-errormessage]=\"errorText() ? effectiveId() + '-error' : null\"\n maxlength=\"2\"\n (input)=\"onInput($event, 'day')\"\n (paste)=\"onPaste($event)\"\n (change)=\"onInput($event, 'day')\"\n (keydown)=\"onKeydown($event, 'day')\"\n (blur)=\"onBlur($event, 'day')\"\n />\n </div>\n <div class=\"kern-form-input\">\n <label kernLabel [for]=\"effectiveId() + '-month'\" [id]=\"effectiveId() + '-month-label'\">\n <span i18n=\"@@kernAngularKit.inputDate.month\">Monat</span>\n </label>\n <input\n #monthInput\n [id]=\"effectiveId() + '-month'\"\n class=\"kern-form-input__input kern-form-input__input--width-2\"\n [class.kern-form-input__input--error]=\"errorText()\"\n type=\"text\"\n inputmode=\"numeric\"\n [readonly]=\"readonly()\"\n [attr.aria-describedby]=\"inputDescribedBy()\"\n [attr.aria-invalid]=\"errorText() ? 'true' : null\"\n [attr.aria-errormessage]=\"errorText() ? effectiveId() + '-error' : null\"\n maxlength=\"2\"\n (input)=\"onInput($event, 'month')\"\n (paste)=\"onPaste($event)\"\n (change)=\"onInput($event, 'month')\"\n (keydown)=\"onKeydown($event, 'month')\"\n (blur)=\"onBlur($event, 'month')\"\n />\n </div>\n <div class=\"kern-form-input\">\n <label kernLabel [for]=\"effectiveId() + '-year'\" [id]=\"effectiveId() + '-year-label'\">\n <span i18n=\"@@kernAngularKit.inputDate.year\">Jahr</span>\n </label>\n <input\n #yearInput\n [id]=\"effectiveId() + '-year'\"\n class=\"kern-form-input__input kern-form-input__input--width-4\"\n [class.kern-form-input__input--error]=\"errorText()\"\n type=\"text\"\n inputmode=\"numeric\"\n [readonly]=\"readonly()\"\n [attr.aria-describedby]=\"inputDescribedBy()\"\n [attr.aria-invalid]=\"errorText() ? 'true' : null\"\n [attr.aria-errormessage]=\"errorText() ? effectiveId() + '-error' : null\"\n maxlength=\"4\"\n (input)=\"onInput($event, 'year')\"\n (paste)=\"onPaste($event)\"\n (change)=\"onInput($event, 'year')\"\n (keydown)=\"onKeydown($event, 'year')\"\n (blur)=\"onBlur($event, 'year')\"\n />\n </div>\n</kern-fieldset>\n","import { Component, computed, inject, input, TemplateRef } from '@angular/core';\nimport { UniqueIdService } from '../../../services/unique-id';\nimport { KernInputError } from '../kern-input-error/kern-input-error';\nimport { KernInputHint } from '../kern-input-hint/kern-input-hint';\nimport { ControlValueAccessorDirective } from '../../../utils/control-value-accessor.directive';\nimport { KernLabel } from '../../../directives/typography/kern-label/kern-label';\n\n@Component({\n selector: 'kern-input-email',\n imports: [KernInputError, KernLabel, KernInputHint],\n templateUrl: './kern-input-email.html',\n hostDirectives: [ControlValueAccessorDirective]\n})\nexport class KernInputEmail {\n protected readonly cva = inject(ControlValueAccessorDirective);\n\n readonly inputId = input<string>();\n readonly labelText = input.required<string>();\n readonly optional = input<boolean>(false);\n readonly readonly = input<boolean>(false);\n readonly required = input<boolean>(false);\n readonly maxlength = input<number | null>(null);\n readonly hintTemplate = input<TemplateRef<unknown> | null>(null);\n readonly hintText = input<string | null>(null);\n readonly errorText = input<string | null>(null);\n readonly titleText = input<string | null>(null);\n readonly placeholder = input<string | null>(null);\n\n private readonly generatedId =\n inject(UniqueIdService).getUniqueId('input-email');\n\n protected readonly effectiveId = computed(\n () => this.inputId() ?? this.generatedId\n );\n\n protected readonly inputDescribedBy = computed(() => {\n const baseId = this.effectiveId();\n const ids: string[] = [];\n\n if (this.hintTemplate() !== null || this.hintText()) {\n ids.push(`${baseId}-hint`);\n }\n if (this.errorText()) {\n ids.push(`${baseId}-error`);\n }\n\n return ids.length ? ids.join(' ') : null;\n });\n\n protected onKeydown(event: KeyboardEvent) {\n if (\n event.target &&\n event.target instanceof HTMLInputElement &&\n (event.code === 'Enter' || event.code === 'NumpadEnter')\n ) {\n this.cva.markTouched();\n }\n }\n}\n","<div class=\"kern-form-input\" [class.kern-form-input--error]=\"errorText()\">\n <label kernLabel [for]=\"effectiveId()\" [id]=\"effectiveId() + '-label'\" [optional]=\"optional()\">\n {{ labelText() }}\n </label>\n\n @if (hintTemplate() || hintText(); as hint) {\n <kern-input-hint [hint]=\"hint\" />\n }\n\n <input\n [attr.title]=\"titleText()\"\n [attr.placeholder]=\"placeholder()\"\n [id]=\"effectiveId()\"\n type=\"email\"\n class=\"kern-form-input__input\"\n [class.kern-form-input__input--error]=\"errorText()\"\n [value]=\"cva.value()\"\n [disabled]=\"cva.disabled()\"\n (blur)=\"cva.markTouched()\"\n (keydown)=\"onKeydown($event)\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n autocomplete=\"email\"\n [attr.aria-describedby]=\"inputDescribedBy()\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.ari