@oslokommune/punkt-react 17.1.3 → 18.0.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.
Files changed (77) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/components/backlink/BackLink.d.ts +3 -0
  3. package/dist/components/breadcrumbs/Breadcrumbs.d.ts +3 -0
  4. package/dist/components/calendar/types.d.ts +14 -12
  5. package/dist/components/checkbox/Checkbox.d.ts +5 -0
  6. package/dist/components/combobox/types.d.ts +5 -0
  7. package/dist/components/consent/strings.d.ts +1 -85
  8. package/dist/components/datepicker/DateTags.d.ts +2 -2
  9. package/dist/components/datepicker/types.d.ts +6 -3
  10. package/dist/components/fileupload/DropZone.d.ts +3 -0
  11. package/dist/components/fileupload/FileUpload.d.ts +3 -0
  12. package/dist/components/header/types.d.ts +5 -0
  13. package/dist/components/index.d.ts +4 -0
  14. package/dist/components/inputwrapper/InputWrapper.d.ts +6 -0
  15. package/dist/components/radio/RadioButton.d.ts +5 -0
  16. package/dist/components/searchinput/SearchInput.d.ts +4 -0
  17. package/dist/components/select/Select.d.ts +3 -0
  18. package/dist/components/strings/PktStringsProvider.d.ts +21 -0
  19. package/dist/components/strings/strings-override.test.d.ts +1 -0
  20. package/dist/components/tag/Tag.d.ts +3 -0
  21. package/dist/components/textarea/Textarea.d.ts +3 -0
  22. package/dist/components/textinput/Textinput.d.ts +3 -0
  23. package/dist/components/timepicker/types.d.ts +3 -2
  24. package/dist/components/timepicker/useTimepickerState.d.ts +9 -1
  25. package/dist/punkt-react.cjs +1 -1
  26. package/dist/punkt-react.js +2969 -2749
  27. package/dist/shared-strings/consent.d.ts +71 -0
  28. package/dist/shared-strings/format.d.ts +21 -0
  29. package/dist/shared-strings/index.d.ts +14 -0
  30. package/dist/shared-strings/nb.d.ts +118 -0
  31. package/dist/shared-strings/resolve.d.ts +12 -0
  32. package/dist/shared-strings/store.d.ts +27 -0
  33. package/dist/shared-strings/types.d.ts +29 -0
  34. package/dist/shared-types/fileupload.d.ts +0 -27
  35. package/dist/shared-types/index.d.ts +1 -2
  36. package/dist/shared-utils/combobox/index.d.ts +1 -0
  37. package/dist/shared-utils/combobox/input-utils.d.ts +2 -1
  38. package/dist/shared-utils/combobox/messages.d.ts +7 -0
  39. package/dist/shared-utils/combobox/option-utils.d.ts +2 -1
  40. package/dist/shared-utils/combobox/selection-manager.d.ts +3 -2
  41. package/package.json +4 -4
  42. package/src/components/backlink/BackLink.tsx +11 -2
  43. package/src/components/breadcrumbs/Breadcrumbs.tsx +8 -2
  44. package/src/components/calendar/Calendar.core.test.tsx +7 -5
  45. package/src/components/calendar/types.ts +14 -34
  46. package/src/components/calendar/useCalendarState.ts +16 -2
  47. package/src/components/checkbox/Checkbox.tsx +20 -4
  48. package/src/components/combobox/Combobox.tsx +1 -0
  49. package/src/components/combobox/Listbox.tsx +4 -2
  50. package/src/components/combobox/types.ts +6 -0
  51. package/src/components/combobox/useComboboxState.ts +15 -8
  52. package/src/components/consent/strings.ts +1 -125
  53. package/src/components/datepicker/DateTags.tsx +4 -3
  54. package/src/components/datepicker/Datepicker.accessibility.test.tsx +2 -2
  55. package/src/components/datepicker/Datepicker.tsx +1 -0
  56. package/src/components/datepicker/DatepickerInputs.tsx +6 -6
  57. package/src/components/datepicker/types.ts +6 -3
  58. package/src/components/datepicker/useDatepickerState.ts +4 -5
  59. package/src/components/fileupload/DropZone.tsx +20 -15
  60. package/src/components/fileupload/FileUpload.test.tsx +37 -0
  61. package/src/components/fileupload/FileUpload.tsx +41 -8
  62. package/src/components/header/HeaderGlobal.tsx +5 -2
  63. package/src/components/header/HeaderService.tsx +12 -7
  64. package/src/components/header/types.ts +6 -0
  65. package/src/components/index.ts +10 -0
  66. package/src/components/inputwrapper/InputWrapper.tsx +28 -6
  67. package/src/components/radio/RadioButton.tsx +18 -2
  68. package/src/components/searchinput/SearchInput.tsx +13 -3
  69. package/src/components/select/Select.tsx +5 -0
  70. package/src/components/strings/PktStringsProvider.tsx +38 -0
  71. package/src/components/strings/strings-override.test.tsx +130 -0
  72. package/src/components/tag/Tag.tsx +13 -2
  73. package/src/components/textarea/Textarea.tsx +5 -0
  74. package/src/components/textinput/Textinput.tsx +5 -0
  75. package/src/components/timepicker/Timepicker.tsx +1 -0
  76. package/src/components/timepicker/types.ts +3 -2
  77. package/src/components/timepicker/useTimepickerState.ts +20 -22
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Tekster og informasjonskapsel-oppsett for samtykkedialogen.
3
+ *
4
+ * Denne ligger utenfor `nb.ts` fordi formen er en annen: en liste med
5
+ * informasjonskapsler som hver har egne tekster per språk, ikke et flatt
6
+ * namespace. Den deles av Elements og React slik at de to ikke kommer i utakt.
7
+ */
8
+ export declare const consentStrings: {
9
+ i18n: {
10
+ nb: {
11
+ contentPresentation: {
12
+ title: string;
13
+ description: string[];
14
+ buttons: {
15
+ accept: string;
16
+ reject: string;
17
+ settings: string;
18
+ };
19
+ };
20
+ contentSettings: {
21
+ title: string;
22
+ description: string[];
23
+ buttons: {
24
+ back: string;
25
+ save: string;
26
+ };
27
+ };
28
+ };
29
+ en: {
30
+ contentPresentation: {
31
+ title: string;
32
+ description: string[];
33
+ buttons: {
34
+ accept: string;
35
+ reject: string;
36
+ settings: string;
37
+ };
38
+ };
39
+ contentSettings: {
40
+ title: string;
41
+ description: string[];
42
+ buttons: {
43
+ back: string;
44
+ save: string;
45
+ };
46
+ };
47
+ };
48
+ };
49
+ cookies: {
50
+ name: string;
51
+ defaultValue: boolean;
52
+ i18n: {
53
+ nb: {
54
+ title: string;
55
+ description: string;
56
+ buttons: {
57
+ yes: string;
58
+ no: string;
59
+ };
60
+ };
61
+ en: {
62
+ title: string;
63
+ description: string;
64
+ buttons: {
65
+ yes: string;
66
+ no: string;
67
+ };
68
+ };
69
+ };
70
+ }[];
71
+ };
@@ -0,0 +1,21 @@
1
+ import type { TPktStringParams } from './types';
2
+ /**
3
+ * Setter verdier inn i `{navn}`-plassholdere.
4
+ *
5
+ * ```ts
6
+ * formatString('Verdien må være større enn eller lik {min}.', { min: 5 })
7
+ * // → 'Verdien må være større enn eller lik 5.'
8
+ * ```
9
+ *
10
+ * En plassholder uten tilsvarende verdi blir stående urørt, slik at en ufullstendig
11
+ * overstyring gir synlig, feilsøkbar tekst i stedet for et tomt felt.
12
+ */
13
+ export declare function formatString(template: string, params?: TPktStringParams): string;
14
+ /**
15
+ * Velger entalls- eller flertallsform.
16
+ *
17
+ * ```ts
18
+ * plural(count, s.fileLabelOne, s.fileLabelOther)
19
+ * ```
20
+ */
21
+ export declare function plural(count: number, one: string, other: string): string;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Delt tekstkatalog for Punkt.
3
+ *
4
+ * Alle UI-tekster i designsystemet defineres i `nb.ts` og brukes derfra av både
5
+ * `@oslokommune/punkt-elements` og `@oslokommune/punkt-react`. Konsumenter kan
6
+ * overstyre tekster globalt med `setPktStrings()` eller per komponentinstans via
7
+ * `strings`-propen.
8
+ */
9
+ export { nb } from './nb';
10
+ export { formatString, plural } from './format';
11
+ export { getPktStrings, resetPktStrings, setPktStrings, subscribePktStrings } from './store';
12
+ export { resolveNamespace, resolveStrings } from './resolve';
13
+ export type { TPktStringParams, TPktStrings, TPktStringsNamespace, TPktStringsOverride, TPktStringsShape, TPktStringValue, } from './types';
14
+ export { consentStrings } from './consent';
@@ -0,0 +1,118 @@
1
+ export declare const nb: {
2
+ /** Tekster som går igjen på tvers av flere komponenter. */
3
+ generic: {
4
+ from: string;
5
+ to: string;
6
+ close: string;
7
+ };
8
+ /** Etiketter og hjelpetekst rundt skjemafelt. */
9
+ forms: {
10
+ optional: string;
11
+ required: string;
12
+ readMore: string;
13
+ };
14
+ /** Valideringsmeldinger. Nøkkelnavnene følger `ValidityState` der det finnes et tilsvarende flagg. */
15
+ validation: {
16
+ valueMissing: string;
17
+ typeMismatch: string;
18
+ patternMismatch: string;
19
+ tooShort: string;
20
+ tooLong: string;
21
+ rangeUnderflow: string;
22
+ rangeOverflow: string;
23
+ rangeUnderflowMin: string;
24
+ rangeOverflowMax: string;
25
+ stepMismatch: string;
26
+ timeStepMismatch: string;
27
+ timeStepMismatchHour: string;
28
+ timeStepMismatchHalfHour: string;
29
+ dateUnderflow: string;
30
+ dateOverflow: string;
31
+ counterExceeded: string;
32
+ };
33
+ /** Måneds- og dagsnavn. Listene må ha henholdsvis 12 og 7 elementer. */
34
+ dates: {
35
+ month: string;
36
+ year: string;
37
+ week: string;
38
+ days: string[];
39
+ daysShort: string[];
40
+ months: string[];
41
+ monthsShort: string[];
42
+ };
43
+ calendar: {
44
+ prevMonth: string;
45
+ nextMonth: string;
46
+ };
47
+ datepicker: {
48
+ openPicker: string;
49
+ deleteDate: string;
50
+ };
51
+ timepicker: {
52
+ hours: string;
53
+ minutes: string;
54
+ openPicker: string;
55
+ prevTime: string;
56
+ nextTime: string;
57
+ selectTime: string;
58
+ };
59
+ searchinput: {
60
+ placeholder: string;
61
+ submit: string;
62
+ };
63
+ backlink: {
64
+ label: string;
65
+ };
66
+ breadcrumbs: {
67
+ ariaLabel: string;
68
+ };
69
+ tag: {
70
+ remove: string;
71
+ };
72
+ header: {
73
+ search: string;
74
+ menu: string;
75
+ openMenu: string;
76
+ openSearch: string;
77
+ };
78
+ listbox: {
79
+ searchLabel: string;
80
+ searchPlaceholder: string;
81
+ };
82
+ combobox: {
83
+ noResults: string;
84
+ maxSelected: string;
85
+ tooManySelected: string;
86
+ alreadySelected: string;
87
+ valueAdded: string;
88
+ noValidValue: string;
89
+ };
90
+ fileupload: {
91
+ dropZoneDragMultiple: string;
92
+ dropZoneDragSingle: string;
93
+ dropZoneDragMultipleThumbnail: string;
94
+ dropZoneDragSingleThumbnail: string;
95
+ dropZoneDragActiveMultiple: string;
96
+ dropZoneDragActiveSingle: string;
97
+ dropZoneDragActiveMultipleThumbnail: string;
98
+ dropZoneDragActiveSingleThumbnail: string;
99
+ dropZoneOpenFileDialogMultiple: string;
100
+ dropZoneOpenFileDialogSingle: string;
101
+ dropZoneOpenFileDialogMultipleThumbnail: string;
102
+ dropZoneOpenFileDialogSingleThumbnail: string;
103
+ supportedFormatsPrefix: string;
104
+ invalidFormat: string;
105
+ sizeTooLarge: string;
106
+ requiredMissing: string;
107
+ genericValidationRejection: string;
108
+ unknownFilename: string;
109
+ previewFallbackName: string;
110
+ previewImage: string;
111
+ fileLabelOne: string;
112
+ fileLabelOther: string;
113
+ srFileAdded: string;
114
+ srFilesAdded: string;
115
+ srFilesUploadedOfTotal: string;
116
+ srFilesFailedOfTotal: string;
117
+ };
118
+ };
@@ -0,0 +1,12 @@
1
+ import type { TPktStrings, TPktStringsNamespace, TPktStringsOverride } from './types';
2
+ /** Slår opp ett namespace. */
3
+ export declare function resolveNamespace<K extends TPktStringsNamespace>(ns: K, ...layers: Array<TPktStringsOverride | undefined>): TPktStrings[K];
4
+ /**
5
+ * Slår opp flere namespace på én gang.
6
+ *
7
+ * ```ts
8
+ * const s = resolveStrings(['forms', 'validation'], this.strings)
9
+ * s.forms.optional
10
+ * ```
11
+ */
12
+ export declare function resolveStrings<NS extends TPktStringsNamespace>(namespaces: readonly NS[], ...layers: Array<TPktStringsOverride | undefined>): Pick<TPktStrings, NS>;
@@ -0,0 +1,27 @@
1
+ import type { TPktStringsOverride } from './types';
2
+ /**
3
+ * Global tekstoverstyring. Tilstanden ligger på `globalThis` bak en
4
+ * `Symbol.for()`-nøkkel, slik at `punkt-react` og `punkt-elements` deler én og
5
+ * samme store på tvers av modulgrafer.
6
+ */
7
+ type TListener = () => void;
8
+ /**
9
+ * Overstyrer tekster for hele applikasjonen. Kall det én gang ved oppstart.
10
+ * Flere kall merges sammen, namespace for namespace.
11
+ *
12
+ * ```ts
13
+ * setPktStrings({ forms: { optional: 'Frivillig' } })
14
+ * ```
15
+ */
16
+ export declare function setPktStrings(overrides: TPktStringsOverride): void;
17
+ /**
18
+ * Gjeldende globale overstyringer. Identiteten endrer seg ved hvert
19
+ * `setPktStrings()`-kall, så den kan brukes direkte som snapshot i
20
+ * `useSyncExternalStore`.
21
+ */
22
+ export declare function getPktStrings(): TPktStringsOverride;
23
+ /** Nullstiller til de innebygde tekstene. Ment for tester. */
24
+ export declare function resetPktStrings(): void;
25
+ /** Abonnerer på endringer. Returnerer en funksjon som melder av. */
26
+ export declare function subscribePktStrings(listener: TListener): () => void;
27
+ export {};
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Typene for tekstkatalogen. Katalogen er nøyaktig to nivåer dyp:
3
+ * namespace → nøkkel → string | string[].
4
+ */
5
+ import type { nb } from './nb';
6
+ /** En enkelt tekstverdi. Lister brukes for måneds- og dagsnavn. */
7
+ export type TPktStringValue = string | readonly string[];
8
+ /** Formen alle språkbundler må følge. */
9
+ export type TPktStringsShape = Record<string, Record<string, TPktStringValue>>;
10
+ /**
11
+ * Hele katalogen, utledet fra bokmålsbundelen slik at `nb.ts` er det eneste
12
+ * stedet en nøkkel defineres.
13
+ */
14
+ export type TPktStrings = typeof nb;
15
+ /** Navnet på et namespace i katalogen, f.eks. `'forms'` eller `'searchinput'`. */
16
+ export type TPktStringsNamespace = keyof TPktStrings;
17
+ /**
18
+ * Delvis overstyring av katalogen. Generisk over namespace slik at en komponent
19
+ * kan smalne typen til de namespacene den faktisk bruker:
20
+ *
21
+ * ```ts
22
+ * strings?: TPktStringsOverride<'forms' | 'validation' | 'searchinput'>
23
+ * ```
24
+ */
25
+ export type TPktStringsOverride<NS extends TPktStringsNamespace = TPktStringsNamespace> = {
26
+ [K in NS]?: Partial<TPktStrings[K]>;
27
+ };
28
+ /** Verdier som kan settes inn i en `{plassholder}`. */
29
+ export type TPktStringParams = Record<string, string | number>;
@@ -44,30 +44,3 @@ export interface IFilesChangedDetail {
44
44
  reason: TFilesChangedReason;
45
45
  changedFileIds?: string[];
46
46
  }
47
- /** Default Norwegian Bokmål strings used by both implementations. */
48
- export interface IFileUploadStrings {
49
- dropZoneDragMultiple: string;
50
- dropZoneDragSingle: string;
51
- dropZoneDragMultipleThumbnail: string;
52
- dropZoneDragSingleThumbnail: string;
53
- dropZoneDragActiveMultiple: string;
54
- dropZoneDragActiveSingle: string;
55
- dropZoneDragActiveMultipleThumbnail: string;
56
- dropZoneDragActiveSingleThumbnail: string;
57
- dropZoneOpenFileDialogMultiple: string;
58
- dropZoneOpenFileDialogSingle: string;
59
- dropZoneOpenFileDialogMultipleThumbnail: string;
60
- dropZoneOpenFileDialogSingleThumbnail: string;
61
- supportedFormatsPrefix: string;
62
- invalidFormatDefault: (formats: string) => string;
63
- sizeTooLargeDefault: (maxSize: string) => string;
64
- requiredMissing: string;
65
- genericValidationRejection: string;
66
- unknownFilename: string;
67
- fileLabel: (count: number) => string;
68
- srFileAdded: (filename: string) => string;
69
- srFilesAdded: (count: number) => string;
70
- srFilesUploadedOfTotal: (uploaded: number, total: number, label: string) => string;
71
- srFilesFailedOfTotal: (failed: number, total: number, label: string) => string;
72
- }
73
- export declare const defaultFileUploadStrings: IFileUploadStrings;
@@ -21,5 +21,4 @@ export type { TProgressbarRole, TProgressbarSkin, TProgressbarStatusPlacement, T
21
21
  export type { IPktComboboxOption, TPktComboboxTagSkin, TPktComboboxDisplayValue, TPktComboboxTagPlacement, } from './combobox';
22
22
  export type { IPktSelectOption, TSelectOption } from './select';
23
23
  export type { TPktSearchInputAppearance, TPktSearchInputMethod, IPktSearchInputSuggestion, IPktSearchInput, } from './searchinput';
24
- export type { TUploadStrategy as TFileUploadStrategy, TFileUploadItemRenderer, TFilesChangedReason, TFileValidator, TTransferProgress, IFileItem, IFileTransfer, IFileValidateDetail, ITransferCancelledDetail, IFilesChangedDetail, IFileUploadStrings, } from './fileupload';
25
- export { defaultFileUploadStrings } from './fileupload';
24
+ export type { TUploadStrategy as TFileUploadStrategy, TFileUploadItemRenderer, TFilesChangedReason, TFileValidator, TTransferProgress, IFileItem, IFileTransfer, IFileValidateDetail, ITransferCancelledDetail, IFilesChangedDetail, } from './fileupload';
@@ -8,3 +8,4 @@ export { isLetterOrSpace, createTypeaheadHandler, findTypeaheadOptionMatch } fro
8
8
  export { getInputKeyAction, isArrowToggleKey, getInputValueAction, checkForMatches, getSingleValueForInput, } from './input-utils';
9
9
  export type { TInputKeyAction, TFocusOutAction, IFocusOutResult, ICheckForMatchesResult, } from './input-utils';
10
10
  export { focusAndScrollIntoView, getOptionElements, focusNextOption, focusPreviousOption, focusFirstOption, focusLastOption, focusFirstOrSelectedOption, } from './keyboard-navigation';
11
+ export type { TComboboxMessageKey } from './messages';
@@ -1,3 +1,4 @@
1
+ import type { TComboboxMessageKey } from './messages';
1
2
  /**
2
3
  * Shared combobox input utility functions used by both Elements and React packages.
3
4
  * Covers keyboard actions, focus-out validation, match checking, and input display.
@@ -23,7 +24,7 @@ export interface IFocusOutResult {
23
24
  export declare const getInputValueAction: (inputValue: string, currentValues: string[], options: IPktComboboxOption[], allowUserInput: boolean, multiple: boolean) => IFocusOutResult;
24
25
  export interface ICheckForMatchesResult {
25
26
  addValueText: string | null;
26
- userInfoMessage: string;
27
+ userInfoMessage: TComboboxMessageKey;
27
28
  shouldRemoveValue: boolean;
28
29
  shouldResetInput: boolean;
29
30
  }
@@ -0,0 +1,7 @@
1
+ import type { TPktStrings } from '../../shared-strings';
2
+ /**
3
+ * Nøkkelen til en statusmelding i comboboxen, eller tom streng når det ikke er
4
+ * noe å melde. Utvalgslogikken her returnerer nøkler i stedet for ferdig tekst,
5
+ * slik at Elements og React kan slå opp teksten i sin egen tekstkatalog.
6
+ */
7
+ export type TComboboxMessageKey = keyof TPktStrings['combobox'] | '';
@@ -1,3 +1,4 @@
1
+ import type { TComboboxMessageKey } from './messages';
1
2
  /**
2
3
  * Shared combobox option utility functions used by both Elements and React packages.
3
4
  * Only framework-agnostic functions belong here.
@@ -46,5 +47,5 @@ export declare const findTypeaheadMatches: (options: IPktComboboxOption[], searc
46
47
  */
47
48
  export declare const getSearchInfoMessage: (searchValue: string, selectedValues: string[], options: IPktComboboxOption[], allowUserInput: boolean) => {
48
49
  addValueText: string | null;
49
- userInfoMessage: string;
50
+ userInfoMessage: TComboboxMessageKey;
50
51
  };
@@ -1,3 +1,4 @@
1
+ import type { TComboboxMessageKey } from './messages';
1
2
  /**
2
3
  * Shared combobox selection management functions used by both Elements and React packages.
3
4
  * Only framework-agnostic functions belong here.
@@ -20,7 +21,7 @@ export interface IToggleSelectionResult {
20
21
  options: IPktComboboxOption[];
21
22
  shouldOptionsBeOpen: boolean;
22
23
  shouldResetInput: boolean;
23
- userInfoMessage: string;
24
+ userInfoMessage: TComboboxMessageKey;
24
25
  searchValue: string;
25
26
  newUserOption: IPktComboboxOption | null;
26
27
  }
@@ -47,7 +48,7 @@ export declare const deselectOption: (value: string | null, currentValues: strin
47
48
  export declare const selectAllOptions: (options: IPktComboboxOption[], maxlength: number | null) => {
48
49
  values: string[];
49
50
  options: IPktComboboxOption[];
50
- userInfoMessage: string;
51
+ userInfoMessage: TComboboxMessageKey;
51
52
  };
52
53
  /**
53
54
  * Clears all selections.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslokommune/punkt-react",
3
- "version": "17.1.3",
3
+ "version": "18.0.0",
4
4
  "description": "React komponentbibliotek til Punkt, et designsystem laget av Oslo Origo",
5
5
  "homepage": "https://punkt.oslo.kommune.no",
6
6
  "author": "Team Designsystem, Oslo Origo",
@@ -44,8 +44,8 @@
44
44
  "@eslint/compat": "^2.1.0",
45
45
  "@eslint/eslintrc": "^3.3.5",
46
46
  "@eslint/js": "^10.0.1",
47
- "@oslokommune/punkt-assets": "^17.1.2",
48
- "@oslokommune/punkt-css": "^17.1.3",
47
+ "@oslokommune/punkt-assets": "^18.0.0",
48
+ "@oslokommune/punkt-css": "^18.0.0",
49
49
  "@testing-library/jest-dom": "^6.9.1",
50
50
  "@testing-library/react": "^16.3.2",
51
51
  "@testing-library/user-event": "^14.6.1",
@@ -102,5 +102,5 @@
102
102
  "url": "https://github.com/oslokommune/punkt/issues"
103
103
  },
104
104
  "license": "MIT",
105
- "gitHead": "f378c0e71d923d9526bc9eea3a399e0d9e00b206"
105
+ "gitHead": "057d0045ccd1af4d0f6591f0e2b0e5ab6fda3843"
106
106
  }
@@ -3,8 +3,13 @@
3
3
  import { AnchorHTMLAttributes, forwardRef, ReactNode, Ref } from 'react'
4
4
 
5
5
  import { PktIcon } from '../icon/Icon'
6
+ import { usePktStrings } from '../../hooks/usePktStrings'
7
+ import type { TPktStringsOverride } from 'shared-strings'
6
8
 
7
9
  export interface IPktBackLink extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {
10
+ /** Overstyrer tekster for denne komponenten. */
11
+ strings?: TPktStringsOverride
12
+
8
13
  href?: string
9
14
  text?: string
10
15
  ariaLabel?: string
@@ -18,7 +23,10 @@ export interface IPktBackLink extends Omit<AnchorHTMLAttributes<HTMLAnchorElemen
18
23
  }
19
24
 
20
25
  export const PktBackLink = forwardRef<HTMLElement, IPktBackLink>(
21
- ({ href = '/', text = 'Forsiden', ariaLabel, renderLink, className, ...props }, ref) => {
26
+ (
27
+ { href = '/', text = 'Forsiden', ariaLabel, renderLink, className, strings, ...props },
28
+ ref,
29
+ ) => {
22
30
  const linkChildren = (
23
31
  <>
24
32
  <PktIcon className="pkt-back-link__icon pkt-icon pkt-link__icon" name="chevron-thin-left" aria-hidden="true" />
@@ -34,10 +42,11 @@ export const PktBackLink = forwardRef<HTMLElement, IPktBackLink>(
34
42
  </a>
35
43
  ))
36
44
 
45
+ const s = usePktStrings(['backlink'], strings)
37
46
  const classes = ['pkt-back-link', className].filter(Boolean).join(' ')
38
47
 
39
48
  return (
40
- <nav className={classes} aria-label={ariaLabel || 'Gå tilbake til forrige side'} ref={ref}>
49
+ <nav className={classes} aria-label={ariaLabel || s.backlink.label} ref={ref}>
41
50
  {linkRenderer({
42
51
  href,
43
52
  className: 'pkt-link pkt-link--icon-left',
@@ -4,6 +4,8 @@ import { ForwardedRef, forwardRef, type AnchorHTMLAttributes, type ReactNode } f
4
4
  import { Link } from 'react-router-dom'
5
5
 
6
6
  import { PktIcon } from '../icon/Icon'
7
+ import { usePktStrings } from '../../hooks/usePktStrings'
8
+ import type { TPktStringsOverride } from 'shared-strings'
7
9
 
8
10
  export interface IBreadcrumbs {
9
11
  text: string
@@ -11,6 +13,9 @@ export interface IBreadcrumbs {
11
13
  }
12
14
 
13
15
  export interface IPktBreadcrumbs extends AnchorHTMLAttributes<HTMLAnchorElement> {
16
+ /** Overstyrer tekster for denne komponenten. */
17
+ strings?: TPktStringsOverride
18
+
14
19
  breadcrumbs: IBreadcrumbs[]
15
20
  navigationType?: 'router' | 'anchor'
16
21
  renderLink?: (args: {
@@ -23,7 +28,7 @@ export interface IPktBreadcrumbs extends AnchorHTMLAttributes<HTMLAnchorElement>
23
28
 
24
29
  export const PktBreadcrumbs = forwardRef(
25
30
  (
26
- { breadcrumbs, navigationType, renderLink, className, ...props }: IPktBreadcrumbs,
31
+ { breadcrumbs, navigationType, renderLink, className, strings, ...props }: IPktBreadcrumbs,
27
32
  ref: ForwardedRef<HTMLAnchorElement>,
28
33
  ) => {
29
34
  const slicedBreadcrumbs = breadcrumbs
@@ -31,6 +36,7 @@ export const PktBreadcrumbs = forwardRef(
31
36
  const backLink = slicedBreadcrumbs[slicedBreadcrumbs.length - 2]
32
37
 
33
38
  // Define the classes
39
+ const s = usePktStrings(['breadcrumbs'], strings)
34
40
  const classes = [className, 'pkt-breadcrumbs'].filter(Boolean).join(' ')
35
41
 
36
42
  // Create a default renderLink implementation based on navigationType
@@ -50,7 +56,7 @@ export const PktBreadcrumbs = forwardRef(
50
56
 
51
57
  // Mobile and desktop have different markup
52
58
  return (
53
- <nav ref={ref} aria-label="brødsmulemeny" className={classes}>
59
+ <nav ref={ref} aria-label={s.breadcrumbs.ariaLabel} className={classes}>
54
60
  <ol className="pkt-breadcrumbs__list pkt-breadcrumbs--desktop">
55
61
  {slicedBreadcrumbs.map((item, index) => (
56
62
  <li key={`breadcrumb-${index}`} className="pkt-breadcrumbs__item">
@@ -223,7 +223,7 @@ describe('PktCalendar', () => {
223
223
 
224
224
  test('handles custom day strings', () => {
225
225
  const { container } = createCalendar({
226
- strings: { daysShort: ['S', 'M', 'T', 'W', 'T', 'F', 'S'] },
226
+ strings: { dates: { daysShort: ['S', 'M', 'T', 'W', 'T', 'F', 'S'] } },
227
227
  })
228
228
 
229
229
  const dayHeaders = container.querySelectorAll('.pkt-calendar__day-name')
@@ -235,10 +235,12 @@ describe('PktCalendar', () => {
235
235
  const { container } = createCalendar({
236
236
  withcontrols: true,
237
237
  strings: {
238
- months: [
239
- 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
240
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
241
- ],
238
+ dates: {
239
+ months: [
240
+ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
241
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
242
+ ],
243
+ },
242
244
  },
243
245
  })
244
246
 
@@ -1,38 +1,17 @@
1
1
  import type { IDateConstraints, TDateRangeMap } from 'shared-types/calendar'
2
2
 
3
- export const DEFAULT_STRINGS: Required<IPktCalendarStrings> = {
4
- month: 'Måned',
5
- year: 'År',
6
- days: ['Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag', 'Søndag'],
7
- daysShort: ['Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør', 'Søn'],
8
- months: [
9
- 'Januar',
10
- 'Februar',
11
- 'Mars',
12
- 'April',
13
- 'Mai',
14
- 'Juni',
15
- 'Juli',
16
- 'August',
17
- 'September',
18
- 'Oktober',
19
- 'November',
20
- 'Desember',
21
- ],
22
- week: 'Uke',
23
- prevMonth: 'Forrige måned',
24
- nextMonth: 'Neste måned',
25
- }
3
+ import type { TPktStringsOverride } from 'shared-strings'
26
4
 
5
+ /** Datonavn og navigasjonstekster slik kalender-underkomponentene forventer dem. */
27
6
  export interface IPktCalendarStrings {
28
- month?: string
29
- year?: string
30
- days?: string[]
31
- daysShort?: string[]
32
- months?: string[]
33
- week?: string
34
- prevMonth?: string
35
- nextMonth?: string
7
+ month: string
8
+ year: string
9
+ days: string[]
10
+ daysShort: string[]
11
+ months: string[]
12
+ week: string
13
+ prevMonth: string
14
+ nextMonth: string
36
15
  }
37
16
 
38
17
  export interface PktCalendarHandle {
@@ -64,7 +43,8 @@ export interface IPktCalendar {
64
43
  today?: string
65
44
 
66
45
  // Localization
67
- strings?: IPktCalendarStrings
46
+ /** Overstyrer tekster for denne komponenten. */
47
+ strings?: TPktStringsOverride
68
48
 
69
49
  // Callbacks
70
50
  onDateSelected?: (selected: string[]) => void
@@ -87,7 +67,7 @@ export type TDayViewData = {
87
67
 
88
68
  export interface ICalendarState {
89
69
  componentId: string
90
- strings: Required<IPktCalendarStrings>
70
+ strings: IPktCalendarStrings
91
71
 
92
72
  // Navigation
93
73
  year: number
@@ -148,7 +128,7 @@ export interface ICalendarState {
148
128
 
149
129
  export interface ICalendarNavProps {
150
130
  componentId: string
151
- strings: Required<IPktCalendarStrings>
131
+ strings: IPktCalendarStrings
152
132
  year: number
153
133
  month: number
154
134
  earliest: string | null
@@ -17,7 +17,8 @@ import {
17
17
  getKeyDirection,
18
18
  } from 'shared-utils/calendar/keyboard-navigation'
19
19
 
20
- import { DEFAULT_STRINGS, type IPktCalendar, type ICalendarState } from './types'
20
+ import { type IPktCalendar, type ICalendarState } from './types'
21
+ import { usePktStrings } from '../../hooks/usePktStrings'
21
22
 
22
23
  export function useCalendarState(props: IPktCalendar): ICalendarState {
23
24
  const {
@@ -43,7 +44,20 @@ export function useCalendarState(props: IPktCalendar): ICalendarState {
43
44
  const generatedId = useId()
44
45
  const componentId = idProp ?? generatedId
45
46
 
46
- const strings = useMemo(() => ({ ...DEFAULT_STRINGS, ...stringsProp }), [stringsProp])
47
+ const catalog = usePktStrings(['dates', 'calendar'], stringsProp)
48
+ const strings = useMemo(
49
+ () => ({
50
+ month: catalog.dates.month,
51
+ year: catalog.dates.year,
52
+ week: catalog.dates.week,
53
+ days: catalog.dates.days,
54
+ daysShort: catalog.dates.daysShort,
55
+ months: catalog.dates.months,
56
+ prevMonth: catalog.calendar.prevMonth,
57
+ nextMonth: catalog.calendar.nextMonth,
58
+ }),
59
+ [catalog],
60
+ )
47
61
 
48
62
  const todayDate = useMemo(
49
63
  () => (todayProp ? parseISODateString(todayProp) : todayInTz()),