@arbetsformedlingen/yrkesvaljaren 2.0.6 → 2.0.11

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.
Files changed (81) hide show
  1. package/README.md +102 -48
  2. package/dist/cjs/{af-validation-message-BzY5H0xU.js → af-validation-message-Cy89nVEv.js} +1 -1
  3. package/dist/cjs/core-selector.cjs.entry.js +79 -27
  4. package/dist/cjs/digi-service-job-selector.cjs.entry.js +74 -46
  5. package/dist/cjs/geo-valjaren.cjs.entry.js +1 -1
  6. package/dist/cjs/{index-BOuTGlEp.js → index-hZgOvC17.js} +9 -2
  7. package/dist/cjs/index.cjs.js +2 -2
  8. package/dist/cjs/job-selector-demo.cjs.entry.js +55 -55
  9. package/dist/cjs/loader.cjs.js +1 -1
  10. package/dist/cjs/neobrutal-search.cjs.entry.js +3 -3
  11. package/dist/cjs/{search.engine-D0cMelRi.js → search.engine-D4cpbVzd.js} +41 -26
  12. package/dist/cjs/{taxonomy-registry-DVmuDUpM.js → taxonomy-registry-Dzt0SPzT.js} +21 -2
  13. package/dist/cjs/yrkesvaljaren.cjs.js +2 -2
  14. package/dist/collection/collection-manifest.json +1 -1
  15. package/dist/collection/components/core-selector/core-selector.css +30 -0
  16. package/dist/collection/components/core-selector/core-selector.js +59 -26
  17. package/dist/collection/components/job-selector/constants.js +2 -2
  18. package/dist/collection/components/job-selector/job-selector-controller.js +34 -22
  19. package/dist/collection/components/job-selector/job-selector.js +26 -24
  20. package/dist/collection/components/job-selector/logic/search.engine.js +2 -2
  21. package/dist/collection/components/job-selector/search.utils.js +35 -22
  22. package/dist/collection/components/job-selector/taxonomy-loader.js +16 -0
  23. package/dist/collection/components/job-selector/taxonomy-registry.js +21 -2
  24. package/dist/collection/verkstad/verkstad.js +14 -13
  25. package/dist/components/core-selector2.js +1 -1
  26. package/dist/components/job-selector-demo.js +1 -1
  27. package/dist/components/job-selector.js +1 -1
  28. package/dist/components/search.engine.js +1 -1
  29. package/dist/esm/{af-validation-message-F8NIH2rC.js → af-validation-message-BgoGzzBf.js} +1 -1
  30. package/dist/esm/core-selector.entry.js +79 -27
  31. package/dist/esm/digi-service-job-selector.entry.js +74 -46
  32. package/dist/esm/geo-valjaren.entry.js +1 -1
  33. package/dist/esm/{index-CGXZllj2.js → index-HNd02eQb.js} +9 -2
  34. package/dist/esm/index.js +2 -2
  35. package/dist/esm/job-selector-demo.entry.js +55 -55
  36. package/dist/esm/loader.js +2 -2
  37. package/dist/esm/neobrutal-search.entry.js +3 -3
  38. package/dist/esm/{search.engine-nZ7AcXba.js → search.engine-BaWUTc3r.js} +41 -27
  39. package/dist/esm/{taxonomy-registry-Dw0VR9Aw.js → taxonomy-registry-C-pSh51L.js} +21 -2
  40. package/dist/esm/yrkesvaljaren.js +3 -3
  41. package/dist/types/components/core-selector/core-selector.d.ts +3 -0
  42. package/dist/types/components/core-selector/types.d.ts +1 -1
  43. package/dist/types/components/job-selector/constants.d.ts +2 -2
  44. package/dist/types/components/job-selector/search.utils.d.ts +5 -0
  45. package/dist/types/components/job-selector/taxonomy-loader.d.ts +15 -0
  46. package/dist/types/components/job-selector/taxonomy-registry.d.ts +1 -2
  47. package/dist/types/components/job-selector/types.d.ts +2 -0
  48. package/dist/types/components.d.ts +4 -4
  49. package/dist/types/vitest-globals.d.ts +1 -0
  50. package/dist/vendor/taxonomy-core/index.d.ts +3 -0
  51. package/dist/vendor/taxonomy-core/index.js +1 -0
  52. package/dist/vendor/taxonomy-core/selector-navigation.d.ts +14 -0
  53. package/dist/vendor/taxonomy-core/selector-navigation.js +55 -0
  54. package/dist/vendor/taxonomy-core/selector-types.d.ts +55 -0
  55. package/dist/vendor/taxonomy-core/selector-types.js +1 -0
  56. package/dist/yrkesvaljaren/index.esm.js +1 -1
  57. package/dist/yrkesvaljaren/p-18eb36b6.entry.js +1 -0
  58. package/dist/yrkesvaljaren/{p-aef7b5ae.entry.js → p-9d97f0e7.entry.js} +1 -1
  59. package/dist/yrkesvaljaren/{p-DYFAzvqX.js → p-BUviBbwX.js} +1 -1
  60. package/dist/yrkesvaljaren/{p-Dw0VR9Aw.js → p-C-pSh51L.js} +1 -1
  61. package/dist/yrkesvaljaren/p-CjMoDiZD.js +1 -0
  62. package/dist/yrkesvaljaren/{p-CGXZllj2.js → p-HNd02eQb.js} +1 -1
  63. package/dist/yrkesvaljaren/p-b6745963.entry.js +1 -0
  64. package/dist/yrkesvaljaren/{p-273cf6df.entry.js → p-dbbea724.entry.js} +1 -1
  65. package/dist/yrkesvaljaren/p-df3fa43b.entry.js +1 -0
  66. package/dist/yrkesvaljaren/yrkesvaljaren.esm.js +1 -1
  67. package/package.json +24 -11
  68. package/dist/collection/demo-data.js +0 -20
  69. package/dist/types/demo-data.d.ts +0 -16
  70. package/dist/yrkesvaljaren/fuse-B0eHOxow.js.map +0 -1
  71. package/dist/yrkesvaljaren/index-Cy4BCo5s.js.map +0 -1
  72. package/dist/yrkesvaljaren/index-DfJXTQqL.js.map +0 -1
  73. package/dist/yrkesvaljaren/index.esm.js.map +0 -1
  74. package/dist/yrkesvaljaren/p-16636162.entry.js +0 -1
  75. package/dist/yrkesvaljaren/p-9e48afa4.entry.js +0 -1
  76. package/dist/yrkesvaljaren/p-b0f16abd.entry.js +0 -1
  77. package/dist/yrkesvaljaren/p-uBrs3sSs.js +0 -1
  78. package/dist/yrkesvaljaren/search.engine-DPT6roRm.js.map +0 -1
  79. package/dist/yrkesvaljaren/taxonomy-registry-s5khf6s4.js.map +0 -1
  80. package/dist/yrkesvaljaren/types-DHUftoZJ.js.map +0 -1
  81. package/dist/yrkesvaljaren/yrkesvaljaren.esm.js.map +0 -1
package/README.md CHANGED
@@ -15,40 +15,105 @@ En robust och intelligent sökkomponent för svenska yrken, designad för hög p
15
15
 
16
16
  ### Installation
17
17
 
18
- Runtime-komponenten kräver inte `@designsystem-se/af`. Den följer Arbetsförmedlingens visuella designsystem via lokala tokens och primitives, men registrerar inga designsystem-webbkomponenter.
18
+ Yrkesväljaren installeras enkelt via npm:
19
19
 
20
- 1. **Konfigurera NPM-scope:** Skapa en `.npmrc`-fil i roten av ditt projekt.
21
- ```ini
22
- @taxonomy:registry=https://gitlab.com/api/v4/projects/74569456/packages/npm/
23
-
24
- ```
25
- 2. **Installera komponenten med senaste data:**
26
- ```bash
27
- npm install @taxonomy/yrkesvaljaren
28
- ```
20
+ ```bash
21
+ npm install @arbetsformedlingen/yrkesvaljaren
22
+ ```
23
+
24
+ När ingen datakälla anges hämtar komponenten automatiskt den senaste publicerade yrkesdatan från CDN.
25
+
26
+ #### Alternativ: installera ett versionerat datapaket
27
+
28
+ Om du vill låsa taxonomiversionen vid build time installerar du även ett versionerat datapaket:
29
29
 
30
- När ingen datakälla anges hämtar komponenten senaste publicerade yrkesdata automatiskt.
30
+ ```bash
31
+ npm install @arbetsformedlingen/yrkesvaljaren @taxonomy/yrkesvaljaren-data-v31
32
+ ```
33
+
34
+ Registrera paketets data i din applikation innan komponenten används:
31
35
 
32
- 3. **Alternativ: installera ett versionerat datapaket:**
33
- ```bash
34
- npm install @taxonomy/yrkesvaljaren @taxonomy/yrkesvaljaren-data-v30
35
- ```
36
+ ```javascript
37
+ import { registerTaxonomy } from '@arbetsformedlingen/yrkesvaljaren';
38
+ import {
39
+ taxonomyData,
40
+ metadata
41
+ } from '@taxonomy/yrkesvaljaren-data-v31';
36
42
 
37
- Detta låser taxonomiversionen vid build time. Registrera paketets data innan komponenten används:
43
+ registerTaxonomy({ data: taxonomyData, metadata });
44
+ ```
38
45
 
39
- ```javascript
40
- import { registerTaxonomy } from '@taxonomy/yrkesvaljaren';
41
- import {
42
- taxonomyData,
43
- metadata
44
- } from '@taxonomy/yrkesvaljaren-data-v30';
46
+ `af-taxonomy-url` är ett tredje, avancerat alternativ om du vill peka komponenten mot en egenhostad datafil.
45
47
 
46
- registerTaxonomy({ data: taxonomyData, metadata });
47
- ```
48
+ ### Användning i Angular
48
49
 
49
- `af-taxonomy-url` är ett tredje, avancerat alternativ. Ange då en fullständig, explicit URL till den datafil som ska användas.
50
+ De flesta som använder Yrkesväljaren bygger i Angular. Komponenten är en vanlig webbkomponent, så den fungerar i standalone-komponenter med eller utan zone.js.
50
51
 
51
- ### Användning
52
+ Registrera webbkomponenterna i `main.ts` innan appen startar:
53
+
54
+ ```ts
55
+ // src/main.ts
56
+ import { bootstrapApplication } from '@angular/platform-browser';
57
+ import { defineCustomElements as defineYv } from '@arbetsformedlingen/yrkesvaljaren/loader';
58
+ import { appConfig } from './app/app.config';
59
+ import { App } from './app/app';
60
+
61
+ defineYv(window);
62
+ bootstrapApplication(App, appConfig).catch((err) => console.error(err));
63
+ ```
64
+
65
+ Använd sedan komponenten i en standalone-komponent med `CUSTOM_ELEMENTS_SCHEMA` och lyssna på eventet i templaten:
66
+
67
+ ```ts
68
+ // src/app/job-picker.component.ts
69
+ import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from '@angular/core';
70
+ import type { JobSelectionItem } from '@arbetsformedlingen/yrkesvaljaren';
71
+
72
+ @Component({
73
+ selector: 'app-job-picker',
74
+ standalone: true,
75
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
76
+ template: `
77
+ <digi-service-job-selector af-label="Välj yrke" (afJobSelected)="onJobSelected($event)"></digi-service-job-selector>
78
+ <p>Valt yrke: {{ selected()[0]?.preferred_label ?? 'inget' }}</p>
79
+ `,
80
+ })
81
+ export class JobPickerComponent {
82
+ readonly selected = signal<JobSelectionItem[]>([]);
83
+
84
+ onJobSelected(event: Event): void {
85
+ this.selected.set((event as CustomEvent<JobSelectionItem[] | null>).detail ?? []);
86
+ }
87
+ }
88
+ ```
89
+
90
+ Uppdatera vyn via signals (eller `ChangeDetectorRef`) när ni sätter värden efter en `await`. Annars uppdateras inte vyn i zoneless-appar.
91
+
92
+ **Låst dataversion i Angular:** taxonomidatan i `@taxonomy/yrkesvaljaren-data-v31` är cirka 2 MB. Importera den dynamiskt i `main.ts`, så hamnar den i en egen chunk. Med en statisk import hamnar den i main-bundlen och `ng build` fastnar på Angulars standardbudget (1 MB).
93
+
94
+ ```ts
95
+ // src/main.ts
96
+ import { bootstrapApplication } from '@angular/platform-browser';
97
+ import { defineCustomElements as defineYv } from '@arbetsformedlingen/yrkesvaljaren/loader';
98
+ import { registerTaxonomy } from '@arbetsformedlingen/yrkesvaljaren';
99
+ import { appConfig } from './app/app.config';
100
+ import { App } from './app/app';
101
+
102
+ async function main() {
103
+ const { metadata, taxonomyData } = await import('@taxonomy/yrkesvaljaren-data-v31');
104
+ registerTaxonomy({ data: taxonomyData, metadata });
105
+ defineYv(window);
106
+ await bootstrapApplication(App, appConfig);
107
+ }
108
+ main().catch((err) => console.error(err));
109
+ ```
110
+
111
+ Kompletta exempel:
112
+
113
+ - [`examples/angular-wizard`](examples/angular-wizard): Yrkesväljaren i Reactive Forms via `ControlValueAccessor`.
114
+ - [`examples/angular-multi-occupation-skills`](examples/angular-multi-occupation-skills): flera yrken med egna kompetensval via Kompetensväljarens headless-API.
115
+
116
+ ### Användning i HTML och andra ramverk
52
117
 
53
118
  För att snabbt komma igång, här är ett komplett HTML-exempel som visar hur du inkluderar och använder Yrkesväljaren:
54
119
 
@@ -69,7 +134,7 @@ För att snabbt komma igång, här är ett komplett HTML-exempel som visar hur d
69
134
  <script type="module">
70
135
 
71
136
  // Imports (sökväg beror på ditt byggverktyg)
72
- import { defineCustomElements as defineYrkesvaljaren } from "@taxonomy/yrkesvaljaren/loader";
137
+ import { defineCustomElements as defineYrkesvaljaren } from "@arbetsformedlingen/yrkesvaljaren/loader";
73
138
  defineYrkesvaljaren(window);
74
139
  document.querySelector("digi-service-job-selector")
75
140
  .addEventListener("afJobSelected", (e) => {
@@ -81,6 +146,8 @@ console.log("Valt yrke:", e.detail);
81
146
  </html>
82
147
  ```
83
148
 
149
+ **React:** koppla komponentens event med `addEventListener` via en `ref` i en `useEffect`. Det fungerar i alla React-versioner; en `onAfJobSelected`-prop fungerar inte i React 18.
150
+
84
151
  ### Vite
85
152
 
86
153
  Yrkesväljaren använder en Stencil-loader som hämtar komponenternas entry-filer dynamiskt. I Vite ska loader-paketet därför undantas från dependency optimizer, annars kan Vite flytta loadern till `.vite/deps` och de dynamiska importerna får fel sökväg.
@@ -90,7 +157,7 @@ Yrkesväljaren använder en Stencil-loader som hämtar komponenternas entry-file
90
157
  export default {
91
158
  optimizeDeps: {
92
159
  exclude: [
93
- '@taxonomy/yrkesvaljaren/loader',
160
+ '@arbetsformedlingen/yrkesvaljaren/loader',
94
161
  ],
95
162
  },
96
163
  };
@@ -98,9 +165,7 @@ export default {
98
165
 
99
166
  ### Designsystem-kompatibilitet
100
167
 
101
- Runtime-komponenten kräver inte `@designsystem-se/af`, registrerar inga designsystem-webbkomponenter och krockar inte om host-appen redan använder det riktiga designsystemet. Komponenten innehåller en liten lokal kompatibilitetsyta med AF-liknande design tokens, typografi, färger, fokusramar och ikoner. Demosidan i repo:t använder fortfarande designsystemet för dokumentationslayout och visuell referens.
102
-
103
- De lokala tokenvärdena och primitive-stilarna är anpassade från Arbetsförmedlingens designsystem under Apache-2.0 och används bara för att runtime-komponenterna ska rendera fristående.
168
+ Yrkesväljaren är uppbyggd med designsystemets tokens, typografi, färger, fokusramar och ikoner och kommer att uppdateras automatiskt för dig som har designsystemet installerat. Den använder de förväntade attributen för att styla etikett, felmeddelande osv, men har inga komponentberoenden till designsystemet. För den som inte har designsystemet installerat används inbyggda fallbacks för att bibehålla utseendet.
104
169
 
105
170
  ### Attribut
106
171
 
@@ -109,7 +174,7 @@ De lokala tokenvärdena och primitive-stilarna är anpassade från Arbetsförmed
109
174
  | `af-label` | Etikettext som visas ovanför sökfältet. | `string` | `'Välj yrke'` |
110
175
  | `disabled` | Om satt till `true`, kan väljaren inte användas med mus eller tangentbord. | `boolean` | `false` |
111
176
  | `af-label-description`| En valfri beskrivningstext som visas under etiketten. | `string` | `undefined` |
112
- | `af-placeholder` | Hjälptext som visas inuti sökfältet. Denna är ett bra stöd för de med kognitiv funktionsvariation - rekommendationen är att behålla denna text, och att inte flytta den till `description`. | `string` | `'T.ex. frisör, vårdbiträde, snickare'` |
177
+ | `af-placeholder` | Hjälptext som visas inuti sökfältet. Denna är ett bra stöd för de med kognitiv funktionsvariation - vi rekommenderar att behålla denna text (den är osynlig för skärmläsare). | `string` | `'T.ex. målare, florist, kock'` |
113
178
  | `af-error-message` | Ett anpassat felmeddelande som visas vid valideringsfel. | `string` | `undefined` |
114
179
  | `af-enable-multiple` | Om satt till `true`, tillåts val av flera yrken. | `boolean` | `false` |
115
180
  | `af-history` | Sparar användarval lokalt i webbläsarens Local Storage och visar historiken på samma domän. | `boolean` | `true` |
@@ -125,7 +190,7 @@ Tre centrala inställningar styr användarupplevelsen och datakvaliteten i Yrkes
125
190
 
126
191
  #### Obligatorisk (`af-required`)
127
192
  * **Hur man kan resonera:** När `af-required="true"` måste användaren välja minst ett yrke för att fältet ska betraktas som giltigt. Komponenten fungerar som ett standardenligt *Form-Associated Custom Element* (FACE). Det innebär att webbläsaren automatiskt validerar fältet vid formulärinskick, förhindrar att formuläret skickas in om det är tomt, och integrerar med formulärets `validity`-status.
128
- * **När det rekommenderas:** I formulär och flöden där ett yrkesval är ett obligatoriskt steg i ett ärende (t.ex. registrering av profil, jobbansökan eller behörighetskontroll).
193
+ * **När det rekommenderas:** I formulär och flöden där ett yrkesval är ett obligatoriskt steg i ett ärende (t.ex. inskriving, aktivtitetsrapportering).
129
194
  * **När det bör undvikas:** I öppna sök- eller filtreringsvyer där användaren ska kunna söka brett, filtrera på andra parametrar (t.ex. enbart ort/geografi) eller frivilligt specificera yrke.
130
195
 
131
196
  #### Tillåt fritext (`af-manual-input`)
@@ -135,9 +200,9 @@ Tre centrala inställningar styr användarupplevelsen och datakvaliteten i Yrkes
135
200
  * **Fritext tillåten (`af-manual-input="true"`):** I öppna fritextprofiler, fritextenkäter eller intresseanmälningar där det är viktigare att fånga upp vad användaren själv kallar sin roll än att få ett taxonomi-ID, eller där man inte vill blockera användare med ovanliga, nischade eller internationella titlar.
136
201
 
137
202
  #### Tillåt historik (`af-history`)
138
- * **Hur man kan resonera:** Sparar gjorda val i webbläsarens `localStorage` per domän och visar dem som *"Tidigare val"* när användaren fokuserar ett tomt sökfält.
139
- * **När det rekommenderas:** I flöden där användaren ofta gör återkommande sökningar (t.ex. jobbsökare eller handläggare).
140
- * **När det bör undvikas:** På delade publika terminaler eller kioskdatorer (t.ex. på Arbetsförmedlingens servicekontor eller bibliotek) där personers tidigare sökningar inte ska sparas eller exponeras för efterföljande besökare på samma dator.
203
+ * **Hur man kan resonera:** Sparar gjorda val i webbläsarens localStorage per domän och enhet, och visar dem som "Tidigare val" när användaren fokuserar Yrkesväljaren. Det betyder att historiken kommer att visas på alla tjänster med yrkesväljare på arbetsformedlingen.se (så länge personen använder samma enhet, t.ex sin mobil).
204
+ * **När det rekommenderas:** På alla tjänster mot konsumenter.
205
+ * **När det bör undvikas:** På delade publika terminaler eller kioskdatorer (t.ex. på Arbetsförmedlingens servicekontor) där personers tidigare sökningar inte ska sparas eller exponeras för efterföljande besökare på samma dator. Kanske är det inget hjälpsamt stöd för tjänster för Handläggare eftersom de söker måååånga olika yrken.
141
206
 
142
207
  ### Välj datakälla
143
208
 
@@ -249,7 +314,7 @@ Komponenten gör inget anrop till Taxonomy API. För ett rikt taxonomiobjekt ide
249
314
  Samma input-array får inte blanda strängar och objekt. Flera värden kräver `af-enable-multiple="true"`; metoden aktiverar aldrig flervalsläge automatiskt.
250
315
 
251
316
  ```javascript
252
- import { InvalidSelectionError } from '@taxonomy/yrkesvaljaren';
317
+ import { InvalidSelectionError } from '@arbetsformedlingen/yrkesvaljaren';
253
318
 
254
319
  const yrkesvaljaren = document.querySelector('digi-service-job-selector');
255
320
 
@@ -356,14 +421,3 @@ form.addEventListener('submit', async (e) => {
356
421
  }
357
422
  });
358
423
  ```
359
- <br>
360
- ### Utveckling och release
361
-
362
- Lokala utvecklingskommandon och releaseinstruktioner finns i [CONTRIBUTING.md](CONTRIBUTING.md).
363
- Komponentpaket publiceras automatiskt av CI från taggar:
364
- * `vX.Y.Z` publicerar Yrkesväljaren till officiella npm som `@arbetsformedlingen/yrkesvaljaren` (samt till GitLab som `@taxonomy/yrkesvaljaren`).
365
- * `kv-vX.Y.Z` publicerar Kompetensväljaren.
366
-
367
- `npm run build` använder endast versionshanterad data och kräver ingen
368
- nätverksåtkomst. `npm run refresh:data` bygger om samtliga versionerade
369
- data-workspaces och hämtar då YV-data från upstream.
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-BOuTGlEp.js');
3
+ var index = require('./index-hZgOvC17.js');
4
4
 
5
5
  const AfValidationMessage = (props, children) => {
6
6
  const extraClass = props.class || '';
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-BOuTGlEp.js');
4
- var afValidationMessage = require('./af-validation-message-BzY5H0xU.js');
3
+ var index = require('./index-hZgOvC17.js');
4
+ var afValidationMessage = require('./af-validation-message-Cy89nVEv.js');
5
5
 
6
6
  const svgMarkup = {
7
7
  search: '<svg width="26" height="26" viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" style="width:100%;height:100%"><path d="M25.645 22.437l-5.063-5.053a1.22 1.22 0 00-.864-.355h-.827a10.477 10.477 0 002.234-6.487C21.125 4.719 16.397 0 10.562 0 4.729 0 0 4.719 0 10.542c0 5.823 4.728 10.542 10.563 10.542 2.452 0 4.707-.831 6.5-2.23v.826c0 .324.126.633.355.862l5.063 5.053c.477.476 1.25.476 1.721 0l1.437-1.435a1.22 1.22 0 00.006-1.723zm-15.082-5.408c-3.59 0-6.5-2.899-6.5-6.487a6.49 6.49 0 016.5-6.487c3.59 0 6.5 2.899 6.5 6.487a6.49 6.49 0 01-6.5 6.487z" fill="currentColor" fill-rule="nonzero"/></svg>',
@@ -31,6 +31,25 @@ function shouldShowManualInput(state, requireSelection = false) {
31
31
  return false;
32
32
  return !state.suggestions.some((suggestion) => suggestion.label.toLowerCase() === inputValue.toLowerCase());
33
33
  }
34
+ function getNextActiveIndex(direction, currentIndex, totalOptions) {
35
+ if (totalOptions <= 0)
36
+ return -1;
37
+ if (direction === 'down') {
38
+ if (currentIndex < totalOptions - 1) {
39
+ return currentIndex + 1;
40
+ }
41
+ return currentIndex; // Stop at bottom, never wrap to top
42
+ }
43
+ // direction === 'up'
44
+ if (currentIndex > 0) {
45
+ return currentIndex - 1;
46
+ }
47
+ if (currentIndex === 0) {
48
+ return -1; // Return to input field
49
+ }
50
+ // currentIndex <= -1: stay in input field, never wrap to bottom
51
+ return -1;
52
+ }
34
53
  function reconcileActiveIndex({ activeIndex, newState, oldState, requireSelection = false, }) {
35
54
  if (oldState && newState.inputValue !== oldState.inputValue) {
36
55
  return { activeIndex: -1, shouldRestoreFocus: false };
@@ -60,7 +79,7 @@ function reconcileActiveIndex({ activeIndex, newState, oldState, requireSelectio
60
79
  };
61
80
  }
62
81
 
63
- const coreSelectorCss = () => `:host{--digi--grayscale-0:#ffffff;--digi--grayscale-50:#fbfbfb;--digi--grayscale-100:#f4f4f4;--digi--grayscale-200:#ededed;--digi--grayscale-300:#e4e4e4;--digi--grayscale-400:#dddddd;--digi--grayscale-500:#cacaca;--digi--grayscale-600:#acacac;--digi--grayscale-700:#757575;--digi--grayscale-800:#5c5c5c;--digi--grayscale-900:#333333;--digi--grayscale-1000:#000000;--digi--global--color--cta--link--base:#1616b2;--digi--global--color--function--danger--base:#da0000;--digi--global--color--function--success--base:#008a20;--digi--global--color--function--success--lightest-3:#d4edda;--digi--global--color--function--warning--base:#ffe200;--digi--color--text--primary:var(--digi--grayscale-900);--digi--color--text--secondary:var(--digi--grayscale-700);--digi--color--text--link:var(--digi--global--color--cta--link--base);--digi--color--icons--success:var(--digi--global--color--function--success--base);--digi--color--icons--warning:#8a7a00;--digi--color--icons--danger:var(--digi--global--color--function--danger--base);--digi--global--typography--font-family--default:"Open Sans", Arial, sans-serif;--digi--global--typography--font-size--base:1rem;--digi--global--typography--font-size--small:0.875rem;--digi--global--typography--font-weight--regular:400;--digi--global--typography--font-weight--semibold:600;--digi--global--typography--font-weight--bold:700;--digi--global--typography--line-height--base:1.5;--digi--typography--label--font-size--desktop:1rem;--digi--typography--label--font-weight--desktop:600;--digi--typography--label--line-height--desktop:1.5;--digi--typography--label-description--font-size--desktop:1rem;--digi--typography--label-description--line-height--desktop:1.5;--digi--typography--tag--font-size--desktop:0.875rem;--digi--gutter--icon:0.625rem;--digi--gutter--smaller:0.75rem;--digi--gutter--small:0.875rem;--digi--gutter--medium:1rem;--digi--border-width--primary:1px;--digi--border-style--primary:solid;--digi--border-radius--primary:0;--digi--border-radius--secondary:6px;--af-tag-color:#091d54;--af-tag-hover-background:#ddf1fc}.af-form-label{color:var(--digi--color--text--primary);display:flex;flex-direction:column;font-family:var(--digi--global--typography--font-family--default);font-size:var(--digi--typography--label--font-size--desktop);margin-bottom:0.5rem}.af-form-label__label{cursor:pointer;display:block;font-weight:var(--digi--typography--label--font-weight--desktop);line-height:var(--digi--typography--label--line-height--desktop)}.af-form-label__description{display:block;font-size:var(--digi--typography--label-description--font-size--desktop);line-height:var(--digi--typography--label-description--line-height--desktop);max-width:35rem}.af-validation-message{align-items:center;display:flex;flex-wrap:wrap}.af-validation-message__icon{flex:0 0 auto;height:1.25em;margin-inline-end:var(--digi--gutter--icon);width:1.25em}.af-validation-message__icon--success,.af-validation-message__icon--error{background-color:var(--af-validation-icon-color, currentColor);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.af-validation-message__icon--success{--af-validation-icon-color:var(--digi--color--icons--success);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 25 25'%3E%3Cpath d='M25 12.5C25 19.404 19.404 25 12.5 25S0 19.404 0 12.5 5.596 0 12.5 0 25 5.596 25 12.5zm-13.946 6.619l9.274-9.275a.806.806 0 000-1.14l-1.14-1.14a.806.806 0 00-1.14 0l-7.564 7.563-3.531-3.531a.807.807 0 00-1.14 0l-1.141 1.14a.806.806 0 000 1.14l5.242 5.243a.806.806 0 001.14 0z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 25 25'%3E%3Cpath d='M25 12.5C25 19.404 19.404 25 12.5 25S0 19.404 0 12.5 5.596 0 12.5 0 25 5.596 25 12.5zm-13.946 6.619l9.274-9.275a.806.806 0 000-1.14l-1.14-1.14a.806.806 0 00-1.14 0l-7.564 7.563-3.531-3.531a.807.807 0 00-1.14 0l-1.141 1.14a.806.806 0 000 1.14l5.242 5.243a.806.806 0 001.14 0z'/%3E%3C/svg%3E")}.af-validation-message__icon--error{--af-validation-icon-color:var(--digi--color--icons--danger);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M34.4328058,0 C35.5494848,0 36.5900526,0.609146757 37.1483921,1.58958113 L47.5812454,19.9104189 C48.1395849,20.8909496 48.1395849,22.1090504 47.5812454,23.0895811 L37.1483921,41.4104189 C36.5900526,42.3908532 35.5494848,43 34.4328058,43 L13.5671942,43 C12.4505152,43 11.4099474,42.3908532 10.8516079,41.4104189 L0.41875464,23.0895811 C-0.13958488,22.1090504 -0.13958488,20.8909496 0.41875464,19.9104189 L10.8516079,1.58958113 C11.4099474,0.609146757 12.4505152,0 13.5671942,0 Z M18.6736823,12.3728178 C18.2711762,11.964729 17.6203819,11.964729 17.2178757,12.3728178 L15.2825964,14.334939 C14.8800903,14.7430278 14.8800903,15.4028485 15.2825964,15.8109373 L20.6089616,21.2111779 L15.2825964,26.6114185 C14.8800903,27.0195074 14.8800903,27.6793281 15.2825964,28.0874169 L17.2178757,30.049538 C17.6203819,30.4576269 18.2711762,30.4576269 18.6736823,30.049538 L24.0000475,24.6492974 L29.3264127,30.049538 C29.7289188,30.4576269 30.3797132,30.4576269 30.7822193,30.049538 L32.7174986,28.0874169 C33.1200048,27.6793281 33.1200048,27.0195074 32.7174986,26.6114185 L27.3911334,21.2111779 L32.7174986,15.8109373 C33.1200048,15.4028485 33.1200048,14.7430278 32.7174986,14.334939 L30.7822193,12.3728178 C30.3797132,11.964729 29.7289188,11.964729 29.3264127,12.3728178 L24.0000475,17.7730584 Z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M34.4328058,0 C35.5494848,0 36.5900526,0.609146757 37.1483921,1.58958113 L47.5812454,19.9104189 C48.1395849,20.8909496 48.1395849,22.1090504 47.5812454,23.0895811 L37.1483921,41.4104189 C36.5900526,42.3908532 35.5494848,43 34.4328058,43 L13.5671942,43 C12.4505152,43 11.4099474,42.3908532 10.8516079,41.4104189 L0.41875464,23.0895811 C-0.13958488,22.1090504 -0.13958488,20.8909496 0.41875464,19.9104189 L10.8516079,1.58958113 C11.4099474,0.609146757 12.4505152,0 13.5671942,0 Z M18.6736823,12.3728178 C18.2711762,11.964729 17.6203819,11.964729 17.2178757,12.3728178 L15.2825964,14.334939 C14.8800903,14.7430278 14.8800903,15.4028485 15.2825964,15.8109373 L20.6089616,21.2111779 L15.2825964,26.6114185 C14.8800903,27.0195074 14.8800903,27.6793281 15.2825964,28.0874169 L17.2178757,30.049538 C17.6203819,30.4576269 18.2711762,30.4576269 18.6736823,30.049538 L24.0000475,24.6492974 L29.3264127,30.049538 C29.7289188,30.4576269 30.3797132,30.4576269 30.7822193,30.049538 L32.7174986,28.0874169 C33.1200048,27.6793281 33.1200048,27.0195074 32.7174986,26.6114185 L27.3911334,21.2111779 L32.7174986,15.8109373 C33.1200048,15.4028485 33.1200048,14.7430278 32.7174986,14.334939 L30.7822193,12.3728178 C30.3797132,11.964729 29.7289188,11.964729 29.3264127,12.3728178 L24.0000475,17.7730584 Z'/%3E%3C/svg%3E")}.af-validation-message__icon--warning{background:center / contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Ccircle cx='9' cy='9' r='6.75' fill='%23333'/%3E%3Cpath d='m18 9c0 4.9717-4.0298 9-9 9-4.9702 0-9-4.0283-9-9 0-4.9688 4.0298-9 9-9 4.9702 0 9 4.0312 9 9zm-9 1.8145c-0.92196 0-1.6694 0.7474-1.6694 1.6694 0 0.92196 0.7474 1.6694 1.6694 1.6694s1.6694-0.7474 1.6694-1.6694c0-0.92196-0.7474-1.6694-1.6694-1.6694zm-1.3157-1.065c0.012593 0.23095 0.20355 0.41175 0.43483 0.41175h1.7618c0.23128 0 0.42224-0.1808 0.43483-0.41175l0.2692-4.9355c0.013609-0.24946-0.18501-0.45922-0.43483-0.45922h-2.3002c-0.24982 0-0.4484 0.20976-0.43479 0.45922l0.2692 4.9355z' fill='%23FFE200'/%3E%3C/svg%3E");position:relative;top:3px}.af-validation-message__text{color:var(--digi--color--text--primary);flex:1;font-family:var(--digi--global--typography--font-family--default);font-size:var(--digi--typography--tag--font-size--desktop);transform:translateY(1px)}.af-tag{display:block;max-width:100%;min-width:0}.af-tag__button{align-items:center;background:var(--digi--grayscale-0);border:var(--digi--border-width--primary) var(--digi--border-style--primary) var(--af-tag-color);border-radius:var(--digi--border-radius--secondary);color:var(--af-tag-color);cursor:pointer;display:inline-flex;font-family:var(--digi--global--typography--font-family--default);font-size:0.875rem;font-weight:var(--digi--global--typography--font-weight--semibold);gap:10px;height:auto;max-width:100%;min-height:unset;min-width:0;padding:6px 8px;text-align:left;white-space:normal}.af-tag__button:hover{background:var(--af-tag-hover-background)}.af-tag__button:focus-visible{background:var(--af-tag-hover-background);border-color:var(--af-tag-color);outline:2px solid var(--digi--grayscale-1000);outline-offset:2px;box-shadow:0 0 0 5px var(--digi--grayscale-0)}.af-tag__button:active{background:var(--af-tag-hover-background)}.af-tag__text{display:inline-block;max-width:100%;min-width:0;white-space:normal}.af-tag__text--break{overflow-wrap:anywhere;word-break:break-word}.af-tag__remove-icon{flex:0 0 auto;height:1em;min-height:0 !important;width:1em}:host{--selector-width:var(--cs-width, 100%);--selector-min-width:var(--cs-min-width, 200px);--selector-max-width:var(--cs-max-width, none);--selector-height:var(--cs-height, auto);--selector-min-height:var(--cs-min-height, auto);--selector-max-height:var(--cs-max-height, none);--selector-font-family:var(--global-font-family, 'Open Sans', sans-serif);--selector-font-size:var(--cs-font-size, 1rem);--selector-text-color:var(--cs-text-color, #212529);--selector-placeholder-color:var(--cs-placeholder-color, #6c757d);--selector-border-color:var(--cs-border-color, #d1d5db);--selector-focus-border-color:var(--cs-focus-border-color, #86b7fe);--selector-focus-shadow:var(--cs-focus-shadow, 0 0 0 0.25rem rgba(13, 110, 253, 0.25));--selector-background-color:var(--cs-background-color, #fff);--selector-icon-color:var(--cs-icon-color, #6c757d);--selector-clear-button-color:var(--cs-clear-button-color, #6c757d);--selector-clear-button-hover-color:var(--cs-clear-button-hover-color, #212529);--selector-suggestion-background-color:var(--cs-suggestion-background-color, #fff);--selector-suggestion-border-color:var(--cs-suggestion-border-color, #ced4da);--selector-suggestion-hover-background:var(--cs-suggestion-hover-background, #e9ecef);--selector-suggestion-active-background:var(--cs-suggestion-active-background, #dde4eb);--selector-suggestion-text-color:var(--cs-suggestion-text-color, #212529);--selector-suggestion-highlight-weight:var(--cs-suggestion-highlight-weight, bold);--selector-error-color:var(--cs-error-color, #dc3545);--selector-loading-color:var(--cs-loading-color, #6c757d);--selector-container-min-height:40px;--selector-padding-y:6px;--selector-padding-x:10px;--selector-icon-size:1.1em;--selector-gap:6px;--cs-row-height:32px;display:flex;flex-direction:column;width:var(--selector-width);min-width:var(--selector-min-width);max-width:var(--selector-max-width);height:var(--selector-height);min-height:var(--selector-min-height);max-height:var(--selector-max-height);font-family:var(--selector-font-family);font-size:var(--selector-font-size);color:var(--selector-text-color);position:relative}:host([cs-size="small"]){--selector-container-min-height:32px;--selector-padding-y:2px;--selector-icon-size:1em;--selector-gap:4px;--cs-row-height:28px}:host([cs-size="medium"]){--selector-container-min-height:40px;--selector-padding-y:6px;--cs-row-height:32px}:host([cs-size="large"]){--selector-container-min-height:48px;--selector-padding-y:10px;--selector-icon-size:1.25em;--selector-gap:8px;--cs-row-height:40px}*{box-sizing:border-box}.core-selector-wrapper{display:flex;flex-direction:column;flex:1;min-height:inherit}.af-form-label{margin-bottom:0.5rem}.search-container{display:flex;align-items:center;flex-wrap:wrap;gap:6px;border:1px solid #757575;border-radius:0px;padding:var(--selector-padding-y) var(--selector-padding-x);flex:1;min-height:var(--selector-container-min-height);cursor:text;background-color:var(--selector-background-color);position:relative;overflow:hidden}.search-container:focus-within{outline:2px solid black;outline-offset:2px}.search-container.is-inactive-selected .selector-input-field{caret-color:transparent;cursor:default}.is-inactive-selected+.suggestions-box-container{display:none !important}.search-container.is-inactive-selected .search-icon-container{display:none}.search-container.is-inactive-selected .input-area{padding-left:0}.input-controls-wrapper{position:relative;width:100%;display:flex;align-items:center}.search-icon-container{position:absolute;left:0;top:50%;width:20px;height:20px;transform:translateY(-50%);z-index:1;pointer-events:none;display:flex;align-items:center;justify-content:center;transition:transform 0.2s ease-in-out, opacity 0.2s ease-in-out;opacity:1;max-height:100%}.search-icon-container.is-hidden{opacity:0;transform:translateY(-50%) scale(0.7)}.selector-search-icon{color:var(--digi--color--icon--primary, #333);display:block;flex:0 0 auto;width:20px;height:20px}.clear-button>span{color:var(--digi--color--icon--primary, #333)}.input-area{flex:1;min-width:0;padding-left:27px;display:flex;align-items:center;transition:padding-left 0.2s ease-in-out}.input-area.has-value{padding-left:0}.selector-input-field{width:100%;font-family:inherit;font-size:var(--selector-font-size);color:inherit;border:none;outline:none;background:transparent;transition:padding-right 0.2s ease-in-out}.search-container.has-input .selector-input-field{padding-right:0}.selector-input-field::placeholder{color:var(--selector-placeholder-color);opacity:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.clear-button{position:static;flex-shrink:0;opacity:0;pointer-events:none;z-index:2;background:none;border:none;padding:0;margin:0;height:20px;width:20px;cursor:pointer;color:var(--selector-clear-button-color);line-height:1;display:flex;align-items:center;transition:color 0.2s ease-in-out, opacity 0.2s ease-in-out}.clear-button.is-visible{opacity:1;pointer-events:auto}.clear-button:hover,.clear-button:focus{color:var(--selector-clear-button-hover-color);outline:none}.search-container.multi-search-container{display:flex;flex-direction:column;gap:0.5rem;align-items:stretch;padding-top:var(--selector-padding-y);padding-bottom:var(--selector-padding-y);width:100%;max-width:100%}.selected-tags-wrapper{display:flex;flex-wrap:wrap;gap:0.5rem;width:100%;max-width:100%;box-sizing:border-box}.selected-tags-wrapper .af-tag{display:block;max-width:100%;min-width:0}.selected-tags-wrapper .af-tag__button{white-space:normal !important;height:auto !important;text-align:left !important;word-break:break-word !important;overflow-wrap:anywhere !important;max-width:100% !important}.search-container.single-value-display{display:flex;align-items:center;flex-wrap:nowrap;gap:0.5rem;min-height:var(--selector-container-min-height);padding:var(--selector-padding-y) var(--selector-padding-x)}.selected-text-in-box{flex-grow:1;white-space:normal;word-break:break-word;min-width:0;line-height:inherit}.search-container.single-value-display .clear-button{position:static;transform:none;opacity:1;pointer-events:auto;flex-shrink:0}.combobox-container{position:relative;margin-top:0;display:flex;flex-direction:column;flex:1}.suggestions-box-container{position:absolute;top:100%;left:0;right:0;z-index:100}.suggestions-box-container.is-hidden-list{z-index:101;pointer-events:none}.suggestions-box{position:relative;background-color:white;border:1px solid var(--selector-suggestion-border-color);border-radius:4px;box-shadow:0 4px 12px rgba(0, 0, 0, 0.15);overflow-y:auto;margin:2px 0px;max-height:calc(var(--max-visible-rows, 10) * var(--cs-row-height) + 40px)}.suggestion-item{display:flex;align-items:center;min-height:var(--cs-row-height);height:auto;padding:6px 1rem;font-size:inherit;line-height:1.25;cursor:pointer;color:var(--selector-suggestion-text-color);list-style:none;transition:background-color 0.15s ease, color 0.15s ease;white-space:normal !important;word-break:break-word !important;overflow-wrap:anywhere !important;position:relative;z-index:1;box-sizing:border-box}.suggestion-item>span{transition:font-weight 0.2s ease, transform 0.2s ease;display:inline;vertical-align:middle;white-space:normal;word-break:break-word;overflow-wrap:anywhere}.suggestion-item:hover,.suggestion-item.active-suggestion{background-color:var(--selector-suggestion-active-background)}.suggestion-item.active-suggestion.is-keyboard-focus{outline:1px solid black;outline-offset:-1px}.suggestion-item.is-selected{color:var(--selector-suggestion-text-color) !important;cursor:default;background-color:#f2f2f2 !important}.suggestion-item.is-selected span{font-weight:600}.selection-indicator-icon{width:0;height:20px;opacity:0;transform:scale(0.5);margin-right:0;transition:width 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), margin-right 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);color:var(--digi--grayscale-800, #333);flex-shrink:0;display:flex;align-items:center;justify-content:center;overflow:hidden}.suggestion-item.is-selected .selection-indicator-icon{width:24px;opacity:1;transform:scale(1);margin-right:8px}.suggestion-item.is-selected.active-suggestion{background-color:#f2f2f2 !important}.suggestion-item .suggestion-text strong,.suggestion-item .match-highlight{font-weight:var(--selector-suggestion-highlight-weight);color:inherit;display:inline}.metadata-dimmed,.occupation-variant-label{font-size:1rem;color:var(--digi--grayscale-700, #757575);margin-left:0.25rem;display:inline;vertical-align:baseline;line-height:inherit;white-space:normal}.suggestion-item.no-results{color:var(--selector-placeholder-color);cursor:default;padding:0.5rem 1rem;font-style:italic;text-align:center;height:auto}.search-container.has-validation-error{border-color:var(--selector-error-color);border-width:2px;background-color:#fef3f2}.search-container.has-positive-validation{border-color:#155724;background-color:#d4edda}.status-message{margin-top:0.5rem}.selector-validation-message{margin-top:0.5rem;display:block}.visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}input::-webkit-search-decoration,input::-webkit-search-cancel-button,input::-webkit-search-results-button,input::-webkit-search-results-decoration{-webkit-appearance:none;display:none}input::-ms-clear{display:none;width:0;height:0}.list-header-container{position:sticky;top:0;z-index:10;background-color:#f8f9fa;border-bottom:1px solid var(--selector-suggestion-border-color);min-height:auto;display:flex;flex-direction:column}.list-header-container ::slotted([slot="suggestions-overlay"]){position:absolute !important;top:0;left:0;width:100%;height:100%;z-index:20}.suggestions-box>::slotted([slot="suggestions-overlay"]){position:sticky !important;top:0;left:0;width:100%;z-index:20}.list-header{display:flex;align-items:center;min-height:var(--cs-row-height);padding:6px 1rem;font-size:0.875rem;line-height:1.25;color:var(--digi--grayscale-700, #757575);border-bottom:1px solid var(--selector-suggestion-border-color, #ced4da)}.list-header span{font-size:0.875rem;font-weight:normal}.history-clear-link{color:var(--digi--grayscale-700, #757575);text-decoration:underline;cursor:pointer;margin-left:0.25rem;background:transparent;border:0;padding:0;font:inherit}.history-clear-link:hover{color:var(--digi--grayscale-900, #222)}@keyframes cs-shrink-fade{from{opacity:1}to{opacity:1}}@keyframes cs-collapse{from{height:auto}to{height:auto}}.cs-toast{position:absolute;top:0;left:0;width:100%;height:100%;z-index:20;display:flex;align-items:center;justify-content:center;gap:8px;background-color:#f8fdf0;animation:cs-toastSlideDown 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;pointer-events:none;box-sizing:border-box}.cs-toast.is-closing{animation:cs-toastSlideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards}.cs-toast-text{margin:0;font-size:0.875rem;font-weight:500;color:#2e7d32}@keyframes cs-toastSlideDown{from{transform:translateY(-100%)}to{transform:translateY(0)}}@keyframes cs-toastSlideUp{from{transform:translateY(0)}to{transform:translateY(-100%)}}.selector-input-field.visually-hidden-selected{position:absolute;opacity:0;pointer-events:none;width:1px;height:1px;overflow:hidden}`;
82
+ const coreSelectorCss = () => `:host{--digi--grayscale-0:#ffffff;--digi--grayscale-50:#fbfbfb;--digi--grayscale-100:#f4f4f4;--digi--grayscale-200:#ededed;--digi--grayscale-300:#e4e4e4;--digi--grayscale-400:#dddddd;--digi--grayscale-500:#cacaca;--digi--grayscale-600:#acacac;--digi--grayscale-700:#757575;--digi--grayscale-800:#5c5c5c;--digi--grayscale-900:#333333;--digi--grayscale-1000:#000000;--digi--global--color--cta--link--base:#1616b2;--digi--global--color--function--danger--base:#da0000;--digi--global--color--function--success--base:#008a20;--digi--global--color--function--success--lightest-3:#d4edda;--digi--global--color--function--warning--base:#ffe200;--digi--color--text--primary:var(--digi--grayscale-900);--digi--color--text--secondary:var(--digi--grayscale-700);--digi--color--text--link:var(--digi--global--color--cta--link--base);--digi--color--icons--success:var(--digi--global--color--function--success--base);--digi--color--icons--warning:#8a7a00;--digi--color--icons--danger:var(--digi--global--color--function--danger--base);--digi--global--typography--font-family--default:"Open Sans", Arial, sans-serif;--digi--global--typography--font-size--base:1rem;--digi--global--typography--font-size--small:0.875rem;--digi--global--typography--font-weight--regular:400;--digi--global--typography--font-weight--semibold:600;--digi--global--typography--font-weight--bold:700;--digi--global--typography--line-height--base:1.5;--digi--typography--label--font-size--desktop:1rem;--digi--typography--label--font-weight--desktop:600;--digi--typography--label--line-height--desktop:1.5;--digi--typography--label-description--font-size--desktop:1rem;--digi--typography--label-description--line-height--desktop:1.5;--digi--typography--tag--font-size--desktop:0.875rem;--digi--gutter--icon:0.625rem;--digi--gutter--smaller:0.75rem;--digi--gutter--small:0.875rem;--digi--gutter--medium:1rem;--digi--border-width--primary:1px;--digi--border-style--primary:solid;--digi--border-radius--primary:0;--digi--border-radius--secondary:6px;--af-tag-color:#091d54;--af-tag-hover-background:#ddf1fc}.af-form-label{color:var(--digi--color--text--primary);display:flex;flex-direction:column;font-family:var(--digi--global--typography--font-family--default);font-size:var(--digi--typography--label--font-size--desktop);margin-bottom:0.5rem}.af-form-label__label{cursor:pointer;display:block;font-weight:var(--digi--typography--label--font-weight--desktop);line-height:var(--digi--typography--label--line-height--desktop)}.af-form-label__description{display:block;font-size:var(--digi--typography--label-description--font-size--desktop);line-height:var(--digi--typography--label-description--line-height--desktop);max-width:35rem}.af-validation-message{align-items:center;display:flex;flex-wrap:wrap}.af-validation-message__icon{flex:0 0 auto;height:1.25em;margin-inline-end:var(--digi--gutter--icon);width:1.25em}.af-validation-message__icon--success,.af-validation-message__icon--error{background-color:var(--af-validation-icon-color, currentColor);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.af-validation-message__icon--success{--af-validation-icon-color:var(--digi--color--icons--success);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 25 25'%3E%3Cpath d='M25 12.5C25 19.404 19.404 25 12.5 25S0 19.404 0 12.5 5.596 0 12.5 0 25 5.596 25 12.5zm-13.946 6.619l9.274-9.275a.806.806 0 000-1.14l-1.14-1.14a.806.806 0 00-1.14 0l-7.564 7.563-3.531-3.531a.807.807 0 00-1.14 0l-1.141 1.14a.806.806 0 000 1.14l5.242 5.243a.806.806 0 001.14 0z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 25 25'%3E%3Cpath d='M25 12.5C25 19.404 19.404 25 12.5 25S0 19.404 0 12.5 5.596 0 12.5 0 25 5.596 25 12.5zm-13.946 6.619l9.274-9.275a.806.806 0 000-1.14l-1.14-1.14a.806.806 0 00-1.14 0l-7.564 7.563-3.531-3.531a.807.807 0 00-1.14 0l-1.141 1.14a.806.806 0 000 1.14l5.242 5.243a.806.806 0 001.14 0z'/%3E%3C/svg%3E")}.af-validation-message__icon--error{--af-validation-icon-color:var(--digi--color--icons--danger);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M34.4328058,0 C35.5494848,0 36.5900526,0.609146757 37.1483921,1.58958113 L47.5812454,19.9104189 C48.1395849,20.8909496 48.1395849,22.1090504 47.5812454,23.0895811 L37.1483921,41.4104189 C36.5900526,42.3908532 35.5494848,43 34.4328058,43 L13.5671942,43 C12.4505152,43 11.4099474,42.3908532 10.8516079,41.4104189 L0.41875464,23.0895811 C-0.13958488,22.1090504 -0.13958488,20.8909496 0.41875464,19.9104189 L10.8516079,1.58958113 C11.4099474,0.609146757 12.4505152,0 13.5671942,0 Z M18.6736823,12.3728178 C18.2711762,11.964729 17.6203819,11.964729 17.2178757,12.3728178 L15.2825964,14.334939 C14.8800903,14.7430278 14.8800903,15.4028485 15.2825964,15.8109373 L20.6089616,21.2111779 L15.2825964,26.6114185 C14.8800903,27.0195074 14.8800903,27.6793281 15.2825964,28.0874169 L17.2178757,30.049538 C17.6203819,30.4576269 18.2711762,30.4576269 18.6736823,30.049538 L24.0000475,24.6492974 L29.3264127,30.049538 C29.7289188,30.4576269 30.3797132,30.4576269 30.7822193,30.049538 L32.7174986,28.0874169 C33.1200048,27.6793281 33.1200048,27.0195074 32.7174986,26.6114185 L27.3911334,21.2111779 L32.7174986,15.8109373 C33.1200048,15.4028485 33.1200048,14.7430278 32.7174986,14.334939 L30.7822193,12.3728178 C30.3797132,11.964729 29.7289188,11.964729 29.3264127,12.3728178 L24.0000475,17.7730584 Z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M34.4328058,0 C35.5494848,0 36.5900526,0.609146757 37.1483921,1.58958113 L47.5812454,19.9104189 C48.1395849,20.8909496 48.1395849,22.1090504 47.5812454,23.0895811 L37.1483921,41.4104189 C36.5900526,42.3908532 35.5494848,43 34.4328058,43 L13.5671942,43 C12.4505152,43 11.4099474,42.3908532 10.8516079,41.4104189 L0.41875464,23.0895811 C-0.13958488,22.1090504 -0.13958488,20.8909496 0.41875464,19.9104189 L10.8516079,1.58958113 C11.4099474,0.609146757 12.4505152,0 13.5671942,0 Z M18.6736823,12.3728178 C18.2711762,11.964729 17.6203819,11.964729 17.2178757,12.3728178 L15.2825964,14.334939 C14.8800903,14.7430278 14.8800903,15.4028485 15.2825964,15.8109373 L20.6089616,21.2111779 L15.2825964,26.6114185 C14.8800903,27.0195074 14.8800903,27.6793281 15.2825964,28.0874169 L17.2178757,30.049538 C17.6203819,30.4576269 18.2711762,30.4576269 18.6736823,30.049538 L24.0000475,24.6492974 L29.3264127,30.049538 C29.7289188,30.4576269 30.3797132,30.4576269 30.7822193,30.049538 L32.7174986,28.0874169 C33.1200048,27.6793281 33.1200048,27.0195074 32.7174986,26.6114185 L27.3911334,21.2111779 L32.7174986,15.8109373 C33.1200048,15.4028485 33.1200048,14.7430278 32.7174986,14.334939 L30.7822193,12.3728178 C30.3797132,11.964729 29.7289188,11.964729 29.3264127,12.3728178 L24.0000475,17.7730584 Z'/%3E%3C/svg%3E")}.af-validation-message__icon--warning{background:center / contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Ccircle cx='9' cy='9' r='6.75' fill='%23333'/%3E%3Cpath d='m18 9c0 4.9717-4.0298 9-9 9-4.9702 0-9-4.0283-9-9 0-4.9688 4.0298-9 9-9 4.9702 0 9 4.0312 9 9zm-9 1.8145c-0.92196 0-1.6694 0.7474-1.6694 1.6694 0 0.92196 0.7474 1.6694 1.6694 1.6694s1.6694-0.7474 1.6694-1.6694c0-0.92196-0.7474-1.6694-1.6694-1.6694zm-1.3157-1.065c0.012593 0.23095 0.20355 0.41175 0.43483 0.41175h1.7618c0.23128 0 0.42224-0.1808 0.43483-0.41175l0.2692-4.9355c0.013609-0.24946-0.18501-0.45922-0.43483-0.45922h-2.3002c-0.24982 0-0.4484 0.20976-0.43479 0.45922l0.2692 4.9355z' fill='%23FFE200'/%3E%3C/svg%3E");position:relative;top:3px}.af-validation-message__text{color:var(--digi--color--text--primary);flex:1;font-family:var(--digi--global--typography--font-family--default);font-size:var(--digi--typography--tag--font-size--desktop);transform:translateY(1px)}.af-tag{display:block;max-width:100%;min-width:0}.af-tag__button{align-items:center;background:var(--digi--grayscale-0);border:var(--digi--border-width--primary) var(--digi--border-style--primary) var(--af-tag-color);border-radius:var(--digi--border-radius--secondary);color:var(--af-tag-color);cursor:pointer;display:inline-flex;font-family:var(--digi--global--typography--font-family--default);font-size:0.875rem;font-weight:var(--digi--global--typography--font-weight--semibold);gap:10px;height:auto;max-width:100%;min-height:unset;min-width:0;padding:6px 8px;text-align:left;white-space:normal}.af-tag__button:hover{background:var(--af-tag-hover-background)}.af-tag__button:focus-visible{background:var(--af-tag-hover-background);border-color:var(--af-tag-color);outline:2px solid var(--digi--grayscale-1000);outline-offset:2px;box-shadow:0 0 0 5px var(--digi--grayscale-0)}.af-tag__button:active{background:var(--af-tag-hover-background)}.af-tag__text{display:inline-block;max-width:100%;min-width:0;white-space:normal}.af-tag__text--break{overflow-wrap:anywhere;word-break:break-word}.af-tag__remove-icon{flex:0 0 auto;height:1em;min-height:0 !important;width:1em}:host{--selector-width:var(--cs-width, 100%);--selector-min-width:var(--cs-min-width, 200px);--selector-max-width:var(--cs-max-width, none);--selector-height:var(--cs-height, auto);--selector-min-height:var(--cs-min-height, auto);--selector-max-height:var(--cs-max-height, none);--selector-font-family:var(--global-font-family, 'Open Sans', sans-serif);--selector-font-size:var(--cs-font-size, 1rem);--selector-text-color:var(--cs-text-color, #212529);--selector-placeholder-color:var(--cs-placeholder-color, #6c757d);--selector-border-color:var(--cs-border-color, #d1d5db);--selector-focus-border-color:var(--cs-focus-border-color, #86b7fe);--selector-focus-shadow:var(--cs-focus-shadow, 0 0 0 0.25rem rgba(13, 110, 253, 0.25));--selector-background-color:var(--cs-background-color, #fff);--selector-icon-color:var(--cs-icon-color, #6c757d);--selector-clear-button-color:var(--cs-clear-button-color, #6c757d);--selector-clear-button-hover-color:var(--cs-clear-button-hover-color, #212529);--selector-suggestion-background-color:var(--cs-suggestion-background-color, #fff);--selector-suggestion-border-color:var(--cs-suggestion-border-color, #ced4da);--selector-suggestion-hover-background:var(--cs-suggestion-hover-background, #e9ecef);--selector-suggestion-active-background:var(--cs-suggestion-active-background, #dde4eb);--selector-suggestion-text-color:var(--cs-suggestion-text-color, #212529);--selector-suggestion-highlight-weight:var(--cs-suggestion-highlight-weight, bold);--selector-error-color:var(--cs-error-color, #dc3545);--selector-loading-color:var(--cs-loading-color, #6c757d);--selector-container-min-height:40px;--selector-padding-y:6px;--selector-padding-x:10px;--selector-icon-size:1.1em;--selector-gap:6px;--cs-row-height:32px;display:flex;flex-direction:column;width:var(--selector-width);min-width:var(--selector-min-width);max-width:var(--selector-max-width);height:var(--selector-height);min-height:var(--selector-min-height);max-height:var(--selector-max-height);font-family:var(--selector-font-family);font-size:var(--selector-font-size);color:var(--selector-text-color);position:relative}:host([cs-size="small"]){--selector-container-min-height:32px;--selector-padding-y:2px;--selector-icon-size:1em;--selector-gap:4px;--cs-row-height:28px}:host([cs-size="medium"]){--selector-container-min-height:40px;--selector-padding-y:6px;--cs-row-height:32px}:host([cs-size="large"]){--selector-container-min-height:48px;--selector-padding-y:10px;--selector-icon-size:1.25em;--selector-gap:8px;--cs-row-height:40px}*{box-sizing:border-box}.core-selector-wrapper{display:flex;flex-direction:column;flex:1;min-height:inherit}.af-form-label{margin-bottom:0.5rem}.search-container{display:flex;align-items:center;flex-wrap:wrap;gap:6px;border:1px solid #757575;border-radius:0px;padding:var(--selector-padding-y) var(--selector-padding-x);flex:1;min-height:var(--selector-container-min-height);cursor:text;background-color:var(--selector-background-color);position:relative;overflow:hidden}.search-container:focus-within{outline:2px solid black;outline-offset:2px}.search-container.is-inactive-selected .selector-input-field{caret-color:transparent;cursor:default}.is-inactive-selected+.suggestions-box-container{display:none !important}.search-container.is-inactive-selected .search-icon-container{display:none}.search-container.is-inactive-selected .input-area{padding-left:0}.input-controls-wrapper{position:relative;width:100%;display:flex;align-items:center}.search-icon-container{position:absolute;left:0;top:50%;width:20px;height:20px;transform:translateY(-50%);z-index:1;pointer-events:none;display:flex;align-items:center;justify-content:center;transition:transform 0.2s ease-in-out, opacity 0.2s ease-in-out;opacity:1;max-height:100%}.search-icon-container.is-hidden{opacity:0;transform:translateY(-50%) scale(0.7)}.selector-search-icon{color:var(--digi--color--icon--primary, #333);display:block;flex:0 0 auto;width:20px;height:20px}.clear-button>span{color:var(--digi--color--icon--primary, #333)}.input-area{position:relative;flex:1;min-width:0;padding-left:27px;display:flex;align-items:center;transition:padding-left 0.2s ease-in-out}.input-area.has-value{padding-left:0}.selector-placeholder-overlay{position:absolute;left:27px;right:0;top:50%;transform:translateY(-50%);color:var(--selector-placeholder-color);font-family:inherit;font-size:var(--selector-font-size);line-height:normal;padding:1px 2px;pointer-events:none;user-select:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:left 0.2s ease-in-out}.input-area.has-value .selector-placeholder-overlay{left:0}.selector-input-field{position:relative;z-index:1;width:100%;font-family:inherit;font-size:var(--selector-font-size);color:inherit;border:none;outline:none;background:transparent;transition:padding-right 0.2s ease-in-out}.search-container.has-input .selector-input-field{padding-right:0}.selector-input-field::placeholder{color:var(--selector-placeholder-color);opacity:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.clear-button{position:static;flex-shrink:0;opacity:0;pointer-events:none;z-index:2;background:none;border:none;padding:0;margin:0;height:20px;width:20px;cursor:pointer;color:var(--selector-clear-button-color);line-height:1;display:flex;align-items:center;transition:color 0.2s ease-in-out, opacity 0.2s ease-in-out}.clear-button.is-visible{opacity:1;pointer-events:auto}.clear-button:hover,.clear-button:focus{color:var(--selector-clear-button-hover-color);outline:none}.search-container.multi-search-container{display:flex;flex-direction:column;gap:0.5rem;align-items:stretch;padding-top:var(--selector-padding-y);padding-bottom:var(--selector-padding-y);width:100%;max-width:100%}.selected-tags-wrapper{display:flex;flex-wrap:wrap;gap:0.5rem;width:100%;max-width:100%;box-sizing:border-box}.selected-tags-wrapper .af-tag{display:block;max-width:100%;min-width:0}.selected-tags-wrapper .af-tag__button{white-space:normal !important;height:auto !important;text-align:left !important;word-break:break-word !important;overflow-wrap:anywhere !important;max-width:100% !important}.search-container.single-value-display{display:flex;align-items:center;flex-wrap:nowrap;gap:0.5rem;min-height:var(--selector-container-min-height);padding:var(--selector-padding-y) var(--selector-padding-x)}.selected-text-in-box{flex-grow:1;white-space:normal;word-break:break-word;min-width:0;line-height:inherit}.search-container.single-value-display .clear-button{position:static;transform:none;opacity:1;pointer-events:auto;flex-shrink:0}.combobox-container{position:relative;margin-top:0;display:flex;flex-direction:column;flex:1}.suggestions-box-container{position:absolute;top:100%;left:0;right:0;z-index:100}.suggestions-box-container.is-hidden-list{z-index:101;pointer-events:none}.suggestions-box{position:relative;background-color:white;border:1px solid var(--selector-suggestion-border-color);border-radius:4px;box-shadow:0 4px 12px rgba(0, 0, 0, 0.15);overflow-y:auto;margin:2px 0px;max-height:calc(var(--max-visible-rows, 10) * var(--cs-row-height) + 40px)}.suggestion-item{display:flex;align-items:center;min-height:var(--cs-row-height);height:auto;padding:6px 1rem;font-size:inherit;line-height:1.25;cursor:pointer;color:var(--selector-suggestion-text-color);list-style:none;transition:background-color 0.15s ease, color 0.15s ease;white-space:normal !important;word-break:break-word !important;overflow-wrap:anywhere !important;position:relative;z-index:1;box-sizing:border-box}.suggestion-item>span{transition:font-weight 0.2s ease, transform 0.2s ease;display:inline;vertical-align:middle;white-space:normal;word-break:break-word;overflow-wrap:anywhere}.suggestion-item:hover,.suggestion-item.active-suggestion{background-color:var(--selector-suggestion-active-background)}.suggestions-box.is-keyboard-nav .suggestion-item:hover:not(.active-suggestion){background-color:transparent}.suggestion-item.active-suggestion.is-keyboard-focus{outline:1px solid black;outline-offset:-1px}.suggestion-item.is-selected{color:var(--selector-suggestion-text-color) !important;cursor:default;background-color:#f2f2f2 !important}.suggestion-item.is-selected span{font-weight:600}.selection-indicator-icon{width:0;height:20px;opacity:0;transform:scale(0.5);margin-right:0;transition:width 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), margin-right 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);color:var(--digi--grayscale-800, #333);flex-shrink:0;display:flex;align-items:center;justify-content:center;overflow:hidden}.suggestion-item.is-selected .selection-indicator-icon{width:24px;opacity:1;transform:scale(1);margin-right:8px}.suggestion-item.is-selected.active-suggestion{background-color:#f2f2f2 !important}.suggestion-item .suggestion-text strong,.suggestion-item .match-highlight{font-weight:var(--selector-suggestion-highlight-weight);color:inherit;display:inline}.metadata-dimmed,.occupation-variant-label{font-size:1rem;color:var(--digi--grayscale-700, #757575);margin-left:0.25rem;display:inline;vertical-align:baseline;line-height:inherit;white-space:normal}.suggestion-item.no-results{color:var(--selector-placeholder-color);cursor:default;padding:0.5rem 1rem;font-style:italic;text-align:center;height:auto}.search-container.has-validation-error{border-color:var(--selector-error-color);border-width:2px;background-color:#fef3f2}.search-container.has-positive-validation{border-color:#155724;background-color:#d4edda}.status-message{margin-top:0.5rem}.selector-validation-message{margin-top:0.5rem;display:block}.visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}input::-webkit-search-decoration,input::-webkit-search-cancel-button,input::-webkit-search-results-button,input::-webkit-search-results-decoration{-webkit-appearance:none;display:none}input::-ms-clear{display:none;width:0;height:0}.list-header-container{position:sticky;top:0;z-index:10;background-color:#f8f9fa;border-bottom:1px solid var(--selector-suggestion-border-color);min-height:auto;display:flex;flex-direction:column}.list-header-container ::slotted([slot="suggestions-overlay"]){position:absolute !important;top:0;left:0;width:100%;height:100%;z-index:20}.suggestions-box>::slotted([slot="suggestions-overlay"]){position:sticky !important;top:0;left:0;width:100%;z-index:20}.list-header{display:flex;align-items:center;min-height:var(--cs-row-height);padding:6px 1rem;font-size:0.875rem;line-height:1.25;color:var(--digi--grayscale-700, #757575);border-bottom:1px solid var(--selector-suggestion-border-color, #ced4da)}.list-header span{font-size:0.875rem;font-weight:normal}.history-clear-link{color:var(--digi--grayscale-700, #757575);text-decoration:underline;cursor:pointer;margin-left:0.25rem;background:transparent;border:0;padding:0;font:inherit}.history-clear-link:hover{color:var(--digi--grayscale-900, #222)}@keyframes cs-shrink-fade{from{opacity:1}to{opacity:1}}@keyframes cs-collapse{from{height:auto}to{height:auto}}.cs-toast{position:absolute;top:0;left:0;width:100%;height:100%;z-index:20;display:flex;align-items:center;justify-content:center;gap:8px;background-color:#f8fdf0;animation:cs-toastSlideDown 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;pointer-events:none;box-sizing:border-box}.cs-toast.is-closing{animation:cs-toastSlideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards}.cs-toast-text{margin:0;font-size:0.875rem;font-weight:500;color:#2e7d32}@keyframes cs-toastSlideDown{from{transform:translateY(-100%)}to{transform:translateY(0)}}@keyframes cs-toastSlideUp{from{transform:translateY(0)}to{transform:translateY(-100%)}}.selector-input-field.visually-hidden-selected{position:absolute;opacity:0;pointer-events:none;width:1px;height:1px;overflow:hidden}`;
64
83
 
65
84
  const CoreSelector = class {
66
85
  constructor(hostRef) {
@@ -88,7 +107,7 @@ const CoreSelector = class {
88
107
  disabled: false,
89
108
  placeholder: 'Sök...',
90
109
  minLength: 1,
91
- maxResults: 10,
110
+ maxResults: 20,
92
111
  enableMultiple: false,
93
112
  showSearchIcon: true,
94
113
  requireSelection: true,
@@ -112,6 +131,7 @@ const CoreSelector = class {
112
131
  activeIndex = -1;
113
132
  isFocusedInternal = false;
114
133
  isNavigatingWithKeyboard = false;
134
+ isKeyboardNavigationActive = false;
115
135
  async setFocus() {
116
136
  if (this.inputRef) {
117
137
  this.inputRef.focus();
@@ -132,9 +152,10 @@ const CoreSelector = class {
132
152
  }
133
153
  if (!this.state)
134
154
  return;
135
- if (event.target.tagName === 'BUTTON')
155
+ if (event.target?.tagName === 'BUTTON')
136
156
  return;
137
157
  if (event.key !== 'ArrowUp' && event.key !== 'ArrowDown' && event.key !== 'Enter' && event.key !== 'Escape') {
158
+ this.isKeyboardNavigationActive = false;
138
159
  this.isNavigatingWithKeyboard = false;
139
160
  }
140
161
  if (this.state.status === 'itemSelected') {
@@ -152,11 +173,10 @@ const CoreSelector = class {
152
173
  case 'ArrowDown':
153
174
  if (totalOptions > 0) {
154
175
  event.preventDefault();
176
+ this.isKeyboardNavigationActive = true;
155
177
  this.isNavigatingWithKeyboard = true;
156
- if (this.activeIndex < totalOptions - 1) {
157
- this.activeIndex = this.activeIndex + 1;
158
- this.scrollToActive();
159
- }
178
+ this.activeIndex = getNextActiveIndex('down', this.activeIndex, totalOptions);
179
+ this.scrollToActive();
160
180
  if (this.activeIndex >= suggestions.length - 3) {
161
181
  this.csLoadMore.emit();
162
182
  }
@@ -168,15 +188,15 @@ const CoreSelector = class {
168
188
  case 'ArrowUp':
169
189
  if (totalOptions > 0) {
170
190
  event.preventDefault();
191
+ this.isKeyboardNavigationActive = true;
171
192
  this.isNavigatingWithKeyboard = true;
172
- if (this.activeIndex > 0) {
173
- this.activeIndex = this.activeIndex - 1;
193
+ this.activeIndex = getNextActiveIndex('up', this.activeIndex, totalOptions);
194
+ if (this.activeIndex >= 0) {
174
195
  this.scrollToActive();
175
196
  }
176
- else if (this.activeIndex === 0 || this.activeIndex === -1) {
177
- // Wrap around to the last option (which might be manual input)
178
- this.activeIndex = totalOptions - 1;
179
- this.scrollToActive();
197
+ else {
198
+ this.isKeyboardNavigationActive = false;
199
+ this.isNavigatingWithKeyboard = false;
180
200
  }
181
201
  }
182
202
  break;
@@ -309,14 +329,42 @@ const CoreSelector = class {
309
329
  this.csLoadMore.emit();
310
330
  }
311
331
  }
332
+ handleMouseMove = (event) => {
333
+ // Chrome fires a zero-movement mousemove when the list scrolls under a
334
+ // stationary pointer; only real pointer movement should end keyboard nav.
335
+ if (event.movementX === 0 && event.movementY === 0)
336
+ return;
337
+ if (this.isKeyboardNavigationActive) {
338
+ this.isKeyboardNavigationActive = false;
339
+ this.isNavigatingWithKeyboard = false;
340
+ }
341
+ };
342
+ handleMouseLeave = () => {
343
+ if (!this.isKeyboardNavigationActive) {
344
+ this.activeIndex = -1;
345
+ }
346
+ };
312
347
  scrollToActive() {
313
348
  if (!this.listRef || !this.state)
314
349
  return;
350
+ if (this.activeIndex === -1) {
351
+ this.listRef.scrollTop = 0;
352
+ return;
353
+ }
315
354
  const optionId = this.activeIndex === this.state.suggestions.length
316
355
  ? `${this.componentId}-list-option-manual-input`
317
356
  : `${this.componentId}-list-option-${this.activeIndex}`;
318
357
  const activeElement = this.listRef.querySelector(`#${optionId}`);
319
- activeElement?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
358
+ if (!activeElement)
359
+ return;
360
+ const containerRect = this.listRef.getBoundingClientRect();
361
+ const targetRect = activeElement.getBoundingClientRect();
362
+ if (targetRect.bottom > containerRect.bottom) {
363
+ this.listRef.scrollTop += (targetRect.bottom - containerRect.bottom);
364
+ }
365
+ else if (targetRect.top < containerRect.top) {
366
+ this.listRef.scrollTop -= (containerRect.top - targetRect.top);
367
+ }
320
368
  }
321
369
  handleManualSelect() {
322
370
  const item = { id: '', label: this.state.inputValue.trim(), metadata: { type: 'ManualInput' } };
@@ -330,7 +378,7 @@ const CoreSelector = class {
330
378
  if (!this.state)
331
379
  return null;
332
380
  const isSelected = this.state.status === 'itemSelected';
333
- return (index.h("div", { class: { 'core-selector-wrapper': true, 'is-disabled': !!this.config.disabled }, "aria-disabled": this.config.disabled ? 'true' : 'false', onKeyDown: (e) => this.handleKeyDown(e), onMouseMove: () => { this.isNavigatingWithKeyboard = false; }, onFocusin: this.onWrapperFocusIn, onFocusout: this.onWrapperFocusOut }, this.label && (index.h(AfLabel, { label: this.label, forId: `${this.componentId}-input`, description: this.labelDescription })), this.labelDescription && (index.h("div", { id: `${this.componentId}-description`, class: "visually-hidden" }, this.labelDescription)), this.state && this.state.status === 'loading' && index.h("div", { class: "loading-indicator" }, "Laddar..."), this.state && this.state.status === 'error' && index.h("div", { class: "error-message" }, this.state.message), this.state && ['searching', 'itemSelected', 'multiSelect'].includes(this.state.status) && (index.h("div", { class: "combobox-container" }, this.renderSearchContainer(), this.isFocusedInternal && !isSelected && this.renderSuggestionsList())), this.state && this.state.validation !== 'idle' && this.state.status !== 'itemSelected' && (index.h(afValidationMessage.AfValidationMessage, { id: `${this.componentId}-validation-message`, variant: this.state.validation === 'error' ? 'error' : 'success', role: this.state.validation === 'error' ? 'alert' : undefined, class: "selector-validation-message" }, this.state.message))));
381
+ return (index.h("div", { class: { 'core-selector-wrapper': true, 'is-disabled': !!this.config.disabled }, "aria-disabled": this.config.disabled ? 'true' : 'false', onKeyDown: (e) => this.handleKeyDown(e), onMouseMove: this.handleMouseMove, onFocusin: this.onWrapperFocusIn, onFocusout: this.onWrapperFocusOut }, this.label && (index.h(AfLabel, { label: this.label, forId: `${this.componentId}-input`, description: this.labelDescription })), this.labelDescription && (index.h("div", { id: `${this.componentId}-description`, class: "visually-hidden" }, this.labelDescription)), this.state && this.state.status === 'loading' && index.h("div", { class: "loading-indicator" }, "Laddar..."), this.state && this.state.status === 'error' && index.h("div", { class: "error-message" }, this.state.message), this.state && ['searching', 'itemSelected', 'multiSelect'].includes(this.state.status) && (index.h("div", { class: "combobox-container" }, this.renderSearchContainer(), this.isFocusedInternal && !isSelected && this.renderSuggestionsList())), this.state && this.state.validation !== 'idle' && this.state.status !== 'itemSelected' && (index.h(afValidationMessage.AfValidationMessage, { id: `${this.componentId}-validation-message`, variant: this.state.validation === 'error' ? 'error' : 'success', role: this.state.validation === 'error' ? 'alert' : undefined, class: "selector-validation-message" }, this.state.message))));
334
382
  }
335
383
  renderSearchContainer() {
336
384
  const isSelected = this.state.status === 'itemSelected';
@@ -377,12 +425,13 @@ const CoreSelector = class {
377
425
  'search-icon-container': true,
378
426
  'selector-search-icon': true,
379
427
  'is-hidden': !this.config.showSearchIcon || hasInput || hasTags,
380
- } }), index.h("div", { class: { 'input-area': true, 'has-value': !this.config.showSearchIcon || hasInput || hasTags } }, isSelected && (index.h("span", { class: "selected-text-in-box" }, displayValue)), index.h("input", { class: {
428
+ } }), index.h("div", { class: { 'input-area': true, 'has-value': !this.config.showSearchIcon || hasInput || hasTags } }, isSelected && (index.h("span", { class: "selected-text-in-box" }, displayValue)), !isSelected && !hasInput && this.config.placeholder && (index.h("span", { class: "selector-placeholder-overlay", "aria-hidden": "true" }, this.config.placeholder)), index.h("input", { class: {
381
429
  'selector-input-field': true,
382
430
  'visually-hidden-selected': isSelected
383
- }, ref: (el) => this.inputRef = el, id: `${this.componentId}-input`, type: "text", placeholder: this.config.placeholder, value: displayValue, onInput: (e) => {
431
+ }, ref: (el) => this.inputRef = el, id: `${this.componentId}-input`, type: "text", value: displayValue, onInput: (e) => {
384
432
  if (this.config.disabled)
385
433
  return;
434
+ this.isKeyboardNavigationActive = false;
386
435
  this.isNavigatingWithKeyboard = false;
387
436
  this.csInput.emit(e.target.value);
388
437
  }, autocomplete: "off", role: "combobox", "aria-label": this.label, "aria-autocomplete": "list", "aria-haspopup": "listbox", "aria-expanded": !isSelected && hasSuggestions && this.isNavigatingWithKeyboard ? 'true' : 'false', "aria-controls": !isSelected && hasSuggestions && this.isNavigatingWithKeyboard ? `${this.componentId}-listbox` : undefined, "aria-activedescendant": activeDescendantId, "aria-invalid": hasError ? 'true' : 'false', "aria-describedby": ariaDescribedBy, readOnly: isSelected, disabled: !!this.config.disabled })), index.h("button", { type: "button", class: { 'clear-button': true, 'is-visible': hasInput || isSelected }, tabIndex: hasInput || isSelected ? 0 : -1, disabled: !!this.config.disabled, "aria-label": "Rensa inmatad text", onMouseDown: (e) => e.preventDefault(), onClick: () => {
@@ -406,10 +455,13 @@ const CoreSelector = class {
406
455
  }
407
456
  const listHeader = this.state.listHeader || this.config.listHeader;
408
457
  const showHistoryHeader = this.state.showHistoryHeader || (this.state.isHistoryView && this.config.showHistoryHeader);
409
- return (index.h("div", { class: "suggestions-box-container" }, index.h("div", { class: "suggestions-box", ref: (el) => (this.listRef = el), onScroll: (e) => this.handleScroll(e) }, (listHeader || showHistoryHeader) && (index.h("div", { class: "list-header-container" }, index.h("slot", { name: "suggestions-overlay" }), listHeader && (index.h("div", { class: "list-header" }, index.h("span", null, listHeader))), showHistoryHeader && (index.h("div", { class: "list-header history-header" }, index.h("span", null, "Din privata historik"), " - ", index.h("button", { type: "button", class: "history-clear-link", "aria-label": "Rensa historik", disabled: !!this.config.disabled, onMouseDown: (e) => e.preventDefault(), onClick: () => {
458
+ return (index.h("div", { class: "suggestions-box-container" }, index.h("div", { class: {
459
+ 'suggestions-box': true,
460
+ 'is-keyboard-nav': this.isNavigatingWithKeyboard
461
+ }, ref: (el) => (this.listRef = el), onScroll: (e) => this.handleScroll(e), onMouseLeave: this.handleMouseLeave }, (listHeader || showHistoryHeader) && (index.h("div", { class: "list-header-container" }, index.h("slot", { name: "suggestions-overlay" }), listHeader && (index.h("div", { class: "list-header" }, index.h("span", null, listHeader))), showHistoryHeader && (index.h("div", { class: "list-header history-header" }, index.h("span", null, "Din privata historik"), " - ", index.h("button", { type: "button", class: "history-clear-link", "aria-label": "Rensa historik", disabled: !!this.config.disabled, onMouseDown: (e) => e.preventDefault(), onClick: () => {
410
462
  if (!this.config.disabled)
411
463
  this.csClearHistory.emit();
412
- } }, "Rensa"))))), !listHeader && !showHistoryHeader && index.h("slot", { name: "suggestions-overlay" }), index.h("div", { id: `${this.componentId}-listbox`, role: "listbox" }, noResults && (index.h("div", { class: "suggestion-item no-results" }, "Inga resultat matchade din s\u00F6kning")), !noResults && this.state.suggestions.map((item, index$1) => (index.h("div", { key: item.id || index$1, role: "option", id: `${this.componentId}-list-option-${index$1}`, "aria-selected": !!item.isSelected, "aria-current": index$1 === this.activeIndex ? 'true' : 'false', class: {
464
+ } }, "Rensa"))))), !listHeader && !showHistoryHeader && index.h("slot", { name: "suggestions-overlay" }), index.h("div", { id: `${this.componentId}-listbox`, role: "listbox" }, noResults && (index.h("div", { class: "suggestion-item no-results" }, "Inga resultat matchade din s\u00F6kning")), !noResults && this.state.suggestions.map((item, index$1) => (index.h("div", { key: item.id ? `${item.id}|${item.label}` : index$1, role: "option", id: `${this.componentId}-list-option-${index$1}`, "aria-selected": !!item.isSelected, "aria-current": index$1 === this.activeIndex ? 'true' : 'false', class: {
413
465
  'suggestion-item': true,
414
466
  'active-suggestion': index$1 === this.activeIndex,
415
467
  'is-selected': !!item.isSelected,
@@ -433,12 +485,12 @@ const CoreSelector = class {
433
485
  this.historyRequestTimer = undefined;
434
486
  }, 50);
435
487
  }
436
- }, onMouseEnter: () => {
437
- if (this.config.disabled)
488
+ }, onMouseMove: this.handleMouseMove, onMouseEnter: () => {
489
+ if (this.config.disabled || this.isKeyboardNavigationActive)
438
490
  return;
491
+ this.isNavigatingWithKeyboard = false;
439
492
  if (!item.isSelected) {
440
493
  this.activeIndex = index$1;
441
- this.isNavigatingWithKeyboard = false;
442
494
  }
443
495
  } }, index.h(AfIcon, { name: "check", class: "selection-indicator-icon" }), item.displaySegments ? (index.h("span", null, item.displaySegments.map((segment, segmentIndex) => (index.h("span", { key: segmentIndex, class: {
444
496
  'match-highlight': !!segment.isMatch,
@@ -451,11 +503,11 @@ const CoreSelector = class {
451
503
  e.preventDefault();
452
504
  if (!this.config.disabled)
453
505
  this.handleManualSelect();
454
- }, onMouseEnter: () => {
455
- if (this.config.disabled)
506
+ }, onMouseMove: this.handleMouseMove, onMouseEnter: () => {
507
+ if (this.config.disabled || this.isKeyboardNavigationActive)
456
508
  return;
457
- this.activeIndex = this.state.suggestions.length;
458
509
  this.isNavigatingWithKeyboard = false;
510
+ this.activeIndex = this.state.suggestions.length;
459
511
  } }, index.h("span", null, "Anv\u00E4nd \"", index.h("strong", null, this.state.inputValue.trim()), "\"")))))));
460
512
  }
461
513
  static get delegatesFocus() { return true; }