@helsenorge/designsystem-react 14.5.1 → 14.7.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 (73) hide show
  1. package/lib/CHANGELOG.md +24 -0
  2. package/lib/Drawer.js +37 -14
  3. package/lib/Drawer.js.map +1 -1
  4. package/lib/Select.js +3 -2
  5. package/lib/Select.js.map +1 -1
  6. package/lib/Title.js +2 -1
  7. package/lib/Title.js.map +1 -1
  8. package/lib/components/Drawer/Drawer.d.ts +6 -0
  9. package/lib/components/Drawer/styles.module.scss +19 -0
  10. package/lib/components/Drawer/styles.module.scss.d.ts +1 -0
  11. package/lib/components/Dropdown/styles.module.scss +4 -4
  12. package/lib/components/Filter/DrawerNavigation/DrawerNavigation.d.ts +35 -0
  13. package/lib/components/Filter/DrawerNavigation/FinnFastlegeFlyt.example.d.ts +2 -0
  14. package/lib/components/Filter/DrawerNavigation/FinnFastlegeFlyt.module.scss +15 -0
  15. package/lib/components/Filter/DrawerNavigation/FinnFastlegeFlyt.module.scss.d.ts +11 -0
  16. package/lib/components/Filter/DrawerNavigation/index.d.ts +4 -0
  17. package/lib/components/Filter/DrawerNavigation/index.js +81 -0
  18. package/lib/components/Filter/DrawerNavigation/index.js.map +1 -0
  19. package/lib/components/Filter/DrawerNavigation/useDrawerNavigation.d.ts +7 -0
  20. package/lib/components/Filter/FilterButton/FilterButton.d.ts +7 -0
  21. package/lib/components/Filter/FilterButton/styles.module.scss +52 -0
  22. package/lib/components/Filter/FilterButton/styles.module.scss.d.ts +12 -0
  23. package/lib/components/Filter/FilterButtonAndChipsWrapper/FilterButtonAndChipsWrapper.d.ts +11 -0
  24. package/lib/components/Filter/FilterButtonAndChipsWrapper/styles.module.scss +8 -0
  25. package/lib/components/Filter/FilterButtonAndChipsWrapper/styles.module.scss.d.ts +9 -0
  26. package/lib/components/Filter/FilterDrawer/FilterDrawer.d.ts +42 -0
  27. package/lib/components/Filter/FilterDrawer/styles.module.scss +29 -0
  28. package/lib/components/Filter/FilterDrawer/styles.module.scss.d.ts +10 -0
  29. package/lib/components/Filter/FilterLinkList/FilterLinkList.d.ts +35 -0
  30. package/lib/components/Filter/FilterLinkList/FilterLinkList.module.scss +89 -0
  31. package/lib/components/Filter/FilterLinkList/FilterLinkList.module.scss.d.ts +14 -0
  32. package/lib/components/Filter/FilterOverviewLinkList/FilterOverviewLinkList.d.ts +19 -0
  33. package/lib/components/Filter/FilterOverviewSearch/FilterOverviewSearch.d.ts +9 -0
  34. package/lib/components/Filter/FilterOverviewSearch/styles.module.scss +14 -0
  35. package/lib/components/Filter/FilterOverviewSearch/styles.module.scss.d.ts +9 -0
  36. package/lib/components/Filter/FilterResultCountAndSortWrapper/FilterResultCountAndSortWrapper.d.ts +8 -0
  37. package/lib/components/Filter/FilterResultCountAndSortWrapper/styles.module.scss +17 -0
  38. package/lib/components/Filter/FilterResultCountAndSortWrapper/styles.module.scss.d.ts +11 -0
  39. package/lib/components/Filter/FilterSearch/FilterSearch.d.ts +19 -0
  40. package/lib/components/Filter/FilterSearch/styles.module.scss +181 -0
  41. package/lib/components/Filter/FilterSearch/styles.module.scss.d.ts +16 -0
  42. package/lib/components/Filter/FilterSort/FilterSort.d.ts +8 -0
  43. package/lib/components/Filter/FilterSort/styles.module.scss +29 -0
  44. package/lib/components/Filter/FilterSort/styles.module.scss.d.ts +11 -0
  45. package/lib/components/Filter/getFilterChips/getFilterChips.d.ts +17 -0
  46. package/lib/components/Filter/index.d.ts +2 -0
  47. package/lib/components/Filter/index.js +109 -0
  48. package/lib/components/Filter/index.js.map +1 -0
  49. package/lib/components/Filter/resourceHelper.d.ts +3 -0
  50. package/lib/components/Filter/resourcesMock.d.ts +41 -0
  51. package/lib/components/Filter/useFilter.d.ts +20 -0
  52. package/lib/components/Filter/useFilterDrawer.d.ts +11 -0
  53. package/lib/components/Filter/utils.d.ts +81 -0
  54. package/lib/components/Highlighter/styles.module.scss +1 -1
  55. package/lib/components/Icons/HTMLFile.js +3 -11
  56. package/lib/components/Icons/HTMLFile.js.map +1 -1
  57. package/lib/components/Label/utils.d.ts +1 -0
  58. package/lib/components/NotificationPanel/NotificationPanel.d.ts +1 -1
  59. package/lib/components/NotificationPanel/index.js +1 -1
  60. package/lib/components/NotificationPanel/index.js.map +1 -1
  61. package/lib/components/Select/Select.d.ts +2 -0
  62. package/lib/components/Select/styles.module.scss +1 -0
  63. package/lib/components/Title/Title.d.ts +2 -0
  64. package/lib/index.d.ts +1 -0
  65. package/lib/index.js +2 -1
  66. package/lib/resource.js +4 -0
  67. package/lib/resource.js.map +1 -0
  68. package/lib/resources/HN.Designsystem.Drawer.nn-NO.json.d.ts +7 -0
  69. package/lib/utils/resource.d.ts +6 -0
  70. package/lib/utils/resource.js +2 -0
  71. package/lib/utils2.js +4 -2
  72. package/lib/utils2.js.map +1 -1
  73. package/package.json +1 -1
@@ -0,0 +1,11 @@
1
+ export type Styles = {
2
+ select: string;
3
+ select__label: string;
4
+ select__wrapper: string;
5
+ };
6
+
7
+ export type ClassNames = keyof Styles;
8
+
9
+ declare const styles: Styles;
10
+
11
+ export default styles;
@@ -0,0 +1,17 @@
1
+ import { FilterValues, UseFilterReturn } from '../useFilter';
2
+ export interface GetFilterChipsArgs<T extends FilterValues> {
3
+ /** The filter instance from useFilter */
4
+ filter: UseFilterReturn<T>;
5
+ /** Look up the display label for a filter key + value */
6
+ getLabel: (key: keyof T, value: unknown) => string;
7
+ /** Called when a chip is clicked (f.ex. to open the drawer at that filter category) */
8
+ onChipClick: (key: keyof T, value: unknown) => void;
9
+ /** Called when a chip's close button is clicked. If not provided, defaults to filter.removeFilter */
10
+ onChipRemove?: (key: keyof T, value: unknown) => void;
11
+ /** Called when the overflow chip is clicked */
12
+ onOverflowChipClick: () => void;
13
+ /** Function for mapping if close button is shown on chip or not */
14
+ willShowCloseButton?: (key: keyof T, value?: unknown) => boolean;
15
+ }
16
+ declare function getFilterChips<T extends FilterValues>({ filter, getLabel, onChipClick, onChipRemove, onOverflowChipClick, willShowCloseButton, }: GetFilterChipsArgs<T>): React.ReactNode[];
17
+ export default getFilterChips;
@@ -0,0 +1,2 @@
1
+ export * from './useFilter';
2
+ export * from './utils';
@@ -0,0 +1,109 @@
1
+ import { useState } from "react";
2
+ const useFilter = (options) => {
3
+ const [filters, setFiltersState] = useState(() => ({ ...options?.defaultValues }));
4
+ const removeFilter = (filterKey, optionValue) => {
5
+ setFiltersState((prev) => {
6
+ const current = prev[filterKey];
7
+ if (current === void 0) return prev;
8
+ if (optionValue !== void 0 && Array.isArray(current)) {
9
+ const updated = current.filter((v) => v !== optionValue);
10
+ if (updated.length === 0) {
11
+ const { [filterKey]: _removed$1, ...rest$1 } = prev;
12
+ return rest$1;
13
+ }
14
+ return {
15
+ ...prev,
16
+ [filterKey]: updated
17
+ };
18
+ }
19
+ const { [filterKey]: _removed, ...rest } = prev;
20
+ return rest;
21
+ });
22
+ };
23
+ const setFilter = (name, value) => {
24
+ if (value === void 0) {
25
+ removeFilter(name);
26
+ return;
27
+ }
28
+ setFiltersState((prev) => ({
29
+ ...prev,
30
+ [name]: value
31
+ }));
32
+ };
33
+ const setFilters = (newFilters) => {
34
+ setFiltersState(newFilters);
35
+ };
36
+ const resetFilters = () => {
37
+ setFiltersState({ ...options?.defaultValues });
38
+ };
39
+ const resetFiltersToEmpty = () => {
40
+ setFiltersState({});
41
+ };
42
+ return {
43
+ filters,
44
+ setFilter,
45
+ setFilters,
46
+ removeFilter,
47
+ resetFilters,
48
+ resetFiltersToEmpty
49
+ };
50
+ };
51
+ const createFilterConfig = (categories) => {
52
+ const defaultValues = {};
53
+ const labelMaps = /* @__PURE__ */ new Map();
54
+ for (const key in categories) {
55
+ const category = categories[key];
56
+ if (category?.defaultValue !== void 0) defaultValues[key] = category.defaultValue;
57
+ if (category?.options) {
58
+ const resolve = category.getLabel ?? ((o) => String(o.value));
59
+ const map = /* @__PURE__ */ new Map();
60
+ for (const opt of category.options) map.set(opt.value, resolve(opt));
61
+ labelMaps.set(key, map);
62
+ }
63
+ }
64
+ const getLabel = (key, value) => {
65
+ return labelMaps.get(key)?.get(value) ?? String(value);
66
+ };
67
+ return {
68
+ filterOptions: { defaultValues },
69
+ getLabel
70
+ };
71
+ };
72
+ const matchFilter = {
73
+ arrayIncludes: (accessor) => (item, value) => {
74
+ const filterValues = Array.isArray(value) ? value : [value];
75
+ const itemValue = accessor(item);
76
+ if (Array.isArray(itemValue)) return itemValue.some((v) => filterValues.includes(v));
77
+ return filterValues.includes(itemValue);
78
+ },
79
+ exactMatch: (accessor) => (item, value) => {
80
+ if (Array.isArray(value)) return value.includes(accessor(item));
81
+ return accessor(item) === value;
82
+ },
83
+ booleanToggle: (accessor) => (item, value) => {
84
+ return !(Array.isArray(value) ? value.includes(true) : value === true) || accessor(item);
85
+ },
86
+ textSearch: (...accessors) => (item, value) => {
87
+ const search = String(value).toLowerCase();
88
+ return accessors.some((accessor) => accessor(item)?.toLowerCase().includes(search));
89
+ }
90
+ };
91
+ const filterItems = (items, filters, matchers) => {
92
+ return items.filter((item) => {
93
+ for (const key in matchers) {
94
+ const value = filters[key];
95
+ if (value === void 0) continue;
96
+ const matcher = matchers[key];
97
+ if (matcher && !matcher(item, value)) return false;
98
+ }
99
+ return true;
100
+ });
101
+ };
102
+ const toggleArrayFilter = (filter, filterKey, value) => {
103
+ const current = filter.filters[filterKey] ?? [];
104
+ const updated = current.includes(value) ? current.filter((v) => v !== value) : [...current, value];
105
+ filter.setFilter(filterKey, updated.length > 0 ? updated : void 0);
106
+ };
107
+ export { createFilterConfig, filterItems, matchFilter, toggleArrayFilter, useFilter };
108
+
109
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Filter/useFilter.ts","../../../src/components/Filter/utils.ts"],"sourcesContent":["import { useState } from 'react';\n\n// Key er string men value kan være hva som helst og er ukjent for oss internt i useFilter. Den er typesikker for consumer.\n// Dette mønsteret lar oss ha ulike typer i samme objekt.\nexport type FilterValues = Record<string, unknown>;\n\nexport interface UseFilterOptions<T extends FilterValues> {\n /** Initial filter values */\n defaultValues?: Partial<T>;\n}\n\nexport interface UseFilterReturn<T extends FilterValues> {\n /** Current filter state */\n filters: Partial<T>;\n /** Update a single filter. Pass undefined to remove it. */\n setFilter: <K extends keyof T>(name: K, value: T[K] | undefined) => void;\n /** Replace all filters at once (useful for applying draft/delayed filters) */\n setFilters: (filters: Partial<T>) => void;\n /** Remove a filter entirely, or a specific value from an array filter */\n removeFilter: (filterKey: keyof T | string, optionValue?: unknown) => void;\n /** Reset filters to default values */\n resetFilters: () => void;\n /** Resets to empty filter */\n resetFiltersToEmpty: () => void;\n}\n\nexport const useFilter = <T extends FilterValues>(options?: UseFilterOptions<T>): UseFilterReturn<T> => {\n const [filters, setFiltersState] = useState<Partial<T>>(() => ({ ...options?.defaultValues }) as Partial<T>);\n\n // Fjern et filter helt, eller fjern en spesifikk verdi fra et array-filter.\n const removeFilter = (filterKey: keyof T, optionValue?: unknown): void => {\n setFiltersState(prev => {\n const current = prev[filterKey];\n if (current === undefined) return prev;\n if (optionValue !== undefined && Array.isArray(current)) {\n const updated = current.filter(v => v !== optionValue);\n if (updated.length === 0) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [filterKey as string]: _removed, ...rest } = prev;\n return rest as Partial<T>;\n }\n return { ...prev, [filterKey]: updated };\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [filterKey as string]: _removed, ...rest } = prev;\n return rest as Partial<T>;\n });\n };\n\n // Sett en filtervalue. Send inn undefined for å fjerne filteret.\n const setFilter = <K extends keyof T>(name: K, value: T[K] | undefined): void => {\n if (value === undefined) {\n removeFilter(name);\n return;\n }\n setFiltersState(prev => ({ ...prev, [name]: value }));\n };\n\n // Erstatt alle filtre på en gang (f.eks. ved \"Bruk filter\" i delayed filtrering).\n const setFilters = (newFilters: Partial<T>): void => {\n setFiltersState(newFilters);\n };\n\n const resetFilters = (): void => {\n setFiltersState({ ...options?.defaultValues } as Partial<T>);\n };\n\n const resetFiltersToEmpty = (): void => {\n setFiltersState({});\n };\n\n return { filters, setFilter, setFilters, removeFilter, resetFilters, resetFiltersToEmpty };\n};\n","import type { FilterValues, UseFilterOptions, UseFilterReturn } from './useFilter';\n\n/** Et filtervalg med verdi og visningstekst */\nexport interface FilterOption<V = string> {\n value: V;\n label: string;\n}\n\n// Hvis V er et array (f.eks. string[]), hent ut typen inni arrayet (string).\n// Hvis V ikke er et array (f.eks. boolean), bruk V som den er.\n// Brukes for å sikre at options-listen matcher elementene, ikke hele arrayet.\n// Eksempel: FilterCategoryConfig<string[]> → options er FilterOption<string>[], ikke FilterOption<string[]>[]\ntype OptionValue<V> = V extends (infer U)[] ? U : V;\n\n/** Konfigurasjon for en filterkategori. */\nexport interface FilterCategoryConfig<V = unknown> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options?: ({ value: OptionValue<V> } & { [key: string]: any })[];\n defaultValue?: V;\n /** Hent visningstekst fra et option-objekt. Hvis ikke satt, brukes String(value). */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getLabel?: (option: any) => string;\n}\n\nexport interface FilterConfigResult<T extends FilterValues> {\n /** Options for useFilter (defaultValues) */\n filterOptions: UseFilterOptions<T>;\n /** Look up the display label for a filter value */\n getLabel: (key: keyof T, value: unknown) => string;\n}\n\n/**\n * Lager UseFilterOptions fra et oppsett av filterkategorier.\n * Samler defaultValues og label-oppslag automatisk fra config.\n *\n * Eksempel:\n * const { filterOptions, getLabel } = createFilterConfig<MyFilters>({\n * sykehus: { options: sykehusOptions, defaultValue: ['haukeland'], getLabel: o => o.label },\n * status: { options: statusOptions, getLabel: o => o.displayText },\n * });\n * const filter = useFilter(filterOptions);\n * getLabel('sykehus', 'haukeland') // → 'Haukeland universitetssjukehus'\n */\nexport const createFilterConfig = <T extends FilterValues>(categories: {\n [K in keyof T]?: FilterCategoryConfig<T[K]>;\n}): FilterConfigResult<T> => {\n const defaultValues = {} as Partial<T>;\n const labelMaps = new Map<string, Map<unknown, string>>();\n\n for (const key in categories) {\n const category = categories[key];\n if (category?.defaultValue !== undefined) {\n defaultValues[key] = category.defaultValue as T[typeof key];\n }\n if (category?.options) {\n const resolve = category.getLabel ?? ((o: { value: unknown }): string => String(o.value));\n const map = new Map<unknown, string>();\n for (const opt of category.options) {\n map.set(opt.value, resolve(opt));\n }\n labelMaps.set(key, map);\n }\n }\n\n const getLabel = (key: keyof T, value: unknown): string => {\n return labelMaps.get(key as string)?.get(value) ?? String(value); // todo: fallback til .displaytext om det ikke er sendt inn noe, og String(value) om .label ikke finnes\n };\n\n return { filterOptions: { defaultValues }, getLabel };\n};\n\n/**\n * Ferdige matcher-funksjoner for typiske filter mønster.\n * Brukes som deler i matcher objektet til filterItems.\n *\n * Eksempel:\n * const filterMatchers = {\n * categories: matchFilter.arrayIncludes<Medisin>(m => m.sykehus),\n * status: matchFilter.exactMatch<Medisin>(m => m.status),\n * eResept: matchFilter.booleanToggle<Medisin>(m => m.eResept),\n * };\n */\nexport const matchFilter = {\n /** Array-filter: matcher hvis det er overlapp mellom filterverdier og item-verdier (OR-logikk). */\n arrayIncludes:\n <TItem>(accessor: (item: TItem) => unknown) =>\n (item: TItem, value: unknown): boolean => {\n const filterValues = Array.isArray(value) ? value : [value];\n const itemValue = accessor(item);\n if (Array.isArray(itemValue)) {\n return itemValue.some(v => filterValues.includes(v));\n }\n return filterValues.includes(itemValue);\n },\n\n /** Eksakt match: matcher hvis item-verdien er lik én av filterverdiene */\n exactMatch:\n <TItem>(accessor: (item: TItem) => unknown) =>\n (item: TItem, value: unknown): boolean => {\n if (Array.isArray(value)) {\n return value.includes(accessor(item));\n }\n return accessor(item) === value;\n },\n\n /** Boolean toggle: når filterverdien er true, inkluder kun items der accessor returnerer true */\n booleanToggle:\n <TItem>(accessor: (item: TItem) => boolean) =>\n (item: TItem, value: unknown): boolean => {\n const active = Array.isArray(value) ? value.includes(true) : value === true;\n return !active || accessor(item);\n },\n\n /** Fritekstsøk: matcher hvis søketeksten finnes i ett eller flere felt (case-insensitive) */\n textSearch:\n <TItem>(...accessors: ((item: TItem) => string | undefined)[]) =>\n (item: TItem, value: unknown): boolean => {\n const search = String(value).toLowerCase();\n return accessors.some(accessor => accessor(item)?.toLowerCase().includes(search));\n },\n};\n\n/**\n * Filtrerer en liste med items basert på aktive filterverdier.\n * Hvert filter som er satt må matche for at et item skal inkluderes (AND-logikk).\n *\n * Eksempel:\n * const filtered = filterItems(medisiner, filter.filters, {\n * sykehus: matchFilter.arrayIncludes<Medisin>(m => m.sykehus),\n * reseptstatus: matchFilter.exactMatch<Medisin>(m => m.reseptstatus),\n * eResept: matchFilter.booleanToggle<Medisin>(m => m.eResept),\n * });\n */\n\n/** Type for matcher-objektet som sendes til filterItems. Sikrer at keys matcher filtertypen. */\nexport type FilterMatchers<TItem, T extends FilterValues> = { [K in keyof T]?: (item: TItem, value: NonNullable<T[K]>) => boolean };\n\nexport const filterItems = <TItem, T extends FilterValues>(\n items: TItem[],\n filters: Partial<T>,\n matchers: FilterMatchers<TItem, T>\n): TItem[] => {\n return items.filter(item => {\n for (const key in matchers) {\n const value = filters[key];\n if (value === undefined) {\n continue;\n }\n const matcher = matchers[key];\n if (matcher && !matcher(item, value as NonNullable<T[typeof key]>)) {\n return false;\n }\n }\n return true;\n });\n};\n\n/**\n * Toggler en verdi i et array-basert filter.\n * Legger til verdien hvis den ikke finnes, fjerner den hvis den finnes.\n * Setter filteret til undefined hvis arrayet blir tomt.\n */\nexport const toggleArrayFilter = <T extends FilterValues, K extends keyof T>(\n filter: UseFilterReturn<T>,\n filterKey: K,\n value: T[K] extends (infer U)[] | undefined ? U : never\n): void => {\n const current = (filter.filters[filterKey] ?? []) as unknown[];\n const updated = current.includes(value) ? current.filter(v => v !== value) : [...current, value];\n filter.setFilter(filterKey, (updated.length > 0 ? updated : undefined) as T[K] | undefined);\n};\n"],"mappings":";AA0BA,MAAa,aAAqC,YAAsD;CACtG,MAAM,CAAC,SAAS,mBAAmB,gBAA4B,EAAE,GAAG,SAAS,eAAe,EAAgB;CAG5G,MAAM,gBAAgB,WAAoB,gBAAgC;AACxE,mBAAgB,SAAQ;GACtB,MAAM,UAAU,KAAK;AACrB,OAAI,YAAY,KAAA,EAAW,QAAO;AAClC,OAAI,gBAAgB,KAAA,KAAa,MAAM,QAAQ,QAAQ,EAAE;IACvD,MAAM,UAAU,QAAQ,QAAO,MAAK,MAAM,YAAY;AACtD,QAAI,QAAQ,WAAW,GAAG;KAExB,MAAM,GAAG,YAAsB,YAAU,GAAG,WAAS;AACrD,YAAO;;AAET,WAAO;KAAE,GAAG;MAAO,YAAY;KAAS;;GAG1C,MAAM,GAAG,YAAsB,UAAU,GAAG,SAAS;AACrD,UAAO;IACP;;CAIJ,MAAM,aAAgC,MAAS,UAAkC;AAC/E,MAAI,UAAU,KAAA,GAAW;AACvB,gBAAa,KAAK;AAClB;;AAEF,mBAAgB,UAAS;GAAE,GAAG;IAAO,OAAO;GAAO,EAAE;;CAIvD,MAAM,cAAc,eAAiC;AACnD,kBAAgB,WAAW;;CAG7B,MAAM,qBAA2B;AAC/B,kBAAgB,EAAE,GAAG,SAAS,eAAe,CAAe;;CAG9D,MAAM,4BAAkC;AACtC,kBAAgB,EAAE,CAAC;;AAGrB,QAAO;EAAE;EAAS;EAAW;EAAY;EAAc;EAAc;EAAqB;;AC5B5F,MAAa,sBAA8C,eAE9B;CAC3B,MAAM,gBAAgB,EAAE;CACxB,MAAM,4BAAY,IAAI,KAAmC;AAEzD,MAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,WAAW,WAAW;AAC5B,MAAI,UAAU,iBAAiB,KAAA,EAC7B,eAAc,OAAO,SAAS;AAEhC,MAAI,UAAU,SAAS;GACrB,MAAM,UAAU,SAAS,cAAc,MAAkC,OAAO,EAAE,MAAM;GACxF,MAAM,sBAAM,IAAI,KAAsB;AACtC,QAAK,MAAM,OAAO,SAAS,QACzB,KAAI,IAAI,IAAI,OAAO,QAAQ,IAAI,CAAC;AAElC,aAAU,IAAI,KAAK,IAAI;;;CAI3B,MAAM,YAAY,KAAc,UAA2B;AACzD,SAAO,UAAU,IAAI,IAAc,EAAE,IAAI,MAAM,IAAI,OAAO,MAAM;;AAGlE,QAAO;EAAE,eAAe,EAAE,eAAe;EAAE;EAAU;;AAcvD,MAAa,cAAc;CAEzB,gBACU,cACP,MAAa,UAA4B;EACxC,MAAM,eAAe,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;EAC3D,MAAM,YAAY,SAAS,KAAK;AAChC,MAAI,MAAM,QAAQ,UAAU,CAC1B,QAAO,UAAU,MAAK,MAAK,aAAa,SAAS,EAAE,CAAC;AAEtD,SAAO,aAAa,SAAS,UAAU;;CAI3C,aACU,cACP,MAAa,UAA4B;AACxC,MAAI,MAAM,QAAQ,MAAM,CACtB,QAAO,MAAM,SAAS,SAAS,KAAK,CAAC;AAEvC,SAAO,SAAS,KAAK,KAAK;;CAI9B,gBACU,cACP,MAAa,UAA4B;AAExC,SAAO,EADQ,MAAM,QAAQ,MAAM,GAAG,MAAM,SAAS,KAAK,GAAG,UAAU,SACrD,SAAS,KAAK;;CAIpC,aACU,GAAG,eACV,MAAa,UAA4B;EACxC,MAAM,SAAS,OAAO,MAAM,CAAC,aAAa;AAC1C,SAAO,UAAU,MAAK,aAAY,SAAS,KAAK,EAAE,aAAa,CAAC,SAAS,OAAO,CAAC;;CAEtF;AAiBD,MAAa,eACX,OACA,SACA,aACY;AACZ,QAAO,MAAM,QAAO,SAAQ;AAC1B,OAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,QAAQ,QAAQ;AACtB,OAAI,UAAU,KAAA,EACZ;GAEF,MAAM,UAAU,SAAS;AACzB,OAAI,WAAW,CAAC,QAAQ,MAAM,MAAoC,CAChE,QAAO;;AAGX,SAAO;GACP;;AAQJ,MAAa,qBACX,QACA,WACA,UACS;CACT,MAAM,UAAW,OAAO,QAAQ,cAAc,EAAE;CAChD,MAAM,UAAU,QAAQ,SAAS,MAAM,GAAG,QAAQ,QAAO,MAAK,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,MAAM;AAChG,QAAO,UAAU,WAAY,QAAQ,SAAS,IAAI,UAAU,KAAA,EAA+B"}
@@ -0,0 +1,3 @@
1
+ import { HNDesignsystemFilter } from '../../resources/Resources';
2
+ import { LanguageLocales } from '../../constants';
3
+ export declare const getResources: (language: LanguageLocales) => HNDesignsystemFilter;
@@ -0,0 +1,41 @@
1
+ import { LanguageLocales } from '../../constants';
2
+ export declare const getResources: (language: LanguageLocales) => {
3
+ verktoydata_aa_name: string;
4
+ verktoydata_aa_ingress: string;
5
+ verktoydata_grubl_name: string;
6
+ verktoydata_grubl_ingress: string;
7
+ verktoydata_mm_name: string;
8
+ verktoydata_mm_ingress: string;
9
+ verktoydata_hverdagshjelpen_name: string;
10
+ verktoydata_hverdagshjelpen_ingress: string;
11
+ verktoydata_ungmestring_name: string;
12
+ verktoydata_ungmestring_ingress: string;
13
+ verktoydata_bevegelsesglede_name: string;
14
+ verktoydata_bevegelsesglede_ingress: string;
15
+ verktoydata_tryggfodsel_name: string;
16
+ verktoydata_tryggfodsel_ingress: string;
17
+ verktoydata_skadekompasset_name: string;
18
+ verktoydata_skadekompasset_ingress: string;
19
+ verktoydata_seniorbalanse_name: string;
20
+ verktoydata_seniorbalanse_ingress: string;
21
+ verktoydata_tankevenn_name: string;
22
+ verktoydata_tankevenn_ingress: string;
23
+ filterOptionTitles_omrade: string;
24
+ filterOptionTitles_passerfor: string;
25
+ filterOptionTitles_type: string;
26
+ omradeOptions_psykiskhelse: string;
27
+ omradeOptions_graviditet: string;
28
+ omradeOptions_livsstil: string;
29
+ omradeOptions_sykdom: string;
30
+ omradeOptions_rad: string;
31
+ omradeOptions_tanker: string;
32
+ passerForOptions_barn: string;
33
+ passerForOptions_ungdom: string;
34
+ passerForOptions_voksne: string;
35
+ passerForOptions_eldre: string;
36
+ typeOptions_app: string;
37
+ typeOptions_web: string;
38
+ filterOption_omrade_legend: string;
39
+ filterOption_passerFor_legend: string;
40
+ filterOption_type_legend: string;
41
+ };
@@ -0,0 +1,20 @@
1
+ export type FilterValues = Record<string, unknown>;
2
+ export interface UseFilterOptions<T extends FilterValues> {
3
+ /** Initial filter values */
4
+ defaultValues?: Partial<T>;
5
+ }
6
+ export interface UseFilterReturn<T extends FilterValues> {
7
+ /** Current filter state */
8
+ filters: Partial<T>;
9
+ /** Update a single filter. Pass undefined to remove it. */
10
+ setFilter: <K extends keyof T>(name: K, value: T[K] | undefined) => void;
11
+ /** Replace all filters at once (useful for applying draft/delayed filters) */
12
+ setFilters: (filters: Partial<T>) => void;
13
+ /** Remove a filter entirely, or a specific value from an array filter */
14
+ removeFilter: (filterKey: keyof T | string, optionValue?: unknown) => void;
15
+ /** Reset filters to default values */
16
+ resetFilters: () => void;
17
+ /** Resets to empty filter */
18
+ resetFiltersToEmpty: () => void;
19
+ }
20
+ export declare const useFilter: <T extends FilterValues>(options?: UseFilterOptions<T>) => UseFilterReturn<T>;
@@ -0,0 +1,11 @@
1
+ export interface UseFilterDrawerReturn<ViewId extends string = string> {
2
+ /** Whether the drawer is currently open */
3
+ isOpen: boolean;
4
+ /** The view to navigate to when the drawer opens */
5
+ initialView: ViewId | undefined;
6
+ /** Open the drawer, optionally navigating directly to a specific view */
7
+ open: (view?: ViewId) => void;
8
+ /** Close the drawer */
9
+ close: () => void;
10
+ }
11
+ export declare const useFilterDrawer: <ViewId extends string = string>() => UseFilterDrawerReturn<ViewId>;
@@ -0,0 +1,81 @@
1
+ import { FilterValues, UseFilterOptions, UseFilterReturn } from './useFilter';
2
+ /** Et filtervalg med verdi og visningstekst */
3
+ export interface FilterOption<V = string> {
4
+ value: V;
5
+ label: string;
6
+ }
7
+ type OptionValue<V> = V extends (infer U)[] ? U : V;
8
+ /** Konfigurasjon for en filterkategori. */
9
+ export interface FilterCategoryConfig<V = unknown> {
10
+ options?: ({
11
+ value: OptionValue<V>;
12
+ } & {
13
+ [key: string]: any;
14
+ })[];
15
+ defaultValue?: V;
16
+ /** Hent visningstekst fra et option-objekt. Hvis ikke satt, brukes String(value). */
17
+ getLabel?: (option: any) => string;
18
+ }
19
+ export interface FilterConfigResult<T extends FilterValues> {
20
+ /** Options for useFilter (defaultValues) */
21
+ filterOptions: UseFilterOptions<T>;
22
+ /** Look up the display label for a filter value */
23
+ getLabel: (key: keyof T, value: unknown) => string;
24
+ }
25
+ /**
26
+ * Lager UseFilterOptions fra et oppsett av filterkategorier.
27
+ * Samler defaultValues og label-oppslag automatisk fra config.
28
+ *
29
+ * Eksempel:
30
+ * const { filterOptions, getLabel } = createFilterConfig<MyFilters>({
31
+ * sykehus: { options: sykehusOptions, defaultValue: ['haukeland'], getLabel: o => o.label },
32
+ * status: { options: statusOptions, getLabel: o => o.displayText },
33
+ * });
34
+ * const filter = useFilter(filterOptions);
35
+ * getLabel('sykehus', 'haukeland') // → 'Haukeland universitetssjukehus'
36
+ */
37
+ export declare const createFilterConfig: <T extends FilterValues>(categories: { [K in keyof T]?: FilterCategoryConfig<T[K]>; }) => FilterConfigResult<T>;
38
+ /**
39
+ * Ferdige matcher-funksjoner for typiske filter mønster.
40
+ * Brukes som deler i matcher objektet til filterItems.
41
+ *
42
+ * Eksempel:
43
+ * const filterMatchers = {
44
+ * categories: matchFilter.arrayIncludes<Medisin>(m => m.sykehus),
45
+ * status: matchFilter.exactMatch<Medisin>(m => m.status),
46
+ * eResept: matchFilter.booleanToggle<Medisin>(m => m.eResept),
47
+ * };
48
+ */
49
+ export declare const matchFilter: {
50
+ /** Array-filter: matcher hvis det er overlapp mellom filterverdier og item-verdier (OR-logikk). */
51
+ arrayIncludes: <TItem>(accessor: (item: TItem) => unknown) => (item: TItem, value: unknown) => boolean;
52
+ /** Eksakt match: matcher hvis item-verdien er lik én av filterverdiene */
53
+ exactMatch: <TItem>(accessor: (item: TItem) => unknown) => (item: TItem, value: unknown) => boolean;
54
+ /** Boolean toggle: når filterverdien er true, inkluder kun items der accessor returnerer true */
55
+ booleanToggle: <TItem>(accessor: (item: TItem) => boolean) => (item: TItem, value: unknown) => boolean;
56
+ /** Fritekstsøk: matcher hvis søketeksten finnes i ett eller flere felt (case-insensitive) */
57
+ textSearch: <TItem>(...accessors: ((item: TItem) => string | undefined)[]) => (item: TItem, value: unknown) => boolean;
58
+ };
59
+ /**
60
+ * Filtrerer en liste med items basert på aktive filterverdier.
61
+ * Hvert filter som er satt må matche for at et item skal inkluderes (AND-logikk).
62
+ *
63
+ * Eksempel:
64
+ * const filtered = filterItems(medisiner, filter.filters, {
65
+ * sykehus: matchFilter.arrayIncludes<Medisin>(m => m.sykehus),
66
+ * reseptstatus: matchFilter.exactMatch<Medisin>(m => m.reseptstatus),
67
+ * eResept: matchFilter.booleanToggle<Medisin>(m => m.eResept),
68
+ * });
69
+ */
70
+ /** Type for matcher-objektet som sendes til filterItems. Sikrer at keys matcher filtertypen. */
71
+ export type FilterMatchers<TItem, T extends FilterValues> = {
72
+ [K in keyof T]?: (item: TItem, value: NonNullable<T[K]>) => boolean;
73
+ };
74
+ export declare const filterItems: <TItem, T extends FilterValues>(items: TItem[], filters: Partial<T>, matchers: FilterMatchers<TItem, T>) => TItem[];
75
+ /**
76
+ * Toggler en verdi i et array-basert filter.
77
+ * Legger til verdien hvis den ikke finnes, fjerner den hvis den finnes.
78
+ * Setter filteret til undefined hvis arrayet blir tomt.
79
+ */
80
+ export declare const toggleArrayFilter: <T extends FilterValues, K extends keyof T>(filter: UseFilterReturn<T>, filterKey: K, value: T[K] extends (infer U)[] | undefined ? U : never) => void;
81
+ export {};
@@ -1,4 +1,4 @@
1
1
  .highlight {
2
- // todo: add styling
3
2
  background-color: yellow;
3
+ font-weight: 600;
4
4
  }
@@ -1,19 +1,11 @@
1
1
  import { t as getIcon } from "../../utils.js";
2
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { jsx } from "react/jsx-runtime";
3
3
  var HTMLFile = ({ size, isHovered }) => {
4
4
  return getIcon({
5
5
  size,
6
6
  isHovered,
7
- normal: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "m21.565 22.235-2.292-2.292 2.292-2.292-.707-.707-2.999 3 2.999 2.998.707-.707Zm8.178-2.292-2.998 3-.707-.708 2.291-2.292-2.291-2.292.707-.707 2.998 3Zm4.052 12.441V33h-3.112v-4.722h.75v4.106h2.362Zm-8.377-4.106h-.968V33h.745v-1.63l-.076-2.139L26.727 33h.547l1.612-3.779-.076 2.15V33h.75v-4.722h-.977l-1.58 3.692-1.585-3.692Zm-3.323.62V33h-.746v-4.102H19.74v-.62h3.972v.62h-1.617Zm-3.834 1.463v-2.083h.75V33h-.75v-2.018h-2.448V33h-.75v-4.722h.75v2.083h2.448Z" }), /* @__PURE__ */ jsx("path", {
8
- fillRule: "evenodd",
9
- d: "M10 7v34h27.6V7H10Zm26.35 1.25h-25.1v31.5h25.1V8.25Z",
10
- clipRule: "evenodd"
11
- })] }),
12
- normalHover: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "m19.565 22.235-2.292-2.292 2.292-2.292-.707-.707-2.999 3 2.999 2.998.707-.707Zm12.178-2.292-2.998 3-.707-.708 2.291-2.292-2.291-2.292.707-.707 2.998 3Zm2.052 12.441V33h-3.112v-4.722h.75v4.106h2.362Zm-8.377-4.106h-.968V33h.745v-1.63l-.076-2.139L26.727 33h.547l1.612-3.779-.076 2.15V33h.75v-4.722h-.977l-1.58 3.692-1.585-3.692Zm-3.323.62V33h-.746v-4.102H19.74v-.62h3.972v.62h-1.617Zm-3.834 1.463v-2.083h.75V33h-.75v-2.018h-2.448V33h-.75v-4.722h.75v2.083h2.448Z" }), /* @__PURE__ */ jsx("path", {
13
- fillRule: "evenodd",
14
- d: "M10 7v34.016h27.6V7H10Zm26.35 1.25h-25.1v31.516h25.1V8.25Z",
15
- clipRule: "evenodd"
16
- })] })
7
+ normal: /* @__PURE__ */ jsx("path", { d: "M37.6 41H10V7h27.6v34Zm-26.35-1.25h25.1V8.25h-25.1v31.5Zm4.563-9.389h2.448v-2.083h.75V33h-.75v-2.019h-2.447V33h-.75v-4.722h.75v2.083Zm7.899-1.463h-1.617V33h-.745v-4.102h-1.61v-.62h3.972v.62Zm3.29 3.073 1.581-3.693h.978V33h-.75v-1.63l.075-2.151L27.274 33h-.547l-1.608-3.769.076 2.14V33h-.746v-4.722h.969l1.585 3.693Zm4.43.413h2.363V33h-3.112v-4.722h.75v4.106ZM21.886 15.78v9.2h-7.042v-9.2h7.042Zm10.873 8.889H24.59v-1h8.167v1ZM15.843 16.78v7.2h5.042v-7.2h-5.042Zm16.915 4.1H24.59v-1h8.167v1Zm0-3.79-8.167.003v-.998l8.167-.002v.998Z" }),
8
+ normalHover: /* @__PURE__ */ jsx("path", { d: "M37.6 41H10V7h27.6v34Zm-26.35-1.25h25.1V8.25h-25.1v31.5Zm4.563-9.389h2.448v-2.083h.75V33h-.75v-2.019h-2.447V33h-.75v-4.722h.75v2.083Zm7.899-1.463h-1.617V33h-.745v-4.102h-1.61v-.62h3.972v.62Zm3.29 3.073 1.581-3.693h.977V33h-.75v-1.629l.076-2.152L27.274 33h-.547l-1.608-3.769.076 2.14V33h-.746v-4.722h.969l1.585 3.693Zm4.43.413h2.363V33h-3.112v-4.722h.75v4.106Zm-8.55-16.604v9.2h-8.04v-9.2h8.04Zm9.876 8.889h-7.17v-1h7.17v1ZM15.843 16.78v7.2h6.04v-7.2h-6.04Zm16.915 4.1h-7.17v-1h7.17v1Zm0-3.79-7.17.003v-.998l7.17-.002v.998Z" })
17
9
  });
18
10
  };
19
11
  var HTMLFile_default = HTMLFile;
@@ -1 +1 @@
1
- {"version":3,"file":"HTMLFile.js","names":["HTMLFile: React.FC<SvgPathProps>"],"sources":["../../../src/components/Icons/HTMLFile.tsx"],"sourcesContent":["import type { SvgPathProps } from '../Icon';\n\nimport { getIcon } from '../Icon/utils';\n\nconst HTMLFile: React.FC<SvgPathProps> = ({ size, isHovered }: SvgPathProps): React.ReactElement => {\n const normal = (\n <>\n <path d=\"m21.565 22.235-2.292-2.292 2.292-2.292-.707-.707-2.999 3 2.999 2.998.707-.707Zm8.178-2.292-2.998 3-.707-.708 2.291-2.292-2.291-2.292.707-.707 2.998 3Zm4.052 12.441V33h-3.112v-4.722h.75v4.106h2.362Zm-8.377-4.106h-.968V33h.745v-1.63l-.076-2.139L26.727 33h.547l1.612-3.779-.076 2.15V33h.75v-4.722h-.977l-1.58 3.692-1.585-3.692Zm-3.323.62V33h-.746v-4.102H19.74v-.62h3.972v.62h-1.617Zm-3.834 1.463v-2.083h.75V33h-.75v-2.018h-2.448V33h-.75v-4.722h.75v2.083h2.448Z\" />\n <path fillRule=\"evenodd\" d=\"M10 7v34h27.6V7H10Zm26.35 1.25h-25.1v31.5h25.1V8.25Z\" clipRule=\"evenodd\" />\n </>\n );\n\n const normalHover = (\n <>\n <path d=\"m19.565 22.235-2.292-2.292 2.292-2.292-.707-.707-2.999 3 2.999 2.998.707-.707Zm12.178-2.292-2.998 3-.707-.708 2.291-2.292-2.291-2.292.707-.707 2.998 3Zm2.052 12.441V33h-3.112v-4.722h.75v4.106h2.362Zm-8.377-4.106h-.968V33h.745v-1.63l-.076-2.139L26.727 33h.547l1.612-3.779-.076 2.15V33h.75v-4.722h-.977l-1.58 3.692-1.585-3.692Zm-3.323.62V33h-.746v-4.102H19.74v-.62h3.972v.62h-1.617Zm-3.834 1.463v-2.083h.75V33h-.75v-2.018h-2.448V33h-.75v-4.722h.75v2.083h2.448Z\" />\n <path fillRule=\"evenodd\" d=\"M10 7v34.016h27.6V7H10Zm26.35 1.25h-25.1v31.516h25.1V8.25Z\" clipRule=\"evenodd\" />\n </>\n );\n\n return getIcon({ size, isHovered, normal, normalHover });\n};\n\nexport default HTMLFile;\n"],"mappings":";;AAIA,IAAMA,YAAoC,EAAE,MAAM,gBAAkD;AAelG,QAAO,QAAQ;EAAE;EAAM;EAAW,QAbhC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAA,EAAK,GAAE,6cAAA,CAA8c,EACtd,oBAAC,QAAA;GAAK,UAAS;GAAU,GAAE;GAAuD,UAAS;IAAY,CAAA,EAAA,CACtG;EAUqC,aANxC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAA,EAAK,GAAE,8cAAA,CAA+c,EACvd,oBAAC,QAAA;GAAK,UAAS;GAAU,GAAE;GAA6D,UAAS;IAAY,CAAA,EAAA,CAC5G;EAGkD,CAAC;;AAG1D,IAAA,mBAAe"}
1
+ {"version":3,"file":"HTMLFile.js","names":["HTMLFile: React.FC<SvgPathProps>"],"sources":["../../../src/components/Icons/HTMLFile.tsx"],"sourcesContent":["import type { SvgPathProps } from '../Icon';\n\nimport { getIcon } from '../Icon/utils';\n\nconst HTMLFile: React.FC<SvgPathProps> = ({ size, isHovered }: SvgPathProps): React.ReactElement => {\n const normal = (\n <path d=\"M37.6 41H10V7h27.6v34Zm-26.35-1.25h25.1V8.25h-25.1v31.5Zm4.563-9.389h2.448v-2.083h.75V33h-.75v-2.019h-2.447V33h-.75v-4.722h.75v2.083Zm7.899-1.463h-1.617V33h-.745v-4.102h-1.61v-.62h3.972v.62Zm3.29 3.073 1.581-3.693h.978V33h-.75v-1.63l.075-2.151L27.274 33h-.547l-1.608-3.769.076 2.14V33h-.746v-4.722h.969l1.585 3.693Zm4.43.413h2.363V33h-3.112v-4.722h.75v4.106ZM21.886 15.78v9.2h-7.042v-9.2h7.042Zm10.873 8.889H24.59v-1h8.167v1ZM15.843 16.78v7.2h5.042v-7.2h-5.042Zm16.915 4.1H24.59v-1h8.167v1Zm0-3.79-8.167.003v-.998l8.167-.002v.998Z\" />\n );\n\n const normalHover = (\n <path d=\"M37.6 41H10V7h27.6v34Zm-26.35-1.25h25.1V8.25h-25.1v31.5Zm4.563-9.389h2.448v-2.083h.75V33h-.75v-2.019h-2.447V33h-.75v-4.722h.75v2.083Zm7.899-1.463h-1.617V33h-.745v-4.102h-1.61v-.62h3.972v.62Zm3.29 3.073 1.581-3.693h.977V33h-.75v-1.629l.076-2.152L27.274 33h-.547l-1.608-3.769.076 2.14V33h-.746v-4.722h.969l1.585 3.693Zm4.43.413h2.363V33h-3.112v-4.722h.75v4.106Zm-8.55-16.604v9.2h-8.04v-9.2h8.04Zm9.876 8.889h-7.17v-1h7.17v1ZM15.843 16.78v7.2h6.04v-7.2h-6.04Zm16.915 4.1h-7.17v-1h7.17v1Zm0-3.79-7.17.003v-.998l7.17-.002v.998Z\" />\n );\n\n return getIcon({ size, isHovered, normal, normalHover });\n};\n\nexport default HTMLFile;\n"],"mappings":";;AAIA,IAAMA,YAAoC,EAAE,MAAM,gBAAkD;AASlG,QAAO,QAAQ;EAAE;EAAM;EAAW,QAPhC,oBAAC,QAAA,EAAK,GAAE,shBAAA,CAAuhB;EAOvf,aAHxC,oBAAC,QAAA,EAAK,GAAE,8gBAAA,CAA+gB;EAGle,CAAC;;AAG1D,IAAA,mBAAe"}
@@ -7,6 +7,7 @@ interface RenderLabelProps {
7
7
  inputId: string;
8
8
  onColor: FormOnColor;
9
9
  markup?: LabelTags;
10
+ className?: string;
10
11
  }
11
12
  export declare const renderLabel: (props: RenderLabelProps) => React.ReactNode;
12
13
  interface RenderLabelAsParentProps {
@@ -37,7 +37,7 @@ export interface NotificationPanelProps {
37
37
  /** Custom id for the label */
38
38
  labelId?: string;
39
39
  /** Custom role for the panel. Default is no role. If variant is alert or crisis, the aria role will be set to "alert" unless the role-prop is also set. */
40
- role?: 'region' | 'alert' | 'status';
40
+ role?: 'region' | 'alert' | 'status' | 'none';
41
41
  /** Sets the data-testid attribute. */
42
42
  testId?: string;
43
43
  /** Ref passed to the component */
@@ -65,7 +65,7 @@ var NotificationPanel = (props) => {
65
65
  [styles["notification-panel--dismissable"]]: dismissable
66
66
  }, className);
67
67
  const ariaRole = role || variant === "error" && "alert" || void 0;
68
- const ariaLabelAttributes = ariaRole ? getAriaLabelAttributes({
68
+ const ariaLabelAttributes = ariaRole && ariaRole !== "none" ? getAriaLabelAttributes({
69
69
  label,
70
70
  id: labelId
71
71
  }) : void 0;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["FluidWrapper: React.FC<WrapFluidProps>","NotificationPanel: React.FC<NotificationPanelProps>"],"sources":["../../../src/components/NotificationPanel/NotificationPanel.tsx","../../../src/components/NotificationPanel/index.ts"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, IconSize } from '../../constants';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { getAriaLabelAttributes } from '../../utils/accessibility';\nimport NotificationBadge from '../Badge/NotificationBadge';\nimport Close from '../Close';\nimport Expander from '../Expander';\n\nimport styles from './styles.module.scss';\n\nexport type NotificationPanelVariants = 'info' | 'warn' | 'error' | 'success';\nexport type NotificationCompactVariants = 'basic' | 'outline';\nexport type NotificationPanelSizes = 'small' | 'medium' | 'large';\nexport type LabelTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'span';\n\nexport interface NotificationPanelProps {\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds inner child elements. */\n children?: React.ReactNode;\n /** Adds inner expander elements. */\n expanderChildren?: React.ReactNode;\n /** Text for expanderButton. */\n expanderButtonText?: string;\n /** Text for expanderButton when closed. */\n expanderButtonClosedText?: string;\n /** Makes expander be open from start. */\n expanderOpenFromStart?: boolean;\n /** Changes the visual representation of the notification panel. */\n variant?: NotificationPanelVariants;\n /** Makes the panel more compact. Available in basic and outline. */\n compactVariant?: NotificationCompactVariants;\n /** Sets a fixed size for the content container. */\n size?: NotificationPanelSizes;\n /** Used in combination with dismissiable property to close the notification panel. */\n onClick?: (e?: React.MouseEvent<HTMLElement, MouseEvent>) => void;\n /** Toggles the close button in the top right corner. */\n dismissable?: boolean;\n /** Enables a fluid outer container that spans the entire width of parent. */\n fluid?: boolean;\n /** Sets a label for the notification panel. */\n label?: string;\n /** Changes the underlying element of the label. */\n labelHtmlMarkup?: LabelTags;\n /** Close button aria-label */\n ariaLabelCloseBtn?: string;\n /** Custom id for the label */\n labelId?: string;\n /** Custom role for the panel. Default is no role. If variant is alert or crisis, the aria role will be set to \"alert\" unless the role-prop is also set. */\n role?: 'region' | 'alert' | 'status';\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Ref passed to the component */\n ref?: React.Ref<HTMLDivElement | null>;\n}\n\ntype WrapFluidProps = Pick<NotificationPanelProps, 'fluid'> & {\n children: React.ReactElement;\n};\n\nconst FluidWrapper: React.FC<WrapFluidProps> = ({ fluid, children }) => {\n if (fluid) {\n const fluidClasses = classNames(styles['fluid-wrapper']);\n\n return <div className={fluidClasses}>{children}</div>;\n }\n return children;\n};\n\nconst NotificationPanel: React.FC<NotificationPanelProps> = props => {\n const {\n children,\n variant = 'info',\n dismissable = false,\n onClick,\n expanderChildren,\n expanderButtonText,\n expanderButtonClosedText,\n expanderOpenFromStart = false,\n compactVariant,\n label,\n labelId: labelIdProp,\n labelHtmlMarkup = 'h1',\n fluid = false,\n size,\n className,\n role,\n testId,\n ref,\n } = props;\n const labelId = useIdWithFallback(labelIdProp);\n const [expanderOpen, setExpanderOpen] = React.useState(expanderOpenFromStart);\n const isMobile = useIsMobileBreakpoint();\n\n const renderContent = (): React.ReactNode => {\n const outlineVariant = compactVariant === 'outline';\n const contentClasses = classNames(styles['notification-panel__content']);\n const labelClasses = classNames(styles['notification-panel__label'], {\n [styles['notification-panel__label--no-content']]: !children && !expanderChildren,\n [styles['notification-panel__label--compact']]: !!compactVariant,\n [styles['notification-panel__label--outline']]: outlineVariant,\n });\n const childrenClasses = classNames(styles['notification-panel__children'], {\n [styles['notification-panel__children--with-label']]: label,\n [styles['notification-panel__children--expander-no-label']]: expanderChildren && !label,\n [styles['notification-panel__children--outline']]: outlineVariant,\n });\n const CustomTag = labelHtmlMarkup;\n\n return (\n <div className={contentClasses} id={!label ? labelId : undefined}>\n {label && (\n <CustomTag className={labelClasses} id={labelId}>\n {label}\n </CustomTag>\n )}\n {children && <div className={childrenClasses}>{children}</div>}\n {expanderChildren && expanderButtonText && expanderButtonClosedText && !compactVariant && (\n <Expander\n title={expanderOpen ? expanderButtonText : expanderButtonClosedText}\n onExpand={setExpanderOpen}\n expanded={expanderOpen}\n testId=\"expand\"\n >\n {expanderChildren}\n </Expander>\n )}\n </div>\n );\n };\n\n const notificationPanelClasses = classNames(\n styles['notification-panel'],\n styles[`notification-panel--${variant}`],\n size && styles[`notification-panel--${size}`],\n {\n [styles['notification-panel--compact']]: !!compactVariant,\n [styles['notification-panel--compact--basic']]: compactVariant === 'basic',\n [styles['notification-panel--compact--outline']]: compactVariant === 'outline',\n [styles['notification-panel--with-content']]: expanderChildren || (label && children),\n [styles['notification-panel--dismissable']]: dismissable,\n },\n className\n );\n\n const ariaRole = role || (variant === 'error' && 'alert') || undefined;\n const ariaLabelAttributes = ariaRole ? getAriaLabelAttributes({ label, id: labelId }) : undefined;\n\n return (\n <FluidWrapper fluid={fluid}>\n <div\n ref={ref}\n role={ariaRole}\n data-testid={testId}\n data-analyticsid={AnalyticsId.NotificationPanel}\n className={notificationPanelClasses}\n {...ariaLabelAttributes}\n >\n <NotificationBadge\n variant={variant}\n size={compactVariant || isMobile ? IconSize.XSmall : IconSize.Small}\n className={styles['notification-panel__icon']}\n />\n {dismissable && (\n <span className={styles['notification-panel__close']}>\n <Close ariaLabel={props.ariaLabelCloseBtn} onClick={onClick} color=\"black\" />\n </span>\n )}\n {renderContent()}\n </div>\n </FluidWrapper>\n );\n};\n\nexport default NotificationPanel;\n","import NotificationPanel from './NotificationPanel';\nexport * from './NotificationPanel';\nexport default NotificationPanel;\n"],"mappings":";;;;;;;;;;;AAgEA,IAAMA,gBAA0C,EAAE,OAAO,eAAe;AACtE,KAAI,MAGF,QAAO,oBAAC,OAAA;EAAI,WAFS,WAAW,OAAO,iBAAiB;EAElB;GAAe;AAEvD,QAAO;;AAGT,IAAMC,qBAAsD,UAAS;CACnE,MAAM,EACJ,UACA,UAAU,QACV,cAAc,OACd,SACA,kBACA,oBACA,0BACA,wBAAwB,OACxB,gBACA,OACA,SAAS,aACT,kBAAkB,MAClB,QAAQ,OACR,MACA,WACA,MACA,QACA,QACE;CACJ,MAAM,UAAU,kBAAkB,YAAY;CAC9C,MAAM,CAAC,cAAc,mBAAmB,MAAM,SAAS,sBAAsB;CAC7E,MAAM,WAAW,uBAAuB;CAExC,MAAM,sBAAuC;EAC3C,MAAM,iBAAiB,mBAAmB;EAC1C,MAAM,iBAAiB,WAAW,OAAO,+BAA+B;EACxE,MAAM,eAAe,WAAW,OAAO,8BAA8B;IAClE,OAAO,2CAA2C,CAAC,YAAY,CAAC;IAChE,OAAO,wCAAwC,CAAC,CAAC;IACjD,OAAO,wCAAwC;GACjD,CAAC;EACF,MAAM,kBAAkB,WAAW,OAAO,iCAAiC;IACxE,OAAO,8CAA8C;IACrD,OAAO,qDAAqD,oBAAoB,CAAC;IACjF,OAAO,2CAA2C;GACpD,CAAC;AAGF,SACE,qBAAC,OAAA;GAAI,WAAW;GAAgB,IAAI,CAAC,QAAQ,UAAU,KAAA;;IACpD,SACC,oBALY,iBAKX;KAAU,WAAW;KAAc,IAAI;eACrC;MACS;IAEb,YAAY,oBAAC,OAAA;KAAI,WAAW;KAAkB;MAAe;IAC7D,oBAAoB,sBAAsB,4BAA4B,CAAC,kBACtE,oBAAC,kBAAA;KACC,OAAO,eAAe,qBAAqB;KAC3C,UAAU;KACV,UAAU;KACV,QAAO;eAEN;MACQ;;IAET;;CAIV,MAAM,2BAA2B,WAC/B,OAAO,uBACP,OAAO,uBAAuB,YAC9B,QAAQ,OAAO,uBAAuB,SACtC;GACG,OAAO,iCAAiC,CAAC,CAAC;GAC1C,OAAO,wCAAwC,mBAAmB;GAClE,OAAO,0CAA0C,mBAAmB;GACpE,OAAO,sCAAsC,oBAAqB,SAAS;GAC3E,OAAO,qCAAqC;EAC9C,EACD,UACD;CAED,MAAM,WAAW,QAAS,YAAY,WAAW,WAAY,KAAA;CAC7D,MAAM,sBAAsB,WAAW,uBAAuB;EAAE;EAAO,IAAI;EAAS,CAAC,GAAG,KAAA;AAExF,QACE,oBAAC,cAAA;EAAoB;YACnB,qBAAC,OAAA;GACM;GACL,MAAM;GACN,eAAa;GACb,oBAAkB,YAAY;GAC9B,WAAW;GACX,GAAI;;IAEJ,oBAAC,2BAAA;KACU;KACT,MAAM,kBAAkB,WAAW,SAAS,SAAS,SAAS;KAC9D,WAAW,OAAO;MAClB;IACD,eACC,oBAAC,QAAA;KAAK,WAAW,OAAO;eACtB,oBAAC,eAAA;MAAM,WAAW,MAAM;MAA4B;MAAS,OAAM;OAAU;MACxE;IAER,eAAe;;IACZ;GACO;;AC5KnB,IAAA,4BDgLe"}
1
+ {"version":3,"file":"index.js","names":["FluidWrapper: React.FC<WrapFluidProps>","NotificationPanel: React.FC<NotificationPanelProps>"],"sources":["../../../src/components/NotificationPanel/NotificationPanel.tsx","../../../src/components/NotificationPanel/index.ts"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, IconSize } from '../../constants';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { getAriaLabelAttributes } from '../../utils/accessibility';\nimport NotificationBadge from '../Badge/NotificationBadge';\nimport Close from '../Close';\nimport Expander from '../Expander';\n\nimport styles from './styles.module.scss';\n\nexport type NotificationPanelVariants = 'info' | 'warn' | 'error' | 'success';\nexport type NotificationCompactVariants = 'basic' | 'outline';\nexport type NotificationPanelSizes = 'small' | 'medium' | 'large';\nexport type LabelTags = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'span';\n\nexport interface NotificationPanelProps {\n /** Adds custom classes to the element. */\n className?: string;\n /** Adds inner child elements. */\n children?: React.ReactNode;\n /** Adds inner expander elements. */\n expanderChildren?: React.ReactNode;\n /** Text for expanderButton. */\n expanderButtonText?: string;\n /** Text for expanderButton when closed. */\n expanderButtonClosedText?: string;\n /** Makes expander be open from start. */\n expanderOpenFromStart?: boolean;\n /** Changes the visual representation of the notification panel. */\n variant?: NotificationPanelVariants;\n /** Makes the panel more compact. Available in basic and outline. */\n compactVariant?: NotificationCompactVariants;\n /** Sets a fixed size for the content container. */\n size?: NotificationPanelSizes;\n /** Used in combination with dismissiable property to close the notification panel. */\n onClick?: (e?: React.MouseEvent<HTMLElement, MouseEvent>) => void;\n /** Toggles the close button in the top right corner. */\n dismissable?: boolean;\n /** Enables a fluid outer container that spans the entire width of parent. */\n fluid?: boolean;\n /** Sets a label for the notification panel. */\n label?: string;\n /** Changes the underlying element of the label. */\n labelHtmlMarkup?: LabelTags;\n /** Close button aria-label */\n ariaLabelCloseBtn?: string;\n /** Custom id for the label */\n labelId?: string;\n /** Custom role for the panel. Default is no role. If variant is alert or crisis, the aria role will be set to \"alert\" unless the role-prop is also set. */\n role?: 'region' | 'alert' | 'status' | 'none';\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Ref passed to the component */\n ref?: React.Ref<HTMLDivElement | null>;\n}\n\ntype WrapFluidProps = Pick<NotificationPanelProps, 'fluid'> & {\n children: React.ReactElement;\n};\n\nconst FluidWrapper: React.FC<WrapFluidProps> = ({ fluid, children }) => {\n if (fluid) {\n const fluidClasses = classNames(styles['fluid-wrapper']);\n\n return <div className={fluidClasses}>{children}</div>;\n }\n return children;\n};\n\nconst NotificationPanel: React.FC<NotificationPanelProps> = props => {\n const {\n children,\n variant = 'info',\n dismissable = false,\n onClick,\n expanderChildren,\n expanderButtonText,\n expanderButtonClosedText,\n expanderOpenFromStart = false,\n compactVariant,\n label,\n labelId: labelIdProp,\n labelHtmlMarkup = 'h1',\n fluid = false,\n size,\n className,\n role,\n testId,\n ref,\n } = props;\n const labelId = useIdWithFallback(labelIdProp);\n const [expanderOpen, setExpanderOpen] = React.useState(expanderOpenFromStart);\n const isMobile = useIsMobileBreakpoint();\n\n const renderContent = (): React.ReactNode => {\n const outlineVariant = compactVariant === 'outline';\n const contentClasses = classNames(styles['notification-panel__content']);\n const labelClasses = classNames(styles['notification-panel__label'], {\n [styles['notification-panel__label--no-content']]: !children && !expanderChildren,\n [styles['notification-panel__label--compact']]: !!compactVariant,\n [styles['notification-panel__label--outline']]: outlineVariant,\n });\n const childrenClasses = classNames(styles['notification-panel__children'], {\n [styles['notification-panel__children--with-label']]: label,\n [styles['notification-panel__children--expander-no-label']]: expanderChildren && !label,\n [styles['notification-panel__children--outline']]: outlineVariant,\n });\n const CustomTag = labelHtmlMarkup;\n\n return (\n <div className={contentClasses} id={!label ? labelId : undefined}>\n {label && (\n <CustomTag className={labelClasses} id={labelId}>\n {label}\n </CustomTag>\n )}\n {children && <div className={childrenClasses}>{children}</div>}\n {expanderChildren && expanderButtonText && expanderButtonClosedText && !compactVariant && (\n <Expander\n title={expanderOpen ? expanderButtonText : expanderButtonClosedText}\n onExpand={setExpanderOpen}\n expanded={expanderOpen}\n testId=\"expand\"\n >\n {expanderChildren}\n </Expander>\n )}\n </div>\n );\n };\n\n const notificationPanelClasses = classNames(\n styles['notification-panel'],\n styles[`notification-panel--${variant}`],\n size && styles[`notification-panel--${size}`],\n {\n [styles['notification-panel--compact']]: !!compactVariant,\n [styles['notification-panel--compact--basic']]: compactVariant === 'basic',\n [styles['notification-panel--compact--outline']]: compactVariant === 'outline',\n [styles['notification-panel--with-content']]: expanderChildren || (label && children),\n [styles['notification-panel--dismissable']]: dismissable,\n },\n className\n );\n\n const ariaRole = role || (variant === 'error' && 'alert') || undefined;\n const ariaLabelAttributes = ariaRole && ariaRole !== 'none' ? getAriaLabelAttributes({ label, id: labelId }) : undefined;\n\n return (\n <FluidWrapper fluid={fluid}>\n <div\n ref={ref}\n role={ariaRole}\n data-testid={testId}\n data-analyticsid={AnalyticsId.NotificationPanel}\n className={notificationPanelClasses}\n {...ariaLabelAttributes}\n >\n <NotificationBadge\n variant={variant}\n size={compactVariant || isMobile ? IconSize.XSmall : IconSize.Small}\n className={styles['notification-panel__icon']}\n />\n {dismissable && (\n <span className={styles['notification-panel__close']}>\n <Close ariaLabel={props.ariaLabelCloseBtn} onClick={onClick} color=\"black\" />\n </span>\n )}\n {renderContent()}\n </div>\n </FluidWrapper>\n );\n};\n\nexport default NotificationPanel;\n","import NotificationPanel from './NotificationPanel';\nexport * from './NotificationPanel';\nexport default NotificationPanel;\n"],"mappings":";;;;;;;;;;;AAgEA,IAAMA,gBAA0C,EAAE,OAAO,eAAe;AACtE,KAAI,MAGF,QAAO,oBAAC,OAAA;EAAI,WAFS,WAAW,OAAO,iBAAiB;EAElB;GAAe;AAEvD,QAAO;;AAGT,IAAMC,qBAAsD,UAAS;CACnE,MAAM,EACJ,UACA,UAAU,QACV,cAAc,OACd,SACA,kBACA,oBACA,0BACA,wBAAwB,OACxB,gBACA,OACA,SAAS,aACT,kBAAkB,MAClB,QAAQ,OACR,MACA,WACA,MACA,QACA,QACE;CACJ,MAAM,UAAU,kBAAkB,YAAY;CAC9C,MAAM,CAAC,cAAc,mBAAmB,MAAM,SAAS,sBAAsB;CAC7E,MAAM,WAAW,uBAAuB;CAExC,MAAM,sBAAuC;EAC3C,MAAM,iBAAiB,mBAAmB;EAC1C,MAAM,iBAAiB,WAAW,OAAO,+BAA+B;EACxE,MAAM,eAAe,WAAW,OAAO,8BAA8B;IAClE,OAAO,2CAA2C,CAAC,YAAY,CAAC;IAChE,OAAO,wCAAwC,CAAC,CAAC;IACjD,OAAO,wCAAwC;GACjD,CAAC;EACF,MAAM,kBAAkB,WAAW,OAAO,iCAAiC;IACxE,OAAO,8CAA8C;IACrD,OAAO,qDAAqD,oBAAoB,CAAC;IACjF,OAAO,2CAA2C;GACpD,CAAC;AAGF,SACE,qBAAC,OAAA;GAAI,WAAW;GAAgB,IAAI,CAAC,QAAQ,UAAU,KAAA;;IACpD,SACC,oBALY,iBAKX;KAAU,WAAW;KAAc,IAAI;eACrC;MACS;IAEb,YAAY,oBAAC,OAAA;KAAI,WAAW;KAAkB;MAAe;IAC7D,oBAAoB,sBAAsB,4BAA4B,CAAC,kBACtE,oBAAC,kBAAA;KACC,OAAO,eAAe,qBAAqB;KAC3C,UAAU;KACV,UAAU;KACV,QAAO;eAEN;MACQ;;IAET;;CAIV,MAAM,2BAA2B,WAC/B,OAAO,uBACP,OAAO,uBAAuB,YAC9B,QAAQ,OAAO,uBAAuB,SACtC;GACG,OAAO,iCAAiC,CAAC,CAAC;GAC1C,OAAO,wCAAwC,mBAAmB;GAClE,OAAO,0CAA0C,mBAAmB;GACpE,OAAO,sCAAsC,oBAAqB,SAAS;GAC3E,OAAO,qCAAqC;EAC9C,EACD,UACD;CAED,MAAM,WAAW,QAAS,YAAY,WAAW,WAAY,KAAA;CAC7D,MAAM,sBAAsB,YAAY,aAAa,SAAS,uBAAuB;EAAE;EAAO,IAAI;EAAS,CAAC,GAAG,KAAA;AAE/G,QACE,oBAAC,cAAA;EAAoB;YACnB,qBAAC,OAAA;GACM;GACL,MAAM;GACN,eAAa;GACb,oBAAkB,YAAY;GAC9B,WAAW;GACX,GAAI;;IAEJ,oBAAC,2BAAA;KACU;KACT,MAAM,kBAAkB,WAAW,SAAS,SAAS,SAAS;KAC9D,WAAW,OAAO;MAClB;IACD,eACC,oBAAC,QAAA;KAAK,WAAW,OAAO;eACtB,oBAAC,eAAA;MAAM,WAAW,MAAM;MAA4B;MAAS,OAAM;OAAU;MACxE;IAER,eAAe;;IACZ;GACO;;AC5KnB,IAAA,4BDgLe"}
@@ -10,6 +10,8 @@ export interface SelectProps extends ErrorWrapperClassNameProps, Pick<React.Sele
10
10
  concept?: SelectConcept;
11
11
  /** The label text above the select */
12
12
  label?: React.ReactNode;
13
+ /** Adds custom classes to the label wrapper */
14
+ labelClassName?: string;
13
15
  /** Changes the visuals of the component */
14
16
  onColor?: keyof typeof FormOnColor;
15
17
  /** Activates Error style for the select component - This is can be true while errorText is empty, when in a FormGroup */
@@ -66,6 +66,7 @@
66
66
  line-height: font-settings.$lineheight-size-sm;
67
67
  border-radius: 0;
68
68
  text-overflow: ellipsis;
69
+ cursor: pointer;
69
70
 
70
71
  @media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
71
72
  height: calc(3rem + 0.25rem); // 48px height + 4px border
@@ -12,6 +12,8 @@ export interface TitleProps {
12
12
  htmlMarkup?: TitleTags;
13
13
  /** Changes the appearance of the title. */
14
14
  appearance?: TitleAppearances;
15
+ /** Sets the tabIndex. Use this with caution. */
16
+ tabIndex?: number;
15
17
  /** Sets the data-testid attribute. */
16
18
  testId?: string;
17
19
  /** Ref passed to the heading element */
package/lib/index.d.ts CHANGED
@@ -15,4 +15,5 @@ export { useOutsideEvent } from './hooks/useOutsideEvent';
15
15
  export { useLanguage } from './hooks/useLanguage';
16
16
  export { isMobileUA } from './utils/mobile';
17
17
  export { uuid } from './utils/uuid';
18
+ export { formatResource } from './utils/resource';
18
19
  export * from './constants';
package/lib/index.js CHANGED
@@ -16,4 +16,5 @@ import { t as useToggle } from "./useToggle.js";
16
16
  import { t as useKeyboardEvent } from "./useKeyboardEvent.js";
17
17
  import { t as useOutsideEvent } from "./useOutsideEvent.js";
18
18
  import { t as isMobileUA } from "./mobile.js";
19
- export { AVERAGE_CHARACTER_WIDTH_PX, AnalyticsId, Breakpoint, FormOnColor, FormSize, IconSize, KeyboardEventKey, LanguageLocales, ZIndex, isMobileUA, theme, useBreakpoint, useFocusToggle, useFocusTrap, useIntersectionObserver, useIsVisible, useKeyboardEvent, useLanguage, useLayoutEvent, useOutsideEvent, usePrevious, usePseudoClasses, useResizeObserver, useSize, useToggle, uuid };
19
+ import { t as formatResource } from "./resource.js";
20
+ export { AVERAGE_CHARACTER_WIDTH_PX, AnalyticsId, Breakpoint, FormOnColor, FormSize, IconSize, KeyboardEventKey, LanguageLocales, ZIndex, formatResource, isMobileUA, theme, useBreakpoint, useFocusToggle, useFocusTrap, useIntersectionObserver, useIsVisible, useKeyboardEvent, useLanguage, useLayoutEvent, useOutsideEvent, usePrevious, usePseudoClasses, useResizeObserver, useSize, useToggle, uuid };
@@ -0,0 +1,4 @@
1
+ const formatResource = (template, ...args) => args.reduce((result, arg, index) => result.replace(`{${index}}`, String(arg)), template);
2
+ export { formatResource as t };
3
+
4
+ //# sourceMappingURL=resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.js","names":[],"sources":["../src/utils/resource.ts"],"sourcesContent":["/**\n * Replace `{0}`, `{1}` etc. placeholders in a resource string with the supplied values.\n * @example formatResource('Siste {0} måneder', 6) // 'Siste 6 måneder'\n * @example formatResource('{0} av {1}', 'side', 10) // 'side av 10'\n */\nexport const formatResource = (template: string, ...args: (string | number)[]): string =>\n args.reduce<string>((result, arg, index) => result.replace(`{${index}}`, String(arg)), template);\n"],"mappings":"AAKA,MAAa,kBAAkB,UAAkB,GAAG,SAClD,KAAK,QAAgB,QAAQ,KAAK,UAAU,OAAO,QAAQ,IAAI,MAAM,IAAI,OAAO,IAAI,CAAC,EAAE,SAAS"}
@@ -0,0 +1,7 @@
1
+ declare const _default: {
2
+ "ariaLabelCloseBtn": "Lukk",
3
+ "ariaLabelBackButton": "Gå tilbake"
4
+ }
5
+ ;
6
+
7
+ export default _default;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Replace `{0}`, `{1}` etc. placeholders in a resource string with the supplied values.
3
+ * @example formatResource('Siste {0} måneder', 6) // 'Siste 6 måneder'
4
+ * @example formatResource('{0} av {1}', 'side', 10) // 'side av 10'
5
+ */
6
+ export declare const formatResource: (template: string, ...args: (string | number)[]) => string;
@@ -0,0 +1,2 @@
1
+ import { t as formatResource } from "../resource.js";
2
+ export { formatResource };
package/lib/utils2.js CHANGED
@@ -100,14 +100,16 @@ const renderLabel = (props) => {
100
100
  return /* @__PURE__ */ jsx(Fragment, { children: props.label && isComponent(props.label, Label_default) ? React.cloneElement(props.label, {
101
101
  htmlFor: props.inputId,
102
102
  htmlMarkup: props.markup || "label",
103
- onColor: props.onColor
103
+ onColor: props.onColor,
104
+ className: props.className
104
105
  }) : typeof props.label === "string" && /* @__PURE__ */ jsx(Label_default, {
105
106
  labelTexts: [{
106
107
  text: props.label,
107
108
  type: "normal"
108
109
  }],
109
110
  htmlFor: props.inputId,
110
- onColor: props.onColor
111
+ onColor: props.onColor,
112
+ className: props.className
111
113
  }) });
112
114
  };
113
115
  const renderLabelAsParent = (props) => {