@arbetsformedlingen/yrkesvaljaren 2.0.6 → 2.0.12

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 (83) hide show
  1. package/README.md +85 -53
  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 +81 -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 +197 -199
  9. package/dist/cjs/loader.cjs.js +1 -1
  10. package/dist/cjs/neobrutal-search.cjs.entry.js +5 -5
  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/neobrutal-search.js +1 -1
  29. package/dist/components/search.engine.js +1 -1
  30. package/dist/esm/{af-validation-message-F8NIH2rC.js → af-validation-message-BgoGzzBf.js} +1 -1
  31. package/dist/esm/core-selector.entry.js +81 -27
  32. package/dist/esm/digi-service-job-selector.entry.js +74 -46
  33. package/dist/esm/geo-valjaren.entry.js +1 -1
  34. package/dist/esm/{index-CGXZllj2.js → index-HNd02eQb.js} +9 -2
  35. package/dist/esm/index.js +2 -2
  36. package/dist/esm/job-selector-demo.entry.js +197 -199
  37. package/dist/esm/loader.js +2 -2
  38. package/dist/esm/neobrutal-search.entry.js +5 -5
  39. package/dist/esm/{search.engine-nZ7AcXba.js → search.engine-BaWUTc3r.js} +41 -27
  40. package/dist/esm/{taxonomy-registry-Dw0VR9Aw.js → taxonomy-registry-C-pSh51L.js} +21 -2
  41. package/dist/esm/yrkesvaljaren.js +3 -3
  42. package/dist/types/components/core-selector/core-selector.d.ts +3 -0
  43. package/dist/types/components/core-selector/types.d.ts +1 -1
  44. package/dist/types/components/job-selector/constants.d.ts +2 -2
  45. package/dist/types/components/job-selector/search.utils.d.ts +5 -0
  46. package/dist/types/components/job-selector/taxonomy-loader.d.ts +15 -0
  47. package/dist/types/components/job-selector/taxonomy-registry.d.ts +1 -2
  48. package/dist/types/components/job-selector/types.d.ts +2 -0
  49. package/dist/types/components/job-selector-demo/job-selector-demo.d.ts +14 -4
  50. package/dist/types/components.d.ts +4 -4
  51. package/dist/types/vitest-globals.d.ts +1 -0
  52. package/dist/vendor/taxonomy-core/index.d.ts +3 -0
  53. package/dist/vendor/taxonomy-core/index.js +1 -0
  54. package/dist/vendor/taxonomy-core/selector-navigation.d.ts +16 -0
  55. package/dist/vendor/taxonomy-core/selector-navigation.js +57 -0
  56. package/dist/vendor/taxonomy-core/selector-types.d.ts +55 -0
  57. package/dist/vendor/taxonomy-core/selector-types.js +1 -0
  58. package/dist/yrkesvaljaren/index.esm.js +1 -1
  59. package/dist/yrkesvaljaren/p-5c3a5308.entry.js +1 -0
  60. package/dist/yrkesvaljaren/p-9ecd5177.entry.js +1 -0
  61. package/dist/yrkesvaljaren/{p-DYFAzvqX.js → p-BUviBbwX.js} +1 -1
  62. package/dist/yrkesvaljaren/{p-Dw0VR9Aw.js → p-C-pSh51L.js} +1 -1
  63. package/dist/yrkesvaljaren/p-CjMoDiZD.js +1 -0
  64. package/dist/yrkesvaljaren/{p-CGXZllj2.js → p-HNd02eQb.js} +1 -1
  65. package/dist/yrkesvaljaren/{p-aef7b5ae.entry.js → p-b6130085.entry.js} +1 -1
  66. package/dist/yrkesvaljaren/{p-273cf6df.entry.js → p-dbbea724.entry.js} +1 -1
  67. package/dist/yrkesvaljaren/p-df3fa43b.entry.js +1 -0
  68. package/dist/yrkesvaljaren/yrkesvaljaren.esm.js +1 -1
  69. package/package.json +21 -11
  70. package/dist/collection/demo-data.js +0 -20
  71. package/dist/types/demo-data.d.ts +0 -16
  72. package/dist/yrkesvaljaren/fuse-B0eHOxow.js.map +0 -1
  73. package/dist/yrkesvaljaren/index-Cy4BCo5s.js.map +0 -1
  74. package/dist/yrkesvaljaren/index-DfJXTQqL.js.map +0 -1
  75. package/dist/yrkesvaljaren/index.esm.js.map +0 -1
  76. package/dist/yrkesvaljaren/p-16636162.entry.js +0 -1
  77. package/dist/yrkesvaljaren/p-9e48afa4.entry.js +0 -1
  78. package/dist/yrkesvaljaren/p-b0f16abd.entry.js +0 -1
  79. package/dist/yrkesvaljaren/p-uBrs3sSs.js +0 -1
  80. package/dist/yrkesvaljaren/search.engine-DPT6roRm.js.map +0 -1
  81. package/dist/yrkesvaljaren/taxonomy-registry-s5khf6s4.js.map +0 -1
  82. package/dist/yrkesvaljaren/types-DHUftoZJ.js.map +0 -1
  83. package/dist/yrkesvaljaren/yrkesvaljaren.esm.js.map +0 -1
package/README.md CHANGED
@@ -9,46 +9,80 @@ En robust och intelligent sökkomponent för svenska yrken, designad för hög p
9
9
 
10
10
  * **Enkelt hitta rätt yrke för användaren** <br>Sökalgoritmen prioriterar exakta träffar, prefix, flerdelade direktträffar och innehåller-träffar. Om inga direktträffar finns kan upp till tre fuzzy-träffar visas. Viktdata används som sekundär sortering.
11
11
  * **Hög prestanda:** <br>Sökningen sker lokalt i webbläsaren mot inläst yrkesdata. Komponenten gör inga sökanrop till Taxonomy API.
12
- * **Flexibel datahantering:** <br>Välj mellan automatiskt uppdaterad data, ett versionerat npm-datapaket eller en egen URL.
12
+ * **Flexibel datahantering:** <br>Versionerat npm-datapaket (rekommenderas), automatiskt uppdaterad data eller en egen URL.
13
13
 
14
14
  ---
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
+ Installera komponenten och datapaketet:
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 @arbetsformedlingen/yrkesvaljaren-data@31
22
+ ```
23
+
24
+ Datapaketets majorversion är taxonomiversionen: `31.x.y` innehåller taxonomi v31. Med `^31.0.0` i `package.json` får du rättningar av v31-datan men byter aldrig taxonomiversion av misstag. Installera nästa majorversion när du vill byta taxonomiversion.
25
+
26
+ Datan registreras med `registerTaxonomy(...)` innan komponenten används. Se [Angular](#användning-i-angular) eller [HTML och andra ramverk](#användning-i-html-och-andra-ramverk).
27
+
28
+ Utan registrerad data hämtar komponenten den senaste publicerade yrkesdatan från CDN. `af-taxonomy-url` är ett avancerat alternativ om du vill peka komponenten mot en egenhostad datafil.
29
+
30
+ ### Användning i Angular
31
+
32
+ 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.
29
33
 
30
- När ingen datakälla anges hämtar komponenten senaste publicerade yrkesdata automatiskt.
34
+ Registrera datan och webbkomponenterna i `main.ts` innan appen startar. Taxonomidatan är cirka 2 MB. Importera den dynamiskt, 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).
31
35
 
32
- 3. **Alternativ: installera ett versionerat datapaket:**
33
- ```bash
34
- npm install @taxonomy/yrkesvaljaren @taxonomy/yrkesvaljaren-data-v30
35
- ```
36
+ ```ts
37
+ // src/main.ts
38
+ import { bootstrapApplication } from '@angular/platform-browser';
39
+ import { defineCustomElements as defineYv } from '@arbetsformedlingen/yrkesvaljaren/loader';
40
+ import { registerTaxonomy } from '@arbetsformedlingen/yrkesvaljaren';
41
+ import { appConfig } from './app/app.config';
42
+ import { App } from './app/app';
36
43
 
37
- Detta låser taxonomiversionen vid build time. Registrera paketets data innan komponenten används:
44
+ async function main() {
45
+ const { metadata, taxonomyData } = await import('@arbetsformedlingen/yrkesvaljaren-data');
46
+ registerTaxonomy({ data: taxonomyData, metadata });
47
+ defineYv(window);
48
+ await bootstrapApplication(App, appConfig);
49
+ }
50
+ main().catch((err) => console.error(err));
51
+ ```
52
+
53
+ Använd sedan komponenten i en standalone-komponent med `CUSTOM_ELEMENTS_SCHEMA` och lyssna på eventet i templaten:
54
+
55
+ ```ts
56
+ // src/app/job-picker.component.ts
57
+ import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from '@angular/core';
58
+ import type { JobSelectionItem } from '@arbetsformedlingen/yrkesvaljaren';
59
+
60
+ @Component({
61
+ selector: 'app-job-picker',
62
+ standalone: true,
63
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
64
+ template: `
65
+ <digi-service-job-selector af-label="Välj yrke" (afJobSelected)="onJobSelected($event)"></digi-service-job-selector>
66
+ <p>Valt yrke: {{ selected()[0]?.preferred_label ?? 'inget' }}</p>
67
+ `,
68
+ })
69
+ export class JobPickerComponent {
70
+ readonly selected = signal<JobSelectionItem[]>([]);
71
+
72
+ onJobSelected(event: Event): void {
73
+ this.selected.set((event as CustomEvent<JobSelectionItem[] | null>).detail ?? []);
74
+ }
75
+ }
76
+ ```
38
77
 
39
- ```javascript
40
- import { registerTaxonomy } from '@taxonomy/yrkesvaljaren';
41
- import {
42
- taxonomyData,
43
- metadata
44
- } from '@taxonomy/yrkesvaljaren-data-v30';
78
+ Uppdatera vyn via signals (eller `ChangeDetectorRef`) när ni sätter värden efter en `await`. Annars uppdateras inte vyn i zoneless-appar.
45
79
 
46
- registerTaxonomy({ data: taxonomyData, metadata });
47
- ```
80
+ Kompletta exempel:
48
81
 
49
- `af-taxonomy-url` är ett tredje, avancerat alternativ. Ange då en fullständig, explicit URL till den datafil som ska användas.
82
+ - [`examples/angular-wizard`](https://gitlab.com/arbetsformedlingen/taxonomy-dev/frontend/yrkesvaljaren/-/tree/main/examples/angular-wizard): Yrkesväljaren i Reactive Forms via `ControlValueAccessor`.
83
+ - [`examples/angular-multi-occupation-skills`](https://gitlab.com/arbetsformedlingen/taxonomy-dev/frontend/yrkesvaljaren/-/tree/main/examples/angular-multi-occupation-skills): flera yrken med egna kompetensval via Kompetensväljarens headless-API.
50
84
 
51
- ### Användning
85
+ ### Användning i HTML och andra ramverk
52
86
 
53
87
  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
88
 
@@ -69,7 +103,7 @@ För att snabbt komma igång, här är ett komplett HTML-exempel som visar hur d
69
103
  <script type="module">
70
104
 
71
105
  // Imports (sökväg beror på ditt byggverktyg)
72
- import { defineCustomElements as defineYrkesvaljaren } from "@taxonomy/yrkesvaljaren/loader";
106
+ import { defineCustomElements as defineYrkesvaljaren } from "@arbetsformedlingen/yrkesvaljaren/loader";
73
107
  defineYrkesvaljaren(window);
74
108
  document.querySelector("digi-service-job-selector")
75
109
  .addEventListener("afJobSelected", (e) => {
@@ -81,6 +115,17 @@ console.log("Valt yrke:", e.detail);
81
115
  </html>
82
116
  ```
83
117
 
118
+ **Utan Angular:** registrera datapaketets data innan komponenten används:
119
+
120
+ ```javascript
121
+ import { registerTaxonomy } from '@arbetsformedlingen/yrkesvaljaren';
122
+ import { taxonomyData, metadata } from '@arbetsformedlingen/yrkesvaljaren-data';
123
+
124
+ registerTaxonomy({ data: taxonomyData, metadata });
125
+ ```
126
+
127
+ **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.
128
+
84
129
  ### Vite
85
130
 
86
131
  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 +135,7 @@ Yrkesväljaren använder en Stencil-loader som hämtar komponenternas entry-file
90
135
  export default {
91
136
  optimizeDeps: {
92
137
  exclude: [
93
- '@taxonomy/yrkesvaljaren/loader',
138
+ '@arbetsformedlingen/yrkesvaljaren/loader',
94
139
  ],
95
140
  },
96
141
  };
@@ -98,9 +143,7 @@ export default {
98
143
 
99
144
  ### Designsystem-kompatibilitet
100
145
 
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.
146
+ 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
147
 
105
148
  ### Attribut
106
149
 
@@ -109,14 +152,14 @@ De lokala tokenvärdena och primitive-stilarna är anpassade från Arbetsförmed
109
152
  | `af-label` | Etikettext som visas ovanför sökfältet. | `string` | `'Välj yrke'` |
110
153
  | `disabled` | Om satt till `true`, kan väljaren inte användas med mus eller tangentbord. | `boolean` | `false` |
111
154
  | `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'` |
155
+ | `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
156
  | `af-error-message` | Ett anpassat felmeddelande som visas vid valideringsfel. | `string` | `undefined` |
114
157
  | `af-enable-multiple` | Om satt till `true`, tillåts val av flera yrken. | `boolean` | `false` |
115
158
  | `af-history` | Sparar användarval lokalt i webbläsarens Local Storage och visar historiken på samma domän. | `boolean` | `true` |
116
159
  | `af-required` | Om satt till `true`, måste användaren göra ett val för att fältet ska vara giltigt (obligatoriskt fält). | `boolean` | `false` |
117
- | `af-manual-input` | Om satt till `true`, tillåts användaren att ange ett yrke fritt via fritext som inte finns i listan. Om satt till `false` måste ett fördefinierat yrke väljas. | `boolean` | `false` |
160
+ | `af-manual-input` | Om satt till `true` kan användaren ange ett yrke som fritext när det inte finns i listan. Om satt till `false` måste ett fördefinierat yrke väljas. | `boolean` | `false` |
118
161
  | `af-size` | Storleken på inputfältet. Möjliga värden: `'small'`, `'medium'`, `'large'`. | `string` | `'medium'` |
119
- | `af-popular` | Om satt till `true`, visas sektionen "Populära sökningar" när historiken är tom. | `boolean` | `true` |
162
+ | `af-popular` | Om satt till `true` visas sektionen "Populära sökningar" när historiken är tom. | `boolean` | `true` |
120
163
  | `af-taxonomy-url` | Fullständig, explicit URL till en egenhostad datafil. Utelämna attributet för att använda senaste data automatiskt. | `string` | `undefined` |
121
164
 
122
165
  ### Riktlinjer och rekommendationer
@@ -125,7 +168,7 @@ Tre centrala inställningar styr användarupplevelsen och datakvaliteten i Yrkes
125
168
 
126
169
  #### Obligatorisk (`af-required`)
127
170
  * **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).
171
+ * **När det rekommenderas:** I formulär och flöden där ett yrkesval är ett obligatoriskt steg i ett ärende (t.ex. inskrivning och aktivitetsrapportering).
129
172
  * **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
173
 
131
174
  #### Tillåt fritext (`af-manual-input`)
@@ -135,9 +178,9 @@ Tre centrala inställningar styr användarupplevelsen och datakvaliteten i Yrkes
135
178
  * **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
179
 
137
180
  #### 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.
181
+ * **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).
182
+ * **När det rekommenderas:** På alla tjänster mot konsumenter.
183
+ * **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. I handläggartjänster är historiken sällan till hjälp, eftersom handläggare söker på många olika yrken.
141
184
 
142
185
  ### Välj datakälla
143
186
 
@@ -170,7 +213,7 @@ dataladdning.
170
213
 
171
214
  | Metod | Returvärde | Beskrivning |
172
215
  |:---|:---|:---|
173
- | `setSelection(input)` | `Promise<JobSelectionItem[]>` | Sätter eller rensar ett programmatiskt val. Returnerar komponentens normaliserade selection. |
216
+ | `setSelection(input)` | `Promise<JobSelectionItem[]>` | Sätter eller rensar ett programmatiskt val. Returnerar komponentens normaliserade val. |
174
217
  | `setFocus()` | `Promise<void>` | Flyttar fokus till sökfältet. Används när värdappen till exempel öppnar en modal eller vill fokusera fältet efter ett fel. |
175
218
 
176
219
  #### Formulärvalidering
@@ -249,7 +292,7 @@ Komponenten gör inget anrop till Taxonomy API. För ett rikt taxonomiobjekt ide
249
292
  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
293
 
251
294
  ```javascript
252
- import { InvalidSelectionError } from '@taxonomy/yrkesvaljaren';
295
+ import { InvalidSelectionError } from '@arbetsformedlingen/yrkesvaljaren';
253
296
 
254
297
  const yrkesvaljaren = document.querySelector('digi-service-job-selector');
255
298
 
@@ -298,7 +341,7 @@ För att göra fältet obligatoriskt, använd `af-required`-attributet och stäl
298
341
  ></digi-service-job-selector>
299
342
  ```
300
343
 
301
- När detta är inställt kommer komponenten att visa ett felmeddelande om användaren klickar i och sedan lämnar fältet utan att göra ett giltigt val. Om `af-manual-input` istället är satt till `true` tillåts användaren att ange ett yrke manuellt via fritext.
344
+ När detta är inställt kommer komponenten att visa ett felmeddelande om användaren klickar i och sedan lämnar fältet utan att göra ett giltigt val. Om `af-manual-input` i stället är satt till `true` tillåts användaren att ange ett yrke manuellt via fritext.
302
345
  <br>
303
346
  #### Lyssna på valideringsstatus (`afJobValidationChange`)
304
347
 
@@ -356,14 +399,3 @@ form.addEventListener('submit', async (e) => {
356
399
  }
357
400
  });
358
401
  ```
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>',
@@ -23,6 +23,8 @@ const AfTag = ({ text, breakWords = false, onRemove }) => (index.h("span", { cla
23
23
  onRemove();
24
24
  } }, index.h("span", { class: { 'af-tag__text': true, 'af-tag__text--break': breakWords } }, text), index.h(AfIcon, { name: "x", class: "af-tag__remove-icon" }))));
25
25
 
26
+ /** Max antal tecken i sökfältet och därmed i ett manuellt val. Längsta begrepp i taxonomin är 90 tecken. */
27
+ const SELECTOR_INPUT_MAX_LENGTH = 120;
26
28
  function shouldShowManualInput(state, requireSelection = false) {
27
29
  if (!state || requireSelection)
28
30
  return false;
@@ -31,6 +33,25 @@ function shouldShowManualInput(state, requireSelection = false) {
31
33
  return false;
32
34
  return !state.suggestions.some((suggestion) => suggestion.label.toLowerCase() === inputValue.toLowerCase());
33
35
  }
36
+ function getNextActiveIndex(direction, currentIndex, totalOptions) {
37
+ if (totalOptions <= 0)
38
+ return -1;
39
+ if (direction === 'down') {
40
+ if (currentIndex < totalOptions - 1) {
41
+ return currentIndex + 1;
42
+ }
43
+ return currentIndex; // Stop at bottom, never wrap to top
44
+ }
45
+ // direction === 'up'
46
+ if (currentIndex > 0) {
47
+ return currentIndex - 1;
48
+ }
49
+ if (currentIndex === 0) {
50
+ return -1; // Return to input field
51
+ }
52
+ // currentIndex <= -1: stay in input field, never wrap to bottom
53
+ return -1;
54
+ }
34
55
  function reconcileActiveIndex({ activeIndex, newState, oldState, requireSelection = false, }) {
35
56
  if (oldState && newState.inputValue !== oldState.inputValue) {
36
57
  return { activeIndex: -1, shouldRestoreFocus: false };
@@ -60,7 +81,7 @@ function reconcileActiveIndex({ activeIndex, newState, oldState, requireSelectio
60
81
  };
61
82
  }
62
83
 
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}`;
84
+ 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
85
 
65
86
  const CoreSelector = class {
66
87
  constructor(hostRef) {
@@ -88,7 +109,7 @@ const CoreSelector = class {
88
109
  disabled: false,
89
110
  placeholder: 'Sök...',
90
111
  minLength: 1,
91
- maxResults: 10,
112
+ maxResults: 20,
92
113
  enableMultiple: false,
93
114
  showSearchIcon: true,
94
115
  requireSelection: true,
@@ -112,6 +133,7 @@ const CoreSelector = class {
112
133
  activeIndex = -1;
113
134
  isFocusedInternal = false;
114
135
  isNavigatingWithKeyboard = false;
136
+ isKeyboardNavigationActive = false;
115
137
  async setFocus() {
116
138
  if (this.inputRef) {
117
139
  this.inputRef.focus();
@@ -132,9 +154,10 @@ const CoreSelector = class {
132
154
  }
133
155
  if (!this.state)
134
156
  return;
135
- if (event.target.tagName === 'BUTTON')
157
+ if (event.target?.tagName === 'BUTTON')
136
158
  return;
137
159
  if (event.key !== 'ArrowUp' && event.key !== 'ArrowDown' && event.key !== 'Enter' && event.key !== 'Escape') {
160
+ this.isKeyboardNavigationActive = false;
138
161
  this.isNavigatingWithKeyboard = false;
139
162
  }
140
163
  if (this.state.status === 'itemSelected') {
@@ -152,11 +175,10 @@ const CoreSelector = class {
152
175
  case 'ArrowDown':
153
176
  if (totalOptions > 0) {
154
177
  event.preventDefault();
178
+ this.isKeyboardNavigationActive = true;
155
179
  this.isNavigatingWithKeyboard = true;
156
- if (this.activeIndex < totalOptions - 1) {
157
- this.activeIndex = this.activeIndex + 1;
158
- this.scrollToActive();
159
- }
180
+ this.activeIndex = getNextActiveIndex('down', this.activeIndex, totalOptions);
181
+ this.scrollToActive();
160
182
  if (this.activeIndex >= suggestions.length - 3) {
161
183
  this.csLoadMore.emit();
162
184
  }
@@ -168,15 +190,15 @@ const CoreSelector = class {
168
190
  case 'ArrowUp':
169
191
  if (totalOptions > 0) {
170
192
  event.preventDefault();
193
+ this.isKeyboardNavigationActive = true;
171
194
  this.isNavigatingWithKeyboard = true;
172
- if (this.activeIndex > 0) {
173
- this.activeIndex = this.activeIndex - 1;
195
+ this.activeIndex = getNextActiveIndex('up', this.activeIndex, totalOptions);
196
+ if (this.activeIndex >= 0) {
174
197
  this.scrollToActive();
175
198
  }
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();
199
+ else {
200
+ this.isKeyboardNavigationActive = false;
201
+ this.isNavigatingWithKeyboard = false;
180
202
  }
181
203
  }
182
204
  break;
@@ -309,14 +331,42 @@ const CoreSelector = class {
309
331
  this.csLoadMore.emit();
310
332
  }
311
333
  }
334
+ handleMouseMove = (event) => {
335
+ // Chrome fires a zero-movement mousemove when the list scrolls under a
336
+ // stationary pointer; only real pointer movement should end keyboard nav.
337
+ if (event.movementX === 0 && event.movementY === 0)
338
+ return;
339
+ if (this.isKeyboardNavigationActive) {
340
+ this.isKeyboardNavigationActive = false;
341
+ this.isNavigatingWithKeyboard = false;
342
+ }
343
+ };
344
+ handleMouseLeave = () => {
345
+ if (!this.isKeyboardNavigationActive) {
346
+ this.activeIndex = -1;
347
+ }
348
+ };
312
349
  scrollToActive() {
313
350
  if (!this.listRef || !this.state)
314
351
  return;
352
+ if (this.activeIndex === -1) {
353
+ this.listRef.scrollTop = 0;
354
+ return;
355
+ }
315
356
  const optionId = this.activeIndex === this.state.suggestions.length
316
357
  ? `${this.componentId}-list-option-manual-input`
317
358
  : `${this.componentId}-list-option-${this.activeIndex}`;
318
359
  const activeElement = this.listRef.querySelector(`#${optionId}`);
319
- activeElement?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
360
+ if (!activeElement)
361
+ return;
362
+ const containerRect = this.listRef.getBoundingClientRect();
363
+ const targetRect = activeElement.getBoundingClientRect();
364
+ if (targetRect.bottom > containerRect.bottom) {
365
+ this.listRef.scrollTop += (targetRect.bottom - containerRect.bottom);
366
+ }
367
+ else if (targetRect.top < containerRect.top) {
368
+ this.listRef.scrollTop -= (containerRect.top - targetRect.top);
369
+ }
320
370
  }
321
371
  handleManualSelect() {
322
372
  const item = { id: '', label: this.state.inputValue.trim(), metadata: { type: 'ManualInput' } };
@@ -330,7 +380,7 @@ const CoreSelector = class {
330
380
  if (!this.state)
331
381
  return null;
332
382
  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))));
383
+ 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
384
  }
335
385
  renderSearchContainer() {
336
386
  const isSelected = this.state.status === 'itemSelected';
@@ -377,12 +427,13 @@ const CoreSelector = class {
377
427
  'search-icon-container': true,
378
428
  'selector-search-icon': true,
379
429
  '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: {
430
+ } }), 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
431
  'selector-input-field': true,
382
432
  'visually-hidden-selected': isSelected
383
- }, ref: (el) => this.inputRef = el, id: `${this.componentId}-input`, type: "text", placeholder: this.config.placeholder, value: displayValue, onInput: (e) => {
433
+ }, ref: (el) => this.inputRef = el, id: `${this.componentId}-input`, type: "text", value: displayValue, maxLength: SELECTOR_INPUT_MAX_LENGTH, onInput: (e) => {
384
434
  if (this.config.disabled)
385
435
  return;
436
+ this.isKeyboardNavigationActive = false;
386
437
  this.isNavigatingWithKeyboard = false;
387
438
  this.csInput.emit(e.target.value);
388
439
  }, 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 +457,13 @@ const CoreSelector = class {
406
457
  }
407
458
  const listHeader = this.state.listHeader || this.config.listHeader;
408
459
  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: () => {
460
+ return (index.h("div", { class: "suggestions-box-container" }, index.h("div", { class: {
461
+ 'suggestions-box': true,
462
+ 'is-keyboard-nav': this.isNavigatingWithKeyboard
463
+ }, 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
464
  if (!this.config.disabled)
411
465
  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: {
466
+ } }, "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
467
  'suggestion-item': true,
414
468
  'active-suggestion': index$1 === this.activeIndex,
415
469
  'is-selected': !!item.isSelected,
@@ -433,12 +487,12 @@ const CoreSelector = class {
433
487
  this.historyRequestTimer = undefined;
434
488
  }, 50);
435
489
  }
436
- }, onMouseEnter: () => {
437
- if (this.config.disabled)
490
+ }, onMouseMove: this.handleMouseMove, onMouseEnter: () => {
491
+ if (this.config.disabled || this.isKeyboardNavigationActive)
438
492
  return;
493
+ this.isNavigatingWithKeyboard = false;
439
494
  if (!item.isSelected) {
440
495
  this.activeIndex = index$1;
441
- this.isNavigatingWithKeyboard = false;
442
496
  }
443
497
  } }, 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
498
  'match-highlight': !!segment.isMatch,
@@ -451,11 +505,11 @@ const CoreSelector = class {
451
505
  e.preventDefault();
452
506
  if (!this.config.disabled)
453
507
  this.handleManualSelect();
454
- }, onMouseEnter: () => {
455
- if (this.config.disabled)
508
+ }, onMouseMove: this.handleMouseMove, onMouseEnter: () => {
509
+ if (this.config.disabled || this.isKeyboardNavigationActive)
456
510
  return;
457
- this.activeIndex = this.state.suggestions.length;
458
511
  this.isNavigatingWithKeyboard = false;
512
+ this.activeIndex = this.state.suggestions.length;
459
513
  } }, index.h("span", null, "Anv\u00E4nd \"", index.h("strong", null, this.state.inputValue.trim()), "\"")))))));
460
514
  }
461
515
  static get delegatesFocus() { return true; }