@sb1/indeks-web 0.17.0 → 0.18.0

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.
@@ -80,6 +80,7 @@ export declare class IxCombobox extends HTMLElement {
80
80
  static get observedAttributes(): string[];
81
81
  connectedCallback(): void;
82
82
  disconnectedCallback(): void;
83
+ focus(options?: FocusOptions): void;
83
84
  attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
84
85
  get multiple(): boolean;
85
86
  set multiple(value: boolean);
@@ -0,0 +1,67 @@
1
+ /**
2
+ * IxDateField — datofelt: formatert tekst-input (dd.mm.åååå) + native OS-kalender.
3
+ *
4
+ * ## Designfilosofi
5
+ *
6
+ * Hybrid av to mønstre. `ix-date-field` ligger NØSTET inne i `ix-field` (som
7
+ * `ix-combobox`), og `ix-field` gjør ARIA-limet: kobler label↔input,
8
+ * aria-describedby, feilmelding, OG formateringen (`data-format="date"` →
9
+ * normaliserer til dd.mm.åååå på blur; brukeren kan taste `1.1.2026` like gjerne
10
+ * som `01.01.2026`). `ix-date-field` dupliserer ingenting av dette. Dens ENESTE
11
+ * jobb er å gjøre feltet til et datofelt:
12
+ *
13
+ * 1. GENERERE to instrumentelle elementer inn i `.ix-text-field` (idempotent):
14
+ * - `.ix-date-field__toggle` kalenderknapp (CSS gir ikonet)
15
+ * - `.ix-date-field__native` overlagt gjennomsiktig `<input type="date">`
16
+ * som bærer ISO-verdien, gir min/max-validering og åpner OS-kalenderen
17
+ * 2. To-veis synk mellom den synlige dd.mm.åååå-inputen og den native ISO-inputen.
18
+ * 3. Speile min/max/disabled/readonly ned til den native inputen.
19
+ * 4. Knapp-klikk → `native.showPicker?.()`; tap/klikk treffer uansett den
20
+ * gjennomsiktige native-inputen som ligger over knappen (mobil).
21
+ *
22
+ * ## Verdi-kontrakt
23
+ *
24
+ * Utad er verdien ISO (`åååå-mm-dd`): den native inputen bærer den, `change`
25
+ * emitter den, og `name` settes på den native inputen så form-innsending gir ISO.
26
+ * Den synlige inputen viser `dd.mm.åååå` og har bevisst INGEN `name` (ville
27
+ * kollidert med ix-field sin formaterings-speiling ved innsending).
28
+ *
29
+ * ## Delelementer (light DOM)
30
+ * - .ix-text-field > input → synlig dd.mm.åååå-input (forfatteren)
31
+ * - .ix-date-field__toggle → kalenderknapp (WC genererer)
32
+ * - .ix-date-field__native (input[date]) → skjult ISO-input (WC genererer)
33
+ *
34
+ * @example
35
+ * <ix-field>
36
+ * <label>Fødselsdato</label>
37
+ * <span data-field="description">dd.mm.åååå</span>
38
+ * <ix-date-field data-open-label="Åpne kalender" name="fodt">
39
+ * <div class="ix-text-field">
40
+ * <input inputmode="numeric" data-format="date" />
41
+ * </div>
42
+ * </ix-date-field>
43
+ * <span data-field="error"></span>
44
+ * </ix-field>
45
+ */
46
+ export declare class IxDateField extends HTMLElement {
47
+ private _input;
48
+ private _toggle;
49
+ private _native;
50
+ private _syncing;
51
+ private _lastEmitted;
52
+ private _onVisibleInput;
53
+ private _onNativeInput;
54
+ private _onToggleClick;
55
+ static get observedAttributes(): string[];
56
+ connectedCallback(): void;
57
+ disconnectedCallback(): void;
58
+ attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
59
+ private _wire;
60
+ private _handleVisibleInput;
61
+ private _handleNativeInput;
62
+ private _emitIfChanged;
63
+ private _seedFromIso;
64
+ private _openPicker;
65
+ private _syncControlState;
66
+ private _syncToggleLabel;
67
+ }
@@ -59,13 +59,18 @@ export interface FieldFormatter {
59
59
  /**
60
60
  * Lager en formatter fra en pattern-streng.
61
61
  *
62
- * `format` fyller slots med matchende tegn fra den rå verdien og setter inn
63
- * separatorer først når neste slot faktisk fylles (ingen dinglende separator på
64
- * slutten mens man skriver). Tegn som ikke passer neste slot — enten fordi
65
- * brukeren skrev flere tegn enn patternet har plasser, eller skrev noe som ikke
66
- * hører hjemme (bokstav i et sifferfelt) — droppes IKKE: den ledende delen som
67
- * passer formateres, og resten legges uformatert på til slutt i samme
68
- * rekkefølge brukeren skrev. Alt brukeren skriver forblir synlig.
62
+ * `format` fyller slots med matchende tegn fra den rå verdien og setter inn en
63
+ * separator så snart gruppen foran er fylt OG resten av verdien er konsumert —
64
+ * separatoren dukker altså opp med én gang gruppen er komplett ("24" → "24.",
65
+ * "2412" → "24.12."), ikke først når neste siffer skrives. En separator legges
66
+ * aldri til for en halvfylt gruppe, og heller ikke når vi stoppet fordi neste
67
+ * tegn ikke passet sloten (da ville vi doblet separatoren ved innliming av
68
+ * allerede formatert tekst). Tegn som ikke passer neste slot — enten fordi
69
+ * brukeren skrev flere tegn enn
70
+ * patternet har plasser, eller skrev noe som ikke hører hjemme (bokstav i et
71
+ * sifferfelt) — droppes IKKE: den ledende delen som passer formateres, og resten
72
+ * legges uformatert på til slutt i samme rekkefølge brukeren skrev. Alt brukeren
73
+ * skriver forblir synlig.
69
74
  *
70
75
  * `parse` er tapsfri: den fjerner kun separator-tegnene patternet definerer
71
76
  * (literal-tokens) og beholder alt annet i rekkefølge — ingen cap på antall
@@ -73,6 +78,42 @@ export interface FieldFormatter {
73
78
  * (bokstav i et sifferfelt) i den rå verdien og kan fanges av validering.
74
79
  */
75
80
  export declare function createPatternFormatter(pattern: string): FieldFormatter;
81
+ export interface DateParts {
82
+ day: string;
83
+ month: string;
84
+ year: string;
85
+ }
86
+ /**
87
+ * Kanonisk dato-parser — den ENE sannheten for hvordan en dato-streng tolkes.
88
+ * Både ix-field sin synlige formatering og IxDateField sin ISO-utleding går
89
+ * gjennom denne, så de aldri kan drifte fra hverandre.
90
+ *
91
+ * Komplett dato → nullutfylte deler; ufullstendig/tvetydig → `null`.
92
+ *
93
+ * - Med punktum: nøyaktig 3 rent-numeriske segmenter, dag/måned 1-2 sifre,
94
+ * år 2 eller 4 sifre. Dag/måned nullutfylles; 2-sifret år utvides til `20xx`
95
+ * (`"26"` → `"2026"`). `"1.1.2026"` og `"1.1.26"` → begge 01/01/2026.
96
+ * - Uten punktum: nøyaktig 8 sifre tolkes som ddmmåååå (`"01012026"`). Annen
97
+ * lengde uten skilletegn (f.eks. `"112026"`) er tvetydig — vi kan ikke vite
98
+ * hvor grensene går uten punktum — og regnes ufullstendig → `null`.
99
+ * - Bokstaver, ekstra punktum eller feil segmentantall → `null`.
100
+ */
101
+ export declare function parseDate(display: string): DateParts | null;
102
+ /** Komplett dato → visning `dd.mm.åååå` (nullutfylt); ellers strengen verbatim. */
103
+ export declare function normalizeDateDisplay(display: string): string;
104
+ /** Komplett dato → ISO `åååå-mm-dd`; ellers tom streng. */
105
+ export declare function isoFromDate(display: string): string;
106
+ /**
107
+ * Formatter for datofelt. `parse` er identitet — punktumet er en meningsfull
108
+ * tastet grense, ikke en separator å fjerne (trivielt tapsfri). `format`
109
+ * nullutfyller til `dd.mm.åååå` når datoen er komplett, ellers vises alt verbatim.
110
+ *
111
+ * Invariant-unntak: `parse(format(raw)) === raw` gjelder IKKE her, fordi
112
+ * nullutfylling (`"1"` → `"01"`) ikke er reversibel. Blur-syklusen krever i
113
+ * stedet at `format` er idempotent på allerede-normaliserte verdier —
114
+ * `format("01.01.2026") === "01.01.2026"` — som holder.
115
+ */
116
+ export declare function createDateFormatter(): FieldFormatter;
76
117
  /**
77
118
  * Beløp er ikke en fast-lengde pattern-maske: lengden varierer og tusenskillet
78
119
  * forskyver seg mens man skriver. Derfor en egen formatter.
@@ -99,3 +140,10 @@ export declare function amountFormatterForLocale(locale: string): FieldFormatter
99
140
  export declare function registerFormat(name: string, formatter: FieldFormatter): void;
100
141
  /** Slår opp en registrert formatter. Returnerer `undefined` om navnet er ukjent. */
101
142
  export declare function resolveFormat(name: string): FieldFormatter | undefined;
143
+ /**
144
+ * Navnene på de innebygde formatvariantene. Eksporteres slik at typelaget
145
+ * (indeks-react dupliserer denne listen for autocomplete på `format`) kan holdes
146
+ * i synk via en sync-test — React importerer ikke web-runtime ellers.
147
+ */
148
+ export declare const BUILTIN_FORMAT_NAMES: readonly ["phone", "amount", "account", "orgnr", "ssn", "date"];
149
+ export type BuiltInFormatName = (typeof BUILTIN_FORMAT_NAMES)[number];
@@ -0,0 +1,33 @@
1
+ export declare class IxPhoneNumberField extends HTMLElement {
2
+ private _errorObserver;
3
+ private _childObserver;
4
+ private _instanceId;
5
+ private _filling;
6
+ private _ownDisabled;
7
+ private _ownReadonly;
8
+ private _ownRequired;
9
+ static get observedAttributes(): string[];
10
+ connectedCallback(): void;
11
+ disconnectedCallback(): void;
12
+ attributeChangedCallback(attr: string, _oldValue: string | null, _newValue: string | null): void;
13
+ private _wire;
14
+ private _wireDescribedBy;
15
+ private _containsControl;
16
+ private _containsGroupField;
17
+ private _combobox;
18
+ private _numberInput;
19
+ private _syncInvalid;
20
+ private _syncDataState;
21
+ private _syncHostStateToControls;
22
+ private _syncRequired;
23
+ private _applyState;
24
+ private _applyFlag;
25
+ private _fillCombobox;
26
+ private _refillCombobox;
27
+ private _applyPreselection;
28
+ private _buildOption;
29
+ private _preselectValue;
30
+ private _resolveCountryOptions;
31
+ private _listbox;
32
+ private _stampNumberDefaults;
33
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Landvalg for <ix-phone-number-field>. `value` er landkoden (uten `+`) og
3
+ * brukes som verdi/`data-country-code`. `label` er kalle-koden (`+47`) — den
4
+ * vises som valgt verdi i input og er primærtekst. `description` er landnavnet
5
+ * (sekundær tekst i lista, som skjermleseren leser etter kallekoden).
6
+ */
7
+ export type CountryOption = {
8
+ /** Landkode uten `+` (option-value, f.eks. `"47"`). */
9
+ value: string;
10
+ /** Kalle-kode vist som primærtekst (`"+47"`). */
11
+ label: string;
12
+ /** Landnavn — sekundær beskrivelse i lista. */
13
+ description?: string;
14
+ };
15
+ /** Språk for den innebygde landlista. */
16
+ export type CountryLocale = 'nb' | 'nn' | 'en';
17
+ /**
18
+ * Bygger standard landliste for en gitt `locale`. Rekkefølge: Norge først,
19
+ * deretter Norden (Sverige, Danmark, Finland, Island), deretter resten
20
+ * alfabetisk etter lokalisert landnavn (locale-bevisst `Intl.Collator`, som
21
+ * håndterer æ/ø/å).
22
+ *
23
+ * @default locale = 'nb'
24
+ */
25
+ export declare function getDefaultCountries(locale?: CountryLocale): CountryOption[];
26
+ /** Normaliserer en `data-locale`-attributt til en gyldig `CountryLocale`. */
27
+ export declare function normalizeLocale(value: string | null): CountryLocale;
@@ -23,6 +23,7 @@
23
23
  * og verdien bakes inn i `aria-label` (samme mønster som u-elements sin
24
24
  * u-progress). Desktop beholder ekte progressbar-semantikk.
25
25
  */
26
+ export type ProgressBarState = 'active' | 'success' | 'error';
26
27
  export declare class IxProgressBar extends HTMLElement {
27
28
  private _instanceId;
28
29
  private _header;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `cn` — slår sammen betingede CSS-klassenavn til én streng.
3
+ *
4
+ * Intern erstatning for `clsx`. Vi implementerer bare mønstrene Indeks faktisk
5
+ * bruker, ikke hele clsx-API-et:
6
+ * - strenger som varargs: cn('ix-a', 'ix-b') → 'ix-a ix-b'
7
+ * - falsy filtreres bort: cn('ix-a', false, undefined) → 'ix-a'
8
+ * (typisk fra `&&`-uttrykk og valgfrie props)
9
+ * - objekt med truthy-verdi: cn({ 'ix-a': true, 'ix-b': 0 }) → 'ix-a'
10
+ * (inkl. computed/template-literal-nøkler)
11
+ * - flate (og nøstede) arrays: cn('ix-a', ['ix-b']) → 'ix-a ix-b'
12
+ *
13
+ * Returnerer alltid en `string` — tom streng når ingenting matcher, slik at
14
+ * mønsteret `cn(className) || undefined` fungerer.
15
+ */
16
+ export interface ClassDictionary {
17
+ [key: string]: unknown;
18
+ }
19
+ export type ClassValue = string | number | boolean | null | undefined | ClassDictionary | ClassValue[];
20
+ export declare function cn(...inputs: ClassValue[]): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sb1/indeks-web",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "type": "module",
5
5
  "description": "Web components for Indeks design system",
6
6
  "homepage": "https://design.sparebank1.no",