@helsevestikt/hviktor-angular 0.0.17 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Input, Component, Directive, booleanAttribute, CUSTOM_ELEMENTS_SCHEMA, EventEmitter, inject, ElementRef, HostListener, Output, ViewChild, DestroyRef, signal, input, computed, HostBinding, ChangeDetectorRef, ViewEncapsulation, numberAttribute, ContentChildren, forwardRef, Renderer2 } from '@angular/core';
2
+ import { Input, Component, Directive, booleanAttribute, CUSTOM_ELEMENTS_SCHEMA, EventEmitter, inject, ElementRef, HostListener, Output, signal, computed, input, HostBinding, numberAttribute, ViewChild, ContentChildren, forwardRef } from '@angular/core';
3
3
  import '@u-elements/u-details';
4
- import { computePosition, offset, flip, shift, autoUpdate } from '@floating-ui/dom';
5
- import { FormGroupDirective, NgControl, ControlContainer, Validators, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
6
- import { HttpClient } from '@angular/common/http';
4
+ import '@digdir/designsystemet-web';
5
+ import { Validators, FormGroupDirective, NgControl, ControlContainer, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
7
6
  import '@u-elements/u-tabs';
8
7
  import { NgTemplateOutlet } from '@angular/common';
9
8
 
@@ -24,10 +23,10 @@ import { NgTemplateOutlet } from '@angular/common';
24
23
  class HviAlert {
25
24
  /** Sets the type of alert by changing the color and */
26
25
  color;
27
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviAlert, deps: [], target: i0.ɵɵFactoryTarget.Component });
28
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviAlert, isStandalone: true, selector: "hvi-alert", inputs: { color: "color" }, host: { properties: { "attr.data-color": "color" }, classAttribute: "ds-alert" }, ngImport: i0, template: `<ng-content />`, isInline: true });
26
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviAlert, deps: [], target: i0.ɵɵFactoryTarget.Component });
27
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviAlert, isStandalone: true, selector: "hvi-alert", inputs: { color: "color" }, host: { properties: { "attr.data-color": "color" }, classAttribute: "ds-alert" }, ngImport: i0, template: `<ng-content />`, isInline: true });
29
28
  }
30
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviAlert, decorators: [{
29
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviAlert, decorators: [{
31
30
  type: Component,
32
31
  args: [{
33
32
  selector: 'hvi-alert',
@@ -69,10 +68,10 @@ class HviAvatar {
69
68
  size;
70
69
  /** The color theme of the avatar */
71
70
  color;
72
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviAvatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
73
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviAvatar, isStandalone: true, selector: "hvi-avatar", inputs: { ariaLabel: "ariaLabel", variant: "variant", initials: "initials", size: "size", color: "color" }, host: { attributes: { "role": "img" }, properties: { "attr.aria-label": "ariaLabel ?? null", "attr.data-variant": "variant ?? null", "attr.data-initials": "initials ?? null", "attr.data-size": "size ?? null", "attr.data-color": "color ?? null" }, classAttribute: "ds-avatar" }, ngImport: i0, template: '<ng-content />', isInline: true });
71
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviAvatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
72
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviAvatar, isStandalone: true, selector: "hvi-avatar", inputs: { ariaLabel: "ariaLabel", variant: "variant", initials: "initials", size: "size", color: "color" }, host: { attributes: { "role": "img" }, properties: { "attr.aria-label": "ariaLabel ?? null", "attr.data-variant": "variant ?? null", "attr.data-initials": "initials ?? null", "attr.data-size": "size ?? null", "attr.data-color": "color ?? null" }, classAttribute: "ds-avatar" }, ngImport: i0, template: '<ng-content />', isInline: true });
74
73
  }
75
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviAvatar, decorators: [{
74
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviAvatar, decorators: [{
76
75
  type: Component,
77
76
  args: [{
78
77
  selector: 'hvi-avatar',
@@ -118,10 +117,10 @@ class HviAvatarStack {
118
117
  expandable;
119
118
  suffix;
120
119
  gap;
121
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviAvatarStack, deps: [], target: i0.ɵɵFactoryTarget.Directive });
122
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviAvatarStack, isStandalone: true, selector: "figure[hviAvatarStack]", inputs: { variant: "variant", expandable: "expandable", suffix: "suffix", gap: "gap" }, host: { properties: { "attr.data-variant": "variant", "attr.data-expandable": "expandable", "attr.data-suffix": "suffix", "attr.data-avatar-stack-gap": "gap" }, classAttribute: "ds-avatar-stack" }, ngImport: i0 });
120
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviAvatarStack, deps: [], target: i0.ɵɵFactoryTarget.Directive });
121
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviAvatarStack, isStandalone: true, selector: "figure[hviAvatarStack]", inputs: { variant: "variant", expandable: "expandable", suffix: "suffix", gap: "gap" }, host: { properties: { "attr.data-variant": "variant", "attr.data-expandable": "expandable", "attr.data-suffix": "suffix", "attr.data-avatar-stack-gap": "gap" }, classAttribute: "ds-avatar-stack" }, ngImport: i0 });
123
122
  }
124
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviAvatarStack, decorators: [{
123
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviAvatarStack, decorators: [{
125
124
  type: Directive,
126
125
  args: [{
127
126
  selector: 'figure[hviAvatarStack]',
@@ -149,10 +148,10 @@ class HviBadgePosition {
149
148
  overlap = 'rectangle';
150
149
  /** Placement of the badge */
151
150
  placement = 'top-right';
152
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviBadgePosition, deps: [], target: i0.ɵɵFactoryTarget.Component });
153
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviBadgePosition, isStandalone: true, selector: "hvi-badge-position", inputs: { overlap: "overlap", placement: "placement" }, host: { properties: { "attr.data-overlap": "overlap", "attr.data-placement": "placement" }, classAttribute: "ds-badge--position" }, ngImport: i0, template: '<ng-content />', isInline: true });
151
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviBadgePosition, deps: [], target: i0.ɵɵFactoryTarget.Component });
152
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviBadgePosition, isStandalone: true, selector: "hvi-badge-position", inputs: { overlap: "overlap", placement: "placement" }, host: { properties: { "attr.data-overlap": "overlap", "attr.data-placement": "placement" }, classAttribute: "ds-badge--position" }, ngImport: i0, template: '<ng-content />', isInline: true });
154
153
  }
155
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviBadgePosition, decorators: [{
154
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviBadgePosition, decorators: [{
156
155
  type: Component,
157
156
  args: [{
158
157
  selector: 'hvi-badge-position',
@@ -177,10 +176,10 @@ class HviBadge {
177
176
  count;
178
177
  /** The color theme of the badge */
179
178
  color;
180
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviBadge, deps: [], target: i0.ɵɵFactoryTarget.Component });
181
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviBadge, isStandalone: true, selector: "hvi-badge", inputs: { variant: "variant", count: "count", color: "color" }, host: { properties: { "attr.data-variant": "variant ?? null", "attr.data-count": "count ?? null", "attr.data-color": "color ?? null" }, classAttribute: "ds-badge" }, ngImport: i0, template: '<ng-content />', isInline: true });
179
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviBadge, deps: [], target: i0.ɵɵFactoryTarget.Component });
180
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviBadge, isStandalone: true, selector: "hvi-badge", inputs: { variant: "variant", count: "count", color: "color" }, host: { properties: { "attr.data-variant": "variant ?? null", "attr.data-count": "count ?? null", "attr.data-color": "color ?? null" }, classAttribute: "ds-badge" }, ngImport: i0, template: '<ng-content />', isInline: true });
182
181
  }
183
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviBadge, decorators: [{
182
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviBadge, decorators: [{
184
183
  type: Component,
185
184
  args: [{
186
185
  selector: 'hvi-badge',
@@ -231,8 +230,8 @@ class HviBreadcrumbs {
231
230
  backLink;
232
231
  /** Array of breadcrumb items */
233
232
  items = [];
234
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviBreadcrumbs, deps: [], target: i0.ɵɵFactoryTarget.Component });
235
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: HviBreadcrumbs, isStandalone: true, selector: "nav[hviBreadcrumbs]", inputs: { ariaLabel: "ariaLabel", backLink: "backLink", items: "items" }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "ariaLabel ?? null" }, classAttribute: "ds-breadcrumbs" }, ngImport: i0, template: `
233
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviBreadcrumbs, deps: [], target: i0.ɵɵFactoryTarget.Component });
234
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: HviBreadcrumbs, isStandalone: true, selector: "nav[hviBreadcrumbs]", inputs: { ariaLabel: "ariaLabel", backLink: "backLink", items: "items" }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "ariaLabel ?? null" }, classAttribute: "ds-breadcrumbs" }, ngImport: i0, template: `
236
235
  <!-- Back link (optional) -->
237
236
  @if (backLink) {
238
237
  <a class="ds-link" [href]="backLink.href" [attr.aria-label]="backLink.ariaLabel ?? null">
@@ -256,7 +255,7 @@ class HviBreadcrumbs {
256
255
  </ol>
257
256
  `, isInline: true });
258
257
  }
259
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviBreadcrumbs, decorators: [{
258
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviBreadcrumbs, decorators: [{
260
259
  type: Component,
261
260
  args: [{
262
261
  selector: 'nav[hviBreadcrumbs]',
@@ -330,10 +329,10 @@ class HviButton {
330
329
  loading = false;
331
330
  /** Makes the button full width */
332
331
  fullWidth = false;
333
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviButton, deps: [], target: i0.ɵɵFactoryTarget.Directive });
334
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.1", type: HviButton, isStandalone: true, selector: "button[hviButton], a[hviButton]", inputs: { size: "size", variant: "variant", type: "type", color: "color", icon: ["icon", "icon", booleanAttribute], loading: ["loading", "loading", booleanAttribute], fullWidth: ["fullWidth", "fullWidth", booleanAttribute] }, host: { properties: { "attr.type": "type", "attr.data-size": "size", "attr.data-variant": "variant", "attr.data-color": "color", "attr.data-fullwidth": "fullWidth ? \"\" : null", "attr.data-icon": "icon ? \"\" : null", "attr.aria-busy": "loading ? \"true\" : null" }, classAttribute: "ds-button" }, ngImport: i0 });
332
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviButton, deps: [], target: i0.ɵɵFactoryTarget.Directive });
333
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.6", type: HviButton, isStandalone: true, selector: "button[hviButton], a[hviButton]", inputs: { size: "size", variant: "variant", type: "type", color: "color", icon: ["icon", "icon", booleanAttribute], loading: ["loading", "loading", booleanAttribute], fullWidth: ["fullWidth", "fullWidth", booleanAttribute] }, host: { properties: { "attr.type": "type", "attr.data-size": "size", "attr.data-variant": "variant", "attr.data-color": "color", "attr.data-fullwidth": "fullWidth ? \"\" : null", "attr.data-icon": "icon ? \"\" : null", "attr.aria-busy": "loading ? \"true\" : null" }, classAttribute: "ds-button" }, ngImport: i0 });
335
334
  }
336
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviButton, decorators: [{
335
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviButton, decorators: [{
337
336
  type: Directive,
338
337
  args: [{
339
338
  selector: 'button[hviButton], a[hviButton]',
@@ -385,10 +384,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
385
384
  * Documentation: https://designsystemet.no/en/components/docs/card/code#with-sections
386
385
  */
387
386
  class HviCardBlock {
388
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviCardBlock, deps: [], target: i0.ɵɵFactoryTarget.Directive });
389
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviCardBlock, isStandalone: true, selector: "[hviCardBlock]", host: { classAttribute: "ds-card__block" }, ngImport: i0 });
387
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviCardBlock, deps: [], target: i0.ɵɵFactoryTarget.Directive });
388
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviCardBlock, isStandalone: true, selector: "[hviCardBlock]", host: { classAttribute: "ds-card__block" }, ngImport: i0 });
390
389
  }
391
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviCardBlock, decorators: [{
390
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviCardBlock, decorators: [{
392
391
  type: Directive,
393
392
  args: [{
394
393
  selector: '[hviCardBlock]',
@@ -418,10 +417,10 @@ class HviCard {
418
417
  color;
419
418
  /** Maximum width of the card, for example '320px' or '20rem' */
420
419
  maxWidth;
421
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
422
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviCard, isStandalone: true, selector: "hvi-card", inputs: { variant: "variant", color: "color", maxWidth: "maxWidth" }, host: { properties: { "attr.data-variant": "variant", "attr.data-color": "color", "style.max-width": "maxWidth" }, classAttribute: "ds-card" }, ngImport: i0, template: '<ng-content />', isInline: true });
420
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
421
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviCard, isStandalone: true, selector: "hvi-card", inputs: { variant: "variant", color: "color", maxWidth: "maxWidth" }, host: { properties: { "attr.data-variant": "variant", "attr.data-color": "color", "style.max-width": "maxWidth" }, classAttribute: "ds-card" }, ngImport: i0, template: '<ng-content />', isInline: true });
423
422
  }
424
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviCard, decorators: [{
423
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviCard, decorators: [{
425
424
  type: Component,
426
425
  args: [{
427
426
  selector: 'hvi-card',
@@ -445,10 +444,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
445
444
  class HviChipButton {
446
445
  /** Whether the chip is removable*/
447
446
  removable = false;
448
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviChipButton, deps: [], target: i0.ɵɵFactoryTarget.Directive });
449
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.1", type: HviChipButton, isStandalone: true, selector: "button[hviChip]", inputs: { removable: ["removable", "removable", booleanAttribute] }, host: { properties: { "attr.data-removable": "removable ? \"true\" : null" }, classAttribute: "ds-chip" }, ngImport: i0 });
447
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviChipButton, deps: [], target: i0.ɵɵFactoryTarget.Directive });
448
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.6", type: HviChipButton, isStandalone: true, selector: "button[hviChip]", inputs: { removable: ["removable", "removable", booleanAttribute] }, host: { properties: { "attr.data-removable": "removable ? \"true\" : null" }, classAttribute: "ds-chip" }, ngImport: i0 });
450
449
  }
451
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviChipButton, decorators: [{
450
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviChipButton, decorators: [{
452
451
  type: Directive,
453
452
  args: [{
454
453
  selector: 'button[hviChip]',
@@ -464,10 +463,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
464
463
  }] } });
465
464
 
466
465
  class HviChipLabel {
467
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviChipLabel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
468
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviChipLabel, isStandalone: true, selector: "label[hviChip]", host: { classAttribute: "ds-chip" }, ngImport: i0 });
466
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviChipLabel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
467
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviChipLabel, isStandalone: true, selector: "label[hviChip]", host: { classAttribute: "ds-chip" }, ngImport: i0 });
469
468
  }
470
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviChipLabel, decorators: [{
469
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviChipLabel, decorators: [{
471
470
  type: Directive,
472
471
  args: [{
473
472
  selector: 'label[hviChip]',
@@ -479,10 +478,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
479
478
  }] });
480
479
 
481
480
  class HviDetailsContent {
482
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDetailsContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
483
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviDetailsContent, isStandalone: true, selector: "hvi-details-content", ngImport: i0, template: `<ng-content />`, isInline: true });
481
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDetailsContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
482
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviDetailsContent, isStandalone: true, selector: "hvi-details-content", ngImport: i0, template: `<ng-content />`, isInline: true });
484
483
  }
485
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDetailsContent, decorators: [{
484
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDetailsContent, decorators: [{
486
485
  type: Component,
487
486
  args: [{
488
487
  selector: 'hvi-details-content',
@@ -491,10 +490,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
491
490
  }] });
492
491
 
493
492
  class HviDetailsSummary {
494
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDetailsSummary, deps: [], target: i0.ɵɵFactoryTarget.Component });
495
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviDetailsSummary, isStandalone: true, selector: "hvi-details-summary", ngImport: i0, template: `<ng-content />`, isInline: true });
493
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDetailsSummary, deps: [], target: i0.ɵɵFactoryTarget.Component });
494
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviDetailsSummary, isStandalone: true, selector: "hvi-details-summary", ngImport: i0, template: `<ng-content />`, isInline: true });
496
495
  }
497
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDetailsSummary, decorators: [{
496
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDetailsSummary, decorators: [{
498
497
  type: Component,
499
498
  args: [{
500
499
  selector: 'hvi-details-summary',
@@ -531,8 +530,8 @@ class HviDetails {
531
530
  handleToggle(event) {
532
531
  console.log('Toggled!', event);
533
532
  }
534
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDetails, deps: [], target: i0.ɵɵFactoryTarget.Component });
535
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviDetails, isStandalone: true, selector: "hvi-details", inputs: { variant: "variant", open: "open", defaultOpen: "defaultOpen", onToggle: "onToggle" }, ngImport: i0, template: ` <u-details
533
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDetails, deps: [], target: i0.ɵɵFactoryTarget.Component });
534
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviDetails, isStandalone: true, selector: "hvi-details", inputs: { variant: "variant", open: "open", defaultOpen: "defaultOpen", onToggle: "onToggle" }, ngImport: i0, template: ` <u-details
536
535
  #detailsRef
537
536
  class="ds-details"
538
537
  [attr.data-variant]="variant"
@@ -548,7 +547,7 @@ class HviDetails {
548
547
  </div>
549
548
  </u-details>`, isInline: true });
550
549
  }
551
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDetails, decorators: [{
550
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDetails, decorators: [{
552
551
  type: Component,
553
552
  args: [{
554
553
  selector: 'hvi-details',
@@ -582,10 +581,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
582
581
  }] } });
583
582
 
584
583
  class HviDialogBlock {
585
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDialogBlock, deps: [], target: i0.ɵɵFactoryTarget.Directive });
586
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviDialogBlock, isStandalone: true, selector: "[hviDialogBlock]", host: { classAttribute: "ds-dialog__block" }, ngImport: i0 });
584
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDialogBlock, deps: [], target: i0.ɵɵFactoryTarget.Directive });
585
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviDialogBlock, isStandalone: true, selector: "[hviDialogBlock]", host: { classAttribute: "ds-dialog__block" }, ngImport: i0 });
587
586
  }
588
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDialogBlock, decorators: [{
587
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDialogBlock, decorators: [{
589
588
  type: Directive,
590
589
  args: [{
591
590
  selector: '[hviDialogBlock]',
@@ -669,10 +668,10 @@ class HviDialog {
669
668
  }
670
669
  this.element.close();
671
670
  }
672
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDialog, deps: [], target: i0.ɵɵFactoryTarget.Directive });
673
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviDialog, isStandalone: true, selector: "dialog[hviDialog]", inputs: { id: "id", open: "open", modal: "modal" }, outputs: { openChange: "openChange" }, host: { attributes: { "id": "{{ id }}" }, listeners: { "close": "handleClose()", "cancel": "handleCancel($event)" }, classAttribute: "ds-dialog" }, ngImport: i0 });
671
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDialog, deps: [], target: i0.ɵɵFactoryTarget.Directive });
672
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviDialog, isStandalone: true, selector: "dialog[hviDialog]", inputs: { id: "id", open: "open", modal: "modal" }, outputs: { openChange: "openChange" }, host: { attributes: { "id": "{{ id }}" }, listeners: { "close": "handleClose()", "cancel": "handleCancel($event)" }, classAttribute: "ds-dialog" }, ngImport: i0 });
674
673
  }
675
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDialog, decorators: [{
674
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDialog, decorators: [{
676
675
  type: Directive,
677
676
  args: [{
678
677
  selector: 'dialog[hviDialog]',
@@ -709,10 +708,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
709
708
  * Dokumentasjon: https://designsystemet.no/no/components/docs/divider/overview
710
709
  */
711
710
  class HviDivider {
712
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDivider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
713
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviDivider, isStandalone: true, selector: "hr[hviDivider]", host: { attributes: { "aria-hidden": "true" }, classAttribute: "ds-divider" }, ngImport: i0 });
711
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDivider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
712
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviDivider, isStandalone: true, selector: "hr[hviDivider]", host: { attributes: { "aria-hidden": "true" }, classAttribute: "ds-divider" }, ngImport: i0 });
714
713
  }
715
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDivider, decorators: [{
714
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDivider, decorators: [{
716
715
  type: Directive,
717
716
  args: [{
718
717
  selector: 'hr[hviDivider]',
@@ -726,12 +725,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
726
725
 
727
726
  /**
728
727
  * @summary
729
- * Dropdown er en generisk nedtrekksliste. Den legger grunnmuren for å bygge menyer og lister..
728
+ * Dropdown er en generisk nedtrekksliste. Den legger grunnmuren for å bygge menyer og lister.
730
729
  *
731
730
  * @example
732
731
  * ```html
733
- * <button hviButton popovertarget="myDropdown">Åpne dropdown</button
734
- * <hvi-dropdown id="myDropdown" popover>
732
+ * <button hviButton popovertarget="myDropdown">Åpne dropdown</button>
733
+ * <hvi-dropdown id="myDropdown">
735
734
  * <ul>
736
735
  * <li>
737
736
  * <button hviButton variant="tertiary">Menylenke</button>
@@ -746,128 +745,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
746
745
  * @see {@link https://designsystemet.no/en/components/docs/dropdown/code}
747
746
  */
748
747
  class HviDropdown {
749
- el = inject((ElementRef));
750
- cleanupAutoUpdate;
751
- boundHandleClick;
752
- boundHandleKeydown;
753
- /**ID to target the popover */
748
+ /** ID to target the popover */
754
749
  id;
755
- /** variant */
750
+ /** Popover type - 'auto' lukkes ved klikk utenfor, 'manual' krever manuell lukking */
751
+ type = 'auto';
752
+ /** Variant */
756
753
  variant;
757
- /** Plassering av popover relativt til trigger */
758
- dropdownPlacement = 'bottom-end';
754
+ /** Plassering av dropdown relativt til trigger */
755
+ dropdownPlacement = 'bottom';
759
756
  /** Aktiver automatisk repositjonering hvis det ikke er plass */
760
757
  autoPlacement = true;
761
- /** Event når popover åpnes */
758
+ /** Event når dropdown åpnes */
762
759
  opened = new EventEmitter();
763
- /** Event når popover lukkes */
760
+ /** Event når dropdown lukkes */
764
761
  closed = new EventEmitter();
765
- get dropdownElement() {
766
- return this.el.nativeElement;
767
- }
768
- get triggerElement() {
769
- const id = this.dropdownElement.id;
770
- return id ? document.querySelector(`[popovertarget="${id}"]`) : null;
771
- }
772
- ngOnInit() {
773
- this.setupEventListeners();
774
- }
775
- ngOnDestroy() {
776
- this.stopAutoUpdate();
777
- this.removeEventListeners();
778
- }
779
- setupEventListeners() {
780
- const dropdown = this.dropdownElement;
781
- // Click utenfor lukker popover
782
- this.boundHandleClick = (event) => {
783
- const el = event.target;
784
- const isTrigger = el?.closest?.(`[popovertarget="${dropdown.id}"]`);
785
- const isOutside = !isTrigger && !dropdown.contains(el);
786
- if (isTrigger) {
787
- event.preventDefault();
788
- dropdown.togglePopover?.();
789
- }
790
- if (isOutside && dropdown.matches(':popover-open')) {
791
- dropdown.togglePopover?.();
792
- }
793
- };
794
- // Escape lukker popover
795
- this.boundHandleKeydown = (event) => {
796
- if (event.key !== 'Escape' || !dropdown.matches(':popover-open'))
797
- return;
798
- event.preventDefault();
799
- dropdown.togglePopover?.();
800
- };
801
- addEventListener('click', this.boundHandleClick);
802
- addEventListener('keydown', this.boundHandleKeydown);
803
- // Toggle events
804
- dropdown.addEventListener('beforetoggle', this.handleBeforeToggle);
805
- dropdown.addEventListener('toggle', this.handleToggle);
806
- }
807
- removeEventListeners() {
808
- if (this.boundHandleClick) {
809
- removeEventListener('click', this.boundHandleClick);
810
- }
811
- if (this.boundHandleKeydown) {
812
- removeEventListener('keydown', this.boundHandleKeydown);
813
- }
814
- this.dropdownElement.removeEventListener('beforetoggle', this.handleBeforeToggle);
815
- this.dropdownElement.removeEventListener('toggle', this.handleToggle);
816
- }
817
- handleBeforeToggle = (event) => {
818
- const toggleEvent = event;
819
- if (toggleEvent.newState === 'open') {
820
- this.updatePosition();
821
- }
822
- };
823
- handleToggle = (event) => {
824
- const toggleEvent = event;
825
- if (toggleEvent.newState === 'open') {
826
- this.startAutoUpdate();
762
+ onToggle(event) {
763
+ if (event.newState === 'open') {
827
764
  this.opened.emit();
828
765
  }
829
766
  else {
830
- this.stopAutoUpdate();
831
767
  this.closed.emit();
832
768
  }
833
- };
834
- updatePosition() {
835
- const trigger = this.triggerElement;
836
- const dropdown = this.dropdownElement;
837
- if (!trigger || !dropdown)
838
- return;
839
- computePosition(trigger, dropdown, {
840
- placement: this.dropdownPlacement,
841
- strategy: 'fixed',
842
- middleware: [
843
- offset((data) => {
844
- const styles = getComputedStyle(data.elements.floating, '::before');
845
- return parseFloat(styles.height) || 12;
846
- }),
847
- ...(this.autoPlacement ? [flip({ fallbackAxisSideDirection: 'start' }), shift()] : []),
848
- ],
849
- }).then(({ x, y }) => {
850
- dropdown.style.translate = `${x}px ${y}px`;
851
- });
852
- }
853
- startAutoUpdate() {
854
- this.stopAutoUpdate();
855
- const trigger = this.triggerElement;
856
- const popover = this.dropdownElement;
857
- if (!trigger || !popover)
858
- return;
859
- this.cleanupAutoUpdate = autoUpdate(trigger, popover, () => this.updatePosition());
860
769
  }
861
- stopAutoUpdate() {
862
- if (this.cleanupAutoUpdate) {
863
- this.cleanupAutoUpdate();
864
- this.cleanupAutoUpdate = undefined;
865
- }
866
- }
867
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDropdown, deps: [], target: i0.ɵɵFactoryTarget.Component });
868
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviDropdown, isStandalone: true, selector: "hvi-dropdown", inputs: { id: "id", variant: "variant", dropdownPlacement: "dropdownPlacement", autoPlacement: "autoPlacement" }, outputs: { opened: "opened", closed: "closed" }, host: { properties: { "attr.data-id": "id", "attr.data-variant": "variant" }, classAttribute: "ds-popover ds-dropdown" }, ngImport: i0, template: '<ng-content />', isInline: true });
770
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDropdown, deps: [], target: i0.ɵɵFactoryTarget.Component });
771
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviDropdown, isStandalone: true, selector: "hvi-dropdown", inputs: { id: "id", type: "type", variant: "variant", dropdownPlacement: "dropdownPlacement", autoPlacement: "autoPlacement" }, outputs: { opened: "opened", closed: "closed" }, host: { listeners: { "toggle": "onToggle($event)" }, properties: { "id": "id", "attr.popover": "type", "attr.data-variant": "variant", "attr.data-placement": "dropdownPlacement", "attr.data-autoplacement": "autoPlacement ? \"\" : null" }, classAttribute: "ds-popover ds-dropdown" }, ngImport: i0, template: '<ng-content />', isInline: true });
869
772
  }
870
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviDropdown, decorators: [{
773
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviDropdown, decorators: [{
871
774
  type: Component,
872
775
  args: [{
873
776
  selector: 'hvi-dropdown',
@@ -875,12 +778,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
875
778
  template: '<ng-content />',
876
779
  host: {
877
780
  class: 'ds-popover ds-dropdown',
878
- '[attr.data-id]': 'id',
781
+ '[id]': 'id',
782
+ '[attr.popover]': 'type',
879
783
  '[attr.data-variant]': 'variant',
784
+ '[attr.data-placement]': 'dropdownPlacement',
785
+ '[attr.data-autoplacement]': 'autoPlacement ? "" : null',
880
786
  },
881
787
  }]
882
788
  }], propDecorators: { id: [{
883
789
  type: Input
790
+ }], type: [{
791
+ type: Input
884
792
  }], variant: [{
885
793
  type: Input
886
794
  }], dropdownPlacement: [{
@@ -891,21 +799,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
891
799
  type: Output
892
800
  }], closed: [{
893
801
  type: Output
802
+ }], onToggle: [{
803
+ type: HostListener,
804
+ args: ['toggle', ['$event']]
894
805
  }] } });
895
806
 
896
807
  /**
897
- * @summary
898
- * Adds submit handling for Angular reactive forms:
899
- * - Tracks submitted state
900
- * - Marks all controls as touched on submit
901
- * - Optionally focuses an ErrorSummary when invalid
808
+ * Analyserer en FormGroup og returnerer required-modus.
809
+ *
810
+ * Alle controls telles – også de uten validators (de regnes som optional).
811
+ *
812
+ * - `'all-required'` alle controls har required/requiredTrue
813
+ * - `'mixed'` – noen controls er required, noen ikke
814
+ * - `'none'` – ingen controls har required
815
+ */
816
+ function analyzeFormRequired(formGroup) {
817
+ const controls = Object.values(formGroup.controls);
818
+ if (controls.length === 0)
819
+ return 'none';
820
+ let requiredCount = 0;
821
+ for (const control of controls) {
822
+ if (control.hasValidator(Validators.required) ||
823
+ control.hasValidator(Validators.requiredTrue)) {
824
+ requiredCount++;
825
+ }
826
+ }
827
+ if (requiredCount === 0)
828
+ return 'none';
829
+ if (requiredCount === controls.length)
830
+ return 'all-required';
831
+ return 'mixed';
832
+ }
833
+ /**
834
+ * Legges på `<form>` for å gi submit-håndtering og automatisk required-tag-analyse
835
+ * for Angular reactive forms.
836
+ *
837
+ * - Tracker submitted-state
838
+ * - Marker alle controls som touched ved submit
839
+ * - Analyserer FormGroup og eksponerer `requiredMode()` som child-komponenter
840
+ * (f.eks. `HviTextfield`) kan injisere for automatisk required/optional-tagging
841
+ * - Sett `[showRequiredTags]="false"` for å skru av automatisk tagging
902
842
  *
903
843
  * @example
904
844
  * ```html
905
- * <[hviForm]></[hviForm]>
845
+ * <form hviForm [formGroup]="myForm">
846
+ * @if (myHviForm.requiredMode() === 'all-required') {
847
+ * <hvi-required-tag mode="all-required" />
848
+ * }
849
+ * <hvi-textfield label="Navn" formControlName="name" />
850
+ * </form>
906
851
  * ```
907
- *
908
- * Documentation: https://designsystemet.no/en/components/docs/form/code
909
852
  */
910
853
  class HviForm {
911
854
  /** Emits when the form has been submitted */
@@ -914,8 +857,31 @@ class HviForm {
914
857
  submitted = false;
915
858
  /** Optional focus target (e.g. HviErrorSummaryComponent) */
916
859
  focusOnInvalid;
860
+ /**
861
+ * Skru av/på automatisk required-tag-visning for child-komponenter.
862
+ * Default `true`. Sett til `false` for manuell kontroll.
863
+ */
864
+ showRequiredTags = true;
917
865
  // Optional injection: present when the form uses [formGroup] and ReactiveFormsModule is in scope
918
866
  formGroupDir = inject(FormGroupDirective, { optional: true });
867
+ /** Internal signal som oppdateres ved submit og init */
868
+ _requiredMode = signal('none', ...(ngDevMode ? [{ debugName: "_requiredMode" }] : /* istanbul ignore next */ []));
869
+ /**
870
+ * Analysert required-modus for FormGroup-en.
871
+ * - `'all-required'` – alle validerte controls er required
872
+ * - `'mixed'` – blanding av required og optional
873
+ * - `'none'` – ingen required-validering
874
+ */
875
+ requiredMode = computed(() => this._requiredMode(), ...(ngDevMode ? [{ debugName: "requiredMode" }] : /* istanbul ignore next */ []));
876
+ /** Oppdater required-analyse. Kalles automatisk ved submit, men kan kalles manuelt. */
877
+ refreshRequiredMode() {
878
+ const form = this.formGroupDir?.form;
879
+ if (!form) {
880
+ this._requiredMode.set('none');
881
+ return;
882
+ }
883
+ this._requiredMode.set(analyzeFormRequired(form));
884
+ }
919
885
  onSubmit(event) {
920
886
  this.submitted = true;
921
887
  this.hviSubmitted.emit();
@@ -928,19 +894,26 @@ class HviForm {
928
894
  queueMicrotask(() => this.focusOnInvalid?.focus?.());
929
895
  }
930
896
  }
931
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviForm, deps: [], target: i0.ɵɵFactoryTarget.Directive });
932
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviForm, isStandalone: true, selector: "form[hviForm]", inputs: { focusOnInvalid: "focusOnInvalid" }, outputs: { hviSubmitted: "hviSubmitted" }, host: { listeners: { "submit": "onSubmit($event)" } }, ngImport: i0 });
897
+ ngOnInit() {
898
+ this.refreshRequiredMode();
899
+ }
900
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviForm, deps: [], target: i0.ɵɵFactoryTarget.Directive });
901
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.6", type: HviForm, isStandalone: true, selector: "form[hviForm]", inputs: { focusOnInvalid: "focusOnInvalid", showRequiredTags: ["showRequiredTags", "showRequiredTags", booleanAttribute] }, outputs: { hviSubmitted: "hviSubmitted" }, host: { listeners: { "submit": "onSubmit($event)" } }, exportAs: ["hviForm"], ngImport: i0 });
933
902
  }
934
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviForm, decorators: [{
903
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviForm, decorators: [{
935
904
  type: Directive,
936
905
  args: [{
937
906
  selector: 'form[hviForm]',
938
907
  standalone: true,
908
+ exportAs: 'hviForm',
939
909
  }]
940
910
  }], propDecorators: { hviSubmitted: [{
941
911
  type: Output
942
912
  }], focusOnInvalid: [{
943
913
  type: Input
914
+ }], showRequiredTags: [{
915
+ type: Input,
916
+ args: [{ transform: booleanAttribute }]
944
917
  }], onSubmit: [{
945
918
  type: HostListener,
946
919
  args: ['submit', ['$event']]
@@ -955,8 +928,6 @@ const DEFAULT_ERROR_PRIORITY$1 = [
955
928
  'min',
956
929
  'max',
957
930
  ];
958
- let errorSummaryIdCounter = 0;
959
- const nextErrorSummaryHeadingId = () => `hvi-error-summary-heading-${++errorSummaryIdCounter}`;
960
931
  /**
961
932
  * @summary
962
933
  * ErrorSummary lists blocking validation errors so users can quickly find and fix them.
@@ -1023,6 +994,7 @@ const nextErrorSummaryHeadingId = () => `hvi-error-summary-heading-${++errorSumm
1023
994
  * Documentation: https://designsystemet.no/en/components/docs/error-summary/code
1024
995
  */
1025
996
  class HviErrorSummary {
997
+ el = inject((ElementRef));
1026
998
  /** Heading text shown above the list */
1027
999
  heading = 'For å gå videre må du rette opp følgende feil:';
1028
1000
  /** Heading level for the heading element (1-6). Defaults to 2 per DS */
@@ -1050,13 +1022,10 @@ class HviErrorSummary {
1050
1022
  idMap;
1051
1023
  /** Auto mode: error key priority (first match wins) */
1052
1024
  errorPriority = DEFAULT_ERROR_PRIORITY$1;
1053
- /** Used for aria-labelledby on the container */
1054
- headingId = nextErrorSummaryHeadingId();
1055
1025
  /** When to show errors from the form controls */
1056
1026
  showWhen = 'submitted';
1057
- container;
1058
1027
  focus() {
1059
- this.container?.nativeElement.focus();
1028
+ this.el.nativeElement.querySelector('ds-error-summary')?.focus();
1060
1029
  }
1061
1030
  /**
1062
1031
  * Handles click on error links to prevent Angular Router navigation
@@ -1132,33 +1101,27 @@ class HviErrorSummary {
1132
1101
  }
1133
1102
  return false;
1134
1103
  }
1135
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviErrorSummary, deps: [], target: i0.ɵɵFactoryTarget.Component });
1136
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: HviErrorSummary, isStandalone: true, selector: "hvi-error-summary", inputs: { heading: "heading", headingLevel: "headingLevel", errors: "errors", form: "form", messages: "messages", idMap: "idMap", errorPriority: "errorPriority", headingId: "headingId", showWhen: "showWhen" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, static: true }], ngImport: i0, template: `
1137
- <div
1138
- #container
1139
- class="ds-error-summary"
1140
- tabindex="-1"
1141
- [attr.aria-labelledby]="headingId"
1142
- [hidden]="!shouldShow"
1143
- >
1104
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviErrorSummary, deps: [], target: i0.ɵɵFactoryTarget.Component });
1105
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: HviErrorSummary, isStandalone: true, selector: "hvi-error-summary", inputs: { heading: "heading", headingLevel: "headingLevel", errors: "errors", form: "form", messages: "messages", idMap: "idMap", errorPriority: "errorPriority", showWhen: "showWhen" }, ngImport: i0, template: `
1106
+ <ds-error-summary class="ds-error-summary" [hidden]="!shouldShow">
1144
1107
  @switch (headingLevel) {
1145
1108
  @case (1) {
1146
- <h1 class="ds-heading" [id]="headingId">{{ heading }}</h1>
1147
- }
1148
- @case (2) {
1149
- <h2 class="ds-heading" [id]="headingId">{{ heading }}</h2>
1109
+ <h1 class="ds-heading">{{ heading }}</h1>
1150
1110
  }
1151
1111
  @case (3) {
1152
- <h3 class="ds-heading" [id]="headingId">{{ heading }}</h3>
1112
+ <h3 class="ds-heading">{{ heading }}</h3>
1153
1113
  }
1154
1114
  @case (4) {
1155
- <h4 class="ds-heading" [id]="headingId">{{ heading }}</h4>
1115
+ <h4 class="ds-heading">{{ heading }}</h4>
1156
1116
  }
1157
1117
  @case (5) {
1158
- <h5 class="ds-heading" [id]="headingId">{{ heading }}</h5>
1118
+ <h5 class="ds-heading">{{ heading }}</h5>
1119
+ }
1120
+ @case (6) {
1121
+ <h6 class="ds-heading">{{ heading }}</h6>
1159
1122
  }
1160
1123
  @default {
1161
- <h6 class="ds-heading" [id]="headingId">{{ heading }}</h6>
1124
+ <h2 class="ds-heading">{{ heading }}</h2>
1162
1125
  }
1163
1126
  }
1164
1127
 
@@ -1175,40 +1138,31 @@ class HviErrorSummary {
1175
1138
  </li>
1176
1139
  }
1177
1140
  </ul>
1178
- </div>
1179
- `, isInline: true });
1141
+ </ds-error-summary>
1142
+ `, isInline: true, styles: [":host{display:contents}\n"] });
1180
1143
  }
1181
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviErrorSummary, decorators: [{
1144
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviErrorSummary, decorators: [{
1182
1145
  type: Component,
1183
- args: [{
1184
- selector: 'hvi-error-summary',
1185
- standalone: true,
1186
- template: `
1187
- <div
1188
- #container
1189
- class="ds-error-summary"
1190
- tabindex="-1"
1191
- [attr.aria-labelledby]="headingId"
1192
- [hidden]="!shouldShow"
1193
- >
1146
+ args: [{ selector: 'hvi-error-summary', schemas: [CUSTOM_ELEMENTS_SCHEMA], standalone: true, template: `
1147
+ <ds-error-summary class="ds-error-summary" [hidden]="!shouldShow">
1194
1148
  @switch (headingLevel) {
1195
1149
  @case (1) {
1196
- <h1 class="ds-heading" [id]="headingId">{{ heading }}</h1>
1197
- }
1198
- @case (2) {
1199
- <h2 class="ds-heading" [id]="headingId">{{ heading }}</h2>
1150
+ <h1 class="ds-heading">{{ heading }}</h1>
1200
1151
  }
1201
1152
  @case (3) {
1202
- <h3 class="ds-heading" [id]="headingId">{{ heading }}</h3>
1153
+ <h3 class="ds-heading">{{ heading }}</h3>
1203
1154
  }
1204
1155
  @case (4) {
1205
- <h4 class="ds-heading" [id]="headingId">{{ heading }}</h4>
1156
+ <h4 class="ds-heading">{{ heading }}</h4>
1206
1157
  }
1207
1158
  @case (5) {
1208
- <h5 class="ds-heading" [id]="headingId">{{ heading }}</h5>
1159
+ <h5 class="ds-heading">{{ heading }}</h5>
1160
+ }
1161
+ @case (6) {
1162
+ <h6 class="ds-heading">{{ heading }}</h6>
1209
1163
  }
1210
1164
  @default {
1211
- <h6 class="ds-heading" [id]="headingId">{{ heading }}</h6>
1165
+ <h2 class="ds-heading">{{ heading }}</h2>
1212
1166
  }
1213
1167
  }
1214
1168
 
@@ -1225,9 +1179,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1225
1179
  </li>
1226
1180
  }
1227
1181
  </ul>
1228
- </div>
1229
- `,
1230
- }]
1182
+ </ds-error-summary>
1183
+ `, styles: [":host{display:contents}\n"] }]
1231
1184
  }], propDecorators: { heading: [{
1232
1185
  type: Input
1233
1186
  }], headingLevel: [{
@@ -1242,129 +1195,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1242
1195
  type: Input
1243
1196
  }], errorPriority: [{
1244
1197
  type: Input
1245
- }], headingId: [{
1246
- type: Input
1247
1198
  }], showWhen: [{
1248
1199
  type: Input
1249
- }], container: [{
1250
- type: ViewChild,
1251
- args: ['container', { static: true }]
1252
1200
  }] } });
1253
1201
 
1254
- // Copied from https://github.com/digdir/designsystemet/blob/main/packages/react/src/components/field/field-observer.ts
1255
- function fieldObserver(fieldElement) {
1256
- if (!fieldElement)
1257
- return;
1258
- const elements = new Map();
1259
- const typeCounter = new Map(); // Track count for each data-field type
1260
- const uuid = `:${Date.now().toString(36)}${Math.random().toString(36).slice(2, 5)}`;
1261
- let input = null;
1262
- let describedby = '';
1263
- const process = (mutations) => {
1264
- const changed = [];
1265
- const removed = [];
1266
- // Merge MutationRecords
1267
- for (const mutation of mutations) {
1268
- if (mutation.attributeName)
1269
- changed.push(mutation.target ?? fieldElement);
1270
- changed.push(...(mutation.addedNodes || []));
1271
- removed.push(...(mutation.removedNodes || []));
1272
- }
1273
- // Register elements
1274
- for (const el of changed) {
1275
- if (!isElement(el))
1276
- continue;
1277
- if (isLabel(el))
1278
- elements.set(el, el.htmlFor);
1279
- else if (el.hasAttribute('data-field'))
1280
- elements.set(el, el.id);
1281
- else if (isInputLike(el) && !el.hidden) {
1282
- input = el;
1283
- describedby = el.getAttribute('aria-describedby') || '';
1284
- }
1285
- }
1286
- // Reset removed elements
1287
- for (const el of removed) {
1288
- if (!isElement(el))
1289
- continue;
1290
- if (input === el)
1291
- input = null;
1292
- if (elements.has(el)) {
1293
- setAttr(el, isLabel(el) ? 'for' : 'id', elements.get(el));
1294
- elements.delete(el);
1295
- }
1296
- }
1297
- // Connect elements
1298
- const describedbyIds = describedby ? describedby.split(' ') : []; // Keep original aria-describedby
1299
- const inputId = input?.id || uuid;
1300
- // Reset type counters since we reprocess all elements
1301
- typeCounter.clear();
1302
- for (const [el, value] of elements) {
1303
- const descriptionType = el.getAttribute('data-field');
1304
- let id;
1305
- if (descriptionType) {
1306
- // Increment type counter for this type
1307
- const count = (typeCounter.get(descriptionType) || 0) + 1;
1308
- typeCounter.set(descriptionType, count);
1309
- id = `${inputId}:${descriptionType}:${count}`;
1310
- }
1311
- else {
1312
- id = inputId;
1313
- }
1314
- if (!value)
1315
- setAttr(el, isLabel(el) ? 'for' : 'id', id); // Ensure we have a value
1316
- if (!describedbyIds.includes(el.id)) {
1317
- if (descriptionType === 'validation')
1318
- describedbyIds.unshift(el.id); // Validations to the front
1319
- else if (descriptionType)
1320
- describedbyIds.push(el.id); // Other descriptions to the back
1321
- }
1322
- }
1323
- // Prune aria-describedby so it does not reference removed elements
1324
- const prunedDescribedbyIds = describedbyIds.filter((id) => {
1325
- if (!id)
1326
- return false;
1327
- if (id === inputId)
1328
- return true;
1329
- // Keep if it still exists anywhere in the document.
1330
- // This preserves "original aria-describedby" entries that live outside the field subtree.
1331
- return !!fieldElement.ownerDocument?.getElementById(id);
1332
- });
1333
- setAttr(input, 'id', inputId);
1334
- setAttr(input, 'aria-describedby', prunedDescribedbyIds.join(' ').trim());
1335
- };
1336
- const observer = createOptimizedMutationObserver(process);
1337
- observer.observe(fieldElement, {
1338
- attributeFilter: ['id', 'for', 'aria-describedby'],
1339
- attributes: true,
1340
- childList: true,
1341
- subtree: true,
1342
- });
1343
- process([{ addedNodes: fieldElement.querySelectorAll('*') }]); // Initial setup
1344
- observer.takeRecords(); // Clear initial setup queue
1345
- return () => observer.disconnect();
1346
- }
1347
- // Utilities
1348
- const isElement = (node) => node instanceof Element;
1349
- const isLabel = (node) => node instanceof HTMLLabelElement;
1350
- const isInputLike = (node) => node instanceof HTMLElement && 'validity' in node && !(node instanceof HTMLButtonElement); // Matches input, textarea, select and form accosiated custom elements
1351
- const setAttr = (el, name, value) => value ? el?.setAttribute(name, value) : el?.removeAttribute(name);
1352
- // Speed up MutationObserver by debouncing, clearing internal queue after changes and only running when page is visible
1353
- function createOptimizedMutationObserver(callback) {
1354
- const queue = [];
1355
- const observer = new MutationObserver((mutations) => {
1356
- if (!queue.length)
1357
- requestAnimationFrame(process);
1358
- queue.push(...mutations);
1359
- });
1360
- const process = () => {
1361
- callback(queue, observer);
1362
- queue.length = 0; // Reset queue
1363
- observer.takeRecords(); // Clear queue due to DOM changes in callback
1364
- };
1365
- return observer;
1366
- }
1367
-
1368
1202
  /**
1369
1203
  * Decorative affix container displayed alongside a text input.
1370
1204
  *
@@ -1383,10 +1217,10 @@ function createOptimizedMutationObserver(callback) {
1383
1217
  * Documentation: https://designsystemet.no/en/components/docs/field/code#prefixsuffix
1384
1218
  */
1385
1219
  class HviFieldAffix {
1386
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldAffix, deps: [], target: i0.ɵɵFactoryTarget.Component });
1387
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviFieldAffix, isStandalone: true, selector: "hvi-field-affix", host: { properties: { "aria-hidden": "true" }, classAttribute: "ds-field-affix" }, ngImport: i0, template: `<ng-content />`, isInline: true });
1220
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldAffix, deps: [], target: i0.ɵɵFactoryTarget.Component });
1221
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviFieldAffix, isStandalone: true, selector: "hvi-field-affix", host: { properties: { "aria-hidden": "true" }, classAttribute: "ds-field-affix" }, ngImport: i0, template: `<ng-content />`, isInline: true });
1388
1222
  }
1389
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldAffix, decorators: [{
1223
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldAffix, decorators: [{
1390
1224
  type: Component,
1391
1225
  args: [{
1392
1226
  selector: 'hvi-field-affix',
@@ -1416,10 +1250,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1416
1250
  * Documentation: https://designsystemet.no/en/components/docs/field/code#prefixsuffix
1417
1251
  */
1418
1252
  class HviFieldAffixes {
1419
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldAffixes, deps: [], target: i0.ɵɵFactoryTarget.Component });
1420
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviFieldAffixes, isStandalone: true, selector: "hvi-field-affixes", host: { classAttribute: "ds-field-affixes" }, ngImport: i0, template: `<ng-content />`, isInline: true });
1253
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldAffixes, deps: [], target: i0.ɵɵFactoryTarget.Component });
1254
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviFieldAffixes, isStandalone: true, selector: "hvi-field-affixes", host: { classAttribute: "ds-field-affixes" }, ngImport: i0, template: `<ng-content />`, isInline: true });
1421
1255
  }
1422
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldAffixes, decorators: [{
1256
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldAffixes, decorators: [{
1423
1257
  type: Component,
1424
1258
  args: [{
1425
1259
  selector: 'hvi-field-affixes',
@@ -1431,129 +1265,55 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1431
1265
  }] });
1432
1266
 
1433
1267
  /**
1434
- * Counter component that displays remaining/exceeded character count for a field.
1268
+ * Counter that displays remaining/exceeded character count for a field.
1435
1269
  *
1436
- * @remarks
1437
- * Shows a visual counter and provides accessible announcements via aria-live.
1438
1270
  * Must be used inside a `hvi-field` component alongside a textarea or input.
1439
- *
1440
- * The component automatically finds and tracks the input/textarea in the same field,
1271
+ * The ds-field web component automatically tracks the input/textarea,
1441
1272
  * so you only need to provide the `limit` property.
1442
1273
  *
1443
1274
  * @example
1444
- * Simple usage (auto-tracking):
1445
1275
  * ```html
1446
1276
  * <hvi-field>
1447
1277
  * <label hviLabel for="description" weight="medium">Beskrivelse</label>
1448
- * <textarea hviInput id="description" rows="3" maxlength="100"></textarea>
1278
+ * <textarea hviInput id="description" rows="3"></textarea>
1449
1279
  * <hvi-field-counter [limit]="100" />
1450
1280
  * </hvi-field>
1451
1281
  * ```
1452
1282
  *
1453
- * @example
1454
- * Manual tracking (for custom scenarios):
1455
- * ```html
1456
- * <hvi-field>
1457
- * <label hviLabel for="description" weight="medium">Beskrivelse</label>
1458
- * <textarea hviInput id="description" rows="3" #textarea></textarea>
1459
- * <hvi-field-counter [limit]="100" [count]="textarea.value.length" />
1460
- * </hvi-field>
1461
- * ```
1462
- *
1463
1283
  * Documentation: https://designsystemet.no/en/components/docs/field/code
1464
1284
  */
1465
1285
  class HviFieldCounter {
1466
- el = inject((ElementRef));
1467
- destroyRef = inject(DestroyRef);
1468
- /** Auto-tracked character count from the input/textarea in the same field */
1469
- autoCount = signal(0, ...(ngDevMode ? [{ debugName: "autoCount" }] : []));
1470
- /**
1471
- * Current character count. If not provided, the component will
1472
- * automatically track the input/textarea in the same hvi-field.
1473
- */
1474
- count = input(...(ngDevMode ? [undefined, { debugName: "count" }] : []));
1475
1286
  /** Maximum allowed characters */
1476
- limit = input.required(...(ngDevMode ? [{ debugName: "limit" }] : []));
1287
+ limit = input.required(...(ngDevMode ? [{ debugName: "limit" }] : /* istanbul ignore next */ []));
1477
1288
  /** Label template when limit is exceeded. Use %d for the count. */
1478
- over = input('%d tegn for mye', ...(ngDevMode ? [{ debugName: "over" }] : []));
1289
+ over = input(...(ngDevMode ? [undefined, { debugName: "over" }] : /* istanbul ignore next */ []));
1479
1290
  /** Label template for remaining characters. Use %d for the count. */
1480
- under = input('%d tegn igjen', ...(ngDevMode ? [{ debugName: "under" }] : []));
1481
- /** Hint text for screen readers about max characters. Use %d for the limit. */
1482
- hint = input('Maks %d tegn tillatt.', ...(ngDevMode ? [{ debugName: "hint" }] : []));
1483
- /** Effective count - uses manual count if provided, otherwise auto-tracked */
1484
- effectiveCount = computed(() => this.count() ?? this.autoCount(), ...(ngDevMode ? [{ debugName: "effectiveCount" }] : []));
1485
- /** Computed difference between limit and current count */
1486
- remaining = computed(() => this.limit() - this.effectiveCount(), ...(ngDevMode ? [{ debugName: "remaining" }] : []));
1487
- /** Whether the limit has been exceeded */
1488
- isOver = computed(() => this.remaining() < 0, ...(ngDevMode ? [{ debugName: "isOver" }] : []));
1489
- /** The formatted message to display */
1490
- message = computed(() => {
1491
- const diff = Math.abs(this.remaining());
1492
- const template = this.isOver() ? this.over() : this.under();
1493
- return template.replace('%d', String(diff));
1494
- }, ...(ngDevMode ? [{ debugName: "message" }] : []));
1495
- /** The formatted hint for screen readers */
1496
- formattedHint = computed(() => this.hint().replace('%d', String(this.limit())), ...(ngDevMode ? [{ debugName: "formattedHint" }] : []));
1497
- ngAfterViewInit() {
1498
- // Only auto-track if count is not manually provided
1499
- if (this.count() !== undefined)
1500
- return;
1501
- // Find the parent hvi-field
1502
- const field = this.el.nativeElement.closest('.ds-field');
1503
- if (!field)
1504
- return;
1505
- // Find input or textarea in the field
1506
- const inputEl = field.querySelector('input, textarea');
1507
- if (!inputEl)
1508
- return;
1509
- // Set initial count
1510
- this.autoCount.set(inputEl.value.length);
1511
- // Listen for input events
1512
- const onInput = () => this.autoCount.set(inputEl.value.length);
1513
- inputEl.addEventListener('input', onInput);
1514
- this.destroyRef.onDestroy(() => {
1515
- inputEl.removeEventListener('input', onInput);
1516
- });
1517
- }
1518
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldCounter, deps: [], target: i0.ɵɵFactoryTarget.Component });
1519
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.1", type: HviFieldCounter, isStandalone: true, selector: "hvi-field-counter", inputs: { count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: false, transformFunction: null }, limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: true, transformFunction: null }, over: { classPropertyName: "over", publicName: "over", isSignal: true, isRequired: false, transformFunction: null }, under: { classPropertyName: "under", publicName: "under", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
1520
- <!-- Screen reader live region for dynamic updates -->
1521
- <div class="ds-sr-only" aria-live="polite">{{ message() }}</div>
1522
-
1523
- <!-- Visible counter text -->
1524
- <p class="ds-paragraph" data-variant="default" aria-hidden="true">{{ message() }}</p>
1525
-
1526
- <!-- Screen reader hint (read when entering field) -->
1527
- <div class="ds-sr-only" aria-hidden="true" data-field="description">
1528
- {{ formattedHint() }}
1529
- </div>
1530
- `, isInline: true });
1291
+ under = input(...(ngDevMode ? [undefined, { debugName: "under" }] : /* istanbul ignore next */ []));
1292
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldCounter, deps: [], target: i0.ɵɵFactoryTarget.Component });
1293
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.6", type: HviFieldCounter, isStandalone: true, selector: "hvi-field-counter", inputs: { limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: true, transformFunction: null }, over: { classPropertyName: "over", publicName: "over", isSignal: true, isRequired: false, transformFunction: null }, under: { classPropertyName: "under", publicName: "under", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `<p
1294
+ class="ds-validation-message"
1295
+ data-field="counter"
1296
+ [attr.data-limit]="limit()"
1297
+ [attr.data-over]="over() ?? null"
1298
+ [attr.data-under]="under() ?? null"
1299
+ ></p>`, isInline: true, styles: [":host{display:contents}\n"] });
1531
1300
  }
1532
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldCounter, decorators: [{
1301
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldCounter, decorators: [{
1533
1302
  type: Component,
1534
- args: [{
1535
- selector: 'hvi-field-counter',
1536
- standalone: true,
1537
- template: `
1538
- <!-- Screen reader live region for dynamic updates -->
1539
- <div class="ds-sr-only" aria-live="polite">{{ message() }}</div>
1540
-
1541
- <!-- Visible counter text -->
1542
- <p class="ds-paragraph" data-variant="default" aria-hidden="true">{{ message() }}</p>
1543
-
1544
- <!-- Screen reader hint (read when entering field) -->
1545
- <div class="ds-sr-only" aria-hidden="true" data-field="description">
1546
- {{ formattedHint() }}
1547
- </div>
1548
- `,
1549
- }]
1550
- }], propDecorators: { count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: false }] }], limit: [{ type: i0.Input, args: [{ isSignal: true, alias: "limit", required: true }] }], over: [{ type: i0.Input, args: [{ isSignal: true, alias: "over", required: false }] }], under: [{ type: i0.Input, args: [{ isSignal: true, alias: "under", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }] } });
1303
+ args: [{ selector: 'hvi-field-counter', standalone: true, template: `<p
1304
+ class="ds-validation-message"
1305
+ data-field="counter"
1306
+ [attr.data-limit]="limit()"
1307
+ [attr.data-over]="over() ?? null"
1308
+ [attr.data-under]="under() ?? null"
1309
+ ></p>`, styles: [":host{display:contents}\n"] }]
1310
+ }], propDecorators: { limit: [{ type: i0.Input, args: [{ isSignal: true, alias: "limit", required: true }] }], over: [{ type: i0.Input, args: [{ isSignal: true, alias: "over", required: false }] }], under: [{ type: i0.Input, args: [{ isSignal: true, alias: "under", required: false }] }] } });
1551
1311
 
1552
1312
  class HviFieldDescription {
1553
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldDescription, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1554
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviFieldDescription, isStandalone: true, selector: "[hviFieldDescription]", host: { attributes: { "data-field": "description" } }, ngImport: i0 });
1313
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldDescription, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1314
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviFieldDescription, isStandalone: true, selector: "[hviFieldDescription]", host: { attributes: { "data-field": "description" } }, ngImport: i0 });
1555
1315
  }
1556
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldDescription, decorators: [{
1316
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldDescription, decorators: [{
1557
1317
  type: Directive,
1558
1318
  args: [{
1559
1319
  selector: '[hviFieldDescription]',
@@ -1565,10 +1325,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1565
1325
  }] });
1566
1326
 
1567
1327
  class HviFieldOptional {
1568
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldOptional, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1569
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviFieldOptional, isStandalone: true, selector: "[hviFieldOptional]", host: { attributes: { "data-field": "optional" } }, ngImport: i0 });
1328
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldOptional, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1329
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviFieldOptional, isStandalone: true, selector: "[hviFieldOptional]", host: { attributes: { "data-field": "optional" } }, ngImport: i0 });
1570
1330
  }
1571
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldOptional, decorators: [{
1331
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldOptional, decorators: [{
1572
1332
  type: Directive,
1573
1333
  args: [{
1574
1334
  selector: '[hviFieldOptional]',
@@ -1580,10 +1340,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1580
1340
  }] });
1581
1341
 
1582
1342
  class HviFieldValidation {
1583
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldValidation, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1584
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviFieldValidation, isStandalone: true, selector: "[hviFieldValidation]", host: { attributes: { "data-field": "validation" }, classAttribute: "ds-validation-message" }, ngImport: i0 });
1343
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldValidation, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1344
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviFieldValidation, isStandalone: true, selector: "[hviFieldValidation]", host: { attributes: { "data-field": "validation" }, classAttribute: "ds-validation-message" }, ngImport: i0 });
1585
1345
  }
1586
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldValidation, decorators: [{
1346
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldValidation, decorators: [{
1587
1347
  type: Directive,
1588
1348
  args: [{
1589
1349
  selector: '[hviFieldValidation]',
@@ -1596,7 +1356,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1596
1356
  }] });
1597
1357
 
1598
1358
  /**
1599
- * Field is a helper component to automatically associate a field with hviLabel, hviFieldDescription and hviFieldValidation.
1359
+ * @summary
1360
+ * Field kobler automatisk sammen label, beskrivelse, validering og input via ds-field web component.
1600
1361
  *
1601
1362
  * @example
1602
1363
  * ```html
@@ -1608,31 +1369,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1608
1369
  * </hvi-field>
1609
1370
  * ```
1610
1371
  *
1611
- * Documentation: https://designsystemet.no/en/components/docs/field/overview
1372
+ * @see {@link https://designsystemet.no/en/components/docs/field/overview}
1612
1373
  */
1613
1374
  class HviField {
1614
1375
  /** Position of toggle inputs (radio, checkbox, switch) in field */
1615
1376
  position;
1616
- el = inject((ElementRef));
1617
- destroyRef = inject(DestroyRef);
1618
- ngAfterViewInit() {
1619
- const stop = fieldObserver(this.el.nativeElement);
1620
- this.destroyRef.onDestroy(() => stop?.());
1621
- }
1622
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviField, deps: [], target: i0.ɵɵFactoryTarget.Component });
1623
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviField, isStandalone: true, selector: "hvi-field", inputs: { position: "position" }, host: { properties: { "attr.data-position": "position ?? null" }, classAttribute: "ds-field" }, ngImport: i0, template: '<ng-content />', isInline: true });
1377
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviField, deps: [], target: i0.ɵɵFactoryTarget.Component });
1378
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviField, isStandalone: true, selector: "hvi-field", inputs: { position: "position" }, ngImport: i0, template: '<ds-field class="ds-field" [attr.data-position]="position ?? null"><ng-content /></ds-field>', isInline: true, styles: [":host{display:contents}\n"] });
1624
1379
  }
1625
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviField, decorators: [{
1380
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviField, decorators: [{
1626
1381
  type: Component,
1627
- args: [{
1628
- selector: 'hvi-field',
1629
- standalone: true,
1630
- template: '<ng-content />',
1631
- host: {
1632
- class: 'ds-field',
1633
- '[attr.data-position]': 'position ?? null',
1634
- },
1635
- }]
1382
+ args: [{ selector: 'hvi-field', schemas: [CUSTOM_ELEMENTS_SCHEMA], standalone: true, template: '<ds-field class="ds-field" [attr.data-position]="position ?? null"><ng-content /></ds-field>', styles: [":host{display:contents}\n"] }]
1636
1383
  }], propDecorators: { position: [{
1637
1384
  type: Input
1638
1385
  }] } });
@@ -1664,10 +1411,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1664
1411
  * Documentation: https://designsystemet.no/en/components/docs/fieldset/overview
1665
1412
  */
1666
1413
  class HviFieldset {
1667
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldset, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1668
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviFieldset, isStandalone: true, selector: "fieldset[hviFieldset]", host: { classAttribute: "ds-fieldset" }, ngImport: i0 });
1414
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldset, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1415
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviFieldset, isStandalone: true, selector: "fieldset[hviFieldset]", host: { classAttribute: "ds-fieldset" }, ngImport: i0 });
1669
1416
  }
1670
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviFieldset, decorators: [{
1417
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviFieldset, decorators: [{
1671
1418
  type: Directive,
1672
1419
  args: [{
1673
1420
  selector: 'fieldset[hviFieldset]',
@@ -1728,10 +1475,10 @@ class HviInput {
1728
1475
  event.stopImmediatePropagation();
1729
1476
  }
1730
1477
  }
1731
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviInput, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1732
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.1", type: HviInput, isStandalone: true, selector: "input[hviInput], textarea[hviInput]", inputs: { type: "type", size: "size", role: "role", disabled: ["disabled", "disabled", booleanAttribute], readOnly: ["readOnly", "readOnly", booleanAttribute], readonly: ["readonly", "readonly", booleanAttribute] }, host: { listeners: { "click": "onClick($event)", "change": "onChange($event)", "keydown": "onKeydown($event)" }, properties: { "attr.type": "type ?? null", "attr.size": "size ?? null", "attr.disabled": "_disabled ? \"\" : null", "attr.readonly": "_readOnly ? \"\" : null", "attr.role": "role ?? null" }, classAttribute: "ds-input" }, ngImport: i0 });
1478
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviInput, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1479
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.6", type: HviInput, isStandalone: true, selector: "input[hviInput], textarea[hviInput]", inputs: { type: "type", size: "size", role: "role", disabled: ["disabled", "disabled", booleanAttribute], readOnly: ["readOnly", "readOnly", booleanAttribute], readonly: ["readonly", "readonly", booleanAttribute] }, host: { listeners: { "click": "onClick($event)", "change": "onChange($event)", "keydown": "onKeydown($event)" }, properties: { "attr.type": "type ?? null", "attr.size": "size ?? null", "attr.disabled": "_disabled ? \"\" : null", "attr.readonly": "_readOnly ? \"\" : null", "attr.role": "role ?? null" }, classAttribute: "ds-input" }, ngImport: i0 });
1733
1480
  }
1734
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviInput, decorators: [{
1481
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviInput, decorators: [{
1735
1482
  type: Directive,
1736
1483
  args: [{
1737
1484
  selector: 'input[hviInput], textarea[hviInput]',
@@ -1791,10 +1538,10 @@ class HviControlInvalid {
1791
1538
  const show = control.invalid && (control.touched || submitted);
1792
1539
  return show ? 'true' : null;
1793
1540
  }
1794
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviControlInvalid, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1795
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviControlInvalid, isStandalone: true, selector: "[hviControlInvalid]", host: { properties: { "attr.aria-invalid": "this.ariaInvalid" } }, ngImport: i0 });
1541
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviControlInvalid, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1542
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviControlInvalid, isStandalone: true, selector: "[hviControlInvalid]", host: { properties: { "attr.aria-invalid": "this.ariaInvalid" } }, ngImport: i0 });
1796
1543
  }
1797
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviControlInvalid, decorators: [{
1544
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviControlInvalid, decorators: [{
1798
1545
  type: Directive,
1799
1546
  args: [{
1800
1547
  selector: '[hviControlInvalid]',
@@ -1857,10 +1604,10 @@ class HviValidationMessage {
1857
1604
  }
1858
1605
  return 'Ugyldig verdi';
1859
1606
  }
1860
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviValidationMessage, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1861
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviValidationMessage, isStandalone: true, selector: "[hviValidationMessage]", inputs: { controlName: ["hviValidationMessage", "controlName"], messages: "messages", errorPriority: "errorPriority" }, host: { properties: { "textContent": "message", "hidden": "!message" } }, ngImport: i0 });
1607
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviValidationMessage, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1608
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviValidationMessage, isStandalone: true, selector: "[hviValidationMessage]", inputs: { controlName: ["hviValidationMessage", "controlName"], messages: "messages", errorPriority: "errorPriority" }, host: { properties: { "textContent": "message", "hidden": "!message" } }, ngImport: i0 });
1862
1609
  }
1863
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviValidationMessage, decorators: [{
1610
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviValidationMessage, decorators: [{
1864
1611
  type: Directive,
1865
1612
  args: [{
1866
1613
  selector: '[hviValidationMessage]',
@@ -2033,6 +1780,119 @@ function hviNullValidator() {
2033
1780
  return { validator: Validators.nullValidator, key: 'null', message: '' };
2034
1781
  }
2035
1782
 
1783
+ /**
1784
+ * @summary
1785
+ * Tag is a label that can be used to categorize items or communicate progress, status, or process. Tags can provide users with a quicker overview of content.
1786
+ *
1787
+ * @example
1788
+ * ```html
1789
+ * <hvi-tag variant="outline" size="sm" color="info">Small info tag</hvi-tag>
1790
+ * ```
1791
+ *
1792
+ * Documentation: https://designsystemet.no/en/components/docs/tag/code
1793
+ */
1794
+ class HviTag {
1795
+ /** The variants of the tag */
1796
+ variant;
1797
+ /** The sizes of the tag */
1798
+ size;
1799
+ /** The color theme of the tag */
1800
+ color;
1801
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTag, deps: [], target: i0.ɵɵFactoryTarget.Component });
1802
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviTag, isStandalone: true, selector: "hvi-tag", inputs: { variant: "variant", size: "size", color: "color" }, host: { properties: { "attr.data-variant": "variant ?? null", "attr.data-size": "size ?? null", "attr.data-color": "color ?? null" }, classAttribute: "ds-tag" }, ngImport: i0, template: '<ng-content />', isInline: true });
1803
+ }
1804
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTag, decorators: [{
1805
+ type: Component,
1806
+ args: [{
1807
+ selector: 'hvi-tag',
1808
+ standalone: true,
1809
+ template: '<ng-content />',
1810
+ host: {
1811
+ class: 'ds-tag',
1812
+ '[attr.data-variant]': 'variant ?? null',
1813
+ '[attr.data-size]': 'size ?? null',
1814
+ '[attr.data-color]': 'color ?? null',
1815
+ },
1816
+ }]
1817
+ }], propDecorators: { variant: [{
1818
+ type: Input
1819
+ }], size: [{
1820
+ type: Input
1821
+ }], color: [{
1822
+ type: Input
1823
+ }] } });
1824
+
1825
+ /**
1826
+ * RequiredTag brukes sammen med labels i skjema for å indikere om et felt er
1827
+ * påkrevd, valgfritt, eller om alle felt må fylles ut.
1828
+ *
1829
+ * Komponenten wrapper `HviTag` med forhåndsdefinerte tekster og farger basert på mode.
1830
+ * Bruker `display: contents` slik at den fungerer inline i `<label>` og frittstående.
1831
+ *
1832
+ * Kan brukes manuelt, eller automatisk via `HviForm` som analyserer FormGroup
1833
+ * og lar child-komponenter som `HviTextfield` vise riktig tag.
1834
+ *
1835
+ * @example
1836
+ * ```html
1837
+ * <hvi-required-tag />
1838
+ * <hvi-required-tag mode="optional" />
1839
+ * <hvi-required-tag mode="all-required" />
1840
+ * ```
1841
+ */
1842
+ class HviRequiredTag {
1843
+ /**
1844
+ * Bestemmer tekst og farge på taggen.
1845
+ * - `required` (default): "Må fylles ut" (warning)
1846
+ * - `optional`: "Valgfritt" (info)
1847
+ * - `all-required`: "Alle felt må fylles ut" (warning)
1848
+ */
1849
+ mode = 'required';
1850
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviRequiredTag, deps: [], target: i0.ɵɵFactoryTarget.Component });
1851
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: HviRequiredTag, isStandalone: true, selector: "hvi-required-tag", inputs: { mode: "mode" }, host: { styleAttribute: "display: contents" }, ngImport: i0, template: `
1852
+ <hvi-tag variant="default" size="sm" [color]="mode === 'optional' ? 'info' : 'warning'">
1853
+ @switch (mode) {
1854
+ @case ('all-required') {
1855
+ Alle felt må fylles ut
1856
+ }
1857
+ @case ('required') {
1858
+ Må fylles ut
1859
+ }
1860
+ @case ('optional') {
1861
+ Valgfritt
1862
+ }
1863
+ }
1864
+ </hvi-tag>
1865
+ `, isInline: true, dependencies: [{ kind: "component", type: HviTag, selector: "hvi-tag", inputs: ["variant", "size", "color"] }] });
1866
+ }
1867
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviRequiredTag, decorators: [{
1868
+ type: Component,
1869
+ args: [{
1870
+ selector: 'hvi-required-tag',
1871
+ standalone: true,
1872
+ imports: [HviTag],
1873
+ template: `
1874
+ <hvi-tag variant="default" size="sm" [color]="mode === 'optional' ? 'info' : 'warning'">
1875
+ @switch (mode) {
1876
+ @case ('all-required') {
1877
+ Alle felt må fylles ut
1878
+ }
1879
+ @case ('required') {
1880
+ Må fylles ut
1881
+ }
1882
+ @case ('optional') {
1883
+ Valgfritt
1884
+ }
1885
+ }
1886
+ </hvi-tag>
1887
+ `,
1888
+ host: {
1889
+ style: 'display: contents',
1890
+ },
1891
+ }]
1892
+ }], propDecorators: { mode: [{
1893
+ type: Input
1894
+ }] } });
1895
+
2036
1896
  // 1) Bare field-byggesteiner
2037
1897
  const HviFieldKit = [
2038
1898
  HviField,
@@ -2042,6 +1902,7 @@ const HviFieldKit = [
2042
1902
  HviFieldAffix,
2043
1903
  HviFieldAffixes,
2044
1904
  HviFieldCounter,
1905
+ HviRequiredTag,
2045
1906
  ];
2046
1907
  // 2) Reactive forms + invalid/validation glue + submit behavior
2047
1908
  const HviValidationKit = [
@@ -2072,10 +1933,10 @@ const HviForms = [
2072
1933
  class HviHeading {
2073
1934
  /** The size of the heading */
2074
1935
  size;
2075
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviHeading, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2076
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviHeading, isStandalone: true, selector: "h1[hviHeading], h2[hviHeading], h3[hviHeading], h4[hviHeading], h5[hviHeading], h6[hviHeading]", inputs: { size: "size" }, host: { properties: { "attr.data-size": "size" }, classAttribute: "ds-heading" }, ngImport: i0 });
1936
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviHeading, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1937
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviHeading, isStandalone: true, selector: "h1[hviHeading], h2[hviHeading], h3[hviHeading], h4[hviHeading], h5[hviHeading], h6[hviHeading]", inputs: { size: "size" }, host: { properties: { "attr.data-size": "size" }, classAttribute: "ds-heading" }, ngImport: i0 });
2077
1938
  }
2078
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviHeading, decorators: [{
1939
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviHeading, decorators: [{
2079
1940
  type: Directive,
2080
1941
  args: [{
2081
1942
  selector: 'h1[hviHeading], h2[hviHeading], h3[hviHeading], h4[hviHeading], h5[hviHeading], h6[hviHeading]',
@@ -2089,55 +1950,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
2089
1950
  type: Input
2090
1951
  }] } });
2091
1952
 
2092
- class HviIcon {
2093
- icon;
2094
- color;
2095
- size = 'md';
2096
- ariaHidden = false;
2097
- http = inject(HttpClient);
2098
- elementRef = inject(ElementRef);
2099
- cdr = inject(ChangeDetectorRef);
2100
- ngOnChanges() {
2101
- this.loadIcon();
2102
- }
2103
- loadIcon() {
2104
- this.http
2105
- .get(`/assets/icons/${this.icon}.svg`, {
2106
- responseType: 'text',
2107
- })
2108
- .subscribe({
2109
- next: (svg) => {
2110
- this.elementRef.nativeElement.innerHTML = svg;
2111
- this.cdr.markForCheck();
2112
- },
2113
- error: (err) => {
2114
- console.error('Failed to load icon:', this.icon, err);
2115
- },
2116
- });
2117
- }
2118
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
2119
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "21.2.1", type: HviIcon, isStandalone: true, selector: "hvi-icon", inputs: { icon: "icon", color: "color", size: "size", ariaHidden: ["ariaHidden", "ariaHidden", booleanAttribute] }, host: { properties: { "attr.data-size": "size", "attr.data-color": "color", "attr.aria-hidden": "ariaHidden" }, classAttribute: "hvi-icon" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, styles: ["hvi-icon{display:inline-block}svg{display:inline-block}hvi-icon[data-size=sm] svg{width:16px;height:16px}hvi-icon[data-size=md] svg{width:24px;height:24px}hvi-icon[data-size=lg] svg{width:32px;height:32px}hvi-icon[data-size=xl] svg{width:40px;height:40px}hvi-icon svg path{fill:currentColor}hvi-icon[data-color=danger] svg path{fill:var(--ds-color-danger-base-default)}\n"], encapsulation: i0.ViewEncapsulation.None });
2120
- }
2121
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviIcon, decorators: [{
2122
- type: Component,
2123
- args: [{ selector: 'hvi-icon', standalone: true, template: '', encapsulation: ViewEncapsulation.None, host: {
2124
- class: 'hvi-icon',
2125
- '[attr.data-size]': 'size',
2126
- '[attr.data-color]': 'color',
2127
- '[attr.aria-hidden]': 'ariaHidden',
2128
- }, styles: ["hvi-icon{display:inline-block}svg{display:inline-block}hvi-icon[data-size=sm] svg{width:16px;height:16px}hvi-icon[data-size=md] svg{width:24px;height:24px}hvi-icon[data-size=lg] svg{width:32px;height:32px}hvi-icon[data-size=xl] svg{width:40px;height:40px}hvi-icon svg path{fill:currentColor}hvi-icon[data-color=danger] svg path{fill:var(--ds-color-danger-base-default)}\n"] }]
2129
- }], propDecorators: { icon: [{
2130
- type: Input,
2131
- args: [{ required: true }]
2132
- }], color: [{
2133
- type: Input
2134
- }], size: [{
2135
- type: Input
2136
- }], ariaHidden: [{
2137
- type: Input,
2138
- args: [{ transform: booleanAttribute }]
2139
- }] } });
2140
-
2141
1953
  /**
2142
1954
  * Label functions as a clear and accessible text label that tells the user what an associated form element is about.
2143
1955
  *
@@ -2151,10 +1963,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
2151
1963
  class HviLabel {
2152
1964
  /** The font weight of the label */
2153
1965
  weight;
2154
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviLabel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2155
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviLabel, isStandalone: true, selector: "label[hviLabel], legend[hviLabel]", inputs: { weight: "weight" }, host: { properties: { "attr.data-weight": "weight ?? null" }, classAttribute: "ds-label" }, ngImport: i0 });
1966
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviLabel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1967
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviLabel, isStandalone: true, selector: "label[hviLabel], legend[hviLabel]", inputs: { weight: "weight" }, host: { properties: { "attr.data-weight": "weight ?? null" }, classAttribute: "ds-label" }, ngImport: i0 });
2156
1968
  }
2157
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviLabel, decorators: [{
1969
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviLabel, decorators: [{
2158
1970
  type: Directive,
2159
1971
  args: [{
2160
1972
  selector: 'label[hviLabel], legend[hviLabel]',
@@ -2181,10 +1993,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
2181
1993
  class HviLink {
2182
1994
  /** Used to change the appearance of the link. */
2183
1995
  color = 'default';
2184
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviLink, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2185
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviLink, isStandalone: true, selector: "a[hviLink]", inputs: { color: "color" }, host: { properties: { "attr.data-color": "color" }, classAttribute: "ds-link" }, ngImport: i0 });
1996
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviLink, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1997
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviLink, isStandalone: true, selector: "a[hviLink]", inputs: { color: "color" }, host: { properties: { "attr.data-color": "color" }, classAttribute: "ds-link" }, ngImport: i0 });
2186
1998
  }
2187
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviLink, decorators: [{
1999
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviLink, decorators: [{
2188
2000
  type: Directive,
2189
2001
  args: [{
2190
2002
  selector: 'a[hviLink]',
@@ -2220,10 +2032,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
2220
2032
  * Documentation: https://designsystemet.no/en/components/docs/input/code
2221
2033
  */
2222
2034
  class HviList {
2223
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviList, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2224
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviList, isStandalone: true, selector: "ol[hviList], ul[hviList]", host: { classAttribute: "ds-list" }, ngImport: i0 });
2035
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviList, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2036
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviList, isStandalone: true, selector: "ol[hviList], ul[hviList]", host: { classAttribute: "ds-list" }, ngImport: i0 });
2225
2037
  }
2226
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviList, decorators: [{
2038
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviList, decorators: [{
2227
2039
  type: Directive,
2228
2040
  args: [{
2229
2041
  selector: 'ol[hviList], ul[hviList]',
@@ -3168,14 +2980,14 @@ const LOGOS = {
3168
2980
  */
3169
2981
  class HviLogo {
3170
2982
  /** Which company logo to display */
3171
- company = input.required(...(ngDevMode ? [{ debugName: "company" }] : []));
2983
+ company = input.required(...(ngDevMode ? [{ debugName: "company" }] : /* istanbul ignore next */ []));
3172
2984
  /** Logo size — sm (40px), md (65px, default), lg (82px) height */
3173
- size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
2985
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
3174
2986
  /** Override the default accessible label */
3175
- ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
3176
- logo = computed(() => LOGOS[this.company()], ...(ngDevMode ? [{ debugName: "logo" }] : []));
3177
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviLogo, deps: [], target: i0.ɵɵFactoryTarget.Component });
3178
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: HviLogo, isStandalone: true, selector: "hvi-logo", inputs: { company: { classPropertyName: "company", publicName: "company", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-size": "size()" }, classAttribute: "hvi-logo" }, ngImport: i0, template: `
2987
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
2988
+ logo = computed(() => LOGOS[this.company()], ...(ngDevMode ? [{ debugName: "logo" }] : /* istanbul ignore next */ []));
2989
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviLogo, deps: [], target: i0.ɵɵFactoryTarget.Component });
2990
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: HviLogo, isStandalone: true, selector: "hvi-logo", inputs: { company: { classPropertyName: "company", publicName: "company", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-size": "size()" }, classAttribute: "hvi-logo" }, ngImport: i0, template: `
3179
2991
  <svg
3180
2992
  [attr.viewBox]="logo().viewBox"
3181
2993
  [attr.aria-label]="ariaLabel() ?? logo().label"
@@ -3188,7 +3000,7 @@ class HviLogo {
3188
3000
  </svg>
3189
3001
  `, isInline: true, styles: [":host{display:inline-block;color:#003087}:host-context([data-color-scheme=\"dark\"]){color:#fff}svg{display:block;height:100%;width:auto}:host([data-size=\"sm\"]){height:46px}:host([data-size=\"md\"]){height:52px}:host([data-size=\"lg\"]){height:60px}\n"] });
3190
3002
  }
3191
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviLogo, decorators: [{
3003
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviLogo, decorators: [{
3192
3004
  type: Component,
3193
3005
  args: [{ selector: 'hvi-logo', standalone: true, template: `
3194
3006
  <svg
@@ -3253,17 +3065,17 @@ class HviPagination {
3253
3065
  /** Event som emitteres med mer detaljer om sideendring */
3254
3066
  pageChange = new EventEmitter();
3255
3067
  // Internal signals
3256
- _totalItems = signal(0, ...(ngDevMode ? [{ debugName: "_totalItems" }] : []));
3257
- _pageSize = signal(10, ...(ngDevMode ? [{ debugName: "_pageSize" }] : []));
3258
- _currentPage = signal(1, ...(ngDevMode ? [{ debugName: "_currentPage" }] : []));
3068
+ _totalItems = signal(0, ...(ngDevMode ? [{ debugName: "_totalItems" }] : /* istanbul ignore next */ []));
3069
+ _pageSize = signal(10, ...(ngDevMode ? [{ debugName: "_pageSize" }] : /* istanbul ignore next */ []));
3070
+ _currentPage = signal(1, ...(ngDevMode ? [{ debugName: "_currentPage" }] : /* istanbul ignore next */ []));
3259
3071
  /** Beregnet totalt antall sider */
3260
3072
  totalPages = computed(() => {
3261
3073
  return Math.max(1, Math.ceil(this._totalItems() / this._pageSize()));
3262
- }, ...(ngDevMode ? [{ debugName: "totalPages" }] : []));
3074
+ }, ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
3263
3075
  /** Er vi på første side? */
3264
- isFirstPage = computed(() => this._currentPage() <= 1, ...(ngDevMode ? [{ debugName: "isFirstPage" }] : []));
3076
+ isFirstPage = computed(() => this._currentPage() <= 1, ...(ngDevMode ? [{ debugName: "isFirstPage" }] : /* istanbul ignore next */ []));
3265
3077
  /** Er vi på siste side? */
3266
- isLastPage = computed(() => this._currentPage() >= this.totalPages(), ...(ngDevMode ? [{ debugName: "isLastPage" }] : []));
3078
+ isLastPage = computed(() => this._currentPage() >= this.totalPages(), ...(ngDevMode ? [{ debugName: "isLastPage" }] : /* istanbul ignore next */ []));
3267
3079
  /** Beregner hvilke elementer som skal vises i pagineringen */
3268
3080
  paginationItems = computed(() => {
3269
3081
  const current = this._currentPage();
@@ -3296,7 +3108,7 @@ class HviPagination {
3296
3108
  items.push({ type: 'page', page: total });
3297
3109
  }
3298
3110
  return items;
3299
- }, ...(ngDevMode ? [{ debugName: "paginationItems" }] : []));
3111
+ }, ...(ngDevMode ? [{ debugName: "paginationItems" }] : /* istanbul ignore next */ []));
3300
3112
  /** Gå til en spesifikk side */
3301
3113
  goToPage(page) {
3302
3114
  const previousPage = this._currentPage();
@@ -3327,8 +3139,8 @@ class HviPagination {
3327
3139
  goToLast() {
3328
3140
  this.goToPage(this.totalPages());
3329
3141
  }
3330
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviPagination, deps: [], target: i0.ɵɵFactoryTarget.Component });
3331
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: HviPagination, isStandalone: true, selector: "hvi-pagination", inputs: { totalItems: ["totalItems", "totalItems", numberAttribute], pageSize: ["pageSize", "pageSize", numberAttribute], currentPage: ["currentPage", "currentPage", numberAttribute], siblingCount: ["siblingCount", "siblingCount", numberAttribute], showEdges: ["showEdges", "showEdges", booleanAttribute], showPreviousNextLabels: ["showPreviousNextLabels", "showPreviousNextLabels", booleanAttribute], ariaLabel: "ariaLabel", previousLabel: "previousLabel", nextLabel: "nextLabel" }, outputs: { currentPageChange: "currentPageChange", pageChange: "pageChange" }, host: { classAttribute: "hvi-pagination" }, ngImport: i0, template: `
3142
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviPagination, deps: [], target: i0.ɵɵFactoryTarget.Component });
3143
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: HviPagination, isStandalone: true, selector: "hvi-pagination", inputs: { totalItems: ["totalItems", "totalItems", numberAttribute], pageSize: ["pageSize", "pageSize", numberAttribute], currentPage: ["currentPage", "currentPage", numberAttribute], siblingCount: ["siblingCount", "siblingCount", numberAttribute], showEdges: ["showEdges", "showEdges", booleanAttribute], showPreviousNextLabels: ["showPreviousNextLabels", "showPreviousNextLabels", booleanAttribute], ariaLabel: "ariaLabel", previousLabel: "previousLabel", nextLabel: "nextLabel" }, outputs: { currentPageChange: "currentPageChange", pageChange: "pageChange" }, host: { classAttribute: "hvi-pagination" }, ngImport: i0, template: `
3332
3144
  <nav [attr.aria-label]="ariaLabel" class="ds-pagination">
3333
3145
  <ul>
3334
3146
  <!-- Forrige -->
@@ -3382,7 +3194,7 @@ class HviPagination {
3382
3194
  </nav>
3383
3195
  `, isInline: true });
3384
3196
  }
3385
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviPagination, decorators: [{
3197
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviPagination, decorators: [{
3386
3198
  type: Component,
3387
3199
  args: [{
3388
3200
  selector: 'hvi-pagination',
@@ -3491,10 +3303,10 @@ class HviParagraph {
3491
3303
  variant;
3492
3304
  /** Paragraph is available in several text sizes to suit different needs */
3493
3305
  size;
3494
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviParagraph, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3495
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviParagraph, isStandalone: true, selector: "p[hviParagraph]", inputs: { variant: "variant", size: "size" }, host: { properties: { "attr.data-variant": "variant ?? null", "attr.data-size": "size ?? null" }, classAttribute: "ds-paragraph" }, ngImport: i0 });
3306
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviParagraph, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3307
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviParagraph, isStandalone: true, selector: "p[hviParagraph]", inputs: { variant: "variant", size: "size" }, host: { properties: { "attr.data-variant": "variant ?? null", "attr.data-size": "size ?? null" }, classAttribute: "ds-paragraph" }, ngImport: i0 });
3496
3308
  }
3497
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviParagraph, decorators: [{
3309
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviParagraph, decorators: [{
3498
3310
  type: Directive,
3499
3311
  args: [{
3500
3312
  selector: 'p[hviParagraph]',
@@ -3511,38 +3323,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
3511
3323
  type: Input
3512
3324
  }] } });
3513
3325
 
3514
- const arrowPseudoElement = {
3515
- name: 'ArrowPseudoElement',
3516
- fn(data) {
3517
- const { elements, rects, placement } = data;
3518
- let arrowX = `${Math.round(rects.reference.width / 2 + rects.reference.x - data.x)}px`;
3519
- let arrowY = `${Math.round(rects.reference.height / 2 + rects.reference.y - data.y)}px`;
3520
- if (rects.reference.width > rects.floating.width) {
3521
- arrowX = `${Math.round(rects.floating.width / 2)}px`;
3522
- }
3523
- if (rects.reference.height > rects.floating.height) {
3524
- arrowY = `${Math.round(rects.floating.height / 2)}px`;
3525
- }
3526
- switch (placement.split('-')[0]) {
3527
- case 'top':
3528
- arrowY = '100%';
3529
- break;
3530
- case 'right':
3531
- arrowX = '0';
3532
- break;
3533
- case 'bottom':
3534
- arrowY = '0';
3535
- break;
3536
- case 'left':
3537
- arrowX = '100%';
3538
- break;
3539
- }
3540
- elements.floating.setAttribute('data-placement', placement.split('-')[0]);
3541
- elements.floating.style.setProperty('--ds-popover-arrow-x', arrowX);
3542
- elements.floating.style.setProperty('--ds-popover-arrow-y', arrowY);
3543
- return data;
3544
- },
3545
- };
3546
3326
  /**
3547
3327
  * @summary
3548
3328
  * Popover vises over andre elementer i grensesnittet og er koblet til et spesifikt element.
@@ -3557,12 +3337,8 @@ const arrowPseudoElement = {
3557
3337
  * @see {@link https://designsystemet.no/en/components/docs/popover/code}
3558
3338
  */
3559
3339
  class HviPopover {
3560
- el = inject((ElementRef));
3561
- cleanupAutoUpdate;
3562
- boundHandleClick;
3563
- boundHandleKeydown;
3564
- /** Popover type - 'manual' krever manuell lukking, 'auto' lukkes ved klikk utenfor */
3565
- type = 'manual';
3340
+ /** Popover type - 'auto' lukkes ved klikk utenfor eller Escape, 'manual' krever manuell lukking */
3341
+ type = 'auto';
3566
3342
  /** Visuell variant */
3567
3343
  variant = 'default';
3568
3344
  /** Farge-tema */
@@ -3575,113 +3351,18 @@ class HviPopover {
3575
3351
  opened = new EventEmitter();
3576
3352
  /** Event når popover lukkes */
3577
3353
  closed = new EventEmitter();
3578
- get popoverElement() {
3579
- return this.el.nativeElement;
3580
- }
3581
- get triggerElement() {
3582
- const id = this.popoverElement.id;
3583
- return id ? document.querySelector(`[popovertarget="${id}"]`) : null;
3584
- }
3585
- ngOnInit() {
3586
- this.setupEventListeners();
3587
- }
3588
- ngOnDestroy() {
3589
- this.stopAutoUpdate();
3590
- this.removeEventListeners();
3591
- }
3592
- setupEventListeners() {
3593
- const popover = this.popoverElement;
3594
- // Click utenfor lukker popover
3595
- this.boundHandleClick = (event) => {
3596
- const el = event.target;
3597
- const isTrigger = el?.closest?.(`[popovertarget="${popover.id}"]`);
3598
- const isOutside = !isTrigger && !popover.contains(el);
3599
- if (isTrigger) {
3600
- event.preventDefault();
3601
- popover.togglePopover?.();
3602
- }
3603
- if (isOutside && popover.matches(':popover-open')) {
3604
- popover.togglePopover?.();
3605
- }
3606
- };
3607
- // Escape lukker popover
3608
- this.boundHandleKeydown = (event) => {
3609
- if (event.key !== 'Escape' || !popover.matches(':popover-open'))
3610
- return;
3611
- event.preventDefault();
3612
- popover.togglePopover?.();
3613
- };
3614
- addEventListener('click', this.boundHandleClick);
3615
- addEventListener('keydown', this.boundHandleKeydown);
3616
- // Toggle events
3617
- popover.addEventListener('beforetoggle', this.handleBeforeToggle);
3618
- popover.addEventListener('toggle', this.handleToggle);
3619
- }
3620
- removeEventListeners() {
3621
- if (this.boundHandleClick) {
3622
- removeEventListener('click', this.boundHandleClick);
3623
- }
3624
- if (this.boundHandleKeydown) {
3625
- removeEventListener('keydown', this.boundHandleKeydown);
3626
- }
3627
- this.popoverElement.removeEventListener('beforetoggle', this.handleBeforeToggle);
3628
- this.popoverElement.removeEventListener('toggle', this.handleToggle);
3629
- }
3630
- handleBeforeToggle = (event) => {
3631
- const toggleEvent = event;
3632
- if (toggleEvent.newState === 'open') {
3633
- this.updatePosition();
3634
- }
3635
- };
3636
- handleToggle = (event) => {
3637
- const toggleEvent = event;
3638
- if (toggleEvent.newState === 'open') {
3639
- this.startAutoUpdate();
3354
+ onToggle(event) {
3355
+ if (event.newState === 'open') {
3640
3356
  this.opened.emit();
3641
3357
  }
3642
3358
  else {
3643
- this.stopAutoUpdate();
3644
3359
  this.closed.emit();
3645
3360
  }
3646
- };
3647
- updatePosition() {
3648
- const trigger = this.triggerElement;
3649
- const popover = this.popoverElement;
3650
- if (!trigger || !popover)
3651
- return;
3652
- computePosition(trigger, popover, {
3653
- placement: this.placement,
3654
- strategy: 'fixed',
3655
- middleware: [
3656
- offset((data) => {
3657
- const styles = getComputedStyle(data.elements.floating, '::before');
3658
- return parseFloat(styles.height) || 12;
3659
- }),
3660
- ...(this.autoPlacement ? [flip({ fallbackAxisSideDirection: 'start' }), shift()] : []),
3661
- arrowPseudoElement,
3662
- ],
3663
- }).then(({ x, y }) => {
3664
- popover.style.translate = `${x}px ${y}px`;
3665
- });
3666
- }
3667
- startAutoUpdate() {
3668
- this.stopAutoUpdate();
3669
- const trigger = this.triggerElement;
3670
- const popover = this.popoverElement;
3671
- if (!trigger || !popover)
3672
- return;
3673
- this.cleanupAutoUpdate = autoUpdate(trigger, popover, () => this.updatePosition());
3674
3361
  }
3675
- stopAutoUpdate() {
3676
- if (this.cleanupAutoUpdate) {
3677
- this.cleanupAutoUpdate();
3678
- this.cleanupAutoUpdate = undefined;
3679
- }
3680
- }
3681
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviPopover, deps: [], target: i0.ɵɵFactoryTarget.Component });
3682
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviPopover, isStandalone: true, selector: "hvi-popover", inputs: { type: "type", variant: "variant", color: "color", placement: "placement", autoPlacement: "autoPlacement" }, outputs: { opened: "opened", closed: "closed" }, host: { properties: { "attr.popover": "type", "attr.data-variant": "variant", "attr.data-color": "color" }, classAttribute: "ds-popover" }, ngImport: i0, template: '<ng-content />', isInline: true });
3362
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviPopover, deps: [], target: i0.ɵɵFactoryTarget.Component });
3363
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviPopover, isStandalone: true, selector: "hvi-popover", inputs: { type: "type", variant: "variant", color: "color", placement: "placement", autoPlacement: "autoPlacement" }, outputs: { opened: "opened", closed: "closed" }, host: { listeners: { "toggle": "onToggle($event)" }, properties: { "attr.popover": "type", "attr.data-variant": "variant", "attr.data-color": "color", "attr.data-placement": "placement", "attr.data-autoplacement": "autoPlacement ? \"\" : null" }, classAttribute: "ds-popover" }, ngImport: i0, template: '<ng-content />', isInline: true });
3683
3364
  }
3684
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviPopover, decorators: [{
3365
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviPopover, decorators: [{
3685
3366
  type: Component,
3686
3367
  args: [{
3687
3368
  selector: 'hvi-popover',
@@ -3692,6 +3373,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
3692
3373
  '[attr.popover]': 'type',
3693
3374
  '[attr.data-variant]': 'variant',
3694
3375
  '[attr.data-color]': 'color',
3376
+ '[attr.data-placement]': 'placement',
3377
+ '[attr.data-autoplacement]': 'autoPlacement ? "" : null',
3695
3378
  },
3696
3379
  }]
3697
3380
  }], propDecorators: { type: [{
@@ -3708,112 +3391,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
3708
3391
  type: Output
3709
3392
  }], closed: [{
3710
3393
  type: Output
3711
- }] } });
3712
-
3713
- /**
3714
- * @summary
3715
- * Tag is a label that can be used to categorize items or communicate progress, status, or process. Tags can provide users with a quicker overview of content.
3716
- *
3717
- * @example
3718
- * ```html
3719
- * <hvi-tag variant="outline" size="sm" color="info">Small info tag</hvi-tag>
3720
- * ```
3721
- *
3722
- * Documentation: https://designsystemet.no/en/components/docs/tag/code
3723
- */
3724
- class HviTag {
3725
- /** The variants of the tag */
3726
- variant;
3727
- /** The sizes of the tag */
3728
- size;
3729
- /** The color theme of the tag */
3730
- color;
3731
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTag, deps: [], target: i0.ɵɵFactoryTarget.Component });
3732
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviTag, isStandalone: true, selector: "hvi-tag", inputs: { variant: "variant", size: "size", color: "color" }, host: { properties: { "attr.data-variant": "variant ?? null", "attr.data-size": "size ?? null", "attr.data-color": "color ?? null" }, classAttribute: "ds-tag" }, ngImport: i0, template: '<ng-content />', isInline: true });
3733
- }
3734
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTag, decorators: [{
3735
- type: Component,
3736
- args: [{
3737
- selector: 'hvi-tag',
3738
- standalone: true,
3739
- template: '<ng-content />',
3740
- host: {
3741
- class: 'ds-tag',
3742
- '[attr.data-variant]': 'variant ?? null',
3743
- '[attr.data-size]': 'size ?? null',
3744
- '[attr.data-color]': 'color ?? null',
3745
- },
3746
- }]
3747
- }], propDecorators: { variant: [{
3748
- type: Input
3749
- }], size: [{
3750
- type: Input
3751
- }], color: [{
3752
- type: Input
3753
- }] } });
3754
-
3755
- /**
3756
- * RequiredTag brukes sammen med labels i skjema for å indikere om et felt er
3757
- * påkrevd, valgfritt, eller om alle felt må fylles ut.
3758
- *
3759
- * Komponenten wrapper `HviTag` med forhåndsdefinerte tekster og farger basert på mode.
3760
- *
3761
- * @example
3762
- * ```html
3763
- * <hvi-required-tag />
3764
- * <hvi-required-tag mode="optional" />
3765
- * <hvi-required-tag mode="all-required" />
3766
- * ```
3767
- */
3768
- class HviRequiredTag {
3769
- /**
3770
- * Bestemmer tekst og farge på taggen.
3771
- * - `required` (default): "Må fylles ut" (warning)
3772
- * - `optional`: "Valgfritt" (info)
3773
- * - `all-required`: "Alle felt må fylles ut" (warning)
3774
- */
3775
- mode = 'required';
3776
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviRequiredTag, deps: [], target: i0.ɵɵFactoryTarget.Component });
3777
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: HviRequiredTag, isStandalone: true, selector: "hvi-required-tag", inputs: { mode: "mode" }, ngImport: i0, template: `
3778
- <hvi-tag variant="default" size="sm" [color]="mode === 'optional' ? 'info' : 'warning'">
3779
- @switch (mode) {
3780
- @case ('all-required') {
3781
- Alle felt må fylles ut
3782
- }
3783
- @case ('required') {
3784
- Må fylles ut
3785
- }
3786
- @case ('optional') {
3787
- Valgfritt
3788
- }
3789
- }
3790
- </hvi-tag>
3791
- `, isInline: true, dependencies: [{ kind: "component", type: HviTag, selector: "hvi-tag", inputs: ["variant", "size", "color"] }] });
3792
- }
3793
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviRequiredTag, decorators: [{
3794
- type: Component,
3795
- args: [{
3796
- selector: 'hvi-required-tag',
3797
- standalone: true,
3798
- imports: [HviTag],
3799
- template: `
3800
- <hvi-tag variant="default" size="sm" [color]="mode === 'optional' ? 'info' : 'warning'">
3801
- @switch (mode) {
3802
- @case ('all-required') {
3803
- Alle felt må fylles ut
3804
- }
3805
- @case ('required') {
3806
- Må fylles ut
3807
- }
3808
- @case ('optional') {
3809
- Valgfritt
3810
- }
3811
- }
3812
- </hvi-tag>
3813
- `,
3814
- }]
3815
- }], propDecorators: { mode: [{
3816
- type: Input
3394
+ }], onToggle: [{
3395
+ type: HostListener,
3396
+ args: ['toggle', ['$event']]
3817
3397
  }] } });
3818
3398
 
3819
3399
  /**
@@ -3847,10 +3427,10 @@ class HviSearchClear {
3847
3427
  input.focus();
3848
3428
  }
3849
3429
  }
3850
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSearchClear, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3851
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviSearchClear, isStandalone: true, selector: "button[hviSearchClear]", host: { attributes: { "type": "reset" }, listeners: { "click": "onClick($event)" }, properties: { "attr.data-icon": "\"true\"", "attr.data-variant": "\"tertiary\"" }, classAttribute: "ds-button" }, ngImport: i0 });
3430
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSearchClear, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3431
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviSearchClear, isStandalone: true, selector: "button[hviSearchClear]", host: { attributes: { "type": "reset" }, listeners: { "click": "onClick($event)" }, properties: { "attr.data-icon": "\"true\"", "attr.data-variant": "\"tertiary\"" }, classAttribute: "ds-button" }, ngImport: i0 });
3852
3432
  }
3853
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSearchClear, decorators: [{
3433
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSearchClear, decorators: [{
3854
3434
  type: Directive,
3855
3435
  args: [{
3856
3436
  selector: 'button[hviSearchClear]',
@@ -3913,10 +3493,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
3913
3493
  * @see {@link https://designsystemet.no/no/components/search}
3914
3494
  */
3915
3495
  class HviSearch {
3916
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSearch, deps: [], target: i0.ɵɵFactoryTarget.Component });
3917
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviSearch, isStandalone: true, selector: "hvi-search", host: { classAttribute: "ds-search" }, ngImport: i0, template: '<ng-content />', isInline: true });
3496
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSearch, deps: [], target: i0.ɵɵFactoryTarget.Component });
3497
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviSearch, isStandalone: true, selector: "hvi-search", host: { classAttribute: "ds-search" }, ngImport: i0, template: '<ng-content />', isInline: true });
3918
3498
  }
3919
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSearch, decorators: [{
3499
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSearch, decorators: [{
3920
3500
  type: Component,
3921
3501
  args: [{
3922
3502
  selector: 'hvi-search',
@@ -3982,10 +3562,10 @@ class HviSelect {
3982
3562
  event.stopImmediatePropagation();
3983
3563
  }
3984
3564
  }
3985
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSelect, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3986
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.1", type: HviSelect, isStandalone: true, selector: "select[hviSelect]", inputs: { width: "width", disabled: ["disabled", "disabled", booleanAttribute], readOnly: ["readOnly", "readOnly", booleanAttribute] }, host: { listeners: { "mousedown": "onMouseDown($event)", "change": "onChange($event)", "keydown": "onKeydown($event)" }, properties: { "attr.data-width": "width", "attr.readonly": "_readOnly ? \"\" : null", "attr.disabled": "_disabled ? \"\" : null" }, classAttribute: "ds-select ds-input" }, ngImport: i0 });
3565
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSelect, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3566
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.6", type: HviSelect, isStandalone: true, selector: "select[hviSelect]", inputs: { width: "width", disabled: ["disabled", "disabled", booleanAttribute], readOnly: ["readOnly", "readOnly", booleanAttribute] }, host: { listeners: { "mousedown": "onMouseDown($event)", "change": "onChange($event)", "keydown": "onKeydown($event)" }, properties: { "attr.data-width": "width", "attr.readonly": "_readOnly ? \"\" : null", "attr.disabled": "_disabled ? \"\" : null" }, classAttribute: "ds-select ds-input" }, ngImport: i0 });
3987
3567
  }
3988
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSelect, decorators: [{
3568
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSelect, decorators: [{
3989
3569
  type: Directive,
3990
3570
  args: [{
3991
3571
  selector: 'select[hviSelect]',
@@ -4031,10 +3611,10 @@ class HviSkeleton {
4031
3611
  variant = 'rectangle';
4032
3612
  width;
4033
3613
  height;
4034
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSkeleton, deps: [], target: i0.ɵɵFactoryTarget.Component });
4035
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviSkeleton, isStandalone: true, selector: "hvi-skeleton", inputs: { variant: "variant", width: "width", height: "height" }, host: { properties: { "attr.aria-hidden": "true", "attr.data-variant": "variant", "style.width": "width", "style.height": "height" }, classAttribute: "ds-skeleton" }, ngImport: i0, template: '<ng-content />', isInline: true });
3614
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSkeleton, deps: [], target: i0.ɵɵFactoryTarget.Component });
3615
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviSkeleton, isStandalone: true, selector: "hvi-skeleton", inputs: { variant: "variant", width: "width", height: "height" }, host: { properties: { "attr.aria-hidden": "true", "attr.data-variant": "variant", "style.width": "width", "style.height": "height" }, classAttribute: "ds-skeleton" }, ngImport: i0, template: '<ng-content />', isInline: true });
4036
3616
  }
4037
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSkeleton, decorators: [{
3617
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSkeleton, decorators: [{
4038
3618
  type: Component,
4039
3619
  args: [{
4040
3620
  selector: 'hvi-skeleton',
@@ -4090,10 +3670,10 @@ class HviSkipLink {
4090
3670
  target.scrollIntoView({ behavior: 'smooth', block: 'start' });
4091
3671
  }
4092
3672
  }
4093
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSkipLink, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4094
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviSkipLink, isStandalone: true, selector: "a[hviSkipLink]", host: { listeners: { "click": "onClick($event)" }, classAttribute: "ds-skip-link" }, ngImport: i0 });
3673
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSkipLink, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3674
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviSkipLink, isStandalone: true, selector: "a[hviSkipLink]", host: { listeners: { "click": "onClick($event)" }, classAttribute: "ds-skip-link" }, ngImport: i0 });
4095
3675
  }
4096
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSkipLink, decorators: [{
3676
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSkipLink, decorators: [{
4097
3677
  type: Directive,
4098
3678
  args: [{
4099
3679
  selector: 'a[hviSkipLink]',
@@ -4125,8 +3705,8 @@ class HviSpinner {
4125
3705
  label;
4126
3706
  /** Size of the spinner */
4127
3707
  size;
4128
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSpinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
4129
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviSpinner, isStandalone: true, selector: "hvi-spinner", inputs: { label: "label", size: "size" }, host: { styleAttribute: "display: contents;" }, ngImport: i0, template: `
3708
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSpinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
3709
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviSpinner, isStandalone: true, selector: "hvi-spinner", inputs: { label: "label", size: "size" }, host: { styleAttribute: "display: contents;" }, ngImport: i0, template: `
4130
3710
  <svg
4131
3711
  [attr.aria-label]="label"
4132
3712
  class="ds-spinner"
@@ -4139,7 +3719,7 @@ class HviSpinner {
4139
3719
  </svg>
4140
3720
  `, isInline: true });
4141
3721
  }
4142
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSpinner, decorators: [{
3722
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSpinner, decorators: [{
4143
3723
  type: Component,
4144
3724
  args: [{
4145
3725
  selector: 'hvi-spinner',
@@ -4242,22 +3822,22 @@ class HviTable {
4242
3822
  /** Event som emitteres med nåværende side (1-basert, for two-way binding) */
4243
3823
  currentPageChange = new EventEmitter();
4244
3824
  // Internal signals
4245
- _value = signal([], ...(ngDevMode ? [{ debugName: "_value" }] : []));
4246
- _sortField = signal(null, ...(ngDevMode ? [{ debugName: "_sortField" }] : []));
4247
- _sortOrder = signal(0, ...(ngDevMode ? [{ debugName: "_sortOrder" }] : [])); // 0 = none, 1 = asc, -1 = desc
4248
- _globalFilter = signal(null, ...(ngDevMode ? [{ debugName: "_globalFilter" }] : []));
4249
- _rows = signal(10, ...(ngDevMode ? [{ debugName: "_rows" }] : []));
4250
- _first = signal(0, ...(ngDevMode ? [{ debugName: "_first" }] : []));
3825
+ _value = signal([], ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
3826
+ _sortField = signal(null, ...(ngDevMode ? [{ debugName: "_sortField" }] : /* istanbul ignore next */ []));
3827
+ _sortOrder = signal(0, ...(ngDevMode ? [{ debugName: "_sortOrder" }] : /* istanbul ignore next */ [])); // 0 = none, 1 = asc, -1 = desc
3828
+ _globalFilter = signal(null, ...(ngDevMode ? [{ debugName: "_globalFilter" }] : /* istanbul ignore next */ []));
3829
+ _rows = signal(10, ...(ngDevMode ? [{ debugName: "_rows" }] : /* istanbul ignore next */ []));
3830
+ _first = signal(0, ...(ngDevMode ? [{ debugName: "_first" }] : /* istanbul ignore next */ []));
4251
3831
  /** Kun sortert data (uten søk) - for bakoverkompatibilitet */
4252
3832
  sortedValue = computed(() => {
4253
3833
  return this.applySorting(this._value());
4254
- }, ...(ngDevMode ? [{ debugName: "sortedValue" }] : []));
3834
+ }, ...(ngDevMode ? [{ debugName: "sortedValue" }] : /* istanbul ignore next */ []));
4255
3835
  /** Filtrert og sortert data - bruk denne i template */
4256
3836
  filteredValue = computed(() => {
4257
3837
  const data = this._value();
4258
3838
  const filtered = this.applyGlobalFilter(data);
4259
3839
  return this.applySorting(filtered);
4260
- }, ...(ngDevMode ? [{ debugName: "filteredValue" }] : []));
3840
+ }, ...(ngDevMode ? [{ debugName: "filteredValue" }] : /* istanbul ignore next */ []));
4261
3841
  /** Paginert, filtrert og sortert data - bruk denne når paginator er aktivert */
4262
3842
  paginatedValue = computed(() => {
4263
3843
  const data = this.filteredValue();
@@ -4266,29 +3846,29 @@ class HviTable {
4266
3846
  const first = this._first();
4267
3847
  const rows = this._rows();
4268
3848
  return data.slice(first, first + rows);
4269
- }, ...(ngDevMode ? [{ debugName: "paginatedValue" }] : []));
3849
+ }, ...(ngDevMode ? [{ debugName: "paginatedValue" }] : /* istanbul ignore next */ []));
4270
3850
  /** Antall rader etter søk */
4271
- totalFilteredRecords = computed(() => this.filteredValue().length, ...(ngDevMode ? [{ debugName: "totalFilteredRecords" }] : []));
3851
+ totalFilteredRecords = computed(() => this.filteredValue().length, ...(ngDevMode ? [{ debugName: "totalFilteredRecords" }] : /* istanbul ignore next */ []));
4272
3852
  /** Antall rader totalt (før søk) */
4273
- totalRecords = computed(() => this._value().length, ...(ngDevMode ? [{ debugName: "totalRecords" }] : []));
3853
+ totalRecords = computed(() => this._value().length, ...(ngDevMode ? [{ debugName: "totalRecords" }] : /* istanbul ignore next */ []));
4274
3854
  /** Totalt antall sider */
4275
3855
  pageCount = computed(() => {
4276
3856
  if (!this.paginator)
4277
3857
  return 1;
4278
3858
  return Math.max(1, Math.ceil(this.totalFilteredRecords() / this._rows()));
4279
- }, ...(ngDevMode ? [{ debugName: "pageCount" }] : []));
3859
+ }, ...(ngDevMode ? [{ debugName: "pageCount" }] : /* istanbul ignore next */ []));
4280
3860
  /** Nåværende side (1-basert) */
4281
3861
  currentPage = computed(() => {
4282
3862
  return Math.floor(this._first() / this._rows()) + 1;
4283
- }, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
3863
+ }, ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
4284
3864
  /** Er vi på første side? */
4285
- isFirstPage = computed(() => this._first() === 0, ...(ngDevMode ? [{ debugName: "isFirstPage" }] : []));
3865
+ isFirstPage = computed(() => this._first() === 0, ...(ngDevMode ? [{ debugName: "isFirstPage" }] : /* istanbul ignore next */ []));
4286
3866
  /** Er vi på siste side? */
4287
3867
  isLastPage = computed(() => {
4288
3868
  return this._first() + this._rows() >= this.totalFilteredRecords();
4289
- }, ...(ngDevMode ? [{ debugName: "isLastPage" }] : []));
3869
+ }, ...(ngDevMode ? [{ debugName: "isLastPage" }] : /* istanbul ignore next */ []));
4290
3870
  /** Nåværende sorteringsfelt */
4291
- currentSortField = computed(() => this._sortField(), ...(ngDevMode ? [{ debugName: "currentSortField" }] : []));
3871
+ currentSortField = computed(() => this._sortField(), ...(ngDevMode ? [{ debugName: "currentSortField" }] : /* istanbul ignore next */ []));
4292
3872
  /** Nåværende sorteringsretning som SortDirection */
4293
3873
  currentSortDirection = computed(() => {
4294
3874
  const order = this._sortOrder();
@@ -4297,9 +3877,9 @@ class HviTable {
4297
3877
  if (order === -1)
4298
3878
  return 'descending';
4299
3879
  return 'none';
4300
- }, ...(ngDevMode ? [{ debugName: "currentSortDirection" }] : []));
3880
+ }, ...(ngDevMode ? [{ debugName: "currentSortDirection" }] : /* istanbul ignore next */ []));
4301
3881
  /** Nåværende søkeverdi */
4302
- currentGlobalFilter = computed(() => this._globalFilter(), ...(ngDevMode ? [{ debugName: "currentGlobalFilter" }] : []));
3882
+ currentGlobalFilter = computed(() => this._globalFilter(), ...(ngDevMode ? [{ debugName: "currentGlobalFilter" }] : /* istanbul ignore next */ []));
4303
3883
  /**
4304
3884
  * Global søk - søker på tvers av alle felt i globalFilterFields.
4305
3885
  * @param value Søkeverdi
@@ -4480,10 +4060,10 @@ class HviTable {
4480
4060
  }
4481
4061
  return value;
4482
4062
  }
4483
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTable, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4484
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.1", type: HviTable, isStandalone: true, selector: "[hviTable]", inputs: { zebra: ["zebra", "zebra", booleanAttribute], border: ["border", "border", booleanAttribute], hover: ["hover", "hover", booleanAttribute], stickyHeader: ["stickyHeader", "stickyHeader", booleanAttribute], value: "value", sortField: "sortField", sortOrder: "sortOrder", globalFilterFields: "globalFilterFields", paginator: ["paginator", "paginator", booleanAttribute], rows: ["rows", "rows", numberAttribute], first: ["first", "first", numberAttribute] }, outputs: { sortChange: "sortChange", pageChange: "pageChange", currentPageChange: "currentPageChange" }, host: { properties: { "attr.data-zebra": "zebra || null", "attr.data-border": "border || null", "attr.data-hover": "hover || null", "attr.data-sticky-header": "stickyHeader || null" }, classAttribute: "ds-table" }, exportAs: ["hviTable"], ngImport: i0 });
4063
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTable, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4064
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.6", type: HviTable, isStandalone: true, selector: "[hviTable]", inputs: { zebra: ["zebra", "zebra", booleanAttribute], border: ["border", "border", booleanAttribute], hover: ["hover", "hover", booleanAttribute], stickyHeader: ["stickyHeader", "stickyHeader", booleanAttribute], value: "value", sortField: "sortField", sortOrder: "sortOrder", globalFilterFields: "globalFilterFields", paginator: ["paginator", "paginator", booleanAttribute], rows: ["rows", "rows", numberAttribute], first: ["first", "first", numberAttribute] }, outputs: { sortChange: "sortChange", pageChange: "pageChange", currentPageChange: "currentPageChange" }, host: { properties: { "attr.data-zebra": "zebra || null", "attr.data-border": "border || null", "attr.data-hover": "hover || null", "attr.data-sticky-header": "stickyHeader || null" }, classAttribute: "ds-table" }, exportAs: ["hviTable"], ngImport: i0 });
4485
4065
  }
4486
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTable, decorators: [{
4066
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTable, decorators: [{
4487
4067
  type: Directive,
4488
4068
  args: [{
4489
4069
  selector: '[hviTable]',
@@ -4583,10 +4163,10 @@ class HviSortableColumn {
4583
4163
  this.table?.sort(this.field);
4584
4164
  }
4585
4165
  }
4586
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSortableColumn, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4587
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviSortableColumn, isStandalone: true, selector: "th[hviSortableColumn]", inputs: { field: ["hviSortableColumn", "field"] }, host: { listeners: { "click": "onClick($event)" }, properties: { "attr.aria-sort": "sortDirection" } }, ngImport: i0 });
4166
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSortableColumn, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4167
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviSortableColumn, isStandalone: true, selector: "th[hviSortableColumn]", inputs: { field: ["hviSortableColumn", "field"] }, host: { listeners: { "click": "onClick($event)" }, properties: { "attr.aria-sort": "sortDirection" } }, ngImport: i0 });
4588
4168
  }
4589
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviSortableColumn, decorators: [{
4169
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviSortableColumn, decorators: [{
4590
4170
  type: Directive,
4591
4171
  args: [{
4592
4172
  selector: 'th[hviSortableColumn]',
@@ -4617,14 +4197,14 @@ class HviTabPanel {
4617
4197
  templateRef;
4618
4198
  /** When this value is selected, render this TabPanel. Must match the value of a Tab. */
4619
4199
  value;
4620
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTabPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
4621
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviTabPanel, isStandalone: true, selector: "hvi-tab-panel", inputs: { value: "value" }, viewQueries: [{ propertyName: "templateRef", first: true, predicate: ["content"], descendants: true, static: true }], ngImport: i0, template: `
4200
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTabPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
4201
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviTabPanel, isStandalone: true, selector: "hvi-tab-panel", inputs: { value: "value" }, viewQueries: [{ propertyName: "templateRef", first: true, predicate: ["content"], descendants: true, static: true }], ngImport: i0, template: `
4622
4202
  <ng-template #content>
4623
4203
  <ng-content />
4624
4204
  </ng-template>
4625
4205
  `, isInline: true });
4626
4206
  }
4627
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTabPanel, decorators: [{
4207
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTabPanel, decorators: [{
4628
4208
  type: Component,
4629
4209
  args: [{
4630
4210
  selector: 'hvi-tab-panel',
@@ -4655,14 +4235,14 @@ class HviTab {
4655
4235
  templateRef;
4656
4236
  /** Unique value that will be set in the Tabs components state when the tab is activated */
4657
4237
  value;
4658
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTab, deps: [], target: i0.ɵɵFactoryTarget.Component });
4659
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviTab, isStandalone: true, selector: "hvi-tab", inputs: { value: "value" }, viewQueries: [{ propertyName: "templateRef", first: true, predicate: ["content"], descendants: true, static: true }], ngImport: i0, template: `
4238
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTab, deps: [], target: i0.ɵɵFactoryTarget.Component });
4239
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviTab, isStandalone: true, selector: "hvi-tab", inputs: { value: "value" }, viewQueries: [{ propertyName: "templateRef", first: true, predicate: ["content"], descendants: true, static: true }], ngImport: i0, template: `
4660
4240
  <ng-template #content>
4661
4241
  <ng-content />
4662
4242
  </ng-template>
4663
4243
  `, isInline: true });
4664
4244
  }
4665
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTab, decorators: [{
4245
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTab, decorators: [{
4666
4246
  type: Component,
4667
4247
  args: [{
4668
4248
  selector: 'hvi-tab',
@@ -4736,8 +4316,8 @@ class HviTabs {
4736
4316
  }
4737
4317
  });
4738
4318
  }
4739
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTabs, deps: [], target: i0.ɵɵFactoryTarget.Component });
4740
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: HviTabs, isStandalone: true, selector: "hvi-tabs", inputs: { value: "value", defaultValue: "defaultValue" }, outputs: { valueChange: "valueChange" }, queries: [{ propertyName: "tabs", predicate: HviTab }, { propertyName: "panels", predicate: HviTabPanel }], viewQueries: [{ propertyName: "uTabsRef", first: true, predicate: ["uTabsRef"], descendants: true }], ngImport: i0, template: `
4319
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTabs, deps: [], target: i0.ɵɵFactoryTarget.Component });
4320
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: HviTabs, isStandalone: true, selector: "hvi-tabs", inputs: { value: "value", defaultValue: "defaultValue" }, outputs: { valueChange: "valueChange" }, queries: [{ propertyName: "tabs", predicate: HviTab }, { propertyName: "panels", predicate: HviTabPanel }], viewQueries: [{ propertyName: "uTabsRef", first: true, predicate: ["uTabsRef"], descendants: true }], ngImport: i0, template: `
4741
4321
  <u-tabs #uTabsRef class="ds-tabs">
4742
4322
  <u-tablist>
4743
4323
  @for (tab of tabs; track tab.value) {
@@ -4758,7 +4338,7 @@ class HviTabs {
4758
4338
  </div>
4759
4339
  `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
4760
4340
  }
4761
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTabs, decorators: [{
4341
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTabs, decorators: [{
4762
4342
  type: Component,
4763
4343
  args: [{
4764
4344
  selector: 'hvi-tabs',
@@ -4842,12 +4422,46 @@ class HviTextfield {
4842
4422
  /** Character counter limit. Displays a counter below the field. */
4843
4423
  counterLimit;
4844
4424
  /**
4845
- * Label text shown in a warning Tag next to the label when the field is required.
4846
- * E.g. "Må fylles ut". Also sets the `required` attribute on the input.
4425
+ * Manuell overstyring av required-tag-mode.
4426
+ * Når satt, vises taggen uavhengig av HviForm-kontekst.
4427
+ * - `'required'`: "Må fylles ut" (warning)
4428
+ * - `'optional'`: "Valgfritt" (info)
4429
+ *
4430
+ * Når IKKE satt og feltet er inne i en `<form hviForm>`, bestemmes mode automatisk:
4431
+ * - Form er `'all-required'` → ingen tag per felt (vis `all-required` øverst i form)
4432
+ * - Form er `'mixed'` → `'required'` hvis feltet er required, `'optional'` hvis ikke
4433
+ * - Form er `'none'` → ingen tag
4847
4434
  */
4848
- requiredLabel;
4435
+ requiredMode;
4849
4436
  /** Autocomplete attribute for the input, e.g. 'given-name', 'email'. */
4850
4437
  autocomplete;
4438
+ /** Injisert HviForm for automatisk required-tag-beregning */
4439
+ hviForm = inject(HviForm, { optional: true });
4440
+ /**
4441
+ * Beregnet required-tag-mode basert på manuell overstyring eller HviForm-kontekst.
4442
+ * Returnerer `null` hvis ingen tag skal vises.
4443
+ */
4444
+ get effectiveRequiredMode() {
4445
+ // Manuell overstyring vinner alltid
4446
+ if (this.requiredMode)
4447
+ return this.requiredMode;
4448
+ // Uten HviForm-kontekst eller med tags skrudd av: ingen automatikk
4449
+ const form = this.hviForm;
4450
+ if (!form || !form.showRequiredTags)
4451
+ return null;
4452
+ const formMode = form.requiredMode();
4453
+ switch (formMode) {
4454
+ case 'all-required':
4455
+ // Alle er required – vis ingen tag per felt (all-required vises øverst i form)
4456
+ return null;
4457
+ case 'mixed':
4458
+ // Blanding – vis required eller optional basert på feltets required-state
4459
+ return this._required ? 'required' : 'optional';
4460
+ case 'none':
4461
+ default:
4462
+ return null;
4463
+ }
4464
+ }
4851
4465
  /** Render a textarea instead of input for multiline support */
4852
4466
  multiline = false;
4853
4467
  /** Supported input types */
@@ -4905,8 +4519,8 @@ class HviTextfield {
4905
4519
  setDisabledState(isDisabled) {
4906
4520
  this._disabled = isDisabled;
4907
4521
  }
4908
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTextfield, deps: [], target: i0.ɵɵFactoryTarget.Component });
4909
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: HviTextfield, isStandalone: true, selector: "hvi-textfield", inputs: { label: "label", description: "description", prefix: "prefix", suffix: "suffix", error: "error", counterLimit: "counterLimit", requiredLabel: "requiredLabel", autocomplete: "autocomplete", multiline: ["multiline", "multiline", booleanAttribute], type: "type", rows: "rows", size: "size", placeholder: "placeholder", name: "name", id: "id", maxLength: "maxLength", value: "value", required: ["required", "required", booleanAttribute], disabled: ["disabled", "disabled", booleanAttribute], readOnly: ["readOnly", "readOnly", booleanAttribute] }, providers: [
4522
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTextfield, deps: [], target: i0.ɵɵFactoryTarget.Component });
4523
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: HviTextfield, isStandalone: true, selector: "hvi-textfield", inputs: { label: "label", description: "description", prefix: "prefix", suffix: "suffix", error: "error", counterLimit: "counterLimit", requiredMode: "requiredMode", autocomplete: "autocomplete", multiline: ["multiline", "multiline", booleanAttribute], type: "type", rows: "rows", size: "size", placeholder: "placeholder", name: "name", id: "id", maxLength: "maxLength", value: "value", required: ["required", "required", booleanAttribute], disabled: ["disabled", "disabled", booleanAttribute], readOnly: ["readOnly", "readOnly", booleanAttribute] }, providers: [
4910
4524
  {
4911
4525
  provide: NG_VALUE_ACCESSOR,
4912
4526
  useExisting: forwardRef(() => HviTextfield),
@@ -4916,13 +4530,8 @@ class HviTextfield {
4916
4530
  <hvi-field>
4917
4531
  <label hviLabel [attr.for]="inputId" weight="medium">
4918
4532
  {{ label }}
4919
- @if (requiredLabel) {
4920
- <hvi-tag
4921
- variant="default"
4922
- color="warning"
4923
- style="margin-inline-start: var(--ds-size-2)"
4924
- >{{ requiredLabel }}</hvi-tag
4925
- >
4533
+ @if (effectiveRequiredMode; as mode) {
4534
+ <hvi-required-tag [mode]="mode" />
4926
4535
  }
4927
4536
  </label>
4928
4537
  @if (description) {
@@ -4979,14 +4588,11 @@ class HviTextfield {
4979
4588
  <span hviFieldValidation>{{ error }}</span>
4980
4589
  }
4981
4590
  </hvi-field>
4982
- `, isInline: true, dependencies: [{ kind: "component", type: HviField, selector: "hvi-field", inputs: ["position"] }, { kind: "directive", type: HviLabel, selector: "label[hviLabel], legend[hviLabel]", inputs: ["weight"] }, { kind: "directive", type: HviInput, selector: "input[hviInput], textarea[hviInput]", inputs: ["type", "size", "role", "disabled", "readOnly", "readonly"] }, { kind: "component", type: HviFieldAffixes, selector: "hvi-field-affixes" }, { kind: "component", type: HviFieldAffix, selector: "hvi-field-affix" }, { kind: "component", type: HviFieldCounter, selector: "hvi-field-counter", inputs: ["count", "limit", "over", "under", "hint"] }, { kind: "directive", type: HviFieldDescription, selector: "[hviFieldDescription]" }, { kind: "directive", type: HviFieldValidation, selector: "[hviFieldValidation]" }, { kind: "component", type: HviTag, selector: "hvi-tag", inputs: ["variant", "size", "color"] }] });
4591
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: HviField, selector: "hvi-field", inputs: ["position"] }, { kind: "directive", type: HviLabel, selector: "label[hviLabel], legend[hviLabel]", inputs: ["weight"] }, { kind: "directive", type: HviInput, selector: "input[hviInput], textarea[hviInput]", inputs: ["type", "size", "role", "disabled", "readOnly", "readonly"] }, { kind: "component", type: HviFieldAffixes, selector: "hvi-field-affixes" }, { kind: "component", type: HviFieldAffix, selector: "hvi-field-affix" }, { kind: "component", type: HviFieldCounter, selector: "hvi-field-counter", inputs: ["limit", "over", "under"] }, { kind: "directive", type: HviFieldDescription, selector: "[hviFieldDescription]" }, { kind: "directive", type: HviFieldValidation, selector: "[hviFieldValidation]" }, { kind: "component", type: HviRequiredTag, selector: "hvi-required-tag", inputs: ["mode"] }] });
4983
4592
  }
4984
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTextfield, decorators: [{
4593
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTextfield, decorators: [{
4985
4594
  type: Component,
4986
- args: [{
4987
- selector: 'hvi-textfield',
4988
- standalone: true,
4989
- imports: [
4595
+ args: [{ selector: 'hvi-textfield', standalone: true, imports: [
4990
4596
  HviField,
4991
4597
  HviLabel,
4992
4598
  HviInput,
@@ -4995,26 +4601,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
4995
4601
  HviFieldCounter,
4996
4602
  HviFieldDescription,
4997
4603
  HviFieldValidation,
4998
- HviTag,
4999
- ],
5000
- providers: [
4604
+ HviRequiredTag,
4605
+ ], providers: [
5001
4606
  {
5002
4607
  provide: NG_VALUE_ACCESSOR,
5003
4608
  useExisting: forwardRef(() => HviTextfield),
5004
4609
  multi: true,
5005
4610
  },
5006
- ],
5007
- template: `
4611
+ ], template: `
5008
4612
  <hvi-field>
5009
4613
  <label hviLabel [attr.for]="inputId" weight="medium">
5010
4614
  {{ label }}
5011
- @if (requiredLabel) {
5012
- <hvi-tag
5013
- variant="default"
5014
- color="warning"
5015
- style="margin-inline-start: var(--ds-size-2)"
5016
- >{{ requiredLabel }}</hvi-tag
5017
- >
4615
+ @if (effectiveRequiredMode; as mode) {
4616
+ <hvi-required-tag [mode]="mode" />
5018
4617
  }
5019
4618
  </label>
5020
4619
  @if (description) {
@@ -5071,8 +4670,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
5071
4670
  <span hviFieldValidation>{{ error }}</span>
5072
4671
  }
5073
4672
  </hvi-field>
5074
- `,
5075
- }]
4673
+ `, styles: [":host{display:block}\n"] }]
5076
4674
  }], propDecorators: { label: [{
5077
4675
  type: Input
5078
4676
  }], description: [{
@@ -5085,7 +4683,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
5085
4683
  type: Input
5086
4684
  }], counterLimit: [{
5087
4685
  type: Input
5088
- }], requiredLabel: [{
4686
+ }], requiredMode: [{
5089
4687
  type: Input
5090
4688
  }], autocomplete: [{
5091
4689
  type: Input
@@ -5149,11 +4747,11 @@ class HviToggleGroup {
5149
4747
  items;
5150
4748
  registeredItems = [];
5151
4749
  /** The variant of the toggle group */
5152
- _variant = signal('primary', ...(ngDevMode ? [{ debugName: "_variant" }] : []));
4750
+ _variant = signal('primary', ...(ngDevMode ? [{ debugName: "_variant" }] : /* istanbul ignore next */ []));
5153
4751
  /** Form element name */
5154
- _name = signal(`togglegroup-name-${++nextGroupId}`, ...(ngDevMode ? [{ debugName: "_name" }] : []));
4752
+ _name = signal(`togglegroup-name-${++nextGroupId}`, ...(ngDevMode ? [{ debugName: "_name" }] : /* istanbul ignore next */ []));
5155
4753
  /** The currently selected value */
5156
- _value = signal(undefined, ...(ngDevMode ? [{ debugName: "_value" }] : []));
4754
+ _value = signal(undefined, ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
5157
4755
  /** Event emitted when value changes */
5158
4756
  valueChange = new EventEmitter();
5159
4757
  // ControlValueAccessor callbacks
@@ -5245,8 +4843,8 @@ class HviToggleGroup {
5245
4843
  registerOnTouched(fn) {
5246
4844
  this.onTouched = fn;
5247
4845
  }
5248
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviToggleGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
5249
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: HviToggleGroup, isStandalone: true, selector: "hvi-toggle-group", inputs: { value: "value", variant: "variant", name: "name" }, outputs: { valueChange: "valueChange" }, host: { attributes: { "role": "radiogroup" }, properties: { "attr.data-variant": "_variant()", "tabindex": "0" }, classAttribute: "ds-toggle-group" }, providers: [
4846
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviToggleGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
4847
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: HviToggleGroup, isStandalone: true, selector: "hvi-toggle-group", inputs: { value: "value", variant: "variant", name: "name" }, outputs: { valueChange: "valueChange" }, host: { attributes: { "role": "radiogroup" }, properties: { "attr.data-variant": "_variant()", "tabindex": "0" }, classAttribute: "ds-toggle-group" }, providers: [
5250
4848
  {
5251
4849
  provide: NG_VALUE_ACCESSOR,
5252
4850
  useExisting: forwardRef(() => HviToggleGroup),
@@ -5254,7 +4852,7 @@ class HviToggleGroup {
5254
4852
  },
5255
4853
  ], queries: [{ propertyName: "items", predicate: i0.forwardRef(() => HviToggleGroupItemToken) }], ngImport: i0, template: '<ng-content />', isInline: true });
5256
4854
  }
5257
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviToggleGroup, decorators: [{
4855
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviToggleGroup, decorators: [{
5258
4856
  type: Component,
5259
4857
  args: [{
5260
4858
  selector: 'hvi-toggle-group',
@@ -5314,13 +4912,13 @@ class HviToggleGroupItem {
5314
4912
  /** Toggle icon-only styling */
5315
4913
  icon = false;
5316
4914
  /** Internal signal for tracking selection state */
5317
- _isSelected = signal(false, ...(ngDevMode ? [{ debugName: "_isSelected" }] : []));
4915
+ _isSelected = signal(false, ...(ngDevMode ? [{ debugName: "_isSelected" }] : /* istanbul ignore next */ []));
5318
4916
  /** Whether this item is currently selected */
5319
4917
  isSelected = this._isSelected.asReadonly();
5320
4918
  /** Computed variant based on selection state */
5321
4919
  computedVariant = computed(() => {
5322
4920
  return this._isSelected() ? this.group._variant() : 'tertiary';
5323
- }, ...(ngDevMode ? [{ debugName: "computedVariant" }] : []));
4921
+ }, ...(ngDevMode ? [{ debugName: "computedVariant" }] : /* istanbul ignore next */ []));
5324
4922
  ngOnInit() {
5325
4923
  this.group.registerItem(this);
5326
4924
  }
@@ -5341,10 +4939,10 @@ class HviToggleGroupItem {
5341
4939
  onKeydown(event) {
5342
4940
  this.group.handleKeydown(event, this);
5343
4941
  }
5344
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviToggleGroupItem, deps: [], target: i0.ɵɵFactoryTarget.Directive });
5345
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.1", type: HviToggleGroupItem, isStandalone: true, selector: "button[hviToggleGroupItem]", inputs: { value: "value", icon: ["icon", "icon", booleanAttribute] }, host: { attributes: { "type": "button", "role": "radio" }, listeners: { "click": "onClick()", "keydown": "onKeydown($event)" }, properties: { "id": "id", "attr.value": "value", "attr.name": "group._name()", "attr.aria-checked": "isSelected()", "attr.aria-current": "isSelected()", "attr.data-variant": "computedVariant()", "attr.data-icon": "icon ? \"\" : null", "attr.data-roving-tabindex-item": "\"true\"", "tabindex": "isSelected() ? 0 : -1" }, classAttribute: "ds-button" }, ngImport: i0 });
4942
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviToggleGroupItem, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4943
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.6", type: HviToggleGroupItem, isStandalone: true, selector: "button[hviToggleGroupItem]", inputs: { value: "value", icon: ["icon", "icon", booleanAttribute] }, host: { attributes: { "type": "button", "role": "radio" }, listeners: { "click": "onClick()", "keydown": "onKeydown($event)" }, properties: { "id": "id", "attr.value": "value", "attr.name": "group._name()", "attr.aria-checked": "isSelected()", "attr.aria-current": "isSelected()", "attr.data-variant": "computedVariant()", "attr.data-icon": "icon ? \"\" : null", "attr.data-roving-tabindex-item": "\"true\"", "tabindex": "isSelected() ? 0 : -1" }, classAttribute: "ds-button" }, ngImport: i0 });
5346
4944
  }
5347
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviToggleGroupItem, decorators: [{
4945
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviToggleGroupItem, decorators: [{
5348
4946
  type: Directive,
5349
4947
  args: [{
5350
4948
  selector: 'button[hviToggleGroupItem]',
@@ -5374,41 +4972,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
5374
4972
  args: [{ transform: booleanAttribute }]
5375
4973
  }] } });
5376
4974
 
5377
- /** Plugin for positioning the tooltip arrow pseudo-element */
5378
- const tooltipArrowPlugin = {
5379
- name: 'TooltipArrowPlugin',
5380
- fn(data) {
5381
- const { elements, rects, placement } = data;
5382
- let arrowX = `${Math.round(rects.reference.width / 2 + rects.reference.x - data.x)}px`;
5383
- let arrowY = `${Math.round(rects.reference.height / 2 + rects.reference.y - data.y)}px`;
5384
- if (rects.reference.width > rects.floating.width) {
5385
- arrowX = `${Math.round(rects.floating.width / 2)}px`;
5386
- }
5387
- if (rects.reference.height > rects.floating.height) {
5388
- arrowY = `${Math.round(rects.floating.height / 2)}px`;
5389
- }
5390
- const basePlacement = placement.split('-')[0];
5391
- switch (basePlacement) {
5392
- case 'top':
5393
- arrowY = '100%';
5394
- break;
5395
- case 'right':
5396
- arrowX = '0';
5397
- break;
5398
- case 'bottom':
5399
- arrowY = '0';
5400
- break;
5401
- case 'left':
5402
- arrowX = '100%';
5403
- break;
5404
- }
5405
- elements.floating.setAttribute('data-placement', basePlacement);
5406
- elements.floating.style.setProperty('--dsc-tooltip-arrow-x', arrowX);
5407
- elements.floating.style.setProperty('--dsc-tooltip-arrow-y', arrowY);
5408
- return data;
5409
- },
5410
- };
5411
- let tooltipIdCounter = 0;
5412
4975
  /**
5413
4976
  * @summary
5414
4977
  * Tooltip viser kort informasjon når brukeren holder musepekeren over
@@ -5424,212 +4987,25 @@ let tooltipIdCounter = 0;
5424
4987
  * @see {@link https://designsystemet.no/en/components/docs/tooltip/code}
5425
4988
  */
5426
4989
  class HviTooltip {
5427
- el = inject((ElementRef));
5428
- renderer = inject(Renderer2);
5429
- tooltipElement = null;
5430
- tooltipId = `hvi-tooltip-${++tooltipIdCounter}`;
5431
- cleanupAutoUpdate;
5432
- showTimeout;
5433
- hideTimeout;
5434
- isOpen = false;
5435
- // Event listener cleanup functions
5436
- listeners = [];
5437
4990
  /** Tooltip content */
5438
4991
  hviTooltip = '';
5439
4992
  /** Placement of the tooltip relative to the trigger */
5440
4993
  tooltipPlacement = 'top';
5441
4994
  /** Enable auto placement when there's not enough space */
5442
4995
  tooltipAutoPlacement = true;
5443
- /**
5444
- * Override ARIA attribute type.
5445
- * - 'describedby': tooltip describes the element (default for elements with text)
5446
- * - 'labelledby': tooltip labels the element (default for icon-only buttons)
5447
- */
5448
- tooltipType;
5449
- /** Delay before showing tooltip (ms) */
5450
- tooltipShowDelay = 150;
5451
- /** Delay before hiding tooltip (ms) */
5452
- tooltipHideDelay = 0;
5453
- get hostElement() {
5454
- return this.el.nativeElement;
5455
- }
5456
- ngOnInit() {
5457
- this.createTooltipElement();
5458
- this.setupTriggerAttributes();
5459
- this.setupEventListeners();
5460
- }
5461
- ngOnDestroy() {
5462
- this.cleanup();
5463
- }
5464
- createTooltipElement() {
5465
- this.tooltipElement = this.renderer.createElement('span');
5466
- if (!this.tooltipElement)
5467
- return;
5468
- this.renderer.setAttribute(this.tooltipElement, 'id', this.tooltipId);
5469
- this.renderer.setAttribute(this.tooltipElement, 'role', 'tooltip');
5470
- this.renderer.setAttribute(this.tooltipElement, 'popover', 'manual');
5471
- this.renderer.addClass(this.tooltipElement, 'ds-tooltip');
5472
- this.renderer.setStyle(this.tooltipElement, 'opacity', '0');
5473
- // Set initial content
5474
- this.tooltipElement.textContent = this.hviTooltip;
5475
- // Append to body to avoid overflow issues
5476
- this.renderer.appendChild(document.body, this.tooltipElement);
5477
- }
5478
- setupTriggerAttributes() {
5479
- const host = this.hostElement;
5480
- // Set popovertarget attributes
5481
- this.renderer.setAttribute(host, 'popovertarget', this.tooltipId);
5482
- this.renderer.setAttribute(host, 'popovertargetaction', 'show');
5483
- // Determine ARIA attribute type
5484
- const ariaType = this.tooltipType ?? this.detectAriaType();
5485
- if (ariaType === 'labelledby') {
5486
- this.renderer.setAttribute(host, 'aria-labelledby', this.tooltipId);
5487
- }
5488
- else {
5489
- this.renderer.setAttribute(host, 'aria-describedby', this.tooltipId);
5490
- }
5491
- }
5492
- detectAriaType() {
5493
- const host = this.hostElement;
5494
- const hasText = host.textContent?.trim();
5495
- const hasAriaLabel = host.hasAttribute('aria-label');
5496
- // If element has no visible text and no aria-label, use labelledby
5497
- if (!hasText && !hasAriaLabel) {
5498
- return 'labelledby';
5499
- }
5500
- return 'describedby';
5501
- }
5502
- setupEventListeners() {
5503
- const host = this.hostElement;
5504
- // Mouse events
5505
- this.listeners.push(this.renderer.listen(host, 'mouseenter', () => this.scheduleShow()), this.renderer.listen(host, 'mouseleave', () => this.scheduleHide()),
5506
- // Focus events
5507
- this.renderer.listen(host, 'focusin', () => this.scheduleShow()), this.renderer.listen(host, 'focusout', () => this.scheduleHide()),
5508
- // Keyboard events
5509
- this.renderer.listen(host, 'keydown', (event) => {
5510
- if (event.key === 'Escape' && this.isOpen) {
5511
- this.hide();
5512
- }
5513
- }));
5514
- // Global escape handler
5515
- this.listeners.push(this.renderer.listen('document', 'keydown', (event) => {
5516
- if (event.key === 'Escape' && this.isOpen) {
5517
- this.hide();
5518
- }
5519
- }));
5520
- }
5521
- scheduleShow() {
5522
- this.clearTimeouts();
5523
- if (this.tooltipShowDelay > 0) {
5524
- this.showTimeout = setTimeout(() => this.show(), this.tooltipShowDelay);
5525
- }
5526
- else {
5527
- this.show();
5528
- }
5529
- }
5530
- scheduleHide() {
5531
- this.clearTimeouts();
5532
- if (this.tooltipHideDelay > 0) {
5533
- this.hideTimeout = setTimeout(() => this.hide(), this.tooltipHideDelay);
5534
- }
5535
- else {
5536
- this.hide();
5537
- }
5538
- }
5539
- clearTimeouts() {
5540
- if (this.showTimeout) {
5541
- clearTimeout(this.showTimeout);
5542
- this.showTimeout = undefined;
5543
- }
5544
- if (this.hideTimeout) {
5545
- clearTimeout(this.hideTimeout);
5546
- this.hideTimeout = undefined;
5547
- }
5548
- }
5549
- show() {
5550
- if (!this.tooltipElement || this.isOpen)
5551
- return;
5552
- // Update content in case it changed
5553
- this.tooltipElement.textContent = this.hviTooltip;
5554
- // Show the popover
5555
- this.tooltipElement.showPopover?.();
5556
- this.isOpen = true;
5557
- // Position and show
5558
- this.updatePosition();
5559
- this.startAutoUpdate();
5560
- // Fade in
5561
- requestAnimationFrame(() => {
5562
- if (this.tooltipElement) {
5563
- this.renderer.setStyle(this.tooltipElement, 'opacity', '1');
5564
- }
5565
- });
5566
- }
5567
- hide() {
5568
- if (!this.tooltipElement || !this.isOpen)
5569
- return;
5570
- // Fade out
5571
- this.renderer.setStyle(this.tooltipElement, 'opacity', '0');
5572
- // Hide after transition
5573
- setTimeout(() => {
5574
- this.tooltipElement?.hidePopover?.();
5575
- this.isOpen = false;
5576
- this.stopAutoUpdate();
5577
- }, 150); // Match CSS transition duration
5578
- }
5579
- updatePosition() {
5580
- const trigger = this.hostElement;
5581
- const tooltip = this.tooltipElement;
5582
- if (!trigger || !tooltip)
5583
- return;
5584
- computePosition(trigger, tooltip, {
5585
- placement: this.tooltipPlacement,
5586
- strategy: 'fixed',
5587
- middleware: [
5588
- offset(8), // Arrow size + small gap
5589
- ...(this.tooltipAutoPlacement ? [flip(), shift({ padding: 8 })] : []),
5590
- tooltipArrowPlugin,
5591
- ],
5592
- }).then(({ x, y }) => {
5593
- if (this.tooltipElement) {
5594
- this.renderer.setStyle(this.tooltipElement, 'translate', `${x}px ${y}px`);
5595
- }
5596
- });
5597
- }
5598
- startAutoUpdate() {
5599
- this.stopAutoUpdate();
5600
- const trigger = this.hostElement;
5601
- const tooltip = this.tooltipElement;
5602
- if (!trigger || !tooltip)
5603
- return;
5604
- this.cleanupAutoUpdate = autoUpdate(trigger, tooltip, () => this.updatePosition());
5605
- }
5606
- stopAutoUpdate() {
5607
- if (this.cleanupAutoUpdate) {
5608
- this.cleanupAutoUpdate();
5609
- this.cleanupAutoUpdate = undefined;
5610
- }
5611
- }
5612
- cleanup() {
5613
- this.clearTimeouts();
5614
- this.stopAutoUpdate();
5615
- // Remove event listeners
5616
- this.listeners.forEach((unlisten) => unlisten());
5617
- this.listeners = [];
5618
- // Remove tooltip element
5619
- if (this.tooltipElement) {
5620
- this.tooltipElement.hidePopover?.();
5621
- this.tooltipElement.remove();
5622
- this.tooltipElement = null;
5623
- }
5624
- }
5625
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive });
5626
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: HviTooltip, isStandalone: true, selector: "[hviTooltip]", inputs: { hviTooltip: "hviTooltip", tooltipPlacement: "tooltipPlacement", tooltipAutoPlacement: "tooltipAutoPlacement", tooltipType: "tooltipType", tooltipShowDelay: "tooltipShowDelay", tooltipHideDelay: "tooltipHideDelay" }, ngImport: i0 });
4996
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4997
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.6", type: HviTooltip, isStandalone: true, selector: "[hviTooltip]", inputs: { hviTooltip: "hviTooltip", tooltipPlacement: "tooltipPlacement", tooltipAutoPlacement: "tooltipAutoPlacement" }, host: { properties: { "attr.data-tooltip": "hviTooltip", "attr.data-placement": "tooltipPlacement", "attr.data-autoplacement": "tooltipAutoPlacement ? \"true\" : null" } }, ngImport: i0 });
5627
4998
  }
5628
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: HviTooltip, decorators: [{
4999
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HviTooltip, decorators: [{
5629
5000
  type: Directive,
5630
5001
  args: [{
5631
5002
  selector: '[hviTooltip]',
5632
5003
  standalone: true,
5004
+ host: {
5005
+ '[attr.data-tooltip]': 'hviTooltip',
5006
+ '[attr.data-placement]': 'tooltipPlacement',
5007
+ '[attr.data-autoplacement]': 'tooltipAutoPlacement ? "true" : null',
5008
+ },
5633
5009
  }]
5634
5010
  }], propDecorators: { hviTooltip: [{
5635
5011
  type: Input,
@@ -5638,12 +5014,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
5638
5014
  type: Input
5639
5015
  }], tooltipAutoPlacement: [{
5640
5016
  type: Input
5641
- }], tooltipType: [{
5642
- type: Input
5643
- }], tooltipShowDelay: [{
5644
- type: Input
5645
- }], tooltipHideDelay: [{
5646
- type: Input
5647
5017
  }] } });
5648
5018
 
5649
5019
  /*
@@ -5654,5 +5024,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
5654
5024
  * Generated bundle index. Do not edit.
5655
5025
  */
5656
5026
 
5657
- export { HviAlert, HviAvatar, HviAvatarStack, HviBadge, HviBadgePosition, HviBreadcrumbs, HviButton, HviCard, HviCardBlock, HviChipButton, HviChipLabel, HviControlInvalid, HviDetails, HviDetailsContent, HviDetailsSummary, HviDialog, HviDialogBlock, HviDivider, HviDropdown, HviErrorSummary, HviField, HviFieldAffix, HviFieldAffixes, HviFieldCounter, HviFieldDescription, HviFieldKit, HviFieldOptional, HviFieldValidation, HviFieldset, HviForm, HviForms, HviHeading, HviIcon, HviInput, HviLabel, HviLink, HviList, HviLogo, HviPagination, HviParagraph, HviPopover, HviRequiredTag, HviSearch, HviSearchClear, HviSelect, HviSkeleton, HviSkipLink, HviSortableColumn, HviSpinner, HviTab, HviTabPanel, HviTable, HviTabs, HviTag, HviTextfield, HviToggleGroup, HviToggleGroupItem, HviToggleGroupItemToken, HviTooltip, HviValidationKit, HviValidationMessage, LOGOS, buildLogo, fieldObserver, hviCustom, hviEmail, hviExtractMessages, hviExtractValidators, hviMax, hviMaxLength, hviMin, hviMinLength, hviNullValidator, hviPattern, hviRequired, hviRequiredTrue, hviValidators, isElement, isInputLike, isLabel };
5027
+ export { HviAlert, HviAvatar, HviAvatarStack, HviBadge, HviBadgePosition, HviBreadcrumbs, HviButton, HviCard, HviCardBlock, HviChipButton, HviChipLabel, HviControlInvalid, HviDetails, HviDetailsContent, HviDetailsSummary, HviDialog, HviDialogBlock, HviDivider, HviDropdown, HviErrorSummary, HviField, HviFieldAffix, HviFieldAffixes, HviFieldCounter, HviFieldDescription, HviFieldKit, HviFieldOptional, HviFieldValidation, HviFieldset, HviForm, HviForms, HviHeading, HviInput, HviLabel, HviLink, HviList, HviLogo, HviPagination, HviParagraph, HviPopover, HviRequiredTag, HviSearch, HviSearchClear, HviSelect, HviSkeleton, HviSkipLink, HviSortableColumn, HviSpinner, HviTab, HviTabPanel, HviTable, HviTabs, HviTag, HviTextfield, HviToggleGroup, HviToggleGroupItem, HviToggleGroupItemToken, HviTooltip, HviValidationKit, HviValidationMessage, LOGOS, analyzeFormRequired, buildLogo, hviCustom, hviEmail, hviExtractMessages, hviExtractValidators, hviMax, hviMaxLength, hviMin, hviMinLength, hviNullValidator, hviPattern, hviRequired, hviRequiredTrue, hviValidators };
5658
5028
  //# sourceMappingURL=helsevestikt-hviktor-angular.mjs.map